box gadget: Redo expand flag handling

We only keep one align flag per child, so it seems odd to
keep separate h/v expand flags. Just keep one expand flag
and interpret it according to orientation. Allow setting
the expand flag for child widgets too, though, so we can
make widget expand without interfering with the recursive
widget expand flag.

Update all callers.

Use the new possibility of expanding child widgets to make
the label of check and radio buttons expand. This fixes
unexpected behavior of these widgets in RTL in some places.

https://bugzilla.gnome.org/show_bug.cgi?id=765742
This commit is contained in:
Matthias Clasen 2016-04-28 21:55:52 -04:00
parent 8a308dd072
commit 2148708917
7 changed files with 67 additions and 101 deletions

View File

@ -49,7 +49,7 @@ typedef gboolean (* ComputeExpandFunc) (GObject *object, GtkOrientation orientat
typedef struct _GtkBoxGadgetChild GtkBoxGadgetChild;
struct _GtkBoxGadgetChild {
GObject *object;
ComputeExpandFunc compute_expand;
gboolean expand;
GtkAlign align;
};
@ -65,6 +65,21 @@ gtk_box_gadget_child_is_visible (GObject *child)
return gtk_css_gadget_get_visible (GTK_CSS_GADGET (child));
}
static gboolean
gtk_box_gadget_child_compute_expand (GtkBoxGadget *gadget,
GtkBoxGadgetChild *child)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
if (child->expand)
return TRUE;
if (GTK_IS_WIDGET (child->object))
return gtk_widget_compute_expand (GTK_WIDGET (child->object), priv->orientation);
return FALSE;
}
static GtkAlign
gtk_box_gadget_child_get_align (GtkBoxGadget *gadget,
GtkBoxGadgetChild *child)
@ -148,7 +163,7 @@ gtk_box_gadget_distribute (GtkBoxGadget *gadget,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
if (gtk_box_gadget_child_is_visible (child->object) &&
child->compute_expand (child->object, priv->orientation))
gtk_box_gadget_child_compute_expand (gadget, child))
n_expand++;
size -= sizes[i].minimum_size;
}
@ -169,7 +184,7 @@ gtk_box_gadget_distribute (GtkBoxGadget *gadget,
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
if (!gtk_box_gadget_child_is_visible (child->object) ||
!child->compute_expand (child->object, priv->orientation))
!gtk_box_gadget_child_compute_expand (gadget, child))
continue;
sizes[i].minimum_size += size / n_expand;
@ -631,17 +646,17 @@ get_css_node (GObject *child)
}
static void
gtk_box_gadget_insert_object (GtkBoxGadget *gadget,
int pos,
GObject *object,
ComputeExpandFunc compute_expand_func,
GtkAlign align)
gtk_box_gadget_insert_object (GtkBoxGadget *gadget,
int pos,
GObject *object,
gboolean expand,
GtkAlign align)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
GtkBoxGadgetChild child;
child.object = g_object_ref (object);
child.compute_expand = compute_expand_func;
child.expand = expand;
child.align = align;
if (pos < 0 || pos >= priv->children->len)
@ -661,15 +676,11 @@ gtk_box_gadget_insert_object (GtkBoxGadget *gadget,
}
void
gtk_box_gadget_insert_widget (GtkBoxGadget *gadget,
int pos,
GtkWidget *widget)
gtk_box_gadget_insert_widget (GtkBoxGadget *gadget,
int pos,
GtkWidget *widget)
{
gtk_box_gadget_insert_object (gadget,
pos,
G_OBJECT (widget),
(ComputeExpandFunc) gtk_widget_compute_expand,
GTK_ALIGN_FILL);
gtk_box_gadget_insert_object (gadget, pos, G_OBJECT (widget), FALSE, GTK_ALIGN_FILL);
}
static GtkBoxGadgetChild *
@ -718,34 +729,11 @@ gtk_box_gadget_remove_widget (GtkBoxGadget *gadget,
gtk_box_gadget_remove_object (gadget, G_OBJECT (widget));
}
static gboolean
only_horizontal (GObject *object,
GtkOrientation orientation)
{
return orientation == GTK_ORIENTATION_HORIZONTAL;
}
static gboolean
only_vertical (GObject *object,
GtkOrientation orientation)
{
return orientation == GTK_ORIENTATION_VERTICAL;
}
static ComputeExpandFunc
expand_func_from_flags (gboolean hexpand,
gboolean vexpand)
{
return hexpand ? (vexpand ? (ComputeExpandFunc) gtk_true : only_horizontal)
: (vexpand ? only_vertical : (ComputeExpandFunc) gtk_false);
}
void
gtk_box_gadget_insert_gadget_before (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align)
{
/* Insert at the end if no sibling specified */
@ -754,15 +742,14 @@ gtk_box_gadget_insert_gadget_before (GtkBoxGadget *gadget,
if (sibling)
gtk_box_gadget_find_object (gadget, G_OBJECT (sibling), &pos);
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, hexpand, vexpand, align);
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, expand, align);
}
void
gtk_box_gadget_insert_gadget_after (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align)
{
/* Insert at the beginning if no sibling specified */
@ -771,25 +758,17 @@ gtk_box_gadget_insert_gadget_after (GtkBoxGadget *gadget,
if (sibling && gtk_box_gadget_find_object (gadget, G_OBJECT (sibling), &pos))
pos++;
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, hexpand, vexpand, align);
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, expand, align);
}
void
gtk_box_gadget_insert_gadget (GtkBoxGadget *gadget,
int pos,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align)
{
ComputeExpandFunc func;
func = expand_func_from_flags (hexpand, vexpand);
gtk_box_gadget_insert_object (gadget,
pos,
G_OBJECT (cssgadget),
func,
align);
gtk_box_gadget_insert_object (gadget, pos, G_OBJECT (cssgadget), expand, align);
}
void
@ -821,34 +800,31 @@ gtk_box_gadget_reverse_children (GtkBoxGadget *gadget)
void
gtk_box_gadget_set_gadget_expand (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand)
GObject *object,
gboolean expand)
{
GtkBoxGadgetChild *child;
ComputeExpandFunc func;
child = gtk_box_gadget_find_object (gadget, G_OBJECT (cssgadget), NULL);
child = gtk_box_gadget_find_object (gadget, object, NULL);
if (!child)
return;
func = expand_func_from_flags (hexpand, vexpand);
if (child->compute_expand == func)
if (child->expand == expand)
return;
child->compute_expand = func;
child->expand = expand;
gtk_css_gadget_queue_resize (GTK_CSS_GADGET (gadget));
}
void
gtk_box_gadget_set_gadget_align (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget,
GObject *object,
GtkAlign align)
{
GtkBoxGadgetChild *child;
child = gtk_box_gadget_find_object (gadget, G_OBJECT (cssgadget), NULL);
child = gtk_box_gadget_find_object (gadget, object, NULL);
if (!child)
return;

View File

@ -73,20 +73,17 @@ void gtk_box_gadget_remove_widget (GtkBoxGadget
void gtk_box_gadget_insert_gadget (GtkBoxGadget *gadget,
int pos,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_insert_gadget_before (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_insert_gadget_after (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_remove_gadget (GtkBoxGadget *gadget,
@ -94,11 +91,10 @@ void gtk_box_gadget_remove_gadget (GtkBoxGadget
void gtk_box_gadget_reverse_children (GtkBoxGadget *gadget);
void gtk_box_gadget_set_gadget_expand (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget,
gboolean hexpand,
gboolean vexpand);
GObject *object,
gboolean expand);
void gtk_box_gadget_set_gadget_align (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget,
GObject *object,
GtkAlign align);
G_END_DECLS

View File

@ -184,6 +184,7 @@ gtk_check_button_add (GtkContainer *container,
pos = gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL ? 0 : 1;
gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), pos, widget);
gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->gadget), G_OBJECT (widget), TRUE);
}
static void
@ -324,7 +325,7 @@ gtk_check_button_init (GtkCheckButton *check_button)
priv->gadget,
NULL);
gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size");
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->indicator_gadget, FALSE, FALSE, GTK_ALIGN_BASELINE);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->indicator_gadget, FALSE, GTK_ALIGN_BASELINE);
gtk_check_button_update_node_state (GTK_WIDGET (check_button));
}

View File

@ -451,7 +451,7 @@ gtk_expander_init (GtkExpander *expander)
NULL);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->title_gadget), GTK_ORIENTATION_HORIZONTAL);
gtk_box_gadget_set_draw_focus (GTK_BOX_GADGET (priv->title_gadget), TRUE);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), -1, priv->title_gadget, FALSE, FALSE, GTK_ALIGN_START);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), -1, priv->title_gadget, FALSE, GTK_ALIGN_START);
priv->arrow_gadget = gtk_builtin_icon_new ("arrow",
GTK_WIDGET (expander),
@ -460,7 +460,7 @@ gtk_expander_init (GtkExpander *expander)
gtk_css_gadget_add_class (priv->arrow_gadget, GTK_STYLE_CLASS_HORIZONTAL);
gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->arrow_gadget), "expander-size");
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->title_gadget), -1, priv->arrow_gadget, FALSE, FALSE, GTK_ALIGN_CENTER);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->title_gadget), -1, priv->arrow_gadget, FALSE, GTK_ALIGN_CENTER);
gtk_drag_dest_set (GTK_WIDGET (expander), 0, NULL, 0, 0);
gtk_drag_dest_set_track_motion (GTK_WIDGET (expander), TRUE);
@ -785,7 +785,7 @@ gtk_expander_direction_changed (GtkWidget *widget,
align = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
gtk_box_gadget_remove_gadget (GTK_BOX_GADGET (priv->gadget), priv->title_gadget);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->title_gadget, FALSE, FALSE, align);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->title_gadget, FALSE, align);
gtk_box_gadget_set_allocate_reverse (GTK_BOX_GADGET (priv->title_gadget),
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);

View File

@ -1321,7 +1321,7 @@ gtk_notebook_init (GtkNotebook *notebook)
NULL,
NULL);
gtk_css_gadget_set_state (priv->stack_gadget, gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), -1, priv->stack_gadget, TRUE, TRUE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), -1, priv->stack_gadget, TRUE, GTK_ALIGN_FILL);
priv->header_gadget = gtk_box_gadget_new ("header",
GTK_WIDGET (notebook),
@ -1330,7 +1330,7 @@ gtk_notebook_init (GtkNotebook *notebook)
gtk_css_gadget_add_class (priv->header_gadget, GTK_STYLE_CLASS_TOP);
gtk_css_gadget_set_state (priv->header_gadget, gtk_css_node_get_state (widget_node));
gtk_css_gadget_set_visible (priv->header_gadget, FALSE);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, GTK_ALIGN_FILL);
priv->tabs_gadget = gtk_css_custom_gadget_new ("tabs",
GTK_WIDGET (notebook),
@ -1342,7 +1342,7 @@ gtk_notebook_init (GtkNotebook *notebook)
NULL,
NULL);
gtk_css_gadget_set_state (priv->tabs_gadget, gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->header_gadget), 0, priv->tabs_gadget, TRUE, TRUE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->header_gadget), 0, priv->tabs_gadget, TRUE, GTK_ALIGN_FILL);
}
static void
@ -7032,7 +7032,7 @@ gtk_notebook_update_tab_pos (GtkNotebook *notebook)
{
case GTK_POS_TOP:
if (priv->show_tabs)
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_set_draw_reverse (GTK_BOX_GADGET (priv->gadget), TRUE);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_VERTICAL);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->header_gadget), GTK_ORIENTATION_HORIZONTAL);
@ -7040,7 +7040,7 @@ gtk_notebook_update_tab_pos (GtkNotebook *notebook)
case GTK_POS_BOTTOM:
if (priv->show_tabs)
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 1, priv->header_gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 1, priv->header_gadget, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_set_draw_reverse (GTK_BOX_GADGET (priv->gadget), FALSE);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_VERTICAL);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->header_gadget), GTK_ORIENTATION_HORIZONTAL);
@ -7048,7 +7048,7 @@ gtk_notebook_update_tab_pos (GtkNotebook *notebook)
case GTK_POS_LEFT:
if (priv->show_tabs)
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->header_gadget, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_set_draw_reverse (GTK_BOX_GADGET (priv->gadget), TRUE);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->header_gadget), GTK_ORIENTATION_VERTICAL);
@ -7056,7 +7056,7 @@ gtk_notebook_update_tab_pos (GtkNotebook *notebook)
case GTK_POS_RIGHT:
if (priv->show_tabs)
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 1, priv->header_gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 1, priv->header_gadget, FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_set_draw_reverse (GTK_BOX_GADGET (priv->gadget), FALSE);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL);
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->header_gadget), GTK_ORIENTATION_VERTICAL);

View File

@ -671,13 +671,6 @@ gtk_range_sync_orientation (GtkRange *range)
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (range));
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (range));
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->contents_gadget), orientation);
if (orientation == GTK_ORIENTATION_VERTICAL)
gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->contents_gadget),
priv->trough_gadget, FALSE, TRUE);
else
gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->contents_gadget),
priv->trough_gadget, TRUE, FALSE);
}
static void
@ -825,7 +818,7 @@ gtk_range_init (GtkRange *range)
gtk_css_gadget_set_state (priv->trough_gadget,
gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->contents_gadget), -1, priv->trough_gadget,
TRUE, FALSE, GTK_ALIGN_CENTER);
TRUE, GTK_ALIGN_CENTER);
priv->slider_gadget = gtk_builtin_icon_new ("slider",
GTK_WIDGET (range),
@ -3964,7 +3957,7 @@ sync_stepper_gadget (GtkRange *range,
gtk_css_gadget_set_state (gadget, gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget_after (GTK_BOX_GADGET (priv->contents_gadget), prev_sibling,
gadget, FALSE, FALSE, GTK_ALIGN_FILL);
gadget, FALSE, GTK_ALIGN_FILL);
*gadget_ptr = gadget;
}

View File

@ -756,10 +756,10 @@ update_node_ordering (GtkSpinButton *spin_button)
gtk_box_gadget_remove_gadget (GTK_BOX_GADGET (priv->gadget), priv->down_button);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
up_button_pos, priv->up_button,
FALSE, TRUE, GTK_ALIGN_FILL);
FALSE, GTK_ALIGN_FILL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
down_button_pos, priv->down_button,
FALSE, TRUE, GTK_ALIGN_FILL);
FALSE, GTK_ALIGN_FILL);
}
static void
@ -802,9 +802,9 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
gtk_css_node_set_state (entry_node, gtk_css_node_get_state (widget_node));
gtk_css_gadget_set_node (gtk_entry_get_gadget (GTK_ENTRY (spin_button)), entry_node);
g_object_unref (entry_node);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
-1, gtk_entry_get_gadget (GTK_ENTRY (spin_button)),
TRUE, FALSE, GTK_ALIGN_FILL);
TRUE, GTK_ALIGN_FILL);
priv->down_button = gtk_icon_helper_new_named ("button",
GTK_WIDGET (spin_button));
@ -815,7 +815,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->down_button), gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
-1, priv->down_button,
FALSE, TRUE, GTK_ALIGN_FILL);
FALSE, GTK_ALIGN_FILL);
priv->up_button = gtk_icon_helper_new_named ("button",
GTK_WIDGET (spin_button));
@ -826,7 +826,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->down_button), gtk_css_node_get_state (widget_node));
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget),
-1, priv->up_button,
FALSE, TRUE, GTK_ALIGN_FILL);
FALSE, GTK_ALIGN_FILL);
gtk_spin_button_set_adjustment (spin_button, NULL);