summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--doc/grid.n28
-rw-r--r--generic/tkGrid.c280
-rw-r--r--tests/grid.test61
4 files changed, 251 insertions, 124 deletions
diff --git a/ChangeLog b/ChangeLog
index eaa8e47..86907e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2003-09-18 Peter Spjuth <peter.spjuth@space.se>
+ * doc/grid.n:
+ * tests/grid.test:
+ * generic/tkGrid.c: Implementation of TIP#147,
+ "Make Grid's Column/Row Configure Easier".
+
2003-09-17 Don Porter <dgp@users.sourceforge.net>
* generic/tkImage.c: Stopped [image create] from generating an
diff --git a/doc/grid.n b/doc/grid.n
index c6c3b17..07c1ddd 100644
--- a/doc/grid.n
+++ b/doc/grid.n
@@ -4,10 +4,10 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: grid.n,v 1.5 2001/09/30 19:01:58 pspjuth Exp $
+'\" RCS: @(#) $Id: grid.n,v 1.6 2003/09/18 18:22:22 pspjuth Exp $
'\"
.so man.macros
-.TH grid n 8.4 Tk "Tk Built-In Commands"
+.TH grid n 8.5 Tk "Tk Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -46,12 +46,16 @@ indicated is returned.
\fBgrid columnconfigure \fImaster index \fR?\fI\-option value...\fR?
Query or set the column properties of the \fIindex\fP column of the
geometry master, \fImaster\fP.
-.VS 8.4
The valid options are \fB\-minsize\fP, \fB\-weight\fP, \fB\-uniform\fP
and \fB-pad\fP.
-.VE
If one or more options are provided, then \fIindex\fP may be given as
-a list of column indeces to which the configuration options will operate on.
+a list of column indices to which the configuration options will operate on.
+.VS 8.5
+Indices may be integers, window names or the keyword \fIall\fP. For \fIall\fP
+the options apply to all columns currently occupied be slave windows. For
+a window name, that window must be a slave of this master and the options
+apply to all columns currently occupied be the slave.
+.VE
The \fB\-minsize\fP option sets the minimum size, in screen units,
that will be permitted for this column.
The \fB\-weight\fP option (an integer value)
@@ -61,14 +65,12 @@ columns.
A weight of zero (0) indicates the column will not deviate from its requested
size. A column whose weight is two will grow at twice the rate as a column
of weight one when extra space is allocated to the layout.
-.VS 8.4
The \fB-uniform\fP option, when a non-empty value is supplied, places
the column in a \fIuniform group\fP with other columns that have the
same value for \fB-uniform\fP. The space for columns belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB-weight\fP values. See
``THE GRID ALGORITHM'' below for further details.
-.VE
The \fB-pad\fP option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
@@ -204,12 +206,16 @@ Propagation is enabled by default.
\fBgrid rowconfigure \fImaster index \fR?\fI\-option value...\fR?
Query or set the row properties of the \fIindex\fP row of the
geometry master, \fImaster\fP.
-.VS 8.4
The valid options are \fB\-minsize\fP, \fB\-weight\fP, \fB\-uniform\fP
and \fB-pad\fP.
-.VE
If one or more options are provided, then \fIindex\fP may be given as
-a list of row indeces to which the configuration options will operate on.
+a list of row indices to which the configuration options will operate on.
+.VS 8.5
+Indices may be integers, window names or the keyword \fIall\fP. For \fIall\fP
+the options apply to all rows currently occupied be slave windows. For
+a window name, that window must be a slave of this master and the options
+apply to all rows currently occupied be the slave.
+.VE
The \fB\-minsize\fP option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fP option (an integer value)
@@ -219,14 +225,12 @@ rows.
A weight of zero (0) indicates the row will not deviate from its requested
size. A row whose weight is two will grow at twice the rate as a row
of weight one when extra space is allocated to the layout.
-.VS 8.4
The \fB-uniform\fP option, when a non-empty value is supplied, places
the row in a \fIuniform group\fP with other rows that have the
same value for \fB-uniform\fP. The space for rows belonging to a
uniform group is allocated so that their sizes are always in strict
proportion to their \fB-weight\fP values. See
``THE GRID ALGORITHM'' below for further details.
-.VE
The \fB-pad\fP option specifies the number of screen units that will be
added to the largest window contained completely in that row when the
grid geometry manager requests a size from the containing window.
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index 0b6ac23..9a8ca90 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkGrid.c,v 1.27 2003/09/16 21:47:15 pspjuth Exp $
+ * RCS: @(#) $Id: tkGrid.c,v 1.28 2003/09/18 18:22:22 pspjuth Exp $
*/
#include "tkInt.h"
@@ -838,17 +838,17 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
- Tk_Window master;
+ Tk_Window master, slave;
Gridder *masterPtr;
+ Gridder *slavePtr;
SlotInfo *slotPtr = NULL;
int slot; /* the column or row number */
int slotType; /* COLUMN or ROW */
int size; /* the configuration value */
- int checkOnly; /* check the size only */
int lObjc; /* Number of items in index list */
Tcl_Obj **lObjv; /* array of indices */
int ok; /* temporary TCL result code */
- int i, j;
+ int i, j, first, last;
char *string;
static CONST char *optionStrings[] = {
"-minsize", "-pad", "-uniform", "-weight", (char *) NULL };
@@ -869,30 +869,26 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
}
string = Tcl_GetString(objv[1]);
- checkOnly = ((objc == 4) || (objc == 5));
masterPtr = GetGrid(master);
slotType = (*string == 'c') ? COLUMN : ROW;
- if (checkOnly && lObjc > 1) {
- Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
- " must be a single element.", (char *) NULL);
- return TCL_ERROR;
- }
- for (j = 0; j < lObjc; j++) {
- if (Tcl_GetIntFromObj(interp, lObjv[j], &slot) != TCL_OK) {
+
+ if ((objc == 4) || (objc == 5)) {
+ if (lObjc != 1) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
+ " must be a single element.", (char *) NULL);
return TCL_ERROR;
}
- ok = CheckSlotData(masterPtr, slot, slotType, checkOnly);
- if ((ok != TCL_OK) && ((objc < 4) || (objc > 5))) {
- Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
- Tcl_GetString(objv[1]), ": \"", Tcl_GetString(lObjv[j]),
- "\" is out of range", (char *) NULL);
+ if (Tcl_GetIntFromObj(interp, lObjv[0], &slot) != TCL_OK) {
+ Tcl_AppendResult(interp,
+ " (when retreiving options only integer indices are allowed)",
+ (char *) NULL);
return TCL_ERROR;
- } else if (ok == TCL_OK) {
- slotPtr = (slotType == COLUMN) ?
- masterPtr->masterDataPtr->columnPtr :
- masterPtr->masterDataPtr->rowPtr;
}
-
+ ok = CheckSlotData(masterPtr, slot, slotType, /* checkOnly */ 1);
+ slotPtr = (slotType == COLUMN) ?
+ masterPtr->masterDataPtr->columnPtr :
+ masterPtr->masterDataPtr->rowPtr;
+
/*
* Return all of the options for this row or column. If the
* request is out of range, return all 0's.
@@ -902,7 +898,7 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
int minsize = 0, pad = 0, weight = 0;
Tk_Uid uniform = NULL;
Tcl_Obj *res = Tcl_NewListObj(0, NULL);
-
+
if (ok == TCL_OK) {
minsize = slotPtr[slot].minSize;
pad = slotPtr[slot].pad;
@@ -926,114 +922,178 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
Tcl_SetObjResult(interp, res);
return TCL_OK;
}
-
+
/*
- * Loop through each option value pair, setting the values as
- * required. If only one option is given, with no value, the
+ * If only one option is given, with no value, the
* current value is returned.
*/
- for (i = 4; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[4], optionStrings,
+ "option", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == ROWCOL_MINSIZE) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].minSize : 0));
+ } else if (index == ROWCOL_WEIGHT) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].weight : 0));
+ } else if (index == ROWCOL_UNIFORM) {
+ Tk_Uid value;
+ value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(value == NULL ? "" : value, -1));
+ } else if (index == ROWCOL_PAD) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].pad : 0));
+ }
+ return TCL_OK;
+ }
+
+ for (j = 0; j < lObjc; j++) {
+ int allSlaves = 0;
+ if (Tcl_GetIntFromObj(interp, lObjv[j], &slot) == TCL_OK) {
+ first = slot;
+ last = slot;
+ slavePtr = NULL;
+ } else if (strcmp(Tcl_GetString(lObjv[j]), "all") == 0) {
+ slavePtr = masterPtr->slavePtr;
+ if (slavePtr == NULL) {
+ continue;
+ }
+ allSlaves = 1;
+ } else if (TkGetWindowFromObj(interp, tkwin, lObjv[j], &slave)
+ == TCL_OK) {
+ /* Is it gridded in this master? */
+ slavePtr = GetGrid(slave);
+ if (slavePtr->masterPtr != masterPtr) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": the window \"",
+ Tcl_GetString(lObjv[j]),
+ "\" is not managed by \"", Tcl_GetString(objv[2]),
+ "\"", (char *) NULL);
return TCL_ERROR;
}
- if (index == ROWCOL_MINSIZE) {
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
- } else if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size)
- != TCL_OK) {
- return TCL_ERROR;
- } else {
- slotPtr[slot].minSize = size;
- }
+ } else {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": illegal index \"",
+ Tcl_GetString(lObjv[j]), "\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * The outer loop is only to handle "all".
+ */
+ do {
+ if (slavePtr != NULL) {
+ first = (slotType == COLUMN) ?
+ slavePtr->column : slavePtr->row;
+ last = first - 1 + ((slotType == COLUMN) ?
+ slavePtr->numCols : slavePtr->numRows);
}
- else if (index == ROWCOL_WEIGHT) {
- int wt;
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].weight : 0));
- } else if (Tcl_GetIntFromObj(interp, objv[i+1], &wt)
- != TCL_OK) {
- return TCL_ERROR;
- } else if (wt < 0) {
- Tcl_AppendResult(interp, "invalid arg \"",
- Tcl_GetString(objv[i]),
- "\": should be non-negative", (char *) NULL);
+
+ for (slot = first; slot <= last; slot++) {
+ ok = CheckSlotData(masterPtr, slot, slotType, /*checkOnly*/ 0);
+ if (ok != TCL_OK) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": \"",
+ Tcl_GetString(lObjv[j]),
+ "\" is out of range", (char *) NULL);
return TCL_ERROR;
- } else {
- slotPtr[slot].weight = wt;
}
- }
- else if (index == ROWCOL_UNIFORM) {
- if (objc == 5) {
- Tk_Uid value;
- value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";
- if (value == NULL) {
- value = "";
+ slotPtr = (slotType == COLUMN) ?
+ masterPtr->masterDataPtr->columnPtr :
+ masterPtr->masterDataPtr->rowPtr;
+
+ /*
+ * Loop through each option value pair, setting the values as
+ * required.
+ */
+
+ for (i = 4; i < objc; i += 2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
+ "option", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
- } else {
- slotPtr[slot].uniform = Tk_GetUid(Tcl_GetString(objv[i+1]));
- if (slotPtr[slot].uniform != NULL &&
- slotPtr[slot].uniform[0] == 0) {
- slotPtr[slot].uniform = NULL;
+ if (index == ROWCOL_MINSIZE) {
+ if (Tk_GetPixelsFromObj(interp, master, objv[i+1],
+ &size) != TCL_OK) {
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].minSize = size;
+ }
+ } else if (index == ROWCOL_WEIGHT) {
+ int wt;
+ if (Tcl_GetIntFromObj(interp, objv[i+1], &wt) != TCL_OK) {
+ return TCL_ERROR;
+ } else if (wt < 0) {
+ Tcl_AppendResult(interp, "invalid arg \"",
+ Tcl_GetString(objv[i]),
+ "\": should be non-negative", (char *) NULL);
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].weight = wt;
+ }
+ } else if (index == ROWCOL_UNIFORM) {
+ slotPtr[slot].uniform = Tk_GetUid(Tcl_GetString(objv[i+1]));
+ if (slotPtr[slot].uniform != NULL &&
+ slotPtr[slot].uniform[0] == 0) {
+ slotPtr[slot].uniform = NULL;
+ }
+ } else if (index == ROWCOL_PAD) {
+ if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size)
+ != TCL_OK) {
+ return TCL_ERROR;
+ } else if (size < 0) {
+ Tcl_AppendResult(interp, "invalid arg \"",
+ Tcl_GetString(objv[i]),
+ "\": should be non-negative", (char *) NULL);
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].pad = size;
+ }
}
}
}
- else if (index == ROWCOL_PAD) {
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].pad : 0));
- } else if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size)
- != TCL_OK) {
- return TCL_ERROR;
- } else if (size < 0) {
- Tcl_AppendResult(interp, "invalid arg \"",
- Tcl_GetString(objv[i]),
- "\": should be non-negative", (char *) NULL);
- return TCL_ERROR;
- } else {
- slotPtr[slot].pad = size;
- }
+ if (slavePtr != NULL) {
+ slavePtr = slavePtr->nextPtr;
}
- }
+ } while ((allSlaves == 1) && (slavePtr != NULL));
}
/*
- * If we changed a property, re-arrange the table,
+ * We changed a property, re-arrange the table,
* and check for constraint shrinkage.
*/
- if (objc != 5) {
- if (slotType == ROW) {
- int last = masterPtr->masterDataPtr->rowMax - 1;
- while ((last >= 0) && (slotPtr[last].weight == 0)
- && (slotPtr[last].pad == 0)
- && (slotPtr[last].minSize == 0)
- && (slotPtr[last].uniform == NULL)) {
- last--;
- }
- masterPtr->masterDataPtr->rowMax = last+1;
- } else {
- int last = masterPtr->masterDataPtr->columnMax - 1;
- while ((last >= 0) && (slotPtr[last].weight == 0)
- && (slotPtr[last].pad == 0)
- && (slotPtr[last].minSize == 0)
- && (slotPtr[last].uniform == NULL)) {
- last--;
- }
- masterPtr->masterDataPtr->columnMax = last + 1;
- }
-
- if (masterPtr->abortPtr != NULL) {
- *masterPtr->abortPtr = 1;
- }
- if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
- masterPtr->flags |= REQUESTED_RELAYOUT;
- Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
+ if (slotType == ROW) {
+ int last = masterPtr->masterDataPtr->rowMax - 1;
+ while ((last >= 0) && (slotPtr[last].weight == 0)
+ && (slotPtr[last].pad == 0)
+ && (slotPtr[last].minSize == 0)
+ && (slotPtr[last].uniform == NULL)) {
+ last--;
+ }
+ masterPtr->masterDataPtr->rowMax = last+1;
+ } else {
+ int last = masterPtr->masterDataPtr->columnMax - 1;
+ while ((last >= 0) && (slotPtr[last].weight == 0)
+ && (slotPtr[last].pad == 0)
+ && (slotPtr[last].minSize == 0)
+ && (slotPtr[last].uniform == NULL)) {
+ last--;
}
+ masterPtr->masterDataPtr->columnMax = last + 1;
+ }
+
+ if (masterPtr->abortPtr != NULL) {
+ *masterPtr->abortPtr = 1;
+ }
+ if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
+ masterPtr->flags |= REQUESTED_RELAYOUT;
+ Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
}
return TCL_OK;
}
diff --git a/tests/grid.test b/tests/grid.test
index 063c9f8..c751db4 100644
--- a/tests/grid.test
+++ b/tests/grid.test
@@ -5,7 +5,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: grid.test,v 1.20 2003/09/16 21:47:15 pspjuth Exp $
+# RCS: @(#) $Id: grid.test,v 1.21 2003/09/18 18:22:22 pspjuth Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -582,7 +582,7 @@ grid_reset 10.3
test grid-10.4 {column/row configure} {
list [catch {grid columnconfigure . nine -weight} msg] $msg
-} {1 {expected integer but got "nine"}}
+} {1 {expected integer but got "nine" (when retreiving options only integer indices are allowed)}}
grid_reset 10.4
test grid-10.5 {column/row configure} {
@@ -687,6 +687,63 @@ test grid-10.20 {column/row configure} {
} {foo}
grid_reset 10.20
+test grid-10.21 {column/row configure} {
+ list [catch {grid columnconfigure . .b -weight 1} msg] $msg
+} {1 {grid columnconfigure: illegal index ".b"}}
+grid_reset 10.21
+
+test grid-10.22 {column/row configure} {
+ button .b
+ list [catch {grid columnconfigure . .b -weight 1} msg] $msg
+} {1 {grid columnconfigure: the window ".b" is not managed by "."}}
+grid_reset 10.22
+
+test grid-10.23 {column/row configure} {
+ button .b
+ grid .b -column 1 -columnspan 2
+ grid columnconfigure . .b -weight 1
+ set res {}
+ foreach i {0 1 2 3} {
+ lappend res [grid columnconfigure . $i -weight]
+ }
+ set res
+} {0 1 1 0}
+grid_reset 10.23
+
+test grid-10.24 {column/row configure} {
+ button .b
+ button .c
+ button .d
+ grid .b -column 1 -columnspan 2
+ grid .c -column 2 -columnspan 3
+ grid .d -column 4 -columnspan 2
+ grid columnconfigure . {.b .d} -weight 1
+ grid columnconfigure . .c -weight 2
+ set res {}
+ foreach i {0 1 2 3 4 5 6} {
+ lappend res [grid columnconfigure . $i -weight]
+ }
+ set res
+} {0 1 2 2 2 1 0}
+grid_reset 10.24
+
+test grid-10.25 {column/row configure} {
+ button .b
+ button .c
+ button .d
+ grid .b -row 1 -rowspan 2
+ grid .c -row 2 -rowspan 3
+ grid .d -row 4 -rowspan 2
+ grid rowconfigure . {7 all} -weight 1
+ grid rowconfigure . {1 .d} -weight 2
+ set res {}
+ foreach i {0 1 2 3 4 5 6 7} {
+ lappend res [grid rowconfigure . $i -weight]
+ }
+ set res
+} {0 2 1 1 2 2 0 1}
+grid_reset 10.25
+
# auto-placement tests
test grid-11.1 {default widget placement} {