libeek: use eek_container_find_by_position() in button event handler of EekGtkKeyboard

This commit is contained in:
Daiki Ueno
2010-06-17 11:23:01 +09:00
parent 2877170d2f
commit 6ba0a734d9
6 changed files with 148 additions and 143 deletions

View File

@ -61,7 +61,7 @@ eek_container_real_add_child (EekContainer *self,
g_object_ref_sink (child); g_object_ref_sink (child);
priv->children = g_slist_prepend (priv->children, child); priv->children = g_slist_prepend (priv->children, child);
eek_element_set_parent (child, self); eek_element_set_parent (child, EEK_ELEMENT(self));
} }
static void static void
@ -105,6 +105,44 @@ eek_container_real_find (EekContainer *self,
return NULL; return NULL;
} }
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;
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))
return 0;
return -1;
}
static EekElement *
eek_container_real_find_by_position (EekContainer *self,
gdouble x,
gdouble y)
{
EekBounds bounds;
FbpData data;
EekElement *element;
eek_element_get_bounds (EEK_ELEMENT(self), &bounds);
data.x = x - bounds.x;
data.y = y - bounds.y;
return eek_container_find (self,
compare_element_by_position,
&data);
}
static void static void
eek_container_dispose (GObject *object) eek_container_dispose (GObject *object)
{ {
@ -141,6 +179,7 @@ eek_container_class_init (EekContainerClass *klass)
klass->remove_child = eek_container_real_remove_child; klass->remove_child = eek_container_real_remove_child;
klass->foreach_child = eek_container_real_foreach_child; klass->foreach_child = eek_container_real_foreach_child;
klass->find = eek_container_real_find; klass->find = eek_container_real_find;
klass->find_by_position = eek_container_real_find_by_position;
gobject_class->finalize = eek_container_finalize; gobject_class->finalize = eek_container_finalize;
gobject_class->dispose = eek_container_dispose; gobject_class->dispose = eek_container_dispose;
@ -230,3 +269,14 @@ eek_container_find (EekContainer *container,
func, func,
user_data); user_data);
} }
EekElement *
eek_container_find_by_position (EekContainer *container,
gdouble x,
gdouble y)
{
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
return EEK_CONTAINER_GET_CLASS(container)->find_by_position (container,
x,
y);
}

View File

@ -64,6 +64,9 @@ struct _EekContainerClass
EekElement *(* find) (EekContainer *self, EekElement *(* find) (EekContainer *self,
EekCompareFunc func, EekCompareFunc func,
gpointer user_data); gpointer user_data);
EekElement *(* find_by_position) (EekContainer *self,
gdouble x,
gdouble y);
/* signals */ /* signals */
void (* child_added) (EekContainer *self, void (* child_added) (EekContainer *self,
@ -80,6 +83,9 @@ void eek_container_foreach_child (EekContainer *container,
EekElement *eek_container_find (EekContainer *container, EekElement *eek_container_find (EekContainer *container,
EekCompareFunc func, EekCompareFunc func,
gpointer user_data); gpointer user_data);
EekElement *eek_container_find_by_position (EekContainer *container,
gdouble x,
gdouble y);
G_END_DECLS G_END_DECLS
#endif /* EEK_CONTAINER_H */ #endif /* EEK_CONTAINER_H */

View File

@ -52,12 +52,12 @@ struct _EekElementPrivate
{ {
gchar *name; gchar *name;
EekBounds bounds; EekBounds bounds;
EekContainer *parent; EekElement *parent;
}; };
static void static void
eek_element_real_set_parent (EekElement *self, eek_element_real_set_parent (EekElement *self,
EekContainer *parent) EekElement *parent)
{ {
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
@ -73,7 +73,7 @@ eek_element_real_set_parent (EekElement *self,
} }
} }
static EekContainer * static EekElement *
eek_element_real_get_parent (EekElement *self) eek_element_real_get_parent (EekElement *self)
{ {
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self); EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
@ -237,16 +237,16 @@ eek_element_init (EekElement *self)
/** /**
* eek_element_set_parent: * eek_element_set_parent:
* @element: an #EekElement * @element: an #EekElement
* @parent: an #EekContainer * @parent: an #EekElement
* *
* Set the parent of @element to @parent. * Set the parent of @element to @parent.
*/ */
void void
eek_element_set_parent (EekElement *element, eek_element_set_parent (EekElement *element,
EekContainer *parent) EekElement *parent)
{ {
g_return_if_fail (EEK_IS_ELEMENT(element)); g_return_if_fail (EEK_IS_ELEMENT(element));
g_return_if_fail (EEK_IS_CONTAINER(parent)); g_return_if_fail (EEK_IS_ELEMENT(parent));
EEK_ELEMENT_GET_CLASS(element)->set_parent (element, parent); EEK_ELEMENT_GET_CLASS(element)->set_parent (element, parent);
} }
@ -255,9 +255,9 @@ eek_element_set_parent (EekElement *element,
* @element: an #EekElement * @element: an #EekElement
* *
* Get the parent of @element. * Get the parent of @element.
* Returns: an #EekContainer if the parent is set * Returns: an #EekElement if the parent is set
*/ */
EekContainer * EekElement *
eek_element_get_parent (EekElement *element) eek_element_get_parent (EekElement *element)
{ {
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL); g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
@ -316,9 +316,8 @@ eek_element_set_bounds (EekElement *element,
* @bounds: pointer where bounding box of @element will be stored * @bounds: pointer where bounding box of @element will be stored
* *
* Get the bounding box of @element. Note that if @element has * Get the bounding box of @element. Note that if @element has
* parent, X and Y positions of @bounds are relative to the parent * parent, position of @bounds are relative to the parent. To obtain
* position. To obtain the absolute position, use * the absolute position, use #eek_element_get_absolute_position().
* #eek_element_get_absolute_position().
*/ */
void void
eek_element_get_bounds (EekElement *element, eek_element_get_bounds (EekElement *element,
@ -341,19 +340,14 @@ eek_element_get_absolute_position (EekElement *element,
gdouble *x, gdouble *x,
gdouble *y) gdouble *y)
{ {
EekContainer *parent;
EekBounds bounds; EekBounds bounds;
gdouble ax, ay; gdouble ax = 0.0, ay = 0.0;
do {
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
ax = bounds.x;
ay = bounds.y;
while ((parent = eek_element_get_parent (element)) != NULL) {
eek_element_get_bounds (EEK_ELEMENT(parent), &bounds);
ax += bounds.x; ax += bounds.x;
ay += bounds.y; ay += bounds.y;
element = EEK_ELEMENT(parent); } while ((element = eek_element_get_parent (element)) != NULL);
}
*x = ax; *x = ax;
*y = ay; *y = ay;
} }

View File

@ -47,8 +47,8 @@ struct _EekElementClass
/*< private >*/ /*< private >*/
GInitiallyUnownedClass parent_class; GInitiallyUnownedClass parent_class;
void (* set_parent) (EekElement *self, void (* set_parent) (EekElement *self,
EekContainer *parent); EekElement *parent);
EekContainer *(* get_parent) (EekElement *self); EekElement *(* get_parent) (EekElement *self);
void (* set_name) (EekElement *self, void (* set_name) (EekElement *self,
const gchar *name); const gchar *name);
@ -64,8 +64,8 @@ struct _EekElementClass
GType eek_element_get_type (void) G_GNUC_CONST; GType eek_element_get_type (void) G_GNUC_CONST;
void eek_element_set_parent (EekElement *element, void eek_element_set_parent (EekElement *element,
EekContainer *parent); EekElement *parent);
EekContainer *eek_element_get_parent (EekElement *element); EekElement *eek_element_get_parent (EekElement *element);
void eek_element_set_name (EekElement *element, void eek_element_set_name (EekElement *element,
const gchar *name); const gchar *name);

View File

@ -234,80 +234,34 @@ on_gtk_expose_event (GtkWidget *widget,
return TRUE; return TRUE;
} }
struct _FkbeCallbackData
{
EekKey *key;
gint x, y;
};
typedef struct _FkbeCallbackData FkbeCallbackData;
static gint
compare_element_by_location (EekElement *element, gpointer user_data)
{
EekBounds bounds;
FkbeCallbackData *data = 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))
return 0;
return -1;
}
static EekKey *
find_key_by_location (EekKeyboard *keyboard, gint x, gint y)
{
EekBounds bounds;
FkbeCallbackData data;
EekElement *element;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
data.x = x - bounds.x;
data.y = y - bounds.y;
element = eek_container_find (EEK_CONTAINER(keyboard),
compare_element_by_location,
&data);
if (element) {
eek_element_get_bounds (element, &bounds);
data.x -= bounds.x;
data.y -= bounds.y;
element = eek_container_find (EEK_CONTAINER(element),
compare_element_by_location,
&data);
return EEK_KEY(element);
}
return NULL;
}
static gboolean static gboolean
on_gtk_button_press_event (GtkWidget *widget, on_gtk_button_event (GtkWidget *widget,
GdkEventButton *event, GdkEventButton *event,
gpointer user_data) gpointer user_data)
{ {
EekKeyboard *keyboard = user_data; EekElement *keyboard = user_data, *section, *key;
EekKey *key; EekBounds bounds;
gdouble x, y;
key = find_key_by_location (keyboard, event->x, event->y); x = (gdouble)event->x;
if (key) { y = (gdouble)event->y;
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:
g_signal_emit_by_name (keyboard, "key-pressed", key); g_signal_emit_by_name (keyboard, "key-pressed", key);
return TRUE; return TRUE;
} case GDK_BUTTON_RELEASE:
return FALSE;
}
static gboolean
on_gtk_button_release_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
EekKeyboard *keyboard = user_data;
EekKey *key;
key = find_key_by_location (keyboard, event->x, event->y);
if (key) {
g_signal_emit_by_name (keyboard, "key-released", key); g_signal_emit_by_name (keyboard, "key-released", key);
return TRUE; return TRUE;
default:
return FALSE;
}
} }
return FALSE; return FALSE;
} }
@ -329,9 +283,9 @@ eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard)
g_signal_connect (priv->widget, "expose_event", g_signal_connect (priv->widget, "expose_event",
G_CALLBACK (on_gtk_expose_event), keyboard); G_CALLBACK (on_gtk_expose_event), keyboard);
g_signal_connect (priv->widget, "button-press-event", g_signal_connect (priv->widget, "button-press-event",
G_CALLBACK (on_gtk_button_press_event), keyboard); G_CALLBACK (on_gtk_button_event), keyboard);
g_signal_connect (priv->widget, "button-release-event", g_signal_connect (priv->widget, "button-release-event",
G_CALLBACK (on_gtk_button_release_event), keyboard); G_CALLBACK (on_gtk_button_event), keyboard);
eek_keyboard_realize (EEK_KEYBOARD(keyboard)); eek_keyboard_realize (EEK_KEYBOARD(keyboard));
} }
return priv->widget; return priv->widget;

View File

@ -192,15 +192,16 @@ eek_keyboard_real_realize (EekKeyboard *self)
priv->is_realized = TRUE; priv->is_realized = TRUE;
} }
struct find_key_by_keycode_data { struct _FkbkData {
EekKey *key; EekKey *key;
guint keycode; guint keycode;
}; };
typedef struct _FkbkData FkbkData;
static gint static gint
compare_section_by_keycode (EekElement *element, gpointer user_data) compare_section_by_keycode (EekElement *element, gpointer user_data)
{ {
struct find_key_by_keycode_data *data = user_data; FkbkData *data = user_data;
data->key = eek_section_find_key_by_keycode (EEK_SECTION(element), data->key = eek_section_find_key_by_keycode (EEK_SECTION(element),
data->keycode); data->keycode);
@ -213,7 +214,7 @@ static EekKey *
eek_keyboard_real_find_key_by_keycode (EekKeyboard *self, eek_keyboard_real_find_key_by_keycode (EekKeyboard *self,
guint keycode) guint keycode)
{ {
struct find_key_by_keycode_data data; FkbkData data;
data.keycode = keycode; data.keycode = keycode;
if (eek_container_find (EEK_CONTAINER(self), if (eek_container_find (EEK_CONTAINER(self),