TIP:            37
Title:          Uniform Rows and Columns in Grid
Version:        $Revision: 1.11 $
Author:         Peter Spjuth <peter.spjuth@space.se>
Author:         Kevin Kenny <kennykb@acm.org>
State:          Final
Type:           Project
Vote:           Done
Created:        19-Jun-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

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.

~ Introduction

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.

~ Specification

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.

~ Rationale

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.

~ Examples

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]|

~ Implementation

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

 * Kevin Kenny raised the issue that the proposed implementation
   uses a Tk_Uid for the "uniform" key, leading to potential resource
   leaks.  Subsequent discussion has convinced him that the potential
   for trouble is small; in any case, it need not block approval.
   The ensuing discussion veered off into a long thread about
   reclaiming the memory used for Tcl_Obj structures; the thread
   is not pertinent to this TIP.

 * George Howlett questioned the need for this feature, citing the
   lack of compelling examples.  The original author replied with
   the example of a dialog holding multiple buttons containing
   text of different widths, and showed how the Tcl code to manage
   such a dialog is clumsy.

 * George Howlett raised the issue of a detailed specification of
   the behavior of -uniform when insufficient space is available to
   satisfy the request.  The original author added clarification in
   the "Examples" section, and supplied additional examples in
   discussions on the mailing list
   [http://www.geocrawler.com/archives/3/7375/2001/7/50/6211900/].

 * George Howlett also asserted that the desired semantics can
   be achieved with Tcl code that either lays out a fixed
   configuration of the widget (with, for example, the ''-minsize''
   option of ''grid columnconfigure'') or responds to the
   ''<Configure>'' event.  Probably the best summary of the ensuing
   discussion is that we need to strike a balance between
   richness of the API and simplicity of the implementation.

~ Copyright

This document has been placed in the public domain.

