753 lines
26 KiB
Diff
753 lines
26 KiB
Diff
From: Adrien Plazas <kekun.plazas@laposte.net>
|
|
Date: Mon, 31 Aug 2020 10:40:01 +0200
|
|
Subject: Add GtkHdyViewSwitcherButton
|
|
|
|
This is imported from HdyViewSwitcherButton from libhandy 1.0.0.
|
|
---
|
|
gtk/hdy-view-switcher-button-private.h | 51 ++++
|
|
gtk/hdy-view-switcher-button.c | 544 +++++++++++++++++++++++++++++++++
|
|
gtk/meson.build | 2 +
|
|
gtk/ui/hdy-view-switcher-button.ui | 105 +++++++
|
|
4 files changed, 702 insertions(+)
|
|
create mode 100644 gtk/hdy-view-switcher-button-private.h
|
|
create mode 100644 gtk/hdy-view-switcher-button.c
|
|
create mode 100644 gtk/ui/hdy-view-switcher-button.ui
|
|
|
|
diff --git a/gtk/hdy-view-switcher-button-private.h b/gtk/hdy-view-switcher-button-private.h
|
|
new file mode 100644
|
|
index 0000000..a37add6
|
|
--- /dev/null
|
|
+++ b/gtk/hdy-view-switcher-button-private.h
|
|
@@ -0,0 +1,51 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Zander Brown <zbrown@gnome.org>
|
|
+ * Copyright (C) 2019 Purism SPC
|
|
+ *
|
|
+ * SPDX-License-Identifier: LGPL-2.1+
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
|
+#error "Only <gtk/gtk.h> can be included directly."
|
|
+#endif
|
|
+
|
|
+#include "gtkradiobutton.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GTK_TYPE_HDY_VIEW_SWITCHER_BUTTON (gtk_hdy_view_switcher_button_get_type())
|
|
+
|
|
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButton, g_object_unref)
|
|
+
|
|
+G_DECLARE_FINAL_TYPE (GtkHdyViewSwitcherButton, gtk_hdy_view_switcher_button, GTK, HDY_VIEW_SWITCHER_BUTTON, GtkRadioButton)
|
|
+
|
|
+GtkWidget *gtk_hdy_view_switcher_button_new (void);
|
|
+
|
|
+const gchar *gtk_hdy_view_switcher_button_get_icon_name (GtkHdyViewSwitcherButton *self);
|
|
+void gtk_hdy_view_switcher_button_set_icon_name (GtkHdyViewSwitcherButton *self,
|
|
+ const gchar *icon_name);
|
|
+
|
|
+GtkIconSize gtk_hdy_view_switcher_button_get_icon_size (GtkHdyViewSwitcherButton *self);
|
|
+void gtk_hdy_view_switcher_button_set_icon_size (GtkHdyViewSwitcherButton *self,
|
|
+ GtkIconSize icon_size);
|
|
+
|
|
+gboolean gtk_hdy_view_switcher_button_get_needs_attention (GtkHdyViewSwitcherButton *self);
|
|
+void gtk_hdy_view_switcher_button_set_needs_attention (GtkHdyViewSwitcherButton *self,
|
|
+ gboolean needs_attention);
|
|
+
|
|
+const gchar *gtk_hdy_view_switcher_button_get_label (GtkHdyViewSwitcherButton *self);
|
|
+void gtk_hdy_view_switcher_button_set_label (GtkHdyViewSwitcherButton *self,
|
|
+ const gchar *label);
|
|
+
|
|
+void gtk_hdy_view_switcher_button_set_narrow_ellipsize (GtkHdyViewSwitcherButton *self,
|
|
+ PangoEllipsizeMode mode);
|
|
+
|
|
+void gtk_hdy_view_switcher_button_get_size (GtkHdyViewSwitcherButton *self,
|
|
+ gint *h_min_width,
|
|
+ gint *h_nat_width,
|
|
+ gint *v_min_width,
|
|
+ gint *v_nat_width);
|
|
+
|
|
+G_END_DECLS
|
|
diff --git a/gtk/hdy-view-switcher-button.c b/gtk/hdy-view-switcher-button.c
|
|
new file mode 100644
|
|
index 0000000..875ca7d
|
|
--- /dev/null
|
|
+++ b/gtk/hdy-view-switcher-button.c
|
|
@@ -0,0 +1,544 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Zander Brown <zbrown@gnome.org>
|
|
+ * Copyright (C) 2019 Purism SPC
|
|
+ *
|
|
+ * SPDX-License-Identifier: LGPL-2.1+
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+#include <glib/gi18n-lib.h>
|
|
+
|
|
+#include "gtkbox.h"
|
|
+#include "gtkimage.h"
|
|
+#include "gtklabel.h"
|
|
+#include "gtkorientable.h"
|
|
+#include "gtkstack.h"
|
|
+#include "gtkstylecontext.h"
|
|
+#include "gtkstyleprovider.h"
|
|
+#include "hdy-view-switcher-button-private.h"
|
|
+
|
|
+
|
|
+/**
|
|
+ * PRIVATE:gtk-hdy-view-switcher-button
|
|
+ * @short_description: Button used in #GtkHdyViewSwitcher.
|
|
+ * @title: GtkHdyViewSwitcherButton
|
|
+ * @See_also: #GtkHdyViewSwitcher
|
|
+ * @stability: Private
|
|
+ *
|
|
+ * #GtkHdyViewSwitcherButton represents an application's view. It is designed to be
|
|
+ * used exclusively internally by #GtkHdyViewSwitcher.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+
|
|
+enum {
|
|
+ PROP_0,
|
|
+ PROP_ICON_SIZE,
|
|
+ PROP_ICON_NAME,
|
|
+ PROP_NEEDS_ATTENTION,
|
|
+
|
|
+ /* Overridden properties */
|
|
+ PROP_LABEL,
|
|
+ PROP_ORIENTATION,
|
|
+
|
|
+ LAST_PROP = PROP_NEEDS_ATTENTION + 1,
|
|
+};
|
|
+
|
|
+struct _GtkHdyViewSwitcherButton
|
|
+{
|
|
+ GtkRadioButton parent_instance;
|
|
+
|
|
+ GtkBox *horizontal_box;
|
|
+ GtkImage *horizontal_image;
|
|
+ GtkLabel *horizontal_label_active;
|
|
+ GtkLabel *horizontal_label_inactive;
|
|
+ GtkStack *horizontal_label_stack;
|
|
+ GtkStack *stack;
|
|
+ GtkBox *vertical_box;
|
|
+ GtkImage *vertical_image;
|
|
+ GtkLabel *vertical_label_active;
|
|
+ GtkLabel *vertical_label_inactive;
|
|
+ GtkStack *vertical_label_stack;
|
|
+
|
|
+ gchar *icon_name;
|
|
+ GtkIconSize icon_size;
|
|
+ gchar *label;
|
|
+ GtkOrientation orientation;
|
|
+};
|
|
+
|
|
+static GParamSpec *props[LAST_PROP];
|
|
+
|
|
+G_DEFINE_TYPE_WITH_CODE (GtkHdyViewSwitcherButton, gtk_hdy_view_switcher_button, GTK_TYPE_RADIO_BUTTON,
|
|
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
|
|
+
|
|
+static void
|
|
+on_active_changed (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self))) {
|
|
+ gtk_stack_set_visible_child (self->horizontal_label_stack, GTK_WIDGET (self->horizontal_label_active));
|
|
+ gtk_stack_set_visible_child (self->vertical_label_stack, GTK_WIDGET (self->vertical_label_active));
|
|
+ } else {
|
|
+ gtk_stack_set_visible_child (self->horizontal_label_stack, GTK_WIDGET (self->horizontal_label_inactive));
|
|
+ gtk_stack_set_visible_child (self->vertical_label_stack, GTK_WIDGET (self->vertical_label_inactive));
|
|
+ }
|
|
+}
|
|
+
|
|
+static GtkOrientation
|
|
+get_orientation (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ g_return_val_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self), GTK_ORIENTATION_HORIZONTAL);
|
|
+
|
|
+ return self->orientation;
|
|
+}
|
|
+
|
|
+static void
|
|
+set_orientation (GtkHdyViewSwitcherButton *self,
|
|
+ GtkOrientation orientation)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ if (self->orientation == orientation)
|
|
+ return;
|
|
+
|
|
+ self->orientation = orientation;
|
|
+
|
|
+ gtk_stack_set_visible_child (self->stack,
|
|
+ GTK_WIDGET (self->orientation == GTK_ORIENTATION_VERTICAL ?
|
|
+ self->vertical_box :
|
|
+ self->horizontal_box));
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_hdy_view_switcher_button_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GtkHdyViewSwitcherButton *self = GTK_HDY_VIEW_SWITCHER_BUTTON (object);
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_ICON_NAME:
|
|
+ g_value_set_string (value, gtk_hdy_view_switcher_button_get_icon_name (self));
|
|
+ break;
|
|
+ case PROP_ICON_SIZE:
|
|
+ g_value_set_int (value, gtk_hdy_view_switcher_button_get_icon_size (self));
|
|
+ break;
|
|
+ case PROP_NEEDS_ATTENTION:
|
|
+ g_value_set_boolean (value, gtk_hdy_view_switcher_button_get_needs_attention (self));
|
|
+ break;
|
|
+ case PROP_LABEL:
|
|
+ g_value_set_string (value, gtk_hdy_view_switcher_button_get_label (self));
|
|
+ break;
|
|
+ case PROP_ORIENTATION:
|
|
+ g_value_set_enum (value, get_orientation (self));
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_hdy_view_switcher_button_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GtkHdyViewSwitcherButton *self = GTK_HDY_VIEW_SWITCHER_BUTTON (object);
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_ICON_NAME:
|
|
+ gtk_hdy_view_switcher_button_set_icon_name (self, g_value_get_string (value));
|
|
+ break;
|
|
+ case PROP_ICON_SIZE:
|
|
+ gtk_hdy_view_switcher_button_set_icon_size (self, g_value_get_int (value));
|
|
+ break;
|
|
+ case PROP_NEEDS_ATTENTION:
|
|
+ gtk_hdy_view_switcher_button_set_needs_attention (self, g_value_get_boolean (value));
|
|
+ break;
|
|
+ case PROP_LABEL:
|
|
+ gtk_hdy_view_switcher_button_set_label (self, g_value_get_string (value));
|
|
+ break;
|
|
+ case PROP_ORIENTATION:
|
|
+ set_orientation (self, g_value_get_enum (value));
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_hdy_view_switcher_button_finalize (GObject *object)
|
|
+{
|
|
+ GtkHdyViewSwitcherButton *self = GTK_HDY_VIEW_SWITCHER_BUTTON (object);
|
|
+
|
|
+ g_free (self->icon_name);
|
|
+ g_free (self->label);
|
|
+
|
|
+ G_OBJECT_CLASS (gtk_hdy_view_switcher_button_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_hdy_view_switcher_button_class_init (GtkHdyViewSwitcherButtonClass *klass)
|
|
+{
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
+
|
|
+ object_class->get_property = gtk_hdy_view_switcher_button_get_property;
|
|
+ object_class->set_property = gtk_hdy_view_switcher_button_set_property;
|
|
+ object_class->finalize = gtk_hdy_view_switcher_button_finalize;
|
|
+
|
|
+ g_object_class_override_property (object_class,
|
|
+ PROP_LABEL,
|
|
+ "label");
|
|
+
|
|
+ g_object_class_override_property (object_class,
|
|
+ PROP_ORIENTATION,
|
|
+ "orientation");
|
|
+
|
|
+ /**
|
|
+ * GtkHdyViewSwitcherButton:icon-name:
|
|
+ *
|
|
+ * The icon name representing the view, or %NULL for no icon.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+ props[PROP_ICON_NAME] =
|
|
+ g_param_spec_string ("icon-name",
|
|
+ _("Icon Name"),
|
|
+ _("Icon name for image"),
|
|
+ "text-x-generic-symbolic",
|
|
+ G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE);
|
|
+
|
|
+ /**
|
|
+ * GtkHdyViewSwitcherButton:icon-size:
|
|
+ *
|
|
+ * The icon size.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+ props[PROP_ICON_SIZE] =
|
|
+ g_param_spec_int ("icon-size",
|
|
+ _("Icon Size"),
|
|
+ _("Symbolic size to use for named icon"),
|
|
+ 0, G_MAXINT, GTK_ICON_SIZE_BUTTON,
|
|
+ G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE);
|
|
+
|
|
+ /**
|
|
+ * GtkHdyViewSwitcherButton:needs-attention:
|
|
+ *
|
|
+ * Sets a flag specifying whether the view requires the user attention. This
|
|
+ * is used by the GtkHdyViewSwitcher to change the appearance of the
|
|
+ * corresponding button when a view needs attention and it is not the current
|
|
+ * one.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+ props[PROP_NEEDS_ATTENTION] =
|
|
+ g_param_spec_boolean ("needs-attention",
|
|
+ _("Needs attention"),
|
|
+ _("Hint the view needs attention"),
|
|
+ FALSE,
|
|
+ G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE);
|
|
+
|
|
+ g_object_class_install_properties (object_class, LAST_PROP, props);
|
|
+
|
|
+ /* We probably should set the class's CSS name to "viewswitcherbutton"
|
|
+ * here, but it doesn't work because GtkCheckButton hardcodes it to "button"
|
|
+ * on instantiation, and the functions required to override it are private.
|
|
+ * In the meantime, we can use the "viewswitcher > button" CSS selector as
|
|
+ * a fairly safe fallback.
|
|
+ */
|
|
+
|
|
+ gtk_widget_class_set_template_from_resource (widget_class,
|
|
+ "/org/gtk/libgtk/ui/hdy-view-switcher-button.ui");
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, horizontal_box);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, horizontal_image);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, horizontal_label_active);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, horizontal_label_inactive);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, horizontal_label_stack);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, stack);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, vertical_box);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, vertical_image);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, vertical_label_active);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, vertical_label_inactive);
|
|
+ gtk_widget_class_bind_template_child (widget_class, GtkHdyViewSwitcherButton, vertical_label_stack);
|
|
+ gtk_widget_class_bind_template_callback (widget_class, on_active_changed);
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_hdy_view_switcher_button_init (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ self->icon_size = GTK_ICON_SIZE_BUTTON;
|
|
+
|
|
+ gtk_widget_init_template (GTK_WIDGET (self));
|
|
+
|
|
+ gtk_stack_set_visible_child (GTK_STACK (self->stack), GTK_WIDGET (self->horizontal_box));
|
|
+
|
|
+ gtk_widget_set_focus_on_click (GTK_WIDGET (self), FALSE);
|
|
+ /* Make the button look like a regular button and not a radio button. */
|
|
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (self), FALSE);
|
|
+
|
|
+ on_active_changed (self);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_new:
|
|
+ *
|
|
+ * Creates a new #GtkHdyViewSwitcherButton widget.
|
|
+ *
|
|
+ * Returns: a new #GtkHdyViewSwitcherButton
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+GtkWidget *
|
|
+gtk_hdy_view_switcher_button_new (void)
|
|
+{
|
|
+ return g_object_new (GTK_TYPE_HDY_VIEW_SWITCHER_BUTTON, NULL);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_get_icon_name:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ *
|
|
+ * Gets the icon name representing the view, or %NULL is no icon is set.
|
|
+ *
|
|
+ * Returns: (transfer none) (nullable): the icon name, or %NULL
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+const gchar *
|
|
+gtk_hdy_view_switcher_button_get_icon_name (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ g_return_val_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self), NULL);
|
|
+
|
|
+ return self->icon_name;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_set_icon_name:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @icon_name: (nullable): an icon name or %NULL
|
|
+ *
|
|
+ * Sets the icon name representing the view, or %NULL to disable the icon.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+void
|
|
+gtk_hdy_view_switcher_button_set_icon_name (GtkHdyViewSwitcherButton *self,
|
|
+ const gchar *icon_name)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ if (!g_strcmp0 (self->icon_name, icon_name))
|
|
+ return;
|
|
+
|
|
+ g_free (self->icon_name);
|
|
+ self->icon_name = g_strdup (icon_name);
|
|
+
|
|
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_get_icon_size:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ *
|
|
+ * Gets the icon size used by @self.
|
|
+ *
|
|
+ * Returns: the icon size used by @self
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+GtkIconSize
|
|
+gtk_hdy_view_switcher_button_get_icon_size (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ g_return_val_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self), GTK_ICON_SIZE_INVALID);
|
|
+
|
|
+ return self->icon_size;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_set_icon_size:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @icon_size: the new icon size
|
|
+ *
|
|
+ * Sets the icon size used by @self.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+void
|
|
+gtk_hdy_view_switcher_button_set_icon_size (GtkHdyViewSwitcherButton *self,
|
|
+ GtkIconSize icon_size)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ if (self->icon_size == icon_size)
|
|
+ return;
|
|
+
|
|
+ self->icon_size = icon_size;
|
|
+
|
|
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_SIZE]);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_get_needs_attention:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ *
|
|
+ * Gets whether the view represented by @self requires the user attention.
|
|
+ *
|
|
+ * Returns: %TRUE if the view represented by @self requires the user attention, %FALSE otherwise
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+gboolean
|
|
+gtk_hdy_view_switcher_button_get_needs_attention (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ GtkStyleContext *context;
|
|
+
|
|
+ g_return_val_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self), FALSE);
|
|
+
|
|
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
|
+
|
|
+ return gtk_style_context_has_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_set_needs_attention:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @needs_attention: the new icon size
|
|
+ *
|
|
+ * Sets whether the view represented by @self requires the user attention.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+void
|
|
+gtk_hdy_view_switcher_button_set_needs_attention (GtkHdyViewSwitcherButton *self,
|
|
+ gboolean needs_attention)
|
|
+{
|
|
+ GtkStyleContext *context;
|
|
+
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ needs_attention = !!needs_attention;
|
|
+
|
|
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
|
+ if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION) == needs_attention)
|
|
+ return;
|
|
+
|
|
+ if (needs_attention)
|
|
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
|
|
+ else
|
|
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
|
|
+
|
|
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NEEDS_ATTENTION]);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_get_label:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ *
|
|
+ * Gets the label representing the view.
|
|
+ *
|
|
+ * Returns: (transfer none) (nullable): the label, or %NULL
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+const gchar *
|
|
+gtk_hdy_view_switcher_button_get_label (GtkHdyViewSwitcherButton *self)
|
|
+{
|
|
+ g_return_val_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self), NULL);
|
|
+
|
|
+ return self->label;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_set_label:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @label: (nullable): a label or %NULL
|
|
+ *
|
|
+ * Sets the label representing the view.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+void
|
|
+gtk_hdy_view_switcher_button_set_label (GtkHdyViewSwitcherButton *self,
|
|
+ const gchar *label)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+
|
|
+ if (!g_strcmp0 (self->label, label))
|
|
+ return;
|
|
+
|
|
+ g_free (self->label);
|
|
+ self->label = g_strdup (label);
|
|
+
|
|
+ g_object_notify (G_OBJECT (self), "label");
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_set_narrow_ellipsize:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @mode: a #PangoEllipsizeMode
|
|
+ *
|
|
+ * Set the mode used to ellipsize the text in narrow mode if there is not
|
|
+ * enough space to render the entire string.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ **/
|
|
+void
|
|
+gtk_hdy_view_switcher_button_set_narrow_ellipsize (GtkHdyViewSwitcherButton *self,
|
|
+ PangoEllipsizeMode mode)
|
|
+{
|
|
+ g_return_if_fail (GTK_IS_HDY_VIEW_SWITCHER_BUTTON (self));
|
|
+ g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE && mode <= PANGO_ELLIPSIZE_END);
|
|
+
|
|
+ gtk_label_set_ellipsize (self->vertical_label_active, mode);
|
|
+ gtk_label_set_ellipsize (self->vertical_label_inactive, mode);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gtk_hdy_view_switcher_button_get_size:
|
|
+ * @self: a #GtkHdyViewSwitcherButton
|
|
+ * @h_min_width: (out) (nullable): the minimum width when horizontal
|
|
+ * @h_nat_width: (out) (nullable): the natural width when horizontal
|
|
+ * @v_min_width: (out) (nullable): the minimum width when vertical
|
|
+ * @v_nat_width: (out) (nullable): the natural width when vertical
|
|
+ *
|
|
+ * Measure the size requests in both horizontal and vertical modes.
|
|
+ *
|
|
+ * Since: 0.0.10
|
|
+ */
|
|
+void
|
|
+gtk_hdy_view_switcher_button_get_size (GtkHdyViewSwitcherButton *self,
|
|
+ gint *h_min_width,
|
|
+ gint *h_nat_width,
|
|
+ gint *v_min_width,
|
|
+ gint *v_nat_width)
|
|
+{
|
|
+ GtkStyleContext *context;
|
|
+ GtkStateFlags state;
|
|
+ GtkBorder border;
|
|
+
|
|
+ /* gtk_widget_get_preferred_width() doesn't accept both its out parameters to
|
|
+ * be NULL, so we must have guards.
|
|
+ */
|
|
+ if (h_min_width != NULL || h_nat_width != NULL)
|
|
+ gtk_widget_get_preferred_width (GTK_WIDGET (self->horizontal_box), h_min_width, h_nat_width);
|
|
+ if (v_min_width != NULL || v_nat_width != NULL)
|
|
+ gtk_widget_get_preferred_width (GTK_WIDGET (self->vertical_box), v_min_width, v_nat_width);
|
|
+
|
|
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
|
+ state = gtk_style_context_get_state (context);
|
|
+ gtk_style_context_get_border (context, state, &border);
|
|
+ if (h_min_width != NULL)
|
|
+ *h_min_width += border.left + border.right;
|
|
+ if (h_nat_width != NULL)
|
|
+ *h_nat_width += border.left + border.right;
|
|
+ if (v_min_width != NULL)
|
|
+ *v_min_width += border.left + border.right;
|
|
+ if (v_nat_width != NULL)
|
|
+ *v_nat_width += border.left + border.right;
|
|
+}
|
|
diff --git a/gtk/meson.build b/gtk/meson.build
|
|
index 4b7a453..38b810c 100644
|
|
--- a/gtk/meson.build
|
|
+++ b/gtk/meson.build
|
|
@@ -383,6 +383,7 @@ gtk_sources = files(
|
|
'gtkwin32draw.c',
|
|
'gtkwin32theme.c',
|
|
'gdkpixbufutils.c',
|
|
+ 'hdy-view-switcher-button.c',
|
|
'language-names.c',
|
|
'script-names.c',
|
|
)
|
|
@@ -390,6 +391,7 @@ gtk_sources = files(
|
|
gtk_private_type_headers = files(
|
|
'gtkcsstypesprivate.h',
|
|
'gtktexthandleprivate.h',
|
|
+ 'hdy-view-switcher-button-private.h',
|
|
)
|
|
|
|
gtk_gir_public_headers = files(
|
|
diff --git a/gtk/ui/hdy-view-switcher-button.ui b/gtk/ui/hdy-view-switcher-button.ui
|
|
new file mode 100644
|
|
index 0000000..6e437dc
|
|
--- /dev/null
|
|
+++ b/gtk/ui/hdy-view-switcher-button.ui
|
|
@@ -0,0 +1,105 @@
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
+<interface>
|
|
+ <requires lib="gtk+" version="3.0"/>
|
|
+ <template class="GtkHdyViewSwitcherButton" parent="GtkRadioButton">
|
|
+ <signal name="notify::active" handler="on_active_changed" after="yes"/>
|
|
+ <child>
|
|
+ <object class="GtkStack" id="stack">
|
|
+ <property name="hhomogeneous">False</property>
|
|
+ <property name="transition-type">crossfade</property>
|
|
+ <property name="vhomogeneous">True</property>
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkBox" id="horizontal_box">
|
|
+ <property name="halign">center</property>
|
|
+ <property name="orientation">horizontal</property>
|
|
+ <property name="spacing">8</property>
|
|
+ <property name="valign">center</property>
|
|
+ <property name="visible">True</property>
|
|
+ <style>
|
|
+ <class name="wide"/>
|
|
+ </style>
|
|
+ <child>
|
|
+ <object class="GtkImage" id="horizontal_image">
|
|
+ <property name="icon-name" bind-source="GtkHdyViewSwitcherButton" bind-property="icon-name" bind-flags="sync-create" />
|
|
+ <property name="icon-size" bind-source="GtkHdyViewSwitcherButton" bind-property="icon-size" bind-flags="sync-create" />
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkStack" id="horizontal_label_stack">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="horizontal_label_inactive">
|
|
+ <property name="label" bind-source="GtkHdyViewSwitcherButton" bind-property="label" bind-flags="sync-create|bidirectional" />
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="name">inactive</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="horizontal_label_active">
|
|
+ <property name="label" bind-source="GtkHdyViewSwitcherButton" bind-property="label" bind-flags="sync-create|bidirectional" />
|
|
+ <property name="visible">True</property>
|
|
+ <style>
|
|
+ <class name="active"/>
|
|
+ </style>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="name">active</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ </child>
|
|
+ </object>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkBox" id="vertical_box">
|
|
+ <property name="halign">center</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <property name="spacing">4</property>
|
|
+ <property name="valign">center</property>
|
|
+ <property name="visible">True</property>
|
|
+ <style>
|
|
+ <class name="narrow"/>
|
|
+ </style>
|
|
+ <child>
|
|
+ <object class="GtkImage" id="vertical_image">
|
|
+ <property name="icon-name" bind-source="GtkHdyViewSwitcherButton" bind-property="icon-name" bind-flags="sync-create" />
|
|
+ <property name="icon-size" bind-source="GtkHdyViewSwitcherButton" bind-property="icon-size" bind-flags="sync-create" />
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkStack" id="vertical_label_stack">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="vertical_label_inactive">
|
|
+ <property name="label" bind-source="GtkHdyViewSwitcherButton" bind-property="label" bind-flags="sync-create|bidirectional" />
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="name">inactive</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="vertical_label_active">
|
|
+ <property name="label" bind-source="GtkHdyViewSwitcherButton" bind-property="label" bind-flags="sync-create|bidirectional" />
|
|
+ <property name="visible">True</property>
|
|
+ <style>
|
|
+ <class name="active"/>
|
|
+ </style>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="name">active</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ </child>
|
|
+ </object>
|
|
+ </child>
|
|
+ </object>
|
|
+ </child>
|
|
+ </template>
|
|
+</interface>
|