Back and Forward walk the panels too, not just the sheets

Opening a Properties or Link view was invisible to the history, so Back
from one did two things at once: it took the panel down and stepped to the
sheet before the one it was opened over. There was no way back to a
picture you had just been reading.

A history entry is now a (kind, element) pair naming what the editor pane
held -- a sheet, a Properties view, or a Link View -- and restoring one
puts that back: a sheet entry selects its tree node, a panel entry
re-opens the panel. So opening a panel is a move like opening a sheet.
Back from a Properties view lands on whatever came before it and Forward
brings the panel back, and following a link out of the Link View now has a
way home: Back returns to the picture the link was followed from, and a
second Back to the sheet that was open before that.

The panel's own Close is deliberately not recorded. It means "leave this
view", and recording it would put a sheet entry after the panel's, so Back
would re-open the panel that had just been closed. Leaving the position
alone means Back steps to what came before the panel and Forward re-opens
it, which is what the arrows are for.

Both arrows still go through close_editor_panel first, so unsaved
Properties edits are asked about exactly as before and a refusal leaves
the view and the position where they were. Pruning now has two kinds of
entry to check -- a sheet needs a tree node, a panel needs its component
still in the document -- and collapses any pair it leaves naming the same
view, since a Back that visibly does nothing is worse than a shorter
trail.

sheet_history and its functions are renamed for what they now hold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 19:39:45 +03:00
co-authored by Claude Opus 5
parent b119e02b9e
commit 1546c1c8e0
3 changed files with 160 additions and 72 deletions
+36 -10
View File
@@ -123,14 +123,36 @@ the boxes back to 1:1 for the routing pass and scales the result again, since th
reads box positions straight off the canvas. Canvas coordinates therefore carry the zoom,
which is why the drag, release and drop handlers snap against `meta_scale * zoom`.
**Back** and **Forward** walk the sheets opened this session, mirrored by the two arrow
buttons in the toolbar. The history records the element whose children are painted -- the
same thing `app_state.current_sheet_parent` holds -- rather than a tree item id, because
rebuilding the tree hands out fresh ids while the elements themselves survive. Opening a
different file retires the history; a delete or an undo drops only the entries whose
element has left the document, keeping the position on screen. Walking the history drives
the tree selection, which is what paints the sheet, and is suppressed from recording so a
walk cannot rewrite the trail it is following.
**Back** and **Forward** walk everything the **editor pane** has held this session,
mirrored by the two arrow buttons in the toolbar -- sheets and the two panels alike. Each
entry is a `(kind, element)` pair naming one of the three:
| Entry | What Back or Forward puts back |
|---|---|
| `(VIEW_SHEET, element)` | selects that element's tree node, which is what paints its children |
| `(VIEW_PROPERTIES, comp)` | re-opens the Properties view of that component |
| `(VIEW_LINKS, comp)` | re-opens the Link View of that component |
So opening a panel is a move like opening a sheet: **Back** from a Properties view lands
on whatever the pane showed before it rather than skipping past to the sheet before that,
and **Forward** brings the panel back. Following a link out of the Link View is an
ordinary sheet opening, so Back from where it lands returns to the picture the link was
followed from, and a second Back to the sheet that was open before that.
The panel's own **Close** is not recorded. It means "leave this view", and recording it
would put a sheet entry after the panel's -- so Back would re-open the panel that had
just been closed. Leaving the position where it is instead means Back still steps to what
came before the panel, and Forward re-opens it, which is what the two arrows are for.
Entries hold elements rather than tree item ids, because rebuilding the tree hands out
fresh ids while the elements themselves survive. Opening a different file retires the
history. A delete or an undo drops the entries that can no longer be shown -- a sheet
with no node left, a component out of the document -- keeping the position on screen, and
collapses any pair that pruning has left naming the same view, since a Back that visibly
does nothing is worse than a shorter trail. Restoring an entry is suppressed from
recording, so a walk cannot rewrite the trail it is following, and both arrows go through
`close_editor_panel` first -- so unsaved Properties edits are still asked about, and a
refusal leaves both the view and the position where they were.
### The component popup
@@ -161,6 +183,9 @@ than leaving the selection looking like it did nothing. So does deleting the com
is showing, from anywhere -- every delete in the UI goes through `delete_component`,
because `sax_file` does its own view refresh rather than going through `refresh_all_views`.
All three are recorded in one history, so **Back** and **Forward** walk them together --
see **The View menu** above.
### The Properties view
**Properties**, from either component popup, is the one place a slot's value is meant to
@@ -477,8 +502,9 @@ was wiped by the repaint that followed it. The link is therefore left in
`_pending_link_selection` for `on_tree_select` to honour once it has painted, and that
handler reads and clears the request first thing -- so a selection that turns out not to
paint a sheet drops it rather than leaving it to be applied to some later one. The link is
then scrolled to the middle of the view. Arriving is an ordinary sheet opening, so **Back**
returns to the sheet the link was followed from.
then scrolled to the middle of the view. Arriving is an ordinary sheet opening, so
**Back** returns to whatever the pane held before it -- the sheet the wire was
right-clicked on, or the Link View the link was clicked in.
### Testing without a window