[tepl] Panel: implementation
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tepl] Panel: implementation
- Date: Tue, 21 Apr 2020 15:37:20 +0000 (UTC)
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]