[tepl] Panel: implementation



commit cdc7b1433acff20314889bf62ce0e36c80f5c508
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Tue Apr 21 14:12:16 2020 +0200

    Panel: implementation
    
    It's tested directly in gnome-latex.

 docs/reference/tepl-sections.txt |   6 +
 tepl/tepl-panel.c                | 255 ++++++++++++++++++++++++++++++++++++++-
 tepl/tepl-panel.h                |  22 +++-
 3 files changed, 277 insertions(+), 6 deletions(-)
---
diff --git a/docs/reference/tepl-sections.txt b/docs/reference/tepl-sections.txt
index fe67ea6..b9eb3b8 100644
--- a/docs/reference/tepl-sections.txt
+++ b/docs/reference/tepl-sections.txt
@@ -322,6 +322,12 @@ tepl_metadata_manager_get_type
 <FILE>panel</FILE>
 TeplPanel
 tepl_panel_new
+tepl_panel_new_for_left_side_panel
+tepl_panel_get_stack
+tepl_panel_add_component
+tepl_panel_set_active_component_setting
+tepl_panel_restore_settings
+tepl_panel_save_settings
 <SUBSECTION Standard>
 TEPL_IS_PANEL
 TEPL_IS_PANEL_CLASS
diff --git a/tepl/tepl-panel.c b/tepl/tepl-panel.c
index 15cd7eb..9795287 100644
--- a/tepl/tepl-panel.c
+++ b/tepl/tepl-panel.c
@@ -17,7 +17,10 @@
  * along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
 #include "tepl-panel.h"
+#include <glib/gi18n-lib.h>
+#include "tepl-utils.h"
 
 /**
  * SECTION:panel
@@ -29,16 +32,25 @@
 
 struct _TeplPanelPrivate
 {
-       gint something;
+       GtkStack *stack;
+
+       GSettings *settings;
+       gchar *active_component_setting_key;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (TeplPanel, tepl_panel, GTK_TYPE_GRID)
 
 static void
-tepl_panel_finalize (GObject *object)
+tepl_panel_dispose (GObject *object)
 {
+       TeplPanel *panel = TEPL_PANEL (object);
+
+       panel->priv->stack = NULL;
+
+       g_clear_object (&panel->priv->settings);
+       g_clear_pointer (&panel->priv->active_component_setting_key, g_free);
 
-       G_OBJECT_CLASS (tepl_panel_parent_class)->finalize (object);
+       G_OBJECT_CLASS (tepl_panel_parent_class)->dispose (object);
 }
 
 static void
@@ -46,18 +58,26 @@ tepl_panel_class_init (TeplPanelClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       object_class->finalize = tepl_panel_finalize;
+       object_class->dispose = tepl_panel_dispose;
 }
 
 static void
 tepl_panel_init (TeplPanel *panel)
 {
        panel->priv = tepl_panel_get_instance_private (panel);
+
+       panel->priv->stack = GTK_STACK (gtk_stack_new ());
+       gtk_widget_show (GTK_WIDGET (panel->priv->stack));
+       gtk_container_add (GTK_CONTAINER (panel),
+                          GTK_WIDGET (panel->priv->stack));
 }
 
 /**
  * tepl_panel_new:
  *
+ * Creates a new #TeplPanel containing only an empty #GtkStack that can be
+ * retrieved with tepl_panel_get_stack().
+ *
  * Returns: (transfer floating): a new #TeplPanel.
  * Since: 5.0
  */
@@ -66,3 +86,230 @@ tepl_panel_new (void)
 {
        return g_object_new (TEPL_TYPE_PANEL, NULL);
 }
+
+static void
+close_button_clicked_cb (GtkButton *close_button,
+                        TeplPanel *panel)
+{
+       gtk_widget_hide (GTK_WIDGET (panel));
+}
+
+static GtkWidget *
+create_close_button (TeplPanel *panel)
+{
+       GtkWidget *close_button;
+
+       close_button = tepl_utils_create_close_button ();
+       gtk_widget_set_tooltip_text (close_button, _("Hide panel"));
+
+       g_signal_connect_object (close_button,
+                                "clicked",
+                                G_CALLBACK (close_button_clicked_cb),
+                                panel,
+                                0);
+
+       return close_button;
+}
+
+static TeplPanel *
+new_for_side_panel (void)
+{
+       TeplPanel *panel;
+       GtkStackSwitcher *stack_switcher;
+       GtkActionBar *action_bar;
+
+       panel = tepl_panel_new ();
+       gtk_orientable_set_orientation (GTK_ORIENTABLE (panel), GTK_ORIENTATION_VERTICAL);
+
+       stack_switcher = GTK_STACK_SWITCHER (gtk_stack_switcher_new ());
+       gtk_stack_switcher_set_stack (stack_switcher, panel->priv->stack);
+
+       action_bar = GTK_ACTION_BAR (gtk_action_bar_new ());
+       gtk_action_bar_set_center_widget (action_bar, GTK_WIDGET (stack_switcher));
+       gtk_action_bar_pack_end (action_bar, create_close_button (panel));
+
+       gtk_grid_attach_next_to (GTK_GRID (panel),
+                                GTK_WIDGET (action_bar),
+                                GTK_WIDGET (panel->priv->stack),
+                                GTK_POS_TOP, 1, 1);
+
+       gtk_widget_show_all (GTK_WIDGET (panel));
+
+       return panel;
+}
+
+/**
+ * tepl_panel_new_for_left_side_panel:
+ *
+ * Creates a new #TeplPanel intended to be used as a side panel added on the
+ * left side inside a #GtkWindow.
+ *
+ * It contains:
+ * - A #GtkStackSwitcher.
+ * - A close button that hides the #TeplPanel when clicked.
+ * - A #GtkStack that can be retrieved with tepl_panel_get_stack().
+ *
+ * Returns: (transfer floating): a new left side #TeplPanel.
+ * Since: 5.0
+ */
+TeplPanel *
+tepl_panel_new_for_left_side_panel (void)
+{
+       TeplPanel *panel;
+
+       panel = new_for_side_panel ();
+       gtk_widget_set_margin_start (GTK_WIDGET (panel), 6);
+
+       return panel;
+}
+
+/**
+ * tepl_panel_get_stack:
+ * @panel: a #TeplPanel.
+ *
+ * Returns: (transfer none): the #GtkStack widget of @panel.
+ * Since: 5.0
+ */
+GtkStack *
+tepl_panel_get_stack (TeplPanel *panel)
+{
+       g_return_val_if_fail (TEPL_IS_PANEL (panel), NULL);
+
+       return panel->priv->stack;
+}
+
+/**
+ * tepl_panel_add_component:
+ * @panel: a #TeplPanel.
+ * @component: the child #GtkWidget to add to the #GtkStack of @panel.
+ * @name: the name for @component.
+ * @title: a human-readable title for @component.
+ * @icon_name: (nullable): the icon name for @component, or %NULL.
+ *
+ * The equivalent of gtk_stack_add_titled(), with an optional @icon_name to set
+ * the “icon-name” #GtkStack child property.
+ *
+ * Since: 5.0
+ */
+void
+tepl_panel_add_component (TeplPanel   *panel,
+                         GtkWidget   *component,
+                         const gchar *name,
+                         const gchar *title,
+                         const gchar *icon_name)
+{
+       g_return_if_fail (TEPL_IS_PANEL (panel));
+       g_return_if_fail (GTK_IS_WIDGET (component));
+       g_return_if_fail (name != NULL);
+       g_return_if_fail (title != NULL);
+
+       gtk_stack_add_titled (panel->priv->stack, component, name, title);
+
+       if (icon_name != NULL)
+       {
+               gtk_container_child_set (GTK_CONTAINER (panel->priv->stack),
+                                        component,
+                                        "icon-name", icon_name,
+                                        NULL);
+       }
+}
+
+/**
+ * tepl_panel_set_active_component_setting:
+ * @panel: a #TeplPanel.
+ * @settings: a #GSettings object.
+ * @setting_key: a #GSettings key of type string.
+ *
+ * Provides a #GSettings key for saving and restoring the
+ * #GtkStack:visible-child-name property of the #GtkStack belonging to @panel.
+ *
+ * This function just stores @settings and @setting_key for further use by
+ * tepl_panel_restore_settings() and tepl_panel_save_settings().
+ *
+ * Since: 5.0
+ */
+void
+tepl_panel_set_active_component_setting (TeplPanel   *panel,
+                                        GSettings   *settings,
+                                        const gchar *setting_key)
+{
+       g_return_if_fail (TEPL_IS_PANEL (panel));
+       g_return_if_fail (G_IS_SETTINGS (settings));
+       g_return_if_fail (setting_key != NULL);
+
+       g_set_object (&panel->priv->settings, settings);
+
+       g_free (panel->priv->active_component_setting_key);
+       panel->priv->active_component_setting_key = g_strdup (setting_key);
+}
+
+/**
+ * tepl_panel_restore_settings:
+ * @panel: a #TeplPanel.
+ *
+ * Restores the state of @panel according to the provided #GSettings.
+ *
+ * This function must be called when all components have been added to the
+ * #GtkStack of @panel.
+ *
+ * Since: 5.0
+ */
+void
+tepl_panel_restore_settings (TeplPanel *panel)
+{
+       gchar *active_component_name;
+       GtkWidget *child_widget;
+
+       g_return_if_fail (TEPL_IS_PANEL (panel));
+
+       if (panel->priv->settings == NULL)
+       {
+               return;
+       }
+
+       active_component_name = g_settings_get_string (panel->priv->settings,
+                                                      panel->priv->active_component_setting_key);
+
+       child_widget = gtk_stack_get_child_by_name (panel->priv->stack, active_component_name);
+
+       /* If child_widget is NULL, do nothing, and do not print an error. It
+        * can happen if it's an old GSettings value and the child in the
+        * GtkStack no longer exists after an upgrade of the application.
+        */
+
+       if (child_widget != NULL)
+       {
+               gtk_stack_set_visible_child (panel->priv->stack, child_widget);
+       }
+
+       g_free (active_component_name);
+}
+
+/**
+ * tepl_panel_save_settings:
+ * @panel: a #TeplPanel.
+ *
+ * Saves the current state of @panel to the provided #GSettings.
+ *
+ * Since: 5.0
+ */
+void
+tepl_panel_save_settings (TeplPanel *panel)
+{
+       const gchar *visible_child_name;
+
+       g_return_if_fail (TEPL_IS_PANEL (panel));
+
+       if (panel->priv->settings == NULL)
+       {
+               return;
+       }
+
+       visible_child_name = gtk_stack_get_visible_child_name (panel->priv->stack);
+       if (visible_child_name != NULL)
+       {
+               g_settings_set_string (panel->priv->settings,
+                                      panel->priv->active_component_setting_key,
+                                      visible_child_name);
+       }
+}
diff --git a/tepl/tepl-panel.h b/tepl/tepl-panel.h
index 3c81a1c..bae07db 100644
--- a/tepl/tepl-panel.h
+++ b/tepl/tepl-panel.h
@@ -53,9 +53,27 @@ struct _TeplPanelClass
        gpointer padding[12];
 };
 
-GType          tepl_panel_get_type     (void);
+GType          tepl_panel_get_type                     (void);
 
-TeplPanel *    tepl_panel_new          (void);
+TeplPanel *    tepl_panel_new                          (void);
+
+TeplPanel *    tepl_panel_new_for_left_side_panel      (void);
+
+GtkStack *     tepl_panel_get_stack                    (TeplPanel *panel);
+
+void           tepl_panel_add_component                (TeplPanel   *panel,
+                                                        GtkWidget   *component,
+                                                        const gchar *name,
+                                                        const gchar *title,
+                                                        const gchar *icon_name);
+
+void           tepl_panel_set_active_component_setting (TeplPanel   *panel,
+                                                        GSettings   *settings,
+                                                        const gchar *setting_key);
+
+void           tepl_panel_restore_settings             (TeplPanel *panel);
+
+void           tepl_panel_save_settings                (TeplPanel *panel);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]