TIP 37: Uniform Rows and Columns in Grid

Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2017 Conference, Houston/TX, US, Oct 16-20
Send your abstracts to tclconference@googlegroups.com
by Aug 21.
Author:         Peter Spjuth <peter.spjuth@space.se>
Author:         Kevin Kenny <kennykb@acm.org>
State:          Final
Type:           Project
Vote:           Done
Created:        19-Jun-2001
Tcl-Version:    8.4


This TIP proposes to add a -uniform option to grid rowconfigure and grid columnconfigure so as to make it easier to create layouts where cells are constrained to have identical dimensions.


The geometry managers in Tk are very powerful and can do most things needed to layout a GUI. One thing that is tricky to do though is to put widgets in rows or columns of the same width. This would be useful for example to layout a row of buttons symmetrically. This could easily be done with the grid manager if an additional option is added.


Anywhere column is used below, the same applies to row too.

A new option, -uniform, is added to grid columnconfigure. The option takes an arbitrary string, the default value being the empty string. Any column with a non-empty value will be grouped with other columns with the same value. Each column in a group will get the size k*-weight (in this aspect a -weight value of 0 is used as 1) , where k is set so that no column becomes smaller. E.g., if all columns in a group have the same -weight they will all get the size of the largest member.

In the grid algorithm -uniform and -weight will be used as specified above in the calculation of the requested size (the first step in the description of the grid algorithm in grid(n)), but for the distribution of extra size (second step) only -weight will be considered. This means that the second step is not altered at all by this.


Getting symmetry in a layout today is possible but even for a simple case it gets tricky if you want more than a half decent result. Message catalogs changing strings and options databases changing appearances can make a GUI very dynamic and normally you never need to count pixels since geometry managers do that for you. For symmetry though you suddenly have to handle pixel details yourself, details that are handled so much better by a geometry manager. With a -uniform option, grid can do symmetry for you in a simple way that takes care of all the details.

To only consider -weight in the extra size distribution is mainly a matter of simplicity. It gives a simpler algorithm that is both easier to explain to the user and to code.

To uphold the uniform property it would be needed to force any zero -weight value in a group where any non-zero -weight exists to be set to one before doing the resize calculations. A bit complicated and the only benefit for the user would be to only have to specify -weight for one column in a group. But in practice this is hardly no gain at all since a typical usage looks like this:

grid columnconfigure . {0 1 2} -uniform a -weight 1

I'm not sure if someone would have a use for the effect you would get by mixing zero and non-zero weights in a group but this leaves you the freedom to do so.


To clarify how -uniform affects a grid here are some examples.

button .b1 -text a
button .b2 -text b
button .b3 -text example
button .b4 -text xyzzy
grid .b1 .b2 .b3 .b4 -sticky news
grid columnconfigure . {0 1 2 3} -uniform a -weight 1

Initially all columns will be equal and if resized, all columns will change equally.

Initial: |[   a   ]|[   b   ]|[example]|[ xyzzy ]|
Shrunk:  |[  a  ]|[  b  ]|[xampl]|[xyzzy]|

Another example. Instead we do:

grid columnconfigure . {0 2} -uniform a -weight 1
grid columnconfigure . {2}   -weight 2
grid columnconfigure . {1 3} -uniform b -weight 0
grid columnconfigure . {1}   -weight 1

Initially column 0 will be half the size of column 2, columns 1 and 3 will be equal. Resizing will affect colums 0 and 1 half of how column 2 is affected. Column 3 is static.

Initial:  |[ a ]|[  b  ]|[example]|[xyzzy]|
Shrunk:   |[a]|[ b ]|[amp]|[xyzzy]|
Expanded: |[  a  ]|[   b   ]|[  example  ]|[xyzzy]|


A quick try shows that this is fairly straightforward to implement. If the option is not used the memory cost is a Tk_Uid field (or similar if some other mechanism than Tk_Uid is used) in the column slot structure to hold the option, and the CPU overhead is small.

Summary of Objections


This document has been placed in the public domain.