flow-layout: Add :snap-to-grid property
Add a :snap-to-grid property to FlowLayout to prevent the layout from assigning it's children a position based on the size of the largest child. https://bugzilla.gnome.org/show_bug.cgi?id=648873
This commit is contained in:
parent
b6f4a8014e
commit
55ec9f57db
@ -111,6 +111,7 @@ struct _ClutterFlowLayoutPrivate
|
|||||||
guint line_count;
|
guint line_count;
|
||||||
|
|
||||||
guint is_homogeneous : 1;
|
guint is_homogeneous : 1;
|
||||||
|
guint snap_to_grid : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -129,6 +130,8 @@ enum
|
|||||||
PROP_MIN_ROW_HEGHT,
|
PROP_MIN_ROW_HEGHT,
|
||||||
PROP_MAX_ROW_HEIGHT,
|
PROP_MAX_ROW_HEIGHT,
|
||||||
|
|
||||||
|
PROP_SNAP_TO_GRID,
|
||||||
|
|
||||||
N_PROPERTIES
|
N_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -256,7 +259,12 @@ clutter_flow_layout_get_preferred_width (ClutterLayoutManager *manager,
|
|||||||
|
|
||||||
if (priv->orientation == CLUTTER_FLOW_VERTICAL && for_height > 0)
|
if (priv->orientation == CLUTTER_FLOW_VERTICAL && for_height > 0)
|
||||||
{
|
{
|
||||||
if (line_item_count == n_rows)
|
clutter_actor_get_preferred_height (child, -1,
|
||||||
|
&child_min,
|
||||||
|
&child_natural);
|
||||||
|
|
||||||
|
if ((priv->snap_to_grid && line_item_count == n_rows) ||
|
||||||
|
(!priv->snap_to_grid && item_y + child_natural > for_height))
|
||||||
{
|
{
|
||||||
total_min_width += line_min_width;
|
total_min_width += line_min_width;
|
||||||
total_natural_width += line_natural_width;
|
total_natural_width += line_natural_width;
|
||||||
@ -273,9 +281,17 @@ clutter_flow_layout_get_preferred_width (ClutterLayoutManager *manager,
|
|||||||
item_y = 0;
|
item_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->snap_to_grid)
|
||||||
|
{
|
||||||
new_y = ((line_item_count + 1) * (for_height + priv->row_spacing))
|
new_y = ((line_item_count + 1) * (for_height + priv->row_spacing))
|
||||||
/ n_rows;
|
/ n_rows;
|
||||||
item_height = new_y - item_y - priv->row_spacing;
|
item_height = new_y - item_y - priv->row_spacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_y = item_y + child_natural + priv->row_spacing;
|
||||||
|
item_height = child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, item_height,
|
clutter_actor_get_preferred_width (child, item_height,
|
||||||
&child_min,
|
&child_min,
|
||||||
@ -434,7 +450,12 @@ clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
|
|||||||
|
|
||||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
|
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
|
||||||
{
|
{
|
||||||
if (line_item_count == n_columns)
|
clutter_actor_get_preferred_width (child, -1,
|
||||||
|
&child_min,
|
||||||
|
&child_natural);
|
||||||
|
|
||||||
|
if ((priv->snap_to_grid && line_item_count == n_columns) ||
|
||||||
|
(!priv->snap_to_grid && item_x + child_natural > for_width))
|
||||||
{
|
{
|
||||||
total_min_height += line_min_height;
|
total_min_height += line_min_height;
|
||||||
total_natural_height += line_natural_height;
|
total_natural_height += line_natural_height;
|
||||||
@ -451,9 +472,17 @@ clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
|
|||||||
item_x = 0;
|
item_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->snap_to_grid)
|
||||||
|
{
|
||||||
new_x = ((line_item_count + 1) * (for_width + priv->col_spacing))
|
new_x = ((line_item_count + 1) * (for_width + priv->col_spacing))
|
||||||
/ n_columns;
|
/ n_columns;
|
||||||
item_width = new_x - item_x - priv->col_spacing;
|
item_width = new_x - item_x - priv->col_spacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_x = item_x + child_natural + priv->col_spacing;
|
||||||
|
item_width = child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
clutter_actor_get_preferred_height (child, item_width,
|
clutter_actor_get_preferred_height (child, item_width,
|
||||||
&child_min,
|
&child_min,
|
||||||
@ -604,15 +633,24 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
ClutterActorBox child_alloc;
|
ClutterActorBox child_alloc;
|
||||||
gfloat item_width, item_height;
|
gfloat item_width, item_height;
|
||||||
gfloat new_x, new_y;
|
gfloat new_x, new_y;
|
||||||
|
gfloat child_min, child_natural;
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
new_x = new_y = 0;
|
new_x = new_y = 0;
|
||||||
|
|
||||||
|
if (!priv->snap_to_grid)
|
||||||
|
clutter_actor_get_preferred_size (child,
|
||||||
|
NULL, NULL,
|
||||||
|
&item_width,
|
||||||
|
&item_height);
|
||||||
|
|
||||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
||||||
{
|
{
|
||||||
if (line_item_count == items_per_line && line_item_count > 0)
|
if ((priv->snap_to_grid &&
|
||||||
|
line_item_count == items_per_line && line_item_count > 0) ||
|
||||||
|
(!priv->snap_to_grid && item_x + item_width > avail_width))
|
||||||
{
|
{
|
||||||
item_y += g_array_index (priv->line_natural,
|
item_y += g_array_index (priv->line_natural,
|
||||||
gfloat,
|
gfloat,
|
||||||
@ -627,31 +665,27 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
item_x = x_off;
|
item_x = x_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->snap_to_grid)
|
||||||
|
{
|
||||||
new_x = x_off + ((line_item_count + 1) * (avail_width + priv->col_spacing))
|
new_x = x_off + ((line_item_count + 1) * (avail_width + priv->col_spacing))
|
||||||
/ items_per_line;
|
/ items_per_line;
|
||||||
item_width = new_x - item_x - priv->col_spacing;
|
item_width = new_x - item_x - priv->col_spacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_x = item_x + item_width + priv->col_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
item_height = g_array_index (priv->line_natural,
|
item_height = g_array_index (priv->line_natural,
|
||||||
gfloat,
|
gfloat,
|
||||||
line_index);
|
line_index);
|
||||||
|
|
||||||
if (!priv->is_homogeneous)
|
|
||||||
{
|
|
||||||
gfloat child_min, child_natural;
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, item_height,
|
|
||||||
&child_min,
|
|
||||||
&child_natural);
|
|
||||||
item_width = MIN (item_width, child_natural);
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_height (child, item_width,
|
|
||||||
&child_min,
|
|
||||||
&child_natural);
|
|
||||||
item_height = MIN (item_height, child_natural);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (line_item_count == items_per_line && line_item_count > 0)
|
if ((priv->snap_to_grid &&
|
||||||
|
line_item_count == items_per_line && line_item_count > 0) ||
|
||||||
|
(!priv->snap_to_grid && item_y + item_height > avail_height))
|
||||||
{
|
{
|
||||||
item_x += g_array_index (priv->line_natural,
|
item_x += g_array_index (priv->line_natural,
|
||||||
gfloat,
|
gfloat,
|
||||||
@ -666,28 +700,41 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
item_y = y_off;
|
item_y = y_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->snap_to_grid)
|
||||||
|
{
|
||||||
new_y = y_off + ((line_item_count + 1) * (avail_height + priv->row_spacing))
|
new_y = y_off + ((line_item_count + 1) * (avail_height + priv->row_spacing))
|
||||||
/ items_per_line;
|
/ items_per_line;
|
||||||
item_height = new_y - item_y - priv->row_spacing;
|
item_height = new_y - item_y - priv->row_spacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_y = item_y + item_height + priv->row_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
item_width = g_array_index (priv->line_natural,
|
item_width = g_array_index (priv->line_natural,
|
||||||
gfloat,
|
gfloat,
|
||||||
line_index);
|
line_index);
|
||||||
|
}
|
||||||
|
|
||||||
if (!priv->is_homogeneous)
|
if (!priv->is_homogeneous &&
|
||||||
|
!clutter_actor_needs_expand (child,
|
||||||
|
CLUTTER_ORIENTATION_HORIZONTAL))
|
||||||
{
|
{
|
||||||
gfloat child_min, child_natural;
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_width (child, item_height,
|
clutter_actor_get_preferred_width (child, item_height,
|
||||||
&child_min,
|
&child_min,
|
||||||
&child_natural);
|
&child_natural);
|
||||||
item_width = MIN (item_width, child_natural);
|
item_width = MIN (item_width, child_natural);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->is_homogeneous &&
|
||||||
|
!clutter_actor_needs_expand (child,
|
||||||
|
CLUTTER_ORIENTATION_VERTICAL))
|
||||||
|
{
|
||||||
clutter_actor_get_preferred_height (child, item_width,
|
clutter_actor_get_preferred_height (child, item_width,
|
||||||
&child_min,
|
&child_min,
|
||||||
&child_natural);
|
&child_natural);
|
||||||
item_height = MIN (item_height, child_natural);
|
item_height = MIN (item_height, child_natural);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (LAYOUT,
|
CLUTTER_NOTE (LAYOUT,
|
||||||
"flow[line:%d, item:%d/%d] ="
|
"flow[line:%d, item:%d/%d] ="
|
||||||
@ -787,6 +834,11 @@ clutter_flow_layout_set_property (GObject *gobject,
|
|||||||
g_value_get_float (value));
|
g_value_get_float (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SNAP_TO_GRID:
|
||||||
|
clutter_flow_layout_set_snap_to_grid (self,
|
||||||
|
g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -835,6 +887,10 @@ clutter_flow_layout_get_property (GObject *gobject,
|
|||||||
g_value_set_float (value, priv->max_row_height);
|
g_value_set_float (value, priv->max_row_height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SNAP_TO_GRID:
|
||||||
|
g_value_set_boolean (value, priv->snap_to_grid);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -1002,6 +1058,21 @@ clutter_flow_layout_class_init (ClutterFlowLayoutClass *klass)
|
|||||||
-1.0,
|
-1.0,
|
||||||
CLUTTER_PARAM_READWRITE);
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterFlowLayout:snap-to-grid:
|
||||||
|
*
|
||||||
|
* Whether the #ClutterFlowLayout should arrange its children
|
||||||
|
* on a grid
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
flow_properties[PROP_SNAP_TO_GRID] =
|
||||||
|
g_param_spec_boolean ("snap-to-grid",
|
||||||
|
P_("Snap to grid"),
|
||||||
|
P_("Snap to grid"),
|
||||||
|
TRUE,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
gobject_class->finalize = clutter_flow_layout_finalize;
|
gobject_class->finalize = clutter_flow_layout_finalize;
|
||||||
gobject_class->set_property = clutter_flow_layout_set_property;
|
gobject_class->set_property = clutter_flow_layout_set_property;
|
||||||
gobject_class->get_property = clutter_flow_layout_get_property;
|
gobject_class->get_property = clutter_flow_layout_get_property;
|
||||||
@ -1027,6 +1098,7 @@ clutter_flow_layout_init (ClutterFlowLayout *self)
|
|||||||
|
|
||||||
priv->line_min = NULL;
|
priv->line_min = NULL;
|
||||||
priv->line_natural = NULL;
|
priv->line_natural = NULL;
|
||||||
|
priv->snap_to_grid = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1432,3 +1504,51 @@ clutter_flow_layout_get_row_height (ClutterFlowLayout *layout,
|
|||||||
if (max_height)
|
if (max_height)
|
||||||
*max_height = layout->priv->max_row_height;
|
*max_height = layout->priv->max_row_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_flow_layout_set_snap_to_grid:
|
||||||
|
* @layout: a #ClutterFlowLayout
|
||||||
|
* @snap_to_grid: %TRUE if @layout should place its children on a grid
|
||||||
|
*
|
||||||
|
* Whether the @layout should place its children on a grid.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_flow_layout_set_snap_to_grid (ClutterFlowLayout *layout,
|
||||||
|
gboolean snap_to_grid)
|
||||||
|
{
|
||||||
|
ClutterFlowLayoutPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||||
|
|
||||||
|
priv = layout->priv;
|
||||||
|
|
||||||
|
if (priv->snap_to_grid != snap_to_grid)
|
||||||
|
{
|
||||||
|
priv->snap_to_grid = snap_to_grid;
|
||||||
|
|
||||||
|
clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (layout));
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (layout),
|
||||||
|
flow_properties[PROP_SNAP_TO_GRID]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_flow_layout_get_snap_to_grid:
|
||||||
|
* @layout: a #ClutterFlowLayout
|
||||||
|
*
|
||||||
|
* Retrieves the value of #ClutterFlowLayout:snap-to-grid property
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the @layout is placing its children on a grid
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clutter_flow_layout_get_snap_to_grid (ClutterFlowLayout *layout)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), FALSE);
|
||||||
|
|
||||||
|
return layout->priv->snap_to_grid;
|
||||||
|
}
|
||||||
|
@ -104,6 +104,9 @@ void clutter_flow_layout_set_row_height (ClutterFlowLayout
|
|||||||
void clutter_flow_layout_get_row_height (ClutterFlowLayout *layout,
|
void clutter_flow_layout_get_row_height (ClutterFlowLayout *layout,
|
||||||
gfloat *min_height,
|
gfloat *min_height,
|
||||||
gfloat *max_height);
|
gfloat *max_height);
|
||||||
|
void clutter_flow_layout_set_snap_to_grid (ClutterFlowLayout *layout,
|
||||||
|
gboolean snap_to_grid);
|
||||||
|
gboolean clutter_flow_layout_get_snap_to_grid (ClutterFlowLayout *layout);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -477,6 +477,7 @@ clutter_flow_layout_get_homogeneous
|
|||||||
clutter_flow_layout_get_orientation
|
clutter_flow_layout_get_orientation
|
||||||
clutter_flow_layout_get_row_height
|
clutter_flow_layout_get_row_height
|
||||||
clutter_flow_layout_get_row_spacing
|
clutter_flow_layout_get_row_spacing
|
||||||
|
clutter_flow_layout_get_snap_to_grid
|
||||||
clutter_flow_layout_get_type
|
clutter_flow_layout_get_type
|
||||||
clutter_flow_layout_new
|
clutter_flow_layout_new
|
||||||
clutter_flow_layout_set_column_spacing
|
clutter_flow_layout_set_column_spacing
|
||||||
@ -485,6 +486,7 @@ clutter_flow_layout_set_homogeneous
|
|||||||
clutter_flow_layout_set_orientation
|
clutter_flow_layout_set_orientation
|
||||||
clutter_flow_layout_set_row_height
|
clutter_flow_layout_set_row_height
|
||||||
clutter_flow_layout_set_row_spacing
|
clutter_flow_layout_set_row_spacing
|
||||||
|
clutter_flow_layout_set_snap_to_grid
|
||||||
clutter_flow_orientation_get_type
|
clutter_flow_orientation_get_type
|
||||||
#ifdef CLUTTER_WINDOWING_GDK
|
#ifdef CLUTTER_WINDOWING_GDK
|
||||||
clutter_gdk_disable_event_retrieval
|
clutter_gdk_disable_event_retrieval
|
||||||
|
@ -1520,6 +1520,8 @@ clutter_flow_layout_set_column_width
|
|||||||
clutter_flow_layout_get_column_width
|
clutter_flow_layout_get_column_width
|
||||||
clutter_flow_layout_set_row_height
|
clutter_flow_layout_set_row_height
|
||||||
clutter_flow_layout_get_row_height
|
clutter_flow_layout_get_row_height
|
||||||
|
clutter_flow_layout_set_snap_to_grid
|
||||||
|
clutter_flow_layout_get_snap_to_grid
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_FLOW_LAYOUT
|
CLUTTER_TYPE_FLOW_LAYOUT
|
||||||
|
@ -9,6 +9,7 @@ static gboolean is_homogeneous = FALSE;
|
|||||||
static gboolean vertical = FALSE;
|
static gboolean vertical = FALSE;
|
||||||
static gboolean random_size = FALSE;
|
static gboolean random_size = FALSE;
|
||||||
static gboolean fixed_size = FALSE;
|
static gboolean fixed_size = FALSE;
|
||||||
|
static gboolean snap_to_grid = TRUE;
|
||||||
|
|
||||||
static gint n_rects = N_RECTS;
|
static gint n_rects = N_RECTS;
|
||||||
static gint x_spacing = 0;
|
static gint x_spacing = 0;
|
||||||
@ -64,6 +65,13 @@ static GOptionEntry entries[] = {
|
|||||||
&fixed_size,
|
&fixed_size,
|
||||||
"Fix the layout size", NULL
|
"Fix the layout size", NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"no-snap-to-grid", 's',
|
||||||
|
G_OPTION_FLAG_REVERSE,
|
||||||
|
G_OPTION_ARG_NONE,
|
||||||
|
&snap_to_grid,
|
||||||
|
"Don't snap elements to grid", NULL
|
||||||
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,6 +110,8 @@ main (int argc, char *argv[])
|
|||||||
x_spacing);
|
x_spacing);
|
||||||
clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout),
|
clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout),
|
||||||
y_spacing);
|
y_spacing);
|
||||||
|
clutter_flow_layout_set_snap_to_grid (CLUTTER_FLOW_LAYOUT (layout),
|
||||||
|
snap_to_grid);
|
||||||
|
|
||||||
box = clutter_actor_new ();
|
box = clutter_actor_new ();
|
||||||
clutter_actor_set_layout_manager (box, layout);
|
clutter_actor_set_layout_manager (box, layout);
|
||||||
|
Loading…
Reference in New Issue
Block a user