Module: Tuile::Component::Overlay::Placement
- Included in:
- ListDropdown::Anchored, At, Centered, TopRight
- Defined in:
- lib/tuile/component/overlay.rb,
sig/tuile.rbs
Overview
Where an overlay wants to be. Include it to be a placement — the pane asks for a rect on every layout pass, and an app supplies its own by answering #rect_for:
Bottom = Data.define do
include Overlay::Placement
def rect_for(, screen_size, _anchor_rect)
size = .declared_size_in(screen_size)
Rect.new(0, screen_size.height - size.height, size.width, size.height)
end
end
.open(Bottom[])
A placement is a rule, not a rect: it is re-read on every resize and every settle, so re-running it moves nothing that stood still. Built in are At, Centered, TopRight and ListDropdown::Anchored.
Anchors
A placement that hangs off something on screen — a field, a menu row — says so by answering #anchor; the pane resolves it and hands the rect to #rect_for:
def anchor = field
Resolving is deliberately the framework's job: a component becomes a screen rect through an ancestor-inclusive visibility walk, an Tuile::Component#attached? test and Tuile::Component#absolute_extent_rect (not Tuile::Component#absolute_rect) — three invariants, one of them the trap Tuile::Component#walk_shown_tree exists to prevent. #anchor therefore answers one of three things:
- a Tuile::Component — resolved while it is reachable, and losable: once detached or hidden there is no rect to compute, so the pane leaves the overlay where it was and warns its owner once rather than placing it against nothing. Closing it is the owner's job.
- a Rect in screen coordinates — always resolves, never lost. Anchors to an absolute position.
nil, the default — not anchored; #rect_for is handednil.
An anchor also earns a second settle pass: the pane lays out before the content its anchor sits in does, so Screen#flush_layout re-reads every #anchor once the queue is empty and runs the pane again if any now resolves elsewhere.
Instance Method Summary collapse
-
#anchor ⇒ Component, ...
What this placement hangs off, re-read on every pass — see the Anchors section above.
-
#rect_for(overlay, screen_size, anchor_rect) ⇒ Rect
The rect this placement wants for
overlay, in screen coordinates.
Instance Method Details
#anchor ⇒ Component, ...
What this placement hangs off, re-read on every pass — see the Anchors section above.
@return — nil, the default, is not anchored.
97 |
# File 'lib/tuile/component/overlay.rb', line 97 def anchor = nil |
#rect_for(overlay, screen_size, anchor_rect) ⇒ Rect
The rect this placement wants for overlay, in screen coordinates.
The pane assigns it as-is — clamping it on screen is the placement's
own job.
@param overlay — the overlay being placed.
@param screen_size — the whole terminal.
@param anchor_rect — #anchor resolved to screen coordinates; nil only for an unanchored placement, since a lost anchor is not placed at all.
109 110 111 |
# File 'lib/tuile/component/overlay.rb', line 109 def rect_for(, screen_size, anchor_rect) raise(NotImplementedError, "#{self.class}#rect_for") end |