[libadwaita/ebassi/tagged-entry: 13/20] Add AdwTagWidget
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/ebassi/tagged-entry: 13/20] Add AdwTagWidget
- Date: Mon, 14 Mar 2022 18:46:41 +0000 (UTC)
commit 7d2e0e501bd757051b55f70651a0625973df5523
Author: Emmanuele Bassi <ebassi gnome org>
Date: Fri Mar 4 18:47:07 2022 +0000
Add AdwTagWidget
The AdwTagWidget is a representation of an AdwTag.
src/adw-tag-widget-private.h | 22 +++++
src/adw-tag-widget.c | 226 +++++++++++++++++++++++++++++++++++++++++++
src/adw-tag-widget.ui | 31 ++++++
src/meson.build | 1 +
4 files changed, 280 insertions(+)
---
diff --git a/src/adw-tag-widget-private.h b/src/adw-tag-widget-private.h
new file mode 100644
index 00000000..a08880a6
--- /dev/null
+++ b/src/adw-tag-widget-private.h
@@ -0,0 +1,22 @@
+/* adw-tag-widget-private.h
+ *
+ * SPDX-FileCopyrightText: 2022 Emmanuele Bassi
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "adw-tag.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ADW_TYPE_TAG_WIDGET (adw_tag_widget_get_type())
+
+G_DECLARE_FINAL_TYPE (AdwTagWidget, adw_tag_widget, ADW, TAG_WIDGET, GtkWidget)
+
+AdwTag *adw_tag_widget_get_tag (AdwTagWidget *self);
+
+G_END_DECLS
diff --git a/src/adw-tag-widget.c b/src/adw-tag-widget.c
new file mode 100644
index 00000000..74006075
--- /dev/null
+++ b/src/adw-tag-widget.c
@@ -0,0 +1,226 @@
+/* adw-tag-widget.c
+ *
+ * SPDX-FileCopyrightText: 2022 Emmanuele Bassi
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "adw-tag-widget-private.h"
+
+#include "adw-tag-private.h"
+
+struct _AdwTagWidget
+{
+ GtkWidget parent_instance;
+
+ AdwTag *tag;
+
+ GtkWidget *icon;
+ GtkWidget *label;
+ GtkWidget *close_button;
+};
+
+struct _AdwTagWidgetClass
+{
+ GtkWidgetClass parent_class;
+};
+
+enum
+{
+ PROP_TAG = 1,
+ N_PROPS
+};
+
+static GParamSpec *obj_props[N_PROPS];
+
+enum
+{
+ CLOSED,
+
+ LAST_SIGNAL
+};
+
+static guint obj_signals[LAST_SIGNAL];
+
+
+G_DEFINE_TYPE (AdwTagWidget, adw_tag_widget, GTK_TYPE_WIDGET)
+
+static void
+adw_tag_widget__close_clicked (AdwTagWidget *self)
+{
+ g_signal_emit (self, obj_signals[CLOSED], 0, self->tag);
+}
+
+static void
+update_tag_icon (AdwTagWidget *self)
+{
+ gtk_widget_set_visible (self->icon, adw_tag_has_icon (self->tag));
+
+ AdwTagIconType icon_type = adw_tag_get_icon_type (self->tag);
+ switch (icon_type) {
+ case ADW_TAG_ICON_GICON:
+ {
+ GIcon *icon = adw_tag_get_gicon (self->tag);
+ gtk_image_set_from_gicon (GTK_IMAGE (self->icon), icon);
+ }
+ break;
+
+ case ADW_TAG_ICON_PAINTABLE:
+ {
+ GdkPaintable *paintable = adw_tag_get_paintable (self->tag);
+ gtk_image_set_from_paintable (GTK_IMAGE (self->icon), paintable);
+ }
+ break;
+
+ case ADW_TAG_ICON_NONE:
+ default:
+ break;
+ }
+}
+
+static void
+adw_tag_widget_set_tag (AdwTagWidget *self,
+ AdwTag *tag)
+{
+ if (g_set_object (&self->tag, tag)) {
+ if (self->tag != NULL) {
+ g_object_bind_property (self->tag, "show-close",
+ self->close_button, "visible",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+ g_object_bind_property (self->tag, "label",
+ self->label, "label",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+ update_tag_icon (self);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TAG]);
+ }
+}
+
+static void
+adw_tag_widget__click_released (AdwTagWidget *self,
+ guint n_press,
+ double x,
+ double y,
+ GtkGesture *gesture)
+{
+ gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_CLAIMED);
+
+ const char *action_name = adw_tag_get_action_name (self->tag);
+ if (action_name == NULL)
+ return;
+
+ gtk_widget_activate_action_variant (GTK_WIDGET (self),
+ action_name,
+ adw_tag_get_action_target_value (self->tag));
+}
+
+static void
+adw_tag_widget_dispose (GObject *gobject)
+{
+ AdwTagWidget *self = ADW_TAG_WIDGET (gobject);
+
+ g_clear_pointer (&self->icon, gtk_widget_unparent);
+ g_clear_pointer (&self->label, gtk_widget_unparent);
+ g_clear_pointer (&self->close_button, gtk_widget_unparent);
+
+ g_clear_object (&self->tag);
+
+ G_OBJECT_CLASS (adw_tag_widget_parent_class)->dispose (gobject);
+}
+
+static void
+adw_tag_widget_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AdwTagWidget *self = ADW_TAG_WIDGET (gobject);
+
+ switch (prop_id) {
+ case PROP_TAG:
+ adw_tag_widget_set_tag (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ }
+}
+
+static void
+adw_tag_widget_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AdwTagWidget *self = ADW_TAG_WIDGET (gobject);
+
+ switch (prop_id) {
+ case PROP_TAG:
+ g_value_set_object (value, self->tag);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ }
+}
+
+static void
+adw_tag_widget_class_init (AdwTagWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->set_property = adw_tag_widget_set_property;
+ gobject_class->get_property = adw_tag_widget_get_property;
+ gobject_class->dispose = adw_tag_widget_dispose;
+
+ obj_props[PROP_TAG] =
+ g_param_spec_object ("tag", NULL, NULL, ADW_TYPE_TAG,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (gobject_class, N_PROPS, obj_props);
+
+ obj_signals[CLOSED] =
+ g_signal_new ("closed",
+ ADW_TYPE_TAG_WIDGET,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE, 1, ADW_TYPE_TAG);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Adwaita/ui/adw-tag-widget.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, AdwTagWidget, icon);
+ gtk_widget_class_bind_template_child (widget_class, AdwTagWidget, label);
+ gtk_widget_class_bind_template_child (widget_class, AdwTagWidget, close_button);
+
+ gtk_widget_class_bind_template_callback (widget_class, adw_tag_widget__click_released);
+ gtk_widget_class_bind_template_callback (widget_class, adw_tag_widget__close_clicked);
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
+ gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
+ gtk_widget_class_set_css_name (widget_class, "tag");
+}
+
+static void
+adw_tag_widget_init (AdwTagWidget *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+AdwTag *
+adw_tag_widget_get_tag (AdwTagWidget *self)
+{
+ g_return_val_if_fail (ADW_IS_TAG_WIDGET (self), NULL);
+
+ return self->tag;
+}
diff --git a/src/adw-tag-widget.ui b/src/adw-tag-widget.ui
new file mode 100644
index 00000000..2b628c98
--- /dev/null
+++ b/src/adw-tag-widget.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="libadwaita">
+ <requires lib="gtk" version="4.0"/>
+ <template class="AdwTagWidget">
+ <child>
+ <object class="GtkGestureClick">
+ <signal name="released" handler="adw_tag_widget__click_released" swapped="yes"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="icon">
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="ellipsize">end</property>
+ <property name="max-width-chars">12</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="icon-name">window-close-symbolic</property>
+ <signal name="clicked" handler="adw_tag_widget__close_clicked" swapped="yes"/>
+ <style>
+ <class name="flat"/>
+ <class name="circular"/>
+ </style>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/meson.build b/src/meson.build
index 6da36a62..6c1e5bee 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -182,6 +182,7 @@ src_sources = [
'adw-tab-bar.c',
'adw-tab-view.c',
'adw-tag.c',
+ 'adw-tag-widget.c',
'adw-timed-animation.c',
'adw-toast.c',
'adw-toast-overlay.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]