diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | doc/ttk_panedwindow.n | 30 | ||||
-rw-r--r-- | generic/ttk/ttkPanedwindow.c | 84 | ||||
-rw-r--r-- | tests/ttk/panedwindow.test | 51 |
4 files changed, 149 insertions, 25 deletions
@@ -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 |