Class: Potty::Widgets::RadioGroup
- Defined in:
- lib/potty/widgets/radio_group.rb
Overview
N mutually exclusive options, one row each. Up/down move the cursor; Space/Enter selects the option under the cursor. Renders “(u25CF) label” for the chosen option and “(u25CB) label” for the rest.
Note the two distinct positions: the cursor (highlight, moved by arrows) and the selection (the committed value). They diverge while the user is navigating and reconverge on select.
Instance Attribute Summary collapse
-
#on_change ⇒ Object
Returns the value of attribute on_change.
Attributes inherited from Base
#app, #focused, #parent, #rect
Instance Method Summary collapse
- #can_focus? ⇒ Boolean
-
#cursor_value ⇒ Object
The value under the cursor (the highlighted row), which may differ from the committed selection while navigating.
- #handle_key(ch) ⇒ Object
-
#initialize(app, options: [], selected: nil, on_change: nil) ⇒ RadioGroup
constructor
A new instance of RadioGroup.
- #options ⇒ Object
- #options=(opts) ⇒ Object
- #preferred_height(_width) ⇒ Object
- #render(window) ⇒ Object
- #selected ⇒ Object
- #selected=(value) ⇒ Object
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, options: [], selected: nil, on_change: nil) ⇒ RadioGroup
Returns a new instance of RadioGroup.
19 20 21 22 23 24 25 |
# File 'lib/potty/widgets/radio_group.rb', line 19 def initialize(app, options: [], selected: nil, on_change: nil) super(app) @options = normalize() @on_change = on_change @selected = selected.nil? ? @options.first&.fetch(:value) : selected @cursor = index_of(@selected) || 0 end |
Instance Attribute Details
#on_change ⇒ Object
Returns the value of attribute on_change.
17 18 19 |
# File 'lib/potty/widgets/radio_group.rb', line 17 def on_change @on_change end |
Instance Method Details
#can_focus? ⇒ Boolean
27 28 29 |
# File 'lib/potty/widgets/radio_group.rb', line 27 def can_focus? true end |
#cursor_value ⇒ Object
The value under the cursor (the highlighted row), which may differ from the committed selection while navigating. Choosers commit this on Enter.
47 48 49 50 |
# File 'lib/potty/widgets/radio_group.rb', line 47 def cursor_value opt = @options[@cursor] opt && opt[:value] end |
#handle_key(ch) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/potty/widgets/radio_group.rb', line 66 def handle_key(ch) case ch when Keys::UP move(-1) when Keys::DOWN move(1) when Keys::SPACE, *Keys::ENTERS choose(@cursor) else return false end true end |
#options ⇒ Object
31 32 33 |
# File 'lib/potty/widgets/radio_group.rb', line 31 def @options end |
#options=(opts) ⇒ Object
35 36 37 38 |
# File 'lib/potty/widgets/radio_group.rb', line 35 def (opts) @options = normalize(opts) @cursor = @cursor.clamp(0, [@options.size - 1, 0].max) end |
#preferred_height(_width) ⇒ Object
62 63 64 |
# File 'lib/potty/widgets/radio_group.rb', line 62 def preferred_height(_width) @options.size end |
#render(window) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/potty/widgets/radio_group.rb', line 80 def render(window) return unless @visible && @rect @options.each_with_index do |opt, i| break if i >= @rect.height marker = opt[:value] == @selected ? "(\u25CF)" : "(\u25CB)" on_cursor = @focused && i == @cursor attr = on_cursor ? theme.style(:selected, bold: true) : theme.style(:normal) text = "#{marker} #{opt[:label]}"[0, @rect.width] window.setpos(@rect.y + i, @rect.x) window.attron(attr) { window.addstr(text) } end end |
#selected ⇒ Object
40 41 42 |
# File 'lib/potty/widgets/radio_group.rb', line 40 def selected @selected end |
#selected=(value) ⇒ Object
52 53 54 55 56 57 58 59 60 |
# File 'lib/potty/widgets/radio_group.rb', line 52 def selected=(value) idx = index_of(value) return unless idx @selected = value @cursor = idx @on_change&.call(@selected) emit(:change, @selected) end |