|
From: Joe E. <jen...@fl...> - 2007-06-10 03:17:16
|
A couple of weeks ago, Paul Mackerras asked on tcl-core
if there was a good way to save and restore the configuration
of a ttk::panedwindow, so that an application could start up
with the same pane sizes that it had last time it was run.
See also bug #1659067, which is about the same problem.
It turns out that there is a way to do so, but not a *good* way --
it's exceedingly tricky to ensure that everything happens in the
right order and at the right time.
Recent changes to the ttk::panedwindow widget should remedy
this somewhat. The widget now takes -width and -height options:
| -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.
| -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.
In addition, the 'sashpos' method is now considered public and
the documentation has been clarified:
| _pathname_ sashpos _index_ ?_newpos_?
| If _newpos_ is specified, sets the position of sash number
| _index_. 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. Returns the new position of sash number _index_.
The "total size" is either the actual panedwindow height
(resp. actual panedwindow width), or the requested -height
(resp. requested -width), depending on which was most recently
changed.
There's also a new [$pw panes] command, which returns the
list of managed panes. (I forgot to add this initially.)
So to save the panedwindow configuration, an application
can use the following procedure:
(S-1) Call [update], so that any pending geometry requests
are fully processed.
(S-2) Record [winfo width $pw] and [winfo height $pw]
(S-3) Record [$pw sashpos $i] for 0 <= $i < #panes-1
To restore the configuration:
(R-1) Call [update idletasks] to ensure that there are no
outstanding geometry requests from slave windows.
(R-2) Call [$pw configure -width $w -height $h], where $w and $h
are the values recorded in step (S-2).
(R-3) Call [$pw sashpos $i $savedPosition($i)] to restore
the sash positions.
(R-4) Let the geometry propagation dance do its thing.
The essential part is to set the -width and -height
*before* setting the sash positions. A full [update]
isn't necessary in step (R-1), but [update idletasks] is:
otherwise GM requests from unmapped slaves will override
the work done in (R-3).
S-[1-3] can be performed any time after the panedwindow is
mapped and before it's destroyed. Of course, step (S-1) must
_not_ be called inside an event binding; if you want to save
the configuration whenever the widget is resized, schedule S-[2-3]
as an [after idle] callback from a <Configure> binding.
R-[1-4] should be done after creating and managing all
of the panedwindow's descendants, but before the panedwindow
itself is mapped (to avoid "blinking").
This should also better support Brian Griffin's use case
(specifying pane sizes as relative fractions of the overall
window size).
--Joe English
jen...@fl...
|