* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
*
* Children are added using gtk_grid_attach(). They can span multiple
* rows or columns. It is also possible to add a child next to an
- * existing child, using gtk_grid_attach_next_to().
+ * existing child, using gtk_grid_attach_next_to(). The behaviour of
+ * GtkGrid when several children occupy the same grid cell is undefined.
*
* GtkGrid can be used like a #GtkBox by just using gtk_container_add(),
* which will place children next to each other in the direction determined
break;
case PROP_ROW_SPACING:
- g_value_set_int (value, ROWS (priv)->spacing);
+ g_value_set_int (value, COLUMNS (priv)->spacing);
break;
case PROP_COLUMN_SPACING:
- g_value_set_int (value, COLUMNS (priv)->spacing);
+ g_value_set_int (value, ROWS (priv)->spacing);
break;
case PROP_ROW_HOMOGENEOUS:
/* If we need to request more space for this child to fill
* its requisition, then divide up the needed space amongst the
* lines it spans, favoring expandable lines if any.
+ *
+ * When doing homogeneous allocation though, try to keep the
+ * line allocations even, since we're going to force them to
+ * be the same anyway, and we don't want to introduce unnecessary
+ * extra space.
*/
if (span_minimum < minimum)
{
- extra = minimum - span_minimum;
- expand = span_expand;
- for (i = 0; i < attach->span; i++)
+ if (linedata->homogeneous)
{
- line = &lines->lines[attach->pos - lines->min + i];
- if (force_expand || line->expand)
+ gint total, m;
+
+ total = minimum - (attach->span - 1) * linedata->spacing;
+ m = total / attach->span + (total % attach->span ? 1 : 0);
+ for (i = 0; i < attach->span; i++)
{
- line_extra = extra / expand;
- line->minimum += line_extra;
- extra -= line_extra;
- expand -= 1;
+ line = &lines->lines[attach->pos - lines->min + i];
+ line->minimum = MAX(line->minimum, m);
+ }
+ }
+ else
+ {
+ extra = minimum - span_minimum;
+ expand = span_expand;
+ for (i = 0; i < attach->span; i++)
+ {
+ line = &lines->lines[attach->pos - lines->min + i];
+ if (force_expand || line->expand)
+ {
+ line_extra = extra / expand;
+ line->minimum += line_extra;
+ extra -= line_extra;
+ expand -= 1;
+ }
}
}
}
if (span_natural < natural)
{
- extra = natural - span_natural;
- expand = span_expand;
- for (i = 0; i < attach->span; i++)
+ if (linedata->homogeneous)
{
- line = &lines->lines[attach->pos - lines->min + i];
- if (force_expand || line->expand)
+ gint total, n;
+
+ total = natural - (attach->span - 1) * linedata->spacing;
+ n = total / attach->span + (total % attach->span ? 1 : 0);
+ for (i = 0; i < attach->span; i++)
{
- line_extra = extra / expand;
- line->natural += line_extra;
- extra -= line_extra;
- expand -= 1;
+ line = &lines->lines[attach->pos - lines->min + i];
+ line->natural = MAX(line->natural, n);
+ }
+ }
+ else
+ {
+ extra = natural - span_natural;
+ expand = span_expand;
+ for (i = 0; i < attach->span; i++)
+ {
+ line = &lines->lines[attach->pos - lines->min + i];
+ if (force_expand || line->expand)
+ {
+ line_extra = extra / expand;
+ line->natural += line_extra;
+ extra -= line_extra;
+ expand -= 1;
+ }
}
}
}
linedata = &priv->linedata[orientation];
lines = &request->lines[orientation];
- min = (nonempty - 1) * linedata->spacing;
- nat = (nonempty - 1) * linedata->spacing;
+ min = 0;
+ nat = 0;
+ if (nonempty > 0)
+ {
+ min = (nonempty - 1) * linedata->spacing;
+ nat = (nonempty - 1) * linedata->spacing;
+ }
for (i = 0; i < lines->max - lines->min; i++)
{
gtk_grid_request_compute_expand (request, orientation, &nonempty, &expand);
+ if (nonempty == 0)
+ return;
+
linedata = &priv->linedata[orientation];
lines = &request->lines[orientation];
* gtk_grid_attach_next_to:
* @grid: a #GtkGrid
* @child: the widget to add
- * @sibling (allow-none): the child of @grid that @child will be placed
+ * @sibling: (allow-none): the child of @grid that @child will be placed
* next to, or %NULL to place @child at the beginning or end
* @side: the side of @sibling that @child is positioned next to
* @width: the number of columns that @child will span
* @side. When @sibling is %NULL, the widget is placed in row (for
* left or right placement) or column 0 (for top or bottom placement),
* at the end indicated by @side.
+ *
+ * Attaching widgets labeled [1], [2], [3] with @sibling == %NULL and
+ * @side == %GTK_POS_LEFT yields a layout of [3][2][1].
*/
void
gtk_grid_attach_next_to (GtkGrid *grid,
switch (side)
{
case GTK_POS_LEFT:
- left = find_attach_position (grid, GTK_ORIENTATION_HORIZONTAL, 0, height, TRUE);
+ left = find_attach_position (grid, GTK_ORIENTATION_HORIZONTAL, 0, height, FALSE);
+ left -= width;
top = 0;
break;
case GTK_POS_RIGHT:
- left = find_attach_position (grid, GTK_ORIENTATION_HORIZONTAL, 0, height, FALSE);
+ left = find_attach_position (grid, GTK_ORIENTATION_HORIZONTAL, 0, height, TRUE);
top = 0;
break;
case GTK_POS_TOP:
left = 0;
- top = find_attach_position (grid, GTK_ORIENTATION_VERTICAL, 0, width, TRUE);
+ top = find_attach_position (grid, GTK_ORIENTATION_VERTICAL, 0, width, FALSE);
+ top -= height;
break;
case GTK_POS_BOTTOM:
left = 0;
- top = find_attach_position (grid, GTK_ORIENTATION_VERTICAL, 0, width, FALSE);
+ top = find_attach_position (grid, GTK_ORIENTATION_VERTICAL, 0, width, TRUE);
break;
default:
g_assert_not_reached ();
* Gets the child of @grid whose area covers the grid
* cell whose upper left corner is at @left, @top.
*
- * Returns: the child at the given position, or %NULL
+ * Returns: (transfer none): the child at the given position, or %NULL
*
* Since: 3.2
*/
gint left,
gint top)
{
- GtkGridPrivate *priv = grid->priv;
+ GtkGridPrivate *priv;
GtkGridChild *child;
GList *list;
+ g_return_val_if_fail (GTK_IS_GRID (grid), NULL);
+
+ priv = grid->priv;
+
for (list = priv->children; list; list = list->next)
{
child = list->data;
gtk_grid_insert_row (GtkGrid *grid,
gint position)
{
- GtkGridPrivate *priv = grid->priv;
+ GtkGridPrivate *priv;
GtkGridChild *child;
GList *list;
gint top, height;
g_return_if_fail (GTK_IS_GRID (grid));
+ priv = grid->priv;
+
for (list = priv->children; list; list = list->next)
{
child = list->data;
gtk_grid_insert_column (GtkGrid *grid,
gint position)
{
- GtkGridPrivate *priv = grid->priv;
+ GtkGridPrivate *priv;
GtkGridChild *child;
GList *list;
gint left, width;
g_return_if_fail (GTK_IS_GRID (grid));
+ priv = grid->priv;
+
for (list = priv->children; list; list = list->next)
{
child = list->data;
priv = grid->priv;
- if (ROWS (priv)->spacing != spacing)
+ if (COLUMNS (priv)->spacing != spacing)
{
- ROWS (priv)->spacing = spacing;
+ COLUMNS (priv)->spacing = spacing;
if (gtk_widget_get_visible (GTK_WIDGET (grid)))
gtk_widget_queue_resize (GTK_WIDGET (grid));
priv = grid->priv;
- return ROWS (priv)->spacing;
+ return COLUMNS (priv)->spacing;
}
/**
priv = grid->priv;
- if (COLUMNS (priv)->spacing != spacing)
+ if (ROWS (priv)->spacing != spacing)
{
- COLUMNS (priv)->spacing = spacing;
+ ROWS (priv)->spacing = spacing;
if (gtk_widget_get_visible (GTK_WIDGET (grid)))
gtk_widget_queue_resize (GTK_WIDGET (grid));
priv = grid->priv;
- return COLUMNS (priv)->spacing;
+ return ROWS (priv)->spacing;
}