[gtk+/wip/baedert/box: 268/269] button: Fix icon-name implementation
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/box: 268/269] button: Fix icon-name implementation
- Date: Wed, 19 Oct 2016 18:42:38 +0000 (UTC)
commit 98c0b9615401677ed552b2d12940c3e22ce4efb3
Author: Timm Bäder <mail baedert org>
Date: Wed Oct 19 20:32:13 2016 +0200
button: Fix icon-name implementation
gtk/gtkbutton.c | 157 ++++++++++++++++++++++++++++++++---------------
gtk/gtkbutton.h | 4 +-
gtk/gtkbuttonprivate.h | 3 +-
3 files changed, 110 insertions(+), 54 deletions(-)
---
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 2358009..b65a991 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -100,6 +100,12 @@ enum {
LAST_PROP = PROP_ACTION_NAME
};
+enum {
+ LABEL_CHILD,
+ ICON_CHILD,
+ WIDGET_CHILD
+};
+
static void gtk_button_finalize (GObject *object);
static void gtk_button_dispose (GObject *object);
@@ -177,6 +183,7 @@ static void gtk_button_allocate (GtkCssGadget *gadget,
int baseline,
GtkAllocation *out_clip,
gpointer data);
+static void gtk_button_set_child_type (GtkButton *button, guint child_type);
static GParamSpec *props[LAST_PROP] = { NULL, };
static guint button_signals[LAST_SIGNAL] = { 0 };
@@ -186,14 +193,36 @@ G_DEFINE_TYPE_WITH_CODE (GtkButton, gtk_button, GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE, gtk_button_actionable_iface_init))
static void
+gtk_button_add (GtkContainer *container, GtkWidget *child)
+{
+ GtkButton *button = GTK_BUTTON (container);
+
+ gtk_button_set_child_type (button, WIDGET_CHILD);
+
+ GTK_CONTAINER_CLASS (gtk_button_parent_class)->add (container, child);
+}
+
+static void
+gtk_button_remove (GtkContainer *container, GtkWidget *child)
+{
+ GtkButton *button = GTK_BUTTON (container);
+
+ gtk_button_set_child_type (button, WIDGET_CHILD);
+
+ GTK_CONTAINER_CLASS (gtk_button_parent_class)->remove (container, child);
+}
+
+static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
gobject_class = G_OBJECT_CLASS (klass);
widget_class = (GtkWidgetClass*) klass;
-
+ container_class = (GtkContainerClass*) klass;
+
gobject_class->dispose = gtk_button_dispose;
gobject_class->finalize = gtk_button_finalize;
gobject_class->set_property = gtk_button_set_property;
@@ -218,6 +247,9 @@ gtk_button_class_init (GtkButtonClass *klass)
widget_class->state_changed = gtk_button_state_changed;
widget_class->grab_notify = gtk_button_grab_notify;
+ container_class->add = gtk_button_add;
+ container_class->remove = gtk_button_remove;
+
klass->clicked = NULL;
klass->activate = gtk_real_button_activate;
@@ -410,6 +442,29 @@ multipress_gesture_cancel_cb (GtkGesture *gesture,
}
static void
+gtk_button_set_child_type (GtkButton *button, guint child_type)
+{
+ GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
+
+ if (child_type == WIDGET_CHILD ||
+ child_type == LABEL_CHILD)
+ {
+ if (priv->child_type == ICON_CHILD)
+ g_object_notify_by_pspec (G_OBJECT (button), props[PROP_ICON_NAME]);
+ }
+
+ if ((child_type == WIDGET_CHILD ||
+ child_type == ICON_CHILD) &&
+ priv->label_text != NULL)
+ {
+ g_clear_pointer (&priv->label_text, g_free);
+ g_object_notify_by_pspec (G_OBJECT (button), props[PROP_LABEL]);
+ }
+
+ priv->child_type = child_type;
+}
+
+static void
gtk_button_init (GtkButton *button)
{
GtkButtonPrivate *priv;
@@ -423,10 +478,10 @@ gtk_button_init (GtkButton *button)
priv->label_text = NULL;
- priv->constructed = FALSE;
priv->in_button = FALSE;
priv->button_down = FALSE;
priv->use_underline = FALSE;
+ priv->child_type = WIDGET_CHILD;
priv->gesture = gtk_gesture_multi_press_new (GTK_WIDGET (button));
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->gesture), FALSE);
@@ -986,7 +1041,6 @@ gtk_real_button_activate (GtkButton *button)
GtkWidget *widget = GTK_WIDGET (button);
GtkButtonPrivate *priv = button->priv;
GdkDevice *device;
- guint32 time;
device = gtk_get_current_event_device ();
@@ -995,8 +1049,6 @@ gtk_real_button_activate (GtkButton *button)
if (gtk_widget_get_realized (widget) && !priv->activate_timeout)
{
- time = gtk_get_current_event_time ();
-
/* bgo#626336 - Only grab if we have a device (from an event), not if we
* were activated programmatically when no event is available.
*/
@@ -1008,7 +1060,6 @@ gtk_real_button_activate (GtkButton *button)
{
gtk_device_grab_add (widget, device, TRUE);
priv->grab_keyboard = device;
- priv->grab_time = time;
}
}
@@ -1168,36 +1219,40 @@ gtk_button_set_label (GtkButton *button,
context = gtk_widget_get_style_context (GTK_WIDGET (button));
- g_free (priv->label_text);
- priv->label_text = g_strdup (label);
-
child = gtk_bin_get_child (GTK_BIN (button));
- if (child != NULL)
+ if (priv->child_type == LABEL_CHILD)
{
- if (!priv->constructed || !GTK_IS_LABEL (child))
- {
- gtk_container_remove (GTK_CONTAINER (button), child);
- }
- else
- {
- gtk_label_set_label (GTK_LABEL (child), label);
- return;
- }
+ gtk_label_set_label (GTK_LABEL (child), label);
+ gtk_widget_show (child);
+ goto out;
+ }
+ else if (child != NULL)
+ {
+ gtk_container_remove (GTK_CONTAINER (button), child);
}
gtk_style_context_remove_class (context, "image-button");
gtk_style_context_add_class (context, "text-button");
+
if (label != NULL)
{
child = gtk_label_new (label);
- gtk_label_set_use_underline (GTK_LABEL (child), priv->use_underline);
+ if (priv->use_underline)
+ {
+ gtk_label_set_use_underline (GTK_LABEL (child), priv->use_underline);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (child), GTK_WIDGET (button));
+ }
gtk_widget_show (child);
gtk_container_add (GTK_CONTAINER (button), child);
- priv->constructed = TRUE;
+ gtk_widget_queue_resize (GTK_WIDGET (button));
}
+ gtk_button_set_child_type (button, LABEL_CHILD);
+
+out:
+ priv->label_text = g_strdup (label);
g_object_notify_by_pspec (G_OBJECT (button), props[PROP_LABEL]);
}
@@ -1244,21 +1299,17 @@ gtk_button_set_use_underline (GtkButton *button,
if (use_underline != priv->use_underline)
{
- priv->use_underline = use_underline;
-
- g_object_notify_by_pspec (G_OBJECT (button), props[PROP_USE_UNDERLINE]);
- }
-
- if (priv->constructed)
- {
- GtkWidget *child;
- child = gtk_bin_get_child (GTK_BIN (button));
-
- if (child != NULL && GTK_IS_LABEL (child))
+ if (priv->child_type == LABEL_CHILD)
{
+ GtkWidget *child;
+ child = gtk_bin_get_child (GTK_BIN (button));
+
gtk_label_set_use_underline (GTK_LABEL (child), use_underline);
gtk_label_set_mnemonic_widget (GTK_LABEL (child), GTK_WIDGET (button));
}
+
+ priv->use_underline = use_underline;
+ g_object_notify_by_pspec (G_OBJECT (button), props[PROP_USE_UNDERLINE]);
}
}
@@ -1373,7 +1424,12 @@ gtk_button_get_event_window (GtkButton *button)
/**
* gtk_button_set_icon_name:
+ * @button: A #GtkButton
+ * @icon_name: A icon name
*
+ * Adds a #GtkImage with the given icon name as a child. The icon will be
+ * of size %GTK_ICON_SIZE_BUTTON. If @button already contains a child widget,
+ * that child widget will be removed and replaced with the image.
*/
void
gtk_button_set_icon_name (GtkButton *button,
@@ -1389,26 +1445,27 @@ gtk_button_set_icon_name (GtkButton *button,
child = gtk_bin_get_child (GTK_BIN (button));
context = gtk_widget_get_style_context (GTK_WIDGET (button));
- if (child != NULL)
+ if (priv->child_type == ICON_CHILD)
{
- if (!priv->constructed || !GTK_IS_IMAGE (child))
- {
- gtk_container_remove (GTK_CONTAINER (button), child);
- }
- else
- {
- gtk_image_set_from_icon_name (GTK_IMAGE (child), icon_name, GTK_ICON_SIZE_BUTTON);
- return;
- }
+ gtk_image_set_from_icon_name (GTK_IMAGE (child), icon_name, GTK_ICON_SIZE_BUTTON);
+ goto out;
+ }
+ else if (child != NULL)
+ {
+ gtk_container_remove (GTK_CONTAINER (button), child);
}
gtk_style_context_remove_class (context, "text-button");
gtk_style_context_add_class (context, "image-button");
+
child = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
gtk_widget_show (child);
gtk_container_add (GTK_CONTAINER (button), child);
- priv->constructed = TRUE;
+
+ gtk_button_set_child_type (button, ICON_CHILD);
+
+out:
g_object_notify_by_pspec (G_OBJECT (button), props[PROP_ICON_NAME]);
}
@@ -1421,18 +1478,18 @@ gtk_button_set_icon_name (GtkButton *button,
const char *
gtk_button_get_icon_name (GtkButton *button)
{
+ GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
+
g_return_val_if_fail (GTK_IS_BUTTON (button), NULL);
- if (button->priv->constructed)
+ if (priv->child_type == ICON_CHILD)
{
+ const char *icon_name;
GtkWidget *child = gtk_bin_get_child (GTK_BIN (button));
+ gtk_image_get_icon_name (GTK_IMAGE (child), &icon_name, NULL);
- if (GTK_IS_IMAGE (child))
- {
- const char *icon_name;
- gtk_image_get_icon_name (GTK_IMAGE (child), &icon_name, NULL);
- return icon_name;
- }
+ return icon_name;
}
+
return NULL;
}
diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h
index 3722c07..b1567de 100644
--- a/gtk/gtkbutton.h
+++ b/gtk/gtkbutton.h
@@ -115,10 +115,10 @@ gboolean gtk_button_get_use_underline (GtkButton *button);
GDK_AVAILABLE_IN_ALL
GdkWindow* gtk_button_get_event_window (GtkButton *button);
-GDK_AVAILABLE_IN_ALL
+GDK_AVAILABLE_IN_3_90
void gtk_button_set_icon_name (GtkButton *button,
const char *icon_name);
-GDK_AVAILABLE_IN_ALL
+GDK_AVAILABLE_IN_3_90
const char * gtk_button_get_icon_name (GtkButton *button);
diff --git a/gtk/gtkbuttonprivate.h b/gtk/gtkbuttonprivate.h
index 8adc4db..251b5ab 100644
--- a/gtk/gtkbuttonprivate.h
+++ b/gtk/gtkbuttonprivate.h
@@ -42,13 +42,12 @@ struct _GtkButtonPrivate
gfloat baseline_align;
guint activate_timeout;
- guint32 grab_time;
- guint align_set : 1;
guint button_down : 1;
guint constructed : 1;
guint in_button : 1;
guint use_underline : 1;
+ guint child_type : 2;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]