libeek: add eek_keyboard_find_key_by_position().
This commit is contained in:
2
TODO
2
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
|
||||
|
||||
@ -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 = \
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-types.h"
|
||||
#include <math.h>
|
||||
|
||||
/* 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)
|
||||
|
||||
@ -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:
|
||||
|
||||
Reference in New Issue
Block a user