summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--doc/ttk_panedwindow.n30
-rw-r--r--generic/ttk/ttkPanedwindow.c84
-rw-r--r--tests/ttk/panedwindow.test51
4 files changed, 149 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index d9a8341..24cb8c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-09 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/ttk/ttkPanedwindow.c, doc/ttk_panedwindow.n,
+ tests/ttk/panedwindow.test: Added -width and -height options.
+ Added 'panes' method, return list of managed windows.
+ 'sashpos' method is now documented as part of the public
+ interface, and details clarified. Should be easier
+ to set initial sash positions now [Alleviates #1659067].
+
2007-06-09 Jeff Hobbs <jeffh@ActiveState.com>
* win/tkWinWm.c (WmIconphotoCmd): fix wm iconphoto RGBA issues.
diff --git a/doc/ttk_panedwindow.n b/doc/ttk_panedwindow.n
index 4928b15..b7d0210 100644
--- a/doc/ttk_panedwindow.n
+++ b/doc/ttk_panedwindow.n
@@ -4,7 +4,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: ttk_panedwindow.n,v 1.5 2007/06/09 21:45:44 jenglish Exp $
+'\" RCS: @(#) $Id: ttk_panedwindow.n,v 1.6 2007/06/10 03:25:32 jenglish Exp $
'\"
.so man.macros
.TH ttk_panedwindow n 8.5 Tk "Tk Themed Widget"
@@ -34,6 +34,16 @@ of the subwindows by dragging the sash between panes.
Specifies the orientation of the window.
If \fBvertical\fR, subpanes are stacked top-to-bottom;
if \fBhorizontal\fR, subpanes are stacked left-to-right.
+.OP \-width width Width
+If present and greater than zero,
+specifies the desired width of the widget in pixels.
+Otherwise, the requested width is determined by the width
+of the managed windows.
+.OP \-height height Height
+If present and greater than zero,
+specifies the desired height of the widget in pixels.
+Otherwise, the requested height is determined by the height
+of the managed windows.
.SH "PANE OPTIONS"
The following options may be specified for each pane:
@@ -71,15 +81,19 @@ If no \fI-option\fR is specified, returns a dictionary of the pane
option values.
If one \fI-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI-option\fRs to the corresponding \fIvalue\fRs.
-
-.SH "INTERNAL ROUTINES"
-The following routines are used internally by the \fBpaned\fR widget
-binding code.
.TP
\fIpathname\fR \fBsashpos\fR \fIindex\fR ?\fInewpos\fR?
-If \fInewpos\fR is specified, sets the sash position
-(subject to constraints).
-Returns the position of sash number \fIindex\fR.
+If \fInewpos\fR is specified, sets the position
+of sash number \fIindex\fR.
+May adjust the positions of adjacent sashes
+to ensure that positions are monotonically increasing.
+Sash positions are further constrained to be between 0
+and the total size of the widget.
+.\" Full story: "total size" is either the -height (resp -width),
+.\" or the actual window height (resp actual window width),
+.\" depending on which changed most recently.
+Returns the new position of sash number \fIindex\fR.
+.\" Full story: new position may be different than the requested position.
.TP
\fIpathname\fR \fBidentify\fR \fIx y\fR
Returns the index of the sash at point \fIx,y\fR,
diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c
index 7de701c..e961815 100644
--- a/generic/ttk/ttkPanedwindow.c
+++ b/generic/ttk/ttkPanedwindow.c
@@ -1,4 +1,4 @@
-/* $Id: ttkPanedwindow.c,v 1.10 2007/06/09 21:45:45 jenglish Exp $
+/* $Id: ttkPanedwindow.c,v 1.11 2007/06/10 03:25:32 jenglish Exp $
*
* Copyright (c) 2005, Joe English. Freely redistributable.
*
@@ -26,7 +26,7 @@
*
* Pane geometry is determined by the sash positions.
* When resizing, sash positions are computed from the request sizes,
- * the available space, and pane weights (see ComputePositions()).
+ * the available space, and pane weights (see PlaceSashes()).
* This ensures continuous resize behavior (that is: changing
* the size by X pixels then changing the size by Y pixels
* gives the same result as changing the size by X+Y pixels
@@ -61,8 +61,10 @@
*/
typedef struct {
- Tcl_Obj *orientObj;
+ Tcl_Obj *orientObj;
int orient;
+ int width;
+ int height;
Ttk_Manager *mgr;
Tk_OptionTable paneOptionTable;
Ttk_Layout sashLayout;
@@ -80,6 +82,12 @@ static Tk_OptionSpec PanedOptionSpecs[] = {
{TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
Tk_Offset(Paned,paned.orientObj), Tk_Offset(Paned,paned.orient),
0,(ClientData)ttkOrientStrings,READONLY_OPTION|STYLE_CHANGED },
+ {TK_OPTION_INT, "-width", "width", "Width", "0",
+ -1,Tk_Offset(Paned,paned.width),
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-height", "height", "Height", "0",
+ -1,Tk_Offset(Paned,paned.height),
+ 0,0,GEOMETRY_CHANGED },
WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};
@@ -168,7 +176,7 @@ error:
/*------------------------------------------------------------------------
- * +++ Layout algorithm.
+ * +++ Sash adjustment.
*/
/* ShoveUp --
@@ -215,7 +223,7 @@ static int ShoveDown(Paned *pw, int i, int pos)
}
/* PanedSize --
- * Compute the requested size of the paned widget
+ * Compute the requested size of the paned widget
* from the individual pane request sizes.
*
* Used as the WidgetSpec sizeProc and the ManagerSpec sizeProc.
@@ -251,8 +259,8 @@ static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
height += nSashes * sashThickness;
}
- *widthPtr = width;
- *heightPtr = height;
+ *widthPtr = pw->paned.width > 0 ? pw->paned.width : width;
+ *heightPtr = pw->paned.height > 0 ? pw->paned.height : height;
return 1;
}
@@ -260,7 +268,7 @@ static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
* Set pane request sizes from sash positions.
*
* NOTE:
- * AdjustPanes followed by ComputePositions (called during relayout)
+ * AdjustPanes followed by PlaceSashes (called during relayout)
* will leave the sashes in the same place, as long as available size
* remains contant.
*/
@@ -278,8 +286,9 @@ static void AdjustPanes(Paned *pw)
}
}
-/* ComputePositions --
+/* PlaceSashes --
* Set sash positions from pane request sizes and available space.
+ * The sentinel sash position is set to the available space.
*
* Allocate pane->reqSize pixels to each pane, and distribute
* the difference = available size - requested size according
@@ -293,14 +302,12 @@ static void AdjustPanes(Paned *pw)
* This doesn't distribute the remainder pixels as evenly as it could
* when more than one pane has weight > 1.
*/
-static void ComputePositions(Paned *pw)
+static void PlaceSashes(Paned *pw, int width, int height)
{
Ttk_Manager *mgr = pw->paned.mgr;
int nPanes = Ttk_NumberSlaves(mgr);
int sashThickness = pw->paned.sashThickness;
- int available
- = pw->paned.orient == TTK_ORIENT_HORIZONTAL
- ? Tk_Width(pw->core.tkwin) : Tk_Height(pw->core.tkwin);
+ int available = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? width : height;
int reqSize = 0, totalWeight = 0;
int difference, delta, remainder, pos, i;
@@ -393,7 +400,7 @@ static void PlacePanes(Paned *pw)
static void PanedPlaceSlaves(void *managerData)
{
Paned *pw = managerData;
- ComputePositions(pw);
+ PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
PlacePanes(pw);
}
@@ -518,6 +525,25 @@ static void PanedCleanup(void *recordPtr)
Ttk_DeleteManager(pw->paned.mgr);
}
+/* Post-configuration hook.
+ */
+static int PanedPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
+{
+ Paned *pw = clientData;
+
+ if (mask & GEOMETRY_CHANGED) {
+ /* User has changed -width or -height.
+ * Recalculate sash positions based on requested size.
+ */
+ Tk_Window tkwin = pw->core.tkwin;
+ PlaceSashes(pw,
+ pw->paned.width > 0 ? pw->paned.width : Tk_Width(tkwin),
+ pw->paned.height > 0 ? pw->paned.height : Tk_Height(tkwin));
+ }
+
+ return TCL_OK;
+}
+
/*------------------------------------------------------------------------
* +++ Layout management hooks.
*/
@@ -762,6 +788,33 @@ static int PanedPaneCommand(
}
}
+/* $pw panes --
+ * Return list of managed panes.
+ */
+static int PanedPanesCommand(
+ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
+{
+ Paned *pw = recordPtr;
+ Ttk_Manager *mgr = pw->paned.mgr;
+ Tcl_Obj *panes;
+ int i;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+
+ panes = Tcl_NewListObj(0, NULL);
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
+ const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
+ Tcl_ListObjAppendElement(interp, panes, Tcl_NewStringObj(pathName,-1));
+ }
+ Tcl_SetObjResult(interp, panes);
+
+ return TCL_OK;
+}
+
+
/* $pw sashpos $index ?$newpos?
* Query or modify sash position.
*/
@@ -821,6 +874,7 @@ static WidgetCommandSpec PanedCommands[] =
{ "insert", PanedInsertCommand },
{ "instate", TtkWidgetInstateCommand },
{ "pane", PanedPaneCommand },
+ { "panes", PanedPanesCommand },
{ "sashpos", PanedSashposCommand },
{ "state", TtkWidgetStateCommand },
{ 0,0 }
@@ -839,7 +893,7 @@ static WidgetSpec PanedWidgetSpec =
PanedInitialize, /* initializeProc */
PanedCleanup, /* cleanupProc */
TtkCoreConfigure, /* configureProc */
- TtkNullPostConfigure, /* postConfigureProc */
+ PanedPostConfigure, /* postConfigureProc */
PanedGetLayout, /* getLayoutProc */
PanedSize, /* sizeProc */
TtkWidgetDoLayout, /* layoutProc */
diff --git a/tests/ttk/panedwindow.test b/tests/ttk/panedwindow.test
index 47764a2..81232ba 100644
--- a/tests/ttk/panedwindow.test
+++ b/tests/ttk/panedwindow.test
@@ -1,5 +1,5 @@
#
-# $Id: panedwindow.test,v 1.3 2007/06/09 21:45:45 jenglish Exp $
+# $Id: panedwindow.test,v 1.4 2007/06/10 03:25:32 jenglish Exp $
#
package require Tk 8.5
@@ -182,7 +182,7 @@ test panedwindow-4.END "cleanup" -body {
# See #1292219
-test panedwindow-5.1 "Propage Map/Unmap state to children" -body {
+test panedwindow-5.1 "Propagate Map/Unmap state to children" -body {
set result [list]
pack [ttk::panedwindow .pw]
.pw add [ttk::button .pw.b]
@@ -199,4 +199,51 @@ test panedwindow-5.1 "Propage Map/Unmap state to children" -body {
destroy .pw
}
+### sashpos tests.
+#
+proc sashpositions {pw} {
+ set positions [list]
+ set npanes [llength [winfo children $pw]]
+ for {set i 0} {$i < $npanes - 1} {incr i} {
+ lappend positions [$pw sashpos $i]
+ }
+ return $positions
+}
+
+test paned-sashpos-setup "Setup for sash position test" -body {
+ ttk::style theme use default
+ ttk::style configure -sashthickness 5
+
+ ttk::panedwindow .pw
+ .pw add [frame .pw.f1 -width 20 -height 20]
+ .pw add [frame .pw.f2 -width 20 -height 20]
+ .pw add [frame .pw.f3 -width 20 -height 20]
+ .pw add [frame .pw.f4 -width 20 -height 20]
+
+ update idletasks
+ list [winfo reqwidth .pw] [winfo reqheight .pw]
+} -result [list 20 [expr {20*4 + 5*3}]]
+
+test paned-sashpos-attempt-restore "Attempt to set sash positions" -body {
+ # This is not expected to succeed, since .pw isn't large enough yet.
+ #
+ .pw sashpos 0 30
+ .pw sashpos 1 60
+ .pw sashpos 2 90
+
+ list [winfo reqwidth .pw] [winfo reqheight .pw] [sashpositions .pw]
+} -result [list 20 95 [list 0 5 10]]
+
+test paned-sashpos-restore "Set height then sash positions" -body {
+ # Setting sash positions after setting -height _should_ succeed.
+ #
+ .pw configure -height 120
+ .pw sashpos 0 30
+ .pw sashpos 1 60
+ .pw sashpos 2 90
+ list [winfo reqwidth .pw] [winfo reqheight .pw] [sashpositions .pw]
+} -result [list 20 120 [list 30 60 90]]
+
+test paned-sashpos-cleanup "Clean up" -body { destroy .pw }
+
tcltest::cleanupTests