G_DEFINE_TYPE (HildonWindowStack, hildon_window_stack, G_TYPE_OBJECT);
+enum {
+ PROP_GROUP = 1,
+};
+
+static void
+hildon_window_stack_set_window_group (HildonWindowStack *stack,
+ GtkWindowGroup *group)
+{
+ g_return_if_fail (HILDON_IS_WINDOW_STACK (stack));
+ g_return_if_fail (!group || GTK_IS_WINDOW_GROUP (group));
+
+ /* The window group is only to be set once during construction */
+ g_return_if_fail (stack->priv->group == NULL);
+
+ if (!group)
+ group = gtk_window_group_new ();
+
+ stack->priv->group = group;
+}
+
+static GtkWindowGroup *
+hildon_window_stack_get_window_group (HildonWindowStack *stack)
+{
+ g_return_val_if_fail (HILDON_IS_WINDOW_STACK (stack), NULL);
+
+ return stack->priv->group;
+}
+
/**
* hildon_window_stack_get_default:
*
* doesn't need to be created by the application.
*
* Return value: the default #HildonWindowStack
+ *
+ * Since: 2.2
**/
HildonWindowStack *
hildon_window_stack_get_default (void)
{
static HildonWindowStack *stack = NULL;
if (G_UNLIKELY (stack == NULL)) {
- stack = g_object_new (HILDON_TYPE_WINDOW_STACK, NULL);
- stack->priv->group = gtk_window_get_group (NULL);
+ stack = g_object_new (HILDON_TYPE_WINDOW_STACK,
+ "window-group", gtk_window_get_group (NULL),
+ NULL);
}
return stack;
}
* Creates a new #HildonWindowStack. The stack is initially empty.
*
* Return value: a new #HildonWindowStack
+ *
+ * Since: 2.2
**/
HildonWindowStack *
hildon_window_stack_new (void)
{
HildonWindowStack *stack = g_object_new (HILDON_TYPE_WINDOW_STACK, NULL);
- stack->priv->group = gtk_window_group_new ();
return stack;
}
* Returns the number of windows in @stack
*
* Return value: Number of windows in @stack
+ *
+ * Since: 2.2
**/
gint
hildon_window_stack_size (HildonWindowStack *stack)
/* If the window is stacked */
if (stack) {
+ GList *pos;
+
hildon_stackable_window_set_stack (win, NULL, -1);
- stack->priv->list = g_list_remove (stack->priv->list, win);
gtk_window_set_transient_for (GTK_WINDOW (win), NULL);
if (GTK_WIDGET (win)->window) {
gdk_window_set_group (GTK_WIDGET (win)->window, NULL);
}
+
+ /* If the window removed is in the middle of the stack, update
+ * transiency of other windows */
+ pos = g_list_find (stack->priv->list, win);
+ g_assert (pos != NULL);
+ if (pos->prev) {
+ GtkWindow *upper = GTK_WINDOW (pos->prev->data);
+ GtkWindow *lower = pos->next ? GTK_WINDOW (pos->next->data) : NULL;
+ gtk_window_set_transient_for (upper, lower);
+ }
+
+ stack->priv->list = g_list_remove (stack->priv->list, win);
+
g_signal_handlers_disconnect_by_func (win, hildon_window_stack_window_realized, stack);
}
}
*
* Return value: the window on top of the stack, or %NULL if the stack
* is empty.
+ *
+ * Since: 2.2
**/
GtkWidget *
hildon_window_stack_peek (HildonWindowStack *stack)
return win;
}
-static gboolean
+/* This function does everything to push a window to the stack _but_
+ * actually calling gtk_widget_show().
+ * It's up to each specific push function to decide the order in which
+ * to show windows. */
+gboolean G_GNUC_INTERNAL
_hildon_window_stack_do_push (HildonWindowStack *stack,
HildonStackableWindow *win)
{
*
* Adds @win to the top of @stack, and shows it. The window must not
* be already stacked.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_push_1 (HildonWindowStack *stack,
*
* Return value: the window on top of the stack, or %NULL if the stack
* is empty.
+ *
+ * Since: 2.2
**/
GtkWidget *
hildon_window_stack_pop_1 (HildonWindowStack *stack)
* them. Everything is done in a single transition, so the user will
* only see the last window in @list during this operation. None of
* the windows must be already stacked.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_push_list (HildonWindowStack *stack,
* Pushes all windows to the top of @stack, and shows them. Everything
* is done in a single transition, so the user will only see the last
* window. None of the windows must be already stacked.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_push (HildonWindowStack *stack,
HildonStackableWindow *win1,
...)
{
- HildonStackableWindow *win;
+ HildonStackableWindow *win = win1;
GList *list = NULL;
va_list args;
va_start (args, win1);
- win = va_arg (args, HildonStackableWindow *);
while (win != NULL) {
list = g_list_prepend (list, win);
va_end (args);
+ list = g_list_reverse (list);
+
hildon_window_stack_push_list (stack, list);
g_list_free (list);
}
* If @popped_windows is not %NULL, the list of popped windows is
* stored there (ordered bottom-up). That list must be freed by the
* user.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_pop (HildonWindowStack *stack,
* If @popped_windows is not %NULL, the list of popped windows is
* stored there (ordered bottom-up). That list must be freed by the
* user.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_pop_and_push_list (HildonWindowStack *stack,
* If @popped_windows is not %NULL, the list of popped windows is
* stored there (ordered bottom-up). That list must be freed by the
* user.
+ *
+ * Since: 2.2
**/
void
hildon_window_stack_pop_and_push (HildonWindowStack *stack,
HildonStackableWindow *win1,
...)
{
- HildonStackableWindow *win;
+ HildonStackableWindow *win = win1;
GList *list = NULL;
va_list args;
va_start (args, win1);
- win = va_arg (args, HildonStackableWindow *);
while (win != NULL) {
list = g_list_prepend (list, win);
va_end (args);
+ list = g_list_reverse (list);
+
hildon_window_stack_pop_and_push_list (stack, nwindows, popped_windows, list);
g_list_free (list);
}
}
static void
+hildon_window_stack_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HildonWindowStack *stack = HILDON_WINDOW_STACK (object);
+
+ switch (prop_id)
+ {
+ case PROP_GROUP:
+ hildon_window_stack_set_window_group (stack, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_window_stack_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonWindowStack *stack = HILDON_WINDOW_STACK (object);
+
+ switch (prop_id)
+ {
+ case PROP_GROUP:
+ g_value_set_object (value, hildon_window_stack_get_window_group (stack));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
hildon_window_stack_class_init (HildonWindowStackClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
+ gobject_class->set_property = hildon_window_stack_set_property;
+ gobject_class->get_property = hildon_window_stack_get_property;
gobject_class->finalize = hildon_window_stack_finalize;
+ g_object_class_install_property (
+ gobject_class,
+ PROP_GROUP,
+ g_param_spec_object (
+ "window-group",
+ "GtkWindowGroup for this stack",
+ "GtkWindowGroup that all windows on this stack belong to",
+ GTK_TYPE_WINDOW_GROUP,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
g_type_class_add_private (klass, sizeof (HildonWindowStackPrivate));
}