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);
priv->children = g_slist_prepend (priv->children, child);
eek_element_set_parent (child, self);
eek_element_set_parent (child, EEK_ELEMENT(self));
}
static void
@ -105,6 +105,44 @@ eek_container_real_find (EekContainer *self,
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
eek_container_dispose (GObject *object)
{
@ -141,6 +179,7 @@ eek_container_class_init (EekContainerClass *klass)
klass->remove_child = eek_container_real_remove_child;
klass->foreach_child = eek_container_real_foreach_child;
klass->find = eek_container_real_find;
klass->find_by_position = eek_container_real_find_by_position;
gobject_class->finalize = eek_container_finalize;
gobject_class->dispose = eek_container_dispose;
@ -230,3 +269,14 @@ eek_container_find (EekContainer *container,
func,
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

@ -51,35 +51,41 @@ struct _EekContainerClass
/*< private >*/
EekElementClass parent_class;
void (* add_child) (EekContainer *self,
EekElement *element);
void (* add_child) (EekContainer *self,
EekElement *element);
void (* remove_child) (EekContainer *self,
EekElement *element);
void (* remove_child) (EekContainer *self,
EekElement *element);
/*< public >*/
void (* foreach_child) (EekContainer *self,
EekCallback callback,
gpointer user_data);
EekElement *(* find) (EekContainer *self,
EekCompareFunc func,
gpointer user_data);
void (* foreach_child) (EekContainer *self,
EekCallback callback,
gpointer user_data);
EekElement *(* find) (EekContainer *self,
EekCompareFunc func,
gpointer user_data);
EekElement *(* find_by_position) (EekContainer *self,
gdouble x,
gdouble y);
/* signals */
void (* child_added) (EekContainer *self,
EekElement *element);
void (* child_removed) (EekContainer *self,
EekElement *element);
void (* child_added) (EekContainer *self,
EekElement *element);
void (* child_removed) (EekContainer *self,
EekElement *element);
};
GType eek_container_get_type (void) G_GNUC_CONST;
GType eek_container_get_type (void) G_GNUC_CONST;
void eek_container_foreach_child (EekContainer *container,
EekCallback callback,
gpointer user_data);
EekElement *eek_container_find (EekContainer *container,
EekCompareFunc func,
gpointer user_data);
void eek_container_foreach_child (EekContainer *container,
EekCallback callback,
gpointer user_data);
EekElement *eek_container_find (EekContainer *container,
EekCompareFunc func,
gpointer user_data);
EekElement *eek_container_find_by_position (EekContainer *container,
gdouble x,
gdouble y);
G_END_DECLS
#endif /* EEK_CONTAINER_H */

View File

@ -52,12 +52,12 @@ struct _EekElementPrivate
{
gchar *name;
EekBounds bounds;
EekContainer *parent;
EekElement *parent;
};
static void
eek_element_real_set_parent (EekElement *self,
EekContainer *parent)
eek_element_real_set_parent (EekElement *self,
EekElement *parent)
{
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)
{
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
@ -237,16 +237,16 @@ eek_element_init (EekElement *self)
/**
* eek_element_set_parent:
* @element: an #EekElement
* @parent: an #EekContainer
* @parent: an #EekElement
*
* Set the parent of @element to @parent.
*/
void
eek_element_set_parent (EekElement *element,
EekContainer *parent)
eek_element_set_parent (EekElement *element,
EekElement *parent)
{
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);
}
@ -255,9 +255,9 @@ eek_element_set_parent (EekElement *element,
* @element: an #EekElement
*
* 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)
{
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
*
* Get the bounding box of @element. Note that if @element has
* parent, X and Y positions of @bounds are relative to the parent
* position. To obtain the absolute position, use
* #eek_element_get_absolute_position().
* parent, position of @bounds are relative to the parent. To obtain
* the absolute position, use #eek_element_get_absolute_position().
*/
void
eek_element_get_bounds (EekElement *element,
@ -341,19 +340,14 @@ eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y)
{
EekContainer *parent;
EekBounds bounds;
gdouble ax, ay;
gdouble ax = 0.0, ay = 0.0;
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);
do {
eek_element_get_bounds (element, &bounds);
ax += bounds.x;
ay += bounds.y;
element = EEK_ELEMENT(parent);
}
} while ((element = eek_element_get_parent (element)) != NULL);
*x = ax;
*y = ay;
}

View File

@ -46,40 +46,40 @@ struct _EekElementClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
void (* set_parent) (EekElement *self,
EekContainer *parent);
EekContainer *(* get_parent) (EekElement *self);
void (* set_name) (EekElement *self,
const gchar *name);
void (* set_parent) (EekElement *self,
EekElement *parent);
EekElement *(* get_parent) (EekElement *self);
void (* set_name) (EekElement *self,
const gchar *name);
G_CONST_RETURN gchar *(* get_name) (EekElement *self);
G_CONST_RETURN gchar *(* get_name) (EekElement *self);
void (* set_bounds) (EekElement *self,
EekBounds *bounds);
void (* set_bounds) (EekElement *self,
EekBounds *bounds);
void (* get_bounds) (EekElement *self,
EekBounds *bounds);
void (* get_bounds) (EekElement *self,
EekBounds *bounds);
};
GType eek_element_get_type (void) G_GNUC_CONST;
void eek_element_set_parent (EekElement *element,
EekContainer *parent);
EekContainer *eek_element_get_parent (EekElement *element);
void eek_element_set_name (EekElement *element,
const gchar *name);
void eek_element_set_parent (EekElement *element,
EekElement *parent);
EekElement *eek_element_get_parent (EekElement *element);
void eek_element_set_name (EekElement *element,
const gchar *name);
G_CONST_RETURN gchar *eek_element_get_name (EekElement *element);
G_CONST_RETURN gchar *eek_element_get_name (EekElement *element);
void eek_element_set_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_set_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_get_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_get_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y);
void eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y);
G_END_DECLS
#endif /* EEK_ELEMENT_H */

View File

@ -234,80 +234,34 @@ on_gtk_expose_event (GtkWidget *widget,
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
on_gtk_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
on_gtk_button_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
EekKeyboard *keyboard = user_data;
EekKey *key;
EekElement *keyboard = user_data, *section, *key;
EekBounds bounds;
gdouble x, y;
key = find_key_by_location (keyboard, event->x, event->y);
if (key) {
g_signal_emit_by_name (keyboard, "key-pressed", key);
return TRUE;
}
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);
return TRUE;
x = (gdouble)event->x;
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);
return TRUE;
case GDK_BUTTON_RELEASE:
g_signal_emit_by_name (keyboard, "key-released", key);
return TRUE;
default:
return FALSE;
}
}
return FALSE;
}
@ -329,9 +283,9 @@ eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard)
g_signal_connect (priv->widget, "expose_event",
G_CALLBACK (on_gtk_expose_event), keyboard);
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_CALLBACK (on_gtk_button_release_event), keyboard);
G_CALLBACK (on_gtk_button_event), keyboard);
eek_keyboard_realize (EEK_KEYBOARD(keyboard));
}
return priv->widget;

View File

@ -192,15 +192,16 @@ eek_keyboard_real_realize (EekKeyboard *self)
priv->is_realized = TRUE;
}
struct find_key_by_keycode_data {
struct _FkbkData {
EekKey *key;
guint keycode;
};
typedef struct _FkbkData FkbkData;
static gint
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->keycode);
@ -213,7 +214,7 @@ static EekKey *
eek_keyboard_real_find_key_by_keycode (EekKeyboard *self,
guint keycode)
{
struct find_key_by_keycode_data data;
FkbkData data;
data.keycode = keycode;
if (eek_container_find (EEK_CONTAINER(self),