Class: Potty::Widgets::Countdown
- Defined in:
- lib/potty/widgets/countdown.rb
Overview
Passive display that counts down from N seconds and fires on_expire once when it reaches zero. Time-driven: it advances off the ‘now` passed to tick(now), so drive it via the Application tick loop (set Application#tick_interval).
The clock starts on the first tick (not at construction), so a Countdown built well before the loop spins up still gets its full N.
Instance Attribute Summary collapse
-
#on_expire ⇒ Object
Returns the value of attribute on_expire.
Attributes inherited from Base
#app, #focused, #parent, #rect
Instance Method Summary collapse
- #expired? ⇒ Boolean
-
#initialize(app, seconds:, on_expire: nil, format: nil) ⇒ Countdown
constructor
A new instance of Countdown.
- #preferred_height(_width) ⇒ Object
-
#remaining ⇒ Object
Whole seconds left (ceil), clamped at 0.
- #render(window) ⇒ Object
-
#start ⇒ Object
(Re)start the countdown from the top.
- #stop ⇒ 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, seconds:, on_expire: nil, format: nil) ⇒ Countdown
Returns a new instance of Countdown.
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/potty/widgets/countdown.rb', line 17 def initialize(app, seconds:, on_expire: nil, format: nil) super(app) @seconds = seconds.to_f @on_expire = on_expire @format = format || ->(remaining) { "Auto-launching in #{remaining}s\u2026" } @started_at = nil @last_now = nil @running = true @expired = false end |
Instance Attribute Details
#on_expire ⇒ Object
Returns the value of attribute on_expire.
15 16 17 |
# File 'lib/potty/widgets/countdown.rb', line 15 def on_expire @on_expire end |
Instance Method Details
#expired? ⇒ Boolean
42 43 44 |
# File 'lib/potty/widgets/countdown.rb', line 42 def expired? @expired end |
#preferred_height(_width) ⇒ Object
53 54 55 |
# File 'lib/potty/widgets/countdown.rb', line 53 def preferred_height(_width) 1 end |
#remaining ⇒ Object
Whole seconds left (ceil), clamped at 0.
47 48 49 50 51 |
# File 'lib/potty/widgets/countdown.rb', line 47 def remaining return @seconds.ceil if @started_at.nil? || @last_now.nil? [@seconds - (@last_now - @started_at), 0].max.ceil end |
#render(window) ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/potty/widgets/countdown.rb', line 72 def render(window) return unless @visible && @rect text = @format.call(remaining).to_s[0, @rect.width] window.setpos(@rect.y, @rect.x) window.attron(theme[:warning]) { window.addstr(text) } end |
#start ⇒ Object
(Re)start the countdown from the top.
29 30 31 32 33 34 35 |
# File 'lib/potty/widgets/countdown.rb', line 29 def start @started_at = nil @last_now = nil @running = true @expired = false self end |
#stop ⇒ Object
37 38 39 40 |
# File 'lib/potty/widgets/countdown.rb', line 37 def stop @running = false self end |
#tick(now) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/potty/widgets/countdown.rb', line 57 def tick(now) @last_now = now return unless @running @started_at ||= now return if @expired return unless now - @started_at >= @seconds @expired = true @running = false @on_expire&.call(self) emit(:expire, self) end |