clients: keyboard: Add per key state and color rendering

Add 2 helper functions for the rendering update.

Signed-off-by: Torben Hohn <torben.hohn@bruker.com>
This commit is contained in:
Torben Hohn 2023-10-06 14:19:11 +02:00 committed by Joscha Wloch
parent 9375cbbbf9
commit 0ced2d5eb2

View file

@ -247,6 +247,9 @@ static const struct layout arabic_layout = {
ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_RTL
};
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define max_count MAX(MAX(sizeof(arabic_keys) / sizeof(*arabic_keys), sizeof(numeric_keys) / sizeof(*numeric_keys) ), sizeof(normal_keys) / sizeof(*normal_keys))
static const char *style_labels[] = {
"default",
"none",
@ -273,6 +276,8 @@ struct keyboard {
struct widget *widget;
enum keyboard_state state;
uint32_t key_state[max_count];
uint32_t key_margin;
uint32_t key_radius;
@ -300,6 +305,16 @@ dbg(const char *fmt, ...)
#endif
}
static void
set_hex_color(cairo_t *cr, uint32_t color)
{
cairo_set_source_rgba(cr,
((color >> 16) & 0xff) / 255.0,
((color >> 8) & 0xff) / 255.0,
((color >> 0) & 0xff) / 255.0,
((color >> 24) & 0xff) / 255.0);
}
static const char *
label_from_key(struct keyboard *keyboard,
const struct key *key)
@ -322,16 +337,42 @@ label_from_key(struct keyboard *keyboard,
return "";
}
static void
rounded_rectangle_path(cairo_t *cr, double x, double y, double width, double height, double radius)
{
double degrees = M_PI / 180.0;
cairo_new_sub_path (cr);
cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
cairo_close_path (cr);
}
static void
draw_key(struct keyboard *keyboard,
const struct key *key,
uint32_t key_state,
cairo_t *cr,
unsigned int row,
unsigned int col)
{
const uint32_t margin = keyboard->key_margin;
const char *label;
cairo_text_extents_t extents;
uint32_t fg_color = keyboard->key_fg_color;
uint32_t bg_color = keyboard->key_bg_color;
if (key_state == WL_KEYBOARD_KEY_STATE_RELEASED) {
fg_color = (key->key_type == keytype_default ? keyboard->key_fg_color : keyboard->special_key_fg_color);
bg_color = (key->key_type == keytype_default ? keyboard->key_bg_color : keyboard->special_key_bg_color);
} else {
fg_color = (key->key_type == keytype_default ? keyboard->key_pressed_fg_color : keyboard->special_key_pressed_fg_color);
bg_color = (key->key_type == keytype_default ? keyboard->key_pressed_bg_color : keyboard->special_key_pressed_bg_color);
}
if (key->key_type == keytype_none)
return;
@ -340,11 +381,18 @@ draw_key(struct keyboard *keyboard,
col * key_width, row * key_height,
key->width * key_width, key_height);
cairo_clip(cr);
rounded_rectangle_path(cr,
col * key_width + margin, row * key_height + margin,
key->width * key_width - 2*margin, key_height - 2*margin,
key_width / 5);
/* Paint key background */
set_hex_color(cr, bg_color);
cairo_fill_preserve(cr);
/* Paint frame */
cairo_rectangle(cr,
col * key_width, row * key_height,
key->width * key_width, key_height);
set_hex_color(cr, fg_color);
cairo_set_line_width(cr, 3);
cairo_stroke(cr);
@ -405,15 +453,16 @@ redraw_handler(struct widget *widget, void *data)
cairo_translate(cr, allocation.x, allocation.y);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 1, 1, 1, 0.75);
cairo_rectangle(cr, 0, 0, layout->columns * key_width, layout->rows * key_height);
cairo_paint(cr);
set_hex_color(cr, keyboard->panel_bg_color);
cairo_fill_preserve(cr);
set_hex_color(cr, keyboard->panel_fg_color);
cairo_stroke(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
for (i = 0; i < layout->count; ++i) {
cairo_set_source_rgb(cr, 0, 0, 0);
draw_key(keyboard, &layout->keys[i], cr, row, col);
draw_key(keyboard, &layout->keys[i], keyboard->key_state[i], cr, row, col);
col += layout->keys[i].width;
if (col >= layout->columns) {
row += 1;
@ -557,7 +606,7 @@ append(char *s1, const char *s2)
}
static void
keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, struct input *input, enum wl_pointer_button_state state)
keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, uint32_t key_num, struct input *input, enum wl_pointer_button_state state)
{
const char *label = NULL;
@ -576,6 +625,8 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
xkb_mod_mask_t mod_mask = keyboard->state == KEYBOARD_STATE_DEFAULT ? 0 : keyboard->keyboard->keysym.shift_mask;
uint32_t key_state = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
keyboard->key_state[key_num] = key_state;
switch (key->key_type) {
case keytype_default:
if (state != WL_POINTER_BUTTON_STATE_PRESSED)
@ -717,7 +768,7 @@ button_handler(struct widget *widget,
for (i = 0; i < layout->count; ++i) {
col -= layout->keys[i].width;
if (col < 0) {
keyboard_handle_key(keyboard, time, &layout->keys[i], input, state);
keyboard_handle_key(keyboard, time, &layout->keys[i], i, input, state);
break;
}
}
@ -748,7 +799,7 @@ touch_handler(struct input *input, uint32_t time,
col -= layout->keys[i].width;
if (col < 0) {
keyboard_handle_key(keyboard, time,
&layout->keys[i], input, state);
&layout->keys[i], i, input, state);
break;
}
}