Documentation
¶
Overview ¶
Package pointer maps rendered terminal cells to pointer interactions.
Index ¶
- func Cancel() tea.Cmd
- func CancelWith(followup tea.Cmd) tea.Cmd
- func IsMessage(message tea.Msg) bool
- func ReplaceActivation(message tea.Msg, action Action) tea.Msg
- func ReplaceFollowup(message tea.Msg, followup tea.Msg) tea.Msg
- func ResetHover() tea.Cmd
- type Action
- type Choice
- type Clicks
- type ControlID
- type Interaction
- type InteractionKind
- type Map
- func (m *Map) Add(rect Rect, action Action)
- func (m *Map) AddBackdrop(bounds, pane Rect, action Action)
- func (m *Map) AddBackdropControl(id ControlID, bounds, pane Rect, action Action)
- func (m *Map) AddControl(id ControlID, rect Rect, action Action)
- func (m *Map) AddWheel(rect Rect, action func(delta int) tea.Msg)
- func (m Map) Handler() func(tea.MouseMsg) tea.Cmd
- func (m Map) Resolve(point Point) (ControlID, bool)
- func (m Map) Snapshot() Snapshot
- func (m Map) Topology() Topology
- type Point
- type Rect
- type Rows
- type Snapshot
- type State
- func (s State) Active() bool
- func (s State) ClearCapture() State
- func (s State) ClearHover() State
- func (s State) ClearHoverObservation() State
- func (s State) Hover(id ControlID, at Point) State
- func (s State) HoverPoint() (Point, bool)
- func (s State) Hovered() ControlID
- func (s State) IsHovered(id ControlID) bool
- func (s State) IsPressed(id ControlID) bool
- func (s State) Pressed() ControlID
- func (s State) Render(styles *theme.Styles, id ControlID, content string) string
- func (s State) Reresolve(m Map) State
- func (s State) Update(message tea.Msg) (State, tea.Cmd, bool)
- type Surface
- type Topology
- func (t Topology) HasControl(id ControlID) bool
- func (t Topology) Merge(other Topology) Topology
- func (t Topology) RebindExact(message tea.Msg) (tea.Msg, bool)
- func (t Topology) RebindWheel(key string, target int) (tea.Msg, WheelIntent, bool)
- func (t Topology) SameControls(other Topology) bool
- func (t Topology) WithWheel(intent WheelIntent, rebuild func(int) tea.Msg) Topology
- type Viewport
- type WheelIntent
- type WheelMessage
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Cancel ¶
Cancel clears any active press when the original control disappeared between render passes, for example after a resize or asynchronous refresh.
func CancelWith ¶
CancelWith clears capture before forwarding a resolved domain command. The command is executed only when the mailbox drains it inside ordered Update.
func IsMessage ¶
IsMessage reports whether message carries pointer feedback that State.Update must consume before an active overlay routes domain messages.
func ReplaceActivation ¶
ReplaceActivation binds a resolved release to the current stable action for the same control identity. It does not perform a coordinate lookup.
func ResetHover ¶
ResetHover clears both the active owner's hover feedback and its retained observation. Capture is deliberately left to Cancel.
Types ¶
type Choice ¶
type Choice struct {
Cursor int // the keyboard cursor
Rows Rows // this surface's own id-to-row resolver
}
Choice is the mouse-mode machine of spec section 10.5.2, for one overlay choice surface. Ratified call 9: the machine runs on the checklist, the drift list, the ADR-split stories, the issue-import list, the pickers and the settings rows, and on nothing else. The board cursor never follows the pointer, because it is the drag source, the anchor every board keybinding resolves against and the card the detail overlay opens.
The machine is pure. It holds no clock, no flag and no copy of hover: mouse mode is on exactly when the caller's State has a hovered id that Rows resolves, so there is one bit of state and it lives in State.
func (Choice) Acting ¶
Acting returns the row that renders this surface's cursor cue: the hovered row while mouse mode is on, the keyboard cursor otherwise. Exactly one cursor is visible at any moment, which is the failure the machine exists to prevent.
func (Choice) Adopt ¶
Adopt applies rows 7 and 8 to one key press and returns the anchor the key's own motion runs from, plus the state with mouse mode turned off.
The ordering of row 7 is normative and is the row most easily got wrong: adopt, then move. A down arrow while row 7 is hovered lands on row 8, not on cursor+1, so the caller applies its own motion to the returned anchor. Row 8 is the opposite and equally deliberate: a hotkey, Enter or Esc acts on the keyboard cursor, never on whatever the pointer happens to be resting over, because a key typed without looking at the mouse must not be redirected by it.
A press while mouse mode is off for this surface leaves both results alone.
type Clicks ¶
type Clicks struct {
// contains filtered or unexported fields
}
Clicks is the double-click classifier of spec section 10.3.5. It lives here rather than in a view because classification is a pointer concern: a view that had to remember the previous click would grow a second, parallel gesture machine beside this one.
A click is a double-click when it lands within Timing.DoubleClickWindow of the previous click, on the same region id, and the previous click's gesture ended with dragged == false. A click on a different id resets the window; so does any drag. The drag exclusion is not optional - kb's board is a drag-and-drop miller board and a lift that ends on its origin must never register as a double-click.
The window closes because a message arrived, not because a render compared time.Since to a token: Click hands back the command that arms it, and Expire consumes it. Under collapsed timing the arming command dispatches immediately, so a collapsed program classifies every click as a single - which is the deterministic reading a golden needs.
func (Clicks) Click ¶
Click records a completed click on id and reports whether it closes a double-click. dragged excludes a lift that ended on its origin.
The returned command arms the window for the next click. It is nil when this click was itself the second half of a double-click, and when the gesture dragged: neither leaves a window open.
type Interaction ¶
type Interaction struct {
Kind InteractionKind
ID ControlID
Point Point
Followup tea.Msg
}
Interaction is the immutable semantic identity resolved by a rendered map. Activation remains private to State.Update.
func ObserveInteraction ¶
func ObserveInteraction(message tea.Msg) (Interaction, bool)
type InteractionKind ¶
type InteractionKind uint8
const ( InteractionPress InteractionKind = iota + 1 InteractionRelease InteractionCancel InteractionHover InteractionResetHover )
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
Map resolves rendered terminal regions to model messages.
func (*Map) AddBackdrop ¶
AddBackdrop registers the portion of bounds outside pane as one action.
func (*Map) AddBackdropControl ¶
AddBackdropControl registers a stable tracked dismissal region outside pane. One identity spans the four non-overlapping strips, so capture survives a handler replacement between press and release.
func (*Map) AddControl ¶
AddControl registers an action region with opt-in pressed feedback. IDs must remain stable across render passes. An empty ID retains Add's legacy behavior.
func (*Map) AddWheel ¶
AddWheel registers a wheel zone. The action receives -1 for up and +1 for down.
type Rows ¶
Rows maps a hovered control id onto a row index of one surface. A control that belongs to a different surface, or to no row at all, reports false: that is how a surface decides whether mouse mode is on for it rather than for the panel next door.
func RowsWithPrefix ¶
RowsWithPrefix is the resolver for the surfaces that key a row's control id as a fixed prefix plus the row index, which is every choice surface in the TUI. An id that does not carry the prefix, or whose tail is not a non-negative decimal, belongs to another surface.
type Snapshot ¶
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot is an immutable copy of one rendered pointer map.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State tracks transient pointer feedback independently from domain state.
Hover mirrors press: one control id and the cell it resolved from. Spec section 10.5.2: mouse mode is not a stored flag, it is the hovered id being set and resolving to one of a surface's own regions, so there is exactly one bit of state to clear and no second copy of the same fact to disagree with.
func (State) ClearCapture ¶
ClearCapture cancels pressed feedback without changing the last hover observation. Root pointer admission uses it when raw correlation fails.
func (State) ClearHover ¶
ClearHover turns mouse mode off for every surface. Spec section 10.5.2: turning mouse mode off is clearing hover, and that is the whole of it.
func (State) ClearHoverObservation ¶
ClearHoverObservation removes both hover feedback and the retained terminal cell. Admission uses it when raw input cannot be correlated with the frame that resolved it; keeping that cell would let a later render resurrect a hover the user never actually delivered.
func (State) Hover ¶
Hover sets the hovered control and the cell it resolved from. An empty id clears hover while retaining the point, which is what a motion onto an overlay's own backdrop reports.
func (State) HoverPoint ¶
HoverPoint returns the last observed pointer cell. The second result is false only before any hover observation; an observation that resolved to no control still retains its cell so stationary re-resolution can discover moved content.
func (State) IsHovered ¶
IsHovered reports whether the identified control is under the pointer. Callers use this while rendering the control's hovered style.
func (State) IsPressed ¶
IsPressed reports whether the identified control owns the active pointer press. Callers use this while rendering the control's pressed style.
func (State) Render ¶
Render applies same-width pressed feedback to the active control. The caller supplies already-sanitized terminal content.
Spec section 9.1: the feedback is theme.Styles.Pressed, not a raw escape written here. The theme owns the attribute and the re-arming a composed run needs; this package only decides which control wears it.
func (State) Reresolve ¶
Reresolve re-derives hover from the retained point against a freshly built map. Rows 6 and 9 of spec section 10.5.2: the pointer can stand still while the content moves under it, so a scroll, a resize or a changed filter has to re-resolve rather than wait for a motion that never comes. A point that no longer lands on a hoverable region clears hover.
type Topology ¶
type Topology struct {
// contains filtered or unexported fields
}
Topology is the immutable semantic half of one published pointer map. It deliberately carries no rectangles: stale input may rebind a stable control or wheel identity to the current action and bounds, but it may never repeat a coordinate lookup against a frame the terminal did not display.
func (Topology) HasControl ¶
HasControl reports whether the current published owner still exposes id.
func (Topology) Merge ¶
Merge returns an immutable union in which bindings from other take precedence. It is used by composite surfaces such as the board, whose hover and activation maps share one published owner.
func (Topology) RebindExact ¶
RebindExact validates a stale exact interaction by stable ID and, for a release, replaces the old frame's activation closure with the current one. Coordinates are retained only as action arguments; they are never resolved.
func (Topology) RebindWheel ¶
RebindWheel rebuilds target against the current binding for key. The caller owns accumulation; topology owns the current absolute bounds and message.
func (Topology) SameControls ¶
SameControls reports semantic topology parity without comparing closures.
type WheelMessage ¶
type WheelMessage interface {
PointerWheelIntent() WheelIntent
PointerWheelTarget(int) tea.Msg
}