Class: Potty::Widgets::List

Inherits:
Base
  • Object
show all
Defined in:
lib/potty/widgets/list.rb

Overview

Scrollable list widget with heterogeneous items. Emits :select(item) on cursor move and :activate(item) on Enter.

Instance Attribute Summary collapse

Attributes inherited from Base

#app, #focused, #parent, #rect

Instance Method Summary collapse

Methods inherited from Base

#activate, #blur, #deactivate, #focus, #handle_escape, #hide, #layout, #on_blur, #on_focus, #on_layout, #show, #theme, #tick, #visible=, #visible?

Methods included from Events

#emit, #listeners?, #off, #on

Constructor Details

#initialize(app) ⇒ List

Returns a new instance of List.



16
17
18
19
20
21
22
23
# File 'lib/potty/widgets/list.rb', line 16

def initialize(app)
  super
  @items = []
  @selected_index = 0
  @scroll_offset = 0
  @on_select = nil
  @on_activate = nil
end

Instance Attribute Details

#itemsObject

Returns the value of attribute items.



13
14
15
# File 'lib/potty/widgets/list.rb', line 13

def items
  @items
end

#on_activateObject

Returns the value of attribute on_activate.



14
15
16
# File 'lib/potty/widgets/list.rb', line 14

def on_activate
  @on_activate
end

#on_selectObject

Returns the value of attribute on_select.



14
15
16
# File 'lib/potty/widgets/list.rb', line 14

def on_select
  @on_select
end

Instance Method Details

#can_focus?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/potty/widgets/list.rb', line 39

def can_focus?
  true
end

#handle_key(ch) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/potty/widgets/list.rb', line 75

def handle_key(ch)
  return false if @items.empty?

  case ch
  when Keys::UP
    move_selection(-1)
    true
  when Keys::DOWN
    move_selection(1)
    true
  when *Keys::ENTERS
    activate_current
    true
  else
    # Delegate to current item (e.g., InputItem handles typing)
    current_item&.handle_key(ch)
  end
end

#preferred_height(width) ⇒ Object



43
44
45
# File 'lib/potty/widgets/list.rb', line 43

def preferred_height(width)
  [@items.size + 2, 10].max  # Items + borders, minimum 10
end

#render(window) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/potty/widgets/list.rb', line 47

def render(window)
  return unless @rect

  visible_height = @rect.height - 2  # Account for borders

  # Draw border
  draw_border(window)

  # Show empty message if no items
  if @items.empty?
    window.setpos(@rect.y + 1, @rect.x + 2)
    window.attron(theme[:dim]) do
      window.addstr("No items")
    end
    return
  end

  # Draw visible items
  visible_items = @items[@scroll_offset, visible_height] || []
  visible_items.each_with_index do |item, display_idx|
    real_idx = @scroll_offset + display_idx
    y = @rect.y + 1 + display_idx
    x = @rect.x + 1

    render_item(window, item, real_idx, y, x)
  end
end

#selected_itemObject

The currently highlighted item (nil if the list is empty).



35
36
37
# File 'lib/potty/widgets/list.rb', line 35

def selected_item
  @items[@selected_index]
end