From: Alberto Garcia Date: Wed, 4 Feb 2009 19:39:39 +0000 (+0000) Subject: 2009-02-04 Alberto Garcia X-Git-Tag: 2.1.66-1~176 X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=a65c18afe2970de158fc7e1d18c1445b15f1ec3d;p=hildon 2009-02-04 Alberto Garcia * doc/hildon-sections.txt * src/hildon-window-private.h * src/hildon-window.h * src/hildon-window.c (hildon_window_init) (hildon_window_realize, hildon_window_unrealize) (hildon_window_map, hildon_window_unmap, hildon_window_expose) (hildon_window_size_request, hildon_window_size_allocate) (hildon_window_forall, hildon_window_show_all) (hildon_window_destroy, +paint_edit_toolbar) (+hildon_window_set_edit_toolbar): New hildon_window_set_edit_toolbar() method, to add a HildonEditToolbar to a window without having to pack it manually. Reorganize hildon_window_size_allocate() * src/hildon-edit-toolbar.c: Update documentation. * examples/hildon-edit-toolbar-example.c (edit_window): Update example to use the new API. Fixes: NB#98039 (Wishlist: hildon_window_add_edit_toolbar()) --- diff --git a/ChangeLog b/ChangeLog index 6dd6a55..a25edce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,29 @@ 2009-02-04 Alberto Garcia + * doc/hildon-sections.txt + * src/hildon-window-private.h + * src/hildon-window.h + * src/hildon-window.c (hildon_window_init) + (hildon_window_realize, hildon_window_unrealize) + (hildon_window_map, hildon_window_unmap, hildon_window_expose) + (hildon_window_size_request, hildon_window_size_allocate) + (hildon_window_forall, hildon_window_show_all) + (hildon_window_destroy, +paint_edit_toolbar) + (+hildon_window_set_edit_toolbar): + New hildon_window_set_edit_toolbar() method, to add a + HildonEditToolbar to a window without having to pack it manually. + + Reorganize hildon_window_size_allocate() + + * src/hildon-edit-toolbar.c: Update documentation. + + * examples/hildon-edit-toolbar-example.c (edit_window): Update + example to use the new API. + + Fixes: NB#98039 (Wishlist: hildon_window_add_edit_toolbar()) + +2009-02-04 Alberto Garcia + * src/hildon-stackable-window.c (hildon_stackable_window_hide): Remove from stack before calling parent's hide. diff --git a/doc/hildon-sections.txt b/doc/hildon-sections.txt index 7145532..fd92b31 100644 --- a/doc/hildon-sections.txt +++ b/doc/hildon-sections.txt @@ -686,6 +686,7 @@ hildon_window_set_main_menu hildon_window_set_menu hildon_window_add_toolbar hildon_window_remove_toolbar +hildon_window_set_edit_toolbar hildon_window_get_is_topmost HILDON_WINDOW diff --git a/examples/hildon-edit-toolbar-example.c b/examples/hildon-edit-toolbar-example.c index d87f09b..15a88b2 100644 --- a/examples/hildon-edit-toolbar-example.c +++ b/examples/hildon-edit-toolbar-example.c @@ -141,23 +141,20 @@ edit_window (void) { GtkWidget *window; GtkWidget *iconview; - GtkWidget *vbox; GtkWidget *toolbar; GtkWidget *area; window = hildon_stackable_window_new (); gtk_container_set_border_width (GTK_CONTAINER (window), 6); - vbox = gtk_vbox_new (FALSE, 10); toolbar = hildon_edit_toolbar_new_with_text ("Choose items to delete", "Delete"); area = hildon_pannable_area_new (); iconview = create_icon_view (EDIT_MODE); - gtk_container_add (GTK_CONTAINER (area), iconview); - gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), area, TRUE, TRUE, 0); + hildon_window_set_edit_toolbar (HILDON_WINDOW (window), HILDON_EDIT_TOOLBAR (toolbar)); - gtk_container_add (GTK_CONTAINER (window), vbox); + gtk_container_add (GTK_CONTAINER (area), iconview); + gtk_container_add (GTK_CONTAINER (window), area); g_signal_connect (toolbar, "button-clicked", G_CALLBACK (delete_button_clicked), iconview); g_signal_connect_swapped (toolbar, "arrow-clicked", G_CALLBACK (gtk_widget_destroy), window); diff --git a/src/hildon-edit-toolbar.c b/src/hildon-edit-toolbar.c index d1afb15..dd9341c 100644 --- a/src/hildon-edit-toolbar.c +++ b/src/hildon-edit-toolbar.c @@ -30,22 +30,24 @@ * actually peform actions the developer must provide callbacks for * them. * + * To add a #HildonEditToolbar to a window use + * hildon_window_set_edit_toolbar(). + * * * HildonEditToolbar example * * GtkWidget *window; - * GtkWidget *vbox; * GtkWidget *toolbar; * // Declare more widgets here ... * * window = hildon_stackable_window_new (); - * vbox = gtk_vbox_new (FALSE, 10); * toolbar = hildon_edit_toolbar_new_with_text ("Choose items to delete", "Delete"); * // Create more widgets here ... * - * gtk_container_add (GTK_CONTAINER (window), vbox); - * gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0); - * // Pack more widgets here ... + * // Add toolbar to window + * hildon_window_set_edit_toolbar (HILDON_WINDOW (window), HILDON_EDIT_TOOLBAR (toolbar)); + * + * // Add other widgets ... * * g_signal_connect (toolbar, "button-clicked", G_CALLBACK (delete_button_clicked), someparameter); * g_signal_connect_swapped (toolbar, "arrow-clicked", G_CALLBACK (gtk_widget_destroy), window); diff --git a/src/hildon-window-private.h b/src/hildon-window-private.h index 63ee139..3d80c23 100644 --- a/src/hildon-window-private.h +++ b/src/hildon-window-private.h @@ -37,6 +37,7 @@ struct _HildonWindowPrivate { GtkWidget *menu; GtkWidget *vbox; + GtkWidget *edit_toolbar; GtkBorder *borders; GtkBorder *toolbar_borders; diff --git a/src/hildon-window.c b/src/hildon-window.c index 46090e8..2ebc4cd 100644 --- a/src/hildon-window.c +++ b/src/hildon-window.c @@ -36,10 +36,13 @@ * a custom button in the window frame. This menu can be set * by providing a GtkMenu to the hildon_window_set_main_menu() method. * - * Similarly a window in the Hildon framework can have several toolbars + * Similarly, a window in the Hildon framework can have several toolbars * attached. These can be added to the HildonWindow with * hildon_window_add_toolbar(). * + * A #HildonWindow can also have a #HildonEditToolbar. To add it to + * the window use hildon_window_set_edit_toolbar(). + * * * Creating a HildonWindow * @@ -223,6 +226,12 @@ paint_toolbar (GtkWidget *widget, GdkEventExpose * event, gboolean fullscreen); +static void +paint_edit_toolbar (GtkWidget *widget, + GtkWidget *toolbar, + GdkEventExpose *event, + gboolean fullscreen); + enum { PROP_0, @@ -319,6 +328,7 @@ hildon_window_init (HildonWindow *self) priv->vbox = gtk_vbox_new (TRUE, TOOLBAR_MIDDLE); gtk_widget_set_parent (priv->vbox, GTK_WIDGET(self)); priv->menu = NULL; + priv->edit_toolbar = NULL; priv->visible_toolbars = 0; priv->is_topmost = FALSE; priv->borders = NULL; @@ -383,6 +393,9 @@ hildon_window_realize (GtkWidget *widget) gtk_widget_realize (GTK_WIDGET (priv->vbox)); + if (priv->edit_toolbar != NULL) + gtk_widget_realize (priv->edit_toolbar); + /* catch the custom button signal from mb to display the menu */ gdk_window_add_filter (widget->window, hildon_window_event_filter, widget); @@ -428,6 +441,10 @@ hildon_window_unrealize (GtkWidget *widget) widget); gtk_widget_unrealize (GTK_WIDGET (priv->vbox)); + + if (priv->edit_toolbar != NULL) + gtk_widget_unrealize (priv->edit_toolbar); + GTK_WIDGET_CLASS(hildon_window_parent_class)->unrealize(widget); } @@ -442,6 +459,9 @@ hildon_window_map (GtkWidget *widget) if (GTK_WIDGET_VISIBLE (priv->vbox)) gtk_widget_map (priv->vbox); + + if (priv->edit_toolbar != NULL && GTK_WIDGET_VISIBLE (priv->edit_toolbar)) + gtk_widget_map (priv->edit_toolbar); } static void @@ -452,6 +472,9 @@ hildon_window_unmap (GtkWidget *widget) gtk_widget_unmap (priv->vbox); + if (priv->edit_toolbar != NULL) + gtk_widget_unmap (priv->edit_toolbar); + if (GTK_WIDGET_CLASS (hildon_window_parent_class)->unmap) GTK_WIDGET_CLASS (hildon_window_parent_class)->unmap (widget); } @@ -544,6 +567,12 @@ hildon_window_expose (GtkWidget *widget, paint_toolbar (widget, box, event, priv->fullscreen); + if (priv->edit_toolbar != NULL) + { + paint_edit_toolbar (widget, priv->edit_toolbar, + event, priv->fullscreen); + } + if (! priv->fullscreen) { /* Draw the left and right window border */ @@ -617,7 +646,7 @@ hildon_window_size_request (GtkWidget *widget, g_assert (priv); GtkWidget *child = GTK_BIN (widget)->child; - GtkRequisition req2; + GtkRequisition req2 = { 0 }; gint border_width = GTK_CONTAINER(widget)->border_width; if (! priv->borders) @@ -632,8 +661,15 @@ hildon_window_size_request (GtkWidget *widget, gtk_widget_size_request (priv->vbox, &req2); requisition->height += req2.height; - requisition->width = (requisition->width < req2.width) ? - req2.width : requisition->width; + requisition->width = MAX (requisition->width, req2.width); + + if (priv->edit_toolbar != NULL && GTK_WIDGET_VISIBLE (priv->edit_toolbar)) + { + GtkRequisition req; + gtk_widget_size_request (priv->edit_toolbar, &req); + requisition->height += req.height; + requisition->width = MAX (requisition->width, req.width); + } requisition->width += 2 * border_width; requisition->height += 2 * border_width; @@ -654,72 +690,90 @@ hildon_window_size_allocate (GtkWidget *widget, HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (widget); g_assert (priv); - GtkAllocation box_alloc; + GtkAllocation box_alloc = { 0 }; + GtkAllocation edittb_alloc = { 0 }; GtkAllocation alloc = *allocation; - GtkRequisition req; - gint border_width = GTK_CONTAINER(widget)->border_width; - GtkWidget *box = priv->vbox; - GtkBin *bin = GTK_BIN(widget); - GtkBorder *b = priv->borders; - GtkBorder *tb = priv->toolbar_borders; + GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget)); + GtkBorder *tb; if (!priv->borders) - { hildon_window_get_borders (HILDON_WINDOW (widget)); - b = priv->borders; - tb = priv->toolbar_borders; - } + + tb = priv->toolbar_borders; widget->allocation = *allocation; - gtk_widget_get_child_requisition (box, &req); + /* Calculate allocation of edit toolbar */ + if (priv->edit_toolbar != NULL && GTK_WIDGET_VISIBLE (priv->edit_toolbar)) + { + GtkRequisition req; + gtk_widget_get_child_requisition (priv->edit_toolbar, &req); + edittb_alloc.width = alloc.width - tb->left - tb->right; + edittb_alloc.height = MIN (req.height, alloc.height); + edittb_alloc.x = alloc.x + tb->left; + edittb_alloc.y = alloc.y + tb->top; + + if (edittb_alloc.height > 0) + { + alloc.y += tb->top + tb->bottom + edittb_alloc.height; + alloc.height -= tb->top + tb->bottom + edittb_alloc.height; + gtk_widget_size_allocate (priv->edit_toolbar, &edittb_alloc); + } + } - box_alloc.width = allocation->width - tb->left - tb->right; - box_alloc.height = ( (req.height < allocation->height) ? - req.height : allocation->height ); - box_alloc.x = allocation->x + tb->left; - box_alloc.y = allocation->y + allocation->height - box_alloc.height - tb->bottom; + /* Calculate allocation of normal toolbars */ + if (priv->vbox != NULL && GTK_WIDGET_VISIBLE (priv->vbox)) + { + GtkRequisition req; + gtk_widget_get_child_requisition (priv->vbox, &req); + box_alloc.width = alloc.width - tb->left - tb->right; + box_alloc.height = MIN (req.height, alloc.height); + box_alloc.x = alloc.x + tb->left; + box_alloc.y = alloc.y + alloc.height - box_alloc.height - tb->bottom; + + if (box_alloc.height > 0) + { + alloc.height -= tb->top + tb->bottom + box_alloc.height; + gtk_widget_size_allocate (priv->vbox, &box_alloc); + } + } - if (bin->child != NULL && GTK_IS_WIDGET (bin->child) - && GTK_WIDGET_VISIBLE (bin->child)) + /* Calculate allocation of the child widget */ + if (child != NULL && GTK_WIDGET_VISIBLE (child)) { + guint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); alloc.x += border_width; alloc.y += border_width; alloc.width -= (border_width * 2); - alloc.height -= (border_width * 2) + box_alloc.height; + alloc.height -= (border_width * 2); if (! priv->fullscreen) { + GtkBorder *b = priv->borders; alloc.x += b->left; alloc.width -= (b->left + b->right); - alloc.y += b->top; - alloc.height -= b->top; + /* Use the top border if there's no edit toolbar */ + if (edittb_alloc.height <= 0) + { + alloc.y += b->top; + alloc.height -= b->top; + } + /* Use the top border if there are no standard toolbars */ if (box_alloc.height <= 0) alloc.height -= b->bottom; - else - alloc.height -= (tb->top + tb->bottom); - } - else - { - if (!(box_alloc.height <= 0)) - alloc.height -= (tb->top + tb->bottom); } - gtk_widget_size_allocate (bin->child, &alloc); + gtk_widget_size_allocate (child, &alloc); } - gtk_widget_size_allocate (box, &box_alloc); - if (priv->previous_vbox_y != box_alloc.y) { /* The size of the VBox has changed, we need to redraw part * of the window borders */ - gint draw_from_y = priv->previous_vbox_y < box_alloc.y? - priv->previous_vbox_y - tb->top: - box_alloc.y - tb->top; + gint draw_from_y = MIN (priv->previous_vbox_y, box_alloc.y) - tb->top; gtk_widget_queue_draw_area (widget, 0, draw_from_y, widget->allocation.width, @@ -744,8 +798,12 @@ hildon_window_forall (GtkContainer *container, GTK_CONTAINER_CLASS (hildon_window_parent_class)->forall (container, include_internals, callback, callback_data); + if (include_internals && priv->vbox != NULL) (* callback)(GTK_WIDGET (priv->vbox), callback_data); + + if (include_internals && priv->edit_toolbar != NULL) + (* callback)(GTK_WIDGET (priv->edit_toolbar), callback_data); } static void @@ -757,7 +815,11 @@ hildon_window_show_all (GtkWidget *widget) g_assert (priv != NULL); GTK_WIDGET_CLASS (hildon_window_parent_class)->show_all (widget); + gtk_widget_show_all (priv->vbox); + + if (priv->edit_toolbar) + gtk_widget_show_all (priv->edit_toolbar); } static void @@ -788,6 +850,12 @@ hildon_window_destroy (GtkObject *obj) } + if (priv->edit_toolbar != NULL) + { + gtk_widget_unparent (priv->edit_toolbar); + priv->edit_toolbar = NULL; + } + menu_list = g_list_copy (gtk_menu_get_for_attach_widget (GTK_WIDGET (obj))); menu_node = menu_list; @@ -892,6 +960,24 @@ paint_toolbar (GtkWidget *widget, } } +static void +paint_edit_toolbar (GtkWidget *widget, + GtkWidget *toolbar, + GdkEventExpose *event, + gboolean fullscreen) +{ + if (!GTK_WIDGET_VISIBLE (toolbar)) + return; + + gtk_paint_box (widget->style, widget->window, + GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT, + &event->area, widget, "toolbar-primary", + toolbar->allocation.x, + toolbar->allocation.y, + toolbar->allocation.width, + toolbar->allocation.height); +} + /* * Checks the root window to know which is the topped window */ @@ -1650,6 +1736,43 @@ hildon_window_remove_toolbar (HildonWindow *self, } /** + * hildon_window_set_edit_toolbar: + * @self: A #HildonWindow + * @toolbar: A #HildonEditToolbar, or %NULL to remove the current one. + * + * Adds a #HildonEditToolbar to the window. Note that the toolbar is + * not automatically shown. You need to call gtk_widget_show() on it + * to make it visible. It's also possible to hide the toolbar (without + * removing it) by calling gtk_widget_hide(). + * + * A window can only have at most one edit toolbar at a time, so the + * previous toolbar (if any) is replaced after calling this function. + **/ +void +hildon_window_set_edit_toolbar (HildonWindow *self, + HildonEditToolbar *toolbar) +{ + HildonWindowPrivate *priv; + + g_return_if_fail (HILDON_IS_WINDOW (self)); + g_return_if_fail (toolbar == NULL || HILDON_IS_EDIT_TOOLBAR (toolbar)); + + priv = HILDON_WINDOW_GET_PRIVATE (self); + + if (priv->edit_toolbar != GTK_WIDGET (toolbar)) + { + GtkWidget *old_toolbar = priv->edit_toolbar; + priv->edit_toolbar = GTK_WIDGET (toolbar); + + if (priv->edit_toolbar) + gtk_widget_set_parent (priv->edit_toolbar, GTK_WIDGET (self)); + + if (old_toolbar) + gtk_widget_unparent (old_toolbar); + } +} + +/** * hildon_window_get_menu: * @self : #HildonWindow * diff --git a/src/hildon-window.h b/src/hildon-window.h index 252185a..fae9e80 100644 --- a/src/hildon-window.h +++ b/src/hildon-window.h @@ -26,6 +26,7 @@ #define __HILDON_WINDOW_H__ #include +#include "hildon-edit-toolbar.h" G_BEGIN_DECLS @@ -109,6 +110,10 @@ void hildon_window_remove_toolbar (HildonWindow *self, GtkToolbar *toolbar); +void +hildon_window_set_edit_toolbar (HildonWindow *self, + HildonEditToolbar *toolbar); + gboolean hildon_window_get_is_topmost (HildonWindow *self);