Class: Tuile::Component::Popup

Inherits:
Tuile::Component show all
Includes:
HasContent
Defined in:
lib/tuile/component/popup.rb

Overview

A modal overlay that wraps any Tuile::Component as its content. Popup itself paints nothing — it’s a transparent host that handles modality (#open / #close / #open?, ESC/q to close), centers itself on the screen, and auto-sizes to the wrapped content.

The wrapped content fills the popup’s full #rect; if you want a frame and caption, wrap a Window (or any subclass — including LogWindow) and let it draw its own border:

window = Component::Window.new("Help")
window.content = Component::List.new.tap { _1.lines = lines }
Component::Popup.new(content: window).open

Bare content also works (a Label, a List…), in which case the popup is borderless.

‘q` and ESC close the popup. Any nested TextField that owns the hardware cursor swallows printable keys first via the standard cursor-owner suppression in #handle_key, so typing `q` into a text field doesn’t dismiss the popup.

Instance Attribute Summary

Attributes included from HasContent

#content

Attributes inherited from Tuile::Component

#key_shortcut, #parent, #rect

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasContent

#children, #handle_mouse, #on_focus, #rect=

Methods inherited from Tuile::Component

#active=, #active?, #attached?, #children, #content_size, #cursor_position, #depth, #find_shortcut_component, #focus, #handle_mouse, #on_child_removed, #on_focus, #on_tree, #repaint, #root, #screen

Constructor Details

#initialize(content: nil) ⇒ Popup

Returns a new instance of Popup.

Parameters:

  • content (Component, nil) (defaults to: nil)

    initial content; can be set later via #content=. When provided here, the popup auto-sizes to fit.



30
31
32
33
34
35
36
37
# File 'lib/tuile/component/popup.rb', line 30

def initialize(content: nil)
  super()
  @content = nil
  # Off-screen sentinel until the content sets a real size and the popup
  # is centered on open.
  @rect = Rect.new(-1, -1, 0, 0)
  self.content = content unless content.nil?
end

Class Method Details

.open(content: nil) ⇒ Popup

Constructs and opens a popup in one call.

Parameters:

  • content (Component, nil) (defaults to: nil)

Returns:

  • (Popup)

    the opened popup.



50
51
52
# File 'lib/tuile/component/popup.rb', line 50

def self.open(content: nil)
  Popup.new(content: content).tap(&:open)
end

Instance Method Details

#centervoid

This method returns an undefined value.

Recenters the popup on the screen, preserving its current width/height. Called automatically by the screen’s layout pass and by #content= when the popup is open.



69
70
71
# File 'lib/tuile/component/popup.rb', line 69

def center
  self.rect = rect.centered(screen.size)
end

#closevoid

This method returns an undefined value.

Removes this popup from the Screen. No-op if not currently open.



56
57
58
# File 'lib/tuile/component/popup.rb', line 56

def close
  screen.remove_popup(self)
end

#content=(new_content) ⇒ Object

Sets the popup’s content and auto-sizes the popup to fit.

Parameters:



79
80
81
82
# File 'lib/tuile/component/popup.rb', line 79

def content=(new_content)
  super
  update_rect unless new_content.nil?
end

#focusable?Boolean

Returns:

  • (Boolean)


39
# File 'lib/tuile/component/popup.rb', line 39

def focusable? = true

#handle_key(key) ⇒ Boolean

Returns true if the key was handled.

Parameters:

  • key (String)

Returns:

  • (Boolean)

    true if the key was handled.



94
95
96
97
98
99
100
101
102
103
# File 'lib/tuile/component/popup.rb', line 94

def handle_key(key)
  return true if super

  if [Keys::ESC, "q"].include?(key)
    close
    true
  else
    false
  end
end

#keyboard_hintString

Hint for the status bar: own “q Close” plus the wrapped content’s hint.

Returns:

  • (String)


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

def keyboard_hint
  prefix = "q #{Rainbow("Close").cadetblue}"
  child_hint = @content&.keyboard_hint.to_s
  child_hint.empty? ? prefix : "#{prefix}  #{child_hint}"
end

#max_heightInteger

Returns max height the popup will grow to fit its content, defaults to 12. Override in a subclass to allow taller popups.

Returns:

  • (Integer)

    max height the popup will grow to fit its content, defaults to 12. Override in a subclass to allow taller popups.



75
# File 'lib/tuile/component/popup.rb', line 75

def max_height = 12

#openvoid

This method returns an undefined value.

Mounts this popup on the Screen.



43
44
45
# File 'lib/tuile/component/popup.rb', line 43

def open
  screen.add_popup(self)
end

#open?Boolean

Returns true if this popup is currently mounted on the screen.

Returns:

  • (Boolean)

    true if this popup is currently mounted on the screen.



61
62
63
# File 'lib/tuile/component/popup.rb', line 61

def open?
  screen.has_popup?(self)
end