GtkModelButton: Add an iconic mode

In iconic mode, model buttons will be styled like regular icon
buttons, preferring to show only the icon if one is set, falling
back to showing the label.

https://bugzilla.gnome.org/show_bug.cgi?id=727477
This commit is contained in:
Matthias Clasen 2014-04-26 13:50:55 -04:00
parent 038de02574
commit 6429b33f44

View File

@ -41,6 +41,7 @@ struct _GtkModelButton
gboolean has_submenu; gboolean has_submenu;
gboolean centered; gboolean centered;
gboolean inverted; gboolean inverted;
gboolean iconic;
GtkMenuTrackerItemRole role; GtkMenuTrackerItemRole role;
}; };
@ -58,7 +59,8 @@ enum
PROP_ACCEL, PROP_ACCEL,
PROP_HAS_SUBMENU, PROP_HAS_SUBMENU,
PROP_INVERTED, PROP_INVERTED,
PROP_CENTERED PROP_CENTERED,
PROP_ICONIC
}; };
static void static void
@ -96,21 +98,33 @@ gtk_model_button_set_action_role (GtkModelButton *button,
atk_object_set_role (accessible, a11y_role); atk_object_set_role (accessible, a11y_role);
} }
static void
update_visibility (GtkModelButton *button)
{
gboolean has_icon;
gboolean has_text;
has_icon = gtk_image_get_storage_type (GTK_IMAGE (button->image)) != GTK_IMAGE_EMPTY;
has_text = gtk_label_get_text (GTK_LABEL (button->label))[0] != '\0';
gtk_widget_set_visible (button->image, has_icon);
gtk_widget_set_visible (button->label, has_text && (!button->iconic || !has_icon));
}
static void static void
gtk_model_button_set_icon (GtkModelButton *button, gtk_model_button_set_icon (GtkModelButton *button,
GIcon *icon) GIcon *icon)
{ {
gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon, GTK_ICON_SIZE_MENU); gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon, GTK_ICON_SIZE_MENU);
gtk_widget_set_visible (button->image, icon != NULL); update_visibility (button);
} }
static void static void
gtk_model_button_set_text (GtkModelButton *button, gtk_model_button_set_text (GtkModelButton *button,
const gchar *text) const gchar *text)
{ {
if (text != NULL) gtk_label_set_text_with_mnemonic (GTK_LABEL (button->label), text);
gtk_label_set_text_with_mnemonic (GTK_LABEL (button->label), text); update_visibility (button);
gtk_widget_set_visible (button->label, text != NULL);
} }
static void static void
@ -153,6 +167,28 @@ gtk_model_button_set_centered (GtkModelButton *button,
gtk_widget_queue_draw (GTK_WIDGET (button)); gtk_widget_queue_draw (GTK_WIDGET (button));
} }
static void
gtk_model_button_set_iconic (GtkModelButton *button,
gboolean iconic)
{
button->iconic = iconic;
if (iconic)
{
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (button)),
GTK_STYLE_CLASS_MENUITEM);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
}
else
{
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (button)),
GTK_STYLE_CLASS_MENUITEM);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
}
update_visibility (button);
gtk_widget_queue_resize (GTK_WIDGET (button));
}
static void static void
gtk_model_button_set_property (GObject *object, gtk_model_button_set_property (GObject *object,
guint prop_id, guint prop_id,
@ -195,6 +231,10 @@ gtk_model_button_set_property (GObject *object,
gtk_model_button_set_centered (button, g_value_get_boolean (value)); gtk_model_button_set_centered (button, g_value_get_boolean (value));
break; break;
case PROP_ICONIC:
gtk_model_button_set_iconic (button, g_value_get_boolean (value));
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }
@ -223,7 +263,10 @@ gtk_model_button_get_full_border (GtkModelButton *button,
border->top = border_width + focus_width + focus_pad; border->top = border_width + focus_width + focus_pad;
border->bottom = border_width + focus_width + focus_pad; border->bottom = border_width + focus_width + focus_pad;
*indicator = indicator_size + 2 * indicator_spacing; if (button->iconic)
*indicator = 0;
else
*indicator = indicator_size + 2 * indicator_spacing;
} }
static gboolean static gboolean
@ -540,12 +583,22 @@ gtk_model_button_draw (GtkWidget *widget,
gint focus_width, focus_pad; gint focus_width, focus_pad;
gint baseline; gint baseline;
state = get_button_state (model_button);
context = gtk_widget_get_style_context (widget);
gtk_style_context_save (context);
gtk_style_context_set_state (context, state);
if (model_button->iconic)
{
GTK_WIDGET_CLASS (gtk_model_button_parent_class)->draw (widget, cr);
goto out;
}
width = gtk_widget_get_allocated_width (widget); width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget); height = gtk_widget_get_allocated_height (widget);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
context = gtk_widget_get_style_context (widget);
baseline = gtk_widget_get_allocated_baseline (widget); baseline = gtk_widget_get_allocated_baseline (widget);
state = get_button_state (model_button);
gtk_widget_style_get (widget, gtk_widget_style_get (widget,
"focus-line-width", &focus_width, "focus-line-width", &focus_width,
@ -566,9 +619,6 @@ gtk_model_button_draw (GtkWidget *widget,
y = CLAMP (baseline - indicator_size * button->priv->baseline_align, y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
0, height - indicator_size); 0, height - indicator_size);
gtk_style_context_save (context);
gtk_style_context_set_state (context, state);
gtk_render_background (context, cr, gtk_render_background (context, cr,
border_width, border_width, border_width, border_width,
width - 2 * border_width, width - 2 * border_width,
@ -614,12 +664,13 @@ gtk_model_button_draw (GtkWidget *widget,
height - 2 * (border_width + focus_pad) - border.top - border.bottom); height - 2 * (border_width + focus_pad) - border.top - border.bottom);
} }
gtk_style_context_restore (context);
child = gtk_bin_get_child (GTK_BIN (widget)); child = gtk_bin_get_child (GTK_BIN (widget));
if (child) if (child)
gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr); gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);
out:
gtk_style_context_restore (context);
return FALSE; return FALSE;
} }
@ -640,30 +691,34 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
widget_class->draw = gtk_model_button_draw; widget_class->draw = gtk_model_button_draw;
g_object_class_install_property (object_class, PROP_ACTION_ROLE, g_object_class_install_property (object_class, PROP_ACTION_ROLE,
g_param_spec_enum ("action-role", "action role", "action role", g_param_spec_enum ("action-role", "", "",
GTK_TYPE_MENU_TRACKER_ITEM_ROLE, GTK_TYPE_MENU_TRACKER_ITEM_ROLE,
GTK_MENU_TRACKER_ITEM_ROLE_NORMAL, GTK_MENU_TRACKER_ITEM_ROLE_NORMAL,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ICON, g_object_class_install_property (object_class, PROP_ICON,
g_param_spec_object ("icon", "icon", "icon", G_TYPE_ICON, g_param_spec_object ("icon", "", "", G_TYPE_ICON,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_TEXT, g_object_class_install_property (object_class, PROP_TEXT,
g_param_spec_string ("text", "text", "text", NULL, g_param_spec_string ("text", "", "", NULL,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_TOGGLED, g_object_class_install_property (object_class, PROP_TOGGLED,
g_param_spec_boolean ("toggled", "toggled", "toggled", FALSE, g_param_spec_boolean ("toggled", "", "", FALSE,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ACCEL, g_object_class_install_property (object_class, PROP_ACCEL,
g_param_spec_string ("accel", "accel", "accel", NULL, g_param_spec_string ("accel", "", "", NULL,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_HAS_SUBMENU, g_object_class_install_property (object_class, PROP_HAS_SUBMENU,
g_param_spec_boolean ("has-submenu", "has-submenu", "has-submenu", FALSE, g_param_spec_boolean ("has-submenu", "", "", FALSE,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_INVERTED, g_object_class_install_property (object_class, PROP_INVERTED,
g_param_spec_boolean ("inverted", "inverted", "inverted", FALSE, g_param_spec_boolean ("inverted", "", "", FALSE,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_CENTERED, g_object_class_install_property (object_class, PROP_CENTERED,
g_param_spec_boolean ("centered", "centered", "centered", FALSE, g_param_spec_boolean ("centered", "", "", FALSE,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ICONIC,
g_param_spec_boolean ("iconic", "", "", TRUE,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_PUSH_BUTTON); gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_PUSH_BUTTON);