Module: Charming::Controller::ClassMethods
- Included in:
- Charming::Controller
- Defined in:
- lib/charming/controller/class_methods.rb
Overview
DSL for declaring controller-level event bindings and configuration: keys, commands, timers, task handlers, the auto-rendered action, layout wrapper, and focus ring. Mixed into Controller as class methods; also exposed for tests and shared base controllers.
Instance Method Summary collapse
-
#animate(name, action:, fps: 30) ⇒ Object
Declares an animation: a stopped timer ticking action at fps frames per second.
-
#auto_render(action = :show) ⇒ Object
Sets the action that the controller should auto-render after a non-rendering action runs.
-
#auto_render_action ⇒ Object
Returns the configured auto-render action, walking the superclass chain when undefined locally.
-
#command(label, action = nil, &block) ⇒ Object
Adds a CommandPalette entry with the given label.
-
#command_bindings ⇒ Object
Array of registered command palette entries, inherited from superclass when undefined.
-
#focus_ring(*slots) ⇒ Object
Defines the named focus slots cycled by Tab/Shift+Tab traversal.
-
#focus_ring_slots ⇒ Object
Returns the focus ring slots, inherited from superclass when undefined.
-
#key(name, action, scope: :content) ⇒ Object
Binds a key press to a controller action.
-
#key_binding_scopes ⇒ Object
Hash of key scopes paralleling
key_bindings(symbol key name => :content or :global). -
#key_bindings ⇒ Object
Hash of registered key bindings (symbol key name => action method name), inherited from superclass controllers.
-
#layout(layout_class = :__charming_layout_reader__) ⇒ Object
Sets or returns the controller's layout.
-
#on_task(name, action:) ⇒ Object
Declares a task handler for async work submitted via
run_task(:name). -
#on_task_progress(name, action:) ⇒ Object
Declares a progress handler for a task: while
run_task(:name)runs, eachprogress.report(...)dispatches action on the controller (the event is available asevent— a TaskProgressEvent with current/total/message). -
#task_bindings ⇒ Object
Hash of task name => TaskBinding, inherited from superclass when undefined.
-
#task_progress_bindings ⇒ Object
Hash of task name => TaskBinding for progress handlers, inherited from superclass.
-
#timer(name, every:, action:, autostart: true) ⇒ Object
Declares a timer that fires every every seconds and dispatches action on the controller.
-
#timer_bindings ⇒ Object
Hash of timer name => TimerBinding, inherited from superclass when undefined.
Instance Method Details
#animate(name, action:, fps: 30) ⇒ Object
Declares an animation: a stopped timer ticking action at fps frames per second.
Begin motion with start_timer(name); the action calls stop_timer(name) once the
motion settles, returning the app to zero idle cost.
38 39 40 41 42 |
# File 'lib/charming/controller/class_methods.rb', line 38 def animate(name, action:, fps: 30) raise ArgumentError, "fps must be positive (got #{fps.inspect})" unless fps.is_a?(Numeric) && fps.positive? timer(name, every: 1.0 / fps, action: action, autostart: false) end |
#auto_render(action = :show) ⇒ Object
Sets the action that the controller should auto-render after a non-rendering action runs. Defaults to :show when unset.
59 60 61 |
# File 'lib/charming/controller/class_methods.rb', line 59 def auto_render(action = :show) @auto_render_action = action.to_sym end |
#auto_render_action ⇒ Object
Returns the configured auto-render action, walking the superclass chain when undefined locally.
64 65 66 67 68 69 |
# File 'lib/charming/controller/class_methods.rb', line 64 def auto_render_action return @auto_render_action if instance_variable_defined?(:@auto_render_action) return superclass.auto_render_action if superclass.respond_to?(:auto_render_action) nil end |
#command(label, action = nil, &block) ⇒ Object
Adds a CommandPalette entry with the given label. action is a method name to send on the controller, or a block to instance_exec when selected.
21 22 23 |
# File 'lib/charming/controller/class_methods.rb', line 21 def command(label, action = nil, &block) command_bindings << Components::CommandPalette::Command.new(label: label, value: block || action) end |
#command_bindings ⇒ Object
Array of registered command palette entries, inherited from superclass when undefined.
102 103 104 |
# File 'lib/charming/controller/class_methods.rb', line 102 def command_bindings @command_bindings ||= superclass.respond_to?(:command_bindings) ? superclass.command_bindings.dup : [] end |
#focus_ring(*slots) ⇒ Object
Defines the named focus slots cycled by Tab/Shift+Tab traversal.
92 93 94 |
# File 'lib/charming/controller/class_methods.rb', line 92 def focus_ring(*slots) @focus_ring_slots = slots end |
#focus_ring_slots ⇒ Object
Returns the focus ring slots, inherited from superclass when undefined.
97 98 99 |
# File 'lib/charming/controller/class_methods.rb', line 97 def focus_ring_slots @focus_ring_slots ||= superclass.respond_to?(:focus_ring_slots) ? superclass.focus_ring_slots.dup : [] end |
#key(name, action, scope: :content) ⇒ Object
Binds a key press to a controller action. name is the normalized key symbol (e.g., "up", "q", "ctrl+c"). scope is :content (default) for content-pane keys or :global for app-wide shortcuts that fire regardless of focus. Raises ArgumentError for any other scope.
12 13 14 15 16 17 |
# File 'lib/charming/controller/class_methods.rb', line 12 def key(name, action, scope: :content) normalized_scope = validate_key_scope(scope) key_name = Charming.key_binding_name(name) key_bindings[key_name] = action key_binding_scopes[key_name] = normalized_scope end |
#key_binding_scopes ⇒ Object
Hash of key scopes paralleling key_bindings (symbol key name => :content or :global).
87 88 89 |
# File 'lib/charming/controller/class_methods.rb', line 87 def key_binding_scopes @key_binding_scopes ||= superclass.respond_to?(:key_binding_scopes) ? superclass.key_binding_scopes.dup : {} end |
#key_bindings ⇒ Object
Hash of registered key bindings (symbol key name => action method name), inherited from superclass controllers.
82 83 84 |
# File 'lib/charming/controller/class_methods.rb', line 82 def key_bindings @key_bindings ||= superclass.respond_to?(:key_bindings) ? superclass.key_bindings.dup : {} end |
#layout(layout_class = :__charming_layout_reader__) ⇒ Object
Sets or returns the controller's layout. Pass a layout class (instantiated per request),
a String/Symbol template name (resolved through Templates), or false to
disable inherited layout wrapping. Called with no arguments returns the resolved layout.
74 75 76 77 78 |
# File 'lib/charming/controller/class_methods.rb', line 74 def layout(layout_class = :__charming_layout_reader__) return resolved_layout if layout_class == :__charming_layout_reader__ @layout = layout_class end |
#on_task(name, action:) ⇒ Object
Declares a task handler for async work submitted via run_task(:name). When the task emits
a TaskEvent with the matching name, the runtime dispatches action on the controller.
46 47 48 |
# File 'lib/charming/controller/class_methods.rb', line 46 def on_task(name, action:) task_bindings[name.to_sym] = TaskBinding.new(name: name.to_sym, action: action) end |
#on_task_progress(name, action:) ⇒ Object
Declares a progress handler for a task: while run_task(:name) runs, each
progress.report(...) dispatches action on the controller (the event is
available as event — a TaskProgressEvent with current/total/message).
53 54 55 |
# File 'lib/charming/controller/class_methods.rb', line 53 def on_task_progress(name, action:) task_progress_bindings[name.to_sym] = TaskBinding.new(name: name.to_sym, action: action) end |
#task_bindings ⇒ Object
Hash of task name => TaskBinding, inherited from superclass when undefined.
112 113 114 |
# File 'lib/charming/controller/class_methods.rb', line 112 def task_bindings @task_bindings ||= superclass.respond_to?(:task_bindings) ? superclass.task_bindings.dup : {} end |
#task_progress_bindings ⇒ Object
Hash of task name => TaskBinding for progress handlers, inherited from superclass.
117 118 119 |
# File 'lib/charming/controller/class_methods.rb', line 117 def task_progress_bindings @task_progress_bindings ||= superclass.respond_to?(:task_progress_bindings) ? superclass.task_progress_bindings.dup : {} end |
#timer(name, every:, action:, autostart: true) ⇒ Object
Declares a timer that fires every every seconds and dispatches action on the controller.
The runtime builds a TimerEvent and routes it to the active controller's dispatch_timer.
Timers run from boot by default; declare autostart: false to schedule one only when an
action calls start_timer.
29 30 31 32 33 |
# File 'lib/charming/controller/class_methods.rb', line 29 def timer(name, every:, action:, autostart: true) raise ArgumentError, "timer interval must be positive (got #{every.inspect})" unless every.is_a?(Numeric) && every.positive? timer_bindings[name.to_sym] = TimerBinding.new(name: name.to_sym, interval: every, action: action, autostart: autostart) end |
#timer_bindings ⇒ Object
Hash of timer name => TimerBinding, inherited from superclass when undefined.
107 108 109 |
# File 'lib/charming/controller/class_methods.rb', line 107 def timer_bindings @timer_bindings ||= superclass.respond_to?(:timer_bindings) ? superclass.timer_bindings.dup : {} end |