Class: Chamomile::Frame

Inherits:
Object
  • Object
show all
Defined in:
lib/chamomile/frame.rb

Overview

Declarative view DSL. Build a widget tree from view, the renderer calls frame.render(width:, height:) to produce the final string.

def view
Chamomile::Frame.build do |f|
  f.horizontal do |left, right|
    left.panel("Routes") { left.text @routes }
    right.panel("Detail") { right.text @detail }
  end
  f.status_bar @status
end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFrame

Returns a new instance of Frame.



25
26
27
# File 'lib/chamomile/frame.rb', line 25

def initialize
  @children = []
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



17
18
19
# File 'lib/chamomile/frame.rb', line 17

def children
  @children
end

Class Method Details

.build(&block) ⇒ Object



19
20
21
22
23
# File 'lib/chamomile/frame.rb', line 19

def self.build(&block)
  frame = new
  block.call(frame) if block
  frame
end

Instance Method Details

#horizontal(&block) ⇒ Object

Add a horizontal layout container.



38
39
40
41
42
43
# File 'lib/chamomile/frame.rb', line 38

def horizontal(&block)
  layout = Widgets::HorizontalLayout.new
  block.call(layout) if block
  @children << layout
  layout
end

#panel(title = nil, border: :rounded, width: nil, &block) ⇒ Object

Add a bordered panel with a title.



46
47
48
49
50
51
# File 'lib/chamomile/frame.rb', line 46

def panel(title = nil, border: :rounded, width: nil, &block)
  p = Widgets::Panel.new(title: title, border: border, width: width)
  block.call(p) if block
  @children << p
  p
end

#render(width:, height:) ⇒ Object

Render the frame to a string.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/chamomile/frame.rb', line 68

def render(width:, height:)
  return "" if @children.empty?

  if @children.length == 1
    @children[0].render(width: width, height: height)
  else
    # Default: stack children vertically
    lines = []
    remaining_height = height
    @children.each_with_index do |child, i|
      child_height = if i == @children.length - 1
                       remaining_height
                     else
                       [remaining_height / (@children.length - i), 1].max
                     end
      lines << child.render(width: width, height: child_height)
      remaining_height -= child_height
    end
    lines.join("\n")
  end
end

#status_bar(content) ⇒ Object

Add a status bar (fixed bottom line).



61
62
63
64
65
# File 'lib/chamomile/frame.rb', line 61

def status_bar(content)
  sb = Widgets::StatusBar.new(content: content.to_s)
  @children << sb
  sb
end

#text(content) ⇒ Object

Add a plain text block.



54
55
56
57
58
# File 'lib/chamomile/frame.rb', line 54

def text(content)
  t = Widgets::Text.new(content: content.to_s)
  @children << t
  t
end

#to_sObject



90
91
92
# File 'lib/chamomile/frame.rb', line 90

def to_s
  render(width: 80, height: 24)
end

#vertical(&block) ⇒ Object

Add a vertical layout container.



30
31
32
33
34
35
# File 'lib/chamomile/frame.rb', line 30

def vertical(&block)
  layout = Widgets::VerticalLayout.new
  block.call(layout) if block
  @children << layout
  layout
end