gst/games/gstpuzzle.c: - handle nav events differently: forward every event no matter if it was handled or not.

Original commit message from CVS:
* gst/games/gstpuzzle.c: (nav_event_handler):
- handle nav events differently: forward every event no matter if it
was handled or not.
- translate events
You can now cheat by using navigationtest ! puzzle and moving the
mouse close to the edge of a tile. ;)
This commit is contained in:
Benjamin Otte 2005-01-08 18:27:07 +00:00
parent 6de8ef1c42
commit d94ba1f15a
2 changed files with 58 additions and 28 deletions

View file

@ -1,3 +1,12 @@
2005-01-08 Benjamin Otte <otte@gnome.org>
* gst/games/gstpuzzle.c: (nav_event_handler):
- handle nav events differently: forward every event no matter if it
was handled or not.
- translate events
You can now cheat by using navigationtest ! puzzle and moving the
mouse close to the edge of a tile. ;)
2005-01-08 Ronald S. Bultje <rbultje@ronald.bitfreak.net> 2005-01-08 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* configure.ac: * configure.ac:

View file

@ -293,18 +293,60 @@ gst_puzzle_shuffle (GstPuzzle * puzzle)
puzzle->solved = FALSE; puzzle->solved = FALSE;
} }
/* The nav event handler handles nav events, but still forwards them, so you
* should be able to even use puzzle while navigating a dvd menu. We return
* TRUE of course even when noone downstream handles the event.
*/
static gboolean static gboolean
nav_event_handler (GstPad * pad, GstEvent * event) nav_event_handler (GstPad * pad, GstEvent * event)
{ {
GstPuzzle *puzzle; GstPuzzle *puzzle;
GstVideofilter *filter; GstVideofilter *filter;
const gchar *type; const gchar *type;
gboolean result = FALSE;
gdouble x, y;
gint xpos = 0, ypos = 0;
puzzle = GST_PUZZLE (gst_pad_get_parent (pad)); puzzle = GST_PUZZLE (gst_pad_get_parent (pad));
filter = GST_VIDEOFILTER (puzzle); filter = GST_VIDEOFILTER (puzzle);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NAVIGATION: case GST_EVENT_NAVIGATION:
/* translate the event */
if (gst_structure_get_double (event->event_data.structure.structure,
"pointer_x", &x) &&
gst_structure_get_double (event->event_data.structure.structure,
"pointer_y", &y)) {
gint width, height;
width = gst_videofilter_get_input_width (filter);
height = gst_videofilter_get_input_height (filter);
width = (width / puzzle->columns) & ~3;
height = (height / puzzle->rows) & ~3;
xpos = (int) x / width;
ypos = (int) y / height;
if (xpos >= 0 && xpos < puzzle->columns && ypos >= 0
&& ypos < puzzle->rows) {
GstEvent *copy;
guint lookup;
lookup = puzzle->permutation[ypos * puzzle->columns + xpos];
GST_DEBUG_OBJECT (puzzle, "translated %dx%d (%gx%g) to %dx%d (%gx%g)",
xpos, ypos, x, y,
lookup % puzzle->columns, lookup / puzzle->columns,
x + ((gint) (lookup % puzzle->columns) - xpos) * width,
y + ((gint) (lookup / puzzle->columns) - ypos) * height);
x += ((gint) (lookup % puzzle->columns) - xpos) * width;
y += ((gint) (lookup / puzzle->columns) - ypos) * height;
copy = gst_event_copy (event);
gst_structure_set (copy->event_data.structure.structure,
"pointer_x", G_TYPE_DOUBLE, x,
"pointer_y", G_TYPE_DOUBLE, y, NULL);
gst_event_unref (event);
event = copy;
}
}
/* handle the event. NOTE: it has already been translated! */
type = gst_structure_get_string (event->event_data.structure.structure, type = gst_structure_get_string (event->event_data.structure.structure,
"event"); "event");
if (g_str_equal (type, "key-press")) { if (g_str_equal (type, "key-press")) {
@ -329,58 +371,37 @@ nav_event_handler (GstPad * pad, GstEvent * event)
gst_puzzle_move (puzzle, DIR_UP); gst_puzzle_move (puzzle, DIR_UP);
} else if (g_str_equal (key, "Down")) { } else if (g_str_equal (key, "Down")) {
gst_puzzle_move (puzzle, DIR_DOWN); gst_puzzle_move (puzzle, DIR_DOWN);
} else {
break;
} }
} }
puzzle->solved = gst_puzzle_is_solved (puzzle); puzzle->solved = gst_puzzle_is_solved (puzzle);
gst_event_unref (event);
return TRUE;
} else if (g_str_equal (type, "mouse-button-press")) { } else if (g_str_equal (type, "mouse-button-press")) {
gint button; gint button;
if (gst_structure_get_int (event->event_data.structure.structure, if (gst_structure_get_int (event->event_data.structure.structure,
"button", &button)) { "button", &button)) {
if (button == 1) { if (button == 1) {
gdouble x, y;
if (gst_structure_get_double (event->event_data.structure.structure,
"pointer_x", &x) &&
gst_structure_get_double (event->event_data.structure.structure,
"pointer_y", &y)) {
gint xpos, ypos;
xpos =
(int) x / ((gst_videofilter_get_input_width (filter) /
puzzle->columns) & ~3);
ypos =
(int) y / ((gst_videofilter_get_input_height (filter) /
puzzle->rows) & ~3);
if (xpos >= 0 && xpos < puzzle->columns && ypos >= 0 if (xpos >= 0 && xpos < puzzle->columns && ypos >= 0
&& ypos < puzzle->rows) { && ypos < puzzle->rows && !puzzle->solved) {
gst_puzzle_swap (puzzle, ypos * puzzle->columns + xpos); gst_puzzle_swap (puzzle, ypos * puzzle->columns + xpos);
}
puzzle->solved = gst_puzzle_is_solved (puzzle); puzzle->solved = gst_puzzle_is_solved (puzzle);
gst_event_unref (event);
return TRUE;
} }
} else if (button == 2) { } else if (button == 2) {
if (gst_puzzle_is_solved (puzzle)) { if (puzzle->solved) {
gst_puzzle_shuffle (puzzle); gst_puzzle_shuffle (puzzle);
} else { } else {
gst_puzzle_solve (puzzle); gst_puzzle_solve (puzzle);
} }
puzzle->solved = gst_puzzle_is_solved (puzzle); puzzle->solved = gst_puzzle_is_solved (puzzle);
gst_event_unref (event);
return TRUE;
} }
} }
} }
/* FIXME: only return TRUE for events we handle? */
result = TRUE;
break; break;
default: default:
break; break;
} }
return gst_pad_event_default (pad, event); return gst_pad_event_default (pad, event) || result;
} }
static void static void