Class: Charming::Controller
- Inherits:
-
Object
- Object
- Charming::Controller
- Extended by:
- ClassMethods
- Includes:
- ActionHooks, CommandPalette, ComponentDispatching, Dispatching, FocusManagement, Rendering, SessionState, SidebarNavigation, Terminal, Timers
- Defined in:
- lib/charming/controller.rb,
lib/charming/controller/focus.rb,
lib/charming/controller/timers.rb,
lib/charming/controller/terminal.rb,
lib/charming/controller/rendering.rb,
lib/charming/controller/dispatching.rb,
lib/charming/controller/action_hooks.rb,
lib/charming/controller/key_dispatch.rb,
lib/charming/controller/class_methods.rb,
lib/charming/controller/session_state.rb,
lib/charming/controller/command_palette.rb,
lib/charming/controller/focus_management.rb,
lib/charming/controller/sidebar_navigation.rb,
lib/charming/controller/component_dispatching.rb
Overview
Controller is the base class for all controller implementations in a Charming application. It provides the action dispatch pipeline, key/command/timer/task bindings, sidebar navigation, command palette management, and view rendering with layout composition.
Direct Known Subclasses
Defined Under Namespace
Modules: ActionHooks, ClassMethods, CommandPalette, ComponentDispatching, Dispatching, FocusManagement, Rendering, SessionState, SidebarNavigation, Terminal, Timers Classes: Focus, KeyDispatch, TaskBinding, TimerBinding
Instance Attribute Summary collapse
-
#application ⇒ Object
readonly
Returns the value of attribute application.
-
#event ⇒ Object
readonly
Returns the value of attribute event.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#route ⇒ Object
readonly
Returns the value of attribute route.
-
#screen ⇒ Object
readonly
Returns the value of attribute screen.
Instance Method Summary collapse
-
#dispatch(action) ⇒ Object
Dispatches a named action on this controller (e.g. :show), running all before/around/after hooks and rescue_from handlers.
-
#dispatch_key ⇒ Object
Key event dispatch.
-
#dispatch_mouse ⇒ Object
Mouse event dispatcher: command palette (if open) wins, then sidebar clicks (route rows navigate directly), then named layout panes/components.
-
#dispatch_paste ⇒ Object
Paste event dispatcher: forwards pasted text to the focused component's
handle_paste(TextInput, TextArea, Form text fields, and Autocomplete support it). -
#dispatch_task ⇒ Object
Task event dispatcher: looks up the handler in task bindings.
-
#dispatch_task_progress ⇒ Object
Task progress dispatcher: looks up the handler in task progress bindings.
-
#dispatch_timer ⇒ Object
Timer event dispatcher: looks up the named action in timer bindings and runs it with the full hook chain.
-
#initialize(application:, event: nil, params: {}, screen: nil, route: nil) ⇒ Controller
constructor
Initializes the controller with its parent application and optional event.
-
#logger ⇒ Object
Returns the application logger.
-
#navigate_to(path) ⇒ Object
Navigates to the given URL path.
-
#open_theme_palette ⇒ Object
Opens the theme picker (a CommandPalette populated with the registered themes) and renders.
-
#quit ⇒ Object
Exits the application — sets a quit response that terminates the event loop.
-
#render(body = "", **assigns) ⇒ Object
Renders a body or template wrapped in the controller's layout.
-
#render_template(name, **assigns) ⇒ Object
Renders a template from
app/viewsby name, applying the controller's layout. - #render_view(view_class, **assigns) ⇒ Object
-
#theme ⇒ Object
Returns the active theme for this request, delegated to the application.
-
#use_theme(name) ⇒ Object
Switches the active theme to name and persists the choice in the application session.
Methods included from ClassMethods
animate, auto_render, auto_render_action, command, command_bindings, focus_ring, focus_ring_slots, key, key_binding_scopes, key_bindings, layout, on_task, on_task_progress, task_bindings, task_progress_bindings, timer, timer_bindings
Methods included from Timers
#start_timer, #stop_timer, #timer_running?
Methods included from Terminal
#bell, #copy, #notify, #set_title
Methods included from CommandPalette
#close_command_palette, #command_palette, #command_palette_open?, #open_command_palette
Methods included from SidebarNavigation
#content_focused?, #current_route?, #focus_content, #focus_sidebar, #sidebar_focused?, #sidebar_index, #sidebar_routes
Methods included from FocusManagement
Methods included from SessionState
#cancel_task, #component_state, #form, #mouse_targets, #register_mouse_targets, #run_task, #session, #state
Methods included from ActionHooks
Constructor Details
#initialize(application:, event: nil, params: {}, screen: nil, route: nil) ⇒ Controller
Initializes the controller with its parent application and optional event. Defaults to an 80x24 screen when no backend size is available.
31 32 33 34 35 36 37 38 |
# File 'lib/charming/controller.rb', line 31 def initialize(application:, event: nil, params: {}, screen: nil, route: nil) @application = application @event = event @params = params @screen = screen || Screen.new(width: 80, height: 24) @route = route @response = nil end |
Instance Attribute Details
#application ⇒ Object (readonly)
Returns the value of attribute application.
27 28 29 |
# File 'lib/charming/controller.rb', line 27 def application @application end |
#event ⇒ Object (readonly)
Returns the value of attribute event.
27 28 29 |
# File 'lib/charming/controller.rb', line 27 def event @event end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
27 28 29 |
# File 'lib/charming/controller.rb', line 27 def params @params end |
#route ⇒ Object (readonly)
Returns the value of attribute route.
27 28 29 |
# File 'lib/charming/controller.rb', line 27 def route @route end |
#screen ⇒ Object (readonly)
Returns the value of attribute screen.
27 28 29 |
# File 'lib/charming/controller.rb', line 27 def screen @screen end |
Instance Method Details
#dispatch(action) ⇒ Object
Dispatches a named action on this controller (e.g. :show), running all before/around/after hooks and rescue_from handlers.
42 43 44 45 46 |
# File 'lib/charming/controller.rb', line 42 def dispatch(action) run_action_with_hooks(action) render_default_action if response.nil? && auto_render_after?(action) response || render("") end |
#dispatch_key ⇒ Object
Key event dispatch. The precedence ladder (palette → focused text capture → global bindings → overlay → sidebar/content/component) lives in KeyDispatch.
50 51 52 |
# File 'lib/charming/controller.rb', line 50 def dispatch_key KeyDispatch.new(self).call end |
#dispatch_mouse ⇒ Object
Mouse event dispatcher: command palette (if open) wins, then sidebar clicks (route rows navigate directly), then named layout panes/components.
96 97 98 99 100 101 102 103 |
# File 'lib/charming/controller.rb', line 96 def dispatch_mouse return dispatch_command_palette_mouse if command_palette_open? = return if dispatch_component_mouse end |
#dispatch_paste ⇒ Object
Paste event dispatcher: forwards pasted text to the focused component's
handle_paste (TextInput, TextArea, Form text fields, and Autocomplete support it).
80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/charming/controller.rb', line 80 def dispatch_paste slot = focus.current return nil unless slot && respond_to?(slot, true) component = send(slot) return nil unless component.respond_to?(:handle_paste) result = component.handle_paste(event) return nil if result.nil? dispatch_component_result(slot, result) response end |
#dispatch_task ⇒ Object
Task event dispatcher: looks up the handler in task bindings.
67 68 69 70 |
# File 'lib/charming/controller.rb', line 67 def dispatch_task b = self.class.task_bindings[event.name.to_sym] b ? dispatch(b.action) : nil end |
#dispatch_task_progress ⇒ Object
Task progress dispatcher: looks up the handler in task progress bindings.
73 74 75 76 |
# File 'lib/charming/controller.rb', line 73 def dispatch_task_progress b = self.class.task_progress_bindings[event.name.to_sym] b ? dispatch(b.action) : nil end |
#dispatch_timer ⇒ Object
Timer event dispatcher: looks up the named action in timer bindings and runs it with the full hook chain. Unlike #dispatch there is no render("") fallback — a timer action that renders nothing yields a nil response, so silent ticks skip the repaint instead of blanking the screen.
58 59 60 61 62 63 64 |
# File 'lib/charming/controller.rb', line 58 def dispatch_timer b = self.class.timer_bindings[event.name.to_sym] return nil unless b run_action_with_hooks(b.action) response end |
#logger ⇒ Object
Returns the application logger. The default logger writes to File::NULL, so logging calls are safe in TUI code unless the app explicitly configures a file or custom logger.
135 136 137 |
# File 'lib/charming/controller.rb', line 135 def logger application.logger end |
#navigate_to(path) ⇒ Object
Navigates to the given URL path.
147 148 149 |
# File 'lib/charming/controller.rb', line 147 def navigate_to(path) @response = Response.navigate(path) end |
#open_theme_palette ⇒ Object
Opens the theme picker (a CommandPalette populated with the registered themes) and renders.
140 141 142 143 144 |
# File 'lib/charming/controller.rb', line 140 def open_theme_palette session[:command_palette] = command_palette_state(:themes) focus.push_scope([:command_palette], origin: :command_palette) render_default_action end |
#quit ⇒ Object
Exits the application — sets a quit response that terminates the event loop.
152 153 154 |
# File 'lib/charming/controller.rb', line 152 def quit @response = Response.quit end |
#render(body = "", **assigns) ⇒ Object
Renders a body or template wrapped in the controller's layout. Out-of-band escape sequences registered while rendering (e.g. image transmissions) are collected by the Runtime around the whole dispatch and attached to the response.
108 109 110 111 |
# File 'lib/charming/controller.rb', line 108 def render(body = "", **assigns) body = view_body(default_template_name(body), **assigns) if body.is_a?(Symbol) @response = Response.render(render_with_layout(body)) end |
#render_template(name, **assigns) ⇒ Object
Renders a template from app/views by name, applying the controller's layout. name is the
template path (e.g., "home/show") and additional keyword assigns are forwarded to the view.
119 120 121 |
# File 'lib/charming/controller.rb', line 119 def render_template(name, **assigns) @response = Response.render(render_with_layout(template_body(name, **assigns))) end |
#render_view(view_class, **assigns) ⇒ Object
113 114 115 |
# File 'lib/charming/controller.rb', line 113 def render_view(view_class, **assigns) @response = Response.render(render_with_layout(view_class.new(**template_assigns(assigns)))) end |
#theme ⇒ Object
Returns the active theme for this request, delegated to the application.
124 125 126 |
# File 'lib/charming/controller.rb', line 124 def theme application.theme end |
#use_theme(name) ⇒ Object
Switches the active theme to name and persists the choice in the application session.
129 130 131 |
# File 'lib/charming/controller.rb', line 129 def use_theme(name) application.use_theme(name) end |