[libgd: 2/2] Make GdTaggedEntryTag a GObject
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgd: 2/2] Make GdTaggedEntryTag a GObject
- Date: Fri, 19 Jul 2013 10:13:13 +0000 (UTC)
commit 7f080984bf6a92212def9fb8aa0f6c0f9979b57e
Author: Ignacio Casal Quinteiro <ignacio casal nice-software com>
Date: Sun Jul 14 11:43:05 2013 +0200
Make GdTaggedEntryTag a GObject
libgd/gd-tagged-entry.c | 417 ++++++++++++++++++++++++++++-------------------
libgd/gd-tagged-entry.h | 87 ++++++-----
test-tagged-entry.c | 37 ++++-
3 files changed, 336 insertions(+), 205 deletions(-)
---
diff --git a/libgd/gd-tagged-entry.c b/libgd/gd-tagged-entry.c
index 59fe5d7..93b2675 100644
--- a/libgd/gd-tagged-entry.c
+++ b/libgd/gd-tagged-entry.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Red Hat, Inc.
+ * Copyright (c) 2013 Ignacio Casal Quinteiro
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -23,22 +24,20 @@
#include <math.h>
-G_DEFINE_TYPE (GdTaggedEntry, gd_tagged_entry, GTK_TYPE_SEARCH_ENTRY)
-
#define BUTTON_INTERNAL_SPACING 6
-typedef struct {
+struct _GdTaggedEntryTagPrivate {
+ GdTaggedEntry *entry;
GdkWindow *window;
PangoLayout *layout;
- gchar *id;
gchar *label;
gchar *style;
gboolean has_close_button;
GdkPixbuf *close_pixbuf;
GtkStateFlags last_button_state;
-} GdTaggedEntryTag;
+};
struct _GdTaggedEntryPrivate {
GList *tags;
@@ -62,8 +61,20 @@ enum {
NUM_PROPERTIES
};
+enum {
+ PROP_TAG_0,
+ PROP_TAG_LABEL,
+ PROP_TAG_HAS_CLOSE_BUTTON,
+ PROP_TAG_STYLE,
+ NUM_TAG_PROPERTIES
+};
+
+G_DEFINE_TYPE (GdTaggedEntry, gd_tagged_entry, GTK_TYPE_SEARCH_ENTRY)
+G_DEFINE_TYPE (GdTaggedEntryTag, gd_tagged_entry_tag, G_TYPE_OBJECT)
+
static guint signals[LAST_SIGNAL] = { 0, };
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+static GParamSpec *tag_properties[NUM_TAG_PROPERTIES] = { NULL, };
static void gd_tagged_entry_get_text_area_size (GtkEntry *entry,
gint *x,
@@ -94,7 +105,7 @@ gd_tagged_entry_tag_ensure_close_pixbuf (GdTaggedEntryTag *tag,
GtkIconInfo *info;
gint icon_size;
- if (tag->close_pixbuf != NULL)
+ if (tag->priv->close_pixbuf != NULL)
return;
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU,
@@ -105,7 +116,7 @@ gd_tagged_entry_tag_ensure_close_pixbuf (GdTaggedEntryTag *tag,
icon_size,
GTK_ICON_LOOKUP_GENERIC_FALLBACK);
- tag->close_pixbuf =
+ tag->priv->close_pixbuf =
gtk_icon_info_load_symbolic_for_context (info, context,
NULL, NULL);
@@ -178,11 +189,11 @@ static void
gd_tagged_entry_tag_ensure_layout (GdTaggedEntryTag *tag,
GdTaggedEntry *entry)
{
- if (tag->layout != NULL)
+ if (tag->priv->layout != NULL)
return;
- tag->layout = pango_layout_new (gtk_widget_get_pango_context (GTK_WIDGET (entry)));
- pango_layout_set_text (tag->layout, tag->label, -1);
+ tag->priv->layout = pango_layout_new (gtk_widget_get_pango_context (GTK_WIDGET (entry)));
+ pango_layout_set_text (tag->priv->layout, tag->priv->label, -1);
}
static GtkStateFlags
@@ -229,7 +240,7 @@ gd_tagged_entry_tag_get_context (GdTaggedEntryTag *tag,
path = gtk_widget_path_copy (gtk_widget_get_path (widget));
pos = gtk_widget_path_append_type (path, GD_TYPE_TAGGED_ENTRY);
- gtk_widget_path_iter_add_class (path, pos, tag->style);
+ gtk_widget_path_iter_add_class (path, pos, tag->priv->style);
gtk_style_context_set_path (retval, path);
@@ -249,7 +260,7 @@ gd_tagged_entry_tag_get_width (GdTaggedEntryTag *tag,
gint button_width;
gd_tagged_entry_tag_ensure_layout (tag, entry);
- pango_layout_get_pixel_size (tag->layout, &layout_width, NULL);
+ pango_layout_get_pixel_size (tag->priv->layout, &layout_width, NULL);
context = gd_tagged_entry_tag_get_context (tag, entry);
state = gd_tagged_entry_tag_get_state (tag, entry);
@@ -263,8 +274,8 @@ gd_tagged_entry_tag_get_width (GdTaggedEntryTag *tag,
g_object_unref (context);
button_width = 0;
- if (entry->priv->button_visible && tag->has_close_button)
- button_width = gdk_pixbuf_get_width (tag->close_pixbuf) + BUTTON_INTERNAL_SPACING;
+ if (entry->priv->button_visible && tag->priv->has_close_button)
+ button_width = gdk_pixbuf_get_width (tag->priv->close_pixbuf) + BUTTON_INTERNAL_SPACING;
return layout_width + button_padding.left + button_padding.right +
button_border.left + button_border.right +
@@ -303,8 +314,8 @@ gd_tagged_entry_tag_get_relative_allocations (GdTaggedEntryTag *tag,
GtkBorder padding, border;
GtkStateFlags state;
- width = gdk_window_get_width (tag->window);
- height = gdk_window_get_height (tag->window);
+ width = gdk_window_get_width (tag->priv->window);
+ height = gdk_window_get_height (tag->priv->window);
state = gd_tagged_entry_tag_get_state (tag, entry);
gtk_style_context_get_margin (context, state, &padding);
@@ -325,15 +336,15 @@ gd_tagged_entry_tag_get_relative_allocations (GdTaggedEntryTag *tag,
gtk_style_context_get_border (context, state, &border);
gd_tagged_entry_tag_ensure_layout (tag, entry);
- pango_layout_get_pixel_size (tag->layout, &layout_width, &layout_height);
+ pango_layout_get_pixel_size (tag->priv->layout, &layout_width, &layout_height);
layout_allocation.x += border.left + padding.left;
layout_allocation.y += (layout_allocation.height - layout_height) / 2;
- if (entry->priv->button_visible && tag->has_close_button)
+ if (entry->priv->button_visible && tag->priv->has_close_button)
{
- pix_width = gdk_pixbuf_get_width (tag->close_pixbuf);
- pix_height = gdk_pixbuf_get_height (tag->close_pixbuf);
+ pix_width = gdk_pixbuf_get_width (tag->priv->close_pixbuf);
+ pix_height = gdk_pixbuf_get_height (tag->priv->close_pixbuf);
}
else
{
@@ -363,7 +374,7 @@ gd_tagged_entry_tag_event_is_button (GdTaggedEntryTag *tag,
GtkAllocation button_allocation;
GtkStyleContext *context;
- if (!entry->priv->button_visible || !tag->has_close_button)
+ if (!entry->priv->button_visible || !tag->priv->has_close_button)
return FALSE;
context = gd_tagged_entry_tag_get_context (tag, entry);
@@ -397,7 +408,7 @@ gd_tagged_entry_tag_draw (GdTaggedEntryTag *tag,
&button_allocation);
cairo_save (cr);
- gtk_cairo_transform_to_window (cr, GTK_WIDGET (entry), tag->window);
+ gtk_cairo_transform_to_window (cr, GTK_WIDGET (entry), tag->priv->window);
gtk_style_context_save (context);
@@ -412,11 +423,11 @@ gd_tagged_entry_tag_draw (GdTaggedEntryTag *tag,
gtk_render_layout (context, cr,
layout_allocation.x, layout_allocation.y,
- tag->layout);
+ tag->priv->layout);
gtk_style_context_restore (context);
- if (!entry->priv->button_visible || !tag->has_close_button)
+ if (!entry->priv->button_visible || !tag->priv->has_close_button)
goto done;
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
@@ -426,12 +437,12 @@ gd_tagged_entry_tag_draw (GdTaggedEntryTag *tag,
/* if the state changed since last time we draw the pixbuf,
* clear and redraw it.
*/
- if (state != tag->last_button_state)
+ if (state != tag->priv->last_button_state)
{
- g_clear_object (&tag->close_pixbuf);
+ g_clear_object (&tag->priv->close_pixbuf);
gd_tagged_entry_tag_ensure_close_pixbuf (tag, context);
- tag->last_button_state = state;
+ tag->priv->last_button_state = state;
}
gtk_render_background (context, cr,
@@ -442,7 +453,7 @@ gd_tagged_entry_tag_draw (GdTaggedEntryTag *tag,
button_allocation.width, button_allocation.height);
gtk_render_icon (context, cr,
- tag->close_pixbuf,
+ tag->priv->close_pixbuf,
button_allocation.x, button_allocation.y);
done:
@@ -454,12 +465,12 @@ done:
static void
gd_tagged_entry_tag_unrealize (GdTaggedEntryTag *tag)
{
- if (tag->window == NULL)
+ if (tag->priv->window == NULL)
return;
- gdk_window_set_user_data (tag->window, NULL);
- gdk_window_destroy (tag->window);
- tag->window = NULL;
+ gdk_window_set_user_data (tag->priv->window, NULL);
+ gdk_window_destroy (tag->priv->window);
+ tag->priv->window = NULL;
}
static void
@@ -471,7 +482,7 @@ gd_tagged_entry_tag_realize (GdTaggedEntryTag *tag,
gint attributes_mask;
gint tag_width, tag_height;
- if (tag->window != NULL)
+ if (tag->priv->window != NULL)
return;
attributes.window_type = GDK_WINDOW_CHILD;
@@ -489,44 +500,9 @@ gd_tagged_entry_tag_realize (GdTaggedEntryTag *tag,
attributes_mask = GDK_WA_X | GDK_WA_Y;
- tag->window = gdk_window_new (gtk_widget_get_window (widget),
+ tag->priv->window = gdk_window_new (gtk_widget_get_window (widget),
&attributes, attributes_mask);
- gdk_window_set_user_data (tag->window, widget);
-}
-
-static GdTaggedEntryTag *
-gd_tagged_entry_tag_new (const gchar *id,
- const gchar *label,
- const gchar *style,
- gboolean has_close_button)
-{
- GdTaggedEntryTag *tag;
-
- tag = g_slice_new0 (GdTaggedEntryTag);
-
- tag->id = g_strdup (id);
- tag->label = g_strdup (label);
- tag->style = g_strdup (style);
- tag->has_close_button = has_close_button;
- tag->last_button_state = GTK_STATE_FLAG_NORMAL;
-
- return tag;
-}
-
-static void
-gd_tagged_entry_tag_free (gpointer _tag)
-{
- GdTaggedEntryTag *tag = _tag;
-
- if (tag->window != NULL)
- gd_tagged_entry_tag_unrealize (tag);
-
- g_clear_object (&tag->layout);
- g_clear_object (&tag->close_pixbuf);
- g_free (tag->id);
- g_free (tag->label);
-
- g_slice_free (GdTaggedEntryTag, tag);
+ gdk_window_set_user_data (tag->priv->window, widget);
}
static gboolean
@@ -562,7 +538,7 @@ gd_tagged_entry_map (GtkWidget *widget)
for (l = self->priv->tags; l != NULL; l = l->next)
{
tag = l->data;
- gdk_window_show (tag->window);
+ gdk_window_show (tag->priv->window);
}
}
}
@@ -579,7 +555,7 @@ gd_tagged_entry_unmap (GtkWidget *widget)
for (l = self->priv->tags; l != NULL; l = l->next)
{
tag = l->data;
- gdk_window_hide (tag->window);
+ gdk_window_hide (tag->priv->window);
}
GTK_WIDGET_CLASS (gd_tagged_entry_parent_class)->unmap (widget);
@@ -659,7 +635,7 @@ gd_tagged_entry_size_allocate (GtkWidget *widget,
tag = l->data;
gd_tagged_entry_tag_get_size (tag, self, &width, &height);
gd_tagged_entry_tag_get_margin (tag, self, &margin);
- gdk_window_move_resize (tag->window, x, y + margin.top, width, height);
+ gdk_window_move_resize (tag->priv->window, x, y + margin.top, width, height);
x += width;
}
@@ -693,7 +669,7 @@ gd_tagged_entry_finalize (GObject *obj)
if (self->priv->tags != NULL)
{
- g_list_free_full (self->priv->tags, gd_tagged_entry_tag_free);
+ g_list_free_full (self->priv->tags, g_object_unref);
self->priv->tags = NULL;
}
@@ -701,26 +677,6 @@ gd_tagged_entry_finalize (GObject *obj)
}
static GdTaggedEntryTag *
-gd_tagged_entry_find_tag_by_id (GdTaggedEntry *self,
- const gchar *id)
-{
- GdTaggedEntryTag *tag = NULL, *elem;
- GList *l;
-
- for (l = self->priv->tags; l != NULL; l = l->next)
- {
- elem = l->data;
- if (g_strcmp0 (elem->id, id) == 0)
- {
- tag = elem;
- break;
- }
- }
-
- return tag;
-}
-
-static GdTaggedEntryTag *
gd_tagged_entry_find_tag_by_window (GdTaggedEntry *self,
GdkWindow *window)
{
@@ -730,7 +686,7 @@ gd_tagged_entry_find_tag_by_window (GdTaggedEntry *self,
for (l = self->priv->tags; l != NULL; l = l->next)
{
elem = l->data;
- if (elem->window == window)
+ if (elem->priv->window == window)
{
tag = elem;
break;
@@ -802,23 +758,21 @@ gd_tagged_entry_button_release_event (GtkWidget *widget,
{
GdTaggedEntry *self = GD_TAGGED_ENTRY (widget);
GdTaggedEntryTag *tag;
- GQuark id_quark;
tag = gd_tagged_entry_find_tag_by_window (self, event->window);
if (tag != NULL)
{
- id_quark = g_quark_from_string (tag->id);
self->priv->in_child_active = FALSE;
if (gd_tagged_entry_tag_event_is_button (tag, self, event->x, event->y))
{
self->priv->in_child_button_active = FALSE;
- g_signal_emit (self, signals[SIGNAL_TAG_BUTTON_CLICKED], id_quark, tag->id);
+ g_signal_emit (self, signals[SIGNAL_TAG_BUTTON_CLICKED], 0, tag);
}
else
{
- g_signal_emit (self, signals[SIGNAL_TAG_CLICKED], id_quark, tag->id);
+ g_signal_emit (self, signals[SIGNAL_TAG_CLICKED], 0, tag);
}
gtk_widget_queue_draw (widget);
@@ -928,14 +882,14 @@ gd_tagged_entry_class_init (GdTaggedEntryClass *klass)
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
0, NULL, NULL, NULL,
G_TYPE_NONE,
- 1, G_TYPE_STRING);
+ 1, GD_TYPE_TAGGED_ENTRY_TAG);
signals[SIGNAL_TAG_BUTTON_CLICKED] =
g_signal_new ("tag-button-clicked",
GD_TYPE_TAGGED_ENTRY,
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
0, NULL, NULL, NULL,
G_TYPE_NONE,
- 1, G_TYPE_STRING);
+ 1, GD_TYPE_TAGGED_ENTRY_TAG);
properties[PROP_TAG_BUTTON_VISIBLE] =
g_param_spec_boolean ("tag-close-visible", "Tag close icon visibility",
@@ -946,6 +900,108 @@ gd_tagged_entry_class_init (GdTaggedEntryClass *klass)
g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
}
+static void
+gd_tagged_entry_tag_init (GdTaggedEntryTag *self)
+{
+ GdTaggedEntryTagPrivate *priv;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GD_TYPE_TAGGED_ENTRY_TAG, GdTaggedEntryTagPrivate);
+ priv = self->priv;
+
+ priv->last_button_state = GTK_STATE_FLAG_NORMAL;
+}
+
+static void
+gd_tagged_entry_tag_finalize (GObject *obj)
+{
+ GdTaggedEntryTag *tag = GD_TAGGED_ENTRY_TAG (obj);
+ GdTaggedEntryTagPrivate *priv = tag->priv;
+
+ if (priv->window != NULL)
+ gd_tagged_entry_tag_unrealize (tag);
+
+ g_clear_object (&priv->layout);
+ g_clear_object (&priv->close_pixbuf);
+ g_free (priv->label);
+ g_free (priv->style);
+
+ G_OBJECT_CLASS (gd_tagged_entry_tag_parent_class)->finalize (obj);
+}
+
+static void
+gd_tagged_entry_tag_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdTaggedEntryTag *self = GD_TAGGED_ENTRY_TAG (object);
+
+ switch (property_id)
+ {
+ case PROP_TAG_LABEL:
+ g_value_set_string (value, gd_tagged_entry_tag_get_label (self));
+ break;
+ case PROP_TAG_HAS_CLOSE_BUTTON:
+ g_value_set_boolean (value, gd_tagged_entry_tag_get_has_close_button (self));
+ break;
+ case PROP_TAG_STYLE:
+ g_value_set_string (value, gd_tagged_entry_tag_get_style (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gd_tagged_entry_tag_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdTaggedEntryTag *self = GD_TAGGED_ENTRY_TAG (object);
+
+ switch (property_id)
+ {
+ case PROP_TAG_LABEL:
+ gd_tagged_entry_tag_set_label (self, g_value_get_string (value));
+ break;
+ case PROP_TAG_HAS_CLOSE_BUTTON:
+ gd_tagged_entry_tag_set_has_close_button (self, g_value_get_boolean (value));
+ break;
+ case PROP_TAG_STYLE:
+ gd_tagged_entry_tag_set_style (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gd_tagged_entry_tag_class_init (GdTaggedEntryTagClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->finalize = gd_tagged_entry_tag_finalize;
+ oclass->set_property = gd_tagged_entry_tag_set_property;
+ oclass->get_property = gd_tagged_entry_tag_get_property;
+
+ tag_properties[PROP_TAG_LABEL] =
+ g_param_spec_string ("label", "Label",
+ "Text to show on the tag.", NULL,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ tag_properties[PROP_TAG_HAS_CLOSE_BUTTON] =
+ g_param_spec_boolean ("has-close-button", "Tag has a close button",
+ "Whether the tag has a close button.", TRUE,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ tag_properties[PROP_TAG_STYLE] =
+ g_param_spec_string ("style", "Style",
+ "Style of the tag.", "documents-entry-tag",
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_type_class_add_private (klass, sizeof (GdTaggedEntryTagPrivate));
+ g_object_class_install_properties (oclass, NUM_TAG_PROPERTIES, tag_properties);
+}
+
GdTaggedEntry *
gd_tagged_entry_new (void)
{
@@ -953,27 +1009,21 @@ gd_tagged_entry_new (void)
}
gboolean
-gd_tagged_entry_insert_tag (GdTaggedEntry *self,
- const gchar *id,
- const gchar *name,
- const gchar *style,
- gboolean has_close_button,
- gint position)
+gd_tagged_entry_insert_tag (GdTaggedEntry *self,
+ GdTaggedEntryTag *tag,
+ gint position)
{
- GdTaggedEntryTag *tag;
-
- if (gd_tagged_entry_find_tag_by_id (self, id) != NULL)
+ if (g_list_find (self->priv->tags, tag) != NULL)
return FALSE;
- has_close_button = has_close_button != FALSE;
- tag = gd_tagged_entry_tag_new (id, name, style, has_close_button);
+ tag->priv->entry = self;
- self->priv->tags = g_list_insert (self->priv->tags, tag, position);
+ self->priv->tags = g_list_insert (self->priv->tags, g_object_ref (tag), position);
if (gtk_widget_get_mapped (GTK_WIDGET (self)))
{
gd_tagged_entry_tag_realize (tag, self);
- gdk_window_show_unraised (tag->window);
+ gdk_window_show_unraised (tag->priv->window);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
@@ -982,88 +1032,127 @@ gd_tagged_entry_insert_tag (GdTaggedEntry *self,
}
gboolean
-gd_tagged_entry_add_tag (GdTaggedEntry *self,
- const gchar *id,
- const gchar *name,
- const gchar *style,
- gboolean has_close_button)
+gd_tagged_entry_add_tag (GdTaggedEntry *self,
+ GdTaggedEntryTag *tag)
{
- return gd_tagged_entry_insert_tag (self, id, name, style, has_close_button, -1);
+ return gd_tagged_entry_insert_tag (self, tag, -1);
}
gboolean
-gd_tagged_entry_remove_tag (GdTaggedEntry *self,
- const gchar *id)
+gd_tagged_entry_remove_tag (GdTaggedEntry *self,
+ GdTaggedEntryTag *tag)
{
- GdTaggedEntryTag *tag;
- gboolean res = FALSE;
+ if (!g_list_find (self->priv->tags, tag))
+ return FALSE;
- tag = gd_tagged_entry_find_tag_by_id (self, id);
+ self->priv->tags = g_list_remove (self->priv->tags, tag);
+ g_object_unref (tag);
- if (tag != NULL)
- {
- res = TRUE;
- self->priv->tags = g_list_remove (self->priv->tags, tag);
- gd_tagged_entry_tag_free (tag);
+ gtk_widget_queue_resize (GTK_WIDGET (self));
- gtk_widget_queue_resize (GTK_WIDGET (self));
- }
+ return TRUE;
+}
- return res;
+GdTaggedEntryTag *
+gd_tagged_entry_tag_new (const gchar *label)
+{
+ return g_object_new (GD_TYPE_TAGGED_ENTRY_TAG, "label", label, NULL);
}
-gboolean
-gd_tagged_entry_set_tag_label (GdTaggedEntry *self,
- const gchar *tag_id,
+void
+gd_tagged_entry_tag_set_label (GdTaggedEntryTag *tag,
const gchar *label)
{
- GdTaggedEntryTag *tag;
- gboolean res = FALSE;
+ GdTaggedEntryTagPrivate *priv;
- tag = gd_tagged_entry_find_tag_by_id (self, tag_id);
+ g_return_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag));
- if (tag != NULL)
+ priv = tag->priv;
+
+ if (g_strcmp0 (priv->label, label) != 0)
{
- res = TRUE;
+ GtkWidget *entry;
- if (g_strcmp0 (tag->label, label) != 0)
- {
- g_free (tag->label);
- tag->label = g_strdup (label);
- g_clear_object (&tag->layout);
+ g_free (priv->label);
+ priv->label = g_strdup (label);
+ g_clear_object (&priv->layout);
- gtk_widget_queue_resize (GTK_WIDGET (self));
- }
+ entry = GTK_WIDGET (tag->priv->entry);
+ if (entry)
+ gtk_widget_queue_resize (entry);
}
+}
+
+const gchar *
+gd_tagged_entry_tag_get_label (GdTaggedEntryTag *tag)
+{
+ g_return_val_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag), NULL);
- return res;
+ return tag->priv->label;
}
-gboolean
-gd_tagged_entry_set_tag_has_close_button (GdTaggedEntry *self,
- const gchar *tag_id,
+void
+gd_tagged_entry_tag_set_has_close_button (GdTaggedEntryTag *tag,
gboolean has_close_button)
{
- GdTaggedEntryTag *tag;
- gboolean res = FALSE;
+ GdTaggedEntryTagPrivate *priv;
+
+ g_return_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag));
+
+ priv = tag->priv;
has_close_button = has_close_button != FALSE;
- tag = gd_tagged_entry_find_tag_by_id (self, tag_id);
+ if (tag->priv->has_close_button != has_close_button)
+ {
+ GtkWidget *entry;
- if (tag != NULL)
+ tag->priv->has_close_button = has_close_button;
+ g_clear_object (&tag->priv->layout);
+
+ entry = GTK_WIDGET (tag->priv->entry);
+ if (entry)
+ gtk_widget_queue_resize (entry);
+ }
+}
+
+gboolean
+gd_tagged_entry_tag_get_has_close_button (GdTaggedEntryTag *tag)
+{
+ g_return_val_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag), FALSE);
+
+ return tag->priv->has_close_button;
+}
+
+void
+gd_tagged_entry_tag_set_style (GdTaggedEntryTag *tag,
+ const gchar *style)
+{
+ GdTaggedEntryTagPrivate *priv;
+
+ g_return_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag));
+
+ priv = tag->priv;
+
+ if (g_strcmp0 (priv->style, style) != 0)
{
- res = TRUE;
+ GtkWidget *entry;
- if (tag->has_close_button != has_close_button)
- {
- tag->has_close_button = has_close_button;
- g_clear_object (&tag->layout);
+ g_free (priv->style);
+ priv->style = g_strdup (style);
+ g_clear_object (&priv->layout);
- gtk_widget_queue_resize (GTK_WIDGET (self));
- }
+ entry = GTK_WIDGET (tag->priv->entry);
+ if (entry)
+ gtk_widget_queue_resize (entry);
}
+}
+
+const gchar *
+gd_tagged_entry_tag_get_style (GdTaggedEntryTag *tag)
+{
+ g_return_val_if_fail (GD_IS_TAGGED_ENTRY_TAG (tag), NULL);
- return res;
+ return tag->priv->style;
}
void
diff --git a/libgd/gd-tagged-entry.h b/libgd/gd-tagged-entry.h
index a754726..18b9d0f 100644
--- a/libgd/gd-tagged-entry.h
+++ b/libgd/gd-tagged-entry.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2011 Red Hat, Inc.
+ * Copyright (c) 2013 Ignacio Casal Quinteiro
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -29,31 +30,20 @@
G_BEGIN_DECLS
#define GD_TYPE_TAGGED_ENTRY gd_tagged_entry_get_type()
-
-#define GD_TAGGED_ENTRY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GD_TYPE_TAGGED_ENTRY, GdTaggedEntry))
-
-#define GD_TAGGED_ENTRY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GD_TYPE_TAGGED_ENTRY, GdTaggedEntryClass))
-
-#define GD_IS_TAGGED_ENTRY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GD_TYPE_TAGGED_ENTRY))
-
-#define GD_IS_TAGGED_ENTRY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GD_TYPE_TAGGED_ENTRY))
-
-#define GD_TAGGED_ENTRY_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GD_TYPE_TAGGED_ENTRY, GdTaggedEntryClass))
+#define GD_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GD_TYPE_TAGGED_ENTRY, GdTaggedEntry))
+#define GD_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GD_TYPE_TAGGED_ENTRY,
GdTaggedEntryClass))
+#define GD_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GD_TYPE_TAGGED_ENTRY))
+#define GD_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GD_TYPE_TAGGED_ENTRY))
+#define GD_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GD_TYPE_TAGGED_ENTRY,
GdTaggedEntryClass))
typedef struct _GdTaggedEntry GdTaggedEntry;
typedef struct _GdTaggedEntryClass GdTaggedEntryClass;
typedef struct _GdTaggedEntryPrivate GdTaggedEntryPrivate;
+typedef struct _GdTaggedEntryTag GdTaggedEntryTag;
+typedef struct _GdTaggedEntryTagClass GdTaggedEntryTagClass;
+typedef struct _GdTaggedEntryTagPrivate GdTaggedEntryTagPrivate;
+
struct _GdTaggedEntry
{
GtkSearchEntry parent;
@@ -66,6 +56,25 @@ struct _GdTaggedEntryClass
GtkSearchEntryClass parent_class;
};
+#define GD_TYPE_TAGGED_ENTRY_TAG gd_tagged_entry_tag_get_type()
+#define GD_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GD_TYPE_TAGGED_ENTRY_TAG,
GdTaggedEntryTag))
+#define GD_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GD_TYPE_TAGGED_ENTRY_TAG,
GdTaggedEntryTagClass))
+#define GD_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GD_TYPE_TAGGED_ENTRY_TAG))
+#define GD_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GD_TYPE_TAGGED_ENTRY_TAG))
+#define GD_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GD_TYPE_TAGGED_ENTRY_TAG,
GdTaggedEntryTagClass))
+
+struct _GdTaggedEntryTag
+{
+ GObject parent;
+
+ GdTaggedEntryTagPrivate *priv;
+};
+
+struct _GdTaggedEntryTagClass
+{
+ GObjectClass parent_class;
+};
+
GType gd_tagged_entry_get_type (void) G_GNUC_CONST;
GdTaggedEntry *gd_tagged_entry_new (void);
@@ -74,29 +83,31 @@ void gd_tagged_entry_set_tag_button_visible (GdTaggedEntry *self,
gboolean visible);
gboolean gd_tagged_entry_get_tag_button_visible (GdTaggedEntry *self);
-gboolean gd_tagged_entry_insert_tag (GdTaggedEntry *self,
- const gchar *id,
- const gchar *name,
- const gchar *style,
- gboolean has_close_button,
- gint position);
+gboolean gd_tagged_entry_insert_tag (GdTaggedEntry *self,
+ GdTaggedEntryTag *tag,
+ gint position);
-gboolean gd_tagged_entry_add_tag (GdTaggedEntry *self,
- const gchar *id,
- const gchar *name,
- const gchar *style,
- gboolean has_close_button);
+gboolean gd_tagged_entry_add_tag (GdTaggedEntry *self,
+ GdTaggedEntryTag *tag);
gboolean gd_tagged_entry_remove_tag (GdTaggedEntry *self,
- const gchar *id);
+ GdTaggedEntryTag *tag);
+
+GType gd_tagged_entry_tag_get_type (void) G_GNUC_CONST;
+
+GdTaggedEntryTag *gd_tagged_entry_tag_new (const gchar *label);
+
+void gd_tagged_entry_tag_set_label (GdTaggedEntryTag *tag,
+ const gchar *label);
+const gchar *gd_tagged_entry_tag_get_label (GdTaggedEntryTag *tag);
-gboolean gd_tagged_entry_set_tag_label (GdTaggedEntry *self,
- const gchar *tag_id,
- const gchar *label);
+void gd_tagged_entry_tag_set_has_close_button (GdTaggedEntryTag *tag,
+ gboolean has_close_button);
+gboolean gd_tagged_entry_tag_get_has_close_button (GdTaggedEntryTag *tag);
-gboolean gd_tagged_entry_set_tag_has_close_button (GdTaggedEntry *self,
- const gchar *tag_id,
- gboolean has_close_button);
+void gd_tagged_entry_tag_set_style (GdTaggedEntryTag *tag,
+ const gchar *style);
+const gchar *gd_tagged_entry_tag_get_style (GdTaggedEntryTag *tag);
G_END_DECLS
diff --git a/test-tagged-entry.c b/test-tagged-entry.c
index 7dba4a0..fa52bbb 100644
--- a/test-tagged-entry.c
+++ b/test-tagged-entry.c
@@ -1,11 +1,28 @@
#include <gtk/gtk.h>
#include <libgd/gd-tagged-entry.h>
+static void
+on_tag_clicked (GdTaggedEntry *entry,
+ GdTaggedEntryTag *tag,
+ gpointer useless)
+{
+ g_print ("tag clicked: %s\n", gd_tagged_entry_tag_get_label (tag));
+}
+
+static void
+on_tag_button_clicked (GdTaggedEntry *entry,
+ GdTaggedEntryTag *tag,
+ gpointer useless)
+{
+ g_print ("tag button clicked: %s\n", gd_tagged_entry_tag_get_label (tag));
+}
+
gint
main (gint argc,
gchar ** argv)
{
GtkWidget *window, *box, *entry;
+ GdTaggedEntryTag *tag;
gtk_init (&argc, &argv);
@@ -16,11 +33,25 @@ main (gint argc,
gtk_container_add (GTK_CONTAINER (window), box);
entry = GTK_WIDGET (gd_tagged_entry_new ());
+ g_signal_connect(entry, "tag-clicked",
+ G_CALLBACK (on_tag_clicked), NULL);
+ g_signal_connect(entry, "tag-button-clicked",
+ G_CALLBACK (on_tag_button_clicked), NULL);
gtk_container_add (GTK_CONTAINER (box), entry);
- gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (entry), "tag1", "Blah1", "documents-entry-tag", TRUE);
- gd_tagged_entry_insert_tag (GD_TAGGED_ENTRY (entry), "tag2", "Blah2", "documents-entry-tag", FALSE, -1);
- gd_tagged_entry_insert_tag (GD_TAGGED_ENTRY (entry), "tag3", "Blah3", "documents-entry-tag", FALSE, 0);
+ tag = gd_tagged_entry_tag_new ("Blah1");
+ gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (entry), tag);
+ g_object_unref (tag);
+
+ tag = gd_tagged_entry_tag_new ("Blah2");
+ gd_tagged_entry_tag_set_has_close_button (tag, FALSE);
+ gd_tagged_entry_insert_tag (GD_TAGGED_ENTRY (entry), tag, -1);
+ g_object_unref (tag);
+
+ tag = gd_tagged_entry_tag_new ("Blah3");
+ gd_tagged_entry_tag_set_has_close_button (tag, FALSE);
+ gd_tagged_entry_insert_tag (GD_TAGGED_ENTRY (entry), tag, 0);
+ g_object_unref (tag);
gtk_widget_show_all (window);
gtk_main ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]