Commit 19b34a44 authored by Matthias Clasen's avatar Matthias Clasen

model button: Complete the CSS node conversion

There was still style context saving in the draw function,
and the CSS node was not always properly updated and positioned.
Fix these things, and use the same CSS node for the arrow
drawing as well.
parent 6791c141
......@@ -143,24 +143,70 @@ enum
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
static gboolean
indicator_is_left (GtkWidget *widget)
{
GtkModelButton *button = GTK_MODEL_BUTTON (widget);
return ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && !button->inverted) ||
(gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && button->inverted));
}
static void
gtk_model_button_update_state (GtkModelButton *button)
{
GtkStateFlags state;
if (button->role == GTK_BUTTON_ROLE_NORMAL)
return;
state = gtk_widget_get_state_flags (GTK_WIDGET (button));
state &= ~GTK_STATE_FLAG_CHECKED;
if (button->role == GTK_BUTTON_ROLE_CHECK ||
button->role == GTK_BUTTON_ROLE_RADIO)
{
state &= ~GTK_STATE_FLAG_CHECKED;
if (button->active && !button->menu_name)
state |= GTK_STATE_FLAG_CHECKED;
if (button->active && !button->menu_name)
state |= GTK_STATE_FLAG_CHECKED;
}
if (button->menu_name)
{
state = state & ~(GTK_STATE_FLAG_DIR_LTR|GTK_STATE_FLAG_DIR_RTL);
if (indicator_is_left (GTK_WIDGET (button)))
state = state | GTK_STATE_FLAG_DIR_RTL;
else
state = state | GTK_STATE_FLAG_DIR_LTR;
}
gtk_css_node_set_state (button->indicator_node, state);
}
static void
update_node_ordering (GtkModelButton *button)
{
GtkCssNode *widget_node, *node;
widget_node = gtk_widget_get_css_node (GTK_WIDGET (button));
if (indicator_is_left (GTK_WIDGET (button)))
{
gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT));
gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT));
node = gtk_css_node_get_first_child (widget_node);
if (node != button->indicator_node)
gtk_css_node_insert_before (widget_node, button->indicator_node, node);
}
else
{
gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT));
gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT));
node = gtk_css_node_get_last_child (widget_node);
if (node != button->indicator_node)
gtk_css_node_insert_after (widget_node, button->indicator_node, node);
}
}
static void
gtk_model_button_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_flags)
......@@ -169,26 +215,40 @@ gtk_model_button_state_flags_changed (GtkWidget *widget,
}
static void
gtk_model_button_set_role (GtkModelButton *button,
GtkButtonRole role)
gtk_model_button_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GtkModelButton *button = GTK_MODEL_BUTTON (widget);
gtk_model_button_update_state (button);
update_node_ordering (button);
GTK_WIDGET_CLASS (gtk_model_button_parent_class)->direction_changed (widget, previous_dir);
}
static void
update_node_name (GtkModelButton *button)
{
AtkObject *accessible;
AtkRole a11y_role;
const gchar *name;
gboolean visible;
if (role == button->role)
return;
button->role = role;
accessible = gtk_widget_get_accessible (GTK_WIDGET (button));
switch (role)
switch (button->role)
{
case GTK_BUTTON_ROLE_NORMAL:
a11y_role = ATK_ROLE_PUSH_BUTTON;
name = I_("check");
visible = FALSE;
if (button->menu_name)
{
name = I_("arrow");
visible = TRUE;
}
else
{
name = I_("check");
visible = FALSE;
}
break;
case GTK_BUTTON_ROLE_CHECK:
......@@ -210,6 +270,18 @@ gtk_model_button_set_role (GtkModelButton *button,
atk_object_set_role (accessible, a11y_role);
gtk_css_node_set_name (button->indicator_node, name);
gtk_css_node_set_visible (button->indicator_node, visible);
}
static void
gtk_model_button_set_role (GtkModelButton *button,
GtkButtonRole role)
{
if (role == button->role)
return;
button->role = role;
update_node_name (button);
gtk_model_button_update_state (button);
gtk_widget_queue_draw (GTK_WIDGET (button));
......@@ -266,7 +338,15 @@ gtk_model_button_set_menu_name (GtkModelButton *button,
{
g_free (button->menu_name);
button->menu_name = g_strdup (menu_name);
update_node_name (button);
gtk_model_button_update_state (button);
if (menu_name)
gtk_css_node_add_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_EXPANDER));
else
gtk_css_node_remove_class (button->indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_EXPANDER));
gtk_widget_queue_resize (GTK_WIDGET (button));
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_MENU_NAME]);
}
......@@ -279,6 +359,8 @@ gtk_model_button_set_inverted (GtkModelButton *button,
return;
button->inverted = inverted;
gtk_model_button_update_state (button);
update_node_ordering (button);
gtk_widget_queue_resize (GTK_WIDGET (button));
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_INVERTED]);
}
......@@ -647,16 +729,6 @@ gtk_model_button_get_preferred_height (GtkWidget *widget,
NULL, NULL);
}
static gboolean
indicator_is_left (GtkWidget *widget)
{
GtkModelButton *button = GTK_MODEL_BUTTON (widget);
return ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && !button->inverted) ||
(gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && button->inverted));
}
static void
gtk_model_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
......@@ -764,18 +836,7 @@ gtk_model_button_draw (GtkWidget *widget,
if (model_button->menu_name)
{
GtkStateFlags state;
gtk_style_context_save_named (context, "arrow");
state = gtk_style_context_get_state (context);
state = state & ~(GTK_STATE_FLAG_DIR_LTR|GTK_STATE_FLAG_DIR_RTL);
if (indicator_is_left (widget))
state = state | GTK_STATE_FLAG_DIR_RTL;
else
state = state | GTK_STATE_FLAG_DIR_LTR;
gtk_style_context_set_state (context, state);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
gtk_style_context_save_to_node (context, model_button->indicator_node);
gtk_render_expander (context, cr, x, y, indicator_size, indicator_size);
gtk_style_context_restore (context);
}
......@@ -863,6 +924,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
widget_class->draw = gtk_model_button_draw;
widget_class->destroy = gtk_model_button_destroy;
widget_class->state_flags_changed = gtk_model_button_state_flags_changed;
widget_class->direction_changed = gtk_model_button_direction_changed;
button_class->clicked = gtk_model_button_clicked;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment