Class: Potty::Widgets::Spinner
- Defined in:
- lib/potty/widgets/spinner.rb
Overview
Single-line activity indicator: an animated braille spinner, a live mutable label, and a trailing state. While active the glyph is the spinner; complete!(result) freezes it to a fixed glyph and flips the color. Passive (no focus/input). Tick-driven via an internal Animator.
s = Spinner.new(app, label: "daemon - running")
s.label = "daemon - surrendering 16 children" # live update
s.complete!(:success) # glyph -> checkmark, color -> :success
Constant Summary collapse
- STATE_GLYPHS =
{ success: "\u2713", failure: "\u2717", cancelled: "\u23F9" }.freeze
- STATE_COLORS =
{ success: :success, failure: :error, cancelled: :dim }.freeze
Instance Attribute Summary collapse
-
#color ⇒ Object
readonly
Returns the value of attribute color.
-
#label ⇒ Object
Returns the value of attribute label.
-
#prefix ⇒ Object
Returns the value of attribute prefix.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Attributes inherited from Base
#app, #focused, #parent, #rect
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#complete!(result = :success) ⇒ Object
Freeze the spinner to a terminal state.
-
#initialize(app, label: '', color: :info, prefix: ' ') ⇒ Spinner
constructor
A new instance of Spinner.
- #preferred_height(_width) ⇒ Object
- #render(window) ⇒ Object
- #tick(now) ⇒ Object
Methods inherited from Base
#activate, #blur, #can_focus?, #deactivate, #focus, #handle_escape, #handle_key, #hide, #layout, #on_blur, #on_focus, #on_layout, #show, #theme, #visible=, #visible?
Methods included from Events
#emit, #listeners?, #off, #on
Constructor Details
#initialize(app, label: '', color: :info, prefix: ' ') ⇒ Spinner
Returns a new instance of Spinner.
24 25 26 27 28 29 30 31 32 |
# File 'lib/potty/widgets/spinner.rb', line 24 def initialize(app, label: '', color: :info, prefix: ' ') super(app) @label = label @color = color @prefix = prefix @state = :active @animator = Animator.new(app) @animator << Sprites::Sample.spinner end |
Instance Attribute Details
#color ⇒ Object (readonly)
Returns the value of attribute color.
22 23 24 |
# File 'lib/potty/widgets/spinner.rb', line 22 def color @color end |
#label ⇒ Object
Returns the value of attribute label.
21 22 23 |
# File 'lib/potty/widgets/spinner.rb', line 21 def label @label end |
#prefix ⇒ Object
Returns the value of attribute prefix.
21 22 23 |
# File 'lib/potty/widgets/spinner.rb', line 21 def prefix @prefix end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
22 23 24 |
# File 'lib/potty/widgets/spinner.rb', line 22 def state @state end |
Instance Method Details
#active? ⇒ Boolean
34 35 36 |
# File 'lib/potty/widgets/spinner.rb', line 34 def active? @state == :active end |
#complete!(result = :success) ⇒ Object
Freeze the spinner to a terminal state. Idempotent: only the first call takes effect, so repeated lifecycle events are harmless.
40 41 42 43 44 45 46 47 48 |
# File 'lib/potty/widgets/spinner.rb', line 40 def complete!(result = :success) return self unless active? @state = result @color = STATE_COLORS.fetch(result, @color) @animator.stop emit(:complete, result) self end |
#preferred_height(_width) ⇒ Object
50 51 52 |
# File 'lib/potty/widgets/spinner.rb', line 50 def preferred_height(_width) 1 end |
#render(window) ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/potty/widgets/spinner.rb', line 58 def render(window) return unless @visible && @rect glyph = active? ? current_frame : STATE_GLYPHS.fetch(@state, '?') text = truncate("#{@prefix}#{glyph} #{@label}", @rect.width) window.setpos(@rect.y, @rect.x) # theme.style (not theme[]) so we render in colour on either surface — # curses resolves the Style to a pair, inline to ANSI SGR. window.attron(theme.style(@color)) { window.addstr(text) } end |
#tick(now) ⇒ Object
54 55 56 |
# File 'lib/potty/widgets/spinner.rb', line 54 def tick(now) @animator.tick(now) if active? end |