88from textual import work
99from textual .app import App , ComposeResult
1010from textual .binding import Binding
11- from textual .widgets import Footer , Input
11+ from textual .widgets import Footer , Input , Label
1212from rich .text import Text
13+ from asyncio import sleep
1314import numbers
1415from adb_wrapper import AdbWrapper
1516import threading
@@ -44,6 +45,9 @@ class TableApp(App):
4445 session_dir = os .path .join (config ["logs" ]["path" ], session_id )
4546 events_file = os .path .join (session_dir , "events.json" )
4647 single_session_mode = config ["single_session_mode" ]
48+ status_widget = None
49+ status_messages = [f" glassesRecord TUI started in { "single-session mode" if single_session_mode else "multi-session mode" } ; Session ID: { session_id } " ]
50+ status_len = config ["logs" ]["TUI_messages_len" ] # Number of status messages to keep
4751
4852 restart_app_in_progress = False
4953
@@ -68,6 +72,7 @@ def on_mount(self) -> None:
6872 format = '[%(asctime)s] %(levelname)s [%(name)s] %(message)s' )
6973 logging .getLogger ('pupil_labs.realtime_api.time_echo' ).setLevel (logging .ERROR )
7074 self .logger = logging .getLogger ('glassesRecord_TUI' )
75+ self .status_widget = self .query_one (Label )
7176
7277 # Setup app theme and table
7378 self .theme = "textual-dark"
@@ -560,6 +565,18 @@ def stop_recording_offsets(self, device_list):
560565 print (e )
561566 pass
562567
568+ def update_status_widget (self , new_msg ):
569+ """Update the status widget with the provided message.
570+
571+ Args:
572+ message (str): The message to display in the status widget.
573+ """
574+ self .status_messages .append (new_msg )
575+ self .status_messages = self .status_messages [- self .status_len :]
576+
577+ if self .status_widget :
578+ self .status_widget .update ('\n ' .join (self .status_messages ))
579+
563580 #Defining actions
564581 @work (exclusive = True , thread = True )
565582 async def action_recording_start (self ) -> None :
@@ -571,7 +588,8 @@ async def action_recording_start(self) -> None:
571588 table = self .query_one (SelectableRowsDataTable )
572589 selected_devices = [row .data [1 ] for row in table .selected_rows ]
573590 self .logger .info ("Selected devices ({}): {}" .format (len (selected_devices ), selected_devices ))
574- print ("STARTING REC on selected devices" )
591+ self .update_status_widget (f" Starting recording on { len (selected_devices )} device(s)..." )
592+ # print("STARTING REC on selected devices")
575593
576594 if self .single_session_mode :
577595 if not self .offset_logger :
@@ -589,6 +607,8 @@ async def action_recording_start(self) -> None:
589607 for d in selected_devices :
590608 t = threading .Thread (target = self .start_recording , args = (d ,), daemon = True )
591609 t .start ()
610+
611+ self .update_status_widget (f" Start recordings action completed!" )
592612
593613
594614 ## Implementing action keys below to control the execution of certain operations manually by the operator.
@@ -602,13 +622,15 @@ async def action_recording_stop_and_save(self) -> None:
602622 """
603623 table = self .query_one (SelectableRowsDataTable )
604624 selected_devices = [row .data [1 ] for row in table .selected_rows ]
605- print ("STOPPING REC on selected device(s): " , selected_devices )
625+ self .update_status_widget (f" Saving recording on { len (selected_devices )} device(s)..." )
626+ # print("STOPPING REC on selected device(s): ", selected_devices)
606627 self .logger .info (f"Stopping recording on { len (selected_devices )} device(s): { selected_devices } " )
607628 # Stop offset logging if it was started
608629 self .stop_recording_offsets (selected_devices )
609630 for d in selected_devices :
610631 t = threading .Thread (target = self .stop_and_save_recording , args = (d ,), daemon = True )
611632 t .start ()
633+ self .update_status_widget (f" Save recordings action completed!" )
612634
613635 @work (exclusive = True , thread = True )
614636 async def action_recording_stop_and_discard (self ) -> None :
@@ -619,13 +641,15 @@ async def action_recording_stop_and_discard(self) -> None:
619641 """
620642 table = self .query_one (SelectableRowsDataTable )
621643 selected_devices = [row .data [1 ] for row in table .selected_rows ]
622- print ("DISCARDING REC on selected devices" )
644+ self .update_status_widget (f" Discarding recordings on { len (selected_devices )} device(s)..." )
645+ # print("DISCARDING REC on selected devices")
623646 # Stop offset logging if it was started
624- self .stop_recording_offsets (selected_devices )
625647 self .logger .info (f"Discarding recording on { len (selected_devices )} device(s): { selected_devices } " )
648+ self .stop_recording_offsets (selected_devices )
626649 for d in selected_devices :
627650 t = threading .Thread (target = self .stop_and_discard_recording , args = (d ,), daemon = True )
628651 t .start ()
652+ self .update_status_widget (f" Discard recordings action completed!" )
629653
630654 @work (exclusive = True , thread = True )
631655 async def action_restart_app_on_devices (self ) -> None :
@@ -645,6 +669,7 @@ async def action_restart_app_on_devices(self) -> None:
645669
646670 table = self .query_one (SelectableRowsDataTable )
647671 selected_device_ip_addrs = [row .data [1 ] for row in table .selected_rows ]
672+ self .update_status_widget (f" Restarting app on { len (selected_device_ip_addrs )} devices..." )
648673 self .logger .info ("Selected devices ({}): {}" .format (len (selected_device_ip_addrs ), selected_device_ip_addrs ))
649674
650675 def f (ip_addr ):
@@ -663,6 +688,7 @@ def f(ip_addr):
663688 for t in tasks :
664689 t .join ()
665690 self .logger .info (f'Restarting apps has finished!' )
691+ self .update_status_widget (f" App restart action completed!" )
666692 finally :
667693 self .restart_app_in_progress = False
668694 self .logger .info (f'self.restart_app_in_progress = False' )
@@ -676,6 +702,7 @@ async def action_reconnect_adb(self) -> None:
676702 print ("RESTARTING ADB on selected devices!" )
677703 table = self .query_one (SelectableRowsDataTable )
678704 selected_device_ip_addrs = [row .data [1 ] for row in table .selected_rows ]
705+ self .update_status_widget (f" Restarting adb on { len (selected_device_ip_addrs )} devices..." )
679706 self .logger .info ("Selected devices ({}): {}" .format (len (selected_device_ip_addrs ), selected_device_ip_addrs ))
680707
681708 def run_adb_cmd (ip_addr ):
@@ -689,6 +716,7 @@ def run_adb_cmd(ip_addr):
689716 t .start ()
690717
691718 print ('FINISHED dispatching adb restart threads!' )
719+ self .update_status_widget (f" adb restart action completed!" )
692720
693721 @work (exclusive = True , thread = True )
694722 def action_stop_all_offsets (self ) -> None :
@@ -711,7 +739,7 @@ def action_toggle_dark(self) -> None:
711739 description = "Save Recording" ),
712740 Binding (key = "u" , action = "recording_stop_and_discard" ,
713741 description = "Cancel Recording" ),
714- Binding (key = "o" , action = "stop_all_offsets" , description = "Stop offsets logging on all devices" ),
742+ * ([ Binding (key = "o" , action = "stop_all_offsets" , description = "Stop offsets logging on all devices" )] if config [ "single_session_mode" ] else [] ),
715743 Binding (key = "t" , action = "restart_app_on_devices" , description = "Restart App" ),
716744 Binding (key = "a" , action = "reconnect_adb" , description = "Reconnect adb" ),
717745 Binding (key = "d" , action = "toggle_dark" , description = "Toggle dark mode" ),
@@ -725,6 +753,7 @@ def compose(self) -> ComposeResult:
725753 """
726754 yield SelectableRowsDataTable ()
727755 yield Input (id = "event_tag" , placeholder = "Enter event tag/desc. here and press enter to log the event." , tooltip = "Use Tab to change focus" )
756+ yield Label (self .status_messages [0 ])
728757 yield Footer (id = "footer" )
729758
730759def as_colored_text (val , ** kwargs ):
0 commit comments