onyx-and-iris ae39a318d9 add --no-rich_log flag
use it to disable the RichLog and load the tui_no_log tcss.

update README and add no log screenshot
2026-03-21 00:00:35 +00:00

131 lines
4.5 KiB
Python

import vban_cmd
from textual.app import App, ComposeResult
from textual.containers import Grid
from textual.widgets import RichLog
from .history import CommandHistory
from .hybrid import LabelInput
from .settings import Settings
class VbanTui(App):
"""A Textual App to display VBAN data."""
def _select_css(self):
if hasattr(self, '_settings') and not self._settings.rich_log:
return 'tui_no_log.tcss'
return 'tui.tcss'
def __init__(self):
self._settings = Settings()
self.CSS_PATH = self._select_css()
super().__init__()
self._command_history = CommandHistory()
self._history_index = None
def compose(self) -> ComposeResult:
"""Create child widgets for the app."""
yield Grid(
LabelInput(
'VBAN Host:',
'localhost',
id='host-labelinput',
label_id='host-label',
input_id='host-input',
),
LabelInput(
'VBAN Port:',
'6980',
id='port-labelinput',
label_id='port-label',
input_id='port-input',
),
LabelInput(
'VBAN Stream Name:',
'Command1',
id='streamname-labelinput',
label_id='streamname-label',
input_id='streamname-input',
),
LabelInput(
'VBAN Command:',
'Enter request',
id='request-labelinput',
label_id='request-label',
input_id='request-input',
),
RichLog(id='response-log'),
id='main-grid',
)
def on_mount(self):
"""Focus the request input on mount."""
self.query_one('#host-input').value = self._settings.host
self.query_one('#port-input').value = str(self._settings.port)
self.query_one('#streamname-input').value = self._settings.streamname
self.query_one('#request-input').focus()
if not self._settings.rich_log:
self.query_one('#response-log').remove()
self.query_one('#main-grid').styles.height = '20'
self.query_one('#main-grid').refresh(layout=True)
def on_key(self, event):
"""Handle key events."""
request_input = self.query_one('#request-input')
match event.key:
case 'q':
self.exit()
case 'enter' if request_input.has_focus:
request_input.add_class('request-sent')
self.send_request()
self.set_timer(0.5, lambda: request_input.remove_class('request-sent'))
value = request_input.value.strip()
if value:
self._command_history.add(value)
self._history_index = None
self.query_one('#request-input').clear()
case 'up' if request_input.has_focus:
if self._command_history:
if self._history_index is None:
self._history_index = len(self._command_history) - 1
elif self._history_index > 0:
self._history_index -= 1
request_input.value = self._command_history.get_previous(
self._history_index
)
case 'down' if request_input.has_focus:
if self._command_history and self._history_index is not None:
if self._history_index < len(self._command_history) - 1:
self._history_index += 1
request_input.value = self._command_history.get_next(
self._history_index
)
else:
self._history_index = None
request_input.value = ''
def send_request(self):
request = self.query_one('#request-input').value.strip()
if request == 'clear':
self.query_one('#response-log').clear()
return
with vban_cmd.api(
'potato',
host=self.query_one('#host-input').value,
port=int(self.query_one('#port-input').value),
streamname=self.query_one('#streamname-input').value,
disable_rt_listeners=True,
) as vban:
if response := vban.sendtext(request):
self.query_one('#response-log').write(response)
def main():
"""Run the VBAN TUI application."""
app = VbanTui()
app.run()