Class: RubyTUI::Widgets::Popup

Inherits:
Object
  • Object
show all
Includes:
RubyTUI::Widget
Defined in:
lib/rubytui/widgets/popup.rb

Overview

Popup renders an overlay on top of existing content. It clears its area, optionally draws a drop shadow, and draws its block; popup content is rendered separately into #inner.

Examples:

popup = RubyTUI::Widgets::Popup.new(width: 40, height: 7, shadow: true)
popup.render(frame.area, frame.buffer)
inner = popup.inner(frame.area)  # draw popup content here

Instance Method Summary collapse

Constructor Details

#initialize(width: nil, height: nil, width_percent: 60, height_percent: 60, x: nil, y: nil, block: nil, style: Style::DEFAULT, shadow: false, shadow_style: nil) ⇒ Popup

Returns a new instance of Popup.

Parameters:

  • width (Integer, nil) (defaults to: nil) —

    fixed width, clamped to the parent width (default: nil, uses width_percent)

  • height (Integer, nil) (defaults to: nil) —

    fixed height, clamped to the parent height (default: nil, uses height_percent)

  • width_percent (Integer) (defaults to: 60) —

    width as a percentage of the parent width when width is nil (default: 60)

  • height_percent (Integer) (defaults to: 60) —

    height as a percentage of the parent height when height is nil (default: 60)

  • x (Integer, nil) (defaults to: nil) —

    absolute column of the left edge (default: nil, centered horizontally in the parent area)

  • y (Integer, nil) (defaults to: nil) —

    absolute row of the top edge (default: nil, centered vertically in the parent area)

  • block (Widgets::Block, nil) (defaults to: nil) —

    border/title block (default: nil, a block with all borders and Symbols::ROUNDED border characters)

  • style (Style) (defaults to: Style::DEFAULT) —

    style used to clear the popup area (default: Style::DEFAULT)

  • shadow (Boolean) (defaults to: false) —

    draw a one-cell shadow to the right of and below the popup (default: false)

  • shadow_style (Style, nil) (defaults to: nil) —

    shadow style (default: bright black foreground on a black background)



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubytui/widgets/popup.rb', line 35

def initialize(
  width: nil,          # fixed width or nil for percentage
  height: nil,         # fixed height or nil for percentage
  width_percent: 60,   # percentage of parent width
  height_percent: 60,  # percentage of parent height
  x: nil,              # fixed x position or nil for centered
  y: nil,              # fixed y position or nil for centered
  block: nil,          # Block widget for border/title
  style: Style::DEFAULT,
  shadow: false,
  shadow_style: nil
)
  @fixed_width = width
  @fixed_height = height
  @width_percent = width_percent
  @height_percent = height_percent
  @fixed_x = x
  @fixed_y = y
  @block = block || Widgets::Block.new(borders: :all, border_set: Symbols::ROUNDED)
  @style = style
  @shadow = shadow
  @shadow_style = shadow_style || Style.new.fg(Color::BRIGHT_BLACK).bg(Color::BLACK)
end

Instance Method Details

#inner(parent_area) ⇒ Rect

Get the inner area (inside the popup's block)

Parameters:

  • parent_area (Rect) —

    area the popup is sized and centered against

Returns:

  • (Rect) —

    the area inside the block's borders and padding, for popup content



82
83
84
# File 'lib/rubytui/widgets/popup.rb', line 82

def inner(parent_area)
  @block.inner(popup_area(parent_area))
end

Calculate the popup area within the given parent area

The size is clamped to the parent size. A fixed x or y is used as is and is not clamped to the parent area.

Parameters:

  • parent_area (Rect) —

    area the popup is sized and centered against

Returns:

  • (Rect) —

    the popup's outer area, including the block's borders



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rubytui/widgets/popup.rb', line 66

def popup_area(parent_area)
  w = @fixed_width || (parent_area.width * @width_percent / 100)
  h = @fixed_height || (parent_area.height * @height_percent / 100)
  w = [w, parent_area.width].min
  h = [h, parent_area.height].min

  px = @fixed_x || (parent_area.x + (parent_area.width - w) / 2)
  py = @fixed_y || (parent_area.y + (parent_area.height - h) / 2)

  Rect.new(x: px, y: py, width: w, height: h)
end

#render(area, buf) ⇒ void

This method returns an undefined value.

Draw the shadow (if enabled), clear the popup area with style, then draw the block.

area is the parent area; the popup is placed within it by #popup_area.

Parameters:

  • area (Rect) —

    the parent area to place the popup in

  • buf (Buffer) —

    the buffer to write cells into



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rubytui/widgets/popup.rb', line 94

def render(area, buf)
  return if area.empty?

  pa = popup_area(area)
  return if pa.empty?

  # Draw shadow first (offset by 1,1)
  if @shadow
    render_shadow(pa, buf)
  end

  # Clear the popup area with background style
  clear_area(pa, buf)

  # Draw the block (border + title)
  @block.render(pa, buf)
end