From: Alberto Garcia Date: Mon, 28 Jul 2008 18:43:44 +0000 (+0000) Subject: * src/hildon-app-menu-private.h * src/hildon-app-menu.c (hildon_app_menu_button_press... X-Git-Tag: 2.1.66-1~657 X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=4f100d4ca49b638b5ebe7b22b1f94797be122ffd;p=hildon * src/hildon-app-menu-private.h * src/hildon-app-menu.c (hildon_app_menu_button_press) (hildon_app_menu_button_release, hildon_app_menu_init) (hildon_app_menu_class_init): Don't hide the menu on button release if the user didn't press outside first. * src/hildon-window.h * src/hildon-window.c (hildon_window_toggle_menu) (hildon_window_toggle_menu_real, hildon_window_class_init): Make hildon_window_toggle_menu a virtual function for the stackable window to override it. * src/hildon-stackable-window.h * src/hildon-stackable-window-private.h * src/hildon-stackable-window.c (hildon_stackable_window_realize) (hildon_stackable_window_finalize) (hildon_stackable_window_class_init) (hildon_stackable_window_init) (hildon_stackable_window_set_main_menu): New function to set the app menu of a HildonStackableWindow. * examples/hildon-app-menu-example.c: Remove the button to show the app menu, now it'll be shown when clicking on the title bar instead. --- diff --git a/ChangeLog b/ChangeLog index cad8bf9..32a5de3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2008-07-28 Alberto Garcia + + * src/hildon-app-menu-private.h + * src/hildon-app-menu.c (hildon_app_menu_button_press) + (hildon_app_menu_button_release, hildon_app_menu_init) + (hildon_app_menu_class_init): Don't hide the menu on button + release if the user didn't press outside first. + + * src/hildon-window.h + * src/hildon-window.c (hildon_window_toggle_menu) + (hildon_window_toggle_menu_real, hildon_window_class_init): Make + hildon_window_toggle_menu a virtual function for the stackable + window to override it. + + * src/hildon-stackable-window.h + * src/hildon-stackable-window-private.h + * src/hildon-stackable-window.c + (hildon_stackable_window_realize) + (hildon_stackable_window_finalize) + (hildon_stackable_window_class_init) + (hildon_stackable_window_init) + (hildon_stackable_window_set_main_menu): New function to set the + app menu of a HildonStackableWindow. + + * examples/hildon-app-menu-example.c: Remove the button to show + the app menu, now it'll be shown when clicking on the title bar + instead. + 2008-07-22 Claudio Saavedra * src/hildon-button.c: (hildon_button_set_arrangement): Do not diff --git a/examples/hildon-app-menu-example.c b/examples/hildon-app-menu-example.c index cf64e2a..32cb9f1 100644 --- a/examples/hildon-app-menu-example.c +++ b/examples/hildon-app-menu-example.c @@ -23,6 +23,7 @@ */ #include +#include #include static void @@ -30,7 +31,7 @@ menu_button_clicked (GtkButton *button, GtkLabel *label) { const char *buttontext = gtk_button_get_label (button); - char *text = g_strdup_printf("Last button clicked:\n%s", buttontext); + char *text = g_strdup_printf("Last option selected:\n%s", buttontext); gtk_label_set_text (label, text); g_free (text); } @@ -77,13 +78,6 @@ create_menu (GtkWidget *label) } static void -button_clicked (GtkButton *button, - HildonAppMenu *menu) -{ - gtk_widget_show (GTK_WIDGET (menu)); -} - -static void close_app (GtkWidget *widget, GdkEvent *event, GtkWidget *menu) @@ -97,7 +91,6 @@ main (int argc, char **argv) { GtkWidget *win; - GtkWidget *button; GtkWidget *label; GtkWidget *label2; GtkBox *vbox; @@ -110,22 +103,26 @@ main (int argc, "}\n" "class \"HildonAppMenu\" style \"default\"\n"); - button = gtk_button_new_with_label ("Press me"); - label = gtk_label_new ("This is an example of the\nHildonAppMenu widget"); - label2 = gtk_label_new ("No button has been clicked"); + label = gtk_label_new ("This is an example of the\nHildonAppMenu widget.\n\n" + "Click on the titlebar\nto pop up the menu."); + label2 = gtk_label_new ("No menu option has been selected yet."); + + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); + gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER); + vbox = GTK_BOX (gtk_vbox_new (FALSE, 10)); - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + win = hildon_stackable_window_new (); menu = create_menu (label2); + hildon_stackable_window_set_main_menu (HILDON_STACKABLE_WINDOW (win), menu); + gtk_box_pack_start (vbox, label, TRUE, TRUE, 0); - gtk_box_pack_start (vbox, button, TRUE, TRUE, 0); gtk_box_pack_start (vbox, label2, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (win), 20); gtk_container_add (GTK_CONTAINER (win), GTK_WIDGET (vbox)); - g_signal_connect (button, "clicked", G_CALLBACK(button_clicked), menu); g_signal_connect (win, "delete_event", G_CALLBACK(close_app), menu); gtk_widget_show_all (win); diff --git a/src/hildon-app-menu-private.h b/src/hildon-app-menu-private.h index 069766b..b1ecc5c 100644 --- a/src/hildon-app-menu-private.h +++ b/src/hildon-app-menu-private.h @@ -35,6 +35,7 @@ struct _HildonAppMenuPrivate GtkSizeGroup *sizegroup; GdkWindow *transfer_window; int nitems; + gboolean pressed_outside; }; diff --git a/src/hildon-app-menu.c b/src/hildon-app-menu.c index e9ee900..714292f 100644 --- a/src/hildon-app-menu.c +++ b/src/hildon-app-menu.c @@ -210,20 +210,46 @@ hildon_app_menu_unmap (GtkWidget *widget) } static gboolean -hildon_app_menu_button_release (GtkWidget *widget, +hildon_app_menu_button_press (GtkWidget *widget, GdkEventButton *event) { int x, y; - gboolean released_outside; + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(widget); gdk_window_get_position (widget->window, &x, &y); - /* Whether the button has been released outside the widget */ - released_outside = (event->x_root < x || event->x_root > x + widget->allocation.width || - event->y_root < y || event->y_root > y + widget->allocation.height); + /* Whether the button has been pressed outside the widget */ + priv->pressed_outside = (event->x_root < x || event->x_root > x + widget->allocation.width || + event->y_root < y || event->y_root > y + widget->allocation.height); + + if (GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_press_event) { + return GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_press_event (widget, event); + } else { + return FALSE; + } +} + +static gboolean +hildon_app_menu_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(widget); + + if (priv->pressed_outside) { + int x, y; + gboolean released_outside; + + gdk_window_get_position (widget->window, &x, &y); + + /* Whether the button has been released outside the widget */ + released_outside = (event->x_root < x || event->x_root > x + widget->allocation.width || + event->y_root < y || event->y_root > y + widget->allocation.height); + + if (released_outside) { + gtk_widget_hide (widget); + } - if (released_outside) { - gtk_widget_hide (widget); + priv->pressed_outside = FALSE; /* Always reset pressed_outside to FALSE */ } if (GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->button_release_event) { @@ -303,6 +329,7 @@ hildon_app_menu_init (HildonAppMenu *menu) priv->sizegroup = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_BOTH)); priv->nitems = 0; priv->transfer_window = NULL; + priv->pressed_outside = FALSE; /* Set spacing between table elements */ gtk_table_set_row_spacings (priv->table, vertical_spacing); @@ -353,6 +380,7 @@ hildon_app_menu_class_init (HildonAppMenuClass *klass) widget_class->map = hildon_app_menu_map; widget_class->unmap = hildon_app_menu_unmap; widget_class->realize = hildon_app_menu_realize; + widget_class->button_press_event = hildon_app_menu_button_press; widget_class->button_release_event = hildon_app_menu_button_release; g_type_class_add_private (klass, sizeof (HildonAppMenuPrivate)); diff --git a/src/hildon-stackable-window-private.h b/src/hildon-stackable-window-private.h index f7058f5..906a90b 100644 --- a/src/hildon-stackable-window-private.h +++ b/src/hildon-stackable-window-private.h @@ -32,6 +32,7 @@ typedef struct _HildonStackableWindowPrivate Hi struct _HildonStackableWindowPrivate { gboolean going_home; + HildonAppMenu *app_menu; }; #define HILDON_STACKABLE_WINDOW_GET_PRIVATE(obj) \ diff --git a/src/hildon-stackable-window.c b/src/hildon-stackable-window.c index 5fe4642..f457887 100644 --- a/src/hildon-stackable-window.c +++ b/src/hildon-stackable-window.c @@ -188,6 +188,56 @@ hildon_stackable_window_unset_program (HildonWindow *hwin) } } +void +hildon_stackable_window_set_main_menu (HildonStackableWindow *self, + HildonAppMenu *menu) +{ + HildonStackableWindowPrivate *priv; + + g_return_if_fail (HILDON_IS_STACKABLE_WINDOW (self)); + g_return_if_fail (!menu || HILDON_IS_APP_MENU (menu)); + priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self); + + /* Remove reference to old menu */ + if (priv->app_menu) + g_object_unref (priv->app_menu); + + /* Add new menu */ + priv->app_menu = menu; + if (priv->app_menu) + g_object_ref (priv->app_menu); +} + +static gboolean +hildon_stackable_window_toggle_menu (HildonWindow *self, + guint button, + guint32 time) +{ + HildonStackableWindowPrivate *priv; + + g_return_val_if_fail (HILDON_IS_STACKABLE_WINDOW (self), FALSE); + priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self); + g_assert (priv != NULL); + + if (priv->app_menu) + { + if (GTK_WIDGET_MAPPED (GTK_WIDGET (priv->app_menu))) + gtk_widget_hide (GTK_WIDGET (priv->app_menu)); + else + gtk_widget_show (GTK_WIDGET (priv->app_menu)); + + return TRUE; + } + else if (HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu) + { + return HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu (self, button, time); + } + else + { + return FALSE; + } +} + static void hildon_stackable_window_realize (GtkWidget *widget) { @@ -223,17 +273,31 @@ hildon_stackable_window_delete_event (GtkWidget *widget, } static void +hildon_stackable_window_finalize (GObject *object) +{ + HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (object); + + if (priv->app_menu) { + gtk_widget_destroy (GTK_WIDGET (priv->app_menu)); + } +} + +static void hildon_stackable_window_class_init (HildonStackableWindowClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); HildonWindowClass *window_class = HILDON_WINDOW_CLASS (klass); + obj_class->finalize = hildon_stackable_window_finalize; + widget_class->map = hildon_stackable_window_map; widget_class->unmap = hildon_stackable_window_unmap; widget_class->realize = hildon_stackable_window_realize; widget_class->delete_event = hildon_stackable_window_delete_event; window_class->unset_program = hildon_stackable_window_unset_program; + window_class->toggle_menu = hildon_stackable_window_toggle_menu; g_type_class_add_private (klass, sizeof (HildonStackableWindowPrivate)); } @@ -241,7 +305,10 @@ hildon_stackable_window_class_init (HildonStackableWindowClass *kla static void hildon_stackable_window_init (HildonStackableWindow *self) { - hildon_stackable_window_set_going_home (self, FALSE); + HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self); + + priv->going_home = FALSE; + priv->app_menu = NULL; } /** diff --git a/src/hildon-stackable-window.h b/src/hildon-stackable-window.h index ee180f8..06a7bae 100644 --- a/src/hildon-stackable-window.h +++ b/src/hildon-stackable-window.h @@ -26,6 +26,7 @@ #define __HILDON_STACKABLE_WINDOW_H__ #include "hildon-window.h" +#include "hildon-app-menu.h" G_BEGIN_DECLS @@ -80,6 +81,10 @@ hildon_stackable_window_get_type (void) G_GNUC_CONST; GtkWidget* hildon_stackable_window_new (void); +void +hildon_stackable_window_set_main_menu (HildonStackableWindow *self, + HildonAppMenu *menu); + G_END_DECLS #endif /* __HILDON_STACKABLE_WINDOW_H__ */ diff --git a/src/hildon-window.c b/src/hildon-window.c index 28a25cd..bb0b79e 100644 --- a/src/hildon-window.c +++ b/src/hildon-window.c @@ -206,6 +206,11 @@ hildon_window_toggle_menu (HildonWindow * self, guint32 time); static gboolean +hildon_window_toggle_menu_real (HildonWindow * self, + guint button, + guint32 time); + +static gboolean hildon_window_escape_timeout (gpointer data); static GdkFilterReturn @@ -280,6 +285,7 @@ hildon_window_class_init (HildonWindowClass * window_clas /* To this class */ window_class->unset_program = hildon_window_unset_program_real; + window_class->toggle_menu = hildon_window_toggle_menu_real; /* gtkobject stuff*/ GTK_OBJECT_CLASS (window_class)->destroy = hildon_window_destroy; @@ -1555,13 +1561,31 @@ detach_menu_func (GtkWidget *attach_widget, /* FIXME Why is this even needed here? */ } +static gboolean +hildon_window_toggle_menu (HildonWindow *self, + guint button, + guint32 time) +{ + g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE); + + if (HILDON_WINDOW_GET_CLASS (self)->toggle_menu != NULL) + { + return HILDON_WINDOW_GET_CLASS (self)->toggle_menu (self, button, time); + } + else + { + return FALSE; + } +} + + /* * Toggles the display of the HildonWindow menu. * Returns whether or not something was done (whether or not we had a menu * to toggle) */ static gboolean -hildon_window_toggle_menu (HildonWindow * self, +hildon_window_toggle_menu_real (HildonWindow * self, guint button, guint32 time) { diff --git a/src/hildon-window.h b/src/hildon-window.h index 40a758d..728e8ac 100644 --- a/src/hildon-window.h +++ b/src/hildon-window.h @@ -80,9 +80,9 @@ struct _HildonWindowClass /* opera hacks for clip board operation */ void (*clipboard_operation)(HildonWindow *hwindow, int operation); void (*unset_program)(HildonWindow *hwindow); + gboolean (*toggle_menu)(HildonWindow * self, guint button, guint32 time); /* Padding for future extension */ void (*_hildon_reserved1)(void); - void (*_hildon_reserved2)(void); }; GType G_GNUC_CONST