* #HildonWindow. Applications that use stackable windows are organized
* in a hierarchical way so users can go from any window back to the
* application's root window.
+ *
+ * To add a window to the stack, use hildon_program_add_window(). Once
+ * you show the new window, the previous one will be automatically
+ * hidden. When the new window is destroyed, the previous one will
+ * appear again.
+ *
+ * <example>
+ * <programlisting>
+ * void
+ * show_first_window (void)
+ * {
+ * HildonProgram *program;
+ * GtkWidget *win1;
+ * <!-- -->
+ * program = hildon_program_get_instance ();
+ * win1 = hildon_stackable_window_new ();
+ * <!-- -->
+ * // ... configure first window
+ * <!-- -->
+ * hildon_program_add_window (program, HILDON_WINDOW (win1));
+ * gtk_widget_show (win1);
+ * }
+ * <!-- -->
+ * void
+ * show_second_window (void)
+ * {
+ * HildonProgram *program;
+ * GtkWidget *win2;
+ * <!-- -->
+ * program = hildon_program_get_instance ();
+ * win2 = hildon_stackable_window_new ();
+ * <!-- -->
+ * // ... configure second window
+ * <!-- -->
+ * hildon_program_add_window (program, HILDON_WINDOW (win2));
+ * gtk_widget_show (win2);
+ * }
+ * </programlisting>
+ * </example>
*/
#include <X11/X.h>
#include <X11/Xatom.h>
#include "hildon-stackable-window.h"
+#include "hildon-stackable-window-private.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
+void G_GNUC_INTERNAL
hildon_stackable_window_set_going_home (HildonStackableWindow *self,
gboolean going_home)
{
priv->going_home = going_home;
}
-static gboolean
+gboolean G_GNUC_INTERNAL
hildon_stackable_window_get_going_home (HildonStackableWindow *self)
{
HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
}
static GtkWidget*
-get_last_window (GtkWidget *widget)
+get_previous_window_if_last (GtkWidget *widget)
{
GtkWidget *retval = NULL;
- GSList *windows = get_window_list (widget);
- GSList *last = NULL;
+ GSList *iter = get_window_list (widget);
+ GSList *previous = NULL;
- g_return_val_if_fail (windows != NULL, NULL);
+ /* Return NULL if the window hasn't been added to the HildonProgram */
+ if (iter == NULL)
+ {
+ return NULL;
+ }
/* Go to the end of the window list */
- while (windows->next != NULL)
+ while (iter->next != NULL)
{
- last = windows;
- windows = windows->next;
+ previous = iter;
+ iter = iter->next;
}
- if ((windows->data == widget) && (last != NULL))
+ if ((iter->data == widget) && (previous != NULL))
{
- retval = GTK_WIDGET (last->data);
+ retval = GTK_WIDGET (previous->data);
}
return retval;
static void
hildon_stackable_window_map (GtkWidget *widget)
{
- GtkWidget *lastwin;
+ GtkWidget *previous = get_previous_window_if_last (widget);
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);
+ if (HILDON_IS_STACKABLE_WINDOW (previous) && GTK_WIDGET_VISIBLE (previous))
+ gtk_widget_hide (previous);
}
static void
hildon_stackable_window_unmap (GtkWidget *widget)
{
- GtkWidget *lastwin;
+ GtkWidget *previous = get_previous_window_if_last (widget);
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) &&
+ if (HILDON_IS_STACKABLE_WINDOW (previous) && !GTK_WIDGET_VISIBLE (previous) &&
!hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (widget)))
{
- gtk_widget_show (lastwin);
+ gtk_widget_show (previous);
}
}
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));
+ GtkWidget *previous = get_previous_window_if_last (GTK_WIDGET (hwin));
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)))
+ if (HILDON_IS_STACKABLE_WINDOW (previous) && !GTK_WIDGET_VISIBLE (previous) &&
+ !hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (hwin)))
{
- gtk_widget_show (nextwin);
+ gtk_widget_show (previous);
}
}
(guchar *)&atom, 1);
}
+static gboolean
+hildon_stackable_window_delete_event (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ GSList *list = get_window_list (widget);
+ list = g_slist_find (list, widget);
+
+ /* Ignore the delete event if this is not the topmost window */
+ if (list != NULL && list->next != NULL)
+ return TRUE;
+ else if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event)
+ return GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event (widget, event);
+ else
+ return FALSE;
+}
+
static void
hildon_stackable_window_class_init (HildonStackableWindowClass *klass)
{
widget_class->map = hildon_stackable_window_map;
widget_class->unmap = hildon_stackable_window_unmap;
widget_class->realize = hildon_stackable_window_realize;
+ widget_class->delete_event = hildon_stackable_window_delete_event;
window_class->unset_program = hildon_stackable_window_unset_program;
return GTK_WIDGET (newwindow);
}
-
-/**
- * hildon_stackable_window_go_to_root_window:
- * @self: A #HildonStackableWindow
- *
- * Will pop out all the stackable windows in the @HildonProgram but the
- * first one, which can be considered as the "home" window.
- */
-void
-hildon_stackable_window_go_to_root_window (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 (GTK_WIDGET (rootwin));
-}