Class: Charming::Presentation::Layout::ScreenLayout

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/presentation/layout/screen_layout.rb

Overview

ScreenLayout is the root of a layout tree. It owns a single child (typically a Split or Pane) rendered into the full terminal screen, and an ordered list of Overlays composited on top of the rendered body.

Instance Method Summary collapse

Constructor Details

#initialize(screen:, background: nil) ⇒ ScreenLayout

screen is the Charming::Screen whose dimensions define the layout area. background (optional) is a UI::Style applied to the empty canvas behind the body.



12
13
14
15
16
17
# File 'lib/charming/presentation/layout/screen_layout.rb', line 12

def initialize(screen:, background: nil)
  @screen = screen
  @background = background
  @child = nil
  @overlays = []
end

Instance Method Details

#add_child(node) ⇒ Object

Sets the single root child. Raises ArgumentError when a child is already present.

Raises:

  • (ArgumentError)


20
21
22
23
24
# File 'lib/charming/presentation/layout/screen_layout.rb', line 20

def add_child(node)
  raise ArgumentError, "screen_layout accepts one root layout node" if child

  @child = node
end

#add_overlay(node) ⇒ Object

Appends an overlay to be composited on top of the body, in registration order.



27
28
29
# File 'lib/charming/presentation/layout/screen_layout.rb', line 27

def add_overlay(node)
  overlays << node
end

#focusable_namesObject

Returns the focusable names from the child, or [] when no child has been added.



32
33
34
# File 'lib/charming/presentation/layout/screen_layout.rb', line 32

def focusable_names
  child ? child.focusable_names : []
end

#renderObject

Renders the child into the full-screen rect, then overlays each registered overlay on top in order.



38
39
40
41
42
43
44
# File 'lib/charming/presentation/layout/screen_layout.rb', line 38

def render
  body = UI.place(render_child, width: screen.width, height: screen.height, background: background)

  overlays.reduce(body) do |current, overlay|
    UI.overlay(current, overlay.render, top: overlay.top, left: overlay.left)
  end
end