From: Alberto Garcia Date: Fri, 23 May 2008 18:05:59 +0000 (+0000) Subject: * doc/hildon-docs.sgml * doc/hildon.types * examples/Makefile.am * examples/hildon... X-Git-Tag: 2.1.66-1~730 X-Git-Url: http://git.maemo.org/git/?a=commitdiff_plain;h=7e5df20cd26c515d095a8fb0c5fd4b17d284bce6;p=hildon * doc/hildon-docs.sgml * doc/hildon.types * examples/Makefile.am * examples/hildon-app-menu-example.c * src/Makefile.am * src/hildon-app-menu-private.h * src/hildon-app-menu.c * src/hildon-app-menu.h * src/hildon.h New HildonAppMenu widget --- diff --git a/ChangeLog b/ChangeLog index 3041923..eb1dc9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-05-23 Alberto Garcia + + * doc/hildon-docs.sgml + * doc/hildon.types + * examples/Makefile.am + * examples/hildon-app-menu-example.c + * src/Makefile.am + * src/hildon-app-menu-private.h + * src/hildon-app-menu.c + * src/hildon-app-menu.h + * src/hildon.h + New HildonAppMenu widget + 2008-05-21 Alejandro G. Castro Rearranged the inheritance of the pannable area, now it inherits diff --git a/doc/hildon-docs.sgml b/doc/hildon-docs.sgml index 4faedb8..f413a72 100644 --- a/doc/hildon-docs.sgml +++ b/doc/hildon-docs.sgml @@ -40,6 +40,7 @@ + diff --git a/doc/hildon.types b/doc/hildon.types index 33e1200..256058f 100644 --- a/doc/hildon.types +++ b/doc/hildon.types @@ -36,6 +36,7 @@ #include #include #include +#include hildon_banner_get_type hildon_calendar_popup_get_type @@ -71,3 +72,4 @@ hildon_calendar_get_type hildon_dialog_get_type hildon_pannable_area_get_type hildon_stackable_window_get_type +hildon_app_menu_get_type diff --git a/examples/Makefile.am b/examples/Makefile.am index f72d758..2e426d1 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -41,6 +41,7 @@ noinst_PROGRAMS = hildon-window-example \ hildon-toolbar-seekbar-example \ hildon-pannable-area-example \ hildon-logical-color-example \ + hildon-app-menu-example \ hildon-dialog-example # Hildon window @@ -243,6 +244,11 @@ hildon_pannable_area_example_LDADD = $(HILDON_OBJ_LIBS) hildon_pannable_area_example_CFLAGS = $(HILDON_OBJ_CFLAGS) hildon_pannable_area_example_SOURCES = hildon-pannable-area-example.c +# Hildon app menu +hildon_app_menu_example_LDADD = $(HILDON_OBJ_LIBS) +hildon_app_menu_example_CFLAGS = $(HILDON_OBJ_CFLAGS) +hildon_app_menu_example_SOURCES = hildon-app-menu-example.c + # Hildon dialog hildon_dialog_example_LDADD = $(HILDON_OBJ_LIBS) hildon_dialog_example_CFLAGS = $(HILDON_OBJ_CFLAGS) diff --git a/examples/hildon-app-menu-example.c b/examples/hildon-app-menu-example.c new file mode 100644 index 0000000..4a4d349 --- /dev/null +++ b/examples/hildon-app-menu-example.c @@ -0,0 +1,143 @@ +/* + * This file is a part of hildon examples + * + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * + * Author: Karl Lattimer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +static void +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); + gtk_label_set_text (label, text); + g_free (text); +} + +static HildonAppMenu * +create_menu (GtkWidget *label) +{ + GtkWidget *button; + GtkWidget *group; + HildonAppMenu *menu = HILDON_APP_MENU (hildon_app_menu_new ()); + + /* Options */ + button = gtk_button_new_with_label ("Menu command one"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_append (menu, GTK_BUTTON (button)); + + button = gtk_button_new_with_label ("Menu command two"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_append (menu, GTK_BUTTON (button)); + + button = gtk_button_new_with_label ("Menu command three"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_append (menu, GTK_BUTTON (button)); + + button = gtk_button_new_with_label ("Menu command four"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_append (menu, GTK_BUTTON (button)); + + button = gtk_button_new_with_label ("Menu command five"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_append (menu, GTK_BUTTON (button)); + + /* Filters */ + button = gtk_toggle_button_new_with_label ("filter one"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_add_filter (menu, GTK_BUTTON (button), NULL); + + button = gtk_radio_button_new_with_label (NULL, "filter two"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + group = hildon_app_menu_add_filter (menu, GTK_BUTTON (button), NULL); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + + button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button), "filter three"); + g_signal_connect (button, "clicked", G_CALLBACK (menu_button_clicked), label); + hildon_app_menu_add_filter (menu, GTK_BUTTON (button), group); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + + gtk_container_set_border_width (GTK_CONTAINER (menu), 30); + + return menu; +} + +static void +button_clicked (GtkButton *button, + HildonAppMenu *menu) +{ + hildon_app_menu_popup (menu); +} + +static void +close_app (GtkWidget *widget, + GdkEvent *event, + GtkWidget *menu) +{ + gtk_widget_destroy (GTK_WIDGET (menu)); + gtk_main_quit (); +} + +int +main (int argc, + char **argv) +{ + GtkWidget *win; + GtkWidget *button; + GtkWidget *label; + GtkWidget *label2; + GtkBox *vbox; + HildonAppMenu *menu; + + gtk_init (&argc, &argv); + + gtk_rc_parse_string ("style \"default\" {\n" + "bg[NORMAL] = \"#505050\"" + "}\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"); + vbox = GTK_BOX (gtk_vbox_new (FALSE, 10)); + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + menu = create_menu (label2); + + 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); + + gtk_main (); + + return 0; +} diff --git a/src/Makefile.am b/src/Makefile.am index 2ba42e1..16f7159 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ libhildon_@API_VERSION_MAJOR@_la_SOURCES = hildon-private.c \ hildon-bread-crumb-trail.c \ hildon-bread-crumb.c \ hildon-bread-crumb-widget.c \ + hildon-app-menu.c \ hildon-dialog.c libhildon_@API_VERSION_MAJOR@_built_public_headers = \ @@ -110,6 +111,7 @@ libhildon_@API_VERSION_MAJOR@_public_headers = hildon-banner.h \ hildon-pannable-area.h \ hildon-bread-crumb-trail.h \ hildon-bread-crumb.h \ + hildon-app-menu.h \ hildon-dialog.h \ hildon-version.h @@ -144,6 +146,7 @@ noinst_HEADERS = hildon-banner-private.h \ hildon-window-private.h \ hildon-wizard-dialog-private.h \ hildon-calendar-private.h \ + hildon-app-menu-private.h \ hildon-bread-crumb-widget.h # Don't build the library until we have built the header that it needs: diff --git a/src/hildon-app-menu-private.h b/src/hildon-app-menu-private.h new file mode 100644 index 0000000..069766b --- /dev/null +++ b/src/hildon-app-menu-private.h @@ -0,0 +1,43 @@ +/* + * This file is a part of hildon + * + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * + * Contact: Karl Lattimer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser Public License as published by + * the Free Software Foundation; version 2 of the license. + * + * 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 Lesser Public License for more details. + * + */ + +#ifndef __HILDON_APP_MENU_PRIVATE_H__ +#define __HILDON_APP_MENU_PRIVATE_H__ + +G_BEGIN_DECLS + +#define HILDON_APP_MENU_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + HILDON_TYPE_APP_MENU, HildonAppMenuPrivate)); + +typedef struct _HildonAppMenuPrivate HildonAppMenuPrivate; + +struct _HildonAppMenuPrivate +{ + GtkBox *filters_hbox; + GtkBox *vbox; + GtkTable *table; + GtkSizeGroup *sizegroup; + GdkWindow *transfer_window; + int nitems; +}; + + +G_END_DECLS + +#endif /* __HILDON_APP_MENU_PRIVATE_H__ */ diff --git a/src/hildon-app-menu.c b/src/hildon-app-menu.c new file mode 100644 index 0000000..ab1577a --- /dev/null +++ b/src/hildon-app-menu.c @@ -0,0 +1,421 @@ +/* + * This file is a part of hildon + * + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * + * Contact: Karl Lattimer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser Public License as published by + * the Free Software Foundation; version 2 of the license. + * + * 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 Lesser Public License for more details. + * + */ + +/** + * SECTION:hildon-app-menu + * @short_description: Widget representing the application menu in the Hildon framework. + * + * The #HildonAppMenu is a GTK widget which represents an application + * menu in the Hildon framework. + * + * This menu opens from the top of the screen and contains a number of + * entries (#GtkButton) organized in two columns. Entries are added + * left to right and top to bottom. + * + * Besides that, the #HildonAppMenu can contain filter buttons + * (#GtkToggleButton or #GtkRadioButton), which can be grouped. + * + * + * Creating a HildonAppMenu + * + * HildonAppMenu *menu; + * GtkWidget *button; + * GtkWidget *filter; + * GtkWidget *filtergroup; + * + * menu = HILDON_APP_MENU (hildon_app_menu_new ()); + * + * // Create a button and add it to the menu + * button = gtk_button_new_with_label ("Menu command one"); + * g_signal_connect (button, "clicked", G_CALLBACK (button_one_clicked), userdata); + * hildon_app_menu_append (menu, GTK_BUTTON (button)); + * // Another button + * button = gtk_button_new_with_label ("Menu command two"); + * g_signal_connect (button, "clicked", G_CALLBACK (button_two_clicked), userdata); + * hildon_app_menu_append (menu, GTK_BUTTON (button)); + * + * // Create a filter and add it to the menu + * filter = gtk_toggle_button_new_with_label ("Filter one"); + * g_signal_connect (filter, "clicked", G_CALLBACK (filter_one_clicked), userdata); + * hildon_app_menu_add_filter (menu, GTK_BUTTON (filter), NULL); + * + * // Create another filter and add it to a new filter group + * filter = gtk_radio_button_new_with_label (NULL, "Filter two"); + * gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (filter), FALSE); + * g_signal_connect (filter, "clicked", G_CALLBACK (filter_two_clicked), userdata); + * filtergroup = hildon_app_menu_add_filter (menu, GTK_BUTTON (filter), NULL); + * // Add a new filter to the same filter group + * filter = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (filter), "Filter three"); + * gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (filter), FALSE); + * g_signal_connect (filter, "clicked", G_CALLBACK (filter_three_clicked), userdata); + * hildon_app_menu_add_filter (menu, GTK_BUTTON (filter), filtergroup); + * + * // Pop the menu up + * hildon_app_menu_popup (menu); + * + * + * + */ + +#include "hildon-app-menu.h" +#include "hildon-app-menu-private.h" + +static void +hildon_app_menu_popdown (HildonAppMenu *menu); + +static GdkWindow * +grab_transfer_window_get (HildonAppMenu *menu); + +G_DEFINE_TYPE (HildonAppMenu, hildon_app_menu, GTK_TYPE_WINDOW); + +/** + * hildon_app_menu_new: + * + * Creates a new HildonAppMenu. + * + * Return value: A @HildonAppMenu. + **/ +GtkWidget * +hildon_app_menu_new (void) +{ + GtkWidget *menu = g_object_new (HILDON_TYPE_APP_MENU, NULL); + return menu; +} + +/** + * hildon_app_menu_append + * @self : A @HildonAppMenu + * @item : A @GtkButton to add to the HildonAppMenu + * + * Adds the @item to the @HildonAppMenu + */ +void +hildon_app_menu_append (HildonAppMenu *self, + GtkButton *item) +{ + HildonAppMenuPrivate *priv; + int row, col; + + g_return_if_fail (HILDON_IS_APP_MENU (self)); + g_return_if_fail (GTK_IS_BUTTON (item)); + + priv = HILDON_APP_MENU_GET_PRIVATE(self); + + /* Calculate the row and column number */ + col = priv->nitems % 2; + row = (priv->nitems - col) / 2; + priv->nitems++; + + /* GtkTable already calls gtk_table_resize() if necessary */ + gtk_table_attach_defaults (priv->table, GTK_WIDGET (item), col, col + 1, row, row + 1); + + /* Close the menu when the button is pressed */ + g_signal_connect_swapped (item, "clicked", G_CALLBACK (hildon_app_menu_popdown), self); + + gtk_widget_show (GTK_WIDGET (item)); +} + +/** + * hildon_app_menu_add_filter + * @self : A @HildonAppMenu + * @filter : A @GtkButton to add to the HildonAppMenu + * @group : An existing filter group, or %NULL to create a new one + * + * Adds the @filter to the @HildonAppMenu, to the group specified by @group + * + * Return value: The filter group where the filter has been added + */ +GtkWidget * +hildon_app_menu_add_filter (HildonAppMenu *self, + GtkButton *filter, + GtkWidget *group) +{ + HildonAppMenuPrivate *priv; + + g_return_val_if_fail (HILDON_IS_APP_MENU (self), NULL); + g_return_val_if_fail (GTK_IS_BUTTON (filter), NULL); + g_return_val_if_fail (!group || GTK_IS_BOX (group), NULL); + + priv = HILDON_APP_MENU_GET_PRIVATE(self); + + /* Create a new group if needed */ + if (!group) { + group = gtk_hbox_new (TRUE, 0); + gtk_box_pack_start (priv->filters_hbox, group, TRUE, TRUE, 0); + gtk_widget_show (group); + } + + /* Pack the filter in the group and set its size */ + gtk_box_pack_start (GTK_BOX (group), GTK_WIDGET (filter), TRUE, TRUE, 0); + gtk_size_group_add_widget (priv->sizegroup, GTK_WIDGET (filter)); + + /* Close the menu when the button is pressed */ + g_signal_connect_swapped (filter, "clicked", G_CALLBACK (hildon_app_menu_popdown), self); + + gtk_widget_show (GTK_WIDGET (filter)); + + return group; +} + +/** + * hildon_app_menu_get_group_from_filter + * @self : A @HildonAppMenu + * @filter : A @GtkButton previously added to the menu + * + * Gets the filter group from a @filter previously added to a @HildonAppMenu + * + * Return value: The group where the @filter is in, or %NULL + */ +GtkWidget * +hildon_app_menu_get_group_from_filter (HildonAppMenu *self, + GtkButton *filter) +{ + HildonAppMenuPrivate *priv; + GList *grouplist; + GtkWidget *result = NULL; + + g_return_val_if_fail (HILDON_IS_APP_MENU (self), NULL); + g_return_val_if_fail (GTK_IS_BUTTON (filter), NULL); + + priv = HILDON_APP_MENU_GET_PRIVATE(self); + + /* Get the list of filter groups */ + grouplist = gtk_container_get_children (GTK_CONTAINER (priv->filters_hbox)); + + for (; grouplist != NULL && !result; grouplist = grouplist->next) { + + GtkBox *group = GTK_BOX (grouplist->data); + GList *items = gtk_container_get_children (GTK_CONTAINER (group)); + + /* Look for the filter inside each filter group */ + for (; items != NULL && !result; items = items->next) { + if (filter == items->data) { + result = GTK_WIDGET (group); + } + } + g_list_free (items); + + } + g_list_free (grouplist); + + if (!result) + g_critical("Filter not found in hildon app menu!"); + + return result; +} + +/** + * hildon_app_menu_popup + * @menu : A @HildonAppMenu + * + * Displays the @HildonAppMenu on top of the screen + */ +void +hildon_app_menu_popup (HildonAppMenu *menu) +{ + g_return_if_fail (HILDON_IS_APP_MENU (menu)); + int xpos; + GtkRequisition req; + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(menu); + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (menu)); + + /* Grab pointer and keyboard */ + if (priv->transfer_window == NULL) { + priv->transfer_window = grab_transfer_window_get (menu); + gdk_pointer_grab ( + priv->transfer_window, TRUE, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME); + gdk_keyboard_grab (priv->transfer_window, TRUE, GDK_CURRENT_TIME); + gtk_grab_add (GTK_WIDGET (menu)); + } + + /* Position the menu in the top center of the screen */ + gtk_widget_size_request (GTK_WIDGET (menu), &req); + xpos = (gdk_screen_get_width (screen) - req.width) / 2; + gtk_window_move (GTK_WINDOW (menu), xpos, 0); + + gtk_widget_show (GTK_WIDGET (menu)); +} + +static void +hildon_app_menu_popdown (HildonAppMenu *menu) +{ + g_return_if_fail (HILDON_IS_APP_MENU (menu)); + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(menu); + + if (priv->transfer_window != NULL) { + /* Remove the grab */ + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (menu)), + GDK_CURRENT_TIME); + gtk_grab_remove (GTK_WIDGET (menu)); + + /* Destroy the transfer window */ + gdk_window_destroy (priv->transfer_window); + priv->transfer_window = NULL; + } + + gtk_widget_hide (GTK_WIDGET (menu)); +} + +static gboolean +hildon_app_menu_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + int x, y; + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(widget); + gdk_window_get_position(widget->window, &x, &y); + if (event->window != priv->transfer_window || + event->x < x || event->x > x + widget->allocation.width || + event->y < y || event->y > y + widget->allocation.height) { + hildon_app_menu_popdown (HILDON_APP_MENU (widget)); + return TRUE; + } else 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; + } +} + +/* Grab transfer window (based on the one from GtkMenu) */ +static GdkWindow * +grab_transfer_window_get (HildonAppMenu *menu) +{ + GdkWindow *window; + GdkWindowAttr attributes; + gint attributes_mask; + + attributes.x = 0; + attributes.y = 0; + attributes.width = 10; + attributes.height = 10; + attributes.window_type = GDK_WINDOW_TEMP; + attributes.wclass = GDK_INPUT_ONLY; + attributes.override_redirect = TRUE; + attributes.event_mask = 0; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR; + + window = gdk_window_new (gtk_widget_get_root_window (GTK_WIDGET (menu)), + &attributes, attributes_mask); + gdk_window_set_user_data (window, menu); + + gdk_window_show (window); + + return window; +} + +static void +hildon_app_menu_realize (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->realize (widget); + gdk_window_set_override_redirect(widget->window, TRUE); +} + +static void +hildon_app_menu_init (HildonAppMenu *self) +{ + GtkWidget *alignment; + guint filter_group_spacing, horizontal_spacing, vertical_spacing; + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(self); + + gtk_widget_style_get (GTK_WIDGET (self), + "filter-group-spacing", &filter_group_spacing, + "horizontal-spacing", &horizontal_spacing, + "vertical-spacing", &vertical_spacing, + NULL); + + /* Initialize private variables */ + priv->filters_hbox = GTK_BOX (gtk_hbox_new (FALSE, filter_group_spacing)); + priv->vbox = GTK_BOX (gtk_vbox_new (FALSE, 10)); + priv->table = GTK_TABLE (gtk_table_new (1, 2, TRUE)); + priv->sizegroup = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_BOTH)); + priv->nitems = 0; + priv->transfer_window = NULL; + + /* Set spacing between table elements */ + gtk_table_set_row_spacings (priv->table, vertical_spacing); + gtk_table_set_col_spacings (priv->table, horizontal_spacing); + + /* Align the filters to the center */ + alignment = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (priv->filters_hbox)); + + /* Pack everything */ + gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (priv->vbox)); + gtk_box_pack_start (priv->vbox, alignment, TRUE, TRUE, 0); + gtk_box_pack_start (priv->vbox, GTK_WIDGET (priv->table), TRUE, TRUE, 0); + + gtk_widget_show_all (GTK_WIDGET (priv->vbox)); + + gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_POPUP_MENU); +} + +static void +hildon_app_menu_finalize (GObject *object) +{ + HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE(object); + + g_object_unref (priv->sizegroup); + if (priv->transfer_window) + gdk_window_destroy (priv->transfer_window); + + g_signal_handlers_destroy (object); + G_OBJECT_CLASS (hildon_app_menu_parent_class)->finalize (object); +} + +static void +hildon_app_menu_class_init (HildonAppMenuClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *)klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; + + gobject_class->finalize = hildon_app_menu_finalize; + widget_class->realize = hildon_app_menu_realize; + widget_class->button_press_event = hildon_app_menu_button_press; + + g_type_class_add_private (klass, sizeof (HildonAppMenuPrivate)); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_uint ( + "filter-group-spacing", + "Space between filter groups", + "Space in pixels between the filter groups", + 0, G_MAXUINT, 10, + G_PARAM_READABLE)); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_uint ( + "horizontal-spacing", + "Horizontal spacing on menu items", + "Horizontal spacing between each menu item (but not filters)", + 0, G_MAXUINT, 10, + G_PARAM_READABLE)); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_uint ( + "vertical-spacing", + "Vertical spacing on menu items", + "Vertical spacing between each menu item (but not filters)", + 0, G_MAXUINT, 10, + G_PARAM_READABLE)); +} diff --git a/src/hildon-app-menu.h b/src/hildon-app-menu.h new file mode 100644 index 0000000..164c85f --- /dev/null +++ b/src/hildon-app-menu.h @@ -0,0 +1,85 @@ +/* + * This file is a part of hildon + * + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * + * Contact: Karl Lattimer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser Public License as published by + * the Free Software Foundation; version 2 of the license. + * + * 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 Lesser Public License for more details. + * + */ + +#ifndef __HILDON_APP_MENU_H__ +#define __HILDON_APP_MENU_H__ + +#include + +G_BEGIN_DECLS + +#define HILDON_TYPE_APP_MENU \ + (hildon_app_menu_get_type()) + +#define HILDON_APP_MENU(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + HILDON_TYPE_APP_MENU, HildonAppMenu)) + +#define HILDON_APP_MENU_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + HILDON_TYPE_APP_MENU, HildonAppMenuClass)) + +#define HILDON_IS_APP_MENU(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_APP_MENU)) + +#define HILDON_IS_APP_MENU_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_APP_MENU)) + +#define HILDON_APP_MENU_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + HILDON_TYPE_APP_MENU, HildonAppMenuClass)) + +typedef struct _HildonAppMenu HildonAppMenu; + +typedef struct _HildonAppMenuClass HildonAppMenuClass; + +struct _HildonAppMenuClass +{ + GtkWindowClass parent_class; +}; + +struct _HildonAppMenu +{ + GtkWindow parent; +}; + +GType +hildon_app_menu_get_type (void) G_GNUC_CONST; + +GtkWidget * +hildon_app_menu_new (void); + +void +hildon_app_menu_append (HildonAppMenu *self, + GtkButton *item); + +GtkWidget * +hildon_app_menu_add_filter (HildonAppMenu *self, + GtkButton *filter, + GtkWidget *group); + +GtkWidget * +hildon_app_menu_get_group_from_filter (HildonAppMenu *menu, + GtkButton *filter); + +void +hildon_app_menu_popup (HildonAppMenu *menu); + +G_END_DECLS + +#endif /* __HILDON_APP_MENU_H__ */ diff --git a/src/hildon.h b/src/hildon.h index a9ae09c..cfa8001 100644 --- a/src/hildon.h +++ b/src/hildon.h @@ -64,6 +64,7 @@ #include "hildon-calendar.h" #include "hildon-bread-crumb-trail.h" #include "hildon-pannable-area.h" +#include "hildon-app-menu.h" #include "hildon-dialog.h" #endif