[gtk/wip/exalm/buttons: 4/4] menu-button: Allow label and icon-name to be set together
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/exalm/buttons: 4/4] menu-button: Allow label and icon-name to be set together
- Date: Mon, 30 Aug 2021 22:02:14 +0000 (UTC)
commit b036179b1f5aa9cd2be618d9fd663a4da4832ed0
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Tue Aug 31 02:58:56 2021 +0500
menu-button: Allow label and icon-name to be set together
Same as for GtkButton. Rework when .arrow-button is added as it makes less
sense when the button can contain text, icon, arrow and all combinations
thereof. Keep .image-button instead of .arrow-button when the button only
has an arrow and arrow-type=none, as it's styled as a menu open icon and is
an image button for the styling purposes.
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4205
gtk/gtkmenubutton.c | 159 ++++++++++++++++++++---------------------
gtk/theme/Default/_common.scss | 12 ++++
2 files changed, 91 insertions(+), 80 deletions(-)
---
diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c
index e1d8209ddc..9231e5e33d 100644
--- a/gtk/gtkmenubutton.c
+++ b/gtk/gtkmenubutton.c
@@ -66,9 +66,9 @@
* `GtkMenuButton` has a single CSS node with name `menubutton`
* which contains a `button` node with a `.toggle` style class.
*
- * If the button contains only an icon or an arrow, it will have the
- * `.image-button` style class, if it contains both, it will have the
- * `.arrow-button` style class.
+ * If the button contains an icon and/or a label, it will have the
+ * `.image-button` and/or `.text-button` style classes. If it contains an arrow,
+ * it will additionally have the `.arrow-button` style class.
*
* Inside the toggle button content, there is an `arrow` node for
* the indicator, which will carry one of the `.none`, `.up`, `.down`,
@@ -119,6 +119,7 @@ struct _GtkMenuButton
gpointer create_popup_user_data;
GDestroyNotify create_popup_destroy_notify;
+ GtkWidget *child;
GtkWidget *label_widget;
GtkWidget *image_widget;
GtkWidget *arrow_widget;
@@ -575,48 +576,65 @@ set_arrow_type (GtkWidget *arrow,
static void
update_style_classes (GtkMenuButton *menu_button)
{
- if (menu_button->arrow_widget == gtk_button_get_child (GTK_BUTTON (menu_button->button)) ||
- (menu_button->image_widget && !menu_button->always_show_arrow))
+ gboolean has_image, has_text, has_arrow;
+
+ has_image = gtk_widget_get_visible (menu_button->image_widget);
+ has_text = gtk_widget_get_visible (menu_button->label_widget);
+ has_arrow = menu_button->arrow_type != GTK_ARROW_NONE;
+
+ if (has_text)
+ gtk_widget_add_css_class (menu_button->button, "text-button");
+ else
+ gtk_widget_remove_css_class (menu_button->button, "text-button");
+
+ if (has_image || (!has_text && !has_arrow))
gtk_widget_add_css_class (menu_button->button, "image-button");
else
gtk_widget_remove_css_class (menu_button->button, "image-button");
- if (menu_button->image_widget && menu_button->always_show_arrow)
+ if (has_arrow && (!has_image || has_text || menu_button->always_show_arrow))
gtk_widget_add_css_class (menu_button->button, "arrow-button");
else
gtk_widget_remove_css_class (menu_button->button, "arrow-button");
}
static void
-update_arrow (GtkMenuButton *menu_button)
+update_alignment (GtkMenuButton *menu_button)
{
- gboolean has_only_arrow, is_text_button;
-
- if (menu_button->arrow_widget == NULL)
- return;
+ gboolean has_image, has_text;
- has_only_arrow = menu_button->arrow_widget == gtk_button_get_child (GTK_BUTTON (menu_button->button));
- is_text_button = menu_button->label_widget != NULL;
+ has_image = gtk_widget_get_visible (menu_button->image_widget);
+ has_text = gtk_widget_get_visible (menu_button->label_widget);
- set_arrow_type (menu_button->arrow_widget,
- menu_button->arrow_type,
- has_only_arrow ||
- ((is_text_button || menu_button->always_show_arrow) &&
- (menu_button->arrow_type != GTK_ARROW_NONE)));
+ if (has_text && has_image)
+ {
+ gtk_widget_set_halign (menu_button->image_widget, GTK_ALIGN_END);
+ gtk_widget_set_halign (menu_button->label_widget, GTK_ALIGN_START);
+ }
+ else
+ {
+ gtk_widget_set_halign (menu_button->image_widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_halign (menu_button->label_widget, GTK_ALIGN_CENTER);
+ }
- update_style_classes (menu_button);
+ gtk_widget_set_hexpand (menu_button->arrow_widget, !has_text && !has_image);
}
static void
-add_arrow (GtkMenuButton *self)
+update_arrow (GtkMenuButton *menu_button)
{
- GtkWidget *arrow;
+ gboolean has_image, has_text;
+
+ has_image = gtk_widget_get_visible (menu_button->image_widget);
+ has_text = gtk_widget_get_visible (menu_button->label_widget);
- arrow = gtk_builtin_icon_new ("arrow");
- gtk_widget_set_halign (arrow, GTK_ALIGN_CENTER);
- set_arrow_type (arrow, self->arrow_type, TRUE);
- gtk_button_set_child (GTK_BUTTON (self->button), arrow);
- self->arrow_widget = arrow;
+ set_arrow_type (menu_button->arrow_widget,
+ menu_button->arrow_type,
+ (!has_image && !has_text) ||
+ ((has_text || menu_button->always_show_arrow) &&
+ (menu_button->arrow_type != GTK_ARROW_NONE)));
+
+ update_style_classes (menu_button);
}
static void
@@ -627,12 +645,39 @@ gtk_menu_button_init (GtkMenuButton *self)
self->button = gtk_toggle_button_new ();
gtk_widget_set_parent (self->button, GTK_WIDGET (self));
g_signal_connect_swapped (self->button, "toggled", G_CALLBACK (gtk_menu_button_toggled), self);
- add_arrow (self);
- update_style_classes (self);
+
+ self->child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_hexpand (self->child, FALSE);
+ gtk_button_set_child (GTK_BUTTON (self->button), self->child);
+
+ self->image_widget = g_object_new (GTK_TYPE_IMAGE,
+ "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
+ NULL);
+ gtk_widget_set_hexpand (self->image_widget, TRUE);
+ gtk_widget_hide (self->image_widget);
+
+ self->label_widget = gtk_label_new (NULL);
+ gtk_widget_hide (self->label_widget);
+ gtk_widget_set_hexpand (self->label_widget, TRUE);
+ gtk_label_set_xalign (GTK_LABEL (self->label_widget), 0);
+ gtk_label_set_use_underline (GTK_LABEL (self->label_widget),
+ gtk_button_get_use_underline (GTK_BUTTON (self->button)));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (self->label_widget), self->button);
+
+ self->arrow_widget = gtk_builtin_icon_new ("arrow");
+ gtk_widget_set_halign (self->arrow_widget, GTK_ALIGN_CENTER);
+ set_arrow_type (self->arrow_widget, self->arrow_type, TRUE);
+
+ gtk_box_append (GTK_BOX (self->child), self->image_widget);
+ gtk_box_append (GTK_BOX (self->child), self->label_widget);
+ gtk_box_append (GTK_BOX (self->child), self->arrow_widget);
gtk_widget_set_sensitive (self->button, FALSE);
gtk_widget_add_css_class (GTK_WIDGET (self), "popup");
+
+ update_alignment (self);
+ update_arrow (self);
}
/**
@@ -937,38 +982,15 @@ void
gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
const char *icon_name)
{
- GtkWidget *box, *image_widget, *arrow;
-
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
- g_object_freeze_notify (G_OBJECT (menu_button));
-
- if (gtk_menu_button_get_label (menu_button))
- g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_LABEL]);
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
-
- image_widget = g_object_new (GTK_TYPE_IMAGE,
- "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
- "icon-name", icon_name,
- NULL);
- menu_button->image_widget = image_widget;
-
- arrow = gtk_builtin_icon_new ("arrow");
- menu_button->arrow_widget = arrow;
-
- gtk_box_append (GTK_BOX (box), image_widget);
- gtk_box_append (GTK_BOX (box), arrow);
- gtk_button_set_child (GTK_BUTTON (menu_button->button), box);
-
- menu_button->label_widget = NULL;
+ gtk_image_set_from_icon_name (GTK_IMAGE (menu_button->image_widget), icon_name);
+ gtk_widget_set_visible (menu_button->image_widget, icon_name && icon_name[0]);
+ update_alignment (menu_button);
update_arrow (menu_button);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_ICON_NAME]);
-
- g_object_thaw_notify (G_OBJECT (menu_button));
}
/**
@@ -1046,38 +1068,15 @@ void
gtk_menu_button_set_label (GtkMenuButton *menu_button,
const char *label)
{
- GtkWidget *box;
- GtkWidget *label_widget;
- GtkWidget *arrow;
-
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
- g_object_freeze_notify (G_OBJECT (menu_button));
-
- if (gtk_menu_button_get_icon_name (menu_button))
- g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_ICON_NAME]);
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- label_widget = gtk_label_new (label);
- gtk_label_set_xalign (GTK_LABEL (label_widget), 0);
- gtk_label_set_use_underline (GTK_LABEL (label_widget),
- gtk_button_get_use_underline (GTK_BUTTON (menu_button->button)));
- gtk_widget_set_hexpand (label_widget, TRUE);
- gtk_widget_set_halign (label_widget, GTK_ALIGN_CENTER);
- arrow = gtk_builtin_icon_new ("arrow");
- menu_button->arrow_widget = arrow;
- gtk_box_append (GTK_BOX (box), label_widget);
- gtk_box_append (GTK_BOX (box), arrow);
- gtk_button_set_child (GTK_BUTTON (menu_button->button), box);
- menu_button->label_widget = label_widget;
-
- menu_button->image_widget = NULL;
+ gtk_label_set_label (GTK_LABEL (menu_button->label_widget), label);
+ gtk_widget_set_visible (menu_button->label_widget, label && label[0]);
+ update_alignment (menu_button);
update_arrow (menu_button);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_LABEL]);
-
- g_object_thaw_notify (G_OBJECT (menu_button));
}
/**
diff --git a/gtk/theme/Default/_common.scss b/gtk/theme/Default/_common.scss
index 344af26831..47e47c1a59 100644
--- a/gtk/theme/Default/_common.scss
+++ b/gtk/theme/Default/_common.scss
@@ -570,6 +570,18 @@ button {
}
}
+ &.arrow-button {
+ padding-left: 10px;
+ padding-right: 10px;
+
+ > box {
+ border-spacing: 4px;
+
+ > label:dir(ltr) { padding-right: 0px; }
+ > label:dir(rtl) { padding-left: 0px; }
+ }
+ }
+
@at-root %button_basic_drop_active,
&:drop(active) {
color: $drop_target_color;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]