diff --git a/TODO b/TODO index 8f5b3673..232bfb3a 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,5 @@ -- Caribou layout engine (XML) -- matchbox-keyboard layout engine (XML) -- delay initialization of XKB and XKL layouts --- add eek_keyboard_find_by_position(), that takes account of section - rotation, in addition to eek_container_find_by_position() -- add mechanism to change appearances (colors?) of UI widgets depending on modifier states diff --git a/eek/Makefile.am b/eek/Makefile.am index 177e3cd3..b94bb956 100644 --- a/eek/Makefile.am +++ b/eek/Makefile.am @@ -47,7 +47,7 @@ libeek_la_SOURCES = \ eek-unicode-keysym-labels.h \ eek-keyname-keysym-labels.h libeek_la_CFLAGS = $(GOBJECT2_CFLAGS) -libeek_la_LIBADD = $(GOBJECT2_LIBS) +libeek_la_LIBADD = $(GOBJECT2_LIBS) -lm if HAVE_CLUTTER libeek_clutter_la_SOURCES = \ diff --git a/eek/eek-container.c b/eek/eek-container.c index f1b71da4..64855c9b 100644 --- a/eek/eek-container.c +++ b/eek/eek-container.c @@ -231,23 +231,16 @@ eek_container_find (EekContainer *container, user_data); } -struct _FbpData -{ - EekKey *key; - gint x, y; -}; -typedef struct _FbpData FbpData; - static gint compare_element_by_position (EekElement *element, gpointer user_data) { EekBounds bounds; - FbpData *data = user_data; + EekPoint *point = user_data; eek_element_get_bounds (element, &bounds); - if (bounds.x <= data->x && bounds.y <= data->y && - data->x <= (bounds.x + bounds.width) && - data->y <= (bounds.y + bounds.height)) + if (bounds.x <= point->x && bounds.y <= point->y && + point->x <= (bounds.x + bounds.width) && + point->y <= (bounds.y + bounds.height)) return 0; return -1; } @@ -258,13 +251,13 @@ eek_container_find_by_position (EekContainer *container, gdouble y) { EekBounds bounds; - FbpData data; + EekPoint point; g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL); eek_element_get_bounds (EEK_ELEMENT(container), &bounds); - data.x = x - bounds.x; - data.y = y - bounds.y; + point.x = x - bounds.x; + point.y = y - bounds.y; return eek_container_find (container, compare_element_by_position, - &data); + &point); } diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index 6315a961..317f9cd7 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -419,45 +419,37 @@ on_button_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - EekElement *keyboard = user_data, *section, *key; + EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(user_data), *key; EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EekBounds bounds; gdouble x, y; x = (gdouble)event->x / priv->scale; y = (gdouble)event->y / priv->scale; - section = eek_container_find_by_position (EEK_CONTAINER(keyboard), x, y); - if (section) { - eek_element_get_bounds (keyboard, &bounds); - x -= bounds.x; - y -= bounds.y; - key = eek_container_find_by_position (EEK_CONTAINER(section), - x, - y); - if (key) - switch (event->type) { - case GDK_BUTTON_PRESS: - if (priv->key == key) - return FALSE; - if (priv->key) { - key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(priv->key)); - g_signal_emit_by_name (keyboard, "key-released", priv->key); - } - key_enlarge (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key)); - g_signal_emit_by_name (keyboard, "key-pressed", key); - priv->key = key; - return TRUE; - case GDK_BUTTON_RELEASE: - if (!priv->key) - return FALSE; + key = eek_keyboard_find_key_by_position (EEK_KEYBOARD(keyboard), x, y); + if (key) + switch (event->type) { + case GDK_BUTTON_PRESS: + if (priv->key == key) + return FALSE; + if (priv->key) { key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(priv->key)); g_signal_emit_by_name (keyboard, "key-released", priv->key); - priv->key = NULL; - return TRUE; - default: - return FALSE; } - } + key_enlarge (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key)); + g_signal_emit_by_name (keyboard, "key-pressed", key); + priv->key = key; + return TRUE; + case GDK_BUTTON_RELEASE: + if (!priv->key) + return FALSE; + key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(priv->key)); + g_signal_emit_by_name (keyboard, "key-released", priv->key); + priv->key = NULL; + return TRUE; + default: + return FALSE; + } return FALSE; } diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index c8e293c2..5cef6069 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -484,3 +484,59 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard, keycode); } + +static gint +compare_section_by_position (EekElement *element, gpointer user_data) +{ + EekSection *section = EEK_SECTION(element); + EekPoint *point = user_data; + gint angle; + EekBounds bounds; + EekPoint rotated; + + eek_element_get_bounds (element, &bounds); + rotated.x = point->x - bounds.x; + rotated.y = point->y - bounds.y; + angle = eek_section_get_angle (section); + eek_point_rotate (&rotated, -angle); + + if (0 <= rotated.x && 0 <= rotated.y && + rotated.x <= bounds.width && + rotated.y <= bounds.height) + return 0; + return -1; +} + +static EekSection * +eek_keyboard_find_section_by_position (EekKeyboard *keyboard, + gdouble x, + gdouble y) +{ + EekBounds bounds; + EekPoint point; + + eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); + point.x = x - bounds.x; + point.y = y - bounds.y; + return eek_container_find (EEK_CONTAINER(keyboard), + compare_section_by_position, + &point); +} + +EekKey * +eek_keyboard_find_key_by_position (EekKeyboard *keyboard, + gdouble x, + gdouble y) +{ + EekSection *section; + EekBounds bounds; + + section = eek_keyboard_find_section_by_position (keyboard, x, y); + if (!section) + return NULL; + + eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); + x -= bounds.x; + y -= bounds.y; + return eek_section_find_key_by_position (section, x, y); +} diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index 8812ed41..7f9ce8c6 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -83,22 +83,25 @@ struct _EekKeyboardClass gpointer pdummy[24]; }; -GType eek_keyboard_get_type (void) G_GNUC_CONST; +GType eek_keyboard_get_type (void) G_GNUC_CONST; -void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, - gint group, - gint level); -void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, - gint *group, - gint *level); +void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, + gint group, + gint level); +void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, + gint *group, + gint *level); -EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); +EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); -void eek_keyboard_set_layout (EekKeyboard *keyboard, - EekLayout *layout); -void eek_keyboard_realize (EekKeyboard *keyboard); -EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, - guint keycode); +void eek_keyboard_set_layout (EekKeyboard *keyboard, + EekLayout *layout); +void eek_keyboard_realize (EekKeyboard *keyboard); +EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, + guint keycode); +EekKey *eek_keyboard_find_key_by_position (EekKeyboard *keyboard, + gdouble x, + gdouble y); G_END_DECLS #endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-section.c b/eek/eek-section.c index 7788a3a9..d78502e6 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -438,3 +438,26 @@ eek_section_find_key_by_keycode (EekSection *section, return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section, keycode); } + +EekKey * +eek_section_find_key_by_position (EekSection *section, + gdouble x, + gdouble y) +{ + gint angle; + EekBounds bounds; + EekPoint point; + EekElement *key; + + eek_element_get_bounds (EEK_ELEMENT(section), &bounds); + point.x = x - bounds.x; + point.y = y - bounds.y; + angle = eek_section_get_angle (section); + eek_point_rotate (&point, -angle); + key = eek_container_find_by_position (EEK_CONTAINER(section), + point.x + bounds.x, + point.y + bounds.y); + if (!key) + return NULL; + return EEK_KEY(key); +} diff --git a/eek/eek-section.h b/eek/eek-section.h index dc78089a..9b990185 100644 --- a/eek/eek-section.h +++ b/eek/eek-section.h @@ -86,27 +86,30 @@ struct _EekSectionClass gpointer pdummy[24]; }; -GType eek_section_get_type (void) G_GNUC_CONST; +GType eek_section_get_type (void) G_GNUC_CONST; -void eek_section_set_angle (EekSection *section, - gint angle); -gint eek_section_get_angle (EekSection *section); +void eek_section_set_angle (EekSection *section, + gint angle); +gint eek_section_get_angle (EekSection *section); -gint eek_section_get_n_rows (EekSection *section); -void eek_section_add_row (EekSection *section, - gint num_columns, - EekOrientation orientation); -void eek_section_get_row (EekSection *section, - gint index, - gint *num_columns, - EekOrientation *orientation); +gint eek_section_get_n_rows (EekSection *section); +void eek_section_add_row (EekSection *section, + gint num_columns, + EekOrientation orientation); +void eek_section_get_row (EekSection *section, + gint index, + gint *num_columns, + EekOrientation *orientation); -EekKey *eek_section_create_key (EekSection *section, - gint column, - gint row); +EekKey *eek_section_create_key (EekSection *section, + gint column, + gint row); -EekKey *eek_section_find_key_by_keycode (EekSection *section, - guint keycode); +EekKey *eek_section_find_key_by_keycode (EekSection *section, + guint keycode); +EekKey *eek_section_find_key_by_position (EekSection *section, + gdouble x, + gdouble y); G_END_DECLS #endif /* EEK_SECTION_H */ diff --git a/eek/eek-types.c b/eek/eek-types.c index 790987e7..46db453a 100644 --- a/eek/eek-types.c +++ b/eek/eek-types.c @@ -28,6 +28,7 @@ #endif /* HAVE_CONFIG_H */ #include "eek-types.h" +#include /* EekKeysymMatrix */ static EekKeysymMatrix * @@ -81,6 +82,19 @@ eek_point_get_type (void) return our_type; } +void +eek_point_rotate (EekPoint *point, gint angle) +{ + EekPoint *p; + gdouble r, phi; + + phi = atan2 (point->y, point->x); + r = sqrt (point->x * point->x + point->y * point->y); + phi += angle * M_PI / 180; + point->x = r * cos (phi); + point->y = r * sin (phi); +} + /* EekBounds */ static EekBounds * eek_bounds_copy (const EekBounds *bounds) diff --git a/eek/eek-types.h b/eek/eek-types.h index b3c0282e..4034fea6 100644 --- a/eek/eek-types.h +++ b/eek/eek-types.h @@ -80,6 +80,8 @@ typedef struct _EekPoint EekPoint; #define EEK_TYPE_POINT (eek_point_get_type ()) GType eek_point_get_type (void) G_GNUC_CONST; +void eek_point_rotate (EekPoint *point, + gint angle); /** * EekBounds: