[gedit/wip/panels-as-stacks: 14/19] Implement a new GeditMenuStackSwitcher widget.
- From: Steve Frécinaux <sfre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit/wip/panels-as-stacks: 14/19] Implement a new GeditMenuStackSwitcher widget.
- Date: Mon, 20 Jan 2014 09:16:34 +0000 (UTC)
commit f006f426d5bb419cba0668a6a0232b32c484a495
Author: Steve Frécinaux <code istique net>
Date: Thu Jan 16 11:58:59 2014 +0100
Implement a new GeditMenuStackSwitcher widget.
This widget is similar to GtkStackSwitcher but uses a dropdown menu.
gedit/Makefile.am | 2 +
gedit/gedit-menu-stack-switcher.c | 289 +++++++++++++++++++++++++++++++++++++
gedit/gedit-menu-stack-switcher.h | 73 ++++++++++
gedit/gedit-window.c | 7 +-
4 files changed, 368 insertions(+), 3 deletions(-)
---
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 075fcfd..28d1697 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -121,6 +121,7 @@ gedit_NOINST_H_FILES = \
gedit/gedit-highlight-mode-dialog.h \
gedit/gedit-history-entry.h \
gedit/gedit-io-error-info-bar.h \
+ gedit/gedit-menu-stack-switcher.h \
gedit/gedit-multi-notebook.h \
gedit/gedit-notebook.h \
gedit/gedit-notebook-popup-menu.h \
@@ -198,6 +199,7 @@ gedit_libgedit_c_files = \
gedit/gedit-highlight-mode-dialog.c \
gedit/gedit-history-entry.c \
gedit/gedit-io-error-info-bar.c \
+ gedit/gedit-menu-stack-switcher.c \
gedit/gedit-message-bus.c \
gedit/gedit-message.c \
gedit/gedit-multi-notebook.c \
diff --git a/gedit/gedit-menu-stack-switcher.c b/gedit/gedit-menu-stack-switcher.c
new file mode 100644
index 0000000..a820f9e
--- /dev/null
+++ b/gedit/gedit-menu-stack-switcher.c
@@ -0,0 +1,289 @@
+/*
+ * gedit-menu-stack-switcher.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Steve Frécinaux
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gedit-menu-stack-switcher.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+struct _GeditMenuStackSwitcherPrivate
+{
+ GtkWidget *label;
+
+ GtkStack *stack;
+ GSimpleActionGroup *action_group;
+
+ GMenu *menu;
+};
+
+enum {
+ PROP_0,
+ PROP_STACK
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GeditMenuStackSwitcher, gedit_menu_stack_switcher, GTK_TYPE_MENU_BUTTON)
+
+static void
+gedit_menu_stack_switcher_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GeditMenuStackSwitcher *switcher = GEDIT_MENU_STACK_SWITCHER (object);
+ GeditMenuStackSwitcherPrivate *priv = switcher->priv;
+
+ switch (prop_id)
+ {
+ case PROP_STACK:
+ g_value_set_object (value, priv->stack);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_menu_stack_switcher_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeditMenuStackSwitcher *switcher = GEDIT_MENU_STACK_SWITCHER (object);
+
+ switch (prop_id)
+ {
+ case PROP_STACK:
+ gedit_menu_stack_switcher_set_stack (switcher, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_menu_stack_switcher_dispose (GObject *object)
+{
+ GeditMenuStackSwitcher *switcher = GEDIT_MENU_STACK_SWITCHER (object);
+
+ gedit_menu_stack_switcher_set_stack (switcher, NULL);
+
+ G_OBJECT_CLASS (gedit_menu_stack_switcher_parent_class)->dispose (object);
+}
+
+static void
+add_menu_entry (GtkWidget *widget,
+ GeditMenuStackSwitcher *switcher)
+{
+ GeditMenuStackSwitcherPrivate *priv = switcher->priv;
+ gchar *title, *name;
+ GMenuItem *item;
+
+ gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+ "title", &title,
+ "name", &name,
+ NULL);
+
+ item = g_menu_item_new (title, NULL);
+ g_menu_item_set_action_and_target (item, "switcher.set-visible-child", "s", name);
+
+ g_free (title);
+ g_free (name);
+
+ g_menu_append_item (priv->menu, item);
+ g_object_unref (item);
+}
+
+static gboolean
+destroy_menu (GtkWidget *switcher)
+{
+ gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (switcher), NULL);
+
+ /* GtkMenuButton makes the widget insensitive when we remove the model... */
+ gtk_widget_set_sensitive (switcher, TRUE);
+
+ return FALSE;
+}
+
+static void
+gedit_menu_stack_switcher_toggled (GtkToggleButton *button)
+{
+ GeditMenuStackSwitcher *switcher = GEDIT_MENU_STACK_SWITCHER (button);
+ GeditMenuStackSwitcherPrivate *priv = switcher->priv;
+
+ if (!priv->stack)
+ return;
+
+ if (gtk_toggle_button_get_active (button))
+ {
+ priv->menu = g_menu_new ();
+ gtk_container_foreach (GTK_CONTAINER (priv->stack), (GtkCallback) add_menu_entry, switcher);
+
+ gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (switcher), G_MENU_MODEL (priv->menu));
+ }
+
+ GTK_TOGGLE_BUTTON_CLASS (gedit_menu_stack_switcher_parent_class)->toggled (button);
+
+ if (!gtk_toggle_button_get_active (button))
+ {
+ g_idle_add ((GSourceFunc) destroy_menu, switcher);
+ priv->menu = NULL;
+ }
+}
+
+static void
+gedit_menu_stack_switcher_class_init (GeditMenuStackSwitcherClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkToggleButtonClass *toggle_button_class = GTK_TOGGLE_BUTTON_CLASS (klass);
+
+ object_class->get_property = gedit_menu_stack_switcher_get_property;
+ object_class->set_property = gedit_menu_stack_switcher_set_property;
+ object_class->dispose = gedit_menu_stack_switcher_dispose;
+
+ toggle_button_class->toggled = gedit_menu_stack_switcher_toggled;
+
+ g_object_class_install_property (object_class,
+ PROP_STACK,
+ g_param_spec_object ("stack",
+ "Stack",
+ "Stack",
+ GTK_TYPE_STACK,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+gedit_menu_stack_switcher_init (GeditMenuStackSwitcher *switcher)
+{
+ GeditMenuStackSwitcherPrivate *priv;
+ GtkWidget *box;
+ GtkWidget *arrow;
+
+ priv = gedit_menu_stack_switcher_get_instance_private (switcher);
+ switcher->priv = priv;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+ arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ g_object_bind_property (switcher, "direction", arrow, "arrow-type", 0);
+ gtk_box_pack_end (GTK_BOX (box), arrow, FALSE, TRUE, 6);
+
+ priv->label = gtk_label_new (NULL);
+ gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 6);
+
+ gtk_widget_show_all (box);
+ gtk_container_add (GTK_CONTAINER (switcher), box);
+}
+
+static void
+update_label (GeditMenuStackSwitcher *switcher)
+{
+ GeditMenuStackSwitcherPrivate *priv = switcher->priv;
+ GtkWidget *child;
+ gchar *title = NULL;
+
+ if (switcher->priv->stack)
+ {
+ child = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+ if (child)
+ gtk_container_child_get (GTK_CONTAINER (priv->stack), child,
+ "title", &title, NULL);
+ }
+
+ gtk_label_set_label (GTK_LABEL (priv->label), title);
+ g_free (title);
+}
+
+static void
+on_visible_child_changed (GtkWidget *widget,
+ GParamSpec *pspec,
+ GeditMenuStackSwitcher *switcher)
+{
+ update_label (switcher);
+}
+
+void
+gedit_menu_stack_switcher_set_stack (GeditMenuStackSwitcher *switcher,
+ GtkStack *stack)
+{
+ GeditMenuStackSwitcherPrivate *priv;
+ GPropertyAction *action;
+
+ g_return_if_fail (GEDIT_IS_MENU_STACK_SWITCHER (switcher));
+ g_return_if_fail (stack == NULL || GTK_IS_STACK (stack));
+
+ priv = switcher->priv;
+
+ if (priv->stack == stack)
+ return;
+
+ if (priv->stack)
+ {
+ gtk_widget_insert_action_group (GTK_WIDGET (switcher), "switcher", NULL);
+ g_clear_object (&priv->action_group);
+ g_clear_object (&priv->stack);
+ }
+
+ if (stack)
+ {
+ priv->stack = g_object_ref (stack);
+ g_signal_connect (priv->stack, "notify::visible-child",
+ G_CALLBACK (on_visible_child_changed), switcher);
+
+ priv->action_group = g_simple_action_group_new ();
+ gtk_widget_insert_action_group (GTK_WIDGET (switcher), "switcher", G_ACTION_GROUP
(priv->action_group));
+
+ action = g_property_action_new ("set-visible-child", priv->stack, "visible-child-name");
+ g_action_map_add_action (G_ACTION_MAP (priv->action_group), G_ACTION (action));
+ g_object_unref (action);
+ }
+
+ update_label (switcher);
+ gtk_widget_set_sensitive (GTK_WIDGET (switcher), stack != NULL);
+
+ g_object_notify (G_OBJECT (switcher), "stack");
+}
+
+GtkStack *
+gedit_menu_stack_switcher_get_stack (GeditMenuStackSwitcher *switcher)
+{
+ g_return_val_if_fail (GEDIT_IS_MENU_STACK_SWITCHER (switcher), NULL);
+
+ return switcher->priv->stack;
+}
+
+GtkWidget *
+gedit_menu_stack_switcher_new (void)
+{
+ return g_object_new (GEDIT_TYPE_MENU_STACK_SWITCHER, NULL);
+}
+
+/* ex:set ts=2 sw=2 et: */
diff --git a/gedit/gedit-menu-stack-switcher.h b/gedit/gedit-menu-stack-switcher.h
new file mode 100644
index 0000000..25f233f
--- /dev/null
+++ b/gedit/gedit-menu-stack-switcher.h
@@ -0,0 +1,73 @@
+/*
+ * gedit-menu-stack-switcher.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Steve Frécinaux
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GEDIT_MENU_STACK_SWITCHER_H__
+#define __GEDIT_MENU_STACK_SWITCHER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_MENU_STACK_SWITCHER (gedit_menu_stack_switcher_get_type())
+#define GEDIT_MENU_STACK_SWITCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),
GEDIT_TYPE_MENU_STACK_SWITCHER, GeditMenuStackSwitcher))
+#define GEDIT_MENU_STACK_SWITCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),
GEDIT_TYPE_MENU_STACK_SWITCHER, GeditMenuStackSwitcherClass))
+#define GEDIT_IS_MENU_STACK_SWITCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),
GEDIT_TYPE_MENU_STACK_SWITCHER))
+#define GEDIT_IS_MENU_STACK_SWITCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GEDIT_TYPE_MENU_STACK_SWITCHER))
+#define GEDIT_MENU_STACK_SWITCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),
GEDIT_TYPE_MENU_STACK_SWITCHER, GeditMenuStackSwitcherClass))
+
+typedef struct _GeditMenuStackSwitcher GeditMenuStackSwitcher;
+typedef struct _GeditMenuStackSwitcherClass GeditMenuStackSwitcherClass;
+typedef struct _GeditMenuStackSwitcherPrivate GeditMenuStackSwitcherPrivate;
+
+struct _GeditMenuStackSwitcher
+{
+ GtkMenuButton parent;
+
+ /*< private >*/
+ GeditMenuStackSwitcherPrivate *priv;
+};
+
+struct _GeditMenuStackSwitcherClass
+{
+ GtkMenuButtonClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gedit_reserved1) (void);
+ void (*_gedit_reserved2) (void);
+ void (*_gedit_reserved3) (void);
+ void (*_gedit_reserved4) (void);
+};
+
+GType gedit_menu_stack_switcher_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gedit_menu_stack_switcher_new (void);
+
+void gedit_menu_stack_switcher_set_stack (GeditMenuStackSwitcher *switcher,
+ GtkStack *stack);
+
+GtkStack * gedit_menu_stack_switcher_get_stack (GeditMenuStackSwitcher *switcher);
+
+G_END_DECLS
+
+#endif /* __GEDIT_MENU_STACK_SWITCHER_H__ */
+
+/* ex:set ts=2 sw=2 et: */
diff --git a/gedit/gedit-window.c b/gedit/gedit-window.c
index 34f25cd..09492d4 100644
--- a/gedit/gedit-window.c
+++ b/gedit/gedit-window.c
@@ -63,6 +63,7 @@
#include "gedit-marshal.h"
#include "gedit-document.h"
#include "gedit-small-button.h"
+#include "gedit-menu-stack-switcher.h"
#define TAB_WIDTH_DATA "GeditWindowTabWidthData"
#define FULLSCREEN_ANIMATION_SPEED 4
@@ -2993,9 +2994,9 @@ gedit_window_init (GeditWindow *window)
G_BINDING_DEFAULT | G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- window->priv->side_stack_switcher = gtk_stack_switcher_new ();
- gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (window->priv->side_stack_switcher),
- GTK_STACK (_gedit_panel_get_stack (GEDIT_PANEL
(window->priv->side_panel))));
+ window->priv->side_stack_switcher = gedit_menu_stack_switcher_new ();
+ gedit_menu_stack_switcher_set_stack (GEDIT_MENU_STACK_SWITCHER (window->priv->side_stack_switcher),
+ GTK_STACK (_gedit_panel_get_stack (GEDIT_PANEL
(window->priv->side_panel))));
gtk_header_bar_set_custom_title (GTK_HEADER_BAR (window->priv->side_headerbar),
window->priv->side_stack_switcher);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]