[libadwaita/wip/exalm/tab-overview: 1/3] Add AdwTabButton
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/tab-overview: 1/3] Add AdwTabButton
- Date: Fri, 26 Aug 2022 15:19:33 +0000 (UTC)
commit 512d6f385b2c22a3192f41a0afce26583d18b4dc
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Thu Aug 19 18:42:03 2021 +0500
Add AdwTabButton
src/adw-tab-button.c | 510 +++++++++++++++++++++
src/adw-tab-button.h | 36 ++
src/adw-tab-button.ui | 38 ++
src/adwaita.gresources.xml | 3 +
src/adwaita.h | 1 +
.../scalable/status/adw-tab-counter-symbolic.svg | 69 +++
.../scalable/status/adw-tab-overflow-symbolic.svg | 41 ++
src/meson.build | 2 +
src/stylesheet/widgets/_buttons.scss | 11 +
9 files changed, 711 insertions(+)
---
diff --git a/src/adw-tab-button.c b/src/adw-tab-button.c
new file mode 100644
index 00000000..9e6a6719
--- /dev/null
+++ b/src/adw-tab-button.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2019 Alexander Mikhaylenko <exalm7659 gmail com>
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ * Author: Alexander Mikhaylenko <alexander mikhaylenko puri sm>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include "adw-tab-button.h"
+
+#include "adw-indicator-bin-private.h"
+#include "adw-macros-private.h"
+
+/* Copied from GtkInspector code */
+#define XFT_DPI_MULTIPLIER (96.0 * PANGO_SCALE)
+
+/**
+ * AdwTabButton:
+ *
+ * A button that displays the number of [class@TabView] pages.
+ *
+ * The `AdwTabButton` widget is a button that displays the number of pages in a
+ * given `AdwTabView`.
+ *
+ * It can be used to open a tab switcher view in a mobile UI.
+ *
+ * ## CSS nodes
+ *
+ * `AdwTabButton` has a main CSS node with name tabbutton.
+ *
+ * It contains the subnode `button`, which contains the subnode `overlay`, which
+ * contains nodes `image` and `label`. The `label` subnode can have the `.small`
+ * style class for 10 or more tabs.
+ *
+ * # Accessibility
+ *
+ * `AdwTabButton` uses the `GTK_ACCESSIBLE_ROLE_BUTTON` role.
+ *
+ * Since: 1.0
+ */
+
+struct _AdwTabButton
+{
+ GtkWidget parent_instance;
+
+ GtkWidget *button;
+ GtkLabel *label;
+ GtkImage *icon;
+ AdwIndicatorBin *indicator;
+
+ AdwTabView *view;
+
+ int needs_attention;
+};
+
+static void adw_tab_button_actionable_init (GtkActionableInterface *iface);
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (AdwTabButton, adw_tab_button, GTK_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE, adw_tab_button_actionable_init))
+
+enum {
+ PROP_0,
+ PROP_VIEW,
+
+ /* actionable properties */
+ PROP_ACTION_NAME,
+ PROP_ACTION_TARGET,
+ LAST_PROP = PROP_ACTION_NAME
+};
+
+static GParamSpec *props[LAST_PROP];
+
+enum {
+ SIGNAL_CLICKED,
+ SIGNAL_ACTIVATE,
+ SIGNAL_LAST_SIGNAL,
+};
+
+static guint signals[SIGNAL_LAST_SIGNAL];
+
+static void
+clicked_cb (AdwTabButton *self)
+{
+ g_signal_emit (self, signals[SIGNAL_CLICKED], 0);
+}
+
+static void
+activate_cb (AdwTabButton *self)
+{
+ g_signal_emit_by_name (self->button, "activate");
+}
+
+/* FIXME: I hope there is a better way to prevent the label from changing scale */
+static void
+update_label_scale (AdwTabButton *self,
+ GtkSettings *settings)
+{
+ int xft_dpi;
+ PangoAttrList *attrs;
+ PangoAttribute *scale_attribute;
+
+ g_object_get (settings, "gtk-xft-dpi", &xft_dpi, NULL);
+
+ attrs = pango_attr_list_new ();
+
+ scale_attribute = pango_attr_scale_new (XFT_DPI_MULTIPLIER / (double) xft_dpi);
+
+ pango_attr_list_change (attrs, scale_attribute);
+
+ gtk_label_set_attributes (self->label, attrs);
+
+ pango_attr_list_unref (attrs);
+}
+
+static void
+xft_dpi_changed (AdwTabButton *self,
+ GParamSpec *pspec,
+ GtkSettings *settings)
+{
+ update_label_scale (self, settings);
+}
+
+static void
+update_icon (AdwTabButton *self)
+{
+ gboolean display_label = FALSE;
+ gboolean small_label = FALSE;
+ const char *icon_name = "adw-tab-counter-symbolic";
+ char *label_text = NULL;
+ GtkStyleContext *context;
+
+ if (self->view) {
+ guint n_pages = adw_tab_view_get_n_pages (self->view);
+
+ small_label = n_pages >= 10;
+
+ if (n_pages < 100) {
+ display_label = TRUE;
+ label_text = g_strdup_printf ("%u", n_pages);
+ } else {
+ icon_name = "adw-tab-overflow-symbolic";
+ }
+ }
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (self->label));
+
+ if (small_label)
+ gtk_style_context_add_class (context, "small");
+ else
+ gtk_style_context_remove_class (context, "small");
+
+ gtk_widget_set_visible (GTK_WIDGET (self->label), display_label);
+ gtk_label_set_text (self->label, label_text);
+ gtk_image_set_from_icon_name (self->icon, icon_name);
+
+ g_free (label_text);
+}
+
+static void
+update_needs_attention (AdwTabButton *self)
+{
+ int needs_attention = self->needs_attention;
+
+ if (self->view) {
+ AdwTabPage *selected_page = adw_tab_view_get_selected_page (self->view);
+
+ if (selected_page && adw_tab_page_get_needs_attention (selected_page))
+ needs_attention--;
+ }
+
+ adw_indicator_bin_set_needs_attention (ADW_INDICATOR_BIN (self->indicator),
+ needs_attention > 0);
+}
+
+static void
+notify_needs_attention_cb (AdwTabButton *self,
+ GParamSpec *pspec,
+ AdwTabPage *page)
+{
+ if (adw_tab_page_get_needs_attention (page))
+ self->needs_attention++;
+ else
+ self->needs_attention--;
+
+ update_needs_attention (self);
+}
+
+static void
+page_attached_cb (AdwTabButton *self,
+ AdwTabPage *page)
+{
+ g_signal_connect_object (page, "notify::needs-attention",
+ G_CALLBACK (notify_needs_attention_cb), self,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+page_detached_cb (AdwTabButton *self,
+ AdwTabPage *page)
+{
+ g_signal_handlers_disconnect_by_func (page, notify_needs_attention_cb, self);
+}
+
+static void
+adw_tab_button_dispose (GObject *object)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (object);
+
+ adw_tab_button_set_view (self, NULL);
+
+ gtk_widget_unparent (GTK_WIDGET (self->button));
+
+ G_OBJECT_CLASS (adw_tab_button_parent_class)->dispose (object);
+}
+
+static void
+adw_tab_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (object);
+
+ switch (prop_id) {
+ case PROP_VIEW:
+ g_value_set_object (value, adw_tab_button_get_view (self));
+ break;
+ case PROP_ACTION_NAME:
+ g_value_set_string (value, gtk_actionable_get_action_name (GTK_ACTIONABLE (self)));
+ break;
+ case PROP_ACTION_TARGET:
+ g_value_set_variant (value, gtk_actionable_get_action_target_value (GTK_ACTIONABLE (self)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+adw_tab_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (object);
+
+ switch (prop_id) {
+ case PROP_VIEW:
+ adw_tab_button_set_view (self, g_value_get_object (value));
+ break;
+ case PROP_ACTION_NAME:
+ gtk_actionable_set_action_name (GTK_ACTIONABLE (self), g_value_get_string (value));
+ break;
+ case PROP_ACTION_TARGET:
+ gtk_actionable_set_action_target_value (GTK_ACTIONABLE (self), g_value_get_variant (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+adw_tab_button_class_init (AdwTabButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = adw_tab_button_dispose;
+ object_class->get_property = adw_tab_button_get_property;
+ object_class->set_property = adw_tab_button_set_property;
+
+ /**
+ * AdwTabButton:view: (attributes org.gtk.Property.get=adw_tab_button_get_view
org.gtk.Property.set=adw_tab_button_set_view)
+ *
+ * The view the tab button displays.
+ *
+ * Since: 1.3
+ */
+ props[PROP_VIEW] =
+ g_param_spec_object ("view", NULL, NULL,
+ ADW_TYPE_TAB_VIEW,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, LAST_PROP, props);
+
+ g_object_class_override_property (object_class, PROP_ACTION_NAME, "action-name");
+ g_object_class_override_property (object_class, PROP_ACTION_TARGET, "action-target");
+
+ /**
+ * AdwTabButton::clicked:
+ * @self: the object that received the signal
+ *
+ * Emitted when the button has been activated (pressed and released).
+ *
+ * Since: 1.3
+ */
+ signals[SIGNAL_CLICKED] =
+ g_signal_new ("clicked",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * AdwTabButton::activate:
+ * @self: the object which received the signal.
+ *
+ * Emitted to animate press then release.
+ *
+ * This is an action signal. Applications should never connect to this signal,
+ * but use the [signal@TabButton::clicked] signal.
+ *
+ * Since: 1.3
+ */
+ signals[SIGNAL_ACTIVATE] =
+ g_signal_new ("activate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+
+ gtk_widget_class_set_activate_signal (widget_class, signals[SIGNAL_ACTIVATE]);
+
+ g_signal_override_class_handler ("activate",
+ G_TYPE_FROM_CLASS (klass),
+ G_CALLBACK (activate_cb));
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/Adwaita/ui/adw-tab-button.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, AdwTabButton, button);
+ gtk_widget_class_bind_template_child (widget_class, AdwTabButton, label);
+ gtk_widget_class_bind_template_child (widget_class, AdwTabButton, icon);
+ gtk_widget_class_bind_template_child (widget_class, AdwTabButton, indicator);
+ gtk_widget_class_bind_template_callback (widget_class, clicked_cb);
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+ gtk_widget_class_set_css_name (widget_class, "tabbutton");
+ gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_BUTTON);
+
+ g_type_ensure (ADW_TYPE_INDICATOR_BIN);
+}
+
+static void
+adw_tab_button_init (AdwTabButton *self)
+{
+ GtkSettings *settings;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ update_icon (self);
+
+ settings = gtk_widget_get_settings (GTK_WIDGET (self));
+
+ update_label_scale (self, settings);
+ g_signal_connect_object (settings, "notify::gtk-xft-dpi",
+ G_CALLBACK (xft_dpi_changed), self,
+ G_CONNECT_SWAPPED);
+}
+
+static const char *
+adw_tab_button_get_action_name (GtkActionable *actionable)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (actionable);
+
+ return gtk_actionable_get_action_name (GTK_ACTIONABLE (self->button));
+}
+
+static void
+adw_tab_button_set_action_name (GtkActionable *actionable,
+ const char *action_name)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (actionable);
+
+ return gtk_actionable_set_action_name (GTK_ACTIONABLE (self->button),
+ action_name);
+}
+
+static GVariant *
+adw_tab_button_get_action_target_value (GtkActionable *actionable)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (actionable);
+
+ return gtk_actionable_get_action_target_value (GTK_ACTIONABLE (self->button));
+}
+
+static void
+adw_tab_button_set_action_target_value (GtkActionable *actionable,
+ GVariant *action_target)
+{
+ AdwTabButton *self = ADW_TAB_BUTTON (actionable);
+
+ return gtk_actionable_set_action_target_value (GTK_ACTIONABLE (self->button),
+ action_target);
+}
+
+static void
+adw_tab_button_actionable_init (GtkActionableInterface *iface)
+{
+ iface->get_action_name = adw_tab_button_get_action_name;
+ iface->set_action_name = adw_tab_button_set_action_name;
+ iface->get_action_target_value = adw_tab_button_get_action_target_value;
+ iface->set_action_target_value = adw_tab_button_set_action_target_value;
+}
+
+/**
+ * adw_tab_button_new:
+ *
+ * Creates a new `AdwTabButton`.
+ *
+ * Returns: the newly created `AdwTabButton`
+ *
+ * Since: 1.3
+ */
+GtkWidget *
+adw_tab_button_new (void)
+{
+ return g_object_new (ADW_TYPE_TAB_BUTTON, NULL);
+}
+
+/**
+ * adw_tab_button_get_view: (attributes org.gtk.Method.get_property=view)
+ * @self: a tab button
+ *
+ * Gets the tab view @self displays.
+ *
+ * Returns: (transfer none) (nullable): the tab view
+ *
+ * Since: 1.3
+ */
+AdwTabView *
+adw_tab_button_get_view (AdwTabButton *self)
+{
+ g_return_val_if_fail (ADW_IS_TAB_BUTTON (self), NULL);
+
+ return self->view;
+}
+
+/**
+ * adw_tab_button_set_view: (attributes org.gtk.Method.set_property=view)
+ * @self: a tab button
+ * @view: (nullable): a tab view
+ *
+ * Sets the tab view to display.
+ *
+ * Since: 1.3
+ */
+void
+adw_tab_button_set_view (AdwTabButton *self,
+ AdwTabView *view)
+{
+ g_return_if_fail (ADW_IS_TAB_BUTTON (self));
+ g_return_if_fail (view == NULL || ADW_IS_TAB_VIEW (view));
+
+ if (self->view == view)
+ return;
+
+ if (self->view) {
+ int i, n;
+
+ g_signal_handlers_disconnect_by_func (self->view, update_icon, self);
+ g_signal_handlers_disconnect_by_func (self->view, update_needs_attention, self);
+ g_signal_handlers_disconnect_by_func (self->view, page_attached_cb, self);
+ g_signal_handlers_disconnect_by_func (self->view, page_detached_cb, self);
+
+ n = adw_tab_view_get_n_pages (self->view);
+
+ for (i = 0; i < n; i++)
+ page_detached_cb (self, adw_tab_view_get_nth_page (self->view, i));
+
+ self->needs_attention = 0;
+ }
+
+ g_set_object (&self->view, view);
+
+ if (self->view) {
+ int i, n;
+
+ g_signal_connect_object (self->view, "notify::n-pages",
+ G_CALLBACK (update_icon), self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->view, "notify::selected-page",
+ G_CALLBACK (update_needs_attention), self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->view, "page-attached",
+ G_CALLBACK (page_attached_cb), self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->view, "page-detached",
+ G_CALLBACK (page_detached_cb), self,
+ G_CONNECT_SWAPPED);
+
+ n = adw_tab_view_get_n_pages (self->view);
+
+ for (i = 0; i < n; i++)
+ page_attached_cb (self, adw_tab_view_get_nth_page (self->view, i));
+ }
+
+ update_icon (self);
+ update_needs_attention (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VIEW]);
+}
diff --git a/src/adw-tab-button.h b/src/adw-tab-button.h
new file mode 100644
index 00000000..8f6f943e
--- /dev/null
+++ b/src/adw-tab-button.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ * Author: Alexander Mikhaylenko <alexander mikhaylenko puri sm>
+ */
+
+#pragma once
+
+#if !defined(_ADWAITA_INSIDE) && !defined(ADWAITA_COMPILATION)
+#error "Only <adwaita.h> can be included directly."
+#endif
+
+#include "adw-version.h"
+
+#include <gtk/gtk.h>
+#include "adw-tab-view.h"
+
+G_BEGIN_DECLS
+
+#define ADW_TYPE_TAB_BUTTON (adw_tab_button_get_type())
+
+ADW_AVAILABLE_IN_1_2
+G_DECLARE_FINAL_TYPE (AdwTabButton, adw_tab_button, ADW, TAB_BUTTON, GtkWidget)
+
+ADW_AVAILABLE_IN_1_2
+GtkWidget *adw_tab_button_new (void) G_GNUC_WARN_UNUSED_RESULT;
+
+ADW_AVAILABLE_IN_1_2
+AdwTabView *adw_tab_button_get_view (AdwTabButton *self);
+ADW_AVAILABLE_IN_1_2
+void adw_tab_button_set_view (AdwTabButton *self,
+ AdwTabView *view);
+
+G_END_DECLS
diff --git a/src/adw-tab-button.ui b/src/adw-tab-button.ui
new file mode 100644
index 00000000..b8354860
--- /dev/null
+++ b/src/adw-tab-button.ui
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk" version="4.0"/>
+ <template class="AdwTabButton" parent="GtkWidget">
+ <child>
+ <object class="GtkButton" id="button">
+ <property name="tooltip-text" translatable="yes">View Open Tabs</property>
+ <signal name="clicked" handler="clicked_cb" swapped="yes"/>
+ <property name="child">
+ <object class="AdwIndicatorBin" id="indicator">
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="child">
+ <object class="GtkOverlay">
+ <child>
+ <object class="GtkImage" id="icon"/>
+ </child>
+ <child type="overlay">
+ <object class="GtkLabel" id="label">
+ <property name="xalign">0.5</property>
+ <property name="justify">center</property>
+ <property name="width-chars">2</property>
+ <style>
+ <class name="numeric"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/adwaita.gresources.xml b/src/adwaita.gresources.xml
index 58a0d7c4..095d250e 100644
--- a/src/adwaita.gresources.xml
+++ b/src/adwaita.gresources.xml
@@ -8,7 +8,9 @@
<file preprocess="xml-stripblanks">icons/scalable/actions/adw-expander-arrow-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/adw-mail-send-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/avatar-default-symbolic.svg</file>
+ <file preprocess="xml-stripblanks">icons/scalable/status/adw-tab-counter-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/adw-tab-icon-missing-symbolic.svg</file>
+ <file preprocess="xml-stripblanks">icons/scalable/status/adw-tab-overflow-symbolic.svg</file>
</gresource>
<gresource prefix="/org/gnome/Adwaita/ui">
<file preprocess="xml-stripblanks">adw-about-window.ui</file>
@@ -24,6 +26,7 @@
<file preprocess="xml-stripblanks">adw-status-page.ui</file>
<file preprocess="xml-stripblanks">adw-tab.ui</file>
<file preprocess="xml-stripblanks">adw-tab-bar.ui</file>
+ <file preprocess="xml-stripblanks">adw-tab-button.ui</file>
<file preprocess="xml-stripblanks">adw-toast-widget.ui</file>
<file preprocess="xml-stripblanks">adw-view-switcher-bar.ui</file>
<file preprocess="xml-stripblanks">adw-view-switcher-button.ui</file>
diff --git a/src/adwaita.h b/src/adwaita.h
index 509a9740..6707b57c 100644
--- a/src/adwaita.h
+++ b/src/adwaita.h
@@ -64,6 +64,7 @@ G_BEGIN_DECLS
#include "adw-swipe-tracker.h"
#include "adw-swipeable.h"
#include "adw-tab-bar.h"
+#include "adw-tab-button.h"
#include "adw-tab-view.h"
#include "adw-timed-animation.h"
#include "adw-toast-overlay.h"
diff --git a/src/icons/scalable/status/adw-tab-counter-symbolic.svg
b/src/icons/scalable/status/adw-tab-counter-symbolic.svg
new file mode 100644
index 00000000..5837085c
--- /dev/null
+++ b/src/icons/scalable/status/adw-tab-counter-symbolic.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ version="1.1"
+ id="svg7384"
+ height="16"
+ sodipodi:docname="tab-counter-symbolic.svg"
+ inkscape:version="0.92.4 5da689c313, 2019-01-14">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ id="namedview8"
+ showgrid="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:zoom="11.313708"
+ inkscape:cx="-14.248148"
+ inkscape:cy="15.003638"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g4572">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4519" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata90">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Gnome Symbolic Icon Theme</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <title
+ id="title9167">Gnome Symbolic Icon Theme</title>
+ <defs
+ id="defs7386" />
+ <g
+ id="g4572">
+ <path
+
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;
stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 2.1992188,0 C 0.94446612,0 0,1.0997689 0,2.3183594 V 13.681641 C 0,14.900231 0.94447706,16
2.1992188,16 H 13.800781 C 15.055523,16 16,14.90024 16,13.681641 V 2.3183594 C 16,1.0997598 15.055534,0
13.800781,0 Z m 0,2 H 13.800781 C 13.874369,2 14,2.0752716 14,2.3183594 V 13.681641 C 14,13.924729
13.87438,14 13.800781,14 H 2.1992188 C 2.1256204,14 2,13.924738 2,13.681641 V 2.3183594 C 2,2.0752625
2.1256314,2 2.1992188,2 Z"
+ id="rect11749-5-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssssssssssss" />
+ </g>
+</svg>
diff --git a/src/icons/scalable/status/adw-tab-overflow-symbolic.svg
b/src/icons/scalable/status/adw-tab-overflow-symbolic.svg
new file mode 100644
index 00000000..602b7ce2
--- /dev/null
+++ b/src/icons/scalable/status/adw-tab-overflow-symbolic.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ height="16"
+ id="svg7384"
+ version="1.1"
+ width="16">
+ <metadata
+ id="metadata90">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Gnome Symbolic Icon Theme</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <title
+ id="title9167">Gnome Symbolic Icon Theme</title>
+ <defs
+ id="defs7386" />
+ <path
+ id="path859"
+ d="M 2.199219,0 C 0.944466,0 0,1.0997689 0,2.3183594 V 13.681641 C 0,14.900231 0.944477,16 2.199219,16
H 13.80078 C 15.05552,16 16,14.90024 16,13.681641 V 2.3183594 C 16,1.0997598 15.05553,0 13.80078,0 Z m 0,2 H
13.80078 C 13.87437,2 14,2.0752716 14,2.3183594 V 13.681641 C 14,13.924729 13.87438,14 13.80078,14 H 2.199219
C 2.12562,14 2,13.924738 2,13.681641 V 2.3183594 C 2,2.0752625 2.125631,2 2.199219,2 Z"
+
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#241f31;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;st
roke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
/>
+ <g
+ transform="translate(20)"
+ id="text863"
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:'Cantarell
Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#241f31;fill-opacity:1;stroke:none"
+ aria-label="∞">
+ <path
+ id="path880"
+ d="m -14.519998,10.488 c 1.14,0 1.836,-0.66 2.388,-1.44 0.504,0.78 1.176,1.44 2.388,1.44 1.572,0
2.628,-1.068 2.628,-2.64 0,-1.488 -0.972,-2.472 -2.376,-2.472 -1.104,0 -1.8,0.624 -2.352,1.356 -0.48,-0.732
-1.14,-1.356 -2.352,-1.356 -1.596,0 -2.688,1.056 -2.688,2.64 0,1.476 0.972,2.472 2.364,2.472 z m -0.804,-2.58
c 0,-0.744 0.396,-1.236 1.056,-1.236 0.744,0 1.152,0.624 1.56,1.38 -0.42,0.636 -0.864,1.14 -1.524,1.14
-0.672,0 -1.092,-0.516 -1.092,-1.284 z m 5.544,-1.236 c 0.648,0 1.104,0.492 1.104,1.32 0,0.72 -0.36,1.2
-1.02,1.2 -0.78,0 -1.176,-0.672 -1.572,-1.452 0.408,-0.6 0.852,-1.068 1.488,-1.068 z" />
+ </g>
+</svg>
diff --git a/src/meson.build b/src/meson.build
index 54664c1e..dd6536a0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -125,6 +125,7 @@ src_headers = [
'adw-swipe-tracker.h',
'adw-swipeable.h',
'adw-tab-bar.h',
+ 'adw-tab-button.h',
'adw-tab-view.h',
'adw-timed-animation.h',
'adw-toast.h',
@@ -189,6 +190,7 @@ src_sources = [
'adw-swipe-tracker.c',
'adw-swipeable.c',
'adw-tab-bar.c',
+ 'adw-tab-button.c',
'adw-tab-view.c',
'adw-timed-animation.c',
'adw-toast.c',
diff --git a/src/stylesheet/widgets/_buttons.scss b/src/stylesheet/widgets/_buttons.scss
index 5f1ee606..3e1f78dd 100644
--- a/src/stylesheet/widgets/_buttons.scss
+++ b/src/stylesheet/widgets/_buttons.scss
@@ -598,3 +598,14 @@ buttoncontent {
}
}
}
+
+tabbutton {
+ label {
+ font-weight: 800;
+ font-size: 8pt;
+
+ &.small {
+ font-size: 6pt;
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]