[gnome-games] swap pieces if placed on existing piece and animate moves (Dan Whitman, Bug #500957)
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] swap pieces if placed on existing piece and animate moves (Dan Whitman, Bug #500957)
- Date: Fri, 2 Apr 2010 07:27:03 +0000 (UTC)
commit e29a19fcd6435770fbe2b5c28de314457c129a5d
Author: Robert Ancell <robert ancell gmail com>
Date: Fri Apr 2 18:22:48 2010 +1100
swap pieces if placed on existing piece and animate moves (Dan Whitman, Bug #500957)
glchess/src/lib/gtkui/chessview.py | 2 -
glchess/src/lib/gtkui/dialogs.py | 9 -
glchess/src/lib/gtkui/gtkui.py | 23 --
glchess/src/lib/gtkui/network.py | 1 -
gnotravex/gnotravex.c | 397 +++++++++++++++++++++++-------------
5 files changed, 254 insertions(+), 178 deletions(-)
---
diff --git a/glchess/src/lib/gtkui/chessview.py b/glchess/src/lib/gtkui/chessview.py
index 7768728..4065893 100644
--- a/glchess/src/lib/gtkui/chessview.py
+++ b/glchess/src/lib/gtkui/chessview.py
@@ -261,8 +261,6 @@ class GtkView(glchess.ui.ViewController):
self.viewWidget = GtkViewArea(self)
self.gui.get_object('view_container').add(self.viewWidget)
- self.ui.setTooltipStyle(self.gui.get_object('info_panel'))
-
# Make a model for navigation (move object, number, description)
model = gtk.ListStore(gobject.TYPE_PYOBJECT, int, str)
iter = model.append()
diff --git a/glchess/src/lib/gtkui/dialogs.py b/glchess/src/lib/gtkui/dialogs.py
index d8ca8f1..3cdc5b9 100644
--- a/glchess/src/lib/gtkui/dialogs.py
+++ b/glchess/src/lib/gtkui/dialogs.py
@@ -96,9 +96,6 @@ class GtkNewGameDialog:
self.window = self.__gui.get_object('new_game_dialog')
self.window.set_transient_for(mainUI.mainWindow)
- # Set style of error panel
- mainUI.setTooltipStyle(self.__gui.get_object('info_box'))
-
# Make all the labels the same width
group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
i = 1
@@ -425,9 +422,6 @@ class GtkLoadGameDialog:
self.window = self.__gui.get_object('game_load_dialog')
self.window.set_transient_for(mainUI.mainWindow)
- # Set style of error panel
- mainUI.setTooltipStyle(self.__gui.get_object('error_box'))
-
fileChooser = self.__gui.get_object('filechooserwidget')
try:
@@ -498,9 +492,6 @@ class GtkSaveGameDialog:
self.__gui = gtkui.loadUIFile('save_game.ui')
self.__gui.connect_signals(self)
- # Set style of error panel
- mainUI.setTooltipStyle(self.__gui.get_object('error_box'))
-
self.window = self.__gui.get_object('save_dialog')
self.window.set_transient_for(mainUI.mainWindow)
chooser = self.__gui.get_object('filechooser')
diff --git a/glchess/src/lib/gtkui/gtkui.py b/glchess/src/lib/gtkui/gtkui.py
index c57697f..689abdc 100644
--- a/glchess/src/lib/gtkui/gtkui.py
+++ b/glchess/src/lib/gtkui/gtkui.py
@@ -231,30 +231,7 @@ class GtkUI(glchess.ui.UI):
glchess.config.watch(key, self.__applyConfig)
# Public methods
-
- def setTooltipStyle(self, widget):
- """Set a widget to be in the tooltip style.
-
- 'widget' is the widget to modify.
- """
- if self._tooltipStyle is None:
- return
- widget.set_style(self._tooltipStyle)
- widget.connect("expose_event", self._on_tooltip_expose_event)
- widget.queue_draw()
- def _on_tooltip_expose_event(self, widget, event):
- """Gtk+ callback"""
- allocation = widget.allocation
- widget.style.paint_flat_box(widget.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None, widget, "tooltip",
- allocation.x, allocation.y, allocation.width, allocation.height)
-
- # The first draw is corrupt for me so draw it twice.
- # Bonus points to anyone who tracks down the problem and fixes it
- if not self._tooltipWidgetsDrawn.has_key(widget):
- self._tooltipWidgetsDrawn[widget] = True
- widget.queue_draw()
-
def watchFileDescriptor(self, fd):
"""Extends ui.UI"""
self._watches[fd] = gobject.io_add_watch(fd, gobject.IO_IN | gobject.IO_PRI | gobject.IO_HUP | gobject.IO_ERR, self.__readData)
diff --git a/glchess/src/lib/gtkui/network.py b/glchess/src/lib/gtkui/network.py
index cbf3381..dc265d2 100644
--- a/glchess/src/lib/gtkui/network.py
+++ b/glchess/src/lib/gtkui/network.py
@@ -217,7 +217,6 @@ class GtkNetworkGameDialog(glchess.ui.NetworkController):
#buffer.create_tag('error', family='Monospace', foreground = 'red')
buffer.create_mark('end', buffer.get_end_iter())
- mainUI.setTooltipStyle(self.__gui.get_object('info_panel'))
self.__addProfileDialog = GtkNetworkAddDialog(self, self.__gui.get_object('network_game_dialog'))
# Extended methods
diff --git a/gnotravex/gnotravex.c b/gnotravex/gnotravex.c
index ad9fde3..b985ea1 100644
--- a/gnotravex/gnotravex.c
+++ b/gnotravex/gnotravex.c
@@ -99,16 +99,6 @@ static int gap;
static GdkPixmap *buffer = NULL;
-typedef struct _mover {
- GdkWindow *window;
- GdkPixmap *pixmap;
- gint xstart, ystart;
- gint xtarget, ytarget;
- gint xoff, yoff;
-} Mover;
-
-static Mover mover;
-
typedef struct _tile {
gint n, w, e, s;
gint status;
@@ -117,6 +107,20 @@ typedef struct _tile {
static tile tiles[9][18];
static tile orig_tiles[9][9];
+typedef struct _mover {
+ GdkWindow *window;
+ GdkPixmap *pixmap;
+ tile heldtile;
+ gint xstart, ystart;
+ gint xend, yend;
+ gint xoff, yoff;
+ gint x, y;
+} Mover;
+
+static GdkWindowAttr windowattrib;
+static Mover mousemover;
+static Mover automover;
+
enum {
gameover,
paused,
@@ -127,7 +131,7 @@ static gint size = -1;
static gint game_state = gameover;
static gint have_been_hinted = 0;
static gint solve_me = 0;
-static gint hint_moving = 0;
+static gint moving = 0;
static gint session_xpos = 0;
static gint session_ypos = 0;
static guint timer_timeout = 0;
@@ -211,7 +215,7 @@ static gdouble tile_colours[11][4][4] = {
void make_buffer (GtkWidget *);
void create_window (void);
GtkWidget *create_menu (GtkUIManager *);
-void create_mover (void);
+void init_window_attrib (void);
GtkWidget *create_statusbar (void);
GdkPixmap *default_background_pixmap;
@@ -229,7 +233,7 @@ void gui_draw_socket (GdkPixmap * target, GtkStateType state, gint xadd,
void gui_draw_number (cairo_t * context, gdouble x, gdouble y, guint number, gdouble *colour);
void gui_draw_tile (GdkPixmap * target, GtkStateType state, gint xadd,
gint yadd, gint north, gint south, gint east, gint west, gboolean prelight);
-void gui_draw_pixmap (GdkPixmap *, gint, gint, gboolean);
+void gui_draw_pixmap (GdkPixmap *, gint, gint, gboolean, Mover*);
void get_pixeltilexy (gint, gint, gint *, gint *);
void get_tilexy (gint, gint, gint *, gint *);
@@ -239,8 +243,13 @@ void message (gchar *);
void new_board (gint);
void redraw_all (void);
void redraw_left (void);
-gint setup_mover (gint, gint, gint);
-gint valid_drop (gint, gint);
+gint setup_mover (gint, gint, Mover*);
+void clear_mover(Mover*);
+void release_tile (gint, gint);
+void place_tile (gint, gint);
+void tile_tilexy (gint, gint, gint*, gint*);
+void swap_without_validation (gint, gint, gint, gint);
+gint valid_drop (gint, gint, gint, gint);
void update_tile_size (gint, gint);
gboolean configure_space (GtkWidget *, GdkEventConfigure *);
@@ -255,9 +264,11 @@ void timer_start (void);
void pause_game (void);
void resume_game (void);
void pause_cb (void);
-void hint_move_cb (void);
+void move_cb (void);
void clickmove_toggle_cb (GtkToggleAction *, gpointer);
void hint_move (gint, gint, gint, gint);
+void move_tile_animate (gint, gint, gint, gint, gboolean);
+void move_held_animate (gint, gint, gint, gint);
gint show_score_dialog (gint, gboolean);
void new_game (void);
@@ -528,7 +539,7 @@ main (int argc, char **argv)
gtk_window_move (GTK_WINDOW (window), session_xpos, session_ypos);
gtk_widget_show_all (window);
- create_mover ();
+ init_window_attrib ();
gtk_action_activate (new_game_action);
@@ -637,13 +648,13 @@ button_press_space (GtkWidget * widget, GdkEventButton * event)
{
if (button_down)
{
- setup_mover (event->x,event->y, RELEASE); /* Seen it happened */
+ release_tile (event->x,event->y); /* Seen it happened */
button_down = 0;
return FALSE;
}
else
{
- if (setup_mover (event->x, event->y, PRESS))
+ if (setup_mover (event->x, event->y, &mousemover))
button_down = 1;
}
}
@@ -651,11 +662,11 @@ button_press_space (GtkWidget * widget, GdkEventButton * event)
{
if (button_down == 1)
{
- setup_mover (event->x,event->y, RELEASE); /* Seen it happened */
+ release_tile (event->x,event->y); /* Seen it happened */
button_down = 0;
return FALSE;
}
- if (setup_mover (event->x, event->y, PRESS))
+ if (setup_mover (event->x, event->y, &mousemover))
button_down = 1;
}
@@ -671,7 +682,7 @@ button_release_space (GtkWidget * widget, GdkEventButton * event)
if (event->button == 1) {
if (button_down == 1) {
- setup_mover (event->x, event->y, RELEASE);
+ release_tile (event->x, event->y);
}
button_down = 0;
}
@@ -937,30 +948,38 @@ button_motion_space (GtkWidget * widget, GdkEventButton * event)
return FALSE;
if (button_down == 1) {
- x = event->x - mover.xoff;
- y = event->y - mover.yoff;
- gdk_window_move (mover.window, x, y);
- gdk_window_clear (mover.window);
- } else {
- /* This code hilights pieces as the mouse moves over them
- * in general imitation of "prelight" in GTK. */
+ mousemover.x = event->x;
+ mousemover.y = event->y;
+ x = event->x - mousemover.xoff;
+ y = event->y - mousemover.yoff;
+ gdk_window_move (mousemover.window, x, y);
+ gdk_window_clear (mousemover.window);
+ }
+
+ /* This code hilights pieces as the mouse moves over them
+ * in general imitation of "prelight" in GTK. Need to highlight
+ * differently depending on if we are holding a tile or not */
+ if(mousemover.window == NULL)
get_tilexy (event->x, event->y, &x, &y);
- if ((x != oldx) || (y != oldy)) {
- if ((oldx != -1) && (tiles[oldy][oldx].status == USED)) {
- gui_draw_pixmap (buffer, oldx, oldy, FALSE);
- }
- if ((x != -1) && (tiles[y][x].status == USED)) {
- gui_draw_pixmap (buffer, x, y, TRUE);
- }
- oldx = x;
- oldy = y;
+ else
+ tile_tilexy (event->x, event->y, &x, &y);
+
+ if ((x != oldx) || (y != oldy)) {
+ if ((oldx != -1) && (tiles[oldy][oldx].status == USED)) {
+ gui_draw_pixmap (buffer, oldx, oldy, FALSE, NULL);
}
+ if ((x != -1) && (tiles[y][x].status == USED)) {
+ gui_draw_pixmap (buffer, x, y, TRUE, NULL);
+ }
+ oldx = x;
+ oldy = y;
}
+
return FALSE;
}
void
-gui_draw_pixmap (GdkPixmap * target, gint x, gint y, gboolean prelight)
+gui_draw_pixmap (GdkPixmap * target, gint x, gint y, gboolean prelight, Mover *mover)
{
gint which, xadd = 0, yadd = 0;
GtkStateType state;
@@ -973,10 +992,10 @@ gui_draw_pixmap (GdkPixmap * target, gint x, gint y, gboolean prelight)
yadd = y * tile_size + yborder;
}
- if (target == mover.pixmap) {
+ if (mover != NULL && target == mover->pixmap) {
xadd = 0;
yadd = 0;
- gdk_window_set_back_pixmap (mover.window, mover.pixmap, 0);
+ gdk_window_set_back_pixmap (mover->window, mover->pixmap, 0);
state = GTK_STATE_PRELIGHT;
}
@@ -1021,6 +1040,16 @@ get_tilexy_lazy (gint x, gint y, gint * xx, gint * yy)
else
*xx = size + (x - (gap + tile_size * size)) / tile_size;
*yy = (y / tile_size);
+
+ /* Bounds checking */
+ if (*xx < 0)
+ *xx = 0;
+ else if (*xx >= size * 2)
+ *xx = size * 2 - 1;
+ if (y < 0)
+ *yy = 0;
+ else if (*yy >= size)
+ *yy = size - 1;
}
void
@@ -1064,93 +1093,134 @@ get_offsetxy (gint x, gint y, gint * xoff, gint * yoff)
}
gint
-setup_mover (gint x, gint y, gint status)
+setup_mover (gint x, gint y, Mover *mover)
{
gint xx, yy;
- if (status == PRESS) {
- get_tilexy (x, y, &xx, &yy);
- if (xx == -1)
- return 0; /* No move */
- if (tiles[yy][xx].status == UNUSED)
- return 0; /* No move */
- get_offsetxy (x, y, &mover.xoff, &mover.yoff);
-
- mover.xstart = xx;
- mover.ystart = yy;
- gdk_window_resize (mover.window, tile_size, tile_size);
- /* We assume elsewhere that this has the same depth as the parent. */
- mover.pixmap = gdk_pixmap_new (mover.window, tile_size, tile_size, -1);
-
- gdk_window_move (mover.window, x - mover.xoff, y - mover.yoff);
- gui_draw_pixmap (mover.pixmap, xx, yy, FALSE);
- gdk_window_show (mover.window);
-
- tiles[yy][xx].status = UNUSED;
- gui_draw_pixmap (buffer, xx, yy, FALSE);
- return 1;
+ get_tilexy (x, y, &xx, &yy);
+ if (xx == -1)
+ return 0; /* No move */
+ if (tiles[yy][xx].status == UNUSED)
+ return 0; /* No move */
+ get_offsetxy (x, y, &mover->xoff, &mover->yoff);
+
+ mover->heldtile = tiles[yy][xx];
+ mover->xstart = xx;
+ mover->ystart = yy;
+
+ clear_mover(mover);
+
+ /* We assume elsewhere that this has the same depth as the parent. */
+ windowattrib.width = tile_size;
+ windowattrib.height = tile_size;
+ mover->window = gdk_window_new (gtk_widget_get_window (space), &windowattrib, (GDK_WA_VISUAL | GDK_WA_COLORMAP));
+ mover->pixmap = gdk_pixmap_new (mover->window, tile_size, tile_size, -1);
+ gdk_window_move (mover->window, x - mover->xoff, y - mover->yoff);
+ gui_draw_pixmap (mover->pixmap, xx, yy, FALSE, mover);
+ gdk_window_show(mover->window);
+ /* Show held tile on top if swapping */
+ if(mover == &automover && mousemover.window != NULL)
+ gdk_window_show(mousemover.window);
+
+ tiles[yy][xx].status = UNUSED;
+ gui_draw_pixmap (buffer, xx, yy, FALSE, NULL);
+ return 1;
+}
+
+void
+clear_mover(Mover* mover)
+{
+ if(mover->window != NULL)
+ gdk_window_destroy(mover->window);
+ mover->window = NULL;
+ if (mover->pixmap)
+ g_object_unref (mover->pixmap);
+ mover->pixmap = NULL;
+}
+
+void
+release_tile(gint x, gint y) {
+ gint xx, yy;
+
+ tile_tilexy (x, y, &xx, &yy);
+ if (xx >= 0 && xx < size * 2 && yy >= 0 && yy < size) {
+ if (tiles[yy][xx].status == UNUSED && valid_drop (mousemover.xstart, mousemover.ystart, xx, yy)) {
+ move_held_animate (x, y, xx, yy);
+ return;
+ } else if (tiles[yy][xx].status == USED) {
+ swap_without_validation(xx, yy, mousemover.xstart, mousemover.ystart);
+ if(valid_drop (xx, yy, xx, yy) && valid_drop (mousemover.xstart, mousemover.ystart, mousemover.xstart, mousemover.ystart)) {
+ swap_without_validation (xx, yy, mousemover.xstart, mousemover.ystart);
+ move_tile_animate (xx, yy, mousemover.xstart, mousemover.ystart, TRUE);
+ return;
+ } else
+ swap_without_validation (xx, yy, mousemover.xstart, mousemover.ystart);
+ }
}
+
+ /* Tile needs to go back to its original position */
+ move_held_animate (x, y, mousemover.xstart, mousemover.ystart);
+}
+
+void
+place_tile (gint x, gint y)
+{
+ tiles[automover.yend][automover.xend] = automover.heldtile;
+ gui_draw_pixmap (buffer, automover.xend, automover.yend, FALSE, NULL);
- if (status == RELEASE) {
- get_tilexy_lazy (x - mover.xoff + tile_size / 2,
- y - mover.yoff + tile_size / 2, &xx, &yy);
- if (tiles[yy][xx].status == UNUSED
- && xx >= 0 && xx < size * 2
- && yy >= 0 && yy < size && valid_drop (xx, yy)) {
- tiles[yy][xx] = tiles[mover.ystart][mover.xstart];
- tiles[yy][xx].status = USED;
- gui_draw_pixmap (buffer, xx, yy, FALSE);
- gui_draw_pixmap (buffer, mover.xstart, mover.ystart, FALSE);
+ clear_mover(&automover);
+ if (game_over () && game_state != gameover) {
+ game_state = gameover;
+ games_clock_stop (GAMES_CLOCK (timer));
+ set_game_menu_items_sensitive (FALSE);
+ if (!have_been_hinted) {
+ message (_("Puzzle solved! Well done!"));
} else {
- tiles[mover.ystart][mover.xstart].status = USED;
- gui_draw_pixmap (buffer, mover.xstart, mover.ystart, FALSE);
- }
- gdk_window_hide (mover.window);
- if (mover.pixmap)
- g_object_unref (mover.pixmap);
- mover.pixmap = NULL;
- if (game_over () && game_state != gameover) {
- game_state = gameover;
- games_clock_stop (GAMES_CLOCK (timer));
- set_game_menu_items_sensitive (FALSE);
- if (!have_been_hinted) {
- message (_("Puzzle solved! Well done!"));
- } else {
- message (_("Puzzle solved!"));
- }
- game_score ();
+ message (_("Puzzle solved!"));
}
- update_move_menu_sensitivity ();
- return 1;
+ game_score ();
}
- return 0;
+ update_move_menu_sensitivity ();
}
-gint
-valid_drop (gint x, gint y)
+void
+tile_tilexy (gint x, gint y, gint *xx, gint *yy)
{
- gint xx, yy;
- xx = mover.xstart;
- yy = mover.ystart;
+ get_tilexy_lazy (x - mousemover.xoff + tile_size / 2,
+ y - mousemover.yoff + tile_size / 2, xx, yy);
+}
- if (x >= size)
+void
+swap_without_validation (gint x1, gint y1, gint x2, gint y2)
+{
+ tile swp = tiles[y1][x1];
+ tiles[y1][x1] = tiles[y2][x2];
+ tiles[y2][x2] = swp;
+ tiles[y1][x1].status = USED;
+ tiles[y2][x2].status = USED;
+}
+
+gint
+valid_drop (gint sx, gint sy, gint ex, gint ey)
+{
+ if (ex >= size)
return 1;
/* West */
- if (x != 0 && tiles[y][x - 1].status == USED
- && tiles[y][x - 1].e != tiles[yy][xx].w)
+ if (ex != 0 && tiles[ey][ex - 1].status == USED
+ && tiles[ey][ex - 1].e != tiles[sy][sx].w)
return 0;
/* East */
- if (x != size - 1 && tiles[y][x + 1].status == USED
- && tiles[y][x + 1].w != tiles[yy][xx].e)
+ if (ex != size - 1 && tiles[ey][ex + 1].status == USED
+ && tiles[ey][ex + 1].w != tiles[sy][sx].e)
return 0;
/* North */
- if (y != 0 && tiles[y - 1][x].status == USED
- && tiles[y - 1][x].s != tiles[yy][xx].n)
+ if (ey != 0 && tiles[ey - 1][ex].status == USED
+ && tiles[ey - 1][ex].s != tiles[sy][sx].n)
return 0;
/* South */
- if (y != size - 1 && tiles[y + 1][x].status == USED
- && tiles[y + 1][x].n != tiles[yy][xx].s)
+ if (ey != size - 1 && tiles[ey + 1][ex].status == USED
+ && tiles[ey + 1][ex].n != tiles[sy][sx].s)
return 0;
return 1;
@@ -1346,7 +1416,7 @@ redraw_all (void)
gdk_draw_rectangle (buffer, bg_gc, TRUE, 0, 0, -1, -1);
for (y = 0; y < size; y++)
for (x = 0; x < size * 2; x++)
- gui_draw_pixmap (buffer, x, y, FALSE);
+ gui_draw_pixmap (buffer, x, y, FALSE, NULL);
gui_draw_arrow(buffer);
@@ -1368,7 +1438,7 @@ redraw_left (void)
for (y = 0; y < size; y++)
for (x = 0; x < size; x++)
- gui_draw_pixmap (buffer, x, y, FALSE);
+ gui_draw_pixmap (buffer, x, y, FALSE, NULL);
gdk_window_end_paint (gtk_widget_get_window (space));
gdk_region_destroy (region);
@@ -1407,22 +1477,17 @@ message (gchar * message)
}
void
-create_mover (void)
+init_window_attrib (void)
{
- GdkWindowAttr attributes;
/* The depth of mover.window must match the depth of gtk_widget_get_window (space). */
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.event_mask = 0;
- attributes.width = tile_size;
- attributes.height = tile_size;
- attributes.colormap = gdk_drawable_get_colormap (gtk_widget_get_window (space));
- attributes.visual = gdk_drawable_get_visual (gtk_widget_get_window (space));
-
- mover.window = gdk_window_new (gtk_widget_get_window (space), &attributes,
- (GDK_WA_VISUAL | GDK_WA_COLORMAP));
- mover.pixmap = NULL;
+ windowattrib.wclass = GDK_INPUT_OUTPUT;
+ windowattrib.window_type = GDK_WINDOW_CHILD;
+ windowattrib.event_mask = 0;
+ windowattrib.width = tile_size;
+ windowattrib.height = tile_size;
+ windowattrib.colormap = gdk_drawable_get_colormap (gtk_widget_get_window (space));
+ windowattrib.visual = gdk_drawable_get_visual (gtk_widget_get_window (space));
}
void
@@ -1440,10 +1505,11 @@ new_board (gint size)
gtk_widget_set_sensitive (GTK_WIDGET (space), TRUE);
}
- if (button_down || hint_moving) {
- setup_mover (0, 0, RELEASE);
+ if (button_down || moving) {
+ clear_mover(&mousemover);
+ clear_mover(&automover);
button_down = 0;
- hint_moving = 0;
+ moving = 0;
}
g_random_set_seed (time (NULL) + myrand);
@@ -1765,29 +1831,38 @@ find_first_tile (gint status, gint * xx, gint * yy)
}
}
-#define COUNT 15
+#define LONG_COUNT 15
+#define SHORT_COUNT 5
#define DELAY 10
-gint hint_src_x, hint_src_y, hint_dest_x, hint_dest_y;
+gint animcount;
+gboolean swapanim;
+gint move_src_x, move_src_y, move_dest_x, move_dest_y;
void
-hint_move_cb (void)
+move_cb (void)
{
float dx, dy;
static gint count = 0;
- dx = (float) (hint_src_x - hint_dest_x) / COUNT;
- dy = (float) (hint_src_y - hint_dest_y) / COUNT;
- if (count <= COUNT) {
- gdk_window_move (mover.window, hint_src_x - (gint) (count * dx),
- (gint) hint_src_y - (gint) (count * dy));
+ dx = (float) (move_src_x - move_dest_x) / animcount;
+ dy = (float) (move_src_y - move_dest_y) / animcount;
+ if (count <= animcount) {
+ gdk_window_move (automover.window, move_src_x - (gint) (count * dx),
+ (gint) move_src_y - (gint) (count * dy));
count++;
}
- if (count > COUNT) {
- hint_moving = 0;
+ if (count > animcount) {
count = 0;
- setup_mover (hint_dest_x + 1, hint_dest_y + 1, RELEASE);
+ place_tile (move_dest_x + 1, move_dest_y + 1);
+ moving = 0;
g_source_remove (timer_timeout);
gtk_widget_set_sensitive (GTK_WIDGET (space), TRUE);
+
+ if(swapanim) {
+ move_held_animate (mousemover.x, mousemover.y, automover.xstart, automover.ystart);
+ return;
+ }
+
if (game_state != playing)
return;
if (solve_me)
@@ -1799,12 +1874,49 @@ void
hint_move (gint x1, gint y1, gint x2, gint y2)
{
have_been_hinted = 1;
- get_pixeltilexy (x1, y1, &hint_src_x, &hint_src_y);
- get_pixeltilexy (x2, y2, &hint_dest_x, &hint_dest_y);
- setup_mover (hint_src_x + 1, hint_src_y + 1, PRESS);
- hint_moving = 1;
+ move_tile_animate (x1, y1, x2, y2, FALSE);
+}
+
+void
+move_tile_animate (gint x1, gint y1, gint x2, gint y2, gboolean sa)
+{
+ get_pixeltilexy (x1, y1, &move_src_x, &move_src_y);
+ get_pixeltilexy (x2, y2, &move_dest_x, &move_dest_y);
+
+ setup_mover (move_src_x, move_src_y, &automover);
+ automover.xend = x2;
+ automover.yend = y2;
+ moving = 1;
+ animcount = LONG_COUNT;
+ swapanim = sa;
+ gtk_widget_set_sensitive (GTK_WIDGET (space), FALSE);
+ timer_timeout = g_timeout_add (DELAY, (GSourceFunc) (move_cb), NULL);
+}
+
+void
+move_held_animate (gint x, gint y, gint tx, gint ty) {
+ /* Need to take over movement from mouse mover to auto mover */
+ gint xx, yy;
+ move_src_x = x - mousemover.xoff;
+ move_src_y = y - mousemover.yoff;
+ get_tilexy (move_src_x, move_src_y, &xx, &yy);
+ get_pixeltilexy (tx, ty, &move_dest_x, &move_dest_y);
+
+ clear_mover(&automover);
+ automover = mousemover;
+ mousemover.window = NULL;
+ mousemover.pixmap = NULL;
+
+ automover.xend = tx;
+ automover.yend = ty;
+ moving = 1;
+ if(xx == tx && yy == ty)
+ animcount = SHORT_COUNT;
+ else
+ animcount = LONG_COUNT;
+ swapanim = FALSE;
gtk_widget_set_sensitive (GTK_WIDGET (space), FALSE);
- timer_timeout = g_timeout_add (DELAY, (GSourceFunc) (hint_move_cb), NULL);
+ timer_timeout = g_timeout_add (DELAY, (GSourceFunc) (move_cb), NULL);
}
void
@@ -1813,7 +1925,7 @@ hint_cb (GtkAction * action, gpointer data)
gint x1, y1, x2 = 0, y2 = 0, x = 0, y = 0;
tile hint_tile;
- if ((game_state != playing) || button_down || hint_moving)
+ if ((game_state != playing) || button_down || moving)
return;
find_first_tile (USED, &x, &y);
@@ -1988,4 +2100,3 @@ load_default_background (void)
default_background_pixmap = pm;
}
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]