[gtk+/wip/baedert/drawing: 224/306] accellabel: Inherit from GtkWidget
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/drawing: 224/306] accellabel: Inherit from GtkWidget
- Date: Fri, 23 Jun 2017 20:15:45 +0000 (UTC)
commit b2010902031952cf8635aba5ea3e63d78d5cf461
Author: Timm Bäder <mail baedert org>
Date: Wed May 24 15:39:39 2017 +0200
accellabel: Inherit from GtkWidget
Use a box and 2 labels.
docs/reference/gtk/gtk4-sections.txt | 2 +
gtk/gtkaccellabel.c | 254 +++++++++++++--------------------
gtk/gtkaccellabel.h | 11 ++-
gtk/gtklabel.c | 11 --
gtk/gtkmenuitem.c | 24 ++-
5 files changed, 127 insertions(+), 175 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 1bc1d5e..b99227b 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -143,6 +143,8 @@ gtk_accel_label_get_accel_width
gtk_accel_label_set_accel
gtk_accel_label_get_accel
gtk_accel_label_refetch
+gtk_accel_label_set_label
+gtk_accel_label_get_label
<SUBSECTION Standard>
GTK_ACCEL_LABEL
GTK_IS_ACCEL_LABEL
diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c
index b1a95b8..6aed168 100644
--- a/gtk/gtkaccellabel.c
+++ b/gtk/gtkaccellabel.c
@@ -40,6 +40,7 @@
#include "gtkwidgetprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssstylepropertyprivate.h"
+#include "gtkbox.h"
/**
* SECTION:gtkaccellabel
@@ -99,30 +100,33 @@
* # CSS nodes
*
* |[<!-- language="plain" -->
- * label
- * ╰── accelerator
+ * accellabel
+ * ╰── box
+ * ├── label
+ * ╰── accelerator
* ]|
*
- * Like #GtkLabel, GtkAccelLabel has a main CSS node with the name label.
- * It adds a subnode with name accelerator.
+ * #GtkAccelLabel has a main CSS node with the name accellabel.
+ * It adds a subnode with name label and another one with name accelerator.
*/
enum {
PROP_0,
PROP_ACCEL_CLOSURE,
PROP_ACCEL_WIDGET,
+ PROP_LABEL,
LAST_PROP
};
struct _GtkAccelLabelPrivate
{
+ GtkWidget *box;
+ GtkWidget *text_label;
+ GtkWidget *accel_label;
+
GtkWidget *accel_widget; /* done */
GClosure *accel_closure; /* has set function */
GtkAccelGroup *accel_group; /* set by set_accel_closure() */
- gchar *accel_string; /* has set function */
- GtkCssNode *accel_node;
- guint accel_padding; /* should be style property? */
- guint16 accel_string_width; /* seems to be private */
guint accel_key; /* manual accel key specification if != 0 */
GdkModifierType accel_mods;
@@ -142,7 +146,6 @@ static void gtk_accel_label_destroy (GtkWidget *widget);
static void gtk_accel_label_finalize (GObject *object);
static void gtk_accel_label_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
-static const gchar *gtk_accel_label_get_string (GtkAccelLabel *accel_label);
static void gtk_accel_label_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
@@ -152,7 +155,17 @@ static void gtk_accel_label_measure (GtkWidget *widget,
int *natural_baseline);
-G_DEFINE_TYPE_WITH_PRIVATE (GtkAccelLabel, gtk_accel_label, GTK_TYPE_LABEL)
+G_DEFINE_TYPE_WITH_PRIVATE (GtkAccelLabel, gtk_accel_label, GTK_TYPE_WIDGET)
+
+static void
+gtk_accel_label_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkAccelLabel *al = GTK_ACCEL_LABEL (widget);
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (al);
+
+ gtk_widget_size_allocate (priv->box, allocation);
+}
static void
gtk_accel_label_class_init (GtkAccelLabelClass *class)
@@ -164,8 +177,9 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
gobject_class->set_property = gtk_accel_label_set_property;
gobject_class->get_property = gtk_accel_label_get_property;
- widget_class->snapshot = gtk_accel_label_snapshot;
widget_class->measure = gtk_accel_label_measure;
+ widget_class->size_allocate = gtk_accel_label_size_allocate;
+ widget_class->snapshot = gtk_accel_label_snapshot;
widget_class->destroy = gtk_accel_label_destroy;
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_ACCEL_LABEL);
@@ -219,7 +233,16 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ props[PROP_LABEL] =
+ g_param_spec_string ("label",
+ P_("Label"),
+ P_("The text displayed next to the accelerator"),
+ "",
+ GTK_PARAM_READWRITE);
+
g_object_class_install_properties (gobject_class, LAST_PROP, props);
+
+ gtk_widget_class_set_css_name (widget_class, "accellabel");
}
static void
@@ -240,6 +263,9 @@ gtk_accel_label_set_property (GObject *object,
case PROP_ACCEL_WIDGET:
gtk_accel_label_set_accel_widget (accel_label, g_value_get_object (value));
break;
+ case PROP_LABEL:
+ gtk_accel_label_set_label (accel_label, g_value_get_string (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -264,6 +290,9 @@ gtk_accel_label_get_property (GObject *object,
case PROP_ACCEL_WIDGET:
g_value_set_object (value, accel_label->priv->accel_widget);
break;
+ case PROP_LABEL:
+ g_value_set_string (value, gtk_accel_label_get_label (accel_label));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -271,38 +300,32 @@ gtk_accel_label_get_property (GObject *object,
}
static void
-node_style_changed_cb (GtkCssNode *node,
- GtkCssStyleChange *change,
- GtkWidget *widget)
-{
- if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP))
- gtk_widget_queue_resize (widget);
- else
- gtk_widget_queue_draw (widget);
-}
-
-static void
gtk_accel_label_init (GtkAccelLabel *accel_label)
{
GtkAccelLabelPrivate *priv;
- GtkCssNode *widget_node;
+
+ gtk_widget_set_has_window (GTK_WIDGET (accel_label), FALSE);
accel_label->priv = gtk_accel_label_get_instance_private (accel_label);
priv = accel_label->priv;
- priv->accel_padding = 3;
priv->accel_widget = NULL;
priv->accel_closure = NULL;
priv->accel_group = NULL;
- priv->accel_string = NULL;
-
- widget_node = gtk_widget_get_css_node (GTK_WIDGET (accel_label));
- priv->accel_node = gtk_css_node_new ();
- gtk_css_node_set_name (priv->accel_node, I_("accelerator"));
- gtk_css_node_set_parent (priv->accel_node, widget_node);
- gtk_css_node_set_state (priv->accel_node, gtk_css_node_get_state (widget_node));
- g_signal_connect_object (priv->accel_node, "style-changed", G_CALLBACK (node_style_changed_cb),
accel_label, 0);
- g_object_unref (priv->accel_node);
+
+ priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ priv->text_label = gtk_label_new ("");
+ gtk_widget_set_hexpand (priv->text_label, TRUE);
+ gtk_label_set_xalign (GTK_LABEL (priv->text_label), 0.0f);
+ gtk_label_set_use_underline (GTK_LABEL (priv->text_label), TRUE);
+ priv->accel_label = g_object_new (GTK_TYPE_LABEL,
+ "css-name", "accelerator",
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (priv->box), priv->text_label);
+ gtk_container_add (GTK_CONTAINER (priv->box), priv->accel_label);
+
+ gtk_widget_set_parent (priv->box, GTK_WIDGET (accel_label));
}
/**
@@ -322,7 +345,7 @@ gtk_accel_label_new (const gchar *string)
accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
- gtk_label_set_text (GTK_LABEL (accel_label), string);
+ gtk_label_set_label (GTK_LABEL (accel_label->priv->text_label), string);
return GTK_WIDGET (accel_label);
}
@@ -343,7 +366,7 @@ gtk_accel_label_finalize (GObject *object)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (object);
- g_free (accel_label->priv->accel_string);
+ gtk_widget_unparent (accel_label->priv->box);
G_OBJECT_CLASS (gtk_accel_label_parent_class)->finalize (object);
}
@@ -378,41 +401,15 @@ gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label)
guint
gtk_accel_label_get_accel_width (GtkAccelLabel *accel_label)
{
- g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), 0);
-
- return (accel_label->priv->accel_string_width +
- (accel_label->priv->accel_string_width ? accel_label->priv->accel_padding : 0));
-}
-
-static PangoLayout *
-gtk_accel_label_get_accel_layout (GtkAccelLabel *accel_label)
-{
- GtkWidget *widget = GTK_WIDGET (accel_label);
- GtkStyleContext *context;
- PangoAttrList *attrs;
- PangoLayout *layout;
- PangoFontDescription *font_desc;
-
- context = gtk_widget_get_style_context (widget);
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
+ int min;
- gtk_style_context_save_to_node (context, accel_label->priv->accel_node);
-
- layout = gtk_widget_create_pango_layout (widget, gtk_accel_label_get_string (accel_label));
-
- attrs = _gtk_style_context_get_pango_attributes (context);
- if (!attrs)
- attrs = pango_attr_list_new ();
- gtk_style_context_get (context,
- "font", &font_desc,
- NULL);
- pango_attr_list_change (attrs, pango_attr_font_desc_new (font_desc));
- pango_font_description_free (font_desc);
- pango_layout_set_attributes (layout, attrs);
- pango_attr_list_unref (attrs);
+ g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), 0);
- gtk_style_context_restore (context);
+ gtk_widget_measure (priv->accel_label, GTK_ORIENTATION_HORIZONTAL, -1,
+ &min, NULL, NULL, NULL);
- return layout;
+ return min;
}
static void
@@ -425,37 +422,11 @@ gtk_accel_label_measure (GtkWidget *widget,
int *natural_baseline)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
- GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->measure (widget,
- orientation,
- for_size,
- minimum, natural,
- minimum_baseline, natural_baseline);
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- PangoLayout *layout;
- int width;
-
- layout = gtk_accel_label_get_accel_layout (accel_label);
- pango_layout_get_pixel_size (layout, &width, NULL);
- accel_label->priv->accel_string_width = width;
-
- g_object_unref (layout);
- }
-}
-
-static gint
-get_first_baseline (PangoLayout *layout)
-{
- PangoLayoutIter *iter;
- gint result;
-
- iter = pango_layout_get_iter (layout);
- result = pango_layout_iter_get_baseline (iter);
- pango_layout_iter_free (iter);
-
- return PANGO_PIXELS (result);
+ gtk_widget_measure (priv->box, orientation, for_size,
+ minimum, natural,
+ minimum_baseline, natural_baseline);
}
static void
@@ -463,44 +434,9 @@ gtk_accel_label_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
- guint ac_width;
- GtkAllocation allocation;
- GtkRequisition requisition;
-
- GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->snapshot (widget, snapshot);
-
- ac_width = gtk_accel_label_get_accel_width (accel_label);
- gtk_widget_get_allocation (widget, &allocation);
- gtk_widget_get_preferred_size (widget, NULL, &requisition);
-
- if (allocation.width >= requisition.width + ac_width)
- {
- GtkStyleContext *context;
- PangoLayout *label_layout;
- PangoLayout *accel_layout;
- gint x;
- gint y;
-
- context = gtk_widget_get_style_context (widget);
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
- label_layout = gtk_label_get_layout (GTK_LABEL (accel_label));
- accel_layout = gtk_accel_label_get_accel_layout (accel_label);
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- x = 0;
- else
- x = gtk_widget_get_allocated_width (widget) - ac_width;
-
- gtk_label_get_layout_offsets (GTK_LABEL (accel_label), NULL, &y);
-
- y += get_first_baseline (label_layout) - get_first_baseline (accel_layout) - allocation.y;
-
- gtk_style_context_save_to_node (context, accel_label->priv->accel_node);
- gtk_snapshot_render_layout (snapshot, context, x, y, accel_layout);
- gtk_style_context_restore (context);
-
- g_object_unref (accel_layout);
- }
+ gtk_widget_snapshot_child (widget, priv->box, snapshot);
}
static void
@@ -580,9 +516,7 @@ gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
static void
gtk_accel_label_reset (GtkAccelLabel *accel_label)
{
- g_clear_pointer (&accel_label->priv->accel_string, g_free);
-
- gtk_widget_queue_resize (GTK_WIDGET (accel_label));
+ gtk_accel_label_refetch (accel_label);
}
static void
@@ -644,15 +578,6 @@ find_accel (GtkAccelKey *key,
return data == (gpointer) closure;
}
-static const gchar *
-gtk_accel_label_get_string (GtkAccelLabel *accel_label)
-{
- if (!accel_label->priv->accel_string)
- gtk_accel_label_refetch (accel_label);
-
- return accel_label->priv->accel_string;
-}
-
/* Underscores in key names are better displayed as spaces
* E.g., Page_Up should be “Page Up”.
*
@@ -935,11 +860,10 @@ gboolean
gtk_accel_label_refetch (GtkAccelLabel *accel_label)
{
gboolean enable_accels;
+ char *accel_string = NULL;
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE);
- g_clear_pointer (&accel_label->priv->accel_string, g_free);
-
g_object_get (gtk_widget_get_settings (GTK_WIDGET (accel_label)),
"gtk-enable-accels", &enable_accels,
NULL);
@@ -979,19 +903,20 @@ gtk_accel_label_refetch (GtkAccelLabel *accel_label)
GtkAccelLabelClass *klass;
klass = GTK_ACCEL_LABEL_GET_CLASS (accel_label);
- accel_label->priv->accel_string =
- _gtk_accel_label_class_get_accelerator_label (klass, accel_key, accel_mods);
+ accel_string = _gtk_accel_label_class_get_accelerator_label (klass, accel_key, accel_mods);
}
else
/* Otherwise we have a closure with no key. Show "-/-". */
- accel_label->priv->accel_string = g_strdup ("-/-");
+ accel_string = g_strdup ("-/-");
}
- if (!accel_label->priv->accel_string)
- accel_label->priv->accel_string = g_strdup ("");
+ if (!accel_string)
+ accel_string = g_strdup ("");
+
+ gtk_label_set_label (GTK_LABEL (accel_label->priv->accel_label), accel_string);
- gtk_widget_queue_resize (GTK_WIDGET (accel_label));
+ g_free (accel_string);
return FALSE;
}
@@ -1046,3 +971,24 @@ gtk_accel_label_get_accel (GtkAccelLabel *accel_label,
*accelerator_key = accel_label->priv->accel_key;
*accelerator_mods = accel_label->priv->accel_mods;
}
+
+void
+gtk_accel_label_set_label (GtkAccelLabel *accel_label,
+ const char *text)
+{
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
+
+ g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
+
+ gtk_label_set_label (GTK_LABEL (priv->text_label), text);
+}
+
+const char *
+gtk_accel_label_get_label (GtkAccelLabel *accel_label)
+{
+ GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
+
+ g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), NULL);
+
+ return gtk_label_get_label (GTK_LABEL (priv->text_label));
+}
diff --git a/gtk/gtkaccellabel.h b/gtk/gtkaccellabel.h
index 3f5a15e..678b081 100644
--- a/gtk/gtkaccellabel.h
+++ b/gtk/gtkaccellabel.h
@@ -56,13 +56,13 @@ typedef struct _GtkAccelLabelPrivate GtkAccelLabelPrivate;
*/
struct _GtkAccelLabel
{
- GtkLabel label;
+ GtkWidget parent_instance;
GtkAccelLabelPrivate *priv;
};
struct _GtkAccelLabelClass
{
- GtkLabelClass parent_class;
+ GtkWidgetClass parent_class;
gchar *signal_quote1;
gchar *signal_quote2;
@@ -104,6 +104,13 @@ void gtk_accel_label_get_accel (GtkAccelLabel *accel_label,
guint *accelerator_key,
GdkModifierType *accelerator_mods);
+GDK_AVAILABLE_IN_3_92
+void gtk_accel_label_set_label (GtkAccelLabel *accel_label,
+ const char *text);
+
+GDK_AVAILABLE_IN_3_92
+const char * gtk_accel_label_get_label (GtkAccelLabel *accel_label);
+
/* private */
gchar * _gtk_accel_label_class_get_accelerator_label (GtkAccelLabelClass *klass,
guint accelerator_key,
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index f8cc270..5005434 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -29,7 +29,6 @@
#include "gtklabel.h"
#include "gtklabelprivate.h"
-#include "gtkaccellabel.h"
#include "gtkbindings.h"
#include "gtkbuildable.h"
#include "gtkbuilderprivate.h"
@@ -1829,8 +1828,6 @@ static void
label_shortcut_setting_apply (GtkLabel *label)
{
gtk_label_recalculate (label);
- if (GTK_IS_ACCEL_LABEL (label))
- gtk_accel_label_refetch (GTK_ACCEL_LABEL (label));
}
static void
@@ -3928,14 +3925,6 @@ gtk_label_snapshot (GtkWidget *widget,
width = allocation.width;
height = allocation.height;
- if (GTK_IS_ACCEL_LABEL (widget))
- {
- guint ac_width = gtk_accel_label_get_accel_width (GTK_ACCEL_LABEL (widget));
- width -= ac_width;
- if (_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- x += ac_width;
- }
-
if (priv->text && (*priv->text != '\0'))
{
lx = ly = 0;
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 43efece..ab130da 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -1292,9 +1292,10 @@ gtk_real_menu_item_set_label (GtkMenuItem *menu_item,
gtk_menu_item_ensure_label (menu_item);
child = gtk_bin_get_child (GTK_BIN (menu_item));
- if (GTK_IS_LABEL (child))
+ if (GTK_IS_LABEL (child) ||
+ GTK_IS_ACCEL_LABEL (child))
{
- gtk_label_set_label (GTK_LABEL (child), label ? label : "");
+ g_object_set (child, "label", label ? label : "", NULL);
g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_LABEL]);
}
@@ -1308,8 +1309,15 @@ gtk_real_menu_item_get_label (GtkMenuItem *menu_item)
gtk_menu_item_ensure_label (menu_item);
child = gtk_bin_get_child (GTK_BIN (menu_item));
- if (GTK_IS_LABEL (child))
- return gtk_label_get_label (GTK_LABEL (child));
+ if (GTK_IS_LABEL (child) ||
+ GTK_IS_ACCEL_LABEL (child))
+ {
+ const char *label;
+
+ g_object_get (child, "label", &label, NULL);
+
+ return label;
+ }
return NULL;
}
@@ -1818,7 +1826,7 @@ gtk_menu_item_ensure_label (GtkMenuItem *menu_item)
if (!gtk_bin_get_child (GTK_BIN (menu_item)))
{
- accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, "xalign", 0.0, NULL);
+ accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
gtk_widget_set_halign (accel_label, GTK_ALIGN_FILL);
gtk_widget_set_valign (accel_label, GTK_ALIGN_CENTER);
@@ -1886,10 +1894,10 @@ gtk_menu_item_set_use_underline (GtkMenuItem *menu_item,
gtk_menu_item_ensure_label (menu_item);
child = gtk_bin_get_child (GTK_BIN (menu_item));
- if (GTK_IS_LABEL (child) &&
- gtk_label_get_use_underline (GTK_LABEL (child)) != setting)
+ if (GTK_IS_ACCEL_LABEL (child) &&
+ gtk_accel_label_get_use_underline (GTK_ACCEL_LABEL (child)) != setting)
{
- gtk_label_set_use_underline (GTK_LABEL (child), setting);
+ gtk_accel_label_set_use_underline (GTK_ACCEL_LABEL (child), setting);
g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_USE_UNDERLINE]);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]