Class: Tuile::Component::Layout

Inherits:
Tuile::Component show all
Defined in:
lib/tuile/component/layout.rb

Overview

A layout doesn’t paint anything by itself: its job is to position child components.

All children must completely cover the contents of a layout: that way, the layout itself doesn’t have to draw and no clipping algorithm is necessary.

Direct Known Subclasses

Absolute

Defined Under Namespace

Classes: Absolute

Instance Attribute Summary

Attributes inherited from Tuile::Component

#key_shortcut, #parent, #rect

Instance Method Summary collapse

Methods inherited from Tuile::Component

#active=, #active?, #attached?, #cursor_position, #depth, #find_shortcut_component, #focus, #focusable?, #keyboard_hint, #on_child_removed, #on_tree, #root, #screen

Constructor Details

#initializeLayout

Returns a new instance of Layout.



12
13
14
15
# File 'lib/tuile/component/layout.rb', line 12

def initialize
  super
  @children = []
end

Instance Method Details

#add(child) ⇒ void

This method returns an undefined value.

Adds a child component to this layout.

Parameters:



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/tuile/component/layout.rb', line 23

def add(child)
  if child.is_a? Enumerable
    child.each { add(it) }
  else
    raise TypeError, "expected Component, got #{child.inspect}" unless child.is_a? Component
    raise ArgumentError, "#{child} already has a parent #{child.parent}" unless child.parent.nil?

    @children << child
    child.parent = self
  end
end

#childrenArray<Component>

Returns:



18
# File 'lib/tuile/component/layout.rb', line 18

def children = @children.to_a

#content_sizeSize

Returns:



48
49
50
51
52
53
54
# File 'lib/tuile/component/layout.rb', line 48

def content_size
  return Size::ZERO if @children.empty?

  right  = @children.map { |c| c.rect.left + c.rect.width  }.max
  bottom = @children.map { |c| c.rect.top  + c.rect.height }.max
  Size.new(right - rect.left, bottom - rect.top)
end

#handle_key(key) ⇒ Boolean

Called when a character is pressed on the keyboard.

Parameters:

  • key (String)

    a key.

Returns:

  • (Boolean)

    true if the key was handled, false if not.



74
75
76
77
78
79
80
81
# File 'lib/tuile/component/layout.rb', line 74

def handle_key(key)
  return true if super

  sc = @children.find(&:active?)
  return false if sc.nil?

  sc.handle_key(key)
end

#handle_mouse(event) ⇒ void

This method returns an undefined value.

Dispatches the event to the child under the mouse cursor.

Parameters:



64
65
66
67
68
69
# File 'lib/tuile/component/layout.rb', line 64

def handle_mouse(event)
  super
  @children.each do |child|
    child.handle_mouse(event) if child.rect.contains?(event.point)
  end
end

#on_focusvoid

This method returns an undefined value.



84
85
86
87
88
89
90
# File 'lib/tuile/component/layout.rb', line 84

def on_focus
  super
  # Let the content component receive focus, so that it can immediately
  # start responding to key presses.
  first_focusable = @children.find(&:focusable?)
  screen.focused = first_focusable unless first_focusable.nil?
end

#remove(child) ⇒ void

This method returns an undefined value.

Parameters:

Raises:

  • (TypeError)


37
38
39
40
41
42
43
44
45
# File 'lib/tuile/component/layout.rb', line 37

def remove(child)
  raise TypeError, "expected Component, got #{child.inspect}" unless child.is_a? Component
  raise ArgumentError, "#{child}'s parent is #{child.parent}, not this layout #{self}" if child.parent != self

  child.parent = nil
  @children.delete(child)
  invalidate if @children.empty?
  on_child_removed(child)
end

#repaintvoid

This method returns an undefined value.



57
58
59
# File 'lib/tuile/component/layout.rb', line 57

def repaint
  clear_background if @children.empty?
end