From: sbkelley Date: Wed, 3 Dec 2025 17:28:52 +0000 (-0500) Subject: Including CSS readability X-Git-Url: https://skyeroc.xyz/gitweb/?a=commitdiff_plain;h=6c6cd8b1b9837e8500c39588e87a02702b2d09ff;p=obs-ctl Including CSS readability --- diff --git a/src/obs_ctl/app.py b/src/obs_ctl/app.py index 092e877..da20684 100644 --- a/src/obs_ctl/app.py +++ b/src/obs_ctl/app.py @@ -3,7 +3,7 @@ from logging import getLogger from textual import on from textual.app import App -from textual.containers import HorizontalGroup, ScrollableContainer +from textual.containers import HorizontalGroup, VerticalGroup from textual.widgets import Footer, Header # need to import log to initalize logging @@ -14,6 +14,8 @@ logger = getLogger(__name__) class OBSCtlApp(App): + DEFAULT_CSS = """ + """ CSS_PATH = importlib.resources.files(data).joinpath("layout.tcss") def compose(self): @@ -21,10 +23,11 @@ class OBSCtlApp(App): yield Footer() yield obs.API(1, id="api") logger.debug("Composing OBSCtlApp") - with HorizontalGroup(id="top_block", classes="block"): - yield RecordControls(id="record_controls", classes="section") - yield SettingsBlock(id="settings_container", classes="section") - yield StatsDisplay(id="stats_display", classes="section") + with VerticalGroup(classes="content"): + with HorizontalGroup(id="top_block", classes="block"): + yield RecordControls(id="record_controls", classes="section") + yield SettingsBlock(id="settings_container", classes="section") + yield StatsDisplay(id="stats_display", classes="section") @on(obs.API.Report, "#api") diff --git a/src/obs_ctl/data/layout.tcss b/src/obs_ctl/data/layout.tcss index 1dfc21d..0e080c8 100644 --- a/src/obs_ctl/data/layout.tcss +++ b/src/obs_ctl/data/layout.tcss @@ -1,57 +1,80 @@ # ------ # Layout # ------ -#top_block { - height:3fr; - min-height:10; - max-height:30; - RecordControls { /** ScrollContainer */ - .record_controls--content { - height:10; - min-width:30; - grid-size:2; +Screen { + overflow-x:auto; + .content { /** VerticalGroup */ + /** Gets this small before being scrollable */ + min-width:74; + min-height:20; + /** --------------------------------------- */ + #top_block { /** HorizontalGroup */ + min-height:10; + max-height:14; + RecordControls { /** RecordControls (ScrollableContainer) DEFAULT_CSS */ + align:center middle; + min-width:24; + max-width:48; + .record_controls--content { /** Grid */ + height:10; + min-width:36; + grid-size:2; + .bool_control--light{ /** RadioButton */ + width:16; + text-align:center; + } + } + } + SettingsBlock { /** Container */ + min-width:50; + .obs_settings_pane--content { + grid-size:2 1; + grid-columns:16 1fr; + min-width:36; + } + } } - } - SettingsBlock { /** Container */ - .obs_settings_pane--content { - grid-size:2 1; - grid-columns:16 1fr; - min-width:36; + + StatsDisplay { /** StatsDisplay (ScrollableContainer) DEFAULT_CSS */ + align:left middle; + min-height:9; + max-height:18; + min-width:33; + .stats_display--content { /** Grid */ + grid-size:12; + min-height:8; + max-height:12; + min-width:75; + max-width:100; + .stats_display--top { /** TextReadout */ + column-span:3; + } + .stats_display--bottom { /** TextReadout */ + column-span:4; + } + TextReadout { /** Container */ + .text_readout--readout { /** Label (both) */ + align-horizontal:center; + } + .text_readout--label { /** Label (top) */ + align-vertical:bottom; + } + } + + } } } } -StatsDisplay { - height:5fr; - min-height:10; - max-height:30; - - .stats_display--content { - grid-size:12; - min-height:8; - max-height:12; - min-width:77; - } - - .stats_display--top { - column-span:3; - } - - .stats_display--bottom { - column-span:4; - } -} # ---------- # Aesthetics # ---------- RecordControls { - align:center middle; border:solid $secondary; padding:0 1; .bool_control--light { background:$panel; - align:center bottom; } .record_controls--output_control { @@ -86,21 +109,13 @@ SettingsBlock { } StatsDisplay { - align:center middle; border:solid $secondary; padding:1 2; -} - -TextReadout { - background:$surface; - border:solid $primary; - - .text_readout--readout { - align-horizontal:center; - background:$panel; - } - - .text_readout--label { - align-vertical:bottom; + TextReadout { + background:$surface; + border:solid $primary; + .text_readout--readout { + background:$panel; + } } -} \ No newline at end of file +} diff --git a/src/obs_ctl/interface/element/bool_control.py b/src/obs_ctl/interface/element/bool_control.py index 3003204..97d2dc5 100644 --- a/src/obs_ctl/interface/element/bool_control.py +++ b/src/obs_ctl/interface/element/bool_control.py @@ -1,6 +1,6 @@ from textual import on from textual.app import ComposeResult -from textual.containers import Container +from textual import containers from textual.message import Message from textual.reactive import reactive from textual.widgets import Button, RadioButton @@ -10,7 +10,7 @@ from logging import getLogger logger = getLogger(__name__) -class BoolControl(Container): +class BoolControl(containers.Container): """BoolControl manages a boolean that belongs to something else. In other words, it can display true or false and this can be set @@ -33,22 +33,20 @@ class BoolControl(Container): |SetTrue|The SetTrue button was clicked ||| |SetFalse|The SetFalse button was clicked ||| # Component Classes - bool_control--light - bool_control--true_button - bool_control--false_button - """ - - DEFAULT_CSS = """ - BoolControl { - Button { - width:1fr; - } - } + bool_control--light (RadioButton) + bool_control--true_button (Button) + bool_control--false_button (Button) + bool_control--buttons (Button) + bool_control--lightbox (Center) + bool_control--buttonbox (Center) """ COMPONENT_CLASSES = { "bool_control--light", "bool_control--true_button", "bool_control--false_button", + "bool_control--buttons", + "bool_control--light_box", + "bool_control--buttons_box", } value: reactive[bool] = reactive(False) """Updates the control's value; turns on or off the light.""" @@ -106,7 +104,7 @@ class BoolControl(Container): self.set_reactive(BoolControl.control_layout, layout) def compose(self) -> ComposeResult: - with Container(classes="bool_control--light"): + with containers.Center(classes="bool_control--light_box"): yield RadioButton( label="", value=False, @@ -116,20 +114,21 @@ class BoolControl(Container): disabled=True, classes="bool_control--light", ) - yield Button( - label="Start", - id="true", - variant="success", - compact=True, - classes="bool_control--true_button" - ) - yield Button( - label="Stop", - id="false", - variant="error", - compact=True, - classes = "bool_control--false_button" - ) + with containers.Center(classes="bool_control--buttons_box bool_control--box"): + yield Button( + label="Start", + id="true", + variant="success", + compact=True, + classes="bool_control--buttons bool_control--true_button" + ) + yield Button( + label="Stop", + id="false", + variant="error", + compact=True, + classes = "bool_control--buttons bool_control--false_button" + ) def _on_mount(self, event): diff --git a/src/obs_ctl/interface/molecule/record_controls.py b/src/obs_ctl/interface/molecule/record_controls.py index 8e471af..71333c0 100644 --- a/src/obs_ctl/interface/molecule/record_controls.py +++ b/src/obs_ctl/interface/molecule/record_controls.py @@ -27,17 +27,24 @@ class RecordControls(ScrollableContainer): |StreamStopped|Posted when streaming is set False.||| |OBSWSConnected|Posted when obsws_connected is set True.||| |OBSWSDisconnected|Posted when obsws_disconnected is set False.||| + # Component Classes + record_controls--content (Grid) + record_controls--control (BoolControl) + record_controls--obsws_control (BoolControl) + record_controls--output_control (BoolControl) + record_controls--record_control (BoolControl) + record_controls--stream_control (BoolControl) + record_controls--pause_control (BoolControl) """ - DEFAULT_CSS = """ - .record_controls--content { - height:auto; - } - """ + COMPONENT_CLASSES = { "record_controls--control", "record_controls--output_control", "record_controls--obsws_control", - "record_controls--content" + "record_controls--content", + "record_controls--record_control", + "record_controls--stream_control", + "record_controls--pause_control", } recording: reactive[bool] = reactive(False) paused: reactive[bool] = reactive(False) @@ -64,8 +71,8 @@ class RecordControls(ScrollableContainer): id="obsws_control", classes = "record_controls--control record_controls--obsws_control" ) - yield BoolControl(False, label="Record", id="record_control", classes="record_controls--control record_controls--output_control") - yield BoolControl(False, label="Stream", id="stream_control", classes="record_controls--control record_controls--output_control") + yield BoolControl(False, label="Record", id="record_control", classes="record_controls--control record_controls--output_control record_controls--record_control") + yield BoolControl(False, label="Stream", id="stream_control", classes="record_controls--control record_controls--output_control record_controls--stream_control") yield BoolControl( False, label="Pause", @@ -73,7 +80,7 @@ class RecordControls(ScrollableContainer): false_label="Unpause", swap_red=True, id="pause_control", - classes="record_controls--control record_controls--output_control" + classes="record_controls--control record_controls--output_control record_controls--pause_control" )