[atomix/wip/gtk3-port] Board: ported selector methods to plain gtk
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [atomix/wip/gtk3-port] Board: ported selector methods to plain gtk
- Date: Mon, 12 Jan 2015 03:38:06 +0000 (UTC)
commit 5c633bac9183888475cbcbbde68f6886c99ba7ad
Author: Robert Roth <robert roth off gmail com>
Date: Mon Jan 12 05:13:48 2015 +0200
Board: ported selector methods to plain gtk
src/board_gtk.c | 387 ++++++++++++++++++++++++++++++++++++++++++++++-----
src/canvas_helper.c | 2 +-
src/canvas_helper.h | 2 +-
3 files changed, 354 insertions(+), 37 deletions(-)
---
diff --git a/src/board_gtk.c b/src/board_gtk.c
index 322fe29..8da0ded 100644
--- a/src/board_gtk.c
+++ b/src/board_gtk.c
@@ -35,6 +35,22 @@ typedef struct
double y_step;
} AnimData;
+typedef struct
+{
+ guint row;
+ guint col;
+ gboolean selected;
+ gint arrow_show_timeout;
+ gint mouse_steering;
+ GtkWidget *sel_item;
+ GtkWidget *selector;
+ GSList *arrows;
+ GtkWidget *arrow_left;
+ GtkWidget *arrow_right;
+ GtkWidget *arrow_top;
+ GtkWidget *arrow_bottom;
+} SelectorData;
+
typedef enum
{
UP,
@@ -45,10 +61,7 @@ typedef enum
typedef struct
{
- GSList *level;
- GSList *obstacles;
GSList *moveables;
- GSList *shadows;
} LevelItems;
@@ -63,6 +76,7 @@ static AnimData *anim_data; /* holds the date for the atom
static GSList *board_canvas_items = NULL; /* a list of all used */
static Goal *board_goal = NULL; /* the goal of this level */
static LevelItems *level_items; /* references to the level groups */
+static SelectorData *selector_data; /* data about the selector */
/* Forward declarations of internal functions */
@@ -70,8 +84,102 @@ void board_gtk_render (void);
static void render_tile (Tile *tile, gint row, gint col);
GtkImage* create_tile (double x, double y, Tile *tile);
+static void selector_move_to (SelectorData *data, guint row, guint col);
+static void selector_unselect (SelectorData *data);
+static void selector_select (SelectorData *data, GtkWidget *item);
+static SelectorData *selector_create (void);
+static void selector_hide (SelectorData *data);
+static void selector_show (SelectorData *data);
+static void selector_arrows_hide (SelectorData *data);
+
/* Function implementations */
+
+static void get_row_col_by_item (GtkWidget *item, guint *row, guint *col)
+{
+ gint x, y;
+
+ g_return_if_fail (GTK_IS_WIDGET (item));
+
+ gtk_container_child_get (GTK_CONTAINER (board_canvas), item, "x", &x, "y", &y, NULL);
+
+ convert_to_playfield (board_theme, x, y, row, col);
+}
+
+static gboolean board_handle_arrow_event (GtkWidget *item,
+ GdkEvent *event, gpointer direction)
+{
+ /* is currently an object moved? */
+ if (anim_data->timeout_id != -1)
+ return FALSE;
+
+ if (event->type == GDK_BUTTON_PRESS && selector_data->selected)
+ {
+ selector_data->mouse_steering = TRUE;
+// move_item (selector_data->sel_item, GPOINTER_TO_INT (direction));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static SelectorData *selector_create (void)
+{
+ SelectorData *data;
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *sel_arrows[4];
+ gint tile_width, tile_height;
+
+ data = g_new0 (SelectorData, 1);
+
+ pixbuf = theme_get_selector_image (board_theme);
+ theme_get_selector_arrow_images (board_theme, &sel_arrows[0]);
+ theme_get_tile_size (board_theme, &tile_width, &tile_height);
+
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+
+ data->row = 0;
+ data->col = 0;
+ data->sel_item = NULL;
+ data->selected = FALSE;
+ data->arrow_show_timeout = -1;
+ data->mouse_steering = FALSE;
+
+ data->selector = gtk_image_new_from_pixbuf (pixbuf);
+
+ data->arrow_top = gtk_image_new_from_pixbuf (sel_arrows[0]);
+
+ g_signal_connect (G_OBJECT (data->arrow_top), "event",
+ G_CALLBACK (board_handle_arrow_event),
+ GINT_TO_POINTER (UP));
+
+ data->arrow_right = gtk_image_new_from_pixbuf (sel_arrows[1]);
+
+ g_signal_connect (G_OBJECT (data->arrow_right), "event",
+ G_CALLBACK (board_handle_arrow_event),
+ GINT_TO_POINTER (RIGHT));
+
+ data->arrow_bottom = gtk_image_new_from_pixbuf (sel_arrows[3]);
+
+ g_signal_connect (G_OBJECT (data->arrow_bottom), "event",
+ G_CALLBACK (board_handle_arrow_event),
+ GINT_TO_POINTER (DOWN));
+
+ data->arrow_left = gtk_image_new_from_pixbuf (sel_arrows[3]);
+
+ g_signal_connect (G_OBJECT (data->arrow_left), "event",
+ G_CALLBACK (board_handle_arrow_event),
+ GINT_TO_POINTER (LEFT));
+ gtk_fixed_put (GTK_FIXED (board_canvas), data->selector, 0, 0);
+ gtk_fixed_put (GTK_FIXED (board_canvas), data->arrow_left, 0, 0);
+ gtk_fixed_put (GTK_FIXED (board_canvas), data->arrow_right, 0, 0);
+ gtk_fixed_put (GTK_FIXED (board_canvas), data->arrow_top, 0, 0);
+ gtk_fixed_put (GTK_FIXED (board_canvas), data->arrow_bottom, 0, 0);
+
+ return data;
+}
+
static void create_background_floor (void)
{
int row, col;
@@ -152,8 +260,9 @@ void board_gtk_init (Theme * theme, gpointer canvas)
g_signal_connect (G_OBJECT (canvas), "key_press_event",
G_CALLBACK (board_gtk_handle_key_event), NULL);
- create_background_floor ();
+ //create_background_floor ();
gtk_widget_show_all (GTK_WIDGET(board_canvas));
+ selector_data = selector_create ();
}
void board_gtk_render () {
@@ -199,7 +308,7 @@ static void render_tile (Tile *tile, gint row, gint col) {
gboolean create = FALSE;
TileType type;
gint row_offset, col_offset;
- gdouble x, y;
+ gint x, y;
type = tile_get_tile_type (tile);
switch (type) {
@@ -230,14 +339,51 @@ static void render_tile (Tile *tile, gint row, gint col) {
}
}
+static gboolean show_arrow_group (SelectorData *data)
+{
+ g_slist_foreach (data->arrows, (GFunc)gtk_widget_show, NULL);
+ data->arrow_show_timeout = -1;
+
+ return FALSE;
+}
+
+
+static gboolean board_handle_item_event (GtkWidget *item,
+ GdkEvent *event, gpointer data) {
+ gboolean just_unselect;
+ guint new_row, new_col;
+ printf ("Item event\n");
+ /* is currently an object moved? */
+ if (anim_data->timeout_id != -1)
+ return FALSE;
+
+ if (event->type == GDK_BUTTON_PRESS) {
+ printf ("Button press\n");
+ selector_data->mouse_steering = TRUE;
+ just_unselect = (item == selector_data->sel_item);
+
+ if (selector_data->selected)
+ /* unselect item, show selector image */
+ selector_unselect (selector_data);
+
+ if (!just_unselect) {
+ get_row_col_by_item (item, &new_row, &new_col);
+ selector_move_to (selector_data, new_row, new_col);
+ selector_select (selector_data, item);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
GtkImage* create_tile (double x, double y,
Tile *tile)
{
GdkPixbuf *pixbuf = NULL;
GtkWidget *item = NULL;
- TileType type;
- type = tile_get_tile_type (tile);
pixbuf = theme_get_tile_image (board_theme, tile);
item = gtk_image_new_from_pixbuf (pixbuf);
@@ -247,33 +393,13 @@ GtkImage* create_tile (double x, double y,
g_object_set_data (G_OBJECT (item), "tile", tile);
// TODO handle button click
-// if (tile_get_tile_type (tile) == TILE_TYPE_ATOM)
-// {
-// g_signal_connect (G_OBJECT (item), "event",
-// G_CALLBACK (board_handle_item_event), NULL);
-// }
+ if (tile_get_tile_type (tile) == TILE_TYPE_ATOM) {
+ printf ("Adding button event handler\n");
+ g_signal_connect (G_OBJECT (item), "button-press-event",
+ G_CALLBACK (board_handle_item_event), NULL);
+ }
board_canvas_items = g_slist_prepend (board_canvas_items, item);
- switch (type)
- {
- case TILE_TYPE_ATOM:
- level_items->moveables = g_slist_prepend (level_items->moveables, item);
- break;
-
- case TILE_TYPE_WALL:
- level_items->obstacles = g_slist_prepend (level_items->obstacles, item);
- break;
-
- case TILE_TYPE_SHADOW:
- level_items->shadows = g_slist_prepend (level_items->shadows, item);
- break;
-
- case TILE_TYPE_UNKNOWN:
- case TILE_TYPE_FLOOR:
- default:
- break;
- }
-
return GTK_IMAGE (item);
}
@@ -292,13 +418,13 @@ static void remove_items (GSList **list)
static void level_clear (void)
{
- remove_items (&(level_items->moveables));
- remove_items (&(level_items->obstacles));
- remove_items (&(level_items->shadows));
+ remove_items (&(board_canvas_items));
}
void board_gtk_init_level (PlayField * base_env, PlayField * sce, Goal * goal)
{
+ gint row, col;
+
/* init item anim structure */
anim_data->timeout_id = -1;
anim_data->counter = 0;
@@ -320,6 +446,13 @@ void board_gtk_init_level (PlayField * base_env, PlayField * sce, Goal * goal)
/* init goal */
board_goal = g_object_ref (goal);
+ /* init selector */
+ row = playfield_get_n_rows (board_env) / 2;
+ col = playfield_get_n_cols (board_env) / 2;
+ selector_hide (selector_data);
+ selector_move_to (selector_data, row, col);
+ selector_unselect (selector_data);
+
/* render level */
board_gtk_render ();
board_gtk_show ();
@@ -327,6 +460,23 @@ void board_gtk_init_level (PlayField * base_env, PlayField * sce, Goal * goal)
void board_gtk_destroy (void)
{
+ g_slist_free_full (board_canvas_items, (GDestroyNotify)gtk_widget_destroy);
+
+ if (board_env)
+ g_object_unref (board_env);
+ if (board_sce)
+ g_object_unref (board_sce);
+ if (anim_data)
+ g_free (anim_data);
+
+ undo_clear ();
+
+ if (board_theme)
+ g_object_unref (board_theme);
+
+ if (board_goal)
+ g_object_unref (board_goal);
+
}
void board_gtk_clear (void)
@@ -359,3 +509,170 @@ void board_gtk_handle_key_event (GObject * canvas, GdkEventKey * event,
{
}
+
+static void selector_move_to (SelectorData *data, guint row, guint col)
+{
+ int tile_width, tile_height;
+ int x, y;
+
+ int row_offset = BGR_FLOOR_ROWS / 2 - playfield_get_n_rows (board_env) / 2;
+ int col_offset = BGR_FLOOR_COLS / 2 - playfield_get_n_cols (board_env) / 2;
+
+ g_return_if_fail (data != NULL);
+
+ if (data->arrow_show_timeout > -1)
+ g_source_remove (data->arrow_show_timeout);
+
+ data->arrow_show_timeout = -1;
+
+ theme_get_tile_size (board_theme, &tile_width, &tile_height);
+
+ convert_to_canvas (board_theme, row+row_offset, col+col_offset, &x, &y);
+
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->selector, x, y);
+
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->selector, x, y);
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->arrow_left, x - tile_width, y);
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->arrow_right, x + tile_width, y);
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->arrow_top, x, y - tile_width);
+ gtk_fixed_move (GTK_FIXED (board_canvas), data->arrow_bottom, x, y + tile_width);
+
+ data->row = row;
+ data->col = col;
+}
+
+static void selector_arrows_show (SelectorData *data)
+{
+ gint r, c;
+ Tile *tile;
+
+ if (board_sce == NULL)
+ {
+ selector_arrows_hide (data);
+ return;
+ }
+
+ r = data->row - 1;
+ c = data->col;
+ if (r >= 0)
+ {
+ tile = playfield_get_tile (board_sce, r, c);
+
+ if (tile == NULL)
+ gtk_widget_show (data->arrow_top);
+
+ else
+ {
+ gtk_widget_hide (data->arrow_top);
+ g_object_unref (tile);
+ }
+ }
+
+ r = data->row;
+ c = data->col + 1;
+
+ if (c < playfield_get_n_cols (board_sce))
+ {
+ tile = playfield_get_tile (board_sce, r, c);
+
+ if (tile == NULL)
+ gtk_widget_show (data->arrow_right);
+ else
+ {
+ gtk_widget_hide (data->arrow_right);
+ g_object_unref (tile);
+ }
+ }
+
+ r = data->row + 1;
+ c = data->col;
+
+ if (r < playfield_get_n_rows (board_sce))
+ {
+ tile = playfield_get_tile (board_sce, r, c);
+
+ if (tile == NULL)
+ gtk_widget_show (data->arrow_bottom);
+ else
+ {
+ gtk_widget_hide (data->arrow_bottom);
+ g_object_unref (tile);
+ }
+ }
+
+ r = data->row;
+ c = data->col - 1;
+
+ if (c >= 0)
+ {
+ tile = playfield_get_tile (board_sce, r, c);
+
+ if (tile == NULL)
+ gtk_widget_show (data->arrow_left);
+
+ else
+ {
+ gtk_widget_hide (data->arrow_left);
+ g_object_unref (tile);
+ }
+ }
+
+ if (data->mouse_steering)
+ {
+ show_arrow_group (data);
+ }
+
+ else
+ {
+ if (data->arrow_show_timeout > -1)
+ g_source_remove (data->arrow_show_timeout);
+
+ data->arrow_show_timeout =
+ g_timeout_add (800, (GSourceFunc) show_arrow_group, data);
+ }
+}
+
+static void selector_select (SelectorData *data, GtkWidget *item)
+{
+ g_return_if_fail (data != NULL);
+
+ data->selected = TRUE;
+ data->sel_item = item;
+
+ gtk_widget_hide (data->selector);
+ selector_arrows_show (data);
+}
+
+static void selector_unselect (SelectorData *data)
+{
+ g_return_if_fail (data != NULL);
+
+ data->selected = FALSE;
+ data->sel_item = NULL;
+
+ if (!data->mouse_steering)
+ selector_show (data);
+
+ selector_arrows_hide (data);
+}
+
+static void selector_arrows_hide (SelectorData *data)
+{
+ if (data->arrow_show_timeout > -1)
+ g_source_remove (data->arrow_show_timeout);
+ data->arrow_show_timeout = -1;
+
+ g_slist_foreach (data->arrows, (GFunc)gtk_widget_hide, NULL);
+}
+
+static void selector_hide (SelectorData *data)
+{
+ gtk_widget_hide (data->selector);
+ selector_arrows_hide (data);
+}
+
+static void selector_show (SelectorData *data)
+{
+ gtk_widget_show (data->selector);
+}
+
diff --git a/src/canvas_helper.c b/src/canvas_helper.c
index e562f20..61241b1 100644
--- a/src/canvas_helper.c
+++ b/src/canvas_helper.c
@@ -36,7 +36,7 @@ void convert_to_playfield (Theme *theme, gdouble x, gdouble y,
}
void convert_to_canvas (Theme *theme, guint row, guint col,
- gdouble *x, gdouble *y)
+ gint *x, gint *y)
{
gint tile_width, tile_height;
diff --git a/src/canvas_helper.h b/src/canvas_helper.h
index 51e6214..cd7ed67 100644
--- a/src/canvas_helper.h
+++ b/src/canvas_helper.h
@@ -25,6 +25,6 @@ void convert_to_playfield (Theme * theme, gdouble x, gdouble y,
guint * row, guint * col);
void convert_to_canvas (Theme * theme, guint row, guint col,
- gdouble * x, gdouble * y);
+ gint * x, gint * y);
#endif /* _ATOMIX_CANVAS_HELPER_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]