From: Alberto Garcia Date: Tue, 3 Jun 2008 12:07:46 +0000 (+0000) Subject: * src/hildon-window.c * src/hildon-window.h (hildon_window_class_init) (hildon_window... X-Git-Tag: 2.1.66-1~722 X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=8ac4fc42c8f5fa0ad426dc3817db05d89f7489ea;p=hildon * 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 --- diff --git a/ChangeLog b/ChangeLog index 78d51b6..4daf2af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-06-03 Alberto Garcia + + * 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 * hildon-pannable-area.c: Added the overshoot property and removed diff --git a/examples/Makefile.am b/examples/Makefile.am index 2e426d1..791e910 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -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 index 0000000..d46579d --- /dev/null +++ b/examples/hildon-stackable-window-example.c @@ -0,0 +1,131 @@ +/* + * This file is a part of hildon examples + * + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * + * Author: Karl Lattimer + * + * 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 +#include +#include +#include +#include "hildon.h" + +#include +#include +#include + +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; +} diff --git a/src/hildon-stackable-window.c b/src/hildon-stackable-window.c index ef2bd3d..9b363b8 100644 --- a/src/hildon-stackable-window.c +++ b/src/hildon-stackable-window.c @@ -34,17 +34,148 @@ */ #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); +} diff --git a/src/hildon-stackable-window.h b/src/hildon-stackable-window.h index fd1155f..01c6bfd 100644 --- a/src/hildon-stackable-window.h +++ b/src/hildon-stackable-window.h @@ -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__ */ diff --git a/src/hildon-window.c b/src/hildon-window.c index 21dead3..be2aa05 100644 --- a/src/hildon-window.c +++ b/src/hildon-window.c @@ -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 diff --git a/src/hildon-window.h b/src/hildon-window.h index 36e58f9..40a758d 100644 --- a/src/hildon-window.h +++ b/src/hildon-window.h @@ -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