[gnome-games] aisleriot: Refactor AisleriotBoard
- From: Christian Persch <chpe src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-games] aisleriot: Refactor AisleriotBoard
- Date: Tue, 8 Dec 2009 14:20:29 +0000 (UTC)
commit 3bc45eef8d1180cefc72cf52a03f3e75b5f4c764
Author: Christian Persch <chpe gnome org>
Date: Thu Nov 19 20:05:34 2009 +0100
aisleriot: Refactor AisleriotBoard
Split AisleriotBoard in two parts. The widget part becomes
ArClutterEmbed; the rest is made into a ClutterActor.
Split the style settings off into the ArStyle object, and make
ArClutterEmbed synchronise the widget style and GtkSettings properties
to its style.
Makefile.am | 1 +
aisleriot/Makefile.am | 12 +-
aisleriot/ar-clutter-embed.c | 550 ++++++++++++
aisleriot/ar-clutter-embed.h | 61 ++
aisleriot/ar-cursor.c | 109 +++
aisleriot/ar-cursor.h | 38 +
aisleriot/ar-style-private.h | 69 ++
aisleriot/ar-style.c | 621 +++++++++++++
aisleriot/ar-style.h | 109 +++
aisleriot/baize.c | 50 +-
aisleriot/board-noclutter.c | 124 ++--
aisleriot/board-noclutter.h | 83 ++
aisleriot/board.c | 1631 ++++++++++++++++-------------------
aisleriot/board.h | 77 +-
aisleriot/card.c | 21 +-
aisleriot/game.c | 32 +-
aisleriot/game.h | 8 +-
aisleriot/slot-renderer.c | 136 ++--
aisleriot/slot-renderer.h | 10 +-
aisleriot/window.c | 144 +++-
libgames-support/games-debug.c | 7 +-
libgames-support/games-debug.h | 7 +-
libgames-support/games-marshal.list | 1 +
23 files changed, 2764 insertions(+), 1137 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 29e7cf4..ce4b18a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,6 +45,7 @@ MAINTAINERCLEANFILES = \
$(srcdir)/aclocal.m4 \
$(srcdir)/autoscan.log \
$(srcdir)/compile \
+ $(srcdir)/py-compile \
$(srcdir)/config.guess \
$(srcdir)/config.h.in \
$(srcdir)/config.sub \
diff --git a/aisleriot/Makefile.am b/aisleriot/Makefile.am
index f1b33a4..f54fb57 100644
--- a/aisleriot/Makefile.am
+++ b/aisleriot/Makefile.am
@@ -22,8 +22,8 @@ bin_PROGRAMS = sol
sol_SOURCES = \
ar-game-chooser.c \
ar-game-chooser.h \
- board.h \
board-noclutter.c \
+ board-noclutter.h \
conf.c \
conf.h \
game.c \
@@ -99,12 +99,18 @@ if ENABLE_AISLERIOT_CLUTTER
noinst_PROGRAMS = sol-clutter
sol_clutter_SOURCES = \
+ ar-clutter-embed.c \
+ ar-clutter-embed.h \
+ ar-cursor.c \
+ ar-cursor.h \
ar-game-chooser.c \
ar-game-chooser.h \
- board.h \
- board.c \
+ ar-style.c \
+ ar-style.h \
baize.c \
baize.h \
+ board.c \
+ board.h \
card.c \
card.h \
conf.c \
diff --git a/aisleriot/ar-clutter-embed.c b/aisleriot/ar-clutter-embed.c
new file mode 100644
index 0000000..21dc499
--- /dev/null
+++ b/aisleriot/ar-clutter-embed.c
@@ -0,0 +1,550 @@
+/*
+ * Copyright © 1998, 2003 Jonathan Blandford <jrb mit edu>
+ * Copyright © 2007, 2008, 2009 Christian Persch
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "ar-clutter-embed.h"
+
+#include "ar-style.h"
+#include "ar-style-private.h"
+
+/**
+ * SECTION: ar-clutter-embed
+ * @short_description: a #GtkClutterEmbed derivative
+ *
+ * #ArClutterEmbed is a #GtkClutterEmbed derivative that syncs the
+ * properties of a #ArStyle to its style properties and the #GtkSettings
+ * properties of its #GdkScreen.
+ */
+
+G_DEFINE_TYPE (ArClutterEmbed, ar_clutter_embed, GTK_CLUTTER_TYPE_EMBED)
+
+enum
+{
+ PROP_0,
+ PROP_STYLE
+};
+
+struct _ArClutterEmbedPrivate
+{
+ ArStyle *style;
+
+ GdkCursor *cursor[AR_LAST_CURSOR];
+};
+
+#define I_(string) (g_intern_static_string (string))
+
+/* private functions */
+
+static void
+sync_settings (GtkSettings *settings,
+ GParamSpec *pspec,
+ ArClutterEmbed *embed)
+{
+ ArClutterEmbedPrivate *embed_priv = embed->priv;
+ ArStyle *style = embed_priv->style;
+ ArStylePrivate *style_priv = style->priv;
+ GObject *style_object = G_OBJECT (style);
+ const char *pspec_name;
+
+ if (pspec)
+ pspec_name = pspec->name;
+ else
+ pspec_name = NULL;
+
+ g_object_freeze_notify (style_object);
+
+ if (pspec_name == NULL || pspec_name == I_("gtk-dnd-drag-threshold")) {
+ int threshold;
+
+ g_object_get (settings, "gtk-dnd-drag-threshold", &threshold, NULL);
+
+ if (threshold != style_priv->dnd_drag_threshold) {
+ style_priv->dnd_drag_threshold = threshold;
+
+ g_object_notify (style_object, AR_STYLE_PROP_DND_DRAG_THRESHOLD);
+ }
+ }
+
+ if (pspec_name == NULL || pspec_name == I_("gtk-double-click-time")) {
+ int double_click_time;
+
+ g_object_get (settings, "gtk-double-click-time", &double_click_time, NULL);
+
+ if (double_click_time != style_priv->double_click_time) {
+ style_priv->double_click_time = double_click_time;
+
+ g_object_notify (style_object, AR_STYLE_PROP_DOUBLE_CLICK_TIME);
+ }
+ }
+
+ if (pspec_name == NULL || pspec_name == I_("gtk-enable-animations")) {
+ gboolean enable;
+
+ g_object_get (settings, "gtk-enable-animations", &enable, NULL);
+
+ if (enable != style_priv->enable_animations_gtk) {
+ style_priv->enable_animations_gtk = enable;
+
+ /* FIXMEchpe: only notify if the effective setting changed */
+ g_object_notify (style_object, AR_STYLE_PROP_ENABLE_ANIMATIONS);
+ }
+ }
+
+#if GTK_CHECK_VERSION (2, 14, 0)
+ if (pspec_name == NULL || pspec_name == I_("gtk-enable-event-sounds")) {
+ gboolean enable;
+
+ g_object_get (settings, "gtk-enable-event-sounds", &enable, NULL);
+
+ if (enable != style_priv->enable_sound_gtk) {
+ style_priv->enable_sound_gtk = enable;
+
+ /* FIXMEchpe: only notify if the effective setting changed */
+ g_object_notify (style_object, AR_STYLE_PROP_ENABLE_SOUND);
+ }
+ }
+#endif /* GTK+ >= 2.14.0 */
+
+#if GTK_CHECK_VERSION (2, 10, 0)
+ if (pspec_name == NULL || pspec_name == I_("gtk-touchscreen-mode")) {
+ gboolean enable;
+
+ g_object_get (settings, "gtk-touchscreen-mode", &enable, NULL);
+
+ if (enable != style_priv->touchscreen_mode) {
+ style_priv->touchscreen_mode = enable;
+
+ /* FIXMEchpe: only notify if the effective setting changed */
+ g_object_notify (style_object, AR_STYLE_PROP_TOUCHSCREEN_MODE);
+ }
+ }
+#endif /* GTK+ >= 2.10.0 */
+
+ g_object_thaw_notify (style_object);
+}
+
+static void
+sync_direction (ArClutterEmbed *embed,
+ GtkTextDirection previous_direction)
+{
+
+ ArClutterEmbedPrivate *embed_priv = embed->priv;
+ ArStyle *style = embed_priv->style;
+ ArStylePrivate *style_priv = style->priv;
+ GObject *style_object = G_OBJECT (style);
+ GtkTextDirection direction;
+ gboolean rtl;
+
+ direction = gtk_widget_get_direction (GTK_WIDGET (embed));
+ if (direction == previous_direction)
+ return;
+
+ g_object_freeze_notify (style_object);
+
+ rtl = (direction == GTK_TEXT_DIR_RTL);
+
+ if (style_priv->rtl != rtl) {
+ style_priv->rtl = rtl;
+
+ g_object_notify (style_object, AR_STYLE_PROP_RTL);
+ }
+
+ g_object_thaw_notify (style_object);
+}
+
+/* GtkWidgetClass impl */
+
+static void
+ar_clutter_embed_realize (GtkWidget *widget)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (widget);
+ ArClutterEmbedPrivate *priv = embed->priv;
+#ifndef HAVE_HILDON
+ GdkDisplay *display;
+#endif
+
+ GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->realize (widget);
+
+ /* FIXMEchpe: this isn't really HILDON, but don't-support-mouse */
+#ifndef HAVE_HILDON
+ /* Create cursors */
+ display = gtk_widget_get_display (widget);
+
+ priv->cursor[AR_CURSOR_DEFAULT] = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
+ priv->cursor[AR_CURSOR_OPEN] = ar_cursor_new (widget->window, AR_CURSOR_OPEN);
+ priv->cursor[AR_CURSOR_CLOSED] = ar_cursor_new (widget->window, AR_CURSOR_CLOSED);
+ priv->cursor[AR_CURSOR_DROPPABLE] = gdk_cursor_new_for_display (display, GDK_DOUBLE_ARROW); /* FIXMEchpe: better cursor */
+#endif /* !HAVE_HILDON */
+
+ ar_clutter_embed_set_cursor (embed, AR_CURSOR_DEFAULT);
+}
+
+static void
+ar_clutter_embed_unrealize (GtkWidget *widget)
+{
+ /* FIXMEchpe */
+#ifndef HAVE_HILDON
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (widget);
+ ArClutterEmbedPrivate *priv = embed->priv;
+ guint i;
+
+ for (i = 0; i < AR_LAST_CURSOR; ++i) {
+ gdk_cursor_unref (priv->cursor[i]);
+ priv->cursor[i] = NULL;
+ }
+#endif /* !HAVE_HILDON*/
+
+ GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->unrealize (widget);
+}
+
+static void
+ar_clutter_embed_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (widget);
+ ArClutterEmbedPrivate *priv = embed->priv;
+ GdkScreen *screen;
+ GtkSettings *settings;
+ void (* screen_changed) (GtkWidget*, GdkScreen *) =
+ GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->screen_changed;
+
+ if (screen_changed) {
+ screen_changed (widget, previous_screen);
+ }
+
+ g_assert (priv->style != NULL);
+
+ screen = gtk_widget_get_screen (widget);
+ if (screen == previous_screen)
+ return;
+
+ if (previous_screen != NULL) {
+ g_signal_handlers_disconnect_by_func (gtk_settings_get_for_screen (previous_screen),
+ G_CALLBACK (sync_settings),
+ embed);
+ }
+
+ if (screen == NULL)
+ return;
+
+ settings = gtk_settings_get_for_screen (screen);
+
+ sync_settings (settings, NULL, embed);
+ g_signal_connect (settings, "notify::gtk-double-click-time",
+ G_CALLBACK (sync_settings), embed);
+ g_signal_connect (settings, "notify::gtk-enable-animations",
+ G_CALLBACK (sync_settings), embed);
+#if GTK_CHECK_VERSION (2, 14, 0)
+ g_signal_connect (settings, "notify::gtk-enable-event-sounds",
+ G_CALLBACK (sync_settings), embed);
+#endif /* GTK+ >= 2.14.0 */
+#if GTK_CHECK_VERSION (2, 10, 0)
+ g_signal_connect (settings, "notify::gtk-touchscreen-mode",
+ G_CALLBACK (sync_settings), embed);
+#endif /* GTK+ >= 2.10.0 */
+}
+
+static void
+ar_clutter_embed_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (widget);
+ ArClutterEmbedPrivate *embed_priv = embed->priv;
+ ArStyle *style = embed_priv->style;
+ ArStylePrivate *style_priv = style->priv;
+ GObject *style_object = G_OBJECT (style);
+ GdkColor *color = NULL;
+ ClutterColor selection_color;
+ int focus_line_width, focus_padding;
+ gboolean interior_focus;
+ double card_slot_ratio;
+
+ GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->style_set (widget, previous_style);
+
+ g_object_freeze_notify (style_object);
+
+ gtk_widget_style_get (widget,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_line_width,
+ "focus-padding", &focus_padding,
+ "card-slot-ratio", &card_slot_ratio,
+ "selection-color", &color,
+ NULL);
+
+ if (style_priv->interior_focus != interior_focus) {
+ style_priv->interior_focus = interior_focus;
+
+ g_object_notify (style_object, AR_STYLE_PROP_INTERIOR_FOCUS);
+ }
+
+ if (style_priv->focus_line_width != focus_line_width) {
+ style_priv->focus_line_width = focus_line_width;
+
+ g_object_notify (style_object, AR_STYLE_PROP_FOCUS_LINE_WIDTH);
+ }
+
+ if (style_priv->focus_padding != focus_padding) {
+ style_priv->focus_padding = focus_padding;
+
+ g_object_notify (style_object, AR_STYLE_PROP_FOCUS_PADDING);
+ }
+
+ if (style_priv->card_slot_ratio != card_slot_ratio) {
+ style_priv->card_slot_ratio = card_slot_ratio;
+
+ g_object_notify (style_object, AR_STYLE_PROP_CARD_SLOT_RATIO);
+ }
+
+ if (color != NULL) {
+ _ar_clutter_color_from_gdk_color (&selection_color, color);
+ gdk_color_free (color);
+ } else {
+ _ar_clutter_color_from_gdk_color (&selection_color, &default_selection_color);
+ }
+
+ if (!clutter_color_equal (&style_priv->selection_color, &selection_color)) {
+ style_priv->selection_color = selection_color;
+
+ g_object_notify (style_object, AR_STYLE_PROP_SELECTION_COLOR);
+ }
+
+ g_object_thaw_notify (style_object);
+}
+
+static void
+ar_clutter_embed_direction_changed (GtkWidget *widget,
+ GtkTextDirection previous_direction)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (widget);
+
+ GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->direction_changed (widget, previous_direction);
+
+ sync_direction (embed, previous_direction);
+}
+
+static gboolean
+ar_clutter_embed_focus_in (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ gboolean retval;
+
+ retval = GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->focus_in_event (widget, event);
+
+#if 0
+ ClutterActor *stage;
+ stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (widget));
+ clutter_stage_set_key_focus (CLUTTER_STAGE (stage), FIXME board actor);
+#endif
+
+ return retval;
+}
+
+static gboolean
+ar_clutter_embed_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+#ifdef FIXMEchpe
+ clear_state (board);
+#endif
+
+ return GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->focus_out_event (widget, event);
+}
+
+static gboolean
+ar_clutter_embed_focus (GtkWidget *widget,
+ GtkDirectionType direction)
+{
+// ArClutterEmbed *embed = AR_CLUTTER_EMBED (embed);
+// ArClutterEmbedPrivate *priv = embed->priv;
+ int count;
+ gboolean retval = FALSE;
+
+ switch (direction) {
+ case GTK_DIR_TAB_FORWARD:
+ count = 1;
+ break;
+ case GTK_DIR_TAB_BACKWARD:
+ count = -1;
+ break;
+ default:
+ break;
+ }
+
+#ifdef FIXMEchpe
+ g_signal_emit_by_name (priv->board_actor, "focus", count, &retval);
+#endif
+
+ if (retval)
+ return TRUE;
+
+ return GTK_WIDGET_CLASS (ar_clutter_embed_parent_class)->focus (widget, direction);
+}
+
+/* GObjectClass impl */
+
+static void
+ar_clutter_embed_init (ArClutterEmbed *embed)
+{
+ GtkWidget *widget = GTK_WIDGET (embed);
+
+ embed->priv = G_TYPE_INSTANCE_GET_PRIVATE (embed, AR_TYPE_CLUTTER_EMBED, ArClutterEmbedPrivate);
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+}
+
+static void
+ar_clutter_embed_dispose (GObject *object)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (object);
+ GtkWidget *widget = GTK_WIDGET (embed);
+
+ g_signal_handlers_disconnect_by_func (gtk_widget_get_settings (widget),
+ G_CALLBACK (sync_settings),
+ embed);
+
+ G_OBJECT_CLASS (ar_clutter_embed_parent_class)->dispose (object);
+}
+
+static void
+ar_clutter_embed_finalize (GObject *object)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (object);
+ ArClutterEmbedPrivate *priv = embed->priv;
+
+ g_assert (priv->style != NULL);
+ g_object_unref (priv->style);
+
+ G_OBJECT_CLASS (ar_clutter_embed_parent_class)->finalize (object);
+}
+
+static void
+ar_clutter_embed_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ArClutterEmbed *embed = AR_CLUTTER_EMBED (object);
+ ArClutterEmbedPrivate *priv = embed->priv;
+
+ switch (property_id) {
+ case PROP_STYLE:
+ priv->style = g_value_dup_object (value);
+
+ /* This is necessary since we don't get an initial change notification! */
+ sync_direction (embed, GTK_TEXT_DIR_LTR);
+
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ar_clutter_embed_class_init (ArClutterEmbedClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (ArClutterEmbedPrivate));
+
+ object_class->set_property = ar_clutter_embed_set_property;
+ object_class->dispose = ar_clutter_embed_dispose;
+ object_class->finalize = ar_clutter_embed_finalize;
+
+ widget_class->realize = ar_clutter_embed_realize;
+ widget_class->unrealize = ar_clutter_embed_unrealize;
+ widget_class->style_set = ar_clutter_embed_style_set;
+ widget_class->direction_changed = ar_clutter_embed_direction_changed;
+ widget_class->screen_changed = ar_clutter_embed_screen_changed;
+ widget_class->focus_in_event = ar_clutter_embed_focus_in;
+ widget_class->focus_out_event = ar_clutter_embed_focus_out;
+ widget_class->focus = ar_clutter_embed_focus;
+
+ /**
+ * ArClutterEmbed:style:
+ *
+ * An #ArStyle that @embed will update with its widget style properties.
+ */
+ g_object_class_install_property
+ (object_class,
+ PROP_STYLE,
+ g_param_spec_object ("style", NULL, NULL,
+ AR_TYPE_STYLE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ gtk_widget_class_install_style_property
+ (widget_class,
+ g_param_spec_boxed ("selection-color", NULL, NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * ArClutterEmbed:card-slot-ratio:
+ *
+ * The ratio of card to slot size. Note that this is the ratio of
+ * card width/slot width and card height/slot height, not of
+ * card area/slot area.
+ */
+ gtk_widget_class_install_style_property
+ (widget_class,
+ g_param_spec_double ("card-slot-ratio", NULL, NULL,
+ 0.1, 1.0, DEFAULT_CARD_SLOT_RATIO,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+/* public API */
+
+/**
+ * ar_clutter_embed_new:
+ * @style: an #ArStyle
+ *
+ * Returns: a new #ArClutterEmbed
+ */
+ArClutterEmbed *
+ar_clutter_embed_new (ArStyle *style)
+{
+ return g_object_new (AR_TYPE_CLUTTER_EMBED,
+ "style", style,
+ NULL);
+}
+
+/**
+ * ar_clutter_embed_set_cursor:
+ * @embed: an #ArClutterEmbed
+ * @cursor_type: the cursor type
+ *
+ * Sets the cursor on @embed to @cursor_type.
+ */
+void
+ar_clutter_embed_set_cursor (ArClutterEmbed *embed,
+ ArCursorType cursor)
+{
+ /* FIXMEchpe */
+#ifndef HAVE_HILDON
+ ArClutterEmbedPrivate *priv = embed->priv;
+
+ gdk_window_set_cursor (GTK_WIDGET (embed)->window,
+ priv->cursor[cursor]);
+#endif /* !HAVE_HILDON */
+}
diff --git a/aisleriot/ar-clutter-embed.h b/aisleriot/ar-clutter-embed.h
new file mode 100644
index 0000000..6bc9e7c
--- /dev/null
+++ b/aisleriot/ar-clutter-embed.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2009 Christian Persch <chpe gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AR_CLUTTER_EMBED_H__
+#define __AR_CLUTTER_EMBED_H__
+
+#include <clutter-gtk/clutter-gtk.h>
+
+#include "ar-style.h"
+#include "ar-cursor.h"
+
+G_BEGIN_DECLS
+
+#define AR_TYPE_CLUTTER_EMBED (ar_clutter_embed_get_type())
+#define AR_CLUTTER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), AR_TYPE_CLUTTER_EMBED, ArClutterEmbed))
+#define AR_CLUTTER_EMBED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), AR_TYPE_CLUTTER_EMBED, ArClutterEmbedClass))
+#define AR_IS_CLUTTER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AR_TYPE_CLUTTER_EMBED))
+#define AR_IS_CLUTTER_EMBED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), AR_TYPE_CLUTTER_EMBED))
+#define AR_CLUTTER_EMBED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), AR_TYPE_CLUTTER_EMBED, ArClutterEmbedClass))
+
+typedef struct _ArClutterEmbed ArClutterEmbed;
+typedef struct _ArClutterEmbedClass ArClutterEmbedClass;
+typedef struct _ArClutterEmbedPrivate ArClutterEmbedPrivate;
+
+struct _ArClutterEmbed
+{
+ GtkClutterEmbed parent;
+
+ /*< private >*/
+ ArClutterEmbedPrivate *priv;
+};
+
+struct _ArClutterEmbedClass
+{
+ GtkClutterEmbedClass parent_class;
+};
+
+GType ar_clutter_embed_get_type (void);
+
+ArClutterEmbed* ar_clutter_embed_new (ArStyle *style);
+
+void ar_clutter_embed_set_cursor (ArClutterEmbed *embed,
+ ArCursorType cursor_type);
+
+G_END_DECLS
+
+#endif /* __AR_CLUTTER_EMBED_H__ */
diff --git a/aisleriot/ar-cursor.c b/aisleriot/ar-cursor.c
new file mode 100644
index 0000000..00f7e49
--- /dev/null
+++ b/aisleriot/ar-cursor.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 1998, 2003 Jonathan Blandford <jrb mit edu>
+ * Copyright © 2007, 2008, 2009 Christian Persch
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "ar-cursor.h"
+
+#ifndef HAVE_HILDON
+
+/* These cursors borrowed from EOG */
+/* FIXMEchpe use themeable cursors here! */
+#define hand_closed_data_width 20
+#define hand_closed_data_height 20
+static const char hand_closed_data_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00,
+ 0x80, 0xff, 0x00, 0x80, 0xff, 0x00, 0xb0, 0xff, 0x00, 0xf0, 0xff, 0x00,
+ 0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
+ 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#define hand_closed_mask_width 20
+#define hand_closed_mask_height 20
+static const char hand_closed_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0xff, 0x00,
+ 0xc0, 0xff, 0x01, 0xf0, 0xff, 0x01, 0xf8, 0xff, 0x01, 0xf8, 0xff, 0x01,
+ 0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
+ 0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#define hand_open_data_width 20
+#define hand_open_data_height 20
+static const char hand_open_data_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+ 0x60, 0x36, 0x00, 0x60, 0x36, 0x00, 0xc0, 0x36, 0x01, 0xc0, 0xb6, 0x01,
+ 0x80, 0xbf, 0x01, 0x98, 0xff, 0x01, 0xb8, 0xff, 0x00, 0xf0, 0xff, 0x00,
+ 0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
+ 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#define hand_open_mask_width 20
+#define hand_open_mask_height 20
+static const char hand_open_mask_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x3f, 0x00,
+ 0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x01, 0xe0, 0xff, 0x03, 0xe0, 0xff, 0x03,
+ 0xd8, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfc, 0xff, 0x01, 0xf8, 0xff, 0x01,
+ 0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
+ 0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static GdkCursor *
+ar_cursor_new_from_data (GdkWindow *window,
+ const char *data,
+ const char *mask_data)
+{
+ const GdkColor fg = { 0, 65535, 65535, 65535 };
+ const GdkColor bg = { 0, 0, 0, 0 };
+ GdkPixmap *source;
+ GdkPixmap *mask;
+ GdkCursor *cursor;
+
+ /* Yeah, hard-coded sizes are bad. */
+ source = gdk_bitmap_create_from_data (window, data, 20, 20);
+ mask = gdk_bitmap_create_from_data (window, mask_data, 20, 20);
+
+ cursor = gdk_cursor_new_from_pixmap (source, mask, &fg, &bg, 10, 10);
+
+ g_object_unref (source);
+ g_object_unref (mask);
+
+ return cursor;
+}
+
+#endif /* !HAVE_HILDON */
+
+GdkCursor *ar_cursor_new (GdkWindow *window,
+ ArCursorType cursor_type)
+{
+#ifndef HAVE_HILDON
+ switch (cursor_type) {
+ case AR_CURSOR_OPEN:
+ return ar_cursor_new_from_data (window, hand_open_data_bits, hand_open_mask_bits);
+
+ case AR_CURSOR_CLOSED:
+ return ar_cursor_new_from_data (window, hand_closed_data_bits, hand_closed_mask_bits);
+
+ default:
+ g_assert_not_reached ();
+ }
+#else
+ return NULL;
+#endif /* !HAVE_HILDON */
+}
diff --git a/aisleriot/ar-cursor.h b/aisleriot/ar-cursor.h
new file mode 100644
index 0000000..f89d278
--- /dev/null
+++ b/aisleriot/ar-cursor.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2009 Christian Persch <chpe gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AR_CURSOR_H__
+#define __AR_CURSOR_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ AR_CURSOR_DEFAULT,
+ AR_CURSOR_OPEN,
+ AR_CURSOR_CLOSED,
+ AR_CURSOR_DROPPABLE,
+ AR_LAST_CURSOR
+} ArCursorType;
+
+GdkCursor *ar_cursor_new (GdkWindow *window,
+ ArCursorType cursor_type);
+
+G_END_DECLS
+
+#endif /* __AR_CURSOR_H__ */
diff --git a/aisleriot/ar-style-private.h b/aisleriot/ar-style-private.h
new file mode 100644
index 0000000..e40b51a
--- /dev/null
+++ b/aisleriot/ar-style-private.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2009 Christian Persch <chpe gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AR_STYLE_PRIVATE_H__
+#define __AR_STYLE_PRIVATE_H__
+
+G_BEGIN_DECLS
+
+static const GdkColor default_selection_color = { 0, 0 /* red */, 0 /* green */, 0xaa00 /* blue */ };
+
+/* The proportion of a slot dedicated to the card (horiz or vert). */
+#ifndef DEFAULT_CARD_SLOT_RATIO
+#ifdef HAVE_HILDON
+#define DEFAULT_CARD_SLOT_RATIO (0.9)
+#else
+#define DEFAULT_CARD_SLOT_RATIO (0.8)
+#endif
+#endif /* !DEFAULT_CARD_SLOT_RATIO */
+
+struct _ArStylePrivate
+{
+ GamesCardTheme* card_theme;
+
+ ClutterColor selection_color;
+
+ double card_slot_ratio;
+
+ int dnd_drag_threshold;
+ int double_click_time;
+ int focus_line_width;
+ int focus_padding;
+
+ guint enable_animations_gtk : 1;
+ guint enable_animations : 1;
+ guint enable_sound_gtk : 1;
+ guint enable_sound : 1;
+ guint touchscreen_mode : 1;
+
+ guint rtl : 1;
+ guint interior_focus : 1;
+
+ guint click_to_move : 1;
+
+ guint keynav_enabled : 1;
+ guint show_focus : 1;
+ guint show_highlight : 1;
+ guint show_seleccion : 1;
+};
+
+void _ar_clutter_color_from_gdk_color (ClutterColor *clutter_color,
+ const GdkColor *gdk_color);
+
+G_END_DECLS
+
+#endif /* __AR_STYLE_PRIVATE_H__ */
diff --git a/aisleriot/ar-style.c b/aisleriot/ar-style.c
new file mode 100644
index 0000000..182304e
--- /dev/null
+++ b/aisleriot/ar-style.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright © 2009 Christian Persch <chpe gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "ar-style.h"
+#include "ar-style-private.h"
+
+enum
+{
+ PROP_0,
+ PROP_CARD_SLOT_RATIO,
+ PROP_CARD_THEME,
+ PROP_CLICK_TO_MOVE,
+ PROP_DND_DRAG_THRESHOLD,
+ PROP_DOUBLE_CLICK_TIME,
+ PROP_ENABLE_ANIMATIONS,
+ PROP_ENABLE_SOUND,
+ PROP_FOCUS_LINE_WIDTH,
+ PROP_FOCUS_PADDING,
+ PROP_INTERIOR_FOCUS,
+ PROP_RTL,
+ PROP_SELECTION_COLOR,
+ PROP_TOUCHSCREEN_MODE,
+};
+
+/* private functions */
+
+/* GObjectClass impl */
+
+G_DEFINE_TYPE (ArStyle, ar_style, G_TYPE_OBJECT)
+
+static void
+ar_style_init (ArStyle *style)
+{
+ ArStylePrivate *priv;
+
+ priv = style->priv = G_TYPE_INSTANCE_GET_PRIVATE (style, AR_TYPE_STYLE, ArStylePrivate);
+
+ _ar_clutter_color_from_gdk_color (&priv->selection_color, &default_selection_color);
+ priv->card_slot_ratio = DEFAULT_CARD_SLOT_RATIO;
+ priv->dnd_drag_threshold = 8;
+ priv->double_click_time = 250;
+ priv->focus_line_width = 1;
+ priv->focus_padding = 1;
+ priv->enable_animations_gtk = FALSE;
+ priv->enable_animations = FALSE;
+ priv->enable_sound_gtk = FALSE;
+ priv->enable_sound = FALSE;
+ priv->touchscreen_mode = FALSE;
+ priv->rtl = FALSE;
+ priv->interior_focus = FALSE;
+ priv->click_to_move = FALSE;
+}
+
+static void
+ar_style_finalize (GObject *object)
+{
+ ArStyle *style = AR_STYLE (object);
+ ArStylePrivate *priv = style->priv;
+
+ if (priv->card_theme) {
+ g_object_unref (priv->card_theme);
+ }
+
+ G_OBJECT_CLASS (ar_style_parent_class)->finalize (object);
+}
+
+static void
+ar_style_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ArStyle *style = AR_STYLE (object);
+ ArStylePrivate *priv = style->priv;
+
+ switch (property_id) {
+ case PROP_CARD_SLOT_RATIO:
+ g_value_set_double (value, ar_style_get_card_slot_ratio (style));
+ break;
+
+ case PROP_CARD_THEME:
+ g_value_set_object (value, ar_style_get_card_theme (style));
+ break;
+
+ case PROP_CLICK_TO_MOVE:
+ g_value_set_boolean (value, ar_style_get_click_to_move (style));
+ break;
+
+ case PROP_DND_DRAG_THRESHOLD:
+ g_value_set_int (value, priv->dnd_drag_threshold);
+ break;
+
+ case PROP_DOUBLE_CLICK_TIME:
+ g_value_set_int (value, ar_style_get_double_click_time (style));
+ break;
+
+ case PROP_ENABLE_ANIMATIONS:
+ g_value_set_boolean (value, ar_style_get_enable_animations (style));
+ break;
+
+ case PROP_ENABLE_SOUND:
+ g_value_set_boolean (value, ar_style_get_enable_sound (style));
+ break;
+
+ case PROP_FOCUS_LINE_WIDTH:
+ g_value_set_int (value, ar_style_get_focus_line_width (style));
+ break;
+
+ case PROP_FOCUS_PADDING:
+ g_value_set_int (value, ar_style_get_focus_padding (style));
+ break;
+
+ case PROP_INTERIOR_FOCUS:
+ g_value_set_boolean (value, ar_style_get_interior_focus (style));
+ break;
+
+ case PROP_RTL:
+ g_value_set_boolean (value, ar_style_get_rtl (style));
+ break;
+
+ case PROP_SELECTION_COLOR:
+ g_value_set_boxed (value, &priv->selection_color);
+ break;
+
+ case PROP_TOUCHSCREEN_MODE:
+ g_value_set_boolean (value, ar_style_get_touchscreen_mode (style));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ar_style_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ArStyle *style = AR_STYLE (object);
+
+ switch (property_id) {
+ case PROP_CARD_THEME:
+ ar_style_set_card_theme (style, g_value_get_object (value));
+ break;
+
+ case PROP_CLICK_TO_MOVE:
+ ar_style_set_click_to_move (style, g_value_get_boolean (value));
+ break;
+
+ case PROP_ENABLE_ANIMATIONS:
+ ar_style_set_enable_animations (style, g_value_get_boolean (value));
+ break;
+
+ case PROP_ENABLE_SOUND:
+ ar_style_set_enable_sound (style, g_value_get_boolean (value));
+ break;
+
+ case PROP_CARD_SLOT_RATIO:
+ case PROP_DND_DRAG_THRESHOLD:
+ case PROP_DOUBLE_CLICK_TIME:
+ case PROP_FOCUS_LINE_WIDTH:
+ case PROP_FOCUS_PADDING:
+ case PROP_INTERIOR_FOCUS:
+ case PROP_RTL:
+ case PROP_SELECTION_COLOR:
+ case PROP_TOUCHSCREEN_MODE:
+ /* not writable */
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ar_style_class_init (ArStyleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ClutterColor color;
+
+ g_type_class_add_private (klass, sizeof (ArStylePrivate));
+
+ object_class->set_property = ar_style_set_property;
+ object_class->get_property = ar_style_get_property;
+ object_class->finalize = ar_style_finalize;
+
+ g_object_class_install_property
+ (object_class,
+ PROP_CARD_SLOT_RATIO,
+ g_param_spec_double (AR_STYLE_PROP_CARD_SLOT_RATIO, NULL, NULL,
+ 0.1, 1.0, DEFAULT_CARD_SLOT_RATIO,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_CARD_THEME,
+ g_param_spec_object (AR_STYLE_PROP_CARD_THEME, NULL, NULL,
+ GAMES_TYPE_CARD_THEME,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_CLICK_TO_MOVE,
+ g_param_spec_boolean (AR_STYLE_PROP_CLICK_TO_MOVE, NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_DND_DRAG_THRESHOLD,
+ g_param_spec_int (AR_STYLE_PROP_DND_DRAG_THRESHOLD, NULL, NULL,
+ 1, G_MAXINT, 8,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_DOUBLE_CLICK_TIME,
+ g_param_spec_int (AR_STYLE_PROP_DOUBLE_CLICK_TIME, NULL, NULL,
+ 0, G_MAXINT, 250,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_ENABLE_ANIMATIONS,
+ g_param_spec_boolean (AR_STYLE_PROP_ENABLE_ANIMATIONS, NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_ENABLE_SOUND,
+ g_param_spec_boolean (AR_STYLE_PROP_ENABLE_SOUND, NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_FOCUS_LINE_WIDTH,
+ g_param_spec_int (AR_STYLE_PROP_FOCUS_LINE_WIDTH, NULL, NULL,
+ 0, G_MAXINT, 1,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_FOCUS_PADDING,
+ g_param_spec_int (AR_STYLE_PROP_FOCUS_PADDING, NULL, NULL,
+ 0, G_MAXINT, 1,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_INTERIOR_FOCUS,
+ g_param_spec_boolean (AR_STYLE_PROP_INTERIOR_FOCUS, NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_RTL,
+ g_param_spec_boolean (AR_STYLE_PROP_RTL, NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ _ar_clutter_color_from_gdk_color (&color, &default_selection_color);
+ g_object_class_install_property
+ (object_class,
+ PROP_SELECTION_COLOR,
+ clutter_param_spec_color (AR_STYLE_PROP_SELECTION_COLOR, NULL, NULL,
+ &color,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_TOUCHSCREEN_MODE,
+ g_param_spec_boolean (AR_STYLE_PROP_TOUCHSCREEN_MODE, NULL, NULL,
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+/* private API */
+
+void
+_ar_clutter_color_from_gdk_color (ClutterColor *clutter_color,
+ const GdkColor *gdk_color)
+{
+ clutter_color->red = gdk_color->red >> 8;
+ clutter_color->green = gdk_color->green >> 8;
+ clutter_color->blue = gdk_color->blue >> 8;
+ clutter_color->alpha = 0xff;
+}
+
+/* public API */
+
+/**
+ * ar_style_new:
+ *
+ * Return value:
+ */
+ArStyle*
+ar_style_new (void)
+{
+ return g_object_new (AR_TYPE_STYLE, NULL);
+}
+
+/**
+ * ar_style_get_enable_animations:
+ * @style: an #ArStyle
+ *
+ * Returns: whether animations are enabled
+ */
+gboolean
+ar_style_get_enable_animations (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->enable_animations && priv->enable_animations_gtk;
+}
+
+/**
+ * ar_style_set_enable_animations:
+ * @style: an #ArStyle
+ * @enable: whether to enable animations
+ *
+ * Note that animations are only used when this the
+ * global gtk-enable-animations setting is enabled as well.
+ */
+void
+ar_style_set_enable_animations (ArStyle *style,
+ gboolean enable)
+{
+ ArStylePrivate *priv = style->priv;
+
+ enable = enable != FALSE;
+ if (priv->enable_animations == enable)
+ return;
+
+ priv->enable_animations = enable;
+ g_object_notify (G_OBJECT (style), AR_STYLE_PROP_ENABLE_ANIMATIONS);
+}
+
+/**
+ * ar_style_get_enable_sound:
+ * @style: an #ArStyle
+ *
+ * Returns: whether sound is enabled
+ */
+gboolean
+ar_style_get_enable_sound (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->enable_sound && priv->enable_sound_gtk;
+}
+
+/**
+ * ar_style_set_enable_sound:
+ * @style: an #ArStyle
+ * @enable: whether to enable sound
+ *
+ * Note that sound is only used when this the
+ * global gtk-enable-event-sounds setting is enabled as well.
+ */
+void
+ar_style_set_enable_sound (ArStyle *style,
+ gboolean enable)
+{
+ ArStylePrivate *priv = style->priv;
+
+ enable = enable != FALSE;
+ if (priv->enable_sound == enable)
+ return;
+
+ priv->enable_sound = enable;
+ g_object_notify (G_OBJECT (style), AR_STYLE_PROP_ENABLE_SOUND);
+}
+
+/**
+ * ar_style_get_click_to_move:
+ * @style: an #ArStyle
+ *
+ * Returns: whether sound is enabled
+ */
+gboolean
+ar_style_get_click_to_move (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->click_to_move;
+}
+
+/**
+ * ar_style_set_click_to_move:
+ * @style: an #ArStyle
+ * @enable: whether to enable sound
+ *
+ * Note that sound is only used when this the
+ * global gtk-enable-event-sounds setting is enabled as well.
+ */
+void
+ar_style_set_click_to_move (ArStyle *style,
+ gboolean enable)
+{
+ ArStylePrivate *priv = style->priv;
+
+ enable = enable != FALSE;
+ if (priv->click_to_move == enable)
+ return;
+
+ priv->click_to_move = enable;
+ g_object_notify (G_OBJECT (style), AR_STYLE_PROP_CLICK_TO_MOVE);
+}
+
+/**
+ * ar_style_get_card_theme:
+ * @style: an #ArStyle
+ *
+ * Returns: @style's #GamesCardTheme
+ */
+GamesCardTheme *
+ar_style_get_card_theme (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->card_theme;
+}
+
+/**
+ * ar_style_set_card_theme:
+ * @style: an #ArStyle
+ * @card_theme: a #GamesCardTheme
+ *
+ * Note that animations are only used when this the
+ * global gtk-enable-animations setting is enabled as well.
+ */
+void
+ar_style_set_card_theme (ArStyle *style,
+ GamesCardTheme *theme)
+{
+ ArStylePrivate *priv = style->priv;
+
+ if (priv->card_theme == theme)
+ return;
+
+ if (priv->card_theme != NULL) {
+ g_object_unref (priv->card_theme);
+ }
+ priv->card_theme = g_object_ref (theme);
+
+ g_object_notify (G_OBJECT (style), AR_STYLE_PROP_CARD_THEME);
+}
+
+/**
+ * ar_style_get_touchscreen_mode:
+ * @style: an #ArStyle
+ *
+ * Returns: whether sound is enabled
+ */
+gboolean
+ar_style_get_touchscreen_mode (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->touchscreen_mode;
+}
+
+/**
+ * ar_style_get_interior_focus:
+ * @style: an #ArStyle
+ *
+ * Returns:
+ */
+gboolean
+ar_style_get_interior_focus (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->interior_focus;
+}
+
+
+/**
+ * ar_style_get_rtl:
+ * @style: an #ArStyle
+ *
+ * Returns:
+ */
+gboolean
+ar_style_get_rtl (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->rtl;
+}
+
+/**
+ * ar_style_get_double_click_time:
+ * @style: an #ArStyle
+ *
+ * Returns: the double click time
+ */
+int
+ar_style_get_double_click_time (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->double_click_time;
+}
+
+/**
+ * ar_style_get_focus_line_width:
+ * @style: an #ArStyle
+ *
+ * Returns:
+ */
+int
+ar_style_get_focus_line_width (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->focus_line_width;
+}
+
+/**
+ * ar_style_get_focus_padding:
+ * @style: an #ArStyle
+ *
+ * Returns:
+ */
+int ar_style_get_focus_padding (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->focus_padding;
+}
+
+/**
+ * ar_style_get_card_slot_ratio:
+ * @style: an #ArStyle
+ *
+ * Returns:
+ */
+double
+ar_style_get_card_slot_ratio (ArStyle *style)
+{
+ ArStylePrivate *priv = style->priv;
+
+ return priv->card_slot_ratio;
+}
+
+/**
+ * ar_style_get_selection_color:
+ * @style: an #ArStyle
+ * @color: location to store the color
+ *
+ */
+void
+ar_style_get_selection_color (ArStyle *style,
+ ClutterColor * const color)
+{
+ ArStylePrivate *priv = style->priv;
+
+ *color = priv->selection_color;
+}
+
+/**
+ * ar_style_check_dnd_drag_threshold:
+ * @style:
+ * @x1:
+ * @y1:
+ * @x2:
+ * @y2:
+ *
+ * Checks whether the distance between (x1, y1) and (x2, y2) is
+ * greater than the drag threshold.
+ *
+ * Returns: %TRUE if the distance between the points is greater
+ * than the drag threshold
+ */
+gboolean
+ar_style_check_dnd_drag_threshold (ArStyle *style,
+ float x1,
+ float y1,
+ float x2,
+ float y2)
+{
+ ArStylePrivate *priv = style->priv;
+
+ /* FIXMEchpe: are these coordinates pixels, or something else? */
+ /* FIXMEchpe: shouldn't this be (x2 - x1)**2 + (y2 - y1)**2 >= threshold**2 ? */
+ return (ABS (x2 - x1) > priv->dnd_drag_threshold ||
+ ABS (y2 - y1) > priv->dnd_drag_threshold);
+}
diff --git a/aisleriot/ar-style.h b/aisleriot/ar-style.h
new file mode 100644
index 0000000..d1505af
--- /dev/null
+++ b/aisleriot/ar-style.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2009 Christian Persch <chpe gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AR_STYLE_H__
+#define __AR_STYLE_H__
+
+#include <glib-object.h>
+
+#include <clutter/clutter.h>
+
+#include <libgames-support/games-card-theme.h>
+
+G_BEGIN_DECLS
+
+#define AR_TYPE_STYLE (ar_style_get_type())
+#define AR_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), AR_TYPE_STYLE, ArStyle))
+#define AR_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), AR_TYPE_STYLE, ArStyleClass))
+#define AR_IS_STYLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AR_TYPE_STYLE))
+#define AR_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), AR_TYPE_STYLE))
+#define AR_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), AR_TYPE_STYLE, ArStyleClass))
+
+typedef struct _ArStyle ArStyle;
+typedef struct _ArStyleClass ArStyleClass;
+typedef struct _ArStylePrivate ArStylePrivate;
+
+struct _ArStyle
+{
+ GObject parent;
+
+ /*< private >*/
+ ArStylePrivate *priv;
+};
+
+struct _ArStyleClass
+{
+ GObjectClass parent_class;
+};
+
+GType ar_style_get_type (void);
+
+ArStyle* ar_style_new (void);
+
+#define AR_STYLE_PROP_CARD_SLOT_RATIO "card-slot-prop"
+#define AR_STYLE_PROP_CARD_THEME "card-theme"
+#define AR_STYLE_PROP_CLICK_TO_MOVE "click-to-move"
+#define AR_STYLE_PROP_DND_DRAG_THRESHOLD "dnd-drag-threshold"
+#define AR_STYLE_PROP_DOUBLE_CLICK_TIME "double-click-time"
+#define AR_STYLE_PROP_ENABLE_ANIMATIONS "enable-animations"
+#define AR_STYLE_PROP_ENABLE_SOUND "enable-sound"
+#define AR_STYLE_PROP_FOCUS_LINE_WIDTH "focus-line-width"
+#define AR_STYLE_PROP_FOCUS_PADDING "focus-padding"
+#define AR_STYLE_PROP_INTERIOR_FOCUS "interior-focus"
+#define AR_STYLE_PROP_RTL "rtl"
+#define AR_STYLE_PROP_SELECTION_COLOR "selection-color"
+#define AR_STYLE_PROP_TOUCHSCREEN_MODE "touchscreen-mode"
+
+gboolean ar_style_get_enable_animations (ArStyle *style);
+void ar_style_set_enable_animations (ArStyle *style,
+ gboolean enable);
+
+gboolean ar_style_get_enable_sound (ArStyle *style);
+void ar_style_set_enable_sound (ArStyle *style,
+ gboolean enable);
+
+gboolean ar_style_get_click_to_move (ArStyle *style);
+void ar_style_set_click_to_move (ArStyle *style,
+ gboolean enable);
+
+GamesCardTheme *ar_style_get_card_theme (ArStyle *style);
+void ar_style_set_card_theme (ArStyle *style,
+ GamesCardTheme *theme);
+
+/* Read-only properties */
+gboolean ar_style_get_touchscreen_mode (ArStyle *style);
+gboolean ar_style_get_interior_focus (ArStyle *style);
+gboolean ar_style_get_rtl (ArStyle *style);
+
+int ar_style_get_double_click_time (ArStyle *style);
+int ar_style_get_focus_line_width (ArStyle *style);
+int ar_style_get_focus_padding (ArStyle *style);
+
+double ar_style_get_card_slot_ratio (ArStyle *style);
+
+void ar_style_get_selection_color (ArStyle *style,
+ ClutterColor * const color);
+
+gboolean ar_style_check_dnd_drag_threshold (ArStyle *style,
+ float x1,
+ float y1,
+ float x2,
+ float y2);
+
+G_END_DECLS
+
+#endif /* __AR_STYLE_H__ */
diff --git a/aisleriot/baize.c b/aisleriot/baize.c
index 51ec6fa..f298977 100644
--- a/aisleriot/baize.c
+++ b/aisleriot/baize.c
@@ -17,16 +17,55 @@
#include <config.h>
-#include <clutter/clutter.h>
+#include "baize.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
#include <cogl/cogl.h>
-#include "baize.h"
+#include <libgames-support/games-runtime.h>
/* Special version of ClutterTexture that repeats the texture to fill
the entire stage. This is used to paint the baize background */
static void aisleriot_baize_paint (ClutterActor *actor);
+static void
+load_background (AisleriotBaize *baize)
+{
+ GError *error = NULL;
+ GdkPixbuf *pixbuf;
+ char *path;
+
+ path = games_runtime_get_file (GAMES_RUNTIME_PIXMAP_DIRECTORY, "baize.png");
+
+ pixbuf = gdk_pixbuf_new_from_file (path, &error);
+ g_free (path);
+ if (error) {
+ g_warning ("Failed to load the baize pixbuf: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ g_assert (pixbuf != NULL);
+
+ clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (baize),
+ gdk_pixbuf_get_pixels (pixbuf),
+ gdk_pixbuf_get_has_alpha (pixbuf),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
+ gdk_pixbuf_get_rowstride (pixbuf),
+ gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3,
+ 0,
+ &error);
+ if (error) {
+ g_warning ("Failed to set texture from pixbuf: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (pixbuf);
+}
+
G_DEFINE_TYPE (AisleriotBaize, aisleriot_baize, CLUTTER_TYPE_TEXTURE);
static void
@@ -38,16 +77,15 @@ aisleriot_baize_class_init (AisleriotBaizeClass *klass)
}
static void
-aisleriot_baize_init (AisleriotBaize *self)
+aisleriot_baize_init (AisleriotBaize *baize)
{
+ load_background (baize);
}
ClutterActor *
aisleriot_baize_new (void)
{
- ClutterActor *self = g_object_new (AISLERIOT_TYPE_BAIZE, NULL);
-
- return self;
+ return g_object_new (AISLERIOT_TYPE_BAIZE, NULL);
}
static void
diff --git a/aisleriot/board-noclutter.c b/aisleriot/board-noclutter.c
index 3c2f586..b83c11b 100644
--- a/aisleriot/board-noclutter.c
+++ b/aisleriot/board-noclutter.c
@@ -38,7 +38,7 @@
#include "game.h"
-#include "board.h"
+#include "board-noclutter.h"
#define AISLERIOT_BOARD_GET_PRIVATE(board)(G_TYPE_INSTANCE_GET_PRIVATE ((board), AISLERIOT_TYPE_BOARD, AisleriotBoardPrivate))
@@ -135,7 +135,7 @@ struct _AisleriotBoardPrivate
/* Cards cache */
GamesCardImages *images;
- /* Slot */
+ /* ArSlot */
gpointer slot_image; /* either a GdkPixbuf or GdkPixmap, depending on drawing mode */
/* Button press */
@@ -145,38 +145,38 @@ struct _AisleriotBoardPrivate
guint32 last_click_time;
/* Moving cards */
- Slot *moving_cards_origin_slot;
+ ArSlot *moving_cards_origin_slot;
int moving_cards_origin_card_id; /* The index of the card that was clicked on in hslot->cards; or -1 if the click wasn't on a card */
GdkWindow *moving_cards_window;
GByteArray *moving_cards;
/* The 'reveal card' action's slot and card link */
- Slot *show_card_slot;
+ ArSlot *show_card_slot;
int show_card_id;
/* Click data */
- Slot *last_clicked_slot;
+ ArSlot *last_clicked_slot;
int last_clicked_card_id;
/* Focus handling */
- Slot *focus_slot;
+ ArSlot *focus_slot;
int focus_card_id; /* -1 for focused empty slot */
int focus_line_width;
int focus_padding;
GdkRectangle focus_rect;
/* Selection */
- Slot *selection_slot;
+ ArSlot *selection_slot;
int selection_start_card_id;
GdkRectangle selection_rect;
GdkColor selection_colour;
/* Highlight */
- Slot *highlight_slot;
+ ArSlot *highlight_slot;
#ifdef HAVE_MAEMO
/* Tap-and-Hold */
- Slot *tap_and_hold_slot;
+ ArSlot *tap_and_hold_slot;
int tap_and_hold_card_id;
#endif
@@ -227,12 +227,12 @@ static guint signals[LAST_SIGNAL];
static void get_slot_and_card_from_point (AisleriotBoard *board,
int x,
int y,
- Slot **slot,
+ ArSlot **slot,
int *_cardid);
static void slot_update_card_images (AisleriotBoard *board,
- Slot *slot);
+ ArSlot *slot);
static void slot_update_card_images_full (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int highlight_start_card_id);
#ifndef HAVE_HILDON
@@ -334,9 +334,9 @@ set_cursor_by_location (AisleriotBoard *board,
{
#ifndef HAVE_HILDON
AisleriotBoardPrivate *priv = board->priv;
- Slot *selection_slot = priv->selection_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
- Slot *slot;
+ ArSlot *slot;
int card_id;
gboolean drop_valid = FALSE;
CursorType cursor = CURSOR_DEFAULT;
@@ -426,7 +426,7 @@ static void
get_slot_and_card_from_point (AisleriotBoard *board,
int x,
int y,
- Slot **slot,
+ ArSlot **slot,
int *_cardid)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -443,7 +443,7 @@ get_slot_and_card_from_point (AisleriotBoard *board,
n_slots = slots->len;
for (i = n_slots - 1; i >= 0; --i) {
- Slot *hslot = slots->pdata[i];
+ ArSlot *hslot = slots->pdata[i];
/* if point is within our rectangle */
if (hslot->rect.x <= x && x <= hslot->rect.x + hslot->rect.width &&
@@ -490,7 +490,7 @@ get_slot_and_card_from_point (AisleriotBoard *board,
#ifdef ENABLE_KEYNAV
static gboolean
-test_slot_projection_intersects_x (Slot *slot,
+test_slot_projection_intersects_x (ArSlot *slot,
int x_start,
int x_end)
{
@@ -500,7 +500,7 @@ test_slot_projection_intersects_x (Slot *slot,
static int
get_slot_index_from_slot (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
@@ -527,7 +527,7 @@ get_slot_index_from_slot (AisleriotBoard *board,
static void
get_rect_by_slot_and_card (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
int num_cards,
GdkRectangle *rect)
@@ -597,7 +597,7 @@ get_focus_rect (AisleriotBoard *board,
static void
set_focus (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
gboolean show_focus)
{
@@ -666,7 +666,7 @@ get_selection_rect (AisleriotBoard *board,
static void
set_selection (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
gboolean show_selection)
{
@@ -715,7 +715,7 @@ set_selection (AisleriotBoard *board,
static void
slot_update_geometry (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
GtkWidget *widget = GTK_WIDGET (board);
@@ -835,7 +835,7 @@ slot_update_geometry (AisleriotBoard *board,
static void
slot_update_card_images_full (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int highlight_start_card_id)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -888,7 +888,7 @@ slot_update_card_images_full (AisleriotBoard *board,
static void
slot_update_card_images (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
int highlight_start_card_id = G_MAXINT;
@@ -980,7 +980,7 @@ aisleriot_board_setup_geometry (AisleriotBoard *board)
n_slots = slots->len;
for (i = 0; i < n_slots; ++i) {
- Slot *slot = slots->pdata[i];
+ ArSlot *slot = slots->pdata[i];
slot_update_geometry (board, slot);
slot_update_card_images (board, slot);
@@ -996,7 +996,7 @@ drag_begin (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
GtkWidget *widget = GTK_WIDGET (board);
- Slot *hslot;
+ ArSlot *hslot;
int delta, height, width;
int x, y;
GdkPixmap *moving_pixmap;
@@ -1193,7 +1193,7 @@ drag_end (AisleriotBoard *board,
static gboolean
cards_are_droppable (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -1206,14 +1206,14 @@ cards_are_droppable (AisleriotBoard *board,
priv->moving_cards->len);
}
-static Slot *
+static ArSlot *
find_drop_target (AisleriotBoard *board,
gint x,
gint y)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *new_hslot;
- Slot *retval = NULL;
+ ArSlot *new_hslot;
+ ArSlot *retval = NULL;
gint i, new_cardid;
gint min_distance = G_MAXINT;
@@ -1261,7 +1261,7 @@ drop_moving_cards (AisleriotBoard *board,
gint y)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *hslot;
+ ArSlot *hslot;
gboolean moved = FALSE;
hslot = find_drop_target (board,
@@ -1292,7 +1292,7 @@ drop_moving_cards (AisleriotBoard *board,
static void
highlight_drop_target (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
GtkWidget *widget = GTK_WIDGET (board);
@@ -1347,7 +1347,7 @@ highlight_drop_target (AisleriotBoard *board,
static void
reveal_card (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int cardid)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -1431,10 +1431,10 @@ aisleriot_board_settings_update (GtkSettings *settings,
/* Note: this unsets the selection! hslot may be equal to priv->selection_slot. */
static gboolean
aisleriot_board_move_selected_cards_to_slot (AisleriotBoard *board,
- Slot *hslot)
+ ArSlot *hslot)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *selection_slot = priv->selection_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
gboolean moved;
guint8 *cards;
@@ -1620,7 +1620,7 @@ aisleriot_board_move_cursor_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot;
+ ArSlot *focus_slot;
int new_focus_card_id, first_card_id;
focus_slot = priv->focus_slot;
@@ -1638,7 +1638,7 @@ aisleriot_board_move_cursor_start_end_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int first_card_id, top_card_id, new_focus_card_id;
guint8 *cards;
@@ -1695,7 +1695,7 @@ aisleriot_board_extend_selection_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot, *selection_slot;
+ ArSlot *focus_slot, *selection_slot;
int new_selection_start_card_id, first_card_id;
focus_slot = priv->focus_slot;
@@ -1744,7 +1744,7 @@ static gboolean
aisleriot_board_extend_selection_in_slot_maximal (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int new_selection_start_card_id, n_selected;
n_selected = 0;
@@ -1776,7 +1776,7 @@ aisleriot_board_move_cursor_left_right_by_slot (AisleriotBoard *board,
GtkWidget *widget = GTK_WIDGET (board);
GPtrArray *slots;
guint n_slots;
- Slot *focus_slot, *new_focus_slot;
+ ArSlot *focus_slot, *new_focus_slot;
int focus_slot_index, new_focus_slot_index;
int new_focus_slot_topmost_card_id, new_focus_card_id;
gboolean is_rtl;
@@ -1860,7 +1860,7 @@ aisleriot_board_move_cursor_up_down_by_slot (AisleriotBoard *board,
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
guint n_slots;
- Slot *focus_slot, *new_focus_slot;
+ ArSlot *focus_slot, *new_focus_slot;
int focus_slot_index, new_focus_slot_index;
int new_focus_slot_topmost_card_id, new_focus_card_id;
int x_start, x_end;
@@ -1945,7 +1945,7 @@ aisleriot_board_move_cursor_start_end_by_slot (AisleriotBoard *board,
{
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
- Slot *new_focus_slot;
+ ArSlot *new_focus_slot;
int new_focus_card_id;
slots = aisleriot_game_get_slots (priv->game);
@@ -1953,10 +1953,10 @@ aisleriot_board_move_cursor_start_end_by_slot (AisleriotBoard *board,
return FALSE;
if (count > 0) {
- new_focus_slot = (Slot *) slots->pdata[slots->len - 1];
+ new_focus_slot = (ArSlot *) slots->pdata[slots->len - 1];
new_focus_card_id = ((int) new_focus_slot->cards->len) - 1;
} else {
- new_focus_slot = (Slot *) slots->pdata[0];
+ new_focus_slot = (ArSlot *) slots->pdata[0];
if (new_focus_slot->cards->len > 0) {
new_focus_card_id = ((int) new_focus_slot->cards->len) - ((int) new_focus_slot->exposed);
} else {
@@ -2044,7 +2044,7 @@ aisleriot_board_extend_selection_start_end (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int new_focus_card_id;
if (count > 0) {
@@ -2135,7 +2135,7 @@ game_new_cb (AisleriotGame *game,
static void
slot_changed_cb (AisleriotGame *game,
- Slot *slot,
+ ArSlot *slot,
AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -2191,8 +2191,8 @@ aisleriot_board_activate (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
GtkWidget *widget = GTK_WIDGET (board);
- Slot *focus_slot = priv->focus_slot;
- Slot *selection_slot = priv->selection_slot;
+ ArSlot *focus_slot = priv->focus_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
guint state = 0;
@@ -2358,7 +2358,7 @@ static void
aisleriot_board_select_all (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
if (!focus_slot ||
focus_slot->cards->len == 0 ||
@@ -2378,7 +2378,7 @@ static void
aisleriot_board_toggle_selection (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot;
+ ArSlot *focus_slot;
int focus_card_id;
focus_slot = priv->focus_slot;
@@ -2562,7 +2562,7 @@ aisleriot_board_style_set (GtkWidget *widget,
priv->selection_colour = *colour;
gdk_color_free (colour);
} else {
- const GdkColor default_colour = { 0, 0 /* red */, 0 /* green */, 0xaa00 /* blue */};
+ static const GdkColor default_colour = { 0, 0 /* red */, 0 /* green */, 0xaa00 /* blue */};
priv->selection_colour = default_colour;
}
@@ -2717,7 +2717,7 @@ aisleriot_board_button_press (GtkWidget *widget,
{
AisleriotBoard *board = AISLERIOT_BOARD (widget);
AisleriotBoardPrivate *priv = board->priv;
- Slot *hslot;
+ ArSlot *hslot;
int cardid;
guint button;
gboolean drag_valid;
@@ -2793,7 +2793,7 @@ aisleriot_board_button_press (GtkWidget *widget,
* different cards and a double-click on one card.
*/
if (is_double_click) {
- Slot *clicked_slot = hslot;
+ ArSlot *clicked_slot = hslot;
priv->click_status = STATUS_NONE;
@@ -2925,7 +2925,7 @@ aisleriot_board_button_release (GtkWidget *widget,
case STATUS_MAYBE_DRAG:
case STATUS_NOT_DRAG: {
- Slot *slot;
+ ArSlot *slot;
int card_id;
/* Don't do the action if the mouse moved away from the clicked slot; see bug #329183 */
@@ -2969,7 +2969,7 @@ aisleriot_board_motion_notify (GtkWidget *widget,
*/
if (priv->click_status == STATUS_IS_DRAG) {
- Slot *slot;
+ ArSlot *slot;
int x, y;
x = event->x - priv->last_click_x;
@@ -3014,7 +3014,7 @@ aisleriot_board_tap_and_hold_query_cb (GtkWidget *widget,
AisleriotBoardPrivate *priv = board->priv;
/* BadDocs! should mention that this is a GdkEventButton! */
GdkEventButton *event = (GdkEventButton *) _event;
- Slot *slot;
+ ArSlot *slot;
int card_id;
/* NOTE: Returning TRUE from this function means that tap-and-hold
@@ -3064,8 +3064,8 @@ aisleriot_board_expose_event (GtkWidget *widget,
int i, n_rects;
GPtrArray *slots;
guint n_slots;
- Slot **exposed_slots;
- Slot *highlight_slot;
+ ArSlot **exposed_slots;
+ ArSlot *highlight_slot;
guint n_exposed_slots;
gboolean use_pixbuf_drawing = priv->use_pixbuf_drawing;
GdkWindow *window;
@@ -3117,11 +3117,11 @@ aisleriot_board_expose_event (GtkWidget *widget,
/* First check which slots are exposed */
/* It's fine to allocate on the stack, since there'll never be very many slots */
- exposed_slots = g_newa (Slot*, n_slots);
+ exposed_slots = g_newa (ArSlot *, n_slots);
n_exposed_slots = 0;
for (i = 0; i < n_slots; ++i) {
- Slot *slot = slots->pdata[i];
+ ArSlot *slot = slots->pdata[i];
/* Check whether this slot needs to be drawn */
if (gdk_region_rect_in (region, &slot->rect) == GDK_OVERLAP_RECTANGLE_OUT)
@@ -3136,7 +3136,7 @@ aisleriot_board_expose_event (GtkWidget *widget,
* (e.g. in Elevator, after a card was removed).
*/
for (i = 0; i < n_exposed_slots; ++i) {
- Slot *hslot = exposed_slots[i];
+ ArSlot *hslot = exposed_slots[i];
int x, y;
/* FIXMEchpe: if ((hslot->length - hslot->exposed) >= 0) ?? */
@@ -3185,7 +3185,7 @@ aisleriot_board_expose_event (GtkWidget *widget,
/* Now draw the cards */
for (i = 0; i < n_exposed_slots; ++i) {
- Slot *hslot = exposed_slots[i];
+ ArSlot *hslot = exposed_slots[i];
GByteArray *cards = hslot->cards;
gpointer *card_images = hslot->card_images->pdata;
GdkRectangle card_rect;
diff --git a/aisleriot/board-noclutter.h b/aisleriot/board-noclutter.h
new file mode 100644
index 0000000..21691b3
--- /dev/null
+++ b/aisleriot/board-noclutter.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 1998, 2003 Jonathan Blandford <jrb mit edu>
+ * Copyright © 2007 Christian Persch
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AISLERIOT_BOARD_H
+#define AISLERIOT_BOARD_H
+
+#include <gtk/gtk.h>
+
+#include <libgames-support/games-card-theme.h>
+
+#include "game.h"
+
+G_BEGIN_DECLS
+
+#define AISLERIOT_TYPE_BOARD (aisleriot_board_get_type ())
+#define AISLERIOT_BOARD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), AISLERIOT_TYPE_BOARD, AisleriotBoard))
+#define AISLERIOT_BOARD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), AISLERIOT_TYPE_BOARD, AisleriotBoardClass))
+#define AISLERIOT_IS_BOARD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), AISLERIOT_TYPE_BOARD))
+#define AISLERIOT_IS_BOARD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), AISLERIOT_TYPE_BOARD))
+#define AISLERIOT_BOARD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), AISLERIOT_TYPE_BOARD, AisleriotBoardClass))
+
+typedef struct _AisleriotBoard AisleriotBoard;
+typedef struct _AisleriotBoardPrivate AisleriotBoardPrivate;
+typedef struct _AisleriotBoardClass AisleriotBoardClass;
+
+struct _AisleriotBoard {
+ GtkDrawingArea parent_instance;
+
+ /*< private >*/
+ AisleriotBoardPrivate *priv;
+};
+
+struct _AisleriotBoardClass {
+ GtkDrawingAreaClass parent_class;
+
+ /* keybinding signals */
+ gboolean (* move_cursor) (AisleriotBoard *board,
+ GtkMovementStep step,
+ int count);
+ void (* activate) (AisleriotBoard *board);
+ void (* toggle_selection) (AisleriotBoard *board);
+ void (* select_all) (AisleriotBoard *board);
+ void (* deselect_all) (AisleriotBoard *board);
+};
+
+GType aisleriot_board_get_type (void);
+
+GtkWidget *aisleriot_board_new (AisleriotGame *game);
+
+void aisleriot_board_set_card_theme (AisleriotBoard * board,
+ GamesCardTheme *theme);
+
+GamesCardTheme *aisleriot_board_get_card_theme (AisleriotBoard * board);
+
+void aisleriot_board_set_click_to_move (AisleriotBoard * board,
+ gboolean click_to_move);
+
+void aisleriot_board_set_animation_mode (AisleriotBoard *board,
+ gboolean enable);
+
+void aisleriot_board_abort_move (AisleriotBoard * board);
+
+void aisleriot_board_set_pixbuf_drawing (AisleriotBoard * board,
+ gboolean use_pixbuf_drawing);
+
+G_END_DECLS
+
+#endif /* !AISLERIOT_BOARD_H */
diff --git a/aisleriot/board.c b/aisleriot/board.c
index 24a6c95..46ad3cd 100644
--- a/aisleriot/board.c
+++ b/aisleriot/board.c
@@ -1,6 +1,6 @@
/*
* Copyright © 1998, 2003 Jonathan Blandford <jrb mit edu>
- * Copyright © 2007, 2008 Christian Persch
+ * Copyright © 2007, 2008, 2009 Christian Persch
*
* Some code copied from gtk+/gtk/gtkiconview (LGPL2+):
* Copyright © 2002, 2004 Anders Carlsson <andersca gnu org>
@@ -29,19 +29,19 @@
#include <clutter/clutter.h>
#include <libgames-support/games-card-textures-cache.h>
+#include <libgames-support/games-debug.h>
#include <libgames-support/games-files.h>
#include <libgames-support/games-marshal.h>
#include <libgames-support/games-pixbuf-utils.h>
-#include <libgames-support/games-runtime.h>
#include <libgames-support/games-sound.h>
#include "conf.h"
#include "game.h"
#include "board.h"
-#include "baize.h"
#include "card.h"
#include "slot-renderer.h"
+#include "ar-cursor.h"
#define AISLERIOT_BOARD_GET_PRIVATE(board)(G_TYPE_INSTANCE_GET_PRIVATE ((board), AISLERIOT_TYPE_BOARD, AisleriotBoardPrivate))
@@ -61,40 +61,16 @@
#define MAX_DELTA (0.2)
#define MAX_OVERHANG (0.2)
-/* The proportion of a slot dedicated to the card (horiz or vert). */
-#ifndef DEFAULT_CARD_SLOT_RATIO
-#ifdef HAVE_HILDON
-#define DEFAULT_CARD_SLOT_RATIO (0.9)
-#else
-#define DEFAULT_CARD_SLOT_RATIO (0.8)
-#endif
-#endif /* !DEFAULT_CARD_SLOT_RATIO */
-
#define DOUBLE_TO_INT_CEIL(d) ((int) (d + 0.5))
#define STATIC_ASSERT(condition) STATIC_ASSERT_IMPL(condition, __LINE__)
#define STATIC_ASSERT_IMPL(condition, line) STATIC_ASSERT_IMPL2(condition, line)
#define STATIC_ASSERT_IMPL2(condition, line) typedef int _static_assert_line_##line[(condition) ? 1 : -1]
-#ifdef HAVE_HILDON
-#define PIXBUF_DRAWING_LIKELIHOOD(cond) G_UNLIKELY (cond)
-#else
-#define PIXBUF_DRAWING_LIKELIHOOD(cond) (cond)
-#endif /* HAVE_HILDON */
-
-#if GLIB_CHECK_VERSION (2, 10, 0)
#define I_(string) g_intern_static_string (string)
-#else
-#define I_(string) string
-#endif
-typedef enum {
- CURSOR_DEFAULT,
- CURSOR_OPEN,
- CURSOR_CLOSED,
- CURSOR_DROPPABLE,
- LAST_CURSOR
-} CursorType;
+#pragma GCC poison GtkWidget
+#pragma GCC poison widget
typedef enum {
STATUS_NONE,
@@ -105,14 +81,33 @@ typedef enum {
LAST_STATUS
} MoveStatus;
+#ifdef ENABLE_KEYNAV
+
+#define MOVE_CURSOR_LEFT_RIGHT 'h'
+#define MOVE_CURSOR_LEFT_RIGHT_S "h"
+#define MOVE_CURSOR_UP_DOWN 'v'
+#define MOVE_CURSOR_UP_DOWN_S "v"
+#define MOVE_CURSOR_PAGES 'p'
+#define MOVE_CURSOR_PAGES_S "p"
+#define MOVE_CURSOR_START_END 'e'
+#define MOVE_CURSOR_START_END_S "e"
+
+#define MOVE_LEFT 'l'
+#define MOVE_LEFT_S "l"
+#define MOVE_RIGHT 'r'
+#define MOVE_RIGHT_S "r"
+
+#endif /* ENABLE_KEYNAV */
+
struct _AisleriotBoardPrivate
{
AisleriotGame *game;
- GdkCursor *cursor[LAST_CURSOR];
+ ArStyle *style;
+
+ ClutterActorBox allocation;
/* Card theme */
- GamesCardTheme *theme;
CardSize card_size;
/* Cards cache */
@@ -137,11 +132,10 @@ struct _AisleriotBoardPrivate
/* Button press */
int last_click_x;
int last_click_y;
- int double_click_time;
guint32 last_click_time;
/* Moving cards */
- Slot *moving_cards_origin_slot;
+ ArSlot *moving_cards_origin_slot;
int moving_cards_origin_card_id; /* The index of the card that was clicked on in hslot->cards; or -1 if the click wasn't on a card */
ClutterActor *moving_cards_group;
GByteArray *moving_cards;
@@ -150,31 +144,26 @@ struct _AisleriotBoardPrivate
ClutterActor *animation_layer;
/* The 'reveal card' action's slot and card link */
- Slot *show_card_slot;
+ ArSlot *show_card_slot;
int show_card_id;
/* Click data */
- Slot *last_clicked_slot;
+ ArSlot *last_clicked_slot;
int last_clicked_card_id;
/* Focus handling */
- Slot *focus_slot;
+ ArSlot *focus_slot;
int focus_card_id; /* -1 for focused empty slot */
int focus_line_width;
int focus_padding;
GdkRectangle focus_rect;
/* Selection */
- Slot *selection_slot;
+ ArSlot *selection_slot;
int selection_start_card_id;
- GdkRectangle selection_rect;
- ClutterColor selection_colour;
/* Highlight */
- Slot *highlight_slot;
-
- /* Actor used for drawing the baize */
- ClutterActor *baize_actor;
+ ArSlot *highlight_slot;
/* Array RemovedCards to be dropped in animations */
GArray *removed_cards;
@@ -183,12 +172,6 @@ struct _AisleriotBoardPrivate
trigger animations */
guint check_animations_handler;
-#ifdef HAVE_MAEMO
- /* Tap-and-Hold */
- Slot *tap_and_hold_slot;
- int tap_and_hold_card_id;
-#endif
-
/* Bit field */
guint droppable_supported : 1;
guint touchscreen_mode : 1;
@@ -208,9 +191,6 @@ struct _AisleriotBoardPrivate
guint show_highlight : 1;
guint force_geometry_update : 1;
-
- guint animation_mode : 1; /* user setting */
- guint animations_enabled: 1; /* gtk setting */
};
typedef struct _RemovedCard RemovedCard;
@@ -228,119 +208,44 @@ enum
{
PROP_0,
PROP_GAME,
- PROP_THEME
+ PROP_STYLE
};
-#ifdef ENABLE_KEYNAV
enum
{
+ REQUEST_CURSOR,
+ ERROR_BELL,
+ FOCUS,
+#ifdef ENABLE_KEYNAV
ACTIVATE,
MOVE_CURSOR,
TOGGLE_SELECTION,
SELECT_ALL,
DESELECT_ALL,
+#endif /* ENABLE_KEYNAV */
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
-#endif /* ENABLE_KEYNAV */
static void get_slot_and_card_from_point (AisleriotBoard *board,
int x,
int y,
- Slot **slot,
+ ArSlot **slot,
int *_cardid);
static void slot_update_card_images (AisleriotBoard *board,
- Slot *slot);
+ ArSlot *slot);
static void slot_update_card_images_full (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
gint highlight_start_card_id);
-#ifndef HAVE_HILDON
-
-/* These cursors borrowed from EOG */
-/* FIXMEchpe use themeable cursors here! */
-#define hand_closed_data_width 20
-#define hand_closed_data_height 20
-static const char hand_closed_data_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00,
- 0x80, 0xff, 0x00, 0x80, 0xff, 0x00, 0xb0, 0xff, 0x00, 0xf0, 0xff, 0x00,
- 0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
- 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#define hand_closed_mask_width 20
-#define hand_closed_mask_height 20
-static const char hand_closed_mask_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0xff, 0x00,
- 0xc0, 0xff, 0x01, 0xf0, 0xff, 0x01, 0xf8, 0xff, 0x01, 0xf8, 0xff, 0x01,
- 0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
- 0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#define hand_open_data_width 20
-#define hand_open_data_height 20
-static const char hand_open_data_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
- 0x60, 0x36, 0x00, 0x60, 0x36, 0x00, 0xc0, 0x36, 0x01, 0xc0, 0xb6, 0x01,
- 0x80, 0xbf, 0x01, 0x98, 0xff, 0x01, 0xb8, 0xff, 0x00, 0xf0, 0xff, 0x00,
- 0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
- 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#define hand_open_mask_width 20
-#define hand_open_mask_height 20
-static const char hand_open_mask_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x3f, 0x00,
- 0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x01, 0xe0, 0xff, 0x03, 0xe0, 0xff, 0x03,
- 0xd8, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfc, 0xff, 0x01, 0xf8, 0xff, 0x01,
- 0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
- 0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#endif /* !HAVE_HILDON */
-
-/* Cursor */
-
-#ifndef HAVE_HILDON
-
-static GdkCursor *
-make_cursor (GtkWidget *widget,
- const char *data,
- const char *mask_data)
-{
- const GdkColor fg = { 0, 65535, 65535, 65535 };
- const GdkColor bg = { 0, 0, 0, 0 };
- GdkPixmap *source;
- GdkPixmap *mask;
- GdkCursor *cursor;
-
- /* Yeah, hard-coded sizes are bad. */
- source = gdk_bitmap_create_from_data (widget->window, data, 20, 20);
- mask = gdk_bitmap_create_from_data (widget->window, mask_data, 20, 20);
-
- cursor = gdk_cursor_new_from_pixmap (source, mask, &fg, &bg, 10, 10);
-
- g_object_unref (source);
- g_object_unref (mask);
-
- return cursor;
-}
-
-#endif /* !HAVE_HILDON */
+static void aisleriot_board_setup_geometry (AisleriotBoard *board);
static void
set_cursor (AisleriotBoard *board,
- CursorType cursor)
+ ArCursorType cursor)
{
-#ifndef HAVE_HILDON
- AisleriotBoardPrivate *priv = board->priv;
-
- gdk_window_set_cursor (GTK_WIDGET (board)->window,
- priv->cursor[cursor]);
-#endif /* !HAVE_HILDON */
+ g_signal_emit (board, signals[REQUEST_CURSOR], 0, (int) cursor);
}
/* If we are over a slot, set the cursor to the given cursor,
@@ -352,12 +257,12 @@ set_cursor_by_location (AisleriotBoard *board,
{
#ifndef HAVE_HILDON
AisleriotBoardPrivate *priv = board->priv;
- Slot *selection_slot = priv->selection_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
- Slot *slot;
+ ArSlot *slot;
int card_id;
gboolean drop_valid = FALSE;
- CursorType cursor = CURSOR_DEFAULT;
+ ArCursorType cursor = AR_CURSOR_DEFAULT;
get_slot_and_card_from_point (board, x, y, &slot, &card_id);
@@ -377,14 +282,14 @@ set_cursor_by_location (AisleriotBoard *board,
/* FIXMEchpe: special cursor when _drag_ is possible? */
if (drop_valid) {
- cursor = CURSOR_DROPPABLE;
+ cursor = AR_CURSOR_DROPPABLE;
} else if (slot != NULL &&
card_id >= 0 &&
!CARD_GET_FACE_DOWN (CARD (slot->cards->data[card_id]))) {
if (priv->click_status == STATUS_NONE) {
- cursor = CURSOR_OPEN;
+ cursor = AR_CURSOR_OPEN;
} else {
- cursor = CURSOR_CLOSED;
+ cursor = AR_CURSOR_CLOSED;
}
}
@@ -392,62 +297,13 @@ set_cursor_by_location (AisleriotBoard *board,
#endif /* !HAVE_HILDON */
}
-/* card drawing functions */
-
-static void
-set_background_from_baize (AisleriotBoard *board)
-{
- AisleriotBoardPrivate *priv = board->priv;
- GError *error = NULL;
- GdkPixbuf *pixbuf;
- char *path;
-
- path = games_runtime_get_file (GAMES_RUNTIME_PIXMAP_DIRECTORY, "baize.png");
-
- pixbuf = gdk_pixbuf_new_from_file (path, &error);
- g_free (path);
- if (error) {
- g_warning ("Failed to load the baize pixbuf: %s\n", error->message);
- g_error_free (error);
- return;
- }
-
- g_assert (pixbuf != NULL);
-
- if (priv->baize_actor == NULL) {
- ClutterActor *stage;
-
- stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
-
- priv->baize_actor = g_object_ref_sink (aisleriot_baize_new ());
- clutter_container_add (CLUTTER_CONTAINER (stage),
- priv->baize_actor, NULL);
- }
-
- clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (priv->baize_actor),
- gdk_pixbuf_get_pixels (pixbuf),
- gdk_pixbuf_get_has_alpha (pixbuf),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- gdk_pixbuf_get_rowstride (pixbuf),
- gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3,
- 0,
- &error);
- if (error) {
- g_warning ("Failed to set texture from pixbuf: %s", error->message);
- g_error_free (error);
- }
-
- g_object_unref (pixbuf);
-}
-
/* Slot helpers */
static void
get_slot_and_card_from_point (AisleriotBoard *board,
int x,
int y,
- Slot **slot,
+ ArSlot **slot,
int *_cardid)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -464,7 +320,7 @@ get_slot_and_card_from_point (AisleriotBoard *board,
n_slots = slots->len;
for (i = n_slots - 1; i >= 0; --i) {
- Slot *hslot = slots->pdata[i];
+ ArSlot *hslot = slots->pdata[i];
/* if point is within our rectangle */
if (hslot->rect.x <= x && x <= hslot->rect.x + hslot->rect.width &&
@@ -511,7 +367,7 @@ get_slot_and_card_from_point (AisleriotBoard *board,
#ifdef ENABLE_KEYNAV
static gboolean
-test_slot_projection_intersects_x (Slot *slot,
+test_slot_projection_intersects_x (ArSlot *slot,
int x_start,
int x_end)
{
@@ -521,7 +377,7 @@ test_slot_projection_intersects_x (Slot *slot,
static int
get_slot_index_from_slot (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
@@ -548,7 +404,7 @@ get_slot_index_from_slot (AisleriotBoard *board,
static void
get_rect_by_slot_and_card (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
int num_cards,
GdkRectangle *rect)
@@ -618,12 +474,12 @@ get_focus_rect (AisleriotBoard *board,
static void
set_focus (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
gboolean show_focus)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
+// GtkWidget *widget = GTK_WIDGET (board);
int top_card_id;
/* Sanitise */
@@ -636,12 +492,14 @@ set_focus (AisleriotBoard *board,
return;
if (priv->focus_slot != NULL) {
+#ifdef FIXMEchpe
if (priv->show_focus &&
GTK_WIDGET_HAS_FOCUS (widget)) {
gdk_window_invalidate_rect (widget->window, &priv->focus_rect, FALSE);
priv->show_focus = FALSE;
}
+#endif
priv->focus_slot = NULL;
priv->focus_card_id = -1;
@@ -655,41 +513,24 @@ set_focus (AisleriotBoard *board,
priv->focus_slot = slot;
priv->focus_card_id = card_id;
+#ifdef FIXMEchpe
if (show_focus &&
GTK_WIDGET_HAS_FOCUS (widget)) {
get_focus_rect (board, &priv->focus_rect);
gdk_window_invalidate_rect (widget->window, &priv->focus_rect, FALSE);
}
+#endif
}
/* Selection handling */
static void
-get_selection_rect (AisleriotBoard *board,
- GdkRectangle *rect)
-{
- AisleriotBoardPrivate *priv = board->priv;
- int n_cards;
-
- if (!priv->selection_slot)
- return;
-
- n_cards = priv->selection_slot->cards->len - priv->selection_start_card_id;
-
- get_rect_by_slot_and_card (board,
- priv->selection_slot,
- priv->selection_start_card_id,
- n_cards, rect);
-}
-
-static void
set_selection (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int card_id,
gboolean show_selection)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
if (priv->selection_slot == slot &&
priv->selection_start_card_id == card_id &&
@@ -698,8 +539,6 @@ set_selection (AisleriotBoard *board,
if (priv->selection_slot != NULL) {
if (priv->show_selection) {
- gdk_window_invalidate_rect (widget->window, &priv->selection_rect, FALSE);
-
/* Clear selection card images */
slot_update_card_images_full (board, priv->selection_slot, G_MAXINT);
}
@@ -719,9 +558,6 @@ set_selection (AisleriotBoard *board,
g_assert (card_id < 0 || card_id < slot->cards->len);
if (priv->show_selection) {
- get_selection_rect (board, &priv->selection_rect);
- gdk_window_invalidate_rect (widget->window, &priv->selection_rect, FALSE);
-
slot_update_card_images_full (board, slot, card_id);
}
}
@@ -730,10 +566,10 @@ set_selection (AisleriotBoard *board,
static void
slot_update_geometry (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
+// GtkWidget *widget = GTK_WIDGET (board);
GdkRectangle old_rect;
GByteArray *cards;
int delta, xofs, yofs, pixeldx;
@@ -772,12 +608,17 @@ slot_update_geometry (AisleriotBoard *board,
if (slot->expanded_down) {
double y_from_bottom, max_dy = MAX_DELTA;
+ float allocation_height = priv->allocation.y2 - priv->allocation.y1;
if (slot->dy_set)
max_dy = slot->expansion.dy;
/* Calculate the compressed_dy that will let us fit within the board */
+#ifdef FIXMEchpe
y_from_bottom = ((double) (widget->allocation.height - slot->rect.y)) / ((double) priv->card_size.height);
+#else
+ y_from_bottom = ((double) (allocation_height - slot->rect.y)) / ((double) priv->card_size.height);
+#endif
dy = (y_from_bottom - MAX_OVERHANG) / n_cards;
dy = CLAMP (dy, MIN_DELTA, max_dy);
} else if (slot->expanded_right) {
@@ -795,11 +636,16 @@ slot_update_geometry (AisleriotBoard *board,
pixeldx = -slot->pixeldx;
} else {
double x_from_right, max_dx = MAX_DELTA;
+ float allocation_width = priv->allocation.x2 - priv->allocation.x1;
if (slot->dx_set)
max_dx = slot->expansion.dx;
+#ifdef FIXMEchpe
x_from_right = ((double) (widget->allocation.width - slot->rect.x)) / ((double) priv->card_size.width);
+#else
+ x_from_right = ((double) (allocation_width - slot->rect.x)) / ((double) priv->card_size.width);
+#endif
dx = (x_from_right - MAX_OVERHANG) / n_cards;
dx = CLAMP (dx, MIN_DELTA, max_dx);
@@ -849,7 +695,7 @@ check_animations_cb (gpointer user_data)
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
int slot_num, i;
- Slot *slot;
+ ArSlot *slot;
GArray *animations = g_array_new (FALSE, FALSE, sizeof (AisleriotAnimStart));
slots = aisleriot_game_get_slots (priv->game);
@@ -987,7 +833,6 @@ check_animations_cb (gpointer user_data)
if (slot->cards->len == 0) {
clutter_actor_lower_bottom (slot->slot_renderer);
- clutter_actor_lower_bottom (priv->baize_actor);
} else {
clutter_actor_raise_top (slot->slot_renderer);
ClutterActor *animation_layer = CLUTTER_ACTOR(aisleriot_slot_renderer_get_animation_layer(AISLERIOT_SLOT_RENDERER(slot->slot_renderer)));
@@ -1012,7 +857,7 @@ queue_check_animations (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- if (!priv->animation_mode || !priv->animations_enabled)
+ if (!ar_style_get_enable_animations (priv->style))
return;
/* The animations are checked for in an idle handler so that this
@@ -1033,24 +878,18 @@ queue_check_animations (AisleriotBoard *board)
static void
slot_update_card_images_full (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
gint highlight_start_card_id)
{
AisleriotBoardPrivate *priv = board->priv;
- ClutterActor *stage;
-
- stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
if (!priv->geometry_set)
return;
if (slot->slot_renderer == NULL) {
- slot->slot_renderer = aisleriot_slot_renderer_new (priv->textures, slot);
+ slot->slot_renderer = aisleriot_slot_renderer_new (priv->style, priv->textures, slot);
g_object_ref_sink (slot->slot_renderer);
- aisleriot_slot_renderer_set_highlight_color (AISLERIOT_SLOT_RENDERER (slot->slot_renderer),
- &priv->selection_colour);
-
aisleriot_slot_renderer_set_animation_layer
(AISLERIOT_SLOT_RENDERER (slot->slot_renderer),
CLUTTER_CONTAINER (priv->animation_layer));
@@ -1058,7 +897,7 @@ slot_update_card_images_full (AisleriotBoard *board,
clutter_actor_set_position (slot->slot_renderer,
slot->rect.x, slot->rect.y);
- clutter_container_add (CLUTTER_CONTAINER (stage),
+ clutter_container_add (CLUTTER_CONTAINER (board),
slot->slot_renderer, NULL);
clutter_actor_raise_top (priv->animation_layer);
@@ -1074,7 +913,7 @@ slot_update_card_images_full (AisleriotBoard *board,
static void
slot_update_card_images (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
int highlight_start_card_id = G_MAXINT;
@@ -1096,9 +935,7 @@ slot_update_card_images (AisleriotBoard *board,
static void
aisleriot_board_error_bell (AisleriotBoard *board)
{
-#if GTK_CHECK_VERSION (2, 12, 0) || (defined (HAVE_HILDON) && !defined(HAVE_MAEMO_3))
- gtk_widget_error_bell (GTK_WIDGET (board));
-#endif
+ g_signal_emit (board, signals[ERROR_BELL], 0);
}
/* Work out new sizes and spacings for the cards. */
@@ -1106,29 +943,35 @@ static void
aisleriot_board_setup_geometry (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
+ ClutterActor *actor = CLUTTER_ACTOR (board);
+ GamesCardTheme *theme;
GPtrArray *slots;
guint i, n_slots;
CardSize card_size;
+ if (!CLUTTER_ACTOR_IS_REALIZED (actor))
+ return;
+
/* Nothing to do yet */
if (aisleriot_game_get_state (priv->game) <= GAME_LOADED)
return;
- if (!priv->theme)
+
+ theme = ar_style_get_card_theme (priv->style);
+ if (theme == NULL)
return;
- g_return_if_fail (GTK_WIDGET_REALIZED (widget));
g_return_if_fail (priv->width > 0 && priv->height > 0);
- priv->xslotstep = ((double) widget->allocation.width) / priv->width;
- priv->yslotstep = ((double) widget->allocation.height) / priv->height;
+ // FIXMEchpe
+ priv->xslotstep = ((double) priv->allocation.x2 - priv->allocation.x1) / priv->width;
+ priv->yslotstep = ((double) priv->allocation.y2 - priv->allocation.y1) / priv->height;
- games_card_theme_set_size (priv->theme,
+ games_card_theme_set_size (theme,
priv->xslotstep,
priv->yslotstep,
priv->card_slot_ratio);
- games_card_theme_get_size (priv->theme, &card_size);
+ games_card_theme_get_size (theme, &card_size);
priv->card_size = card_size;
/* If the cards are too far apart, bunch them in the middle. */
@@ -1136,7 +979,11 @@ aisleriot_board_setup_geometry (AisleriotBoard *board)
if (priv->xslotstep > (card_size.width * 3) / 2) {
priv->xslotstep = (card_size.width * 3) / 2;
/* FIXMEchpe: if there are expand-right slots, reserve the space for them instead? */
+#ifdef FIXMEchpe
priv->xbaseoffset = (widget->allocation.width - priv->xslotstep * priv->width) / 2;
+#else
+ priv->xbaseoffset = (priv->allocation.x2 - priv->allocation.x1 - priv->xslotstep * priv->width) / 2;
+#endif
}
if (priv->yslotstep > (card_size.height * 3) / 2) {
priv->yslotstep = (card_size.height * 3) / 2;
@@ -1158,7 +1005,7 @@ aisleriot_board_setup_geometry (AisleriotBoard *board)
n_slots = slots->len;
for (i = 0; i < n_slots; ++i) {
- Slot *slot = slots->pdata[i];
+ ArSlot *slot = slots->pdata[i];
slot_update_geometry (board, slot);
slot_update_card_images (board, slot);
@@ -1166,20 +1013,18 @@ aisleriot_board_setup_geometry (AisleriotBoard *board)
/* Update the focus and selection rects */
get_focus_rect (board, &priv->focus_rect);
- get_selection_rect (board, &priv->selection_rect);
}
static void
drag_begin (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *hslot;
+ ArSlot *hslot;
int delta, height, width;
int x, y;
int num_moving_cards;
guint i;
GByteArray *cards;
- ClutterActor *stage;
if (!priv->selection_slot ||
priv->selection_start_card_id < 0) {
@@ -1263,16 +1108,14 @@ drag_begin (AisleriotBoard *board)
slot_update_card_images (board, hslot);
aisleriot_game_reset_old_cards (hslot);
- stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
- clutter_container_add (CLUTTER_CONTAINER (stage),
+ clutter_container_add (CLUTTER_CONTAINER (board),
priv->moving_cards_group, NULL);
if (hslot->cards->len == 0) {
clutter_actor_lower_bottom (hslot->slot_renderer);
- clutter_actor_lower_bottom (priv->baize_actor);
}
- set_cursor (board, CURSOR_CLOSED);
+ set_cursor (board, AR_CURSOR_CLOSED);
}
static void
@@ -1308,7 +1151,7 @@ drag_end (AisleriotBoard *board,
static gboolean
cards_are_droppable (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -1321,14 +1164,14 @@ cards_are_droppable (AisleriotBoard *board,
priv->moving_cards->len);
}
-static Slot *
+static ArSlot *
find_drop_target (AisleriotBoard *board,
gint x,
gint y)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *new_hslot;
- Slot *retval = NULL;
+ ArSlot *new_hslot;
+ ArSlot *retval = NULL;
gint i, new_cardid;
gint min_distance = G_MAXINT;
@@ -1376,7 +1219,7 @@ drop_moving_cards (AisleriotBoard *board,
gint y)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *hslot;
+ ArSlot *hslot;
gboolean moved = FALSE;
guint i;
@@ -1420,12 +1263,10 @@ drop_moving_cards (AisleriotBoard *board,
static void
highlight_drop_target (AisleriotBoard *board,
- Slot *slot)
+ ArSlot *slot)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
- GdkRectangle rect;
- Slot *old_slot = priv->highlight_slot;
+ ArSlot *old_slot = priv->highlight_slot;
if (slot == old_slot)
return;
@@ -1438,12 +1279,6 @@ highlight_drop_target (AisleriotBoard *board,
/* Invalidate the old highlight rect */
if (old_slot != NULL &&
priv->show_highlight) {
- get_rect_by_slot_and_card (board,
- old_slot,
- old_slot->cards->len - 1 /* it's ok if this is == -1 */,
- 1, &rect);
- gdk_window_invalidate_rect (widget->window, &rect, FALSE);
-
/* FIXMEchpe only update the topmost card? */
/* It's ok to call this directly here, since the old highlight_slot cannot
* have been the same as the current selection_slot!
@@ -1457,12 +1292,7 @@ highlight_drop_target (AisleriotBoard *board,
if (!priv->show_highlight)
return;
- /* Prepare the highlight pixbuf/pixmaps and invalidate the new highlight rect */
- get_rect_by_slot_and_card (board,
- slot,
- slot->cards->len - 1 /* it's ok if this is == -1 */,
- 1, &rect);
- gdk_window_invalidate_rect (widget->window, &rect, FALSE);
+ /* Prepare the highlight pixbuf/pixmaps */
/* FIXMEchpe only update the topmost card? */
/* It's ok to call this directly, since the highlight slot is always
@@ -1473,7 +1303,7 @@ highlight_drop_target (AisleriotBoard *board,
static void
reveal_card (AisleriotBoard *board,
- Slot *slot,
+ ArSlot *slot,
int cardid)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -1523,40 +1353,13 @@ clear_state (AisleriotBoard *board)
priv->last_clicked_card_id = -1;
}
-static void
-aisleriot_board_settings_update (GtkSettings *settings,
- GParamSpec *pspec,
- AisleriotBoard *board)
-{
- AisleriotBoardPrivate *priv = board->priv;
- gboolean animations_enabled;
-#if GTK_CHECK_VERSION (2, 10, 0)
- gboolean touchscreen_mode;
-#endif /* GTK >= 2.10.0 */
-
- /* Set up the double-click detection. */
- g_object_get (settings,
- "gtk-double-click-time", &priv->double_click_time,
- "gtk-enable-animations", &animations_enabled,
-#if GTK_CHECK_VERSION (2, 10, 0)
- "gtk-touchscreen-mode", &touchscreen_mode,
-#endif /* GTK >= 2.10.0 */
- NULL);
-
- priv->animations_enabled = animations_enabled;
-
-#if GTK_CHECK_VERSION (2, 10, 0)
- priv->touchscreen_mode = touchscreen_mode != FALSE;
-#endif /* GTK >= 2.10.0 */
-}
-
/* Note: this unsets the selection! */
static gboolean
aisleriot_board_move_selected_cards_to_slot (AisleriotBoard *board,
- Slot *hslot)
+ ArSlot *hslot)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *selection_slot = priv->selection_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
gboolean moved;
guint8 *cards;
@@ -1688,53 +1491,59 @@ aisleriot_board_move_selected_cards_to_slot (AisleriotBoard *board,
*/
static void
-aisleriot_board_add_move_binding (GtkBindingSet *binding_set,
- guint keyval,
- guint modmask,
- GtkMovementStep step,
- gint count)
-{
- gtk_binding_entry_add_signal (binding_set, keyval,
- modmask,
- "move-cursor", 2,
- G_TYPE_ENUM, step,
- G_TYPE_INT, count);
-
- if (modmask & GDK_CONTROL_MASK)
- return;
-
- gtk_binding_entry_add_signal (binding_set, keyval,
- modmask | GDK_CONTROL_MASK,
- "move-cursor", 2,
- G_TYPE_ENUM, step,
- G_TYPE_INT, count);
+aisleriot_board_add_move_binding (ClutterBindingPool *binding_pool,
+ GClosure *closure,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
+{
+ clutter_binding_pool_install_closure (binding_pool,
+ action,
+ keyval,
+ modifiers,
+ closure);
+
+ if (modifiers & CLUTTER_CONTROL_MASK)
+ return;
+ clutter_binding_pool_install_closure (binding_pool,
+ action,
+ keyval,
+ modifiers | CLUTTER_CONTROL_MASK,
+ closure);
}
static void
-aisleriot_board_add_move_and_select_binding (GtkBindingSet *binding_set,
- guint keyval,
- guint modmask,
- GtkMovementStep step,
- gint count)
+aisleriot_board_add_move_and_select_binding (ClutterBindingPool *binding_pool,
+ GClosure *closure,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
- aisleriot_board_add_move_binding (binding_set, keyval, modmask, step, count);
- aisleriot_board_add_move_binding (binding_set, keyval, modmask | GDK_SHIFT_MASK, step, count);
+ aisleriot_board_add_move_binding (binding_pool, closure, action, keyval, modifiers);
+ aisleriot_board_add_move_binding (binding_pool, closure, action, keyval, modifiers | CLUTTER_SHIFT_MASK);
}
static void
-aisleriot_board_add_activate_binding (GtkBindingSet *binding_set,
- guint keyval,
- guint modmask)
-{
- gtk_binding_entry_add_signal (binding_set, keyval, modmask,
- "activate", 0);
-
- if (modmask & GDK_CONTROL_MASK)
+aisleriot_board_add_activate_binding (ClutterBindingPool *binding_pool,
+ GClosure *closure,
+ guint keyval,
+ ClutterModifierType modifiers)
+{
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("activate"),
+ keyval,
+ modifiers,
+ closure);
+
+ if (modifiers & CLUTTER_CONTROL_MASK)
return;
- gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_CONTROL_MASK,
- "activate", 0);
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("activate"),
+ keyval,
+ modifiers | CLUTTER_CONTROL_MASK,
+ closure);
}
static gboolean
@@ -1742,7 +1551,7 @@ aisleriot_board_move_cursor_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot;
+ ArSlot *focus_slot;
int new_focus_card_id, first_card_id;
focus_slot = priv->focus_slot;
@@ -1760,7 +1569,7 @@ aisleriot_board_move_cursor_start_end_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int first_card_id, top_card_id, new_focus_card_id;
guint8 *cards;
@@ -1817,7 +1626,7 @@ aisleriot_board_extend_selection_in_slot (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot, *selection_slot;
+ ArSlot *focus_slot, *selection_slot;
int new_selection_start_card_id, first_card_id;
focus_slot = priv->focus_slot;
@@ -1866,7 +1675,7 @@ static gboolean
aisleriot_board_extend_selection_in_slot_maximal (AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int new_selection_start_card_id, n_selected;
n_selected = 0;
@@ -1895,16 +1704,12 @@ aisleriot_board_move_cursor_left_right_by_slot (AisleriotBoard *board,
gboolean wrap)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
GPtrArray *slots;
guint n_slots;
- Slot *focus_slot, *new_focus_slot;
+ ArSlot *focus_slot, *new_focus_slot;
int focus_slot_index, new_focus_slot_index;
int new_focus_slot_topmost_card_id, new_focus_card_id;
gboolean is_rtl;
-#if GTK_CHECK_VERSION (2, 12, 0)
- GtkDirectionType direction;
-#endif
slots = aisleriot_game_get_slots (priv->game);
if (!slots || slots->len == 0)
@@ -1918,8 +1723,8 @@ aisleriot_board_move_cursor_left_right_by_slot (AisleriotBoard *board,
focus_slot_index = get_slot_index_from_slot (board, focus_slot);
/* Move visually */
- is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
- if (is_rtl) {
+ is_rtl = priv->is_rtl;
+ if (priv->is_rtl) {
new_focus_slot_index = focus_slot_index - count;
} else {
new_focus_slot_index = focus_slot_index + count;
@@ -1931,7 +1736,11 @@ aisleriot_board_move_cursor_left_right_by_slot (AisleriotBoard *board,
if (!wrap)
return FALSE;
+#ifdef FIXMEchpe
+{
+ GtkDirectionType direction;
#if GTK_CHECK_VERSION (2, 12, 0)
+
if (count > 0) {
direction = GTK_DIR_RIGHT;
} else {
@@ -1942,6 +1751,8 @@ aisleriot_board_move_cursor_left_right_by_slot (AisleriotBoard *board,
return gtk_widget_child_focus (gtk_widget_get_toplevel (widget), direction);
}
#endif /* GTK 2.12. 0 */
+}
+#endif // FIXMEchpe
if (new_focus_slot_index < 0) {
new_focus_slot_index = ((int) n_slots) - 1;
@@ -1982,7 +1793,7 @@ aisleriot_board_move_cursor_up_down_by_slot (AisleriotBoard *board,
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
guint n_slots;
- Slot *focus_slot, *new_focus_slot;
+ ArSlot *focus_slot, *new_focus_slot;
int focus_slot_index, new_focus_slot_index;
int new_focus_slot_topmost_card_id, new_focus_card_id;
int x_start, x_end;
@@ -2009,6 +1820,7 @@ aisleriot_board_move_cursor_up_down_by_slot (AisleriotBoard *board,
!test_slot_projection_intersects_x (slots->pdata[new_focus_slot_index], x_start, x_end));
if (new_focus_slot_index < 0 || new_focus_slot_index == n_slots) {
+#ifdef FIXMEchpe
#if GTK_CHECK_VERSION (2, 12, 0)
GtkWidget *widget = GTK_WIDGET (board);
GtkDirectionType direction;
@@ -2023,6 +1835,7 @@ aisleriot_board_move_cursor_up_down_by_slot (AisleriotBoard *board,
return gtk_widget_child_focus (gtk_widget_get_toplevel (widget), direction);
}
#endif /* GTK 2.12. 0 */
+#endif // FIXMEchpe
/* Wrap around */
if (count > 0) {
@@ -2067,7 +1880,7 @@ aisleriot_board_move_cursor_start_end_by_slot (AisleriotBoard *board,
{
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
- Slot *new_focus_slot;
+ ArSlot *new_focus_slot;
int new_focus_card_id;
slots = aisleriot_game_get_slots (priv->game);
@@ -2075,10 +1888,10 @@ aisleriot_board_move_cursor_start_end_by_slot (AisleriotBoard *board,
return FALSE;
if (count > 0) {
- new_focus_slot = (Slot *) slots->pdata[slots->len - 1];
+ new_focus_slot = (ArSlot *) slots->pdata[slots->len - 1];
new_focus_card_id = ((int) new_focus_slot->cards->len) - 1;
} else {
- new_focus_slot = (Slot *) slots->pdata[0];
+ new_focus_slot = (ArSlot *) slots->pdata[0];
if (new_focus_slot->cards->len > 0) {
new_focus_card_id = ((int) new_focus_slot->cards->len) - ((int) new_focus_slot->exposed);
} else {
@@ -2099,15 +1912,11 @@ aisleriot_board_move_cursor_left_right (AisleriotBoard *board,
gboolean is_control)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
- gboolean is_rtl;
-
- is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
/* First try in-slot focus movement */
if (!is_control &&
priv->focus_slot->expanded_right &&
- aisleriot_board_move_cursor_in_slot (board, is_rtl ? -count : count))
+ aisleriot_board_move_cursor_in_slot (board, priv->is_rtl ? -count : count))
return TRUE;
/* Cannot move in-slot; move focused slot */
@@ -2120,13 +1929,9 @@ aisleriot_board_move_cursor_up_down (AisleriotBoard *board,
gboolean is_control)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
- gboolean is_rtl;
g_assert (priv->focus_slot != NULL);
- is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-
/* First try in-slot focus movement */
if (!is_control &&
priv->focus_slot->expanded_down &&
@@ -2166,7 +1971,7 @@ aisleriot_board_extend_selection_start_end (AisleriotBoard *board,
int count)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
int new_focus_card_id;
if (count > 0) {
@@ -2254,13 +2059,11 @@ game_new_cb (AisleriotGame *game,
/* Check for animations so that the differences will be reset */
queue_check_animations (board);
-
- gtk_widget_queue_draw (GTK_WIDGET (board));
}
static void
slot_changed_cb (AisleriotGame *game,
- Slot *slot,
+ ArSlot *slot,
AisleriotBoard *board)
{
AisleriotBoardPrivate *priv = board->priv;
@@ -2305,26 +2108,147 @@ slot_changed_cb (AisleriotGame *game,
queue_check_animations (board);
}
+/* Style handling */
+
+static void
+aisleriot_board_sync_style (ArStyle *style,
+ GParamSpec *pspec,
+ AisleriotBoard *board)
+{
+ AisleriotBoardPrivate *priv = board->priv;
+ const char *pspec_name;
+ gboolean update_geometry = FALSE, redraw_focus = FALSE;
+
+ g_assert (style == priv->style);
+
+ if (pspec != NULL) {
+ pspec_name = pspec->name;
+ } else {
+ pspec_name = NULL;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_CARD_THEME)) {
+ GamesCardTheme *theme;
+
+ theme = ar_style_get_card_theme (style);
+ if (theme != NULL) {
+ games_card_textures_cache_set_theme (priv->textures, theme);
+
+ priv->geometry_set = FALSE;
+
+ update_geometry |= TRUE;
+ }
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_CARD_SLOT_RATIO)) {
+ double card_slot_ratio;
+
+ card_slot_ratio = ar_style_get_card_slot_ratio (style);
+
+ update_geometry |= (card_slot_ratio != priv->card_slot_ratio);
+
+ priv->card_slot_ratio = card_slot_ratio;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_INTERIOR_FOCUS)) {
+ gboolean interior_focus;
+
+ interior_focus = ar_style_get_interior_focus (style);
+
+ redraw_focus = (interior_focus != priv->interior_focus);
+
+ priv->interior_focus = interior_focus;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_FOCUS_LINE_WIDTH)) {
+ int focus_line_width;
+
+ focus_line_width = ar_style_get_focus_line_width (style);
+
+ redraw_focus = (focus_line_width != priv->focus_line_width);
+
+ priv->focus_line_width = focus_line_width;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_FOCUS_PADDING)) {
+ int focus_padding;
+
+ focus_padding = ar_style_get_focus_padding (style);
+
+ redraw_focus = (focus_padding != priv->focus_padding);
+
+ priv->focus_padding = focus_padding;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_RTL)) {
+ gboolean is_rtl;
+
+ is_rtl = ar_style_get_rtl (style);
+
+ update_geometry |= (is_rtl != priv->is_rtl);
+
+ priv->is_rtl = is_rtl;
+
+ /* FIXMEchpe: necessary? */
+ priv->force_geometry_update = TRUE;
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_ENABLE_ANIMATIONS)) {
+ /* FIXMEchpe: abort animations-in-progress if the setting is now OFF */
+ }
+
+ if (pspec_name == NULL || pspec_name == I_(AR_STYLE_PROP_CLICK_TO_MOVE)) {
+ gboolean click_to_move;
+
+ click_to_move = ar_style_get_click_to_move (style);
+ if (click_to_move != priv->click_to_move) {
+ /* Clear the selection. Do this before setting the new value,
+ * since otherwise selection won't get cleared correctly.
+ */
+ set_selection (board, NULL, -1, FALSE);
+
+ priv->click_to_move = click_to_move;
+
+ /* FIXMEchpe: we used to queue a redraw here. WHY?? Check that it's safe not to. */
+ }
+ }
+
+ /* FIXMEchpe: queue a relayout instead? */
+ if (update_geometry) {
+ aisleriot_board_setup_geometry (board);
+ }
+
+ if (redraw_focus) {
+ /* FIXMEchpe: do redraw the focus! */
+ }
+}
+
/* Class implementation */
-G_DEFINE_TYPE (AisleriotBoard, aisleriot_board, GTK_CLUTTER_TYPE_EMBED);
+G_DEFINE_TYPE (AisleriotBoard, aisleriot_board, CLUTTER_TYPE_GROUP);
/* AisleriotBoardClass methods */
#ifdef ENABLE_KEYNAV
static void
-aisleriot_board_activate (AisleriotBoard *board)
+aisleriot_board_activate (AisleriotBoard *board,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
- AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
- Slot *focus_slot = priv->focus_slot;
- Slot *selection_slot = priv->selection_slot;
+ AisleriotBoardPrivate *priv = board->priv; ArSlot *focus_slot = priv->focus_slot;
+ ArSlot *selection_slot = priv->selection_slot;
int selection_start_card_id = priv->selection_start_card_id;
- guint state = 0;
+#ifdef FIXMEchpe
if (!GTK_WIDGET_HAS_FOCUS (widget))
return;
+#endif
+
+ _games_debug_print (GAMES_DEBUG_GAME_KEYNAV,
+ "board ::activate keyval %x modifiers %x\n",
+ keyval, modifiers);
if (!focus_slot) {
aisleriot_board_error_bell (board);
@@ -2337,11 +2261,8 @@ aisleriot_board_activate (AisleriotBoard *board)
return;
}
- if (!gtk_get_current_event_state (&state))
- state = 0;
-
/* Control-Activate is double-click */
- if (state & GDK_CONTROL_MASK) {
+ if (modifiers & CLUTTER_CONTROL_MASK) {
aisleriot_game_record_move (priv->game, -1, NULL, 0);
if (aisleriot_game_button_double_clicked_lambda (priv->game, focus_slot->id)) {
aisleriot_game_end_move (priv->game);
@@ -2394,35 +2315,39 @@ aisleriot_board_activate (AisleriotBoard *board)
static gboolean
aisleriot_board_move_cursor (AisleriotBoard *board,
- GtkMovementStep step,
- int count)
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
- guint state;
gboolean is_control, is_shift, moved = FALSE;
+ char step;
+ int count;
+#ifdef FIXMEchpe
if (!GTK_WIDGET_HAS_FOCUS (widget))
return FALSE;
+#endif
+
+ step = action[0];
+ count = (action[1] == MOVE_LEFT ? -1 : 1);
- g_return_val_if_fail (step == GTK_MOVEMENT_LOGICAL_POSITIONS ||
- step == GTK_MOVEMENT_VISUAL_POSITIONS ||
- step == GTK_MOVEMENT_DISPLAY_LINES ||
- step == GTK_MOVEMENT_PAGES ||
- step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
+ _games_debug_print (GAMES_DEBUG_GAME_KEYNAV,
+ "board ::move-cursor keyval %x modifiers %x step '%c' count %d\n",
+ keyval, modifiers,
+ step, count);
/* No focus? Set focus to the first/last slot */
/* This will always return TRUE, no need for keynav-failed handling */
if (!priv->focus_slot) {
switch (step) {
- case GTK_MOVEMENT_DISPLAY_LINES:
- case GTK_MOVEMENT_PAGES:
+ case MOVE_CURSOR_UP_DOWN:
+ case MOVE_CURSOR_PAGES:
/* Focus the first slot */
return aisleriot_board_move_cursor_start_end_by_slot (board, -1);
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- case GTK_MOVEMENT_VISUAL_POSITIONS:
+ case MOVE_CURSOR_LEFT_RIGHT:
/* Move as if we'd been on the last/first slot */
- if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) {
+ if (!priv->is_rtl) {
return aisleriot_board_move_cursor_start_end_by_slot (board, -count);
}
/* fall-through */
@@ -2433,34 +2358,30 @@ aisleriot_board_move_cursor (AisleriotBoard *board,
g_assert (priv->focus_slot != NULL);
- if (!gtk_get_current_event_state (&state))
- state = 0;
-
- is_shift = (state & GDK_SHIFT_MASK) != 0;
- is_control = (state & GDK_CONTROL_MASK) != 0;
+ is_shift = (modifiers & CLUTTER_SHIFT_MASK) != 0;
+ is_control = (modifiers & CLUTTER_CONTROL_MASK) != 0;
switch (step) {
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- case GTK_MOVEMENT_VISUAL_POSITIONS:
+ case MOVE_CURSOR_LEFT_RIGHT:
if (is_shift) {
moved = aisleriot_board_extend_selection_left_right (board, count);
} else {
moved = aisleriot_board_move_cursor_left_right (board, count, is_control);
}
break;
- case GTK_MOVEMENT_DISPLAY_LINES:
+ case MOVE_CURSOR_UP_DOWN:
if (is_shift) {
moved = aisleriot_board_extend_selection_up_down (board, count);
} else {
moved = aisleriot_board_move_cursor_up_down (board, count, is_control);
}
break;
- case GTK_MOVEMENT_PAGES:
+ case MOVE_CURSOR_PAGES:
if (!is_shift) {
moved = aisleriot_board_move_cursor_up_down (board, count, TRUE);
}
break;
- case GTK_MOVEMENT_BUFFER_ENDS:
+ case MOVE_CURSOR_START_END:
if (is_shift) {
moved = aisleriot_board_extend_selection_start_end (board, count);
} else if (is_control) {
@@ -2483,10 +2404,17 @@ aisleriot_board_move_cursor (AisleriotBoard *board,
}
static void
-aisleriot_board_select_all (AisleriotBoard *board)
+aisleriot_board_select_all (AisleriotBoard *board,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot = priv->focus_slot;
+ ArSlot *focus_slot = priv->focus_slot;
+
+ _games_debug_print (GAMES_DEBUG_GAME_KEYNAV,
+ "board ::select-all keyval %x modifiers %x\n",
+ keyval, modifiers);
if (!focus_slot ||
focus_slot->cards->len == 0 ||
@@ -2497,18 +2425,32 @@ aisleriot_board_select_all (AisleriotBoard *board)
}
static void
-aisleriot_board_deselect_all (AisleriotBoard *board)
+aisleriot_board_deselect_all (AisleriotBoard *board,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
+ _games_debug_print (GAMES_DEBUG_GAME_KEYNAV,
+ "board ::deselect-all keyval %x modifiers %x\n",
+ keyval, modifiers);
+
set_selection (board, NULL, -1, FALSE);
}
static void
-aisleriot_board_toggle_selection (AisleriotBoard *board)
+aisleriot_board_toggle_selection (AisleriotBoard *board,
+ const char *action,
+ guint keyval,
+ ClutterModifierType modifiers)
{
AisleriotBoardPrivate *priv = board->priv;
- Slot *focus_slot;
+ ArSlot *focus_slot;
int focus_card_id;
+ _games_debug_print (GAMES_DEBUG_GAME_KEYNAV,
+ "board ::toggle-selection keyval %x modifiers %x\n",
+ keyval, modifiers);
+
focus_slot = priv->focus_slot;
if (!focus_slot)
return;
@@ -2550,28 +2492,18 @@ aisleriot_board_toggle_selection (AisleriotBoard *board)
#endif /* ENABLE_KEYNAV */
-/* GtkWidgetClass methods */
+
+/* ClutterActorClass impl */
+
+#if 0
static void
aisleriot_board_realize (GtkWidget *widget)
{
AisleriotBoard *board = AISLERIOT_BOARD (widget);
- AisleriotBoardPrivate *priv = board->priv;
- GdkDisplay *display;
+// AisleriotBoardPrivate *priv = board->priv;
GTK_WIDGET_CLASS (aisleriot_board_parent_class)->realize (widget);
- display = gtk_widget_get_display (widget);
-
- set_background_from_baize (board);
-
-#ifndef HAVE_HILDON
- /* Create cursors */
- priv->cursor[CURSOR_DEFAULT] = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
- priv->cursor[CURSOR_OPEN] = make_cursor (widget, hand_open_data_bits, hand_open_mask_bits);
- priv->cursor[CURSOR_CLOSED] = make_cursor (widget, hand_closed_data_bits, hand_closed_mask_bits);
- priv->cursor[CURSOR_DROPPABLE] = gdk_cursor_new_for_display (display, GDK_DOUBLE_ARROW); /* FIXMEchpe: better cursor */
-#endif /* !HAVE_HILDON */
-
aisleriot_board_setup_geometry (board);
}
@@ -2580,197 +2512,81 @@ aisleriot_board_unrealize (GtkWidget *widget)
{
AisleriotBoard *board = AISLERIOT_BOARD (widget);
AisleriotBoardPrivate *priv = board->priv;
-#ifndef HAVE_HILDON
- guint i;
-#endif
priv->geometry_set = FALSE;
-#ifndef HAVE_HILDON
- for (i = 0; i < LAST_CURSOR; ++i) {
- gdk_cursor_unref (priv->cursor[i]);
- priv->cursor[i] = NULL;
- }
-#endif /* !HAVE_HILDON*/
-
clear_state (board);
GTK_WIDGET_CLASS (aisleriot_board_parent_class)->unrealize (widget);
}
+#endif
static void
-aisleriot_board_screen_changed (GtkWidget *widget,
- GdkScreen *previous_screen)
-{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
- GdkScreen *screen;
- GtkSettings *settings;
-
- if (GTK_WIDGET_CLASS (aisleriot_board_parent_class)->screen_changed) {
- GTK_WIDGET_CLASS (aisleriot_board_parent_class)->screen_changed (widget, previous_screen);
- }
-
- screen = gtk_widget_get_screen (widget);
- if (screen == previous_screen)
- return;
-
- if (previous_screen) {
- g_signal_handlers_disconnect_by_func (gtk_settings_get_for_screen (previous_screen),
- G_CALLBACK (aisleriot_board_settings_update),
- board);
- }
-
- if (screen == NULL)
- return;
-
- settings = gtk_settings_get_for_screen (screen);
-
- aisleriot_board_settings_update (settings, NULL, board);
- g_signal_connect (settings, "notify::gtk-double-click-time",
- G_CALLBACK (aisleriot_board_settings_update), board);
- g_signal_connect (settings, "notify::gtk-enable-animations",
- G_CALLBACK (aisleriot_board_settings_update), board);
-#if GTK_CHECK_VERSION (2, 10, 0)
- g_signal_connect (settings, "notify::gtk-touchscreen-mode",
- G_CALLBACK (aisleriot_board_settings_update), board);
-#endif /* GTK >= 2.10.0 */
-}
-
-static void
-aisleriot_board_style_set (GtkWidget *widget,
- GtkStyle *previous_style)
+aisleriot_board_allocate (ClutterActor *actor,
+ const ClutterActorBox *box,
+ ClutterAllocationFlags flags)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
+ AisleriotBoard *board = AISLERIOT_BOARD (actor);
AisleriotBoardPrivate *priv = board->priv;
- GdkColor *colour = NULL;
- GdkColor selection_colour;
- gboolean interior_focus;
- double card_slot_ratio;
- GPtrArray *slots;
- int i, n_slots;
-
- gtk_widget_style_get (widget,
- "focus-line-width", &priv->focus_line_width,
- "focus-padding", &priv->focus_padding,
- "interior-focus", &interior_focus,
- "selection-color", &colour,
- "card-slot-ratio", &card_slot_ratio,
- NULL);
-
-#if 0
- g_print ("style-set: focus width %d padding %d interior-focus %s card-slot-ratio %.2f\n",
- priv->focus_line_width,
- priv->focus_padding,
- interior_focus ? "t" : "f",
- card_slot_ratio);
-#endif
+ gboolean is_same;
- priv->interior_focus = interior_focus != FALSE;
+ is_same = clutter_actor_box_equal (box, &priv->allocation);
- priv->card_slot_ratio = card_slot_ratio;
- /* FIXMEchpe: if the ratio changed, we should re-layout the board below */
+ _games_debug_print (GAMES_DEBUG_GAME_SIZING,
+ "board ::allocate (%f / %f)-(%f / %f) => %f x %f is-same %s force-update %s\n",
+ box->x1, box->y1, box->x2, box->y2,
+ box->x2 - box->x1, box->y2 - box->y1,
+ is_same ? "t" : "f",
+ priv->force_geometry_update ? "t" : "f");
- if (colour != NULL) {
- selection_colour = *colour;
- gdk_color_free (colour);
- } else {
- const GdkColor default_selection_colour = { 0, 0 /* red */, 0 /* green */, 0xaa00 /* blue */};
+ CLUTTER_ACTOR_CLASS (aisleriot_board_parent_class)->allocate (actor, box, flags);
- selection_colour = default_selection_colour;
- }
+ priv->allocation = *box;
- priv->selection_colour.red = selection_colour.red >> 8;
- priv->selection_colour.green = selection_colour.green >> 8;
- priv->selection_colour.blue = selection_colour.blue >> 8;
- priv->selection_colour.alpha = 0xff;
-
- /* Update the existing slots */
- slots = aisleriot_game_get_slots (priv->game);
- n_slots = slots->len;
- for (i = 0; i < n_slots; ++i) {
- Slot *slot = slots->pdata[i];
+ if (is_same && !priv->force_geometry_update)
+ return;
- if (slot->slot_renderer)
- aisleriot_slot_renderer_set_highlight_color (AISLERIOT_SLOT_RENDERER (slot->slot_renderer),
- &priv->selection_colour);
- }
+ priv->force_geometry_update = FALSE;
- GTK_WIDGET_CLASS (aisleriot_board_parent_class)->style_set (widget, previous_style);
+ /* FIXMEchpe: just queue this instead maybe? */
+ aisleriot_board_setup_geometry (board);
}
static void
-aisleriot_board_direction_changed (GtkWidget *widget,
- GtkTextDirection previous_direction)
+aisleriot_board_get_preferred_width (ClutterActor *actor,
+ float for_height,
+ float *min_width_p,
+ float *natural_width_p)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
- AisleriotBoardPrivate *priv = board->priv;
- GtkTextDirection direction;
-
- direction = gtk_widget_get_direction (widget);
-
- priv->is_rtl = (direction == GTK_TEXT_DIR_RTL);
-
- if (direction != previous_direction) {
- priv->force_geometry_update = TRUE;
- }
+ _games_debug_print (GAMES_DEBUG_GAME_SIZING,
+ "board ::get-preferred-width\n");
- /* This will queue a resize */
- GTK_WIDGET_CLASS (aisleriot_board_parent_class)->direction_changed (widget, previous_direction);
+ *min_width_p = BOARD_MIN_WIDTH;
+ *natural_width_p = 3 * BOARD_MIN_WIDTH;
}
static void
-aisleriot_board_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
+aisleriot_board_get_preferred_height (ClutterActor *actor,
+ float for_width,
+ float *min_height_p,
+ float *natural_height_p)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
- AisleriotBoardPrivate *priv = board->priv;
- gboolean is_same;
+ _games_debug_print (GAMES_DEBUG_GAME_SIZING,
+ "board ::get-preferred-height\n");
- is_same = (memcmp (&widget->allocation, allocation, sizeof (GtkAllocation)) == 0);
-
- GTK_WIDGET_CLASS (aisleriot_board_parent_class)->size_allocate (widget, allocation);
-
- if (is_same && !priv->force_geometry_update)
- return;
-
- priv->force_geometry_update = FALSE;
-
- if (GTK_WIDGET_REALIZED (widget)) {
- aisleriot_board_setup_geometry (board);
- }
-}
-
-static void
-aisleriot_board_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- requisition->width = BOARD_MIN_WIDTH;
- requisition->height = BOARD_MIN_HEIGHT;
+ *min_height_p = BOARD_MIN_HEIGHT;
+ *natural_height_p = 3 * BOARD_MIN_HEIGHT;
}
#ifdef ENABLE_KEYNAV
static gboolean
-aisleriot_board_focus (GtkWidget *widget,
- GtkDirectionType direction)
+aisleriot_board_focus (AisleriotBoard *board,
+ int count)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
AisleriotBoardPrivate *priv = board->priv;
if (!priv->focus_slot) {
- int count;
-
- switch (direction) {
- case GTK_DIR_TAB_FORWARD:
- count = 1;
- break;
- case GTK_DIR_TAB_BACKWARD:
- count = -1;
- break;
- default:
- break;
- }
-
return aisleriot_board_move_cursor_start_end_by_slot (board, -count);
}
@@ -2779,11 +2595,31 @@ aisleriot_board_focus (GtkWidget *widget,
return TRUE;
#endif
- return GTK_WIDGET_CLASS (aisleriot_board_parent_class)->focus (widget, direction);
+ return FALSE;
+}
+
+static gboolean
+aisleriot_board_key_press (ClutterActor *actor,
+ ClutterKeyEvent *event)
+{
+ ClutterBindingPool *pool;
+
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::key-press keyval %x modifiers %x\n",
+ event->keyval, event->modifier_state);
+
+ pool = clutter_binding_pool_get_for_class (CLUTTER_ACTOR_GET_CLASS (actor));
+ g_assert (pool != NULL);
+
+ return clutter_binding_pool_activate (pool,
+ event->keyval,
+ event->modifier_state,
+ G_OBJECT (actor));
}
#endif /* ENABLE_KEYNAV */
+#ifdef FIXMEchpe
/* The gtkwidget.c focus in/out handlers queue a shallow draw;
* that's ok for us but maybe we want to optimise this a bit to
* only do it if we have a focus to draw/erase?
@@ -2827,30 +2663,43 @@ aisleriot_board_focus_out (GtkWidget *widget,
return FALSE;
}
+#endif /* FIXMEchpe */
static gboolean
-aisleriot_board_button_press (GtkWidget *widget,
- GdkEventButton *event)
+aisleriot_board_button_press (ClutterActor *actor,
+ ClutterButtonEvent *event)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
+ AisleriotBoard *board = AISLERIOT_BOARD (actor);
AisleriotBoardPrivate *priv = board->priv;
- Slot *hslot;
+ ArSlot *hslot;
int cardid;
- guint button;
+ guint32 button;
gboolean drag_valid;
guint state;
gboolean is_double_click, show_focus;
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::button-press @(%f / %f) button %d click-count %d modifiers %x\n",
+ event->x, event->y,
+ event->button, event->click_count,
+ event->modifier_state);
+
/* NOTE: It's ok to just return instead of chaining up, since the
- * parent class has no class closure for this event.
+ * parent classes have no class closure for this event.
*/
+ /* FIXMEchpe: check event coordinate handling (float vs int!) */
+
+#ifdef FIXMEchpe
+ /* FIXMEchpe: we might be able to use ClutterButtonEvent::click_count for double-click detection! */
/* ignore the gdk synthetic double/triple click events */
if (event->type != GDK_BUTTON_PRESS)
return FALSE;
+#endif
/* Don't do anything if a modifier is pressed */
- state = event->state & gtk_accelerator_get_default_mod_mask ();
+ /* FIXMEchpe: is there anything like gtk_accelerator_get_default_mod_mask() in clutter? */
+ state = event->modifier_state;
if (state != 0)
return FALSE;
@@ -2872,7 +2721,7 @@ aisleriot_board_button_press (GtkWidget *widget,
is_double_click = button == 2 ||
(priv->last_click_left_click &&
- (event->time - priv->last_click_time <= priv->double_click_time) &&
+ (event->time - priv->last_click_time <= ar_style_get_double_click_time (priv->style)) &&
priv->last_clicked_slot == hslot &&
priv->last_clicked_card_id == cardid);
@@ -2892,7 +2741,7 @@ aisleriot_board_button_press (GtkWidget *widget,
return FALSE;
}
- set_cursor (board, CURSOR_CLOSED);
+ set_cursor (board, AR_CURSOR_CLOSED);
/* First check if it's a right-click: if so, we reveal the card and do nothing else */
if (button == 3) {
@@ -2910,7 +2759,7 @@ aisleriot_board_button_press (GtkWidget *widget,
* different cards and a double-click on one card.
*/
if (is_double_click) {
- Slot *clicked_slot = hslot;
+ ArSlot *clicked_slot = hslot;
priv->click_status = STATUS_NONE;
@@ -2926,7 +2775,7 @@ aisleriot_board_button_press (GtkWidget *widget,
aisleriot_game_test_end_of_game (priv->game);
- set_cursor (board, CURSOR_OPEN);
+ set_cursor (board, AR_CURSOR_OPEN);
return TRUE;
}
@@ -3012,15 +2861,23 @@ set_selection:
}
static gboolean
-aisleriot_board_button_release (GtkWidget *widget,
- GdkEventButton *event)
+aisleriot_board_button_release (ClutterActor *actor,
+ ClutterButtonEvent *event)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
+ AisleriotBoard *board = AISLERIOT_BOARD (actor);
AisleriotBoardPrivate *priv = board->priv;
/* guint state; */
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::button-release @(%f / %f) button %d click-count %d modifiers %x\n",
+ event->x, event->y,
+ event->button, event->click_count,
+ event->modifier_state);
+
+ /* FIXMEchpe: check event coordinate handling (float vs int!) */
+
/* NOTE: It's ok to just return instead of chaining up, since the
- * parent class has no class closure for this event.
+ * parent classes have no class closure for this event.
*/
/* We just abort any action on button release, even if the button-up
@@ -3042,7 +2899,7 @@ aisleriot_board_button_release (GtkWidget *widget,
case STATUS_MAYBE_DRAG:
case STATUS_NOT_DRAG: {
- Slot *slot;
+ ArSlot *slot;
int card_id;
/* Don't do the action if the mouse moved away from the clicked slot; see bug #329183 */
@@ -3075,18 +2932,25 @@ aisleriot_board_button_release (GtkWidget *widget,
}
static gboolean
-aisleriot_board_motion_notify (GtkWidget *widget,
- GdkEventMotion * event)
+aisleriot_board_motion (ClutterActor *actor,
+ ClutterMotionEvent *event)
{
- AisleriotBoard *board = AISLERIOT_BOARD (widget);
+ AisleriotBoard *board = AISLERIOT_BOARD (actor);
AisleriotBoardPrivate *priv = board->priv;
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::motion @(%f / %f) modifiers %x\n",
+ event->x, event->y,
+ event->modifier_state);
+
+ /* FIXMEchpe: check event coordinate handling (float vs int!) */
+
/* NOTE: It's ok to just return instead of chaining up, since the
- * parent class has no class closure for this event.
+ * parent classes have no class closure for this event.
*/
if (priv->click_status == STATUS_IS_DRAG) {
- Slot *slot;
+ ArSlot *slot;
int x, y;
x = event->x - priv->last_click_x;
@@ -3098,13 +2962,13 @@ aisleriot_board_motion_notify (GtkWidget *widget,
clutter_actor_set_position (priv->moving_cards_group, x, y);
clutter_actor_raise_top (priv->moving_cards_group);
- set_cursor (board, CURSOR_CLOSED);
+ set_cursor (board, AR_CURSOR_CLOSED);
} else if (priv->click_status == STATUS_MAYBE_DRAG &&
- gtk_drag_check_threshold (widget,
- priv->last_click_x,
- priv->last_click_y,
- event->x,
- event->y)) {
+ ar_style_check_dnd_drag_threshold (priv->style,
+ priv->last_click_x,
+ priv->last_click_y,
+ event->x,
+ event->y)) {
drag_begin (board);
} else {
set_cursor_by_location (board, event->x, event->y);
@@ -3114,83 +2978,72 @@ aisleriot_board_motion_notify (GtkWidget *widget,
}
static gboolean
-aisleriot_board_key_press (GtkWidget *widget,
- GdkEventKey* event)
+aisleriot_board_enter (ClutterActor *actor,
+ ClutterCrossingEvent *event)
{
- return GTK_WIDGET_CLASS (aisleriot_board_parent_class)->key_press_event (widget, event);
-}
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::enter @(%f / %f)\n",
+ event->x, event->y);
-#ifdef HAVE_MAEMO
+ /* NOTE: It's ok to just return instead of chaining up, since the
+ * parent classes have no class closure for this event.
+ */
+
+ return FALSE;
+}
static gboolean
-aisleriot_board_tap_and_hold_query_cb (GtkWidget *widget,
- GdkEvent *_event,
- AisleriotBoard *board)
+aisleriot_board_leave (ClutterActor *actor,
+ ClutterCrossingEvent *event)
{
- AisleriotBoardPrivate *priv = board->priv;
- /* BadDocs! should mention that this is a GdkEventButton! */
- GdkEventButton *event = (GdkEventButton *) _event;
- Slot *slot;
- int card_id;
+ AisleriotBoard *board = AISLERIOT_BOARD (actor);
- /* NOTE: Returning TRUE from this function means that tap-and-hold
- * is disallowed here; FALSE means to allow tap-and-hold.
- */
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::leave @(%f / %f)\n",
+ event->x, event->y);
- /* In click-to-move mode, we always reveal with just the left click */
- if (priv->click_to_move)
- return TRUE;
-
- get_slot_and_card_from_point (board, event->x, event->y, &slot, &card_id);
- if (!slot ||
- card_id < 0 ||
- card_id == slot->cards->len - 1 ||
- CARD_GET_FACE_DOWN (CARD (slot->cards->data[card_id])))
- return TRUE;
+ /* NOTE: It's ok to just return instead of chaining up, since the
+ * parent classes have no class closure for this event.
+ */
- priv->tap_and_hold_slot = slot;
- priv->tap_and_hold_card_id = card_id;
+ set_cursor (board, AR_CURSOR_DEFAULT);
- return FALSE; /* chain up to the default handler */
+ return FALSE;
}
static void
-aisleriot_board_tap_and_hold_cb (GtkWidget *widget,
- AisleriotBoard *board)
+aisleriot_board_key_focus_in (ClutterActor *actor)
{
- AisleriotBoardPrivate *priv = board->priv;
-
- if (priv->tap_and_hold_slot == NULL ||
- priv->tap_and_hold_card_id < 0)
- return;
-
- reveal_card (board, priv->tap_and_hold_slot, priv->tap_and_hold_card_id);
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::key-focus-in\n");
}
-#endif /* HAVE_MAEMO */
+static void
+aisleriot_board_key_focus_out (ClutterActor *actor)
+{
+ _games_debug_print (GAMES_DEBUG_GAME_EVENTS,
+ "board ::key-focus-out\n");
+}
/* GObjectClass methods */
static void
aisleriot_board_init (AisleriotBoard *board)
{
- GtkWidget *widget = GTK_WIDGET (board);
+ ClutterActor *actor = CLUTTER_ACTOR (board);
AisleriotBoardPrivate *priv;
- ClutterActor *stage;
priv = board->priv = AISLERIOT_BOARD_GET_PRIVATE (board);
- gtk_widget_set_name (widget, "aisleriot-board");
+ memset (&priv->allocation, 0, sizeof (ClutterActorBox));
- GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
-
- priv->is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+ /* We want to receive events! */
+ clutter_actor_set_reactive (actor, TRUE);
priv->force_geometry_update = FALSE;
priv->click_to_move = FALSE;
priv->show_selection = FALSE;
- priv->animation_mode = FALSE;
priv->show_card_id = -1;
@@ -3198,25 +3051,8 @@ aisleriot_board_init (AisleriotBoard *board)
priv->removed_cards = g_array_new (FALSE, FALSE, sizeof (RemovedCard));
- gtk_widget_set_events (widget,
- gtk_widget_get_events (widget) |
- GDK_EXPOSURE_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_RELEASE_MASK);
- /* FIMXEchpe: no need for motion events on maemo, unless we explicitly activate drag mode */
-
-#ifdef HAVE_MAEMO
- gtk_widget_tap_and_hold_setup (widget, NULL, NULL, GTK_TAP_AND_HOLD_PASS_PRESS);
- g_signal_connect (widget, "tap-and-hold-query",
- G_CALLBACK (aisleriot_board_tap_and_hold_query_cb), board);
- g_signal_connect (widget, "tap-and-hold",
- G_CALLBACK (aisleriot_board_tap_and_hold_cb), board);
-#endif /* HAVE_MAEMO */
-
- stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
priv->animation_layer = g_object_ref_sink (clutter_group_new ());
- clutter_container_add (CLUTTER_CONTAINER (stage),
+ clutter_container_add (CLUTTER_CONTAINER (board),
priv->animation_layer, NULL);
}
@@ -3235,6 +3071,7 @@ aisleriot_board_constructor (GType type,
board = AISLERIOT_BOARD (object);
priv = board->priv;
+ g_assert (priv->style != NULL);
g_assert (priv->game != NULL);
priv->textures = games_card_textures_cache_new ();
@@ -3257,8 +3094,12 @@ aisleriot_board_finalize (GObject *object)
g_byte_array_free (priv->moving_cards, TRUE);
- if (priv->theme) {
- g_object_unref (priv->theme);
+ if (priv->style != NULL) {
+ g_signal_handlers_disconnect_matched (priv->style,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, board);
+
+ g_object_unref (priv->style);
}
#if 0
@@ -3277,12 +3118,6 @@ aisleriot_board_dispose (GObject *object)
AisleriotBoard *board = AISLERIOT_BOARD (object);
AisleriotBoardPrivate *priv = board->priv;
- if (priv->baize_actor) {
- clutter_actor_destroy (priv->baize_actor);
- g_object_unref (priv->baize_actor);
- priv->baize_actor = NULL;
- }
-
if (priv->textures) {
g_object_unref (priv->textures);
priv->textures = NULL;
@@ -3302,21 +3137,6 @@ aisleriot_board_dispose (GObject *object)
}
static void
-aisleriot_board_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- AisleriotBoard *board = AISLERIOT_BOARD (object);
-
- switch (prop_id) {
- case PROP_THEME:
- g_value_set_object (value, aisleriot_board_get_card_theme (board));
- break;
- }
-}
-
-static void
aisleriot_board_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -3339,9 +3159,17 @@ aisleriot_board_set_property (GObject *object,
G_CALLBACK (slot_changed_cb), board);
break;
- case PROP_THEME:
- aisleriot_board_set_card_theme (board, g_value_get_object (value));
+
+ case PROP_STYLE:
+ priv->style = g_value_dup_object (value);
+
+ aisleriot_board_sync_style (priv->style, NULL, board);
+ g_signal_connect (priv->style, "notify",
+ G_CALLBACK (aisleriot_board_sync_style), board);
break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
@@ -3349,9 +3177,10 @@ static void
aisleriot_board_class_init (AisleriotBoardClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
#ifdef ENABLE_KEYNAV
- GtkBindingSet *binding_set;
+ ClutterBindingPool *binding_pool;
+ GClosure *closure;
#endif
g_type_class_add_private (gobject_class, sizeof (AisleriotBoardPrivate));
@@ -3360,30 +3189,63 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
gobject_class->dispose = aisleriot_board_dispose;
gobject_class->finalize = aisleriot_board_finalize;
gobject_class->set_property = aisleriot_board_set_property;
- gobject_class->get_property = aisleriot_board_get_property;
+#ifdef FIXMEchpe
widget_class->realize = aisleriot_board_realize;
widget_class->unrealize = aisleriot_board_unrealize;
- widget_class->screen_changed = aisleriot_board_screen_changed;
- widget_class->style_set = aisleriot_board_style_set;
- widget_class->direction_changed = aisleriot_board_direction_changed;
- widget_class->size_allocate = aisleriot_board_size_allocate;
- widget_class->size_request = aisleriot_board_size_request;
-#ifdef ENABLE_KEYNAV
- widget_class->focus = aisleriot_board_focus;
-#endif /* ENABLE_KEYNAV */
widget_class->focus_in_event = aisleriot_board_focus_in;
widget_class->focus_out_event = aisleriot_board_focus_out;
- widget_class->button_press_event = aisleriot_board_button_press;
- widget_class->button_release_event = aisleriot_board_button_release;
- widget_class->motion_notify_event = aisleriot_board_motion_notify;
- widget_class->key_press_event = aisleriot_board_key_press;
-#ifdef HAVE_MAEMO
- widget_class->tap_and_hold_query = aisleriot_board_tap_and_hold_query;
- widget_class->tap_and_hold = aisleriot_board_tap_and_hold;
-#endif /* HAVE_MAEMO */
+#endif // FIXMEchpe
+ actor_class->allocate = aisleriot_board_allocate;
+ actor_class->get_preferred_width = aisleriot_board_get_preferred_width;
+ actor_class->get_preferred_height = aisleriot_board_get_preferred_height;
#ifdef ENABLE_KEYNAV
+ actor_class->key_press_event = aisleriot_board_key_press;
+#endif /* ENABLE_KEYNAV */
+ actor_class->button_press_event = aisleriot_board_button_press;
+ actor_class->button_release_event = aisleriot_board_button_release;
+ actor_class->motion_event = aisleriot_board_motion;
+ actor_class->enter_event = aisleriot_board_enter;
+ actor_class->leave_event = aisleriot_board_leave;
+ actor_class->key_focus_in = aisleriot_board_key_focus_in;
+ actor_class->key_focus_out = aisleriot_board_key_focus_out;
+
+
+ signals[REQUEST_CURSOR] =
+ g_signal_new (I_("request-cursor"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (AisleriotBoardClass, request_cursor),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ signals[ERROR_BELL] =
+ g_signal_new (I_("error-bell"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (AisleriotBoardClass, request_cursor),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[ERROR_BELL] =
+ g_signal_new (I_("focus"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (AisleriotBoardClass, focus),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_BOOLEAN,
+ 1,
+ G_TYPE_INT);
+
+#ifdef ENABLE_KEYNAV
+ klass->focus = aisleriot_board_focus;
klass->activate = aisleriot_board_activate;
klass->move_cursor = aisleriot_board_move_cursor;
klass->select_all = aisleriot_board_select_all;
@@ -3391,15 +3253,21 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
klass->toggle_selection = aisleriot_board_toggle_selection;
/* Keybinding signals */
- widget_class->activate_signal = signals[ACTIVATE] =
+#ifdef FIXMEchpe
+ widget_class->activate_signal =
+#endif
+ signals[ACTIVATE] =
g_signal_new (I_("activate"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (AisleriotBoardClass, activate),
NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ games_marshal_BOOLEAN__STRING_UINT_ENUM,
+ G_TYPE_BOOLEAN,
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_UINT,
+ CLUTTER_TYPE_MODIFIER_TYPE);
signals[MOVE_CURSOR] =
g_signal_new (I_("move-cursor"),
@@ -3407,11 +3275,12 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (AisleriotBoardClass, move_cursor),
NULL, NULL,
- games_marshal_BOOLEAN__ENUM_INT,
+ games_marshal_BOOLEAN__STRING_UINT_ENUM,
G_TYPE_BOOLEAN,
- 2,
- GTK_TYPE_MOVEMENT_STEP,
- G_TYPE_INT);
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_UINT,
+ CLUTTER_TYPE_MODIFIER_TYPE);
signals[TOGGLE_SELECTION] =
g_signal_new (I_("toggle-selection"),
@@ -3419,9 +3288,12 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (AisleriotBoardClass, toggle_selection),
NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ games_marshal_BOOLEAN__STRING_UINT_ENUM,
+ G_TYPE_BOOLEAN,
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_UINT,
+ CLUTTER_TYPE_MODIFIER_TYPE);
signals[SELECT_ALL] =
g_signal_new (I_("select-all"),
@@ -3429,9 +3301,12 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (AisleriotBoardClass, select_all),
NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ games_marshal_BOOLEAN__STRING_UINT_ENUM,
+ G_TYPE_BOOLEAN,
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_UINT,
+ CLUTTER_TYPE_MODIFIER_TYPE);
signals[DESELECT_ALL] =
g_signal_new (I_("deselect-all"),
@@ -3439,9 +3314,12 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (AisleriotBoardClass, deselect_all),
NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ games_marshal_BOOLEAN__STRING_UINT_ENUM,
+ G_TYPE_BOOLEAN,
+ 3,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_UINT,
+ CLUTTER_TYPE_MODIFIER_TYPE);
#endif /* ENABLE_KEYNAV */
/* Properties */
@@ -3450,195 +3328,148 @@ aisleriot_board_class_init (AisleriotBoardClass *klass)
PROP_GAME,
g_param_spec_object ("game", NULL, NULL,
AISLERIOT_TYPE_GAME,
- G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(gobject_class,
- PROP_THEME,
- g_param_spec_object ("theme", NULL, NULL,
- GAMES_TYPE_CARD_THEME,
- G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- gtk_widget_class_install_style_property
- (widget_class,
- g_param_spec_boxed ("selection-color", NULL, NULL,
- GDK_TYPE_COLOR,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- /**
- * AisleriotBoard:card-slot-ratio:
- *
- * The ratio of card to slot size. Note that this is the ratio of
- * card width/slot width and card height/slot height, not of
- * card area/slot area.
- */
- gtk_widget_class_install_style_property
- (widget_class,
- g_param_spec_double ("card-slot-ratio", NULL, NULL,
- 0.1, 1.0, DEFAULT_CARD_SLOT_RATIO,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+ PROP_STYLE,
+ g_param_spec_object ("style", NULL, NULL,
+ AR_TYPE_STYLE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
#ifdef ENABLE_KEYNAV
/* Keybindings */
- binding_set = gtk_binding_set_by_class (klass);
+ binding_pool = clutter_binding_pool_get_for_class (klass);
/* Cursor movement */
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_Left, 0,
- GTK_MOVEMENT_VISUAL_POSITIONS, -1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_Left, 0,
- GTK_MOVEMENT_VISUAL_POSITIONS, -1);
-
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_Right, 0,
- GTK_MOVEMENT_VISUAL_POSITIONS, 1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_Right, 0,
- GTK_MOVEMENT_VISUAL_POSITIONS, 1);
+ closure = g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (klass),
+ G_STRUCT_OFFSET (AisleriotBoardClass, move_cursor));
+
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_LEFT_RIGHT_S MOVE_LEFT_S),
+ CLUTTER_Left, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_LEFT_RIGHT_S MOVE_LEFT_S),
+ CLUTTER_KP_Left, 0);
+
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_LEFT_RIGHT_S MOVE_RIGHT_S),
+ CLUTTER_Right, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_LEFT_RIGHT_S MOVE_RIGHT_S),
+ CLUTTER_KP_Right, 0);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_Up, 0,
- GTK_MOVEMENT_DISPLAY_LINES, -1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_Up, 0,
- GTK_MOVEMENT_DISPLAY_LINES, -1);
-
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_Down, 0,
- GTK_MOVEMENT_DISPLAY_LINES, 1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_Down, 0,
- GTK_MOVEMENT_DISPLAY_LINES, 1);
-
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_Home, 0,
- GTK_MOVEMENT_BUFFER_ENDS, -1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_Home, 0,
- GTK_MOVEMENT_BUFFER_ENDS, -1);
-
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_End, 0,
- GTK_MOVEMENT_BUFFER_ENDS, 1);
- aisleriot_board_add_move_and_select_binding (binding_set, GDK_KP_End, 0,
- GTK_MOVEMENT_BUFFER_ENDS, 1);
-
- aisleriot_board_add_move_binding (binding_set, GDK_Page_Up, 0,
- GTK_MOVEMENT_PAGES, -1);
- aisleriot_board_add_move_binding (binding_set, GDK_KP_Page_Up, 0,
- GTK_MOVEMENT_PAGES, -1);
-
- aisleriot_board_add_move_binding (binding_set, GDK_Page_Down, 0,
- GTK_MOVEMENT_PAGES, 1);
- aisleriot_board_add_move_binding (binding_set, GDK_KP_Page_Down, 0,
- GTK_MOVEMENT_PAGES, 1);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_UP_DOWN_S MOVE_LEFT_S),
+ CLUTTER_Up, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_UP_DOWN_S MOVE_LEFT_S),
+ CLUTTER_KP_Up, 0);
+
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_UP_DOWN_S MOVE_RIGHT_S),
+ CLUTTER_Down, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_UP_DOWN_S MOVE_RIGHT_S),
+ CLUTTER_KP_Down, 0);
+
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_START_END_S MOVE_LEFT_S),
+ CLUTTER_Home, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_START_END_S MOVE_LEFT_S),
+ CLUTTER_KP_Home, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_START_END_S MOVE_LEFT_S),
+ CLUTTER_Begin, 0);
+
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_START_END_S MOVE_RIGHT_S),
+ CLUTTER_End, 0);
+ aisleriot_board_add_move_and_select_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_START_END_S MOVE_RIGHT_S),
+ CLUTTER_KP_End, 0);
+
+ aisleriot_board_add_move_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_PAGES_S MOVE_LEFT_S),
+ CLUTTER_Page_Up, 0);
+ aisleriot_board_add_move_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_PAGES_S MOVE_LEFT_S),
+ CLUTTER_KP_Page_Up, 0);
+
+ aisleriot_board_add_move_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_PAGES_S MOVE_RIGHT_S),
+ CLUTTER_Page_Down, 0);
+ aisleriot_board_add_move_binding (binding_pool, closure,
+ I_(MOVE_CURSOR_PAGES_S MOVE_RIGHT_S),
+ CLUTTER_KP_Page_Down, 0);
+
+ g_closure_unref (closure);
/* Selection */
- gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
- "toggle-selection", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
- "toggle-selection", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK,
- "select-all", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
- "deselect-all", 0);
+ closure = g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (klass),
+ G_STRUCT_OFFSET (AisleriotBoardClass, toggle_selection));
+
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("toggle-selection"),
+ CLUTTER_space,
+ 0,
+ closure);
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("toggle-selection"),
+ CLUTTER_KP_Space,
+ 0,
+ closure);
+ g_closure_unref (closure);
+
+ closure = g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (klass),
+ G_STRUCT_OFFSET (AisleriotBoardClass, select_all));
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("select-all"),
+ CLUTTER_a,
+ CLUTTER_CONTROL_MASK,
+ closure);
+ g_closure_unref (closure);
+
+ closure = g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (klass),
+ G_STRUCT_OFFSET (AisleriotBoardClass, deselect_all));
+ clutter_binding_pool_install_closure (binding_pool,
+ I_("deselect-all"),
+ CLUTTER_a,
+ CLUTTER_CONTROL_MASK | CLUTTER_SHIFT_MASK,
+ closure);
+ g_closure_unref (closure);
/* Activate */
- aisleriot_board_add_activate_binding (binding_set, GDK_Return, 0);
- aisleriot_board_add_activate_binding (binding_set, GDK_ISO_Enter, 0);
- aisleriot_board_add_activate_binding (binding_set, GDK_KP_Enter, 0);
+ closure = g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (klass),
+ G_STRUCT_OFFSET (AisleriotBoardClass, activate));
+
+ aisleriot_board_add_activate_binding (binding_pool, closure, CLUTTER_Return, 0);
+ aisleriot_board_add_activate_binding (binding_pool, closure, CLUTTER_ISO_Enter, 0);
+ aisleriot_board_add_activate_binding (binding_pool, closure, CLUTTER_KP_Enter, 0);
+
+ g_closure_unref (closure);
#endif /* ENABLE_KEYNAV */
}
/* public API */
-GtkWidget *
-aisleriot_board_new (AisleriotGame *game)
+ClutterActor *
+aisleriot_board_new (ArStyle *style,
+ AisleriotGame *game)
{
return g_object_new (AISLERIOT_TYPE_BOARD,
+ "style", style,
"game", game,
NULL);
}
void
-aisleriot_board_set_card_theme (AisleriotBoard *board,
- GamesCardTheme *theme)
-{
- AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
-
- g_return_if_fail (AISLERIOT_IS_BOARD (board));
- g_return_if_fail (GAMES_IS_CARD_THEME (theme));
-
- if (theme == priv->theme)
- return;
-
- if (priv->theme) {
- g_object_unref (priv->theme);
- }
-
- priv->geometry_set = FALSE;
-
- priv->theme = g_object_ref (theme);
-
- games_card_textures_cache_set_theme (priv->textures, priv->theme);
-
- if (GTK_WIDGET_REALIZED (widget)) {
- /* Update card size and slot locations for new card theme (might have changed aspect!)*/
- aisleriot_board_setup_geometry (board);
-
- gtk_widget_queue_draw (widget);
- }
-
- g_object_notify (G_OBJECT (board), "theme");
-}
-
-GamesCardTheme *
-aisleriot_board_get_card_theme (AisleriotBoard *board)
-{
- AisleriotBoardPrivate *priv = board->priv;
-
- return priv->theme;
-}
-
-void
-aisleriot_board_set_click_to_move (AisleriotBoard *board,
- gboolean click_to_move)
-{
- AisleriotBoardPrivate *priv = board->priv;
- GtkWidget *widget = GTK_WIDGET (board);
-
- click_to_move = click_to_move != FALSE;
- if (priv->click_to_move == click_to_move)
- return;
-
- /* Clear the selection. Do this before setting the new value,
- * since otherwise selection won't get cleared correctly.
- */
- set_selection (board, NULL, -1, FALSE);
-
- priv->click_to_move = click_to_move;
-
- /* FIXMEchpe why? */
- if (GTK_WIDGET_REALIZED (widget)) {
- gtk_widget_queue_draw (widget);
- }
-}
-
-void
-aisleriot_board_set_animation_mode (AisleriotBoard *board,
- gboolean enabled)
-{
- AisleriotBoardPrivate *priv = board->priv;
-
- enabled = enabled != FALSE;
- if (priv->animation_mode == enabled)
- return;
-
- priv->animation_mode = enabled;
-
- /* FIXME: stop in-progress animations? */
-}
-
-void
aisleriot_board_abort_move (AisleriotBoard *board)
{
clear_state (board);
}
-
-void
-aisleriot_board_set_pixbuf_drawing (AisleriotBoard *board,
- gboolean use_pixbuf_drawing)
-{
- /* makes no sense for Clutter */
-}
diff --git a/aisleriot/board.h b/aisleriot/board.h
index bab8997..908fceb 100644
--- a/aisleriot/board.h
+++ b/aisleriot/board.h
@@ -19,14 +19,14 @@
#ifndef AISLERIOT_BOARD_H
#define AISLERIOT_BOARD_H
-#include <gtk/gtk.h>
-
-#ifdef HAVE_CLUTTER
-#include <clutter-gtk/clutter-gtk.h>
+#ifndef HAVE_CLUTTER
+#error board.h requires clutter
#endif
-#include <libgames-support/games-card-theme.h>
+#include <clutter/clutter.h>
+#include "ar-style.h"
+#include "ar-cursor.h"
#include "game.h"
G_BEGIN_DECLS
@@ -43,52 +43,53 @@ typedef struct _AisleriotBoardPrivate AisleriotBoardPrivate;
typedef struct _AisleriotBoardClass AisleriotBoardClass;
struct _AisleriotBoard {
-#ifdef HAVE_CLUTTER
- GtkClutterEmbed parent_instance;
-#else
- GtkDrawingArea parent_instance;
-#endif
+ ClutterGroup parent_instance;
/*< private >*/
AisleriotBoardPrivate *priv;
};
struct _AisleriotBoardClass {
-#ifdef HAVE_CLUTTER
- GtkClutterEmbedClass parent_class;
-#else
- GtkDrawingAreaClass parent_class;
-#endif
+ ClutterGroupClass parent_class;
- /* keybinding signals */
- gboolean (* move_cursor) (AisleriotBoard *board,
- GtkMovementStep step,
- int count);
- void (* activate) (AisleriotBoard *board);
- void (* toggle_selection) (AisleriotBoard *board);
- void (* select_all) (AisleriotBoard *board);
- void (* deselect_all) (AisleriotBoard *board);
-};
+ void (* request_cursor) (AisleriotBoard *board,
+ ArCursorType cursor_type);
-GType aisleriot_board_get_type (void);
+ void (* error_bell) (AisleriotBoard *board);
-GtkWidget *aisleriot_board_new (AisleriotGame *game);
+ /* Focus */
+ gboolean (* focus) (AisleriotBoard *,
+ int direction);
-void aisleriot_board_set_card_theme (AisleriotBoard * board,
- GamesCardTheme *theme);
-
-GamesCardTheme *aisleriot_board_get_card_theme (AisleriotBoard * board);
-
-void aisleriot_board_set_click_to_move (AisleriotBoard * board,
- gboolean click_to_move);
+ /* keybinding signals */
+ gboolean (* move_cursor) (AisleriotBoard *,
+ const char *,
+ guint,
+ ClutterModifierType);
+ void (* activate) (AisleriotBoard *,
+ const char *,
+ guint,
+ ClutterModifierType);
+ void (* toggle_selection) (AisleriotBoard *,
+ const char *,
+ guint,
+ ClutterModifierType);
+ void (* select_all) (AisleriotBoard *,
+ const char *,
+ guint,
+ ClutterModifierType);
+ void (* deselect_all) (AisleriotBoard *,
+ const char *,
+ guint,
+ ClutterModifierType);
+};
-void aisleriot_board_set_animation_mode (AisleriotBoard *board,
- gboolean enable);
+GType aisleriot_board_get_type (void);
-void aisleriot_board_abort_move (AisleriotBoard * board);
+ClutterActor *aisleriot_board_new (ArStyle *style,
+ AisleriotGame *game);
-void aisleriot_board_set_pixbuf_drawing (AisleriotBoard * board,
- gboolean use_pixbuf_drawing);
+void aisleriot_board_abort_move (AisleriotBoard *board);
G_END_DECLS
diff --git a/aisleriot/card.c b/aisleriot/card.c
index d7c1ef9..0a56fe4 100644
--- a/aisleriot/card.c
+++ b/aisleriot/card.c
@@ -95,30 +95,21 @@ aisleriot_card_class_init (AisleriotCardClass *klass)
pspec = g_param_spec_uchar ("bottom-card", NULL, NULL,
0, 255, 0,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_BOTTOM_CARD, pspec);
pspec = g_param_spec_uchar ("top-card", NULL, NULL,
0, 255, 0,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_TOP_CARD, pspec);
pspec = g_param_spec_object ("cache", NULL, NULL,
GAMES_TYPE_CARD_TEXTURES_CACHE,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
+ G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_CACHE, pspec);
g_type_class_add_private (klass, sizeof (AisleriotCardPrivate));
diff --git a/aisleriot/game.c b/aisleriot/game.c
index 39dd9c2..c48ac7b 100644
--- a/aisleriot/game.c
+++ b/aisleriot/game.c
@@ -44,8 +44,6 @@
#include "game.h"
-#include "board.h"
-
#define DELAYED_CALLBACK_DELAY (50)
#if GLIB_CHECK_VERSION (2, 10, 0)
@@ -239,7 +237,7 @@ clear_slots (AisleriotGame *game,
n_slots = game->slots->len;
for (i = 0; i < n_slots; ++i) {
- Slot *slot = game->slots->pdata[i];
+ ArSlot *slot = game->slots->pdata[i];
#ifdef HAVE_CLUTTER
if (slot->slot_renderer) {
@@ -254,7 +252,7 @@ clear_slots (AisleriotGame *game,
g_byte_array_free (slot->cards, TRUE);
#if GLIB_CHECK_VERSION (2, 10, 0)
- g_slice_free (Slot, slot);
+ g_slice_free (ArSlot, slot);
#else
g_free (slot);
#endif
@@ -267,7 +265,7 @@ clear_slots (AisleriotGame *game,
}
}
-static Slot *
+static ArSlot *
get_slot (AisleriotGame *game,
gint slotid)
{
@@ -275,7 +273,7 @@ get_slot (AisleriotGame *game,
n_slots = game->slots->len;
for (i = 0; i < n_slots; ++i) {
- Slot *hslot = game->slots->pdata[i];
+ ArSlot *hslot = game->slots->pdata[i];
if (hslot->id == slotid)
return hslot;
@@ -347,7 +345,7 @@ cscmi_exception_get_backtrace (SCM tag, SCM throw_args)
n_slots = slots->len;
if (n_slots > 0) {
for (i = 0; i < n_slots; ++i) {
- Slot *slot = slots->pdata[i];
+ ArSlot *slot = slots->pdata[i];
GByteArray *cards = slot->cards;
guint n_cards;
@@ -529,7 +527,7 @@ c2scm_deck (guint8 *cards,
}
static void
-cscmi_slot_set_cards (Slot *slot,
+cscmi_slot_set_cards (ArSlot *slot,
SCM cards)
{
AisleriotGame *game = app_game;
@@ -569,7 +567,7 @@ static SCM
cscmi_add_slot (SCM slot_data)
{
AisleriotGame *game = app_game;
- Slot *slot;
+ ArSlot *slot;
gboolean expanded_down = FALSE;
gboolean expanded_right = FALSE;
int expansion_depth = 0;
@@ -633,7 +631,7 @@ cscmi_add_slot (SCM slot_data)
/* create and initialize slot */
#if GLIB_CHECK_VERSION (2, 10, 0)
- slot = g_slice_new0 (Slot);
+ slot = g_slice_new0 (ArSlot);
#else
slot = g_new0 (Slot, 1);
#endif
@@ -789,7 +787,7 @@ scm_set_slot_x_expansion (SCM scm_slot_id,
SCM new_exp_val)
{
AisleriotGame *game = app_game;
- Slot *slot;
+ ArSlot *slot;
slot = get_slot (game, scm_num2int (scm_slot_id, SCM_ARG1, NULL));
@@ -813,7 +811,7 @@ scm_set_slot_y_expansion (SCM scm_slot_id,
SCM new_exp_val)
{
AisleriotGame *game = app_game;
- Slot *slot;
+ ArSlot *slot;
slot = get_slot (game, scm_num2int (scm_slot_id, SCM_ARG1, NULL));
@@ -836,7 +834,7 @@ static SCM
scm_get_slot (SCM scm_slot_id)
{
AisleriotGame *game = app_game;
- Slot *slot;
+ ArSlot *slot;
slot = get_slot (game, scm_num2int (scm_slot_id, SCM_ARG1, NULL));
@@ -853,7 +851,7 @@ scm_set_cards (SCM scm_slot_id,
SCM new_cards)
{
AisleriotGame *game = app_game;
- Slot *slot;
+ ArSlot *slot;
slot = get_slot (game, scm_num2int (scm_slot_id, SCM_ARG1, NULL));
@@ -1439,7 +1437,7 @@ aisleriot_game_get_slots (AisleriotGame *game)
*/
void
aisleriot_game_slot_add_cards (AisleriotGame *game,
- Slot *slot,
+ ArSlot *slot,
guint8 *cards,
guint n_cards)
{
@@ -2396,7 +2394,7 @@ aisleriot_game_deal_cards (AisleriotGame *game)
#ifdef HAVE_CLUTTER
void
-aisleriot_game_get_card_offset (Slot *slot,
+aisleriot_game_get_card_offset (ArSlot *slot,
guint card_num,
gboolean old_cards,
gint *xoff, gint *yoff)
@@ -2422,7 +2420,7 @@ aisleriot_game_get_card_offset (Slot *slot,
}
void
-aisleriot_game_reset_old_cards (Slot *slot)
+aisleriot_game_reset_old_cards (ArSlot *slot)
{
g_byte_array_set_size (slot->old_cards, 0);
g_byte_array_append (slot->old_cards, slot->cards->data, slot->cards->len);
diff --git a/aisleriot/game.h b/aisleriot/game.h
index 2e778ea..f76c262 100644
--- a/aisleriot/game.h
+++ b/aisleriot/game.h
@@ -83,7 +83,7 @@ typedef struct {
guint dx_set : 1;
guint dy_set : 1;
guint needs_update : 1;
-} Slot;
+} ArSlot;
#define SLOT_CARDS_N_PREALLOC (32)
@@ -151,7 +151,7 @@ AisleriotGame *aisleriot_game_new (void);
GPtrArray *aisleriot_game_get_slots (AisleriotGame * game);
void aisleriot_game_slot_add_cards (AisleriotGame * game,
- Slot * slot,
+ ArSlot * slot,
guint8 * cards, guint n_cards);
guint aisleriot_game_get_state (AisleriotGame * game);
@@ -228,12 +228,12 @@ void aisleriot_game_generate_exception (AisleriotGame * game);
void aisleriot_game_deal_cards (AisleriotGame *game);
-void aisleriot_game_get_card_offset (Slot *slot,
+void aisleriot_game_get_card_offset (ArSlot *slot,
guint card_num,
gboolean old_cards,
gint *xoff, gint *yoff);
-void aisleriot_game_reset_old_cards (Slot *slot);
+void aisleriot_game_reset_old_cards (ArSlot *slot);
G_END_DECLS
diff --git a/aisleriot/slot-renderer.c b/aisleriot/slot-renderer.c
index 4a829f9..3e60672 100644
--- a/aisleriot/slot-renderer.c
+++ b/aisleriot/slot-renderer.c
@@ -45,7 +45,6 @@ static void aisleriot_slot_renderer_set_cache (AisleriotSlotRenderer *srend,
static void completed_cb (AisleriotSlotRenderer *srend);
-static const ClutterColor default_highlight_color = { 0, 0, 0xaa, 0xff };
G_DEFINE_TYPE (AisleriotSlotRenderer, aisleriot_slot_renderer,
CLUTTER_TYPE_ACTOR);
@@ -58,9 +57,11 @@ typedef struct _AnimationData AnimationData;
struct _AisleriotSlotRendererPrivate
{
+ ArStyle *style;
+
GamesCardTexturesCache *cache;
- Slot *slot;
+ ArSlot *slot;
CoglHandle material;
@@ -90,13 +91,30 @@ enum
PROP_CACHE,
PROP_SLOT,
+ PROP_STYLE,
PROP_HIGHLIGHT,
- PROP_HIGHLIGHT_COLOR,
PROP_REVEALED_CARD,
PROP_ANIMATION_LAYER
};
static void
+sync_style_selection_color (ArStyle *style,
+ GParamSpec *pspec,
+ AisleriotSlotRenderer *srend)
+{
+ AisleriotSlotRendererPrivate *priv = srend->priv;
+ ClutterColor color;
+
+ ar_style_get_selection_color (style, &color);
+ if (clutter_color_equal (&color, &priv->highlight_color))
+ return;
+
+ priv->highlight_color = color;
+
+ /* FIXMEchpe: queue a redraw if necessary! */
+}
+
+static void
aisleriot_slot_renderer_class_init (AisleriotSlotRendererClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -111,67 +129,44 @@ aisleriot_slot_renderer_class_init (AisleriotSlotRendererClass *klass)
actor_class->paint = aisleriot_slot_renderer_paint;
+ g_object_class_install_property
+ (gobject_class,
+ PROP_STYLE,
+ g_param_spec_object ("style", NULL, NULL,
+ AR_TYPE_STYLE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
pspec = g_param_spec_object ("cache", NULL, NULL,
GAMES_TYPE_CARD_TEXTURES_CACHE,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_CACHE, pspec);
pspec = g_param_spec_pointer ("slot", NULL, NULL,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_SLOT, pspec);
pspec = g_param_spec_int ("highlight", NULL, NULL,
-1, G_MAXINT, G_MAXINT,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_HIGHLIGHT, pspec);
-
-#if 0
- pspec = clutter_param_spec_color ("highlight-color", NULL, NULL,
- &default_highlight_color,
- G_PARAM_WRITABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB |
- G_PARAM_CONSTRUCT);
-#else
- pspec = g_param_spec_boxed ("highlight-color", NULL, NULL,
- CLUTTER_TYPE_COLOR,
- G_PARAM_WRITABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
-#endif
- g_object_class_install_property (gobject_class, PROP_HIGHLIGHT_COLOR, pspec);
-
pspec = g_param_spec_int ("revealed-card", NULL, NULL,
-1, G_MAXINT, -1,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_REVEALED_CARD, pspec);
pspec = g_param_spec_object ("animation-layer", NULL, NULL,
CLUTTER_TYPE_CONTAINER,
- G_PARAM_WRITABLE |
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_property (gobject_class, PROP_ANIMATION_LAYER, pspec);
g_type_class_add_private (klass, sizeof (AisleriotSlotRendererPrivate));
@@ -186,7 +181,6 @@ aisleriot_slot_renderer_init (AisleriotSlotRenderer *self)
priv->revealed_card = -1;
priv->highlight_start = G_MAXINT;
- priv->highlight_color = default_highlight_color;
priv->animations = g_array_new (FALSE, FALSE, sizeof (AnimationData));
priv->timeline = clutter_timeline_new (500);
@@ -223,23 +217,29 @@ aisleriot_slot_renderer_dispose (GObject *object)
static void
aisleriot_slot_renderer_finalize (GObject *object)
{
- AisleriotSlotRenderer *self = (AisleriotSlotRenderer *) object;
- AisleriotSlotRendererPrivate *priv = self->priv;
+ AisleriotSlotRenderer *srend = AISLERIOT_SLOT_RENDERER (object);
+ AisleriotSlotRendererPrivate *priv = srend->priv;
g_array_free (priv->animations, TRUE);
+ g_signal_handlers_disconnect_by_func (priv->style,
+ G_CALLBACK (sync_style_selection_color),
+ srend);
+ g_object_unref (priv->style);
+
G_OBJECT_CLASS (aisleriot_slot_renderer_parent_class)->finalize (object);
}
ClutterActor *
-aisleriot_slot_renderer_new (GamesCardTexturesCache *cache, Slot *slot)
+aisleriot_slot_renderer_new (ArStyle *style,
+ GamesCardTexturesCache *cache,
+ ArSlot *slot)
{
- ClutterActor *self = g_object_new (AISLERIOT_TYPE_SLOT_RENDERER,
- "cache", cache,
- "slot", slot,
- NULL);
-
- return self;
+ return g_object_new (AISLERIOT_TYPE_SLOT_RENDERER,
+ "style", style,
+ "cache", cache,
+ "slot", slot,
+ NULL);
}
static void
@@ -278,16 +278,19 @@ aisleriot_slot_renderer_set_property (GObject *object,
priv->slot = g_value_get_pointer (value);
break;
+ case PROP_STYLE:
+ priv->style = g_value_dup_object (value);
+
+ sync_style_selection_color (priv->style, NULL, srend);
+ g_signal_connect (priv->style, "notify::" AR_STYLE_PROP_SELECTION_COLOR,
+ G_CALLBACK (sync_style_selection_color), srend);
+ break;
+
case PROP_HIGHLIGHT:
aisleriot_slot_renderer_set_highlight (srend,
g_value_get_int (value));
break;
- case PROP_HIGHLIGHT_COLOR:
- aisleriot_slot_renderer_set_highlight_color (srend,
- g_value_get_boxed (value));
- break;
-
case PROP_REVEALED_CARD:
aisleriot_slot_renderer_set_revealed_card (srend,
g_value_get_int (value));
@@ -328,7 +331,6 @@ aisleriot_slot_renderer_get_property (GObject *object,
aisleriot_slot_renderer_get_animation_layer (srend));
break;
- case PROP_HIGHLIGHT_COLOR:
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -485,22 +487,6 @@ aisleriot_slot_renderer_set_highlight (AisleriotSlotRenderer *srend,
g_object_notify (G_OBJECT (srend), "highlight");
}
-void
-aisleriot_slot_renderer_set_highlight_color (AisleriotSlotRenderer *srend,
- const ClutterColor *color)
-{
- AisleriotSlotRendererPrivate *priv = srend->priv;
-
- g_return_if_fail (color != NULL);
-
- if (clutter_color_equal (color, &priv->highlight_color))
- return;
-
- priv->highlight_color = *color;
-
- g_object_notify (G_OBJECT (srend), "highlight-color");
-}
-
gint
aisleriot_slot_renderer_get_revealed_card (AisleriotSlotRenderer *srend)
{
diff --git a/aisleriot/slot-renderer.h b/aisleriot/slot-renderer.h
index e2b564c..e96737b 100644
--- a/aisleriot/slot-renderer.h
+++ b/aisleriot/slot-renderer.h
@@ -20,7 +20,9 @@
#include <clutter/clutter.h>
#include <libgames-support/games-card-textures-cache.h>
+
#include "game.h"
+#include "ar-style.h"
G_BEGIN_DECLS
@@ -71,16 +73,14 @@ struct _AisleriotAnimStart
GType aisleriot_slot_renderer_get_type (void) G_GNUC_CONST;
-ClutterActor *aisleriot_slot_renderer_new (GamesCardTexturesCache *cache,
- Slot *slot);
+ClutterActor *aisleriot_slot_renderer_new (ArStyle *style,
+ GamesCardTexturesCache *cache,
+ ArSlot *slot);
void aisleriot_slot_renderer_set_highlight (AisleriotSlotRenderer *srend,
gint hightlight_start);
guint aisleriot_slot_renderer_get_highlight (AisleriotSlotRenderer *srend);
-void aisleriot_slot_renderer_set_highlight_color (AisleriotSlotRenderer *srend,
- const ClutterColor *color);
-
void aisleriot_slot_renderer_set_revealed_card (AisleriotSlotRenderer *srend,
gint revealed_card);
gint aisleriot_slot_renderer_get_revealed_card (AisleriotSlotRenderer *srend);
diff --git a/aisleriot/window.c b/aisleriot/window.c
index 59e9032..1e08e53 100644
--- a/aisleriot/window.c
+++ b/aisleriot/window.c
@@ -50,7 +50,15 @@
#include <libgames-support/games-atk-utils.h>
#endif
+#ifdef HAVE_CLUTTER
+#include "ar-clutter-embed.h"
+#include "ar-style.h"
+#include "baize.h"
#include "board.h"
+#else
+#include "board-noclutter.h"
+#endif
+
#include "conf.h"
#include "game.h"
#include "stats-dialog.h"
@@ -121,7 +129,14 @@ enum
struct _AisleriotWindowPrivate
{
AisleriotGame *game;
+#ifdef HAVE_CLUTTER
+ ArClutterEmbed *board;
+ ArStyle *board_style;
+ ClutterActor *baize_actor;
+ ClutterActor *board_actor;
+#else
AisleriotBoard *board;
+#endif
GamesCardThemes *theme_manager;
GamesCardTheme *theme;
@@ -168,7 +183,10 @@ struct _AisleriotWindowPrivate
guint load_idle_id;
+#ifndef HAVE_CLUTTER
guint use_pixbuf_drawing : 1;
+#endif
+
guint changing_game_type : 1;
guint freecell_mode : 1;
guint toolbar_visible : 1;
@@ -357,7 +375,7 @@ new_game_cb (GtkAction *action,
aisleriot_game_new_game (priv->game, NULL);
gtk_widget_grab_focus (GTK_WIDGET (priv->board));
-};
+}
static void
undo_cb (GtkAction *action,
@@ -366,7 +384,11 @@ undo_cb (GtkAction *action,
AisleriotWindowPrivate *priv = window->priv;
/* If a move is in progress, cancel it before changing the game! */
+#ifdef HAVE_CLUTTER
+ aisleriot_board_abort_move (AISLERIOT_BOARD (priv->board_actor));
+#else
aisleriot_board_abort_move (priv->board);
+#endif
aisleriot_game_undo_move (priv->game);
}
@@ -377,8 +399,11 @@ redo_cb (GtkAction *action,
{
AisleriotWindowPrivate *priv = window->priv;
- /* If a move is in progress, cancel it before changing the game! */
+#ifdef HAVE_CLUTTER
+ aisleriot_board_abort_move (AISLERIOT_BOARD (priv->board_actor));
+#else
aisleriot_board_abort_move (priv->board);
+#endif
aisleriot_game_redo_move (priv->game);
}
@@ -831,6 +856,7 @@ debug_choose_seed_cb (GtkAction *action,
gtk_window_present (GTK_WINDOW (dialog));
}
+#ifndef HAVE_CLUTTER
static void
debug_pixbuf_drawing_cb (GtkToggleAction *action,
AisleriotWindow *window)
@@ -841,6 +867,7 @@ debug_pixbuf_drawing_cb (GtkToggleAction *action,
active = gtk_toggle_action_get_active (action);
aisleriot_board_set_pixbuf_drawing (priv->board, active);
}
+#endif /* !HAVE_CLUTTER */
#endif /* ENABLE_DEBUG_UI */
@@ -971,7 +998,11 @@ clickmove_toggle_cb (GtkToggleAction *action,
click_to_move = gtk_toggle_action_get_active (action);
aisleriot_game_set_click_to_move (priv->game, click_to_move);
+#ifdef HAVE_CLUTTER
+ ar_style_set_click_to_move (priv->board_style, click_to_move);
+#else
aisleriot_board_set_click_to_move (priv->board, click_to_move);
+#endif
games_conf_set_boolean (NULL, aisleriot_conf_get_key (CONF_CLICK_TO_MOVE), click_to_move);
}
@@ -1004,7 +1035,11 @@ animations_toggle_cb (GtkToggleAction *action,
enabled = gtk_toggle_action_get_active (action);
+#ifdef HAVE_CLUTTER
+ ar_style_set_enable_animations (priv->board_style, enabled);
+#else
aisleriot_board_set_animation_mode (priv->board, enabled);
+#endif
games_conf_set_boolean (NULL, aisleriot_conf_get_key (CONF_ANIMATIONS), enabled);
}
@@ -1388,7 +1423,11 @@ aisleriot_window_take_card_theme (AisleriotWindow *window,
}
#endif /* GTK+ 2.10.0 */
+#ifdef HAVE_CLUTTER
+ ar_style_set_card_theme (priv->board_style, theme);
+#else
aisleriot_board_set_card_theme (priv->board, theme);
+#endif
}
static void
@@ -2006,6 +2045,37 @@ aisleriot_window_set_freecell_mode (AisleriotWindow *window,
}
}
+#ifdef HAVE_CLUTTER
+
+static void
+board_cursor_cb (AisleriotBoard *board,
+ int cursor_type,
+ ArClutterEmbed *embed)
+{
+ ar_clutter_embed_set_cursor (embed, (ArCursorType) cursor_type);
+}
+
+static void
+board_error_bell_cb (AisleriotBoard *board,
+ ArClutterEmbed *embed)
+{
+#if GTK_CHECK_VERSION (2, 12, 0) || (defined (HAVE_HILDON) && !defined(HAVE_MAEMO_3))
+ gtk_widget_error_bell (GTK_WIDGET (embed));
+#endif
+}
+
+static void
+embed_size_allocate_cb (ArClutterEmbed *embed,
+ GtkAllocation *allocation,
+ AisleriotWindow *window)
+{
+ AisleriotWindowPrivate *priv = window->priv;
+
+ clutter_actor_set_size (priv->board_actor, allocation->width, allocation->height);
+}
+
+#endif /* HAVE_CLUTTER */
+
/* Class implementation */
#ifdef HAVE_HILDON
@@ -2232,7 +2302,7 @@ aisleriot_window_init (AisleriotWindow *window)
G_CALLBACK (animations_toggle_cb),
FALSE /* not active by default */ },
#endif /* HAVE_CLUTTER */
-#ifdef ENABLE_DEBUG_UI
+#if defined(ENABLE_DEBUG_UI) && !defined(HAVE_CLUTTER)
{ "DebugPixbufDrawing", NULL, "_Pixbuf drawing", NULL, NULL,
G_CALLBACK (debug_pixbuf_drawing_cb),
FALSE },
@@ -2296,7 +2366,9 @@ aisleriot_window_init (AisleriotWindow *window)
#ifdef ENABLE_DEBUG_UI
"<menu action='DebugMenu'>"
"<menuitem action='DebugChooseSeed'/>"
+#ifndef HAVE_CLUTTER
"<menuitem action='DebugPixbufDrawing'/>"
+#endif /* !HAVE_CLUTTER */
"</menu>"
#endif /* ENABLE_DEBUG_UI */
"<menuitem action='CloseWindow'/>"
@@ -2400,11 +2472,11 @@ aisleriot_window_init (AisleriotWindow *window)
GamesCardTheme *theme;
guint i;
#ifndef HAVE_HILDON
- const char *env;
GtkStatusbar *statusbar;
- GtkWidget *statusbar_hbox, *statusbar_label, *label, *time_box;
- GtkContainer *statusbar_frame;
- GList *list;
+ GtkWidget *statusbar_hbox, *label, *time_box;
+#endif
+#ifdef HAVE_CLUTTER
+ ClutterContainer *stage;
#endif
g_assert (G_N_ELEMENTS (names) == LAST_ACTION);
@@ -2415,12 +2487,19 @@ aisleriot_window_init (AisleriotWindow *window)
priv->game = aisleriot_game_new ();
+#ifndef HAVE_CLUTTER
+
#ifdef HAVE_HILDON
priv->use_pixbuf_drawing = FALSE;
#else
- /* Default to pixbuf drawing */
+{
+ const char *env;
+
env = g_getenv ("AISLERIOT_PIXBUF_DRAWING");
+
+ /* Default to pixbuf drawing */
priv->use_pixbuf_drawing = env == NULL || g_ascii_strtoull (env, NULL, 10) != 0;
+}
#endif /* HAVE_HILDON */
#ifdef GNOME_ENABLE_DEBUG
@@ -2430,11 +2509,41 @@ aisleriot_window_init (AisleriotWindow *window)
g_print ("Using pixmap drawing method\n");
#endif /* GNOME_ENABLE_DEBUG */
+#endif /* !HAVE_CLUTTER */
+
priv->theme_manager = games_card_themes_new ();
+#ifdef HAVE_CLUTTER
+ priv->board_style = ar_style_new ();
+ priv->board = ar_clutter_embed_new (priv->board_style);
+
+ priv->baize_actor = aisleriot_baize_new ();
+
+ stage = CLUTTER_CONTAINER (gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (priv->board)));
+ clutter_container_add (stage, priv->baize_actor, NULL);
+ /* FIXMEchpe: how to ensure this is ALWAYS the lowest actor? */
+ clutter_actor_lower_bottom (priv->baize_actor);
+
+ priv->board_actor = aisleriot_board_new (priv->board_style, priv->game);
+ clutter_container_add (stage, priv->board_actor, NULL);
+
+ /* FIXMEchpe */
+ clutter_stage_set_key_focus (CLUTTER_STAGE (stage), priv->board_actor);
+
+ g_signal_connect_after (priv->board, "size-allocate",
+ G_CALLBACK (embed_size_allocate_cb), window);
+
+ g_signal_connect (priv->board_actor, "request-cursor",
+ G_CALLBACK (board_cursor_cb), priv->board);
+ g_signal_connect (priv->board_actor, "error-bell",
+ G_CALLBACK (board_error_bell_cb), priv->board);
+
+ /* FIXMEchpe: unref baize & board_actor here? */
+#else
priv->board = AISLERIOT_BOARD (aisleriot_board_new (priv->game));
aisleriot_board_set_pixbuf_drawing (priv->board, priv->use_pixbuf_drawing);
+#endif /* HAVE_CLUTTER */
theme_name = games_conf_get_string (NULL, aisleriot_conf_get_key (CONF_THEME), NULL);
theme = games_card_themes_get_theme_by_name (priv->theme_manager, theme_name);
@@ -2490,6 +2599,15 @@ aisleriot_window_init (AisleriotWindow *window)
gtk_statusbar_set_has_resize_grip (priv->statusbar, FALSE);
#endif
+#if GTK_CHECK_VERSION (2, 19, 1)
+ statusbar_hbox = gtk_statusbar_get_message_area (statusbar);
+ gtk_box_set_spacing (GTK_BOX (statusbar_hbox), 24);
+#else
+{
+ GtkWidget *statusbar_label,
+ GtkContainer *statusbar_frame;
+ GList *list;
+
/* Widget surgery: move the statusbar's label into a hbox
* which we put in the statusbar's frame instead.
*/
@@ -2504,6 +2622,8 @@ aisleriot_window_init (AisleriotWindow *window)
g_object_unref (statusbar_label);
gtk_container_add (statusbar_frame, statusbar_hbox);
gtk_widget_show (statusbar_hbox);
+}
+#endif /* GTK+ >= 2.19.1 */
/* Score */
priv->score_box = gtk_hbox_new (12, FALSE);
@@ -2717,10 +2837,10 @@ aisleriot_window_init (AisleriotWindow *window)
G_CALLBACK (sync_window_topmost_cb), NULL);
#endif
-#ifdef ENABLE_DEBUG_UI
+#if defined(ENABLE_DEBUG_UI) && !defined(HAVE_CLUTTER)
action = gtk_action_group_get_action (priv->action_group, "DebugPixbufDrawing");
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), priv->use_pixbuf_drawing);
-#endif /* ENABLE_DEBUG_UI */
+#endif /* ENABLE_DEBUG_UI && !HAVE_CLUTTER */
}
static void
@@ -2775,6 +2895,10 @@ aisleriot_window_finalize (GObject *object)
AisleriotWindow *window = AISLERIOT_WINDOW (object);
AisleriotWindowPrivate *priv = window->priv;
+#ifdef HAVE_CLUTTER
+ g_object_unref (priv->board_style);
+#endif /* HAVE_CLUTTER */
+
if (priv->theme) {
g_object_unref (priv->theme);
}
diff --git a/libgames-support/games-debug.c b/libgames-support/games-debug.c
index 0145a8c..852c94d 100644
--- a/libgames-support/games-debug.c
+++ b/libgames-support/games-debug.c
@@ -37,7 +37,12 @@ _games_debug_init (void)
{ "runtime", GAMES_DEBUG_RUNTIME },
{ "scheme", GAMES_DEBUG_SCHEME },
{ "sound", GAMES_DEBUG_SOUND },
- { "window-state", GAMES_DEBUG_WINDOW_STATE }
+ { "window-state", GAMES_DEBUG_WINDOW_STATE },
+
+ { "game-drawing", GAMES_DEBUG_GAME_DRAWING },
+ { "game-events", GAMES_DEBUG_GAME_EVENTS },
+ { "game-keynav", GAMES_DEBUG_GAME_KEYNAV },
+ { "game-sizing", GAMES_DEBUG_GAME_SIZING }
};
const char *env;
diff --git a/libgames-support/games-debug.h b/libgames-support/games-debug.h
index b9c7fe7..cdc4d38 100644
--- a/libgames-support/games-debug.h
+++ b/libgames-support/games-debug.h
@@ -34,7 +34,12 @@ typedef enum {
GAMES_DEBUG_RUNTIME = 1 << 3,
GAMES_DEBUG_SCHEME = 1 << 4,
GAMES_DEBUG_SOUND = 1 << 5,
- GAMES_DEBUG_WINDOW_STATE = 1 << 6
+ GAMES_DEBUG_WINDOW_STATE = 1 << 6,
+
+ GAMES_DEBUG_GAME_DRAWING = 1 << 7,
+ GAMES_DEBUG_GAME_EVENTS = 1 << 8,
+ GAMES_DEBUG_GAME_KEYNAV = 1 << 9,
+ GAMES_DEBUG_GAME_SIZING = 1 << 10
} GamesDebugFlags;
#ifdef GNOME_ENABLE_DEBUG
diff --git a/libgames-support/games-marshal.list b/libgames-support/games-marshal.list
index d726378..4b35878 100644
--- a/libgames-support/games-marshal.list
+++ b/libgames-support/games-marshal.list
@@ -1,2 +1,3 @@
VOID:STRING,STRING
BOOLEAN:ENUM,INT
+BOOLEAN:STRING,UINT,ENUM
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]