+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
hildon-pannable-area-example \
hildon-logical-color-example \
hildon-app-menu-example \
+ hildon-stackable-window-example \
hildon-dialog-example
# Hildon window
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)
--- /dev/null
+/*
+ * 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;
+}
*/
#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);
}
/**
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);
+}
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
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__ */
GdkEventExpose * event,
gboolean fullscreen);
+static void
+hildon_window_unset_program_real (HildonWindow *self);
+
enum
{
PROP_0,
/* 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;
* 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);
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
/* 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