1313from rich .console import Console
1414
1515from . import events
16+ from . import actions
1617from ._context import active_app
1718from .driver import Driver
1819from ._linux_driver import LinuxDriver
2223log = logging .getLogger ("rich" )
2324
2425
25- LayoutDefinition = dict [str , Any ]
26+ LayoutDefinition = " dict[str, Any]"
2627
2728try :
2829 import uvloop
@@ -54,6 +55,8 @@ def __init__(
5455 self .view = view or LayoutView ()
5556 self .children : set [MessagePump ] = set ()
5657
58+ self ._action_targets = {"app" : self , "view" : self .view }
59+
5760 def __rich_repr__ (self ) -> RichReprResult :
5861 yield "title" , self .title
5962
@@ -107,9 +110,7 @@ async def add(self, child: MessagePump) -> None:
107110 def refresh (self ) -> None :
108111 console = self .console
109112 with console :
110- console .print (
111- Screen (Control .home (), self .view , Control .home (), application_mode = True )
112- )
113+ console .print (Screen (Control .home (), self .view , Control .home ()))
113114
114115 async def on_event (self , event : events .Event , priority : int ) -> None :
115116 if isinstance (event , events .Key ):
@@ -128,18 +129,38 @@ async def on_idle(self, event: events.Idle) -> None:
128129 await self .view .post_message (event )
129130
130131 async def action (self , action : str ) -> None :
131- if "." in action :
132- destination , action_name , * tokens = action .split ("." )
132+ """Perform an action.
133+
134+ Args:
135+ action (str): Action encoded in a string.
136+ """
137+
138+ target , params = actions .parse (action )
139+ if "." in target :
140+ destination , action_name = target .split ("." , 1 )
133141 else :
134142 destination = "app"
135143 action_name = action
136- tokens = []
137144
138- if destination == "app" :
145+ log .debug ("ACTION %r %r" , destination , action_name )
146+ await self .dispatch_action (destination , action_name , params )
147+
148+ async def dispatch_action (
149+ self , destination : str , action_name : str , params : Any
150+ ) -> None :
151+ action_target = self ._action_targets .get (destination , None )
152+ log .debug ("ACTION TARGET %r" , action_target )
153+ if action_target is not None :
139154 method_name = f"action_{ action_name } "
140- method = getattr (self , method_name , None )
155+ method = getattr (action_target , method_name , None )
156+ log .debug ("ACTION METHOD %r" , method )
141157 if method is not None :
142- await method (tokens )
158+ try :
159+ await method (* params )
160+ except Exception :
161+ log .exception (
162+ f"error in action { destination } .{ action_name } { params !r} "
163+ )
143164
144165 async def on_shutdown_request (self , event : events .ShutdownRequest ) -> None :
145166 log .debug ("shutdown request" )
@@ -163,7 +184,7 @@ async def on_mouse_scroll_up(self, event: events.MouseScrollUp) -> None:
163184 async def on_mouse_scroll_down (self , event : events .MouseScrollUp ) -> None :
164185 await self .view .post_message (event )
165186
166- async def action_quit (self , tokens : list [ str ] ) -> None :
187+ async def action_quit (self ) -> None :
167188 await self .close_messages ()
168189
169190
@@ -191,7 +212,7 @@ async def action_quit(self, tokens: list[str]) -> None:
191212
192213 class MyApp (App ):
193214
194- KEYS = {"q" : "quit" , "ctrl+c" : "quit" }
215+ KEYS = {"q" : "quit" , "ctrl+c" : "quit" , "b" : "view.toggle('left')" }
195216
196217 async def on_startup (self , event : events .Startup ) -> None :
197218 await self .view .mount_all (
0 commit comments