[gnome-builder] GbTabStack: add stack container for new style tabs
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] GbTabStack: add stack container for new style tabs
- Date: Tue, 2 Dec 2014 04:24:06 +0000 (UTC)
commit 7587c1f26c74d451f1ad416785b24162f6459f3b
Author: Christian Hergert <christian hergert me>
Date: Mon Dec 1 19:44:02 2014 -0800
GbTabStack: add stack container for new style tabs
src/gnome-builder.mk | 2 +
src/resources/ui/gb-tab-stack.ui | 75 +++++
src/tabs/gb-tab-stack.c | 580 ++++++++++++++++++++++++++++++++++++++
src/tabs/gb-tab-stack.h | 72 +++++
4 files changed, 729 insertions(+), 0 deletions(-)
---
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 18e42f7..96d9a87 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -145,6 +145,8 @@ libgnome_builder_la_SOURCES = \
src/tabs/gb-tab-label-private.h \
src/tabs/gb-tab.c \
src/tabs/gb-tab.h \
+ src/tabs/gb-tab-stack.c \
+ src/tabs/gb-tab-stack.h \
src/theatrics/gb-box-theatric.c \
src/theatrics/gb-box-theatric.h \
src/tree/gb-tree.c \
diff --git a/src/resources/ui/gb-tab-stack.ui b/src/resources/ui/gb-tab-stack.ui
new file mode 100644
index 0000000..104f353
--- /dev/null
+++ b/src/resources/ui/gb-tab-stack.ui
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.8 -->
+ <template class="GbTabStack" parent="GtkBox">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="header_box">
+ <property name="visible">false</property>
+ <property name="orientation">horizontal</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkMenuButton" id="stack_menu">
+ <property name="visible">true</property>
+ <style>
+ <class name="image-button"/>
+ <class name="tab-header-first"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combo">
+ <property name="visible">true</property>
+ <property name="hexpand">true</property>
+ <property name="model">store</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="controls">
+ <property name="homogeneous">false</property>
+ <property name="hexpand">false</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="visible">true</property>
+ <property name="sensitive">false</property>
+ <property name="tooltip_text">Close tab</property>
+ <style>
+ <class name="image-button"/>
+ <class name="tab-header-last"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">true</property>
+ <property name="expand">true</property>
+ <property name="transition-type">GTK_STACK_TRANSITION_TYPE_CROSSFADE</property>
+ </object>
+ </child>
+ </template>
+ <object class="GtkListStore" id="store">
+ <columns>
+ <!-- column-name tab -->
+ <column type="GbTab"/>
+ </columns>
+ </object>
+</interface>
diff --git a/src/tabs/gb-tab-stack.c b/src/tabs/gb-tab-stack.c
new file mode 100644
index 0000000..ebbe484
--- /dev/null
+++ b/src/tabs/gb-tab-stack.c
@@ -0,0 +1,580 @@
+/* gb-tab-stack.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "tab-stack"
+
+#include <glib/gi18n.h>
+
+#include "gb-tab-grid.h"
+#include "gb-log.h"
+#include "gb-tab-stack.h"
+
+struct _GbTabStackPrivate
+{
+ GtkButton *close;
+ GtkComboBox *combo;
+ GtkStack *controls;
+ GtkBox *header_box;
+ GtkMenuButton *stack_menu;
+ GtkStack *stack;
+ GtkListStore *store;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbTabStack, gb_tab_stack, GTK_TYPE_BOX)
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static void gb_tab_stack_tab_closed (GbTabStack *stack,
+ GbTab *tab);
+
+static guint gSignals [LAST_SIGNAL];
+
+GtkWidget *
+gb_tab_stack_new (void)
+{
+ return g_object_new (GB_TYPE_TAB_STACK, NULL);
+}
+
+static gboolean
+gb_tab_stack_queue_draw (gpointer data)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (data), FALSE);
+
+ gtk_widget_queue_draw (GTK_WIDGET (data));
+
+ return G_SOURCE_REMOVE;
+}
+
+guint
+gb_tab_stack_get_n_tabs (GbTabStack *stack)
+{
+ GbTabStackPrivate *priv;
+ GList *children;
+ guint n_tabs;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), 0);
+
+ priv = stack->priv;
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->stack));
+ n_tabs = g_list_length (children);
+ g_list_free (children);
+
+ return n_tabs;
+}
+
+/**
+ * gb_tab_stack_get_tabs:
+ * @stack: (in): A #GbTabStack.
+ *
+ * Returns all of the tabs within the stack.
+ *
+ * Returns: (transfer container) (element-type GbTab*): A #GList of #GbTab.
+ */
+GList *
+gb_tab_stack_get_tabs (GbTabStack *stack)
+{
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), NULL);
+
+ return gtk_container_get_children (GTK_CONTAINER (stack->priv->stack));
+}
+
+static gboolean
+gb_tab_stack_get_tab_iter (GbTabStack *stack,
+ GbTab *tab,
+ GtkTreeIter *iter)
+{
+ GtkTreeModel *model;
+ gint position = -1;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+ g_return_val_if_fail (iter, FALSE);
+
+ if (gtk_widget_get_parent (GTK_WIDGET (tab)) == GTK_WIDGET (stack->priv->stack))
+ gtk_container_child_get (GTK_CONTAINER (stack->priv->stack), GTK_WIDGET (tab),
+ "position", &position,
+ NULL);
+
+ if (position != -1)
+ {
+ model = GTK_TREE_MODEL (stack->priv->store);
+
+ if (gtk_tree_model_get_iter_first (model, iter))
+ {
+ for (; position; position--)
+ {
+ if (!gtk_tree_model_iter_next (model, iter))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gb_tab_stack_focus_iter (GbTabStack *stack,
+ GtkTreeIter *iter)
+{
+ gboolean ret = FALSE;
+ GbTab *tab = NULL;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+ g_return_val_if_fail (iter, FALSE);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (stack->priv->store), iter,
+ 0, &tab,
+ -1);
+
+ if (GB_IS_TAB (tab))
+ {
+ gtk_combo_box_set_active_iter (stack->priv->combo, iter);
+ gtk_widget_grab_focus (GTK_WIDGET (tab));
+ ret = TRUE;
+ }
+
+ g_clear_object (&tab);
+
+ return ret;
+}
+
+gboolean
+gb_tab_stack_focus_tab (GbTabStack *stack,
+ GbTab *tab)
+{
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+ g_return_val_if_fail (GB_IS_TAB (tab), FALSE);
+
+ if (gb_tab_stack_get_tab_iter (stack, tab, &iter))
+ {
+ gb_tab_stack_focus_iter (stack, &iter);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+gb_tab_stack_remove_tab (GbTabStack *stack,
+ GbTab *tab)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+ g_return_if_fail (GB_IS_TAB (tab));
+
+ model = GTK_TREE_MODEL (stack->priv->store);
+
+ if (gb_tab_stack_get_tab_iter (stack, tab, &iter))
+ {
+ g_signal_handlers_disconnect_by_func (tab,
+ gb_tab_stack_tab_closed,
+ stack);
+ g_signal_handlers_disconnect_by_func (tab,
+ gb_tab_stack_queue_draw,
+ stack);
+
+ gtk_container_remove (GTK_CONTAINER (stack->priv->controls),
+ gb_tab_get_controls (tab));
+ gtk_container_remove (GTK_CONTAINER (stack->priv->stack),
+ GTK_WIDGET (tab));
+
+ if (!gtk_list_store_remove (stack->priv->store, &iter))
+ {
+ guint count;
+
+ if ((count = gtk_tree_model_iter_n_children (model, NULL)))
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, count-1))
+ gb_tab_stack_focus_iter (stack, &iter);
+ }
+ }
+ else
+ gb_tab_stack_focus_iter (stack, &iter);
+ }
+
+ g_signal_emit (stack, gSignals [CHANGED], 0);
+}
+
+gboolean
+gb_tab_stack_focus_next (GbTabStack *stack)
+{
+ GtkWidget *child;
+ GtkTreeIter iter;
+ gboolean ret = FALSE;
+
+ ENTRY;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+
+ if (!(child = gtk_stack_get_visible_child (stack->priv->stack)))
+ RETURN (FALSE);
+
+ if (gb_tab_stack_get_tab_iter (stack, GB_TAB (child), &iter) &&
+ gtk_tree_model_iter_next (GTK_TREE_MODEL (stack->priv->store), &iter))
+ ret = gb_tab_stack_focus_iter (stack, &iter);
+
+ RETURN (ret);
+}
+
+gboolean
+gb_tab_stack_focus_previous (GbTabStack *stack)
+{
+ GtkWidget *child;
+ GtkTreeIter iter;
+ gboolean ret = FALSE;
+
+ ENTRY;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+
+ if (!(child = gtk_stack_get_visible_child (stack->priv->stack)))
+ RETURN (FALSE);
+
+ if (gb_tab_stack_get_tab_iter (stack, GB_TAB (child), &iter) &&
+ gtk_tree_model_iter_previous (GTK_TREE_MODEL (stack->priv->store), &iter))
+ ret = gb_tab_stack_focus_iter (stack, &iter);
+
+ RETURN (ret);
+}
+
+gboolean
+gb_tab_stack_focus_first (GbTabStack *stack)
+{
+ GtkTreeIter iter;
+
+ ENTRY;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (stack->priv->store),
+ &iter))
+ RETURN (gb_tab_stack_focus_iter (stack, &iter));
+
+ RETURN (FALSE);
+}
+
+gboolean
+gb_tab_stack_focus_last (GbTabStack *stack)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ guint n_children;
+
+ ENTRY;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+
+ model = GTK_TREE_MODEL (stack->priv->store);
+ n_children = gtk_tree_model_iter_n_children (model, NULL);
+
+ if (n_children != 0)
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, n_children-1))
+ RETURN (gb_tab_stack_focus_iter (stack, &iter));
+ }
+
+ RETURN (FALSE);
+}
+
+gboolean
+gb_tab_stack_contains_tab (GbTabStack *stack,
+ GbTab *tab)
+{
+ gboolean ret = FALSE;
+ GList *list;
+ GList *iter;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+ g_return_val_if_fail (GB_IS_TAB (tab), FALSE);
+
+ list = gb_tab_stack_get_tabs (stack);
+
+ for (iter = list; iter; iter = iter->next)
+ {
+ if (iter->data == (void *)tab)
+ {
+ ret = TRUE;
+ break;
+ }
+ }
+
+ g_list_free (list);
+
+ return ret;
+}
+
+static void
+gb_tab_stack_combobox_changed (GbTabStack *stack,
+ GtkComboBox *combobox)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GbTab *tab = NULL;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+ model = gtk_combo_box_get_model (combobox);
+
+ if (gtk_combo_box_get_active_iter (combobox, &iter))
+ {
+ gtk_tree_model_get (model, &iter, 0, &tab, -1);
+
+ if (GB_IS_TAB (tab))
+ {
+ GtkWidget *controls;
+
+ gtk_stack_set_visible_child (stack->priv->stack, GTK_WIDGET (tab));
+ gtk_widget_set_sensitive (GTK_WIDGET (stack->priv->close), TRUE);
+
+ if ((controls = gb_tab_get_controls (tab)))
+ gtk_stack_set_visible_child (stack->priv->controls, controls);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (stack->priv->close), FALSE);
+ }
+
+ g_clear_object (&tab);
+ }
+}
+
+GbTab *
+gb_tab_stack_get_active (GbTabStack *stack)
+{
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), NULL);
+
+ return GB_TAB (gtk_stack_get_visible_child (stack->priv->stack));
+}
+
+static void
+gb_tab_stack_tab_closed (GbTabStack *stack,
+ GbTab *tab)
+{
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+ g_return_if_fail (GB_IS_TAB (tab));
+
+ gb_tab_stack_remove_tab (stack, tab);
+}
+
+static void
+gb_tab_stack_add_tab (GbTabStack *stack,
+ GbTab *tab)
+{
+ GtkTreeIter iter;
+ GtkWidget *controls;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+ g_return_if_fail (GB_IS_TAB (tab));
+
+ gtk_list_store_append (stack->priv->store, &iter);
+ g_object_freeze_notify (G_OBJECT (stack->priv->stack));
+ gtk_list_store_set (stack->priv->store, &iter, 0, tab, -1);
+ gtk_container_add (GTK_CONTAINER (stack->priv->stack), GTK_WIDGET (tab));
+ if ((controls = gb_tab_get_controls (tab)))
+ gtk_container_add (GTK_CONTAINER (stack->priv->controls), controls);
+ g_object_thaw_notify (G_OBJECT (stack->priv->stack));
+ gtk_combo_box_set_active_iter (stack->priv->combo, &iter);
+
+ /* TODO: need to disconnect on (re)move */
+ g_signal_connect_object (tab,
+ "close",
+ G_CALLBACK (gb_tab_stack_tab_closed),
+ stack,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (tab,
+ "notify::title",
+ G_CALLBACK (gb_tab_stack_queue_draw),
+ stack,
+ G_CONNECT_SWAPPED);
+
+ gtk_widget_show (GTK_WIDGET (stack->priv->header_box));
+
+ g_signal_emit (stack, gSignals [CHANGED], 0);
+}
+
+static void
+gb_tab_stack_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GbTabStack *stack = (GbTabStack *)container;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (GB_IS_TAB (widget))
+ gb_tab_stack_add_tab (stack, GB_TAB (widget));
+ else
+ GTK_CONTAINER_CLASS (gb_tab_stack_parent_class)->add (container, widget);
+}
+
+static void
+gb_tab_stack_combobox_text_func (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ const gchar *title = NULL;
+ GbTab *tab = NULL;
+
+ gtk_tree_model_get (tree_model, iter, 0, &tab, -1);
+
+ if (GB_IS_TAB (tab))
+ title = gb_tab_get_title (tab);
+ if (!title)
+ title = _("untitled");
+
+ if (gb_tab_get_dirty (tab))
+ {
+ gchar *str;
+
+ str = g_strdup_printf ("%s •", title);
+ g_object_set (cell, "text", str, NULL);
+ g_free (str);
+ }
+ else
+ g_object_set (cell, "text", title, NULL);
+
+ g_clear_object (&tab);
+}
+
+static void
+gb_tab_stack_grab_focus (GtkWidget *widget)
+{
+ GbTabStack *stack = (GbTabStack *)widget;
+ GtkWidget *child;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+ child = gtk_stack_get_visible_child (stack->priv->stack);
+
+ if (child)
+ gtk_widget_grab_focus (child);
+}
+
+static GbTabGrid *
+get_grid (GbTabStack *stack)
+{
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (stack);
+
+ while (widget && !GB_IS_TAB_GRID (widget))
+ widget = gtk_widget_get_parent (widget);
+
+ return (GbTabGrid *)widget;
+}
+
+static void
+gb_tab_stack_do_close_tab (GbTabStack *stack,
+ GdkEvent *event,
+ GtkButton *button)
+{
+ GbTabGrid *grid;
+ GbTab *tab;
+
+ g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+ grid = get_grid (stack);
+ tab = gb_tab_stack_get_active (stack);
+
+ if (grid && tab)
+ gb_tab_stack_remove_tab (stack, tab);
+}
+
+static void
+gb_tab_stack_class_init (GbTabStackClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+ container_class->add = gb_tab_stack_add;
+
+ widget_class->grab_focus = gb_tab_stack_grab_focus;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/builder/ui/gb-tab-stack.ui");
+ gtk_widget_class_bind_template_child_internal_private (widget_class, GbTabStack, controls);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, close);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, combo);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, header_box);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, stack);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, stack_menu);
+ gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, store);
+
+ gSignals [CHANGED] = g_signal_new ("changed",
+ GB_TYPE_TAB_STACK,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GbTabStackClass, changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_ensure (GB_TYPE_TAB);
+}
+
+static void
+gb_tab_stack_init (GbTabStack *stack)
+{
+ GtkCellLayout *layout;
+ GtkCellRenderer *cell;
+ GApplication *app;
+ GMenu *menu;
+
+ stack->priv = gb_tab_stack_get_instance_private (stack);
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (stack),
+ GTK_ORIENTATION_VERTICAL);
+
+ gtk_widget_init_template (GTK_WIDGET (stack));
+
+ g_signal_connect_object (stack->priv->combo,
+ "changed",
+ G_CALLBACK (gb_tab_stack_combobox_changed),
+ stack,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (stack->priv->close,
+ "clicked",
+ G_CALLBACK (gb_tab_stack_do_close_tab),
+ stack,
+ G_CONNECT_SWAPPED);
+
+ layout = GTK_CELL_LAYOUT (stack->priv->combo);
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (layout, cell, TRUE);
+ gtk_cell_layout_set_cell_data_func (layout, cell,
+ gb_tab_stack_combobox_text_func,
+ NULL, NULL);
+ gtk_cell_renderer_text_set_fixed_height_from_font (
+ GTK_CELL_RENDERER_TEXT (cell), 1);
+
+ app = g_application_get_default ();
+ menu = gtk_application_get_menu_by_id (GTK_APPLICATION (app), "stack-menu");
+ gtk_menu_button_set_menu_model (stack->priv->stack_menu, G_MENU_MODEL (menu));
+}
diff --git a/src/tabs/gb-tab-stack.h b/src/tabs/gb-tab-stack.h
new file mode 100644
index 0000000..6b52034
--- /dev/null
+++ b/src/tabs/gb-tab-stack.h
@@ -0,0 +1,72 @@
+/* gb-tab-stack.h
+ *
+ * Copyright (C) 2011 Christian Hergert <chris dronelabs com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_TAB_STACK_H
+#define GB_TAB_STACK_H
+
+#include <gtk/gtk.h>
+
+#include "gb-tab.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_TAB_STACK (gb_tab_stack_get_type())
+#define GB_TAB_STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_TAB_STACK, GbTabStack))
+#define GB_TAB_STACK_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_TAB_STACK, GbTabStack
const))
+#define GB_TAB_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_TAB_STACK, GbTabStackClass))
+#define GB_IS_TAB_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_TAB_STACK))
+#define GB_IS_TAB_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_TAB_STACK))
+#define GB_TAB_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_TAB_STACK, GbTabStackClass))
+
+typedef struct _GbTabStack GbTabStack;
+typedef struct _GbTabStackClass GbTabStackClass;
+typedef struct _GbTabStackPrivate GbTabStackPrivate;
+
+struct _GbTabStack
+{
+ GtkBox parent;
+
+ /*< private >*/
+ GbTabStackPrivate *priv;
+};
+
+struct _GbTabStackClass
+{
+ GtkBoxClass parent_class;
+
+ void (*changed) (GbTabStack *stack);
+};
+
+GType gb_tab_stack_get_type (void) G_GNUC_CONST;
+GbTab *gb_tab_stack_get_active (GbTabStack *stack);
+gboolean gb_tab_stack_contains_tab (GbTabStack *stack,
+ GbTab *tab);
+void gb_tab_stack_remove_tab (GbTabStack *stack,
+ GbTab *tab);
+guint gb_tab_stack_get_n_tabs (GbTabStack *stack);
+gboolean gb_tab_stack_focus_first (GbTabStack *stack);
+gboolean gb_tab_stack_focus_last (GbTabStack *stack);
+gboolean gb_tab_stack_focus_next (GbTabStack *stack);
+gboolean gb_tab_stack_focus_previous (GbTabStack *stack);
+gboolean gb_tab_stack_focus_tab (GbTabStack *stack,
+ GbTab *tab);
+GList *gb_tab_stack_get_tabs (GbTabStack *stack);
+
+G_END_DECLS
+
+#endif /* GB_TAB_STACK_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]