[maemo-commits] [maemo-commits] r8866 - in projects/haf/branches/gtk+/maemo-gtk-2-10: . gtk
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Fri Dec 22 17:21:49 EET 2006
- Previous message: [maemo-commits] r8865 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r8867 - projects/haf/trunk/pyrex/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: kris Date: 2006-12-22 17:21:45 +0200 (Fri, 22 Dec 2006) New Revision: 8866 Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkbutton.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkcontainer.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkiconfactory.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkicontheme.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.h projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkstyle.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtktreeview.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.c projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.h projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/updateiconcache.c Log: 2006-12-22 Kristian Rietveld <kris at imendio.com> * gtk/gtkwidget.[ch]: Ported over the tap and hold implementation from maemo-gtk-2-6. * gtk/gtktreeview.c * gtk/gtkcontainer.c * gtk/gtkbutton.c: Port over tap and hold support from maemo-gtk-2-6. * gtk/gtkmenu.[ch] (gtk_menu_init), (gtk_menu_popup): Partially port over _gtk_menu_enable_context_menu_behaviour() and related changes. * gtk/gtkiconfactory.c (init_icon_sizes): Initialize hildon icon sizes, don't scale icons with hildon icon size. * gtk/gtkicontheme.c: Support animations, don't prefer built in icons when looking up icons. * gtk/gtkstyle.c (gtk_default_render_icon): Ported over maemo-gtk-2-6 change which refrains from scaling icons with hildon icon size. * gtk/updateiconcache.c: Port over support for animations. Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog 2006-12-22 15:21:45 UTC (rev 8866) @@ -1,3 +1,27 @@ +2006-12-22 Kristian Rietveld <kris at imendio.com> + + * gtk/gtkwidget.[ch]: Ported over the tap and hold implementation + from maemo-gtk-2-6. + + * gtk/gtktreeview.c + * gtk/gtkcontainer.c + * gtk/gtkbutton.c: Port over tap and hold support from maemo-gtk-2-6. + + * gtk/gtkmenu.[ch] (gtk_menu_init), (gtk_menu_popup): Partially + port over _gtk_menu_enable_context_menu_behaviour() and related + changes. + + * gtk/gtkiconfactory.c (init_icon_sizes): Initialize hildon icon + sizes, don't scale icons with hildon icon size. + + * gtk/gtkicontheme.c: Support animations, don't prefer built in + icons when looking up icons. + + * gtk/gtkstyle.c (gtk_default_render_icon): Ported over maemo-gtk-2-6 + change which refrains from scaling icons with hildon icon size. + + * gtk/updateiconcache.c: Port over support for animations. + 2006-12-22 Michael Natterer <mitch at imendio.com> * gtk/gtkenums.h: add HILDON_ICON_SIZE_FOO GtkIconSize values. Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkbutton.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkbutton.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkbutton.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -515,6 +515,12 @@ priv->align_set = 0; priv->image_is_stock = TRUE; priv->image_position = GTK_POS_LEFT; + + /* MAEMO START */ + g_object_set (G_OBJECT (button), + "tap-and-hold-state", GTK_STATE_ACTIVE, + NULL); + /* MAEMO END */ } static void Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkcontainer.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkcontainer.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkcontainer.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -39,8 +39,10 @@ #include <gobject/gobjectnotifyqueue.c> #include <gobject/gvaluecollector.h> #include "gtkalias.h" +/* MAEMO START */ +#include "gtkmenu.h" +/* MAEMO END */ - enum { ADD, REMOVE, @@ -56,6 +58,16 @@ PROP_CHILD }; +/* MAEMO START */ +typedef struct +{ + GtkWidget *menu; + void *func; + GtkWidgetTapAndHoldFlags flags; +} GtkContainerTAH; + +/* MAEMO END */ + #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id) #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id)) @@ -99,6 +111,14 @@ static gchar* gtk_container_child_default_composite_name (GtkContainer *container, GtkWidget *child); +/* MAEMO START */ +static void gtk_container_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags); +static void gtk_container_tap_and_hold_setup_forall (GtkWidget *widget, + GtkContainerTAH *tah); +/* MAEMO END */ /* --- variables --- */ static const gchar vadjustment_key[] = "gtk-vadjustment"; @@ -190,6 +210,9 @@ widget_class->map = gtk_container_map; widget_class->unmap = gtk_container_unmap; widget_class->focus = gtk_container_focus; + /* MAEMO START */ + widget_class->tap_and_hold_setup = gtk_container_tap_and_hold_setup; + /* MAEMO END */ class->add = gtk_container_add_unimplemented; class->remove = gtk_container_remove_unimplemented; @@ -2464,5 +2487,40 @@ } } +/* MAEMO START */ +static void +gtk_container_tap_and_hold_setup_forall (GtkWidget *widget, + GtkContainerTAH *tah) +{ + gtk_widget_tap_and_hold_setup (widget, tah->menu, tah->func, tah->flags); +} + +static void +gtk_container_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags) +{ + GtkContainerTAH tah; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (menu == NULL || GTK_IS_MENU (menu)); + + tah.menu = menu; + tah.func = func; + tah.flags = flags; + + if (flags & GTK_TAP_AND_HOLD_NO_INTERNALS) + gtk_container_foreach (GTK_CONTAINER (widget), + (GtkCallback)gtk_container_tap_and_hold_setup_forall, &tah); + else + gtk_container_forall (GTK_CONTAINER (widget), + (GtkCallback)gtk_container_tap_and_hold_setup_forall, + &tah); + + parent_class->tap_and_hold_setup (widget, menu, func, flags); +} +/* MAEMO END */ + #define __GTK_CONTAINER_C__ #include "gtkaliasdef.c" Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkiconfactory.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkiconfactory.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkiconfactory.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -555,7 +555,9 @@ { if (icon_sizes == NULL) { -#define NUM_BUILTIN_SIZES 7 +/* MAEMO START */ +#define NUM_BUILTIN_SIZES 11 +/* MAEMO END */ gint i; icon_aliases = g_hash_table_new (g_str_hash, g_str_equal); @@ -605,8 +607,30 @@ icon_sizes[GTK_ICON_SIZE_DIALOG].width = 48; icon_sizes[GTK_ICON_SIZE_DIALOG].height = 48; - g_assert ((GTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES); + /* MAEMO START */ + icon_sizes[HILDON_ICON_SIZE_26].size = HILDON_ICON_SIZE_26; + icon_sizes[HILDON_ICON_SIZE_26].name = "hildon-26"; + icon_sizes[HILDON_ICON_SIZE_26].width = 26; + icon_sizes[HILDON_ICON_SIZE_26].height = 26; + icon_sizes[HILDON_ICON_SIZE_40].size = HILDON_ICON_SIZE_40; + icon_sizes[HILDON_ICON_SIZE_40].name = "hildon-40"; + icon_sizes[HILDON_ICON_SIZE_40].width = 40; + icon_sizes[HILDON_ICON_SIZE_40].height = 40; + + icon_sizes[HILDON_ICON_SIZE_50].size = HILDON_ICON_SIZE_50; + icon_sizes[HILDON_ICON_SIZE_50].name = "hildon-50"; + icon_sizes[HILDON_ICON_SIZE_50].width = 50; + icon_sizes[HILDON_ICON_SIZE_50].height = 50; + + icon_sizes[HILDON_ICON_SIZE_64].size = HILDON_ICON_SIZE_64; + icon_sizes[HILDON_ICON_SIZE_64].name = "hildon-64"; + icon_sizes[HILDON_ICON_SIZE_64].width = 54; + icon_sizes[HILDON_ICON_SIZE_64].height = 64; + + g_assert ((HILDON_ICON_SIZE_64 + 1) == NUM_BUILTIN_SIZES); + /* MAEMO END */ + /* Alias everything to itself. */ i = 1; /* skip invalid size */ while (i < NUM_BUILTIN_SIZES) @@ -1477,7 +1501,10 @@ tmp_source.source.pixbuf = tmp_pixbuf; pixbuf = gtk_style_render_icon (style, &tmp_source, - direction, state, -1, + direction, state, + /* MAEMO START */ + (size < HILDON_ICON_SIZE_26) ? -1 : size, + /* MAEMO END */ widget, detail); if (!pixbuf) Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkicontheme.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkicontheme.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkicontheme.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -62,7 +62,10 @@ ICON_SUFFIX_XPM = 1 << 0, ICON_SUFFIX_SVG = 1 << 1, ICON_SUFFIX_PNG = 1 << 2, - HAS_ICON_FILE = 1 << 3 + HAS_ICON_FILE = 1 << 3, + /* MAEMO START */ + ICON_SUFFIX_ANI = 1 << 4 + /* MAEMO END */ } IconSuffix; @@ -1257,7 +1260,7 @@ for (l = priv->themes; l; l = l->next) { IconTheme *theme = l->data; - + icon_info = theme_lookup_icon (theme, icon_name, size, allow_svg, use_builtin); if (icon_info) goto out; @@ -1795,6 +1798,10 @@ return ".svg"; case ICON_SUFFIX_PNG: return ".png"; + /* MAEMO START */ + case ICON_SUFFIX_ANI: + return ".ani"; + /* MAEMO END */ default: g_assert_not_reached(); } @@ -1812,6 +1819,10 @@ retval = ICON_SUFFIX_SVG; else if (g_str_has_suffix (name, ".xpm")) retval = ICON_SUFFIX_XPM; + /* MAEMO START */ + else if (g_str_has_prefix (name, ".ani")) + retval = ICON_SUFFIX_ANI; + /* MAEMO END */ else retval = ICON_SUFFIX_NONE; @@ -1828,6 +1839,10 @@ return ICON_SUFFIX_SVG; else if ((suffix & ICON_SUFFIX_XPM) != 0) return ICON_SUFFIX_XPM; + /* MAEMO START */ + else if ((suffix & ICON_SUFFIX_ANI) != 0) + return ICON_SUFFIX_ANI; + /* MAEMO END */ else return ICON_SUFFIX_NONE; } @@ -1879,24 +1894,9 @@ min_dir = NULL; has_larger = FALSE; - /* Builtin icons are logically part of the default theme and - * are searched before other subdirectories of the default theme. - */ - if (strcmp (theme->name, DEFAULT_THEME_NAME) == 0 && use_builtin) - { - closest_builtin = find_builtin_icon (icon_name, - size, - &min_difference, - &has_larger); + /* MAEMO CHANGE: code to prefer built in icons removed */ + dirs = theme->dirs; - if (min_difference == 0) - return icon_info_new_builtin (closest_builtin); - - dirs = builtin_dirs; - } - else - dirs = theme->dirs; - l = dirs; while (l != NULL) { @@ -1946,8 +1946,7 @@ } } - if (closest_builtin) - return icon_info_new_builtin (closest_builtin); + /* MAEMO CHANGE: code to prefer built in icons removed */ if (min_dir) { @@ -2014,6 +2013,21 @@ return icon_info; } + + /* MAEMO START */ + /* When an icon isn't found even in the default theme, try builtin stock + * icons as the last resort + */ + if (strcmp (theme->name, DEFAULT_THEME_NAME) == 0 && use_builtin) + { + closest_builtin = find_builtin_icon (icon_name, size, + &min_difference, + &has_larger); + + if (closest_builtin) + return icon_info_new_builtin (closest_builtin); + } + /* MAEMO END */ return NULL; } Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -100,6 +100,13 @@ gboolean ignore_button_release; gboolean initially_pushed_in; + + /* MAEMO START */ + /* For context menu behavior */ + gboolean context_menu; + int popup_pointer_x; + int popup_pointer_y; + /* MAEMO END */ }; typedef struct @@ -896,6 +903,12 @@ priv->upper_arrow_state = GTK_STATE_NORMAL; priv->lower_arrow_state = GTK_STATE_NORMAL; + /* MAEMO START */ + priv->context_menu = FALSE; + priv->popup_pointer_x = -1; + priv->popup_pointer_y = -1; + /* MAEMO END */ + priv->have_layout = FALSE; } @@ -1429,6 +1442,15 @@ gtk_menu_scroll_to (menu, menu->scroll_offset); + /* MAEMO START */ + /* Hildon: save position of the pointer during popup. Not multihead safe. */ + if (priv->context_menu) + gdk_display_get_pointer (gtk_widget_get_display (widget), NULL, + &priv->popup_pointer_x, + &priv->popup_pointer_y, + NULL); + /* MAEMO END */ + /* Once everything is set up correctly, map the toplevel window on the screen. */ @@ -4835,5 +4857,16 @@ } } +/* MAEMO START */ +/* Hildon function to make context menus behave according to spec */ +void +_gtk_menu_enable_context_menu_behavior (GtkMenu *menu) +{ + GtkMenuPrivate *priv = gtk_menu_get_private (menu); + + priv->context_menu = TRUE; +} +/* MAEMO END */ + #define __GTK_MENU_C__ #include "gtkaliasdef.c" Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.h =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.h 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkmenu.h 2006-12-22 15:21:45 UTC (rev 8866) @@ -198,6 +198,10 @@ gint monitor_num); GList* gtk_menu_get_for_attach_widget (GtkWidget *widget); +/* MAEMO START */ +void _gtk_menu_enable_context_menu_behavior (GtkMenu *menu); +/* MAEMO END */ + #ifndef GTK_DISABLE_DEPRECATED #define gtk_menu_append(menu,child) gtk_menu_shell_append ((GtkMenuShell *)(menu),(child)) #define gtk_menu_prepend(menu,child) gtk_menu_shell_prepend ((GtkMenuShell *)(menu),(child)) Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkstyle.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkstyle.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkstyle.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -2126,7 +2126,8 @@ /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise, * leave it alone. */ - if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source)) + if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source) + /* MAEMO START */ && size < HILDON_ICON_SIZE_26 /* MAEMO END */) scaled = scale_or_ref (base_pixbuf, width, height); else scaled = g_object_ref (base_pixbuf); Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtktreeview.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtktreeview.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtktreeview.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -462,6 +462,11 @@ static gint scroll_row_timeout (gpointer data); static void remove_scroll_timeout (GtkTreeView *tree_view); +/* MAEMO START */ +static gboolean gtk_tree_view_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event); +/* MAEMO END */ + static guint tree_view_signals [LAST_SIGNAL] = { 0 }; @@ -525,6 +530,9 @@ widget_class->style_set = gtk_tree_view_style_set; widget_class->grab_notify = gtk_tree_view_grab_notify; widget_class->state_changed = gtk_tree_view_state_changed; + /* MAEMO START */ + widget_class->tap_and_hold_query = gtk_tree_view_tap_and_hold_query; + /* MAEMO END */ /* GtkContainer signals */ container_class->remove = gtk_tree_view_remove; @@ -14748,5 +14756,41 @@ } } +/* MAEMO START */ +static gboolean +gtk_tree_view_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event) +{ + GtkTreeView *tree_view = GTK_TREE_VIEW (widget); + GtkTreePath *path; + GtkRBTree *tree = NULL; + GtkRBNode *node = NULL; + gdouble x, y; + gint new_y; + gboolean sensitive; + + if (!tree_view->priv->tree) + return FALSE; + + if (!gdk_event_get_coords (event, &x, &y)) + return FALSE; + + new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y); + if (new_y < 0) + new_y = 0; + _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); + if (node == NULL) + return TRUE; + + path = _gtk_tree_view_find_path (tree_view, tree, node); + sensitive = _gtk_tree_selection_row_is_selectable (tree_view->priv->selection, + node, path); + gtk_tree_path_free (path); + + return !sensitive; +} + +/* MAEMO END */ + #define __GTK_TREE_VIEW_C__ #include "gtkaliasdef.c" Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -53,11 +53,25 @@ #include "gtktooltips.h" #include "gtkinvisible.h" #include "gtkalias.h" +/* MAEMO START */ +#include <x11/gdkx.h> +#include <stdlib.h> +#include "gtkmenu.h" +#include "gtkmenuitem.h" +#include "gtkicontheme.h" +#include "gtkdnd.h" +/* MAEMO END */ #define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w) #define INIT_PATH_SIZE (512) +/* MAEMO START */ +#define TAP_AND_HOLD_TIMER_COUNTER 11 +#define TAP_AND_HOLD_TIMER_INTERVAL 100 +#define TAP_AND_HOLD_ANIMATION 1 +/* MAEMO END */ + enum { SHOW, HIDE, @@ -122,6 +136,11 @@ CAN_ACTIVATE_ACCEL, GRAB_BROKEN, COMPOSITED_CHANGED, + /* MAEMO START */ + TAP_AND_HOLD, + TAP_AND_HOLD_SETUP, + TAP_AND_HOLD_QUERY, + /* MAEMO END */ LAST_SIGNAL }; @@ -144,7 +163,10 @@ PROP_STYLE, PROP_EVENTS, PROP_EXTENSION_EVENTS, - PROP_NO_SHOW_ALL + PROP_NO_SHOW_ALL, + /* MAEMO START */ + PROP_TAP_AND_HOLD + /* MAEMO END */ }; typedef struct _GtkStateData GtkStateData; @@ -157,7 +179,46 @@ guint use_forall : 1; }; +/* MAEMO START */ +typedef struct +{ + GtkWidget *menu; + guint timer_id; + GtkMenuPositionFunc func; + gint x, y; + gint timer_counter; + gint signals_connected : 1; + guint interval; + GdkWindow *tah_on_window; + +#ifdef TAP_AND_HOLD_ANIMATION + GdkPixbufAnimation *anim; + GdkPixbufAnimationIter *iter; +#endif +} TahData; + + +/* --- Tap And Hold --- */ +static gboolean gtk_widget_tap_and_hold_timeout (GtkWidget *widget); +static gboolean gtk_widget_tap_and_hold_button_press (GtkWidget *widget, + GdkEvent *event, + TahData *td); +static gboolean gtk_widget_tap_and_hold_event_stop (GtkWidget *widget, + gpointer unused, + TahData *td); +static void gtk_widget_real_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags ); +static void gtk_widget_real_tap_and_hold (GtkWidget *widget); +static gboolean gtk_widget_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event); +static gboolean gtk_widget_real_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event); +/* MAEMO END */ + + /* --- prototypes --- */ static void gtk_widget_class_init (GtkWidgetClass *klass); static void gtk_widget_base_class_finalize (GtkWidgetClass *klass); @@ -404,6 +465,11 @@ klass->screen_changed = NULL; klass->can_activate_accel = gtk_widget_real_can_activate_accel; klass->grab_broken_event = NULL; + /* MAEMO START */ + klass->tap_and_hold_setup = gtk_widget_real_tap_and_hold_setup; + klass->tap_and_hold = gtk_widget_real_tap_and_hold; + klass->tap_and_hold_query = gtk_widget_real_tap_and_hold_query; + /* MAEMO END */ klass->show_help = gtk_widget_real_show_help; @@ -545,6 +611,31 @@ P_("Whether gtk_widget_show_all() should not affect this widget"), FALSE, GTK_PARAM_READWRITE)); + + /* MAEMO START */ + /** + * GtkWidget:tap-and-hold-state: + * + * Sets the state (#GtkStateType) to be used to the tap and hold + * functionality. The default is GTK_STATE_NORMAL. + * + * Warning: Functionality for setting and getting this propery is not + * implemented. + * + * Since: maemo 1.0 + */ + g_object_class_install_property (gobject_class, + PROP_TAP_AND_HOLD, + g_param_spec_int ("tap-and-hold-state", + P_("Tap and hold State type"), + P_("Sets the state to be used to the tap and hold functionality. The default is GTK_STATE_NORMAL"), + 0, + 4, /*4 == Last state in GTK+-2.0*/ + GTK_STATE_NORMAL, + G_PARAM_READWRITE)); + + /* MAEMO END */ + widget_signals[SHOW] = g_signal_new (I_("show"), G_TYPE_FROM_CLASS (gobject_class), @@ -1465,6 +1556,72 @@ _gtk_marshal_BOOLEAN__UINT, G_TYPE_BOOLEAN, 1, G_TYPE_UINT); + /* MAEMO START */ + /** + * GtkWidget::tap-and-hold: + * @widget: the object which received the signal + * + * The signal is emited when tap and hold activity occurs. + * + * Since: maemo 1.0 + */ + widget_signals[TAP_AND_HOLD] = + g_signal_new("tap_and_hold", G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold), + NULL, NULL, + _gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + /** + * GtkWidget::tap-and-hold-setup: + * @widget: the object which received the signal + * @menu: the menu to be opened. + * @func: the menu position function + * @flags: debricated + * + * Enables the tap and hold functionality to the @widget. + * Usually a @menu is used at tap and hold signal, + * but this is optional. Setup can be run and some other functionality + * may be connected to it as well. Usually this signal is not used, + * instead the virtual function is over written. + * + * Signal is deprecated and should not be used. + * + * @Deprecated + * + * Since: maemo 1.0 + */ + widget_signals[TAP_AND_HOLD_SETUP] = + g_signal_new("tap_and_hold_setup", G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold_setup), + NULL, NULL, /*FIXME -- OBJECT_POINTER_FLAGS*/ + _gtk_marshal_VOID__OBJECT_UINT_FLAGS, + G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT); + + /** + * GtkWidget::tap-and-hold-query: + * @widget: the object which received the signal + * @returns: %FALSE if tap and hold is allowed to be started + * + * Signal is used in a situation where tap and hold is not allowed to be + * started in some mysterious reason. A good mysterious reason could be, + * a widget which area is big and only part of it is allowed to start + * tap and hold. + * + * Since: maemo 1.0 + */ + widget_signals[TAP_AND_HOLD_QUERY] = + g_signal_new ("tap_and_hold_query", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkWidgetClass, tap_and_hold_query), + _gtk_boolean_handled_accumulator, NULL, + _gtk_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, 1, GDK_TYPE_EVENT); + + /* MAEMO END */ + binding_set = gtk_binding_set_by_class (klass); gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK, "popup_menu", 0); @@ -1753,6 +1910,10 @@ case PROP_NO_SHOW_ALL: gtk_widget_set_no_show_all (widget, g_value_get_boolean (value)); break; + /* MAEMO START */ + case PROP_TAP_AND_HOLD: + break; + /* MAEMO END */ default: break; } @@ -1847,6 +2008,10 @@ case PROP_NO_SHOW_ALL: g_value_set_boolean (value, gtk_widget_get_no_show_all (widget)); break; + /* MAEMO START */ + case PROP_TAP_AND_HOLD: + break; + /* MAEMO END */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -8067,16 +8232,460 @@ return FALSE; } -void gtk_widget_tap_and_hold_menu_position_top (GtkWidget *menu, - gint *x, gint *y, gboolean *push_in, GtkWidget *widget) + +/* -- Tap and hold implementation -- */ + +static TahData* +gtk_widget_peek_tah_data (GtkWidget *widget) { + TahData *td = g_object_get_data (G_OBJECT (widget), "MaemoGtkWidget-tap-and-hold"); + return td; } -void gtk_widget_tap_and_hold_setup (GtkWidget *widget, GtkWidget *menu, - GtkCallback func, GtkWidgetTapAndHoldFlags flags) +static void +tap_and_hold_stop_animation (TahData *td) { +#ifdef TAP_AND_HOLD_ANIMATION + if (td->tah_on_window) + gdk_window_set_cursor (td->tah_on_window, NULL); + td->tah_on_window = NULL; + + if (td->anim) + g_object_unref (td->anim); + td->anim = NULL; + + if (td->iter) + g_object_unref (td->iter); + td->iter = NULL; +#endif } +static void +tap_and_hold_free_data (gpointer data) +{ + TahData *td = data; + if (td) + { + if (td->timer_id) + g_source_remove (td->timer_id); + td->timer_id = 0; + + if (GTK_IS_MENU (td->menu)) + g_object_unref (td->menu); + td->menu = NULL; + + tap_and_hold_stop_animation (td); + + g_free (td); + } +} + +static void +gtk_widget_set_tah_data (GtkWidget *widget, TahData *td) +{ + g_object_set_data_full (G_OBJECT (widget), "MaemoGtkWidget-tap-and-hold", + td, tap_and_hold_free_data); +} + +static TahData* +gtk_widget_get_tah_data (GtkWidget *widget) +{ + TahData *td = gtk_widget_peek_tah_data (widget); + if (!td) + { + td = g_new0 (TahData, 1); + td->interval = TAP_AND_HOLD_TIMER_INTERVAL; + gtk_widget_set_tah_data (widget, td); + } + return td; +} + +static void +tap_and_hold_remove_timer (GtkWidget *widget) +{ + TahData *td = gtk_widget_peek_tah_data (widget); + if (td) + { + if (td->timer_id) + { + g_source_remove (td->timer_id); + td->timer_id = 0; + } + + td->x = td->y = td->timer_counter = 0; + tap_and_hold_stop_animation (td); + } +} + +#ifdef TAP_AND_HOLD_ANIMATION +static GdkPixbufAnimation * +tap_and_hold_load_animation_for_screen (GdkScreen *screen) +{ + GtkIconTheme *theme; + GtkIconInfo *info; + const char *filename = NULL; + GdkPixbufAnimation *anim = NULL; + GError *error = NULL; + + theme = gtk_icon_theme_get_for_screen (screen); + + info = gtk_icon_theme_lookup_icon (theme, "qgn_indi_tap_hold_a", + GTK_ICON_SIZE_BUTTON, + GTK_ICON_LOOKUP_NO_SVG); + if (info) + filename = gtk_icon_info_get_filename (info); + if (!info || !filename) + { + g_warning ("Unable to find tap and hold icon filename"); + goto out; + } + + anim = gdk_pixbuf_animation_new_from_file (filename, &error); + if (!anim) + { + g_warning ("Unable to load tap and hold animation: %s", error->message); + goto out; + } + +out: + if (info) + gtk_icon_info_free (info); + if (error) + g_error_free (error); + + return anim; +} +#endif + +static void +tap_and_hold_init_animation (TahData *td) +{ +#ifdef TAP_AND_HOLD_ANIMATION + if (!td->anim) + td->anim = tap_and_hold_load_animation_for_screen (gdk_drawable_get_screen (td->tah_on_window)); + + if (td->anim) + { + if (td->iter) + g_object_unref (td->iter); + td->iter = gdk_pixbuf_animation_get_iter (td->anim, NULL); + + td->interval = gdk_pixbuf_animation_iter_get_delay_time (td->iter); + } +#endif +} + +static gboolean +tap_and_hold_animation_timeout (GtkWidget *widget) +{ +#ifdef TAP_AND_HOLD_ANIMATION + TahData *td = gtk_widget_peek_tah_data (widget); + + if (!td || !GDK_IS_WINDOW (td->tah_on_window)) + { + tap_and_hold_remove_timer (widget); + return FALSE; + } + + if (td->anim) + { + guint new_interval = 0; + GTimeVal time; + GdkScreen *screen; + GdkPixbuf *pic; + GdkCursor *cursor; + const gchar *x_hot, *y_hot; + gint x, y; + + g_get_current_time (&time); + screen = gdk_screen_get_default (); + pic = gdk_pixbuf_animation_iter_get_pixbuf (td->iter); + + pic = gdk_pixbuf_copy (pic); + + if (!GDK_IS_PIXBUF (pic)) + return TRUE; + + x_hot = gdk_pixbuf_get_option (pic, "x_hot"); + y_hot = gdk_pixbuf_get_option (pic, "y_hot"); + x = (x_hot) ? atoi(x_hot) : gdk_pixbuf_get_width(pic) / 2; + y = (y_hot) ? atoi(y_hot) : gdk_pixbuf_get_height(pic) / 2; + + cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (), pic, + x, y); + g_object_unref (pic); + + if (!cursor) + return TRUE; + + gdk_window_set_cursor (td->tah_on_window, cursor); + gdk_cursor_unref (cursor); + + gdk_pixbuf_animation_iter_advance (td->iter, &time); + + new_interval = gdk_pixbuf_animation_iter_get_delay_time (td->iter); + + if (new_interval != td->interval && td->timer_counter) + { + td->interval = new_interval; + td->timer_id = g_timeout_add (td->interval, + (GSourceFunc)gtk_widget_tap_and_hold_timeout, widget); + return FALSE; + } + } +#endif + return TRUE; +} + +/** + * gtk_widget_tap_and_hold_menu_position_top: + * @menu: a #GtkMenu + * @x: x cordinate to be returned + * @y: y cordinate to be returned + * @push_in: If going off screen, push it pack on the screen + * @widget: a #GtkWidget + * + * Pre-made menu positioning function. + * It positiones the @menu over the @widget. + * + * Since: maemo 1.0 + **/ +void +gtk_widget_tap_and_hold_menu_position_top (GtkWidget *menu, + gint *x, + gint *y, + gboolean *push_in, + GtkWidget *widget) +{ + /* + * This function positiones the menu above widgets. + * This is a modified version of the position function + * gtk_combo_box_position_over. + */ + GtkWidget *topw; + GtkRequisition requisition; + gint screen_width = 0; + gint menu_xpos = 0; + gint menu_ypos = 0; + gint w_xpos = 0, w_ypos = 0; + gtk_widget_size_request (menu, &requisition); + + topw = gtk_widget_get_toplevel (widget); + gdk_window_get_origin (topw->window, &w_xpos, &w_ypos); + + menu_xpos += widget->allocation.x + w_xpos; + menu_ypos += widget->allocation.y + w_ypos - requisition.height; + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + menu_xpos = menu_xpos + widget->allocation.width - requisition.width; + + screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget)); + + if (menu_xpos < w_xpos) + menu_xpos = w_xpos; + else if ((menu_xpos + requisition.width) > screen_width) + menu_xpos -= ((menu_xpos + requisition.width) - screen_width); + if (menu_ypos < w_ypos) + menu_ypos = w_ypos; + + *x = menu_xpos; + *y = menu_ypos; + *push_in = TRUE; +} + +/** + * gtk_widget_tap_and_hold_setup: + * @widget : a @GtkWidget + * @menu : a @GtkWidget + * @func : a @GtkCallback + * @flags : a @GtkWidgetTapAndHoldFlags + * + * Setups the tap and hold functionality to the @widget. + * The @menu is shown when the functionality is activated. + * If the @menu is wanted to be positioned in a different way than the + * gtk+ default, the menuposition @func can be passed as a third parameter. + * Fourth parameter, @flags is deprecated and has no effect. + * + * Since: maemo 1.0 + */ +void +gtk_widget_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (menu == NULL || GTK_IS_MENU (menu)); + + g_signal_emit (widget, widget_signals[TAP_AND_HOLD_SETUP], 0, menu, func, + flags); +} + +static void +gtk_widget_real_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags) +{ + TahData *td; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (menu == NULL || GTK_IS_MENU (menu)); + + td = gtk_widget_get_tah_data (widget); + if (td->signals_connected) + return; + + if (menu != NULL) + { + g_object_ref (menu); + gtk_object_sink (GTK_OBJECT (menu)); + _gtk_menu_enable_context_menu_behavior (GTK_MENU (menu)); + + if (gtk_menu_get_attach_widget (GTK_MENU (menu)) == NULL) + gtk_menu_attach_to_widget (GTK_MENU (menu), widget, NULL); + } + + td->menu = menu; + td->func = (GtkMenuPositionFunc)func; + td->signals_connected = TRUE; + td->timer_counter = 0; + + g_signal_connect (widget, "button-press-event", + G_CALLBACK (gtk_widget_tap_and_hold_button_press), td); + g_signal_connect (widget, "button-release-event", + G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td); + g_signal_connect (widget, "leave-notify-event", + G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td); + g_signal_connect (widget, "drag-begin", + G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td); +} + +static void +gtk_widget_real_tap_and_hold (GtkWidget *widget) +{ + TahData *td = gtk_widget_peek_tah_data (widget); + if (td && GTK_IS_MENU (td->menu)) + gtk_menu_popup (GTK_MENU (td->menu), NULL, NULL, + (GtkMenuPositionFunc)td->func, + widget, 1, gdk_x11_get_server_time (widget->window)); +} + +static gboolean +gtk_widget_tap_and_hold_timeout (GtkWidget *widget) +{ + TahData *td = gtk_widget_peek_tah_data (widget); + gboolean result; + gint x = 0, y = 0; + + GDK_THREADS_ENTER (); + + if (!td || !GDK_IS_WINDOW (td->tah_on_window)) + { + tap_and_hold_remove_timer (widget); + + GDK_THREADS_LEAVE (); + return FALSE; + } + + /* A small timeout before starting the tap and hold */ + if (td->timer_counter == TAP_AND_HOLD_TIMER_COUNTER) + { + td->timer_counter--; + + GDK_THREADS_LEAVE (); + return TRUE; + } + + result = tap_and_hold_animation_timeout (widget); + + if (td->timer_counter) + td->timer_counter--; + else + td->timer_id = 0; + + gdk_display_get_pointer (gdk_drawable_get_display (td->tah_on_window), + NULL, &x, &y, NULL); + + /* Did we dragged too far from the start point */ + if (gtk_drag_check_threshold (widget, td->x, td->y, x, y)) + { + tap_and_hold_remove_timer (widget); + + GDK_THREADS_LEAVE (); + return FALSE; + } + + /* Was that the last cycle -> tah starts */ + if (!td->timer_id) + { + tap_and_hold_remove_timer (widget); + _gtk_widget_grab_notify (widget, FALSE); + g_signal_emit (widget, widget_signals[TAP_AND_HOLD], 0); + + GDK_THREADS_LEAVE (); + return FALSE; + } + + GDK_THREADS_LEAVE (); + return result; +} + +static gboolean +gtk_widget_real_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event) +{ + return FALSE; +} + +static gboolean +gtk_widget_tap_and_hold_query (GtkWidget *widget, + GdkEvent *event) +{ + gboolean return_value = FALSE; + + g_signal_emit (G_OBJECT (widget), widget_signals[TAP_AND_HOLD_QUERY], + 0, event, &return_value); + + return return_value; +} + +static gboolean +gtk_widget_tap_and_hold_button_press (GtkWidget *widget, + GdkEvent *event, + TahData *td) +{ + if (event->button.type == GDK_2BUTTON_PRESS) + return FALSE; + + if (!gtk_widget_tap_and_hold_query (widget, event) && !td->timer_id) + { + gdk_display_get_pointer (gtk_widget_get_display (widget), + NULL, &td->x, &td->y, NULL); + + td->timer_counter = TAP_AND_HOLD_TIMER_COUNTER; + td->tah_on_window = widget->window; + + tap_and_hold_init_animation (td); + td->timer_id = g_timeout_add (td->interval, + (GSourceFunc) + gtk_widget_tap_and_hold_timeout, widget); + } + return FALSE; +} + +static gboolean +gtk_widget_tap_and_hold_event_stop (GtkWidget *widget, + gpointer unused, + TahData *td) +{ + if (td->timer_id) + tap_and_hold_remove_timer (widget); + + return FALSE; +} + + void gtk_widget_insensitive_press ( GtkWidget *widget ) { } Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.h =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.h 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkwidget.h 2006-12-22 15:21:45 UTC (rev 8866) @@ -427,10 +427,14 @@ void (*_gtk_reserved6) (void); void (*_gtk_reserved7) (void); #endif - void (*tap_and_hold) (GtkWidget *widget); /* Tap and hold action */ - void (*tap_and_hold_setup) (GtkWidget *widget, GtkWidget *menu, - GtkCallback func, GtkWidgetTapAndHoldFlags flags); - gboolean (*tap_and_hold_query) (GtkWidget *widget, GdkEvent *event); + void (*tap_and_hold) (GtkWidget *widget); /* Tap and hold action */ + void (*tap_and_hold_setup) (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags); + gboolean (*tap_and_hold_query) (GtkWidget *widget, + GdkEvent *event); + void (*insensitive_press) (GtkWidget *widget); /* MAEMO END */ }; @@ -819,10 +823,15 @@ void gtk_widget_set_hildon_focus_handling( GtkWidget *widget, gboolean hildon_like ); gboolean gtk_widget_get_hildon_focus_handling( GtkWidget *widget ); -void gtk_widget_tap_and_hold_menu_position_top (GtkWidget *menu, - gint *x, gint *y, gboolean *push_in, GtkWidget *widget); -void gtk_widget_tap_and_hold_setup (GtkWidget *widget, GtkWidget *menu, - GtkCallback func, GtkWidgetTapAndHoldFlags flags); +void gtk_widget_tap_and_hold_menu_position_top (GtkWidget *menu, + gint *x, + gint *y, + gboolean *push_in, + GtkWidget *widget); +void gtk_widget_tap_and_hold_setup (GtkWidget *widget, + GtkWidget *menu, + GtkCallback func, + GtkWidgetTapAndHoldFlags flags); void gtk_widget_insensitive_press ( GtkWidget *widget ); /* MAEMO END */ Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/updateiconcache.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/updateiconcache.c 2006-12-22 14:53:29 UTC (rev 8865) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/updateiconcache.c 2006-12-22 15:21:45 UTC (rev 8866) @@ -51,6 +51,9 @@ #define HAS_SUFFIX_SVG (1 << 1) #define HAS_SUFFIX_PNG (1 << 2) #define HAS_ICON_FILE (1 << 3) +/* MAEMO START */ +#define HAS_SUFFIX_ANI (1 << 4) +/* MAEMO END */ #define CAN_CACHE_IMAGE_DATA(flags) (!index_only && (((flags) & HAS_SUFFIX_PNG) || ((flags) & HAS_SUFFIX_XPM))) @@ -510,6 +513,10 @@ flags |= HAS_SUFFIX_XPM; else if (g_str_has_suffix (name, ".icon")) flags |= HAS_ICON_FILE; + /* MAEMO START */ + else if (g_str_has_suffix (name, ".ani")) + flags |= HAS_SUFFIX_ANI; + /* MAEMO END */ if (flags == 0) continue;
- Previous message: [maemo-commits] r8865 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r8867 - projects/haf/trunk/pyrex/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]