2009-02-04 Alberto Garcia <agarcia@igalia.com>
authorAlberto Garcia <agarcia@igalia.com>
Wed, 4 Feb 2009 19:39:39 +0000 (19:39 +0000)
committerAlberto Garcia <agarcia@igalia.com>
Wed, 4 Feb 2009 19:39:39 +0000 (19:39 +0000)
* 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())

ChangeLog
doc/hildon-sections.txt
examples/hildon-edit-toolbar-example.c
src/hildon-edit-toolbar.c
src/hildon-window-private.h
src/hildon-window.c
src/hildon-window.h

index 6dd6a55..a25edce 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2009-02-04  Alberto Garcia  <agarcia@igalia.com>
 
+       * 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  <agarcia@igalia.com>
+
        * src/hildon-stackable-window.c (hildon_stackable_window_hide):
        Remove from stack before calling parent's hide.
 
index 7145532..fd92b31 100644 (file)
@@ -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
 <SUBSECTION Standard>
 HILDON_WINDOW
index d87f09b..15a88b2 100644 (file)
@@ -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);
index d1afb15..dd9341c 100644 (file)
  * actually peform actions the developer must provide callbacks for
  * them.
  *
+ * To add a #HildonEditToolbar to a window use
+ * hildon_window_set_edit_toolbar().
+ *
  * <example>
  * <title>HildonEditToolbar example</title>
  * <programlisting>
  * 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);
index 63ee139..3d80c23 100644 (file)
@@ -37,6 +37,7 @@ struct                                          _HildonWindowPrivate
 {
     GtkWidget *menu;
     GtkWidget *vbox;
+    GtkWidget *edit_toolbar;
 
     GtkBorder *borders;
     GtkBorder *toolbar_borders;
index 46090e8..2ebc4cd 100644 (file)
  * 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().
+ *
  * <example>
  * <title>Creating a HildonWindow</title>
  * <programlisting>
@@ -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
  * 
index 252185a..fae9e80 100644 (file)
@@ -26,6 +26,7 @@
 #define                                         __HILDON_WINDOW_H__
 
 #include                                        <gtk/gtk.h>
+#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);