I think the undoers should be pushed on a stack. The commander will have a
method that pops the stack and executes that single undoer. This approach
lets a user change the layout, and then change it again without losing the
ability to return to an earlier layout.
There could be a method to walk back to the stack bottom, which would be
the initial layout. I wonder if Qt can freeze visible changes during this
process, to avoid too much screen flashing.
On Saturday, July 20, 2024 at 8:00:24 AM UTC-4 Edward K. Ream wrote:
> We now have several scripts that change Leo's layouts. Let's call the
> results of those scripts *alternate *layouts.
>
> Those scripts suffice if an outline only uses one layout at a time. But
> what if we want to switch between layouts?
>
> - How can we switch between *alternate *layouts?
> - How can we revert to Leo's default layout?
>
> After some experimentation, I saw the answer. *Each layout script must
> define its own undoer.* There is no other way. This creates the following
> (tested) top-level pattern for layout scripts:
>
> """Change layout to Jacob Peck's quadrants layout."""
>
> from typing import Any
> from leo.core.leoQt import Orientation, QtWidgets
> h = c.hash()
> pc = g.app.pluginsController
>
> @others # Define helpers
>
> undo_layout()
>
> if pc.isLoaded('leo.plugins.viewrendered3'):
> import leo.plugins.viewrendered3 as vr3
> try:
> parent = vr3.controllers[h]
> except KeyError:
> vr3.controllers[h] = parent = vr3.ViewRenderedController3(c)
> switch_layout('vr3-show', parent)
> c.layout_undoer = undoer
>
> if pc.isLoaded('leo.plugins.viewrendered'):
> import leo.plugins.viewrendered as vr
> parent = vr.controllers[h]
> switch_layout('vr-show', parent)
> c.layout_undoer = undoer
>
> Here is the latest *switch_layout *method:
>
> def switch_layout(cmd: str, parent: Any) -> None:
>
> gui = g.app.gui
>
> def make_splitter():
> w = QtWidgets.QSplitter()
> w.setObjectName('body_splitter')
> return w
>
> ms = gui.find_widget_by_name(c, 'main_splitter')
> ss = gui.find_widget_by_name(c, 'secondary_splitter')
> edf = gui.find_widget_by_name(c, 'bodyFrame')
>
> # add vertical splitter to ms (hosting only the editor)
> body_splitter = make_splitter()
> body_splitter.setOrientation(Orientation.Vertical)
> ms.addWidget(body_splitter)
> body_splitter.addWidget(edf)
>
> if not parent.isVisible():
> body_splitter.addWidget(parent)
> body_splitter.setSizes([100_000] * len(body_splitter.sizes()))
> ms.setSizes([100_000] * len(ms.sizes()))
> ss.setSizes([100_000] * len(ss.sizes()))
> c.doCommandByName(cmd)
>
> There are two *undo helpers* defined as follows:
>
> def undo_layout():
> layout_undoer = getattr(c, 'layout_undoer', None)
> if layout_undoer:
> layout_undoer(c)
> c.layout_undoer = None
>
> def undoer(c):
> print('')
> print('*** quadrants layout undoer')
> print('')
>
> The undoer function shown above is merely a placeholder.
>
> *Summary*
>
> Each layout script must define a bespoke undoer. That's my next task.
>
> Edward
--
You received this message because you are subscribed to the Google Groups
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/leo-editor/40972920-c86d-4214-84d0-901a5e97a7ben%40googlegroups.com.