Compare commits

...

12 Commits

Author SHA1 Message Date
Matthias Clasen
11140f8ba9 Queue an expand recompute if scrollbar visibility changes 2010-10-11 22:35:28 -04:00
Matthias Clasen
ffd079a411 Queue an expand recompute if scrollbar visibility changes 2010-10-11 19:46:48 -04:00
Matthias Clasen
175f361d33 Unify handling of GtkWindow::resizable property 2010-10-11 17:23:01 -04:00
Matthias Clasen
406d1981be Support GtkWidget expand properties in GtkScrolledWindow
Always expand if a scrollbar is visible, otherwise inherit
the contents expand flag.
2010-10-11 15:39:47 -04:00
Matthias Clasen
f0e7c9fc64 Support GtkWidget expand properties in GtkNotebook
We expand a tab if either tab-expand is set, or the generic widget
expand property in the correct direction is set. And we do not
propagate expand flags from tab labels to the notebook, only
the expand flags from the pages.
2010-10-11 15:23:03 -04:00
Matthias Clasen
8017a12b46 Remove expand child properties from GtkWrapBox
Instead, use generic widget expand properties.
2010-10-11 14:44:43 -04:00
Matthias Clasen
1f7966c143 Support GtkWidget expand properties in GtkTable
We expand a child when it either has the table-specific expand flag
or the generic expand property set. Override compute_expand so that
it also takes the table-specific expand flags of children into
account.

https://bugzilla.gnome.org/show_bug.cgi?id=628902
2010-10-11 13:59:44 -04:00
Matthias Clasen
a0950f0f54 Set fill options on all children 2010-10-11 13:56:36 -04:00
Matthias Clasen
f618f781b9 Add a GtkTable testcase 2010-10-11 13:26:11 -04:00
Havoc Pennington
5a11341c19 add tests/testexpand.c used to test the expand props on GtkWidget
There are two colored boxes with toggle buttons nested
inside several GtkBox. Toggling these to expand mode
should automatically propagate expansion up through
the several GtkBox such that resizing the window
results in resizing the colored boxes.

https://bugzilla.gnome.org/show_bug.cgi?id=628902
2010-09-25 11:53:12 -04:00
Havoc Pennington
9c2dde1c27 Support GtkWidget expand properties in GtkBox
This consists of:
* expand a child if either child->expand || gtk_widget_get_expand(child)
* override compute_expand so that child->expand will cause us to
  return TRUE for gtk_widget_get_expand()

https://bugzilla.gnome.org/show_bug.cgi?id=628902
2010-09-25 11:53:07 -04:00
Havoc Pennington
23715e121a Add horizontal and vertical expand flags, compute_expand() to GtkWidget
GtkWidget now has flags for horizontal and vertical expand, and
a compute_expand() method. compute_expand() is used by containers
to set a default expand flag. (If a widget has expand set explicitly,
it always overrides the results of compute_expand.)

GtkContainer has a default implementation of compute_expand which
simply walks over all child widgets and sets expand=TRUE
if any child is expanding.

The overall effect is that you only have to set expand on
leaf nodes in the widget tree, while previously you had to
set expand all the way up the tree as you packed every
container. Also, now containers need not have their own child
properties for expand.

For old containers which do have "expand" child properties,
they should override compute_expand and include the child
properties in whether the container is expand=TRUE.
Also, the old container should use
"child_prop_expand || gtk_widget_compute_expand()" everywhere
it previously used simply "child_prop_expand"

https://bugzilla.gnome.org/show_bug.cgi?id=628902
2010-09-25 11:52:58 -04:00
15 changed files with 1247 additions and 255 deletions

View File

@@ -4510,7 +4510,6 @@ gtk_wrap_box_get_type G_GNUC_CONST
gtk_wrap_box_get_vertical_spacing
gtk_wrap_box_insert_child
gtk_wrap_box_new
gtk_wrap_box_packing_get_type
gtk_wrap_box_reorder_child
gtk_wrap_box_set_allocation_mode
gtk_wrap_box_set_horizontal_spacing

View File

@@ -141,6 +141,10 @@ struct _GtkBoxChild
static void gtk_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_box_compute_expand (GtkWidget *widget,
gboolean *hexpand,
gboolean *vexpand);
static void gtk_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -149,7 +153,6 @@ static void gtk_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_box_add (GtkContainer *container,
GtkWidget *widget);
static void gtk_box_remove (GtkContainer *container,
@@ -207,6 +210,7 @@ gtk_box_class_init (GtkBoxClass *class)
object_class->get_property = gtk_box_get_property;
widget_class->size_allocate = gtk_box_size_allocate;
widget_class->compute_expand = gtk_box_compute_expand;
container_class->add = gtk_box_add;
container_class->remove = gtk_box_remove;
@@ -391,7 +395,7 @@ count_expand_children (GtkBox *box,
if (gtk_widget_get_visible (child->widget))
{
*visible_children += 1;
if (child->expand)
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
*expand_children += 1;
}
}
@@ -569,7 +573,7 @@ gtk_box_size_allocate (GtkWidget *widget,
{
child_size = sizes[i].minimum_size + child->padding * 2;
if (child->expand)
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
{
child_size += extra;
@@ -641,6 +645,56 @@ gtk_box_size_allocate (GtkWidget *widget,
}
}
static void
gtk_box_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
GtkBoxPrivate *private = GTK_BOX (widget)->priv;
GList *children;
GtkBoxChild *child;
gboolean our_expand;
gboolean opposite_expand;
GtkOrientation opposite_orientation;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
opposite_orientation = GTK_ORIENTATION_VERTICAL;
else
opposite_orientation = GTK_ORIENTATION_HORIZONTAL;
our_expand = FALSE;
opposite_expand = FALSE;
for (children = private->children; children; children = children->next)
{
child = children->data;
/* we don't recurse into children anymore as soon as we know
* expand=TRUE in an orientation
*/
if (child->expand || (!our_expand && gtk_widget_compute_expand (child->widget, private->orientation)))
our_expand = TRUE;
if (!opposite_expand && gtk_widget_compute_expand (child->widget, opposite_orientation))
opposite_expand = TRUE;
if (our_expand && opposite_expand)
break;
}
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
*hexpand_p = our_expand;
*vexpand_p = opposite_expand;
}
else
{
*hexpand_p = opposite_expand;
*vexpand_p = our_expand;
}
}
static GType
gtk_box_child_type (GtkContainer *container)
{
@@ -1050,7 +1104,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
{
child_size = sizes[i].minimum_size + child->padding * 2;
if (child->expand)
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
{
child_size += extra;
@@ -1547,8 +1601,20 @@ gtk_box_set_child_packing (GtkBox *box,
gtk_widget_freeze_child_notify (child);
if (list)
{
child_info->expand = expand != FALSE;
gtk_widget_child_notify (child, "expand");
gboolean expanded;
expanded = expand != FALSE;
/* avoid setting expand if unchanged, since queue_compute_expand
* can be expensive-ish
*/
if (child_info->expand != expanded)
{
child_info->expand = expand != FALSE;
gtk_widget_queue_compute_expand (GTK_WIDGET (box));
gtk_widget_child_notify (child, "expand");
}
child_info->fill = fill != FALSE;
gtk_widget_child_notify (child, "fill");
child_info->padding = padding;

View File

@@ -94,6 +94,9 @@ static void gtk_container_add_unimplemented (GtkContainer *container
static void gtk_container_remove_unimplemented (GtkContainer *container,
GtkWidget *widget);
static void gtk_container_real_check_resize (GtkContainer *container);
static void gtk_container_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p);
static gboolean gtk_container_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_container_real_set_focus_child (GtkContainer *container,
@@ -237,6 +240,7 @@ gtk_container_class_init (GtkContainerClass *class)
object_class->destroy = gtk_container_destroy;
widget_class->compute_expand = gtk_container_compute_expand;
widget_class->show_all = gtk_container_show_all;
widget_class->hide_all = gtk_container_hide_all;
widget_class->expose_event = gtk_container_expose;
@@ -1832,6 +1836,53 @@ _gtk_container_child_composite_name (GtkContainer *container,
return NULL;
}
typedef struct {
gboolean hexpand;
gboolean vexpand;
} ComputeExpandData;
static void
gtk_container_compute_expand_callback (GtkWidget *widget,
gpointer client_data)
{
ComputeExpandData *data = client_data;
/* note that we don't get_expand on the child if we already know we
* have to expand, so we only recurse into children until we find
* one that expands and then we basically don't do any more
* work. This means that we can leave some children in a
* need_compute_expand state, which is fine, as long as GtkWidget
* doesn't rely on an invariant that "if a child has
* need_compute_expand, its parents also do"
*
* gtk_widget_compute_expand() always returns FALSE if the
* child is !visible so that's taken care of.
*/
data->hexpand = data->hexpand ||
gtk_widget_compute_expand (widget, GTK_ORIENTATION_HORIZONTAL);
data->vexpand = data->vexpand ||
gtk_widget_compute_expand (widget, GTK_ORIENTATION_VERTICAL);
}
static void
gtk_container_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
ComputeExpandData data;
data.hexpand = FALSE;
data.vexpand = FALSE;
gtk_container_forall (GTK_CONTAINER (widget),
gtk_container_compute_expand_callback,
&data);
*hexpand_p = data.hexpand;
*vexpand_p = data.vexpand;
}
static void
gtk_container_real_set_focus_child (GtkContainer *container,
GtkWidget *child)

View File

@@ -581,20 +581,6 @@ typedef enum {
GTK_WRAP_BOX_SPREAD_EXPAND
} GtkWrapBoxSpreading;
/**
* GtkWrapBoxPacking:
* @GTK_WRAP_BOX_H_EXPAND: Whether the child expands horizontally.
* @GTK_WRAP_BOX_V_EXPAND: Whether the child expands vertically.
*
* Specifies how widgets will expand vertically and
* horizontally when placed inside a #GtkWrapBox.
*/
typedef enum
{
GTK_WRAP_BOX_H_EXPAND = 1 << 0,
GTK_WRAP_BOX_V_EXPAND = 1 << 1
} GtkWrapBoxPacking;
G_END_DECLS

View File

@@ -535,6 +535,39 @@ gtk_object_handled_accumulator (GSignalInvocationHint *ihint,
return continue_emission;
}
static void
gtk_notebook_compute_expand (GtkContainer *container,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
GtkNotebook *notebook = GTK_NOTEBOOK (container);
GtkNotebookPrivate *priv = notebook->priv;
gboolean hexpand;
gboolean vexpand;
GList *list;
GtkNotebookPage *page;
hexpand = FALSE;
vexpand = FALSE;
for (list = priv->children; list; list = list->next)
{
page = list->data;
hexpand = hexpand ||
gtk_widget_compute_expand (page->child, GTK_ORIENTATION_HORIZONTAL);
vexpand = vexpand ||
gtk_widget_compute_expand (page->child, GTK_ORIENTATION_VERTICAL);
if (hexpand & vexpand)
break;
}
*hexpand_p = hexpand;
*vexpand_p = vexpand;
}
static void
gtk_notebook_class_init (GtkNotebookClass *class)
{
@@ -573,6 +606,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
widget_class->drag_drop = gtk_notebook_drag_drop;
widget_class->drag_data_get = gtk_notebook_drag_data_get;
widget_class->drag_data_received = gtk_notebook_drag_data_received;
widget_class->compute_expand = gtk_notebook_compute_expand;
container_class->add = gtk_notebook_add;
container_class->remove = gtk_notebook_remove;
@@ -5393,9 +5427,14 @@ gtk_notebook_calculate_shown_tabs (GtkNotebook *notebook,
}
else /* !show_arrows */
{
GtkOrientation tab_expand_orientation;
gint c = 0;
*n = 0;
if (priv->tab_pos == GTK_POS_TOP || priv->tab_pos == GTK_POS_BOTTOM)
tab_expand_orientation = GTK_ORIENTATION_HORIZONTAL;
else
tab_expand_orientation = GTK_ORIENTATION_VERTICAL;
*remaining_space = max - min - tab_overlap - tab_space;
children = priv->children;
priv->first_tab = gtk_notebook_search_page (notebook, NULL,
@@ -5411,7 +5450,8 @@ gtk_notebook_calculate_shown_tabs (GtkNotebook *notebook,
c++;
if (page->expand)
if (page->expand ||
(gtk_widget_compute_expand (page->tab_label, tab_expand_orientation)))
(*n)++;
}
@@ -5471,6 +5511,7 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook *notebook,
guint border_width;
gboolean gap_left, packing_changed;
GtkAllocation child_allocation = { 0, };
GtkOrientation tab_expand_orientation;
widget = GTK_WIDGET (notebook);
container = GTK_CONTAINER (notebook);
@@ -5520,6 +5561,11 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook *notebook,
bottom_y = top_y + priv->cur_page->allocation.height;
gap_left = packing_changed = FALSE;
if (priv->tab_pos == GTK_POS_TOP || priv->tab_pos == GTK_POS_BOTTOM)
tab_expand_orientation = GTK_ORIENTATION_HORIZONTAL;
else
tab_expand_orientation = GTK_ORIENTATION_VERTICAL;
while (*children && *children != last_child)
{
page = (*children)->data;
@@ -5546,7 +5592,7 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook *notebook,
continue;
tab_extra_space = 0;
if (*expanded_tabs && (showarrow || page->expand || priv->homogeneous))
if (*expanded_tabs && (showarrow || page->expand || gtk_widget_compute_expand (page->tab_label, tab_expand_orientation) || priv->homogeneous))
{
tab_extra_space = *remaining_space / *expanded_tabs;
*remaining_space -= tab_extra_space;

View File

@@ -150,6 +150,9 @@ static void gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjus
gpointer data);
static void gtk_scrolled_window_update_real_placement (GtkScrolledWindow *scrolled_window);
static void gtk_scrolled_window_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p);
static void gtk_scrolled_window_size_request_init (GtkSizeRequestIface *iface);
static void gtk_scrolled_window_get_width (GtkSizeRequest *widget,
@@ -229,6 +232,7 @@ gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
widget_class->size_allocate = gtk_scrolled_window_size_allocate;
widget_class->scroll_event = gtk_scrolled_window_scroll_event;
widget_class->focus = gtk_scrolled_window_focus;
widget_class->compute_expand = gtk_scrolled_window_compute_expand;
container_class->add = gtk_scrolled_window_add;
container_class->remove = gtk_scrolled_window_remove;
@@ -1388,7 +1392,9 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
gboolean scrollbars_within_bevel;
gint scrollbar_spacing;
guint border_width;
gboolean hscrollbar_was_visible;
gboolean vscrollbar_was_visible;
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
g_return_if_fail (allocation != NULL);
@@ -1405,6 +1411,9 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
gtk_widget_set_allocation (widget, allocation);
hscrollbar_was_visible = priv->hscrollbar_visible;
vscrollbar_was_visible = priv->vscrollbar_visible;
if (priv->hscrollbar_policy == GTK_POLICY_ALWAYS)
priv->hscrollbar_visible = TRUE;
else if (priv->hscrollbar_policy == GTK_POLICY_NEVER)
@@ -1445,6 +1454,10 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
priv->hscrollbar_visible = TRUE;
priv->vscrollbar_visible = TRUE;
if (hscrollbar_was_visible != priv->hscrollbar_visible ||
vscrollbar_was_visible != priv->vscrollbar_visible)
gtk_widget_queue_compute_expand (widget);
/* a new resize is already queued at this point,
* so we will immediatedly get reinvoked
*/
@@ -1463,6 +1476,10 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
}
if (hscrollbar_was_visible != priv->hscrollbar_visible ||
vscrollbar_was_visible != priv->vscrollbar_visible)
gtk_widget_queue_compute_expand (widget);
if (priv->hscrollbar_visible)
{
GtkRequisition hscrollbar_requisition;
@@ -1662,7 +1679,10 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
priv->hscrollbar_visible = (adjustment->upper - adjustment->lower >
adjustment->page_size);
if (priv->hscrollbar_visible != visible)
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
{
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
gtk_widget_queue_compute_expand (GTK_WIDGET (scrolled_window));
}
}
}
else if (priv->vscrollbar &&
@@ -1676,7 +1696,10 @@ gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
priv->vscrollbar_visible = (adjustment->upper - adjustment->lower >
adjustment->page_size);
if (priv->vscrollbar_visible != visible)
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
{
gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
gtk_widget_queue_compute_expand (GTK_WIDGET (scrolled_window));
}
}
}
}
@@ -1811,6 +1834,23 @@ _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window)
}
}
static void
gtk_scrolled_window_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
GtkScrolledWindowPrivate *priv = scrolled_window->priv;
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (scrolled_window));
*hexpand_p = priv->hscrollbar_visible ||
gtk_widget_compute_expand (child, GTK_ORIENTATION_HORIZONTAL);
*vexpand_p = priv->vscrollbar_visible ||
gtk_widget_compute_expand (child, GTK_ORIENTATION_VERTICAL);
}
static void
gtk_scrolled_window_size_request_init (GtkSizeRequestIface *iface)

View File

@@ -78,6 +78,9 @@ static void gtk_table_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_table_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_table_compute_expand (GtkWidget *widget,
gboolean *hexpand,
gboolean *vexpand);
static void gtk_table_add (GtkContainer *container,
GtkWidget *widget);
static void gtk_table_remove (GtkContainer *container,
@@ -133,6 +136,7 @@ gtk_table_class_init (GtkTableClass *class)
widget_class->size_request = gtk_table_size_request;
widget_class->size_allocate = gtk_table_size_allocate;
widget_class->compute_expand = gtk_table_compute_expand;
container_class->add = gtk_table_add;
container_class->remove = gtk_table_remove;
@@ -246,6 +250,43 @@ gtk_table_class_init (GtkTableClass *class)
g_type_class_add_private (class, sizeof (GtkTablePrivate));
}
static void
gtk_table_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
GtkTable *table = GTK_TABLE (widget);
GtkTablePrivate *priv = table->priv;
GList *list;
GtkTableChild *child;
gboolean hexpand;
gboolean vexpand;
hexpand = FALSE;
vexpand = FALSE;
for (list = priv->children; list; list = list->next)
{
child = list->data;
if (!hexpand)
hexpand = child->xexpand ||
gtk_widget_compute_expand (child->widget,
GTK_ORIENTATION_HORIZONTAL);
if (!vexpand)
vexpand = child->yexpand ||
gtk_widget_compute_expand (child->widget,
GTK_ORIENTATION_VERTICAL);
if (hexpand && vexpand)
break;
}
*hexpand_p = hexpand;
*vexpand_p = vexpand;
}
static GType
gtk_table_child_type (GtkContainer *container)
{
@@ -373,14 +414,36 @@ gtk_table_set_child_property (GtkContainer *container,
gtk_table_resize (table, table_child->bottom_attach, priv->ncols);
break;
case CHILD_PROP_X_OPTIONS:
table_child->xexpand = (g_value_get_flags (value) & GTK_EXPAND) != 0;
table_child->xshrink = (g_value_get_flags (value) & GTK_SHRINK) != 0;
table_child->xfill = (g_value_get_flags (value) & GTK_FILL) != 0;
{
gboolean xexpand;
xexpand = (g_value_get_flags (value) & GTK_EXPAND) != 0;
if (table_child->xexpand != xexpand)
{
table_child->xexpand = xexpand;
gtk_widget_queue_compute_expand (GTK_WIDGET (table));
}
table_child->xshrink = (g_value_get_flags (value) & GTK_SHRINK) != 0;
table_child->xfill = (g_value_get_flags (value) & GTK_FILL) != 0;
}
break;
case CHILD_PROP_Y_OPTIONS:
table_child->yexpand = (g_value_get_flags (value) & GTK_EXPAND) != 0;
table_child->yshrink = (g_value_get_flags (value) & GTK_SHRINK) != 0;
table_child->yfill = (g_value_get_flags (value) & GTK_FILL) != 0;
{
gboolean yexpand;
yexpand = (g_value_get_flags (value) & GTK_EXPAND) != 0;
if (table_child->yexpand != yexpand)
{
table_child->yexpand = yexpand;
gtk_widget_queue_compute_expand (GTK_WIDGET (table));
}
table_child->yshrink = (g_value_get_flags (value) & GTK_SHRINK) != 0;
table_child->yfill = (g_value_get_flags (value) & GTK_FILL) != 0;
}
break;
case CHILD_PROP_X_PADDING:
table_child->xpadding = g_value_get_uint (value);
@@ -1042,10 +1105,12 @@ gtk_table_size_request_init (GtkTable *table)
gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
NULL, NULL);
if (child->left_attach == (child->right_attach - 1) && child->xexpand)
if (child->left_attach == (child->right_attach - 1) &&
(child->xexpand || gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_HORIZONTAL)))
priv->cols[child->left_attach].expand = TRUE;
if (child->top_attach == (child->bottom_attach - 1) && child->yexpand)
if (child->top_attach == (child->bottom_attach - 1) &&
(child->yexpand || gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_VERTICAL)))
priv->rows[child->top_attach].expand = TRUE;
}
}
@@ -1292,7 +1357,7 @@ gtk_table_size_allocate_init (GtkTable *table)
{
if (child->left_attach == (child->right_attach - 1))
{
if (child->xexpand)
if (child->xexpand || gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_HORIZONTAL))
priv->cols[child->left_attach].expand = TRUE;
if (!child->xshrink)
@@ -1303,7 +1368,7 @@ gtk_table_size_allocate_init (GtkTable *table)
if (child->top_attach == (child->bottom_attach - 1))
{
if (child->yexpand)
if (child->yexpand || gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_VERTICAL))
priv->rows[child->top_attach].expand = TRUE;
if (!child->yshrink)

View File

@@ -146,8 +146,17 @@ struct _GtkWidgetPrivate
*/
guint saved_state : 3;
/* Expand-related flags */
guint need_compute_expand : 1; /* Need to recompute computed_[hv]_expand */
guint computed_hexpand : 1; /* computed results (composite of child flags) */
guint computed_vexpand : 1;
guint hexpand : 1; /* application-forced expand */
guint vexpand : 1;
guint hexpand_set : 1; /* whether to use application-forced */
guint vexpand_set : 1; /* instead of computing from children */
/* unused bits in our 32-bit block */
guint reserved : 10;
guint reserved : 3;
/* The widget's name. If the widget does not have a name
* (the name is NULL), then its name (as returned by
@@ -285,7 +294,12 @@ enum {
PROP_MARGIN_RIGHT,
PROP_MARGIN_TOP,
PROP_MARGIN_BOTTOM,
PROP_MARGIN
PROP_MARGIN,
PROP_HEXPAND,
PROP_VEXPAND,
PROP_HEXPAND_SET,
PROP_VEXPAND_SET,
PROP_EXPAND
};
typedef struct _GtkStateData GtkStateData;
@@ -1004,6 +1018,81 @@ gtk_widget_class_init (GtkWidgetClass *klass)
0,
GTK_PARAM_READWRITE));
/**
* GtkWidget:hexpand
*
* Whether to expand horizontally. See gtk_widget_set_hexpand().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HEXPAND,
g_param_spec_boolean ("hexpand",
P_("Horizontal Expand"),
P_("Whether widget wants more horizontal space"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:hexpand-set
*
* Whether to use the GtkWidget:hexpand property. See gtk_widget_get_hexpand_set().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_HEXPAND_SET,
g_param_spec_boolean ("hexpand-set",
P_("Horizontal Expand Set"),
P_("Whether to use the hexpand property"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:vexpand
*
* Whether to expand vertically. See gtk_widget_set_vexpand().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_VEXPAND,
g_param_spec_boolean ("vexpand",
P_("Vertical Expand"),
P_("Whether widget wants more vertical space"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:vexpand-set
*
* Whether to use the GtkWidget:vexpand property. See gtk_widget_get_vexpand_set().
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_VEXPAND_SET,
g_param_spec_boolean ("vexpand-set",
P_("Vertical Expand Set"),
P_("Whether to use the vexpand property"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget:expand
*
* Whether to expand in both directions. Setting this sets both GtkWidget:hexpand and GtkWidget:vexpand
*
* Since: 3.0
*/
g_object_class_install_property (gobject_class,
PROP_EXPAND,
g_param_spec_boolean ("expand",
P_("Expand Both"),
P_("Whether widget wants to expand in both directions"),
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkWidget::show:
* @widget: the object which received the signal.
@@ -2967,6 +3056,24 @@ gtk_widget_set_property (GObject *object,
gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
g_object_thaw_notify (G_OBJECT (widget));
break;
case PROP_HEXPAND:
gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
break;
case PROP_HEXPAND_SET:
gtk_widget_set_hexpand_set (widget, g_value_get_boolean (value));
break;
case PROP_VEXPAND:
gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
break;
case PROP_VEXPAND_SET:
gtk_widget_set_vexpand_set (widget, g_value_get_boolean (value));
break;
case PROP_EXPAND:
g_object_freeze_notify (G_OBJECT (widget));
gtk_widget_set_hexpand (widget, g_value_get_boolean (value));
gtk_widget_set_vexpand (widget, g_value_get_boolean (value));
g_object_thaw_notify (G_OBJECT (widget));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3111,6 +3218,23 @@ gtk_widget_get_property (GObject *object,
}
}
break;
case PROP_HEXPAND:
g_value_set_boolean (value, gtk_widget_get_hexpand (widget));
break;
case PROP_HEXPAND_SET:
g_value_set_boolean (value, gtk_widget_get_hexpand_set (widget));
break;
case PROP_VEXPAND:
g_value_set_boolean (value, gtk_widget_get_vexpand (widget));
break;
case PROP_VEXPAND_SET:
g_value_set_boolean (value, gtk_widget_get_vexpand_set (widget));
break;
case PROP_EXPAND:
g_value_set_boolean (value,
gtk_widget_get_hexpand (widget) &&
gtk_widget_get_vexpand (widget));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3148,6 +3272,15 @@ gtk_widget_init (GtkWidget *widget)
GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED);
GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
/* this will be set to TRUE if the widget gets a child or if the
* expand flag is set on the widget, but until one of those happen
* we know the expand is already properly FALSE.
*
* We really want to default FALSE here to avoid computing expand
* all over the place while initially building a widget tree.
*/
priv->need_compute_expand = FALSE;
priv->style = gtk_widget_get_default_style ();
g_object_ref (priv->style);
}
@@ -3381,13 +3514,26 @@ gtk_widget_unparent (GtkWidget *widget)
old_parent = priv->parent;
priv->parent = NULL;
gtk_widget_set_parent_window (widget, NULL);
/* parent may no longer expand if the removed
* child was expand=TRUE and could therefore
* be forcing it to.
*/
if (gtk_widget_get_visible (widget) &&
(priv->need_compute_expand ||
priv->computed_hexpand ||
priv->computed_vexpand))
{
gtk_widget_queue_compute_expand (old_parent);
}
g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
if (toplevel)
{
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
g_object_unref (toplevel);
}
g_object_notify (G_OBJECT (widget), "parent");
g_object_thaw_notify (G_OBJECT (widget));
if (!priv->parent)
@@ -3474,6 +3620,17 @@ gtk_widget_show (GtkWidget *widget)
g_object_ref (widget);
if (!gtk_widget_is_toplevel (widget))
gtk_widget_queue_resize (widget);
/* see comment in set_parent() for why this should and can be
* conditional
*/
if (widget->priv->need_compute_expand ||
widget->priv->computed_hexpand ||
widget->priv->computed_vexpand)
{
gtk_widget_queue_compute_expand (widget);
}
g_signal_emit (widget, widget_signals[SHOW], 0);
g_object_notify (G_OBJECT (widget), "visible");
g_object_unref (widget);
@@ -3560,6 +3717,14 @@ gtk_widget_hide (GtkWidget *widget)
if (toplevel != widget && gtk_widget_is_toplevel (toplevel))
_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
/* a parent may now be expand=FALSE since we're hidden. */
if (widget->priv->need_compute_expand ||
widget->priv->computed_hexpand ||
widget->priv->computed_vexpand)
{
gtk_widget_queue_compute_expand (widget);
}
g_signal_emit (widget, widget_signals[HIDE], 0);
if (!gtk_widget_is_toplevel (widget))
gtk_widget_queue_resize (widget);
@@ -6828,6 +6993,24 @@ gtk_widget_set_parent (GtkWidget *widget,
gtk_widget_queue_resize (widget);
}
/* child may cause parent's expand to change, if the child is
* expanded. If child is not expanded, then it can't modify the
* parent's expand. If the child becomes expanded later then it will
* queue compute_expand then. This optimization plus defaulting
* newly-constructed widgets to need_compute_expand=FALSE should
* mean that initially building a widget tree doesn't have to keep
* walking up setting need_compute_expand on parents over and over.
*
* We can't change a parent to need to expand unless we're visible.
*/
if (gtk_widget_get_visible (widget) &&
(priv->need_compute_expand ||
priv->computed_hexpand ||
priv->computed_vexpand))
{
gtk_widget_queue_compute_expand (parent);
}
}
/**
@@ -10921,6 +11104,424 @@ gtk_widget_ref_accessible (AtkImplementor *implementor)
return accessible;
}
/*
* Expand flag management
*/
static void
gtk_widget_update_computed_expand (GtkWidget *widget)
{
GtkWidgetPrivate *priv;
priv = widget->priv;
if (priv->need_compute_expand)
{
gboolean h, v;
if (priv->hexpand_set)
h = priv->hexpand;
else
h = FALSE;
if (priv->vexpand_set)
v = priv->vexpand;
else
v = FALSE;
/* we don't need to use compute_expand if both expands are
* forced by the app
*/
if (!(priv->hexpand_set && priv->vexpand_set))
{
if (GTK_WIDGET_GET_CLASS (widget)->compute_expand != NULL)
{
gboolean ignored;
GTK_WIDGET_GET_CLASS (widget)->compute_expand (widget,
priv->hexpand_set ? &ignored : &h,
priv->vexpand_set ? &ignored : &v);
}
}
priv->need_compute_expand = FALSE;
priv->computed_hexpand = h != FALSE;
priv->computed_vexpand = v != FALSE;
}
}
void
gtk_widget_queue_compute_expand (GtkWidget *widget)
{
GtkWidget *parent;
gboolean changed_anything;
if (widget->priv->need_compute_expand)
return;
changed_anything = FALSE;
parent = widget;
while (parent != NULL)
{
if (!parent->priv->need_compute_expand)
{
parent->priv->need_compute_expand = TRUE;
changed_anything = TRUE;
}
/* Note: if we had an invariant that "if a child needs to
* compute expand, its parents also do" then we could stop going
* up when we got to a parent that already needed to
* compute. However, in general we compute expand lazily (as
* soon as we see something in a subtree that is expand, we know
* we're expanding) and so this invariant does not hold and we
* have to always walk all the way up in case some ancestor
* is not currently need_compute_expand.
*/
parent = parent->priv->parent;
}
/* recomputing expand always requires
* a relayout as well
*/
if (changed_anything)
gtk_widget_queue_resize (widget);
}
/**
* gtk_widget_compute_expand:
* @widget: the widget
* @orientation: expand direction
*
* Computes whether a container should give this widget extra space
* when possible. Containers should check this, rather than
* looking at gtk_widget_get_hexpand() or gtk_widget_get_vexpand().
*
* This function already checks whether the widget is visible, so
* visibility does not need to be checked separately. Non-visible
* widgets are not expanded.
*
* The computed expand value uses either the expand setting explicitly
* set on the widget itself, or, if none has been explicitly set,
* the widget may expand if some of its children do.
*
* Return value: whether widget tree rooted here should be expanded
*/
gboolean
gtk_widget_compute_expand (GtkWidget *widget,
GtkOrientation orientation)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
/* We never make a widget expand if not even showing. */
if (!gtk_widget_get_visible (widget))
return FALSE;
gtk_widget_update_computed_expand (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
return widget->priv->computed_hexpand;
}
else
{
return widget->priv->computed_vexpand;
}
}
static void
gtk_widget_set_expand (GtkWidget *widget,
GtkOrientation orientation,
gboolean expand)
{
const char *expand_prop;
const char *expand_set_prop;
gboolean was_both;
GtkWidgetPrivate *priv;
g_return_if_fail (GTK_IS_WIDGET (widget));
priv = widget->priv;
expand = expand != FALSE;
was_both = priv->hexpand && priv->vexpand;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (priv->hexpand_set &&
priv->hexpand == expand)
return;
priv->hexpand_set = TRUE;
priv->hexpand = expand;
expand_prop = "hexpand";
expand_set_prop = "hexpand-set";
}
else
{
if (priv->vexpand_set &&
priv->vexpand == expand)
return;
priv->vexpand_set = TRUE;
priv->vexpand = expand;
expand_prop = "vexpand";
expand_set_prop = "vexpand-set";
}
gtk_widget_queue_compute_expand (widget);
g_object_freeze_notify (G_OBJECT (widget));
g_object_notify (G_OBJECT (widget), expand_prop);
g_object_notify (G_OBJECT (widget), expand_set_prop);
if (was_both != (priv->hexpand && priv->vexpand))
g_object_notify (G_OBJECT (widget), "expand");
g_object_thaw_notify (G_OBJECT (widget));
}
static void
gtk_widget_set_expand_set (GtkWidget *widget,
GtkOrientation orientation,
gboolean set)
{
GtkWidgetPrivate *priv;
const char *prop;
priv = widget->priv;
set = set != FALSE;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (set == priv->hexpand_set)
return;
priv->hexpand_set = set;
prop = "hexpand-set";
}
else
{
if (set == priv->vexpand_set)
return;
priv->vexpand_set = set;
prop = "vexpand-set";
}
gtk_widget_queue_compute_expand (widget);
g_object_notify (G_OBJECT (widget), prop);
}
/**
* gtk_widget_get_hexpand:
* @widget: the widget
*
* Gets whether the widget would like any available extra horizontal
* space. When a user resizes a #GtkWindow, widgets with expand=TRUE
* generally receive the extra space. For example, a list or
* scrollable area or document in your window would often be set to
* expand.
*
* Containers should use gtk_widget_compute_expand() rather than
* this function, to see whether a widget, or any of its children,
* has the expand flag set. If any child of a widget wants to
* expand, the parent may ask to expand also.
*
* This function only looks at the widget's own hexpand flag, rather
* than computing whether the entire widget tree rooted at this widget
* wants to expand.
*
* Return value: whether hexpand flag is set
*/
gboolean
gtk_widget_get_hexpand (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
return widget->priv->hexpand;
}
/**
* gtk_widget_set_hexpand:
* @widget: the widget
* @expand: whether to expand
*
* Sets whether the widget would like any available extra horizontal
* space. When a user resizes a #GtkWindow, widgets with expand=TRUE
* generally receive the extra space. For example, a list or
* scrollable area or document in your window would often be set to
* expand.
*
* Call this function to set the expand flag if you would like your
* widget to become larger horizontally when the window has extra
* room.
*
* By default, widgets automatically expand if any of their children
* want to expand. (To see if a widget will automatically expand given
* its current children and state, call gtk_widget_compute_expand(). A
* container can decide how the expandability of children affects the
* expansion of the container by overriding the compute_expand virtual
* method on #GtkWidget.).
*
* Setting hexpand explicitly with this function will override the
* automatic expand behavior.
*
* This function forces the widget to expand or not to expand,
* regardless of children. The override occurs because
* gtk_widget_set_hexpand() sets the hexpand-set property (see
* gtk_widget_set_hexpand_set()) which causes the widget's hexpand
* value to be used, rather than looking at children and widget state.
*/
void
gtk_widget_set_hexpand (GtkWidget *widget,
gboolean expand)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_widget_set_expand (widget, GTK_ORIENTATION_HORIZONTAL, expand);
}
/**
* gtk_widget_get_hexpand_set:
* @widget: the widget
*
* Gets whether gtk_widget_set_hexpand() has been used to
* explicitly set the expand flag on this widget.
*
* If hexpand is set, then it overrides any computed
* expand value based on child widgets. If hexpand is not
* set, then the expand value depends on whether any
* children of the widget would like to expand.
*
* There are few reasons to use this function, but it's here
* for completeness and consistency.
*
* Return value: whether hexpand has been explicitly set
*/
gboolean
gtk_widget_get_hexpand_set (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
return widget->priv->hexpand_set;
}
/**
* gtk_widget_set_hexpand_set:
* @widget: the widget
* @set: value for hexpand-set property
*
* Sets whether the hexpand flag (see gtk_widget_get_hexpand()) will
* be used.
*
* The hexpand-set property will be set automatically when you call
* gtk_widget_set_hexpand() to set hexpand, so the most likely
* reason to use this function would be to unset an explicit expand
* flag.
*
* If hexpand is set, then it overrides any computed
* expand value based on child widgets. If hexpand is not
* set, then the expand value depends on whether any
* children of the widget would like to expand.
*
* There are few reasons to use this function, but it's here
* for completeness and consistency.
*
* Return value: whether hexpand has been explicitly set
*/
void
gtk_widget_set_hexpand_set (GtkWidget *widget,
gboolean set)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_widget_set_expand_set (widget, GTK_ORIENTATION_HORIZONTAL, set);
}
/**
* gtk_widget_get_vexpand:
* @widget: the widget
*
* Gets whether the widget would like any available extra vertical
* space.
*
* See gtk_widget_get_hexpand() for more detail.
*
* Return value: whether vexpand flag is set
*/
gboolean
gtk_widget_get_vexpand (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
return widget->priv->vexpand;
}
/**
* gtk_widget_set_vexpand:
* @widget: the widget
* @expand: whether to expand
*
* Sets whether the widget would like any available extra vertical
* space.
*
* See gtk_widget_set_hexpand() for more detail.
*/
void
gtk_widget_set_vexpand (GtkWidget *widget,
gboolean expand)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_widget_set_expand (widget, GTK_ORIENTATION_VERTICAL, expand);
}
/**
* gtk_widget_get_vexpand_set:
* @widget: the widget
*
* Gets whether gtk_widget_set_vexpand() has been used to
* explicitly set the expand flag on this widget.
*
* See gtk_widget_get_hexpand_set() for more detail.
*
* Return value: whether vexpand has been explicitly set
*/
gboolean
gtk_widget_get_vexpand_set (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
return widget->priv->vexpand_set;
}
/**
* gtk_widget_set_vexpand_set:
* @widget: the widget
* @set: value for vexpand-set property
*
* Sets whether the vexpand flag (see gtk_widget_get_vexpand()) will
* be used.
*
* See gtk_widget_set_hexpand_set() for more detail.
*
* Return value: whether vexpand has been explicitly set
*/
void
gtk_widget_set_vexpand_set (GtkWidget *widget,
gboolean set)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_widget_set_expand_set (widget, GTK_ORIENTATION_VERTICAL, set);
}
/*
* GtkBuildable implementation
*/

View File

@@ -492,6 +492,9 @@ struct _GtkWidgetClass
GtkTooltip *tooltip);
/*< public >*/
void (* compute_expand) (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p);
void (* adjust_size_request) (GtkWidget *widget,
GtkOrientation orientation,
@@ -752,6 +755,25 @@ GtkClipboard *gtk_widget_get_clipboard (GtkWidget *widget,
GdkPixmap * gtk_widget_get_snapshot (GtkWidget *widget,
GdkRectangle *clip_rect);
/* Expand flags and related support */
gboolean gtk_widget_get_hexpand (GtkWidget *widget);
void gtk_widget_set_hexpand (GtkWidget *widget,
gboolean expand);
gboolean gtk_widget_get_hexpand_set (GtkWidget *widget);
void gtk_widget_set_hexpand_set (GtkWidget *widget,
gboolean set);
gboolean gtk_widget_get_vexpand (GtkWidget *widget);
void gtk_widget_set_vexpand (GtkWidget *widget,
gboolean expand);
gboolean gtk_widget_get_vexpand_set (GtkWidget *widget);
void gtk_widget_set_vexpand_set (GtkWidget *widget,
gboolean set);
void gtk_widget_queue_compute_expand (GtkWidget *widget);
gboolean gtk_widget_compute_expand (GtkWidget *widget,
GtkOrientation orientation);
/* Multidevice support */
gboolean gtk_widget_get_support_multidevice (GtkWidget *widget);
void gtk_widget_set_support_multidevice (GtkWidget *widget,

View File

@@ -1063,8 +1063,7 @@ gtk_window_set_property (GObject *object,
gtk_window_set_startup_id (window, g_value_get_string (value));
break;
case PROP_RESIZABLE:
priv->resizable = g_value_get_boolean (value);
gtk_widget_queue_resize (GTK_WIDGET (window));
gtk_window_set_resizable (window, g_value_get_boolean (value));
break;
case PROP_MODAL:
gtk_window_set_modal (window, g_value_get_boolean (value));
@@ -7495,11 +7494,16 @@ gtk_window_set_resizable (GtkWindow *window,
priv = window->priv;
priv->resizable = (resizable != FALSE);
resizable = (resizable != FALSE);
g_object_notify (G_OBJECT (window), "resizable");
if (priv->resizable != resizable)
{
priv->resizable = (resizable != FALSE);
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
g_object_notify (G_OBJECT (window), "resizable");
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
}
/**

View File

@@ -75,13 +75,6 @@ struct _GtkWrapBoxPrivate
GList *children;
};
struct _GtkWrapBoxChild
{
GtkWidget *widget;
GtkWrapBoxPacking packing;
};
/* GObjectClass */
static void gtk_wrap_box_get_property (GObject *object,
guint prop_id,
@@ -105,16 +98,6 @@ static void gtk_wrap_box_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void gtk_wrap_box_set_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_wrap_box_get_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
GValue *value,
GParamSpec *pspec);
static GType gtk_wrap_box_child_type (GtkContainer *container);
@@ -171,8 +154,6 @@ gtk_wrap_box_class_init (GtkWrapBoxClass *class)
container_class->remove = gtk_wrap_box_remove;
container_class->forall = gtk_wrap_box_forall;
container_class->child_type = gtk_wrap_box_child_type;
container_class->set_child_property = gtk_wrap_box_set_child_property;
container_class->get_child_property = gtk_wrap_box_get_child_property;
gtk_container_class_handle_border_width (container_class);
/* GObjectClass properties */
@@ -293,22 +274,6 @@ gtk_wrap_box_class_init (GtkWrapBoxClass *class)
0,
GTK_PARAM_READWRITE));
/* GtkContainerClass child properties */
/**
* GtkWrapBox:packing:
*
* The #GtkWrapBoxPacking options to specify how to pack a child into the box.
*/
gtk_container_class_install_child_property (container_class,
CHILD_PROP_PACKING,
g_param_spec_flags
("packing",
P_("Packing"),
P_("The packing options to use for this child"),
GTK_TYPE_WRAP_BOX_PACKING, 0,
GTK_PARAM_READWRITE));
g_type_class_add_private (class, sizeof (GtkWrapBoxPrivate));
}
@@ -432,9 +397,9 @@ get_visible_children (GtkWrapBox *box)
for (list = priv->children; list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
GtkWidget *child = list->data;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
i++;
@@ -454,13 +419,12 @@ get_visible_expand_children (GtkWrapBox *box,
for (i = 0, list = cursor; (n_visible > 0 ? i < n_visible : TRUE) && list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
GtkWidget *child = list->data;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if ((orientation == GTK_ORIENTATION_HORIZONTAL && (child->packing & GTK_WRAP_BOX_H_EXPAND) != 0) ||
(orientation == GTK_ORIENTATION_VERTICAL && (child->packing & GTK_WRAP_BOX_V_EXPAND) != 0))
if (gtk_widget_compute_expand (child, orientation))
expand_children++;
i++;
@@ -485,17 +449,17 @@ get_average_item_size (GtkWrapBox *box,
for (list = priv->children; list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint child_min, child_nat;
GtkWidget *child = list->data;
gint child_min, child_nat;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
else
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
max_min_size = MAX (max_min_size, child_min);
@@ -526,18 +490,18 @@ get_largest_size_for_opposing_orientation (GtkWrapBox *box,
for (list = priv->children; list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint child_min, child_nat;
GtkWidget *child = list->data;
gint child_min, child_nat;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child),
item_size,
&child_min, &child_nat);
else
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child),
item_size,
&child_min, &child_nat);
@@ -573,10 +537,10 @@ get_largest_size_for_line_in_opposing_orientation (GtkWrapBox *box,
for (list = cursor, i = 0; list && i < line_length; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint child_min, child_nat, this_item_size;
GtkWidget *child = list->data;
gint child_min, child_nat, this_item_size;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
/* Distribute the extra pixels to the first children in the line
@@ -589,11 +553,11 @@ get_largest_size_for_line_in_opposing_orientation (GtkWrapBox *box,
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child),
this_item_size,
&child_min, &child_nat);
else
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child),
this_item_size,
&child_min, &child_nat);
@@ -648,17 +612,17 @@ get_largest_size_for_free_line_in_opposing_orientation (GtkWrapBox *box,
/* First determine the length of this line in items (how many items fit) */
for (i = 0, list = cursor; size > 0 && list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint child_size;
GtkWidget *child = list->data;
gint child_size;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
NULL, &child_size);
else
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
NULL, &child_size);
if (i > 0)
@@ -680,19 +644,19 @@ get_largest_size_for_free_line_in_opposing_orientation (GtkWrapBox *box,
for (i = 0, list = cursor; i < line_length && list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
GtkWidget *child = list->data;
GtkRequestedSize requested;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
requested.data = child;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&requested.minimum_size,
&requested.natural_size);
else
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&requested.minimum_size,
&requested.natural_size);
@@ -736,16 +700,15 @@ get_largest_size_for_free_line_in_opposing_orientation (GtkWrapBox *box,
* in the opposing orientation */
for (i = 0, list = cursor; i < line_length && list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
GtkWidget *child = list->data;
gint child_min, child_nat;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
g_assert (child == sizes[i].data);
if ((orientation == GTK_ORIENTATION_HORIZONTAL && (child->packing & GTK_WRAP_BOX_H_EXPAND) != 0) ||
(orientation == GTK_ORIENTATION_VERTICAL && (child->packing & GTK_WRAP_BOX_V_EXPAND) != 0) ||
if (gtk_widget_compute_expand (child, orientation) ||
expand_children == 0)
{
sizes[i].minimum_size += expand_per_child;
@@ -757,11 +720,11 @@ get_largest_size_for_free_line_in_opposing_orientation (GtkWrapBox *box,
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child),
sizes[i].minimum_size,
&child_min, &child_nat);
else
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child),
sizes[i].minimum_size,
&child_min, &child_nat);
@@ -787,12 +750,12 @@ get_largest_size_for_free_line_in_opposing_orientation (GtkWrapBox *box,
}
static void
allocate_child (GtkWrapBox *box,
GtkWrapBoxChild *child,
gint item_offset,
gint line_offset,
gint item_size,
gint line_size)
allocate_child (GtkWrapBox *box,
GtkWidget *child,
gint item_offset,
gint line_offset,
gint item_size,
gint line_size)
{
GtkWrapBoxPrivate *priv = box->priv;
GtkAllocation widget_allocation;
@@ -815,7 +778,7 @@ allocate_child (GtkWrapBox *box,
child_allocation.height = item_size;
}
gtk_widget_size_allocate (child->widget, &child_allocation);
gtk_widget_size_allocate (child, &child_allocation);
}
/* fit_aligned_item_requests() helper */
@@ -836,18 +799,18 @@ gather_aligned_item_requests (GtkWrapBox *box,
for (list = priv->children, i = 0; list; list = list->next, i++)
{
GtkWrapBoxChild *child = list->data;
gint child_min, child_nat;
gint position;
GtkWidget *child = list->data;
gint child_min, child_nat;
gint position;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
else
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
/* Get the index and push it over for the last line when spreading to the end */
@@ -870,8 +833,8 @@ gather_aligned_item_requests (GtkWrapBox *box,
}
static GtkRequestedSize *
fit_aligned_item_requests (GtkWrapBox *box,
GtkOrientation orientation,
fit_aligned_item_requests (GtkWrapBox *box,
GtkOrientation orientation,
gint avail_size,
gint item_spacing,
gint *line_length, /* in-out */
@@ -883,7 +846,7 @@ fit_aligned_item_requests (GtkWrapBox *box,
sizes = g_new0 (GtkRequestedSize, *line_length);
/* get the sizes for the initial guess */
try_line_size =
try_line_size =
gather_aligned_item_requests (box, orientation, *line_length, item_spacing, n_children, sizes);
/* Try columnizing the whole thing and adding an item to the end of the line;
@@ -891,7 +854,7 @@ fit_aligned_item_requests (GtkWrapBox *box,
for (try_length = *line_length + 1; try_line_size < avail_size; try_length++)
{
try_sizes = g_new0 (GtkRequestedSize, try_length);
try_line_size = gather_aligned_item_requests (box, orientation, try_length, item_spacing,
try_line_size = gather_aligned_item_requests (box, orientation, try_length, item_spacing,
n_children, try_sizes);
if (try_line_size <= avail_size)
@@ -952,7 +915,7 @@ gtk_wrap_box_size_allocate (GtkWidget *widget,
/*********************************************************
* Deal with ALIGNED/HOMOGENEOUS modes first, start with *
* Deal with ALIGNED/HOMOGENEOUS modes first, start with *
* initial guesses at item/line sizes *
*********************************************************/
if (priv->mode == GTK_WRAP_ALLOCATE_ALIGNED ||
@@ -1144,11 +1107,11 @@ gtk_wrap_box_size_allocate (GtkWidget *widget,
for (i = 0, line_count = 0, list = priv->children; list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint position;
gint this_item_size;
GtkWidget *child = list->data;
gint position;
gint this_item_size;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
/* Get item position */
@@ -1163,7 +1126,7 @@ gtk_wrap_box_size_allocate (GtkWidget *widget,
if (line_spreading == GTK_WRAP_BOX_SPREAD_EVEN)
{
line_offset += extra_per_line;
if (line_count < extra_line_extra)
line_offset++;
}
@@ -1180,7 +1143,7 @@ gtk_wrap_box_size_allocate (GtkWidget *widget,
if (line_spreading == GTK_WRAP_BOX_SPREAD_EXPAND)
{
this_line_size += extra_per_line;
if (line_count < extra_line_extra)
this_line_size++;
}
@@ -1360,8 +1323,8 @@ gtk_wrap_box_size_allocate (GtkWidget *widget,
for (i = 0; i < line_array->len; i++)
{
GtkWrapBoxChild *child = line_sizes[i].data;
gint item_size = line_sizes[i].minimum_size;
GtkWidget *child = line_sizes[i].data;
gint item_size = line_sizes[i].minimum_size;
/* Do the actual allocation */
allocate_child (box, child, item_offset, line_offset, item_size, line_size);
@@ -1407,14 +1370,7 @@ static void
gtk_wrap_box_add (GtkContainer *container,
GtkWidget *widget)
{
gtk_wrap_box_insert_child (GTK_WRAP_BOX (container), widget, -1, 0);
}
static gint
find_child_in_list (GtkWrapBoxChild *child_in_list,
GtkWidget *search)
{
return (child_in_list->widget == search) ? 0 : -1;
gtk_wrap_box_insert_child (GTK_WRAP_BOX (container), widget, -1);
}
static void
@@ -1425,17 +1381,14 @@ gtk_wrap_box_remove (GtkContainer *container,
GtkWrapBoxPrivate *priv = box->priv;
GList *list;
list = g_list_find_custom (priv->children, widget,
(GCompareFunc)find_child_in_list);
list = g_list_find (priv->children, widget);
if (list)
{
GtkWrapBoxChild *child = list->data;
gboolean was_visible = gtk_widget_get_visible (widget);
gtk_widget_unparent (widget);
g_slice_free (GtkWrapBoxChild, child);
priv->children = g_list_delete_link (priv->children, list);
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
@@ -1451,14 +1404,14 @@ gtk_wrap_box_forall (GtkContainer *container,
{
GtkWrapBox *box = GTK_WRAP_BOX (container);
GtkWrapBoxPrivate *priv = box->priv;
GtkWrapBoxChild *child;
GtkWidget *child;
GList *list;
for (list = priv->children; list; list = list->next)
{
child = list->data;
(* callback) (child->widget, callback_data);
(* callback) (child, callback_data);
}
}
@@ -1468,68 +1421,6 @@ gtk_wrap_box_child_type (GtkContainer *container)
return GTK_TYPE_WIDGET;
}
static void
gtk_wrap_box_set_child_property (GtkContainer *container,
GtkWidget *widget,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkWrapBox *box = GTK_WRAP_BOX (container);
GtkWrapBoxPrivate *priv = box->priv;
GtkWrapBoxChild *child;
GList *list;
list = g_list_find_custom (priv->children, widget,
(GCompareFunc)find_child_in_list);
g_return_if_fail (list != NULL);
child = list->data;
switch (property_id)
{
case CHILD_PROP_PACKING:
child->packing = g_value_get_flags (value);
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
}
if (gtk_widget_get_visible (widget) &&
gtk_widget_get_visible (GTK_WIDGET (box)))
gtk_widget_queue_resize (widget);
}
static void
gtk_wrap_box_get_child_property (GtkContainer *container,
GtkWidget *widget,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkWrapBox *box = GTK_WRAP_BOX (container);
GtkWrapBoxPrivate *priv = box->priv;
GtkWrapBoxChild *child;
GList *list;
list = g_list_find_custom (priv->children, widget,
(GCompareFunc)find_child_in_list);
g_return_if_fail (list != NULL);
child = list->data;
switch (property_id)
{
case CHILD_PROP_PACKING:
g_value_set_flags (value, child->packing);
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
}
}
/*****************************************************
* GtkSizeRequestIface *
*****************************************************/
@@ -1584,17 +1475,17 @@ get_largest_line_length (GtkWrapBox *box,
for (l = list, i = 0; l && i < line_length; l = l->next)
{
GtkWrapBoxChild *child = l->data;
gint child_min, child_nat;
GtkWidget *child = l->data;
gint child_min, child_nat;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
else /* GTK_ORIENTATION_VERTICAL */
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
line_min += child_min;
@@ -1644,17 +1535,17 @@ get_largest_aligned_line_length (GtkWrapBox *box,
*/
for (list = priv->children, i = 0; list; list = list->next)
{
GtkWrapBoxChild *child = list->data;
gint child_min, child_nat;
GtkWidget *child = list->data;
gint child_min, child_nat;
if (!gtk_widget_get_visible (child->widget))
if (!gtk_widget_get_visible (child))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
else /* GTK_ORIENTATION_VERTICAL */
gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget),
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&child_min, &child_nat);
aligned_item_sizes[i % line_length].minimum_size =
@@ -2565,19 +2456,16 @@ gtk_wrap_box_get_natural_line_children (GtkWrapBox *box)
* @box: And #GtkWrapBox
* @widget: the child #GtkWidget to add
* @index: the position in the child list to insert, specify -1 to append to the list.
* @packing: The #GtkWrapBoxPacking options to use.
*
* Adds a child to an #GtkWrapBox with its packing options set
* Adds a child to a #GtkWrapBox.
*
*/
void
gtk_wrap_box_insert_child (GtkWrapBox *box,
GtkWidget *widget,
gint index,
GtkWrapBoxPacking packing)
gint index)
{
GtkWrapBoxPrivate *priv;
GtkWrapBoxChild *child;
GList *list;
g_return_if_fail (GTK_IS_WRAP_BOX (box));
@@ -2585,15 +2473,10 @@ gtk_wrap_box_insert_child (GtkWrapBox *box,
priv = box->priv;
list = g_list_find_custom (priv->children, widget,
(GCompareFunc)find_child_in_list);
list = g_list_find (priv->children, widget);
g_return_if_fail (list == NULL);
child = g_slice_new0 (GtkWrapBoxChild);
child->widget = widget;
child->packing = packing;
priv->children = g_list_insert (priv->children, child, index);
priv->children = g_list_insert (priv->children, widget, index);
gtk_widget_set_parent (widget, GTK_WIDGET (box));
}
@@ -2612,7 +2495,6 @@ gtk_wrap_box_reorder_child (GtkWrapBox *box,
guint index)
{
GtkWrapBoxPrivate *priv;
GtkWrapBoxChild *child;
GList *list;
g_return_if_fail (GTK_IS_WRAP_BOX (box));
@@ -2620,15 +2502,13 @@ gtk_wrap_box_reorder_child (GtkWrapBox *box,
priv = box->priv;
list = g_list_find_custom (priv->children, widget,
(GCompareFunc)find_child_in_list);
list = g_list_find (priv->children, widget);
g_return_if_fail (list != NULL);
if (g_list_position (priv->children, list) != index)
{
child = list->data;
priv->children = g_list_delete_link (priv->children, list);
priv->children = g_list_insert (priv->children, child, index);
priv->children = g_list_insert (priv->children, widget, index);
gtk_widget_queue_resize (GTK_WIDGET (box));
}

View File

@@ -89,8 +89,7 @@ guint gtk_wrap_box_get_natural_line_children (GtkWrapBox
void gtk_wrap_box_insert_child (GtkWrapBox *box,
GtkWidget *widget,
gint index,
GtkWrapBoxPacking packing);
gint index);
void gtk_wrap_box_reorder_child (GtkWrapBox *box,
GtkWidget *widget,

View File

@@ -89,6 +89,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testactions \
testgrouping \
testtooltips \
testexpand \
testexpander \
testvolumebutton \
testwrapbox
@@ -176,6 +177,7 @@ testtooltips_DEPENDENCIES = $(TEST_DEPS)
testvolumebutton_DEPENDENCIES = $(TEST_DEPS)
testwrapbox_DEPENDENCIES = $(TEST_DEPS)
testwindows_DEPENDENCIES = $(TEST_DEPS)
testexpand_DEPENDENCIES = $(TEST_DEPS)
testexpander_DEPENDENCIES = $(TEST_DEPS)
flicker_LDADD = $(LDADDS)
@@ -247,6 +249,7 @@ testtooltips_LDADD = $(LDADDS)
testvolumebutton_LDADD = $(LDADDS)
testwrapbox_LDADD = $(LDADDS)
testwindows_LDADD = $(LDADDS)
testexpand_LDADD = $(LDADDS)
testexpander_LDADD = $(LDADDS)
testentrycompletion_SOURCES = \
@@ -359,6 +362,8 @@ testoffscreenwindow_SOURCES = \
testwindows_SOURCES = \
testwindows.c
testexpand_SOURCES = testexpand.c
testexpander_SOURCES = testexpander.c
EXTRA_DIST += \

219
tests/testexpand.c Normal file
View File

@@ -0,0 +1,219 @@
/* testexpand.c
* Copyright (C) 2010 Havoc Pennington
*
* Author:
* Havoc Pennington <hp@pobox.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
static void
on_toggle_hexpand (GtkToggleButton *toggle,
void *data)
{
GtkWidget *parent;
/* get the event box with color set on it */
parent = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (toggle)));
g_object_set (toggle,
"hexpand", gtk_toggle_button_get_active (toggle),
NULL);
}
static void
on_toggle_vexpand (GtkToggleButton *toggle,
void *data)
{
GtkWidget *parent;
/* get the event box with color set on it */
parent = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (toggle)));
g_object_set (toggle,
"vexpand", gtk_toggle_button_get_active (toggle),
NULL);
}
static void
create_box_window (void)
{
GtkWidget *window;
GtkWidget *box1, *box2, *box3;
GtkWidget *toggle;
GtkWidget *alignment;
GtkWidget *colorbox;
GdkColor red, blue;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Boxes");
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
box3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1),
gtk_label_new ("VBox 1 Top"),
FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box1),
box2,
FALSE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (box1),
gtk_label_new ("VBox 1 Bottom"),
FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2),
gtk_label_new ("HBox 2 Left"),
FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box2),
box3,
FALSE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (box2),
gtk_label_new ("HBox 2 Right"),
FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box3),
gtk_label_new ("VBox 3 Top"),
FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (box3),
gtk_label_new ("VBox 3 Bottom"),
FALSE, FALSE, 0);
gdk_color_parse ("red", &red);
gdk_color_parse ("blue", &blue);
colorbox = gtk_event_box_new ();
gtk_widget_modify_bg (colorbox, GTK_STATE_NORMAL, &red);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 5, 5, 5, 5);
gtk_container_add (GTK_CONTAINER (colorbox), alignment);
toggle = gtk_toggle_button_new_with_label ("H Expand");
g_signal_connect (G_OBJECT (toggle), "toggled",
G_CALLBACK (on_toggle_hexpand), NULL);
gtk_container_add (GTK_CONTAINER (alignment), toggle);
gtk_box_pack_start (GTK_BOX (box3),
colorbox,
FALSE, TRUE, 0);
colorbox = gtk_event_box_new ();
gtk_widget_modify_bg (colorbox, GTK_STATE_NORMAL, &blue);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 5, 5, 5, 5);
gtk_container_add (GTK_CONTAINER (colorbox), alignment);
toggle = gtk_toggle_button_new_with_label ("V Expand");
g_signal_connect (G_OBJECT (toggle), "toggled",
G_CALLBACK (on_toggle_vexpand), NULL);
gtk_container_add (GTK_CONTAINER (alignment), toggle);
gtk_box_pack_start (GTK_BOX (box3),
colorbox,
FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show_all (window);
}
static void
create_table_window (void)
{
GtkWidget *window;
GtkWidget *table;
GtkWidget *toggle;
GtkWidget *alignment;
GtkWidget *colorbox;
GdkColor red, blue;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Table");
table = gtk_table_new (4, 3, FALSE);
gtk_table_attach (GTK_TABLE (table),
gtk_label_new ("Top"),
1, 2, 0, 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_label_new ("Bottom"),
1, 2, 3, 4,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_label_new ("Left"),
0, 1, 1, 3,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_label_new ("Right"),
2, 3, 1, 3,
GTK_FILL, GTK_FILL, 0, 0);
gdk_color_parse ("red", &red);
gdk_color_parse ("blue", &blue);
colorbox = gtk_event_box_new ();
gtk_widget_modify_bg (colorbox, GTK_STATE_NORMAL, &red);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 5, 5, 5, 5);
gtk_container_add (GTK_CONTAINER (colorbox), alignment);
toggle = gtk_toggle_button_new_with_label ("H Expand");
g_signal_connect (G_OBJECT (toggle), "toggled",
G_CALLBACK (on_toggle_hexpand), NULL);
gtk_container_add (GTK_CONTAINER (alignment), toggle);
gtk_table_attach (GTK_TABLE (table),
colorbox,
1, 2, 1, 2,
GTK_FILL, GTK_FILL, 0, 0);
colorbox = gtk_event_box_new ();
gtk_widget_modify_bg (colorbox, GTK_STATE_NORMAL, &blue);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 5, 5, 5, 5);
gtk_container_add (GTK_CONTAINER (colorbox), alignment);
toggle = gtk_toggle_button_new_with_label ("V Expand");
g_signal_connect (G_OBJECT (toggle), "toggled",
G_CALLBACK (on_toggle_vexpand), NULL);
gtk_container_add (GTK_CONTAINER (alignment), toggle);
gtk_table_attach (GTK_TABLE (table),
colorbox,
1, 2, 2, 3,
GTK_FILL, GTK_FILL, 0, 0);
gtk_container_add (GTK_CONTAINER (window), table);
gtk_widget_show_all (window);
}
int
main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
create_box_window ();
create_table_window ();
gtk_main ();
return 0;
}

View File

@@ -61,9 +61,12 @@ populate_wrapbox_simple (GtkWrapBox *wrapbox)
if (text_orientation == GTK_ORIENTATION_VERTICAL)
gtk_label_set_angle (GTK_LABEL (widget), 90);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), frame, -1,
(items_xexpand ? GTK_WRAP_BOX_H_EXPAND : 0) |
(items_yexpand ? GTK_WRAP_BOX_V_EXPAND : 0));
if (items_xexpand)
gtk_widget_set_hexpand (frame, TRUE);
if (items_yexpand)
gtk_widget_set_vexpand (frame, TRUE);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), frame, -1);
g_free (text);
}
@@ -100,9 +103,12 @@ populate_wrapbox_wrappy (GtkWrapBox *wrapbox)
gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD);
gtk_label_set_width_chars (GTK_LABEL (widget), 10);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), frame, -1,
(items_xexpand ? GTK_WRAP_BOX_H_EXPAND : 0) |
(items_yexpand ? GTK_WRAP_BOX_V_EXPAND : 0));
if (items_xexpand)
gtk_widget_set_hexpand (frame, TRUE);
if (items_yexpand)
gtk_widget_set_vexpand (frame, TRUE);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), frame, -1);
}
}
@@ -125,9 +131,12 @@ populate_wrapbox_stock (GtkWrapBox *wrapbox)
widget = gtk_button_new_from_stock (stock_id);
gtk_widget_show (widget);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), widget, -1,
(items_xexpand ? GTK_WRAP_BOX_H_EXPAND : 0) |
(items_yexpand ? GTK_WRAP_BOX_V_EXPAND : 0));
if (items_xexpand)
gtk_widget_set_hexpand (widget, TRUE);
if (items_yexpand)
gtk_widget_set_vexpand (widget, TRUE);
gtk_wrap_box_insert_child (GTK_WRAP_BOX (wrapbox), widget, -1);
}
}