* src/hildon-window.c * src/hildon-window.h (hildon_window_class_init) (hildon_window...
authorAlberto Garcia <agarcia@igalia.com>
Tue, 3 Jun 2008 12:07:46 +0000 (12:07 +0000)
committerAlberto Garcia <agarcia@igalia.com>
Tue, 3 Jun 2008 12:07:46 +0000 (12:07 +0000)
* src/hildon-stackable-window.c
* src/hildon-stackable-window.h
Added hildon_stackable_window_go_home()

* examples/Makefile.am
* examples/hildon-stackable-window-example.c
HildonStackableWindow example

ChangeLog
examples/Makefile.am
examples/hildon-stackable-window-example.c [new file with mode: 0644]
src/hildon-stackable-window.c
src/hildon-stackable-window.h
src/hildon-window.c
src/hildon-window.h

index 78d51b6..4daf2af 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-06-03  Alberto Garcia  <agarcia@igalia.com>
+
+       * src/hildon-window.c
+       * src/hildon-window.h
+       (hildon_window_class_init)
+       (hildon_window_unset_program)
+       (hildon_window_unset_program_real):
+       Make unset_program a virtual function
+
+       * src/hildon-stackable-window.c
+       * src/hildon-stackable-window.h
+       Added hildon_stackable_window_go_home()
+
+       * examples/Makefile.am
+       * examples/hildon-stackable-window-example.c
+       HildonStackableWindow example
+
 2008-06-03 Alejandro G. Castro <alex@igalia.com>
 
        * hildon-pannable-area.c: Added the overshoot property and removed
index 2e426d1..791e910 100644 (file)
@@ -42,6 +42,7 @@ noinst_PROGRAMS                               = hildon-window-example                         \
                                          hildon-pannable-area-example                  \
                                          hildon-logical-color-example                  \
                                          hildon-app-menu-example                       \
+                                         hildon-stackable-window-example               \
                                          hildon-dialog-example
 
 # Hildon window
@@ -49,6 +50,11 @@ hildon_window_example_LDADD          = $(HILDON_OBJ_LIBS)
 hildon_window_example_CFLAGS           = $(HILDON_OBJ_CFLAGS)
 hildon_window_example_SOURCES          = hildon-window-example.c
 
+# Hildon stackable window
+hildon_stackable_window_example_LDADD  = $(HILDON_OBJ_LIBS)
+hildon_stackable_window_example_CFLAGS = $(HILDON_OBJ_CFLAGS)
+hildon_stackable_window_example_SOURCES = hildon-stackable-window-example.c
+
 # Hildon logical color
 hildon_logical_color_example_LDADD     = $(HILDON_OBJ_LIBS)
 hildon_logical_color_example_CFLAGS    = $(HILDON_OBJ_CFLAGS)
diff --git a/examples/hildon-stackable-window-example.c b/examples/hildon-stackable-window-example.c
new file mode 100644 (file)
index 0000000..d46579d
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * This file is a part of hildon examples
+ *
+ * Copyright (C) 2008 Nokia Corporation, all rights reserved.
+ *
+ * Author: Karl Lattimer <karl.lattimer@nokia.com>
+ *
+ * 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                                        <stdio.h>
+#include                                        <stdlib.h>
+#include                                        <glib.h>
+#include                                        <gtk/gtk.h>
+#include                                        "hildon.h"
+
+#include                                        <X11/X.h>
+#include                                        <X11/Xlib.h>
+#include                                        <X11/Xatom.h>
+
+static void
+add_window                                      (GtkWidget* w);
+
+static void
+detach_window                                   (GtkWidget* w)
+{
+    HildonProgram *program = hildon_program_get_instance ();
+    hildon_program_remove_window (program, HILDON_WINDOW (w));
+}
+
+static GtkWidget*
+new_window                                      (gboolean ismain)
+{
+    GtkWidget *window, *hbbox, *add;
+    static int count = 0;
+    gchar* title;
+
+    window = hildon_stackable_window_new ();
+
+    if (count == 0)
+        title = g_strdup ("main window");
+    else
+        title = g_strdup_printf ("win%d", count);
+
+    gtk_window_set_title (GTK_WINDOW (window), title);
+    g_free (title);
+
+    count++;
+
+    gtk_container_set_border_width (GTK_CONTAINER (window), 6);
+
+    hbbox = gtk_hbutton_box_new ();
+    gtk_container_add (GTK_CONTAINER (window), hbbox);
+
+    add = gtk_button_new_with_label ("Add a window");
+    gtk_box_pack_start (GTK_BOX (hbbox), add, FALSE, FALSE, 0);
+
+    g_signal_connect (G_OBJECT (add), "clicked", G_CALLBACK (add_window), NULL);
+
+    if (!ismain)
+    {
+        GtkWidget *detach, *back;
+        detach = GTK_WIDGET (gtk_button_new_with_label ("Detach"));
+        gtk_box_pack_end (GTK_BOX (hbbox), detach, FALSE, FALSE, 0);
+
+        g_signal_connect_swapped (G_OBJECT (detach), "clicked",
+                                  G_CALLBACK (detach_window),
+                                  HILDON_STACKABLE_WINDOW (window));
+
+        back = GTK_WIDGET (gtk_button_new_with_label ("Back to root"));
+        gtk_box_pack_end (GTK_BOX (hbbox), back, FALSE, FALSE, 0);
+
+        g_signal_connect_swapped (G_OBJECT (back), "clicked",
+                                  G_CALLBACK (hildon_stackable_window_go_home),
+                                  HILDON_STACKABLE_WINDOW (window));
+    }
+
+    return window;
+}
+
+static void
+add_window                                      (GtkWidget *w)
+{
+    GtkWidget *window = new_window (FALSE);
+    HildonProgram *program = hildon_program_get_instance ();
+
+    hildon_program_add_window (program, HILDON_WINDOW (window));
+
+    gtk_widget_show_all (window);
+
+    return;
+}
+
+int
+main                                            (int argc,
+                                                 char **args)
+{
+    HildonProgram *program;
+    GtkWidget *window;
+
+    gtk_init (&argc, &args);
+
+    g_set_application_name ("stack");
+
+    program = hildon_program_get_instance ();
+    window = new_window (TRUE);
+    hildon_program_add_window (program, HILDON_WINDOW (window));
+
+    g_signal_connect (G_OBJECT (window), "delete_event",
+                      G_CALLBACK (gtk_main_quit), NULL);
+
+    gtk_widget_show_all (GTK_WIDGET (window));
+
+    gtk_main ();
+
+    return 0;
+}
index ef2bd3d..9b363b8 100644 (file)
  */
 
 #include                                        "hildon-stackable-window.h"
+#include                                        "hildon-program.h"
+#include                                        "hildon-window-private.h"
+#include                                        "hildon-program-private.h"
+
+typedef struct                                  _HildonStackableWindowPrivate HildonStackableWindowPrivate;
+
+struct                                          _HildonStackableWindowPrivate
+{
+    gboolean going_home;
+};
+
+#define                                         HILDON_STACKABLE_WINDOW_GET_PRIVATE(obj) \
+                                                (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+                                                HILDON_TYPE_STACKABLE_WINDOW, HildonStackableWindowPrivate))
 
 G_DEFINE_TYPE (HildonStackableWindow, hildon_stackable_window, HILDON_TYPE_WINDOW);
 
 static void
+hildon_stackable_window_set_going_home          (HildonStackableWindow *self,
+                                                 gboolean going_home)
+{
+    HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
+    priv->going_home = going_home;
+}
+
+static gboolean
+hildon_stackable_window_get_going_home          (HildonStackableWindow *self)
+{
+    HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
+    return priv->going_home;
+}
+
+static GSList*
+get_window_list                                 (GtkWidget *widget)
+{
+    HildonWindowPrivate *wpriv;
+    HildonProgramPrivate *ppriv;
+    GSList *retval = NULL;
+    g_return_val_if_fail (widget != NULL, NULL);
+
+    wpriv = HILDON_WINDOW_GET_PRIVATE (widget);
+    g_assert (wpriv != NULL);
+
+    if (wpriv->program)
+    {
+        ppriv = HILDON_PROGRAM_GET_PRIVATE (wpriv->program);
+        g_assert (ppriv != NULL);
+        retval = ppriv->windows;
+    }
+
+    return retval;
+}
+
+static GtkWidget*
+get_last_window                                 (GtkWidget *widget)
+{
+    GtkWidget *retval;
+    GSList *windows = get_window_list (widget);
+
+    g_return_val_if_fail (windows != NULL, NULL);
+
+    retval = GTK_WIDGET (g_slist_last (windows)->data);
+
+    if (retval == widget)
+    {
+        gint l = g_slist_length (windows);
+        retval = GTK_WIDGET (g_slist_nth_data (windows, l - 2));
+    }
+    else
+    {
+        retval = NULL;
+    }
+
+    return retval;
+}
+
+static void
+hildon_stackable_window_map                     (GtkWidget *widget)
+{
+    GtkWidget *lastwin;
+
+    if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->map)
+        GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->map (widget);
+
+    lastwin = get_last_window (widget);
+
+    if (HILDON_IS_STACKABLE_WINDOW (lastwin) && GTK_WIDGET_VISIBLE (lastwin))
+        gtk_widget_hide (lastwin);
+}
+
+static void
+hildon_stackable_window_unmap                   (GtkWidget *widget)
+{
+    GtkWidget *lastwin;
+
+    if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->unmap)
+        GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->unmap (widget);
+
+    lastwin = get_last_window (widget);
+
+    if (HILDON_IS_STACKABLE_WINDOW (lastwin) && !GTK_WIDGET_VISIBLE (lastwin) &&
+        !hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (widget)))
+    {
+        gtk_widget_show (lastwin);
+    }
+}
+
+static void
+hildon_stackable_window_unset_program           (HildonWindow *hwin)
+{
+    GSList *windows = get_window_list (GTK_WIDGET (hwin));
+    gint l = g_slist_length (windows);
+    GtkWidget *nextwin = GTK_WIDGET (g_slist_nth_data (windows, l - 2));
+
+    if (HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->unset_program)
+        HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->unset_program (hwin);
+
+    if (HILDON_IS_STACKABLE_WINDOW (nextwin) && !GTK_WIDGET_VISIBLE (nextwin) &&
+        !hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (nextwin)))
+    {
+        gtk_widget_show (nextwin);
+    }
+}
+
+static void
 hildon_stackable_window_class_init              (HildonStackableWindowClass *klass)
 {
+    GtkWidgetClass    *widget_class = GTK_WIDGET_CLASS (klass);
+    HildonWindowClass *window_class = HILDON_WINDOW_CLASS (klass);
+
+    widget_class->map               = hildon_stackable_window_map;
+    widget_class->unmap             = hildon_stackable_window_unmap;
+
+    window_class->unset_program     = hildon_stackable_window_unset_program;
+
+    g_type_class_add_private (klass, sizeof (HildonWindowPrivate));
 }
 
 static void
 hildon_stackable_window_init                    (HildonStackableWindow *self)
 {
+    hildon_stackable_window_set_going_home (self, FALSE);
 }
 
 /**
@@ -61,3 +192,38 @@ hildon_stackable_window_new                     (void)
 
     return GTK_WIDGET (newwindow);
 }
+
+/**
+ * hildon_stackable_window_go_home:
+ * @self: A #HildonStackableWindow
+ *
+ * Will pop out all the stackable windows in the HildonProgram until the
+ * first one, which can be considered as the "home" window
+ */
+void
+hildon_stackable_window_go_home                 (HildonStackableWindow *self)
+{
+    g_return_if_fail (HILDON_IS_STACKABLE_WINDOW (self));
+
+    GSList *windows       = get_window_list (GTK_WIDGET (self));
+    GSList *tmp           = NULL;
+    HildonWindow *rootwin = HILDON_WINDOW (g_slist_nth_data (windows, 0));
+
+    g_return_if_fail (rootwin != NULL);
+
+    tmp = g_slist_nth (windows, 1);
+    while (tmp != NULL)
+    {
+        if (HILDON_IS_STACKABLE_WINDOW (tmp->data))
+        {
+            HildonStackableWindow *win = HILDON_STACKABLE_WINDOW (tmp->data);
+            hildon_stackable_window_set_going_home (win, TRUE);
+            gtk_widget_destroy (GTK_WIDGET (win));
+        }
+
+        tmp = g_slist_nth (windows, 1);
+    }
+
+    if (!GTK_WIDGET_VISIBLE (rootwin))
+        gtk_widget_show (rootwin);
+}
index fd1155f..01c6bfd 100644 (file)
@@ -61,6 +61,12 @@ typedef struct                                  _HildonStackableWindowClass Hild
 struct                                          _HildonStackableWindowClass
 {
     HildonWindowClass parent_class;
+
+    /* Padding for future extension */
+    void (*_hildon_reserved1)(void);
+    void (*_hildon_reserved2)(void);
+    void (*_hildon_reserved3)(void);
+    void (*_hildon_reserved4)(void);
 };
 
 struct                                          _HildonStackableWindow
@@ -68,11 +74,15 @@ struct                                          _HildonStackableWindow
     HildonWindow parent;
 };
 
-GType hildon_stackable_window_get_type (void) G_GNUC_CONST;
+GType
+hildon_stackable_window_get_type                (void) G_GNUC_CONST;
 
 GtkWidget*
 hildon_stackable_window_new                     (void);
 
+void
+hildon_stackable_window_go_home                 (HildonStackableWindow* self);
+
 G_END_DECLS
 
 #endif                                 /* __HILDON_STACKABLE_WINDOW_H__ */
index 21dead3..be2aa05 100644 (file)
@@ -231,6 +231,9 @@ paint_toolbar                                   (GtkWidget *widget,
                                                  GdkEventExpose * event, 
                                                  gboolean fullscreen);
 
+static void
+hildon_window_unset_program_real                (HildonWindow *self);
+
 enum
 {
     PROP_0,
@@ -275,6 +278,9 @@ hildon_window_class_init                        (HildonWindowClass * window_clas
     /* To the container */
     container_class->forall             = hildon_window_forall;
 
+    /* To this class */
+    window_class->unset_program         = hildon_window_unset_program_real;
+
     /* gtkobject stuff*/
     GTK_OBJECT_CLASS (window_class)->destroy = hildon_window_destroy; 
 
@@ -1350,8 +1356,8 @@ hildon_window_set_program                       (HildonWindow *self,
  * Unsets the program to which the window belongs. This should only be called
  * by hildon_program_add_window
  */
-void G_GNUC_INTERNAL
-hildon_window_unset_program                     (HildonWindow *self)
+static void
+hildon_window_unset_program_real                (HildonWindow *self)
 {
     HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
 
@@ -1375,6 +1381,15 @@ hildon_window_unset_program                     (HildonWindow *self)
     priv->program = NULL;
 }
 
+void G_GNUC_INTERNAL
+hildon_window_unset_program                     (HildonWindow *self)
+{
+    g_return_if_fail (HILDON_IS_WINDOW (self));
+
+    if (HILDON_WINDOW_GET_CLASS (self)->unset_program != NULL)
+        HILDON_WINDOW_GET_CLASS (self)->unset_program (self);
+}
+
 /*
  * Sets whether or not the program to which this window belongs is
  * killable. This is used by the HildonProgram to signify to the
index 36e58f9..40a758d 100644 (file)
@@ -79,10 +79,10 @@ struct                                          _HildonWindowClass
 
     /* opera hacks for clip board operation */
     void (*clipboard_operation)(HildonWindow *hwindow, int operation);
+    void (*unset_program)(HildonWindow *hwindow);
     /* Padding for future extension */
     void (*_hildon_reserved1)(void);
     void (*_hildon_reserved2)(void);
-    void (*_hildon_reserved3)(void);
 };
 
 GType G_GNUC_CONST