\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#37: Uniform Rows and Columns in Grid}
\date{June 19, 2001}
\author{Peter Spjuth, Kevin Kenny}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#37}&\textbf{Uniform Rows and Columns in Grid}\\\hline
Author&

Peter Spjuth \tipmail{peter.spjuth}{space.se}
\par
Kevin Kenny \tipmail{kennykb}{acm.org}
\\
Created&Tuesday, \(\text{19}^{\text{th}}\) June 2001\\
Type&Project\\
Tcl Version&\(8.4\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.11 $\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes to add a \textit{-uniform} option to \textit{grid rowconfigure} and \textit{grid columnconfigure} so as to make it easier to create layouts where cells are constrained to have identical dimensions.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{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.

\section{Specification}

Anywhere \textit{column} is used below, the same applies to \textit{row} too.

A new option, \textit{-uniform}, is added to \textit{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*\textit{-weight} (in this aspect a \textit{-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 \textit{-weight} they will all get the size of the largest member.

In the grid algorithm \textit{-uniform} and \textit{-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 \textit{-weight} will be considered. This means that the second step is not altered at all by this.

\section{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 \textit{-uniform} option, grid can do symmetry for you in a simple way that takes care of all the details.

To only consider \textit{-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 \textit{-weight} value in a group where any non-zero \textit{-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 \textit{-weight} for one column in a group. But in practice this is hardly no gain at all since a typical usage looks like this:
\begingroup\small\begin{verbatim}
grid columnconfigure . {0 1 2} -uniform a -weight 1
\end{verbatim}
\endgroup

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.

\section{Examples}

To clarify how -uniform affects a grid here are some examples.
\begingroup\small\begin{verbatim}
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
\end{verbatim}
\endgroup

Initially all columns will be equal and if resized, all columns will change equally.
\begingroup\small\begin{verbatim}
Initial: |[   a   ]|[   b   ]|[example]|[ xyzzy ]|
Shrunk:  |[  a  ]|[  b  ]|[xampl]|[xyzzy]|
\end{verbatim}
\endgroup

Another example. Instead we do:
\begingroup\small\begin{verbatim}
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
\end{verbatim}
\endgroup

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.
\begingroup\small\begin{verbatim}
Initial:  |[ a ]|[  b  ]|[example]|[xyzzy]|
Shrunk:   |[a]|[ b ]|[amp]|[xyzzy]|
Expanded: |[  a  ]|[   b   ]|[  example  ]|[xyzzy]|
\end{verbatim}
\endgroup

\section{Implementation}

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

\section{Summary of Objections}
\begin{itemize}
\item{}
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.
\item{}
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.
\item{}
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 [\url{http://www.geocrawler.com/archives/3/7375/2001/7/50/6211900/}].
\item{}
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 \textit{-minsize} option of \textit{grid columnconfigure}) or responds to the \textit{\tiplangle{}Configure\tiprangle{}} 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.
\end{itemize}

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
