[maemo-commits] [maemo-commits] r11272 - in projects/haf/trunk/hildon-desktop: . libhildondesktop
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Wed Apr 25 00:31:25 EEST 2007
- Previous message: [maemo-commits] r11271 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r11273 - projects/haf/trunk/gtk+/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: moimart Date: 2007-04-25 00:31:24 +0300 (Wed, 25 Apr 2007) New Revision: 11272 Modified: projects/haf/trunk/hildon-desktop/ChangeLog projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.c projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.h projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h Log: * libhildondesktop/hildon-desktop-popup-menu.ch: - Each item has a pre-specified size except GtkSeparatorMenuItems. - Added method to scroll to pre-selected item. Based on size of each item. - Now inherits from a GtkVBox - Set proper size to internal GtkScrolledWindow. - Added scroll buttons. - Several bugfixes. * libhildondesktop/hildon-desktop-popup-window.ch: - Emit signal when popping up the menu. (to be used along "scrolling-to" HildonDesktopPopupMenu functionality). * ChangeLog updated. Modified: projects/haf/trunk/hildon-desktop/ChangeLog =================================================================== --- projects/haf/trunk/hildon-desktop/ChangeLog 2007-04-24 19:02:26 UTC (rev 11271) +++ projects/haf/trunk/hildon-desktop/ChangeLog 2007-04-24 21:31:24 UTC (rev 11272) @@ -1,3 +1,16 @@ +2007-04 25 Moises Martinez <moises.martinez at nokia.com> + + * libhildondesktop/hildon-desktop-popup-menu.ch: + - Each item has a pre-specified size except GtkSeparatorMenuItems. + - Added method to scroll to pre-selected item. Based on size of each item. + - Now inherits from a GtkVBox + - Set proper size to internal GtkScrolledWindow. + - Added scroll buttons. + - Several bugfixes. + * libhildondesktop/hildon-desktop-popup-window.ch: + - Emit signal when popping up the menu. (to be used along + "scrolling-to" HildonDesktopPopupMenu functionality). + 2007-04-24 Johan Bilien <johan.bilien at nokia.com> * configure.ac: 0.0.9 Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.c =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.c 2007-04-24 19:02:26 UTC (rev 11271) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.c 2007-04-24 21:31:24 UTC (rev 11272) @@ -25,35 +25,76 @@ #include "hildon-desktop-popup-menu.h" -#include <gtk/gtkvbox.h> +#include <gtk/gtkseparatormenuitem.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtkscrolledwindow.h> +#include <gtk/gtkimage.h> +#include <gtk/gtkbutton.h> #include <gtk/gtkwindow.h> +#include <gdk/gdk.h> + #define HILDON_DESKTOP_POPUP_MENU_GET_PRIVATE(object) \ (G_TYPE_INSTANCE_GET_PRIVATE ((object), HILDON_DESKTOP_TYPE_POPUP_MENU, HildonDesktopPopupMenuPrivate)) -G_DEFINE_TYPE (HildonDesktopPopupMenu, hildon_desktop_popup_menu, GTK_TYPE_SCROLLED_WINDOW); +G_DEFINE_TYPE (HildonDesktopPopupMenu, hildon_desktop_popup_menu, GTK_TYPE_VBOX); +enum +{ + PROP_POPUP_ITEM_HEIGHT=1 +}; + struct _HildonDesktopPopupMenuPrivate { - GtkWidget *box; + GtkWidget *scrolled_window; GtkWidget *box_items; - guint n_menu_items; + GtkWidget *box_buttons; + GtkWidget *scroll_down; + GtkWidget *scroll_up; + gboolean controls_on; + + guint n_items; + + guint item_height; + + gdouble upper_hack; + + GtkMenuItem *selected_item; }; static GObject *hildon_desktop_popup_menu_constructor (GType gtype, guint n_params, GObjectConstructParam *params); +static void hildon_desktop_popup_menu_finalize (GObject *object); + +static void hildon_desktop_popup_menu_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void hildon_desktop_popup_menu_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + static gboolean hildon_desktop_popup_menu_motion_notify (GtkWidget *widget, GdkEventMotion *event); static gboolean hildon_desktop_popup_menu_release_event (GtkWidget *widget, GdkEventButton *event); +static void hildon_desktop_popup_menu_scroll_cb (GtkWidget *widget, HildonDesktopPopupMenu *menu); + static void hildon_desktop_popup_menu_init (HildonDesktopPopupMenu *menu) { menu->priv = HILDON_DESKTOP_POPUP_MENU_GET_PRIVATE (menu); - menu->priv->n_menu_items = 0; + menu->priv->item_height = + menu->priv->n_items = 0; + + menu->priv->controls_on = FALSE; + + menu->priv->selected_item = NULL; } static void @@ -63,11 +104,27 @@ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (menu_class); object_class->constructor = hildon_desktop_popup_menu_constructor; + object_class->finalize = hildon_desktop_popup_menu_finalize; + + object_class->get_property = hildon_desktop_popup_menu_get_property; + object_class->set_property = hildon_desktop_popup_menu_set_property; + widget_class->motion_notify_event = hildon_desktop_popup_menu_motion_notify; widget_class->button_release_event = hildon_desktop_popup_menu_release_event; g_type_class_add_private (object_class, sizeof (HildonDesktopPopupMenuPrivate)); + + g_object_class_install_property (object_class, + PROP_POPUP_ITEM_HEIGHT, + g_param_spec_uint( + "height-item", + "height-item", + "Height of the menu items", + 1, + G_MAXINT, + 40, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static GObject * @@ -80,32 +137,115 @@ object = G_OBJECT_CLASS (hildon_desktop_popup_menu_parent_class)->constructor (gtype, n_params, - params); - + params); menu = HILDON_DESKTOP_POPUP_MENU (object); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (menu), + menu->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL); + + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (menu->priv->scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_widget_push_composite_child (); - menu->priv->box = gtk_vbox_new (FALSE,0); - - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (menu), menu->priv->box); - gtk_widget_show (menu->priv->box); - menu->priv->box_items = gtk_vbox_new (FALSE, 0); /* FIXME: add spacing decoration */ + + gtk_scrolled_window_add_with_viewport + (GTK_SCROLLED_WINDOW (menu->priv->scrolled_window), + menu->priv->box_items); - gtk_container_add (GTK_CONTAINER (menu->priv->box), - menu->priv->box_items); gtk_widget_show (menu->priv->box_items); + gtk_box_pack_start (GTK_BOX (menu), + menu->priv->scrolled_window, + FALSE, FALSE, 0); + gtk_widget_show (menu->priv->scrolled_window); + + menu->priv->box_buttons = gtk_hbox_new (TRUE,0); + + menu->priv->scroll_down = gtk_button_new_with_label ("down"); + menu->priv->scroll_up = gtk_button_new_with_label ("up"); + + + g_signal_connect (menu->priv->scroll_down, + "clicked", + G_CALLBACK (hildon_desktop_popup_menu_scroll_cb), + (gpointer)menu); + g_signal_connect (menu->priv->scroll_up, + "clicked", + G_CALLBACK (hildon_desktop_popup_menu_scroll_cb), + (gpointer)menu); + + gtk_box_pack_start (GTK_BOX (menu->priv->box_buttons), + menu->priv->scroll_down, + TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (menu->priv->box_buttons), + menu->priv->scroll_up, + TRUE, TRUE, 0); + + gtk_widget_show (menu->priv->scroll_down); + gtk_widget_show (menu->priv->scroll_up); + + g_object_ref (G_OBJECT (menu->priv->box_buttons)); + gtk_object_sink (GTK_OBJECT (menu->priv->box_buttons)); + gtk_widget_pop_composite_child (); return object; } +static void +hildon_desktop_popup_menu_finalize (GObject *object) +{ + g_object_unref (G_OBJECT (HILDON_DESKTOP_POPUP_MENU (object)->priv->box_buttons)); + + G_OBJECT_CLASS (hildon_desktop_popup_menu_parent_class)->finalize (object); +} + +static void +hildon_desktop_popup_menu_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + HildonDesktopPopupMenu *menu = HILDON_DESKTOP_POPUP_MENU (object); + + switch (prop_id) + { + case PROP_POPUP_ITEM_HEIGHT: + g_value_set_uint (value, menu->priv->item_height); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +hildon_desktop_popup_menu_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + HildonDesktopPopupMenu *menu = HILDON_DESKTOP_POPUP_MENU (object); + + switch (prop_id) + { + case PROP_POPUP_ITEM_HEIGHT: + menu->priv->item_height = g_value_get_uint (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + + static gboolean hildon_desktop_popup_menu_motion_notify (GtkWidget *widget, GdkEventMotion *event) @@ -118,6 +258,9 @@ gtk_container_get_children (GTK_CONTAINER (menu->priv->box_items)); for (l = menu_items; l != NULL; l = g_list_next (l)) + gtk_item_deselect (GTK_ITEM (l->data)); + + for (l = menu_items; l != NULL; l = g_list_next (l)) { gtk_widget_get_pointer (GTK_WIDGET (l->data), &x, &y); @@ -125,15 +268,7 @@ h = GTK_WIDGET (l->data)->allocation.height; if ((x >= 0) && (x <= w) && (y >= 0) && (y <= h)) - { - if (GTK_IS_ITEM (l->data)) - gtk_item_select (GTK_ITEM (l->data)); - } - else - { - if (GTK_IS_ITEM (l->data)) - gtk_item_deselect (GTK_ITEM (l->data)); - } + gtk_item_select (GTK_ITEM (l->data)); } g_list_free (menu_items); @@ -141,6 +276,26 @@ return TRUE; } +static void +hildon_desktop_popup_menu_scroll_cb (GtkWidget *widget, HildonDesktopPopupMenu *menu) +{ + gdouble position; + gint delta = menu->priv->item_height; + GtkAdjustment *adj = + gtk_scrolled_window_get_vadjustment + (GTK_SCROLLED_WINDOW (menu->priv->scrolled_window)); + + if (widget == menu->priv->scroll_up) + delta *= -1; + + position = gtk_adjustment_get_value (adj); + + if ((gint)(position + (gdouble)delta) <= menu->priv->upper_hack) + gtk_adjustment_set_value (adj, position + (gdouble)delta); + + g_debug ("min: %lf max: %lf current: %lf", adj->lower,adj->upper, adj->value); +} + static gboolean hildon_desktop_popup_menu_release_event (GtkWidget *widget, GdkEventButton *event) @@ -176,33 +331,77 @@ return TRUE; } -void -hildon_desktop_popup_menu_add_item (HildonDesktopPopupMenu *menu, GtkMenuItem *item) +static void +hildon_desktop_popup_menu_show_controls (HildonDesktopPopupMenu *menu) +{ + if (!menu->priv->controls_on) + { + gtk_box_pack_start (GTK_BOX (menu), + menu->priv->box_buttons, + FALSE, FALSE, 0); + gtk_widget_show (menu->priv->box_buttons); + + menu->priv->controls_on = TRUE; + } +} + +static void +hildon_desktop_popup_menu_hide_controls (HildonDesktopPopupMenu *menu) { + if (menu->priv->controls_on) + { + gtk_container_remove (GTK_CONTAINER (menu), + menu->priv->box_buttons); + menu->priv->controls_on = FALSE; + } +} + +static void +hildon_desktop_popup_menu_parent_size (HildonDesktopPopupMenu *menu) +{ GList *children = NULL, *l; - gint d_height = 0; + gint d_height = 0; + gboolean show_scroll_controls = FALSE; GtkRequisition req; - - g_assert (HILDON_DESKTOP_IS_POPUP_MENU (menu)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - gtk_box_pack_start (GTK_BOX (menu->priv->box_items), - GTK_WIDGET (item), - FALSE, FALSE, 0); - - gtk_widget_show (GTK_WIDGET (item)); + gint separators = 0; + gint screen_height = gdk_screen_height (); + GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (menu)); + children = gtk_container_get_children (GTK_CONTAINER (menu->priv->box_items)); + + for (l=children; l != NULL; l = g_list_next (l)) + { + if (GTK_IS_SEPARATOR_MENU_ITEM (l->data)) + separators++; + + gtk_widget_size_request (GTK_WIDGET (l->data), &req); + + d_height += req.height; + + if (d_height > screen_height) + { + d_height -= menu->priv->item_height; + show_scroll_controls = TRUE; + break; + } + } - for (l = children; l != NULL; l = g_list_next (l)) + if (show_scroll_controls) { - gtk_widget_size_request (GTK_WIDGET (l->data), &req); + hildon_desktop_popup_menu_show_controls (menu); + gtk_widget_set_size_request + (menu->priv->scrolled_window, req.width, d_height - menu->priv->item_height); - d_height += req.height; - } + menu->priv->upper_hack = d_height - menu->priv->item_height*separators; + } + else + { + hildon_desktop_popup_menu_hide_controls (menu); + gtk_widget_set_size_request + (menu->priv->scrolled_window, req.width, d_height); + } - GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (menu)); - if (GTK_IS_WINDOW (parent)) { gtk_widget_size_request (parent, &req); @@ -210,6 +409,44 @@ } g_list_free (children); +} + +void +hildon_desktop_popup_menu_add_item (HildonDesktopPopupMenu *menu, GtkMenuItem *item) +{ + GtkRequisition req; + + g_assert (HILDON_DESKTOP_IS_POPUP_MENU (menu)); + g_return_if_fail (GTK_IS_MENU_ITEM (item)); + + GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (menu)); + + if (GTK_IS_WINDOW (parent)) + { + gtk_widget_size_request (parent, &req); + + if (GTK_IS_SEPARATOR_MENU_ITEM (item)) + { + GtkRequisition req_sep; + + gtk_widget_size_request (GTK_WIDGET (item), &req_sep); + gtk_widget_set_size_request (GTK_WIDGET (item), req.width, req_sep.height); + } + else + gtk_widget_set_size_request (GTK_WIDGET (item), req.width, menu->priv->item_height); + + gtk_widget_set_size_request (menu->priv->box_buttons, req.width, menu->priv->item_height); + } + + gtk_box_pack_start (GTK_BOX (menu->priv->box_items), + GTK_WIDGET (item), + FALSE, FALSE, 0); + + gtk_widget_show (GTK_WIDGET (item)); + + menu->priv->n_items++; + + hildon_desktop_popup_menu_parent_size (menu); } void @@ -230,7 +467,9 @@ break; } } - + + menu->priv->n_items--; + g_list_free (children); } @@ -258,9 +497,8 @@ { if (l->data == item) { - if (GTK_IS_ITEM (item)) - gtk_item_select (GTK_ITEM (item)); - + gtk_item_select (GTK_ITEM (item)); + menu->priv->selected_item = item; break; } } @@ -274,7 +512,6 @@ GList *children = NULL, *l; g_assert (HILDON_DESKTOP_IS_POPUP_MENU (menu)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); children = gtk_container_get_children (GTK_CONTAINER (menu->priv->box_items)); @@ -282,12 +519,44 @@ { if (l->data == item) { - if (GTK_IS_MENU_ITEM (item)) - gtk_menu_item_activate (GTK_MENU_ITEM (item)); - + gtk_menu_item_activate (GTK_MENU_ITEM (item)); break; } } g_list_free (children); } + +void +hildon_desktop_popup_menu_scroll_to_selected (HildonDesktopPopupMenu *menu) +{ + GList *children = NULL, *l; + gint position = 0, screen_height = gdk_screen_height (); + + if (HILDON_DESKTOP_IS_POPUP_MENU (menu)) + return; + + if (menu->priv->selected_item) + { + children = gtk_container_get_children (GTK_CONTAINER (menu->priv->box_items)); + + for (l=children; l != NULL; l = g_list_next (l)) + { + position += menu->priv->item_height; + + if (l->data == menu->priv->selected_item) + break; + } + + if (position > screen_height) + { + do + { + hildon_desktop_popup_menu_scroll_cb (menu->priv->scroll_down, menu); + position -= menu->priv->item_height; + } + while (position > screen_height); + } + + } +} Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.h =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.h 2007-04-24 19:02:26 UTC (rev 11271) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-menu.h 2007-04-24 21:31:24 UTC (rev 11272) @@ -26,7 +26,7 @@ #ifndef __HILDON_DESKTOP_POPUP_MENU_H__ #define __HILDON_DESKTOP_POPUP_MENU_H__ -#include <gtk/gtkscrolledwindow.h> +#include <gtk/gtkvbox.h> #include <gtk/gtkmenuitem.h> G_BEGIN_DECLS @@ -44,14 +44,14 @@ struct _HildonDesktopPopupMenu { - GtkScrolledWindow parent; + GtkVBox parent; HildonDesktopPopupMenuPrivate *priv; }; struct _HildonDesktopPopupMenuClass { - GtkScrolledWindowClass parent_class; + GtkVBoxClass parent_class; /* */ }; @@ -74,6 +74,10 @@ void hildon_desktop_popup_menu_activate_item (HildonDesktopPopupMenu *menu, GtkMenuItem *item); + +void +hildon_desktop_popup_menu_scroll_to_selected (HildonDesktopPopupMenu *menu); + G_BEGIN_DECLS #endif/*__HILDON_DESKTOP_POPUP_MENU_H__*/ Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c 2007-04-24 19:02:26 UTC (rev 11271) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.c 2007-04-24 21:31:24 UTC (rev 11272) @@ -43,9 +43,12 @@ enum { + SIGNAL_POPUP_SHOW, POPUP_N_SIGNALS }; +static gint signals[POPUP_N_SIGNALS]; + static GObject *hildon_desktop_popup_window_constructor (GType gtype, guint n_params, GObjectConstructParam *params); @@ -143,6 +146,15 @@ g_type_class_add_private (object_class, sizeof (HildonDesktopPopupWindowPrivate)); + signals[SIGNAL_POPUP_SHOW] = + g_signal_new ("popup-window", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (HildonDesktopPopupWindowClass,popup_window), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + g_object_class_install_property (object_class, PROP_POPUP_N_PANES, g_param_spec_uint( @@ -935,11 +947,13 @@ hildon_desktop_popup_window_calculate_position (popup); - gtk_widget_show (GTK_WIDGET (popup)); + gtk_widget_show_all (GTK_WIDGET (popup)); popup_grab_on_window (GTK_WIDGET (popup)->window, activate_time, TRUE); /* Should always succeed */ gtk_grab_add (GTK_WIDGET (popup)); + + g_signal_emit_by_name (popup, "popup-window"); } void Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h =================================================================== --- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h 2007-04-24 19:02:26 UTC (rev 11271) +++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-popup-window.h 2007-04-24 21:31:24 UTC (rev 11272) @@ -64,6 +64,8 @@ { GtkWindowClass parent_class; /* */ + + void (*popup_window) (HildonDesktopPopupWindow *window); }; GType
- Previous message: [maemo-commits] r11271 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r11273 - projects/haf/trunk/gtk+/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]