Class: Gemba::ModalStack
- Inherits:
-
Object
- Object
- Gemba::ModalStack
- Defined in:
- lib/gemba/modal_stack.rb
Overview
Push/pop stack for modal child windows.
One modal can push another (e.g. Settings → Replay Player) and the previous modal is automatically re-shown on pop.
Windows must implement the ModalWindow protocol:
show_modal(**args) — reveal the window (deiconify, grab, position)
withdraw — hide the window (release grab, withdraw — NO callback)
Defined Under Namespace
Classes: Entry
Instance Method Summary collapse
-
#active? ⇒ Boolean
True if any modal is open.
-
#current ⇒ Symbol?
Name of the topmost modal, or nil.
-
#initialize(on_enter:, on_exit:, on_focus_change: nil) ⇒ ModalStack
constructor
A new instance of ModalStack.
-
#pop ⇒ Object
Pop the current modal off the stack.
-
#push(name, window, show_args: {}) ⇒ Object
Push a modal onto the stack.
-
#size ⇒ Integer
Number of modals on the stack.
Constructor Details
#initialize(on_enter:, on_exit:, on_focus_change: nil) ⇒ ModalStack
Returns a new instance of ModalStack.
29 30 31 32 33 34 |
# File 'lib/gemba/modal_stack.rb', line 29 def initialize(on_enter:, on_exit:, on_focus_change: nil) @stack = [] @on_enter = on_enter @on_exit = on_exit @on_focus_change = on_focus_change end |
Instance Method Details
#active? ⇒ Boolean
Returns true if any modal is open.
37 |
# File 'lib/gemba/modal_stack.rb', line 37 def active? = !@stack.empty? |
#current ⇒ Symbol?
Returns name of the topmost modal, or nil.
40 |
# File 'lib/gemba/modal_stack.rb', line 40 def current = @stack.last&.name |
#pop ⇒ Object
Pop the current modal off the stack.
If the stack still has entries, the previous modal is re-shown. If the stack is now empty, on_exit is fired (unpause emulation, etc.).
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/gemba/modal_stack.rb', line 69 def pop return unless (entry = @stack.pop) entry.window.withdraw if (prev = @stack.last) @on_focus_change&.call(prev.name) prev.window.show_modal(**prev.show_args) else @on_exit.call end end |
#push(name, window, show_args: {}) ⇒ Object
Push a modal onto the stack.
If another modal is on top, it is withdrawn (without callback). If the stack was empty, on_enter is fired (pause emulation, etc.).
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/gemba/modal_stack.rb', line 53 def push(name, window, show_args: {}) was_empty = @stack.empty? # Withdraw current top without firing its on_dismiss @stack.last&.window&.withdraw @stack.push(Entry.new(name: name, window: window, show_args: show_args)) @on_enter.call(name) if was_empty @on_focus_change&.call(name) window.show_modal(**show_args) end |
#size ⇒ Integer
Returns number of modals on the stack.
43 |
# File 'lib/gemba/modal_stack.rb', line 43 def size = @stack.length |