F-key lane: a directional pair rises toward its outer key
F4/F5 keeps up on the right; an F1/F2 pair puts up on F1, so a select list reads Sect ↑ then Sect ↓ — the hand anchors on the lane's edge and rocks inward, whichever side the pair lives on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cbdabef174
commit
6787aace3c
4 files changed
+23
-20
No files matched your search
@@ -203,11 +203,12 @@ branch on the platform per frame, and never `from meshterm.platforms import PLAT
|
||||
wanted a chip for consistency. That leaves **F1–F3 free on every screen** for its own
|
||||
verbs, and `EMPTY_LANE` for a screen with none at all (every dialog). **A chip names an
|
||||
action, never a key** — `Page ↑`, not `PgUp`; `Latest` on a transcript; `Region` on the
|
||||
map, whose Home reframes and whose paging zooms. **A directional pair rises to the
|
||||
right**: where two adjacent chips are opposite ends of one axis (F4/F5's paging, the
|
||||
map's zoom, a select list's section jumps), the *up · in · more* end takes the right
|
||||
slot — `Zoom -` then `Zoom +`, a rocker — and a slot's Shift companion follows the same
|
||||
rule along its own slot. The lane *is* the footer here, so it obeys the hint line's rule
|
||||
map, whose Home reframes and whose paging zooms. **A directional pair rises toward its
|
||||
outer key**: where two adjacent chips are opposite ends of one axis, the *up · in ·
|
||||
more* end takes the slot nearer the lane's edge — F5 on the right-hand pair (F4/F5's
|
||||
paging, the map's zoom: `Zoom -` then `Zoom +`, a rocker), F1 on a left-hand pair (a
|
||||
select list's `Sect ↑` then `Sect ↓`) — and a slot's Shift companion follows its own
|
||||
slot's direction. The lane *is* the footer here, so it obeys the hint line's rule
|
||||
— never advertise a key that would do nothing. Empty and dim are different claims: leave
|
||||
the slot **empty** when the action isn't a thing on this screen (Retry in a channel), and
|
||||
clear `enabled`/`opp_enabled` to draw it **dim** (label kept, fill dropped) when it's a
|
||||
|
||||
@@ -104,13 +104,15 @@ Lane = Sequence[Optional[FPair]]
|
||||
#: none leaves them blank rather than filling the lane out. A screen whose body is not one
|
||||
#: scrolling column says so in its own words (see :class:`ChatScreen`, ``MapScreen``).
|
||||
#:
|
||||
#: **A directional pair rises to the right** (JP, 2026-08-08): wherever two adjacent chips
|
||||
#: are opposite ends of one axis — the F4/F5 pager here, the map's zoom, a select list's
|
||||
#: section jumps — the *up · in · more* end takes the right slot and its opposite the left,
|
||||
#: so every such pair reads like a rocker (``−`` then ``+``) and one handedness carries
|
||||
#: across screens. A slot's own Shift companion follows the same rule *along its slot*: the
|
||||
#: jump behind ``Page ↑`` is the one Page ↑ is heading for, so F10 is Top and F9 Bottom. A
|
||||
#: screen relabelling a pair keeps that order (a chat's ``Latest``/``Oldest``).
|
||||
#: **A directional pair rises toward its outer key** (JP, 2026-08-08): wherever two
|
||||
#: adjacent chips are opposite ends of one axis, the *up · in · more* end takes the slot
|
||||
#: nearer the lane's own edge. On the right-hand F4/F5 pair that is F5 — the pager here,
|
||||
#: the map's zoom, ``Zoom -`` then ``Zoom +``, a rocker — and on a left-hand F1/F2 pair it
|
||||
#: is F1, so a select list reads ``Sect ↑`` then ``Sect ↓``: ergonomically the hand
|
||||
#: anchors on the lane's edge and rocks inward, whichever side the pair lives on. A slot's
|
||||
#: own Shift companion follows the same rule *along its slot*: the jump behind ``Page ↑``
|
||||
#: is the one Page ↑ is heading for, so F10 is Top and F9 Bottom. A screen relabelling a
|
||||
#: pair keeps its order (a chat's ``Latest``/``Oldest``).
|
||||
DEFAULT_LANE: tuple[Optional[FPair], ...] = (
|
||||
None,
|
||||
None,
|
||||
|
||||
@@ -213,8 +213,8 @@ class SelectScreen(Screen):
|
||||
Ctrl+PageUp/PageDown step the highlight heading by heading — and on the PicoCalc
|
||||
they are the one binding in the app that is *physically unreachable*: paging has
|
||||
no key there to hold Ctrl over. So a grouped list promotes them onto the lane,
|
||||
keeping the shared handedness (down left, up right — see
|
||||
:data:`~meshterm.ui.tui.fkeys.DEFAULT_LANE`).
|
||||
keeping the shared handedness — a pair rises toward its outer key, so on this
|
||||
left-edge pair *up* takes F1 (see :data:`~meshterm.ui.tui.fkeys.DEFAULT_LANE`).
|
||||
|
||||
Their two gates say different things, per the lane's empty-versus-dim rule. A list
|
||||
that has no headings *at all* leaves both slots blank: sections aren't a thing
|
||||
@@ -237,8 +237,8 @@ class SelectScreen(Screen):
|
||||
lane = list(default_lane(nav=len(self._choices(rows)) > 1))
|
||||
if len(self._all_section_starts()) >= 2:
|
||||
live = len(self._section_starts(rows)) > 1
|
||||
lane[0] = FPair("Sect ↓", "ctrl_pagedown", enabled=live)
|
||||
lane[1] = FPair("Sect ↑", "ctrl_pageup", enabled=live)
|
||||
lane[0] = FPair("Sect ↑", "ctrl_pageup", enabled=live)
|
||||
lane[1] = FPair("Sect ↓", "ctrl_pagedown", enabled=live)
|
||||
if self._delete_hint:
|
||||
choices = self._choices(rows)
|
||||
current = choices[max(0, min(self._index, len(choices) - 1))] if choices else None
|
||||
|
||||
@@ -181,9 +181,9 @@ def test_select_lane_promotes_the_section_jumps_only_where_there_are_sections()
|
||||
Separator("── Far ──"), Choice("gamma", 3),
|
||||
])
|
||||
lane = grouped.fkey_lane
|
||||
assert [pair.label for pair in lane[:2]] == ["Sect ↓", "Sect ↑"]
|
||||
# Down left, up right — the same handedness the pager below them reads with.
|
||||
assert action_for(lane, 1) == "ctrl_pagedown" and action_for(lane, 2) == "ctrl_pageup"
|
||||
assert [pair.label for pair in lane[:2]] == ["Sect ↑", "Sect ↓"]
|
||||
# A pair rises toward its outer key: on this left-edge pair, up takes F1.
|
||||
assert action_for(lane, 1) == "ctrl_pageup" and action_for(lane, 2) == "ctrl_pagedown"
|
||||
assert all(pair.enabled for pair in lane[:2])
|
||||
|
||||
# A filter that collapses the list onto one section keeps the labels and dims them:
|
||||
@@ -191,7 +191,7 @@ def test_select_lane_promotes_the_section_jumps_only_where_there_are_sections()
|
||||
for ch in "gam":
|
||||
grouped.handle("text", ch)
|
||||
dim = grouped.fkey_lane
|
||||
assert [pair.label for pair in dim[:2]] == ["Sect ↓", "Sect ↑"]
|
||||
assert [pair.label for pair in dim[:2]] == ["Sect ↑", "Sect ↓"]
|
||||
assert not any(pair.enabled for pair in dim[:2])
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user