Class: Tuile::Component::Layout::Absolute
- Inherits:
-
Layout
- Object
- Layout
- Tuile::Component::Layout::Absolute
- Defined in:
- lib/tuile/component/layout/absolute.rb,
sig/tuile.rbs
Overview
Places each child at the Rect it was added with, in this layout's own coordinates, and does no arithmetic of its own:
layout = Component::Layout::Absolute.new
layout.add(title, Rect.new(0, 0, 40, 1))
layout.add(body, Rect.new(0, 2, 40, 10))
layout.constrain(body, Rect.new(0, 2, 40, 20)) # moves it on the next settle
The rect is where the child wants to be, and this layout's
Tuile::Component#relayout is what assigns it, so moving a child means
#constraining it rather than writing its rect. A rect that sticks out
of this layout is clipped at paint time, and this layout's own size
doesn't matter: a detached Absolute with no rect still places its
children, which is how a spec measures a tree that has no screen.
When the rects depend on this layout's size, subclass Tuile::Component::Layout and write
the relayout instead.
Instance Method Summary collapse
-
#add(child, rect = nil) ⇒ void
@param
child— one child, or several sharing the rect. -
#constrain(child, rect) ⇒ void
Moves a child already in the layout; it takes the new rect on the next settle.
-
#initialize ⇒ Absolute
constructor
A new instance of Absolute.
- #relayout ⇒ void
-
#remove(child) ⇒ void
@param
child. -
#validate_rect(rect) ⇒ void
@param
rect.
Constructor Details
#initialize ⇒ Absolute
Returns a new instance of Absolute.
24 25 26 27 28 |
# File 'lib/tuile/component/layout/absolute.rb', line 24 def initialize super # Identity-keyed: two == children are still two distinct slots. @rects = {}.compare_by_identity end |
Instance Method Details
#add(child, rect = nil) ⇒ void
This method returns an undefined value.
@param child — one child, or several sharing the rect.
@param rect — where the child sits, in this layout's coordinates; nil keeps the rect the child already has, which for a new component is empty.
37 38 39 40 41 42 43 44 |
# File 'lib/tuile/component/layout/absolute.rb', line 37 def add(child, rect = nil) return child.each { add(_1, rect) } if child.is_a?(Enumerable) rect ||= child.rect if child.is_a?(Component) validate_rect(rect) add_child(child) @rects[child] = rect end |
#constrain(child, rect) ⇒ void
This method returns an undefined value.
Moves a child already in the layout; it takes the new rect on the next settle.
@param child — a child of this layout.
@param rect
53 54 55 56 57 58 59 60 61 |
# File 'lib/tuile/component/layout/absolute.rb', line 53 def constrain(child, rect) raise ArgumentError, "#{child} is not a child of #{self}" unless children.any? { _1.equal?(child) } validate_rect(rect) return if @rects[child] == rect @rects[child] = rect invalidate_layout end |
#relayout ⇒ void
This method returns an undefined value.
73 74 75 |
# File 'lib/tuile/component/layout/absolute.rb', line 73 def relayout children.each { _1.rect = @rects.fetch(_1) } end |
#remove(child) ⇒ void
This method returns an undefined value.
@param child
65 66 67 68 |
# File 'lib/tuile/component/layout/absolute.rb', line 65 def remove(child) super @rects.delete(child) end |
#validate_rect(rect) ⇒ void
This method returns an undefined value.
@param rect
80 81 82 |
# File 'lib/tuile/component/layout/absolute.rb', line 80 def validate_rect(rect) raise TypeError, "expected Rect, got #{rect.inspect}" unless rect.is_a?(Rect) end |