Class: Charming::Controller
- Inherits:
-
Object
- Object
- Charming::Controller
- Extended by:
- ClassMethods
- Includes:
- ActionHooks, CommandPalette, ComponentDispatching, Dispatching, FocusManagement, Rendering, SessionState, SidebarNavigation, Terminal
- Defined in:
- lib/charming/controller.rb,
lib/charming/controller/focus.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 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
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 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.
26 27 28 29 30 31 32 33 |
# File 'lib/charming/controller.rb', line 26 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.
22 23 24 |
# File 'lib/charming/controller.rb', line 22 def application @application end |
#event ⇒ Object (readonly)
Returns the value of attribute event.
22 23 24 |
# File 'lib/charming/controller.rb', line 22 def event @event end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
22 23 24 |
# File 'lib/charming/controller.rb', line 22 def params @params end |
#route ⇒ Object (readonly)
Returns the value of attribute route.
22 23 24 |
# File 'lib/charming/controller.rb', line 22 def route @route end |
#screen ⇒ Object (readonly)
Returns the value of attribute screen.
22 23 24 |
# File 'lib/charming/controller.rb', line 22 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.
37 38 39 40 41 |
# File 'lib/charming/controller.rb', line 37 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.
45 46 47 |
# File 'lib/charming/controller.rb', line 45 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.
91 92 93 94 95 96 97 98 |
# File 'lib/charming/controller.rb', line 91 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).
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/charming/controller.rb', line 75 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.
62 63 64 65 |
# File 'lib/charming/controller.rb', line 62 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.
68 69 70 71 |
# File 'lib/charming/controller.rb', line 68 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.
53 54 55 56 57 58 59 |
# File 'lib/charming/controller.rb', line 53 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.
130 131 132 |
# File 'lib/charming/controller.rb', line 130 def logger application.logger end |
#navigate_to(path) ⇒ Object
Navigates to the given URL path.
142 143 144 |
# File 'lib/charming/controller.rb', line 142 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.
135 136 137 138 139 |
# File 'lib/charming/controller.rb', line 135 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.
147 148 149 |
# File 'lib/charming/controller.rb', line 147 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.
103 104 105 106 |
# File 'lib/charming/controller.rb', line 103 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.
114 115 116 |
# File 'lib/charming/controller.rb', line 114 def render_template(name, **assigns) @response = Response.render(render_with_layout(template_body(name, **assigns))) end |
#render_view(view_class, **assigns) ⇒ Object
108 109 110 |
# File 'lib/charming/controller.rb', line 108 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.
119 120 121 |
# File 'lib/charming/controller.rb', line 119 def theme application.theme end |
#use_theme(name) ⇒ Object
Switches the active theme to name and persists the choice in the application session.
124 125 126 |
# File 'lib/charming/controller.rb', line 124 def use_theme(name) application.use_theme(name) end |