--- /dev/null
+Textual Widget Docstring template:
+
+"""Widget description
+
+# Reactives
+|name |type |description|
+|--- |--- |--- |
+# Messages
+|name |description|members|member description |
+|--- |--- |--- |--- |
+"""
+
+"""Initialize Widget
+
+# Parameters
+|pos/kw |name |type |description|
+|--- |--- |--- |--- |
+"""
\ No newline at end of file
-"""Provides RecordControls, OBSSettingsPane, and StatsDisplay to obs-ctl"""
+"""Provides RecordControls, OBSSettingsPane, StatsDisplay, and the obs module"""
from .molecule import RecordControls, OBSSettingsPane, StatsDisplay
from . import obs
\ No newline at end of file
+"""Provides BoolControl and TextReadout
+
+Only uses builtins, textual, and maybe log and const."""
from .bool_control import BoolControl
from .text_readout import TextReadout
\ No newline at end of file
from textual.reactive import reactive
from textual.widgets import Button, RadioButton
+from ..message import MSGBase
from ...log import getLogger
logger = getLogger(__name__)
class BoolControl(Container):
"""BoolControl manages a boolean that belongs to something else.
-
+
In other words, it can display true or false and this can be set
on it directly, but its buttons do nothing other than post a
- message. Designed as i/o for an API"""
+ message. Designed as i/o for an API
+
+ # Reactives
+ |name |type |description |
+ |--- |--- |--- |
+ |value |bool |Updates the control's value; turns on or off the light.|
+ |label |str |Updates the label content |
+ |true_label |str |Updates the SetFalse label |
+ |false_label|str |Updates the SetTrue label |
+ |swap_red |bool |Updates the red swappedness |
+ |compact |bool |Updates the compactedness |
+ |layout |str |Updates the layout style |
+ # Messages
+ |name |description |members |member description |
+ |--- |--- |--- |--- |
+ |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 = """
.bool_control--light {
background:$panel;
"bool_control--false_button",
}
value: reactive[bool] = reactive(False)
+ """Updates the control's value; turns on or off the light."""
label: reactive[str] = reactive("Status")
+ """Updates the label content"""
true_label: reactive[str] = reactive("Start")
+ """Updates the SetFalse label"""
false_label: reactive[str] = reactive("Stop")
+ """Updates the SetTrue label"""
swap_red: reactive[bool] = reactive(False)
+ """Updates the red swappedness"""
compact: reactive[bool] = reactive(True)
+ """Updates the compactedness"""
control_layout: reactive[str] = reactive("vertical")
+ """Updates the layout style"""
+
+ class SetTrue(MSGBase):
+ """Posted when the SetTrue button is pressed."""
- class MsgBase(Message):
- control: "BoolControl" = None
- def __init__(self, control: "BoolControl"):
- super().__init__()
- self.control = control
- class SetTrue(MsgBase): ...
- class SetFalse(MsgBase): ...
+ class SetFalse(MSGBase):
+ """Posted when the SetFalse button is pressed."""
def __init__(
self,
value: bool,
+ *args,
label: str = "Boolean",
true_label: str = "Start",
false_label: str = "Stop",
swap_red: bool = False,
compact: bool = True,
- *children,
layout = "vertical",
- name = None,
- id = None,
- classes = None,
- disabled = False,
- markup = True):
- super().__init__(*children, name=name, id=id, classes=classes, disabled=disabled, markup=markup)
+ **kwargs,):
+ """Initialize BoolControl
+
+ # Parameters
+ |pos/kw |name |type |default |description |
+ |--- |--- |--- |--- |--- |
+ |pos/kw |value |bool | |Initial value of the control |
+ |kw |label |str |"Boolean" |Label content |
+ |kw |true_label |str |"Start" |SetTrue button label |
+ |kw |false_label|str |"Stop" |SetFalse button label |
+ |kw |swap_red |bool |False |Styles bool_control--true_button with 'error' instead of --false_button|
+ |kw |compact |bool |True |Sets everything to height:1 and removes borders |
+ |kw |layout |str |"vertical" |Sets layout style |
+ """
+ super().__init__(*args, **kwargs)
self.set_reactive(BoolControl.value, value)
self.set_reactive(BoolControl.label, label)
self.set_reactive(BoolControl.true_label, true_label)
from textual.widgets import Label
class TextReadout(Container):
+ """Simple widget, a labeled label. Subclasses Container.
+
+ # Reactives
+ |name |type |description |
+ |--- |--- |--- |
+ |label |str |Updates the label content |
+ |text |str |Updates the text content |
+ |layout |str |Sets the layout style |
+ # Component Classes
+ text_readout--label
+ text_readout--text
+ """
DEFAULT_CSS = """
TextReadout {
width:1fr;
label = reactive("Label")
readout_layout = reactive("vertical")
- def __init__(self, label, text, *children, layout = "vertical", name = None, id = None, classes = None, disabled = False, markup = True):
- super().__init__(*children, name=name, id=id, classes=classes, disabled=disabled, markup=markup)
+ def __init__(self, label, text, *args, layout = "vertical", **kwargs):
+ """Initialize TextReadout
+
+ # Parameters
+ |pos/kw |name |type |description |
+ |--- |--- |--- |--- |
+ |positional |label |str |Displayed above or to the left of the text |
+ |positional |text |str |Displayed below or to the right of the label |
+ |kw |layout |str |'vertical' or 'horizontal', textual css |
+ """
+ super().__init__(*args, **kwargs)
self.set_reactive(TextReadout.label, label)
self.set_reactive(TextReadout.text, text)
self.set_reactive(TextReadout.readout_layout, layout)
+"""Provides RecordControls, OBSSettingsPane, and StatsDisplay
+
+Uses obs_ctl.interface.element
+"""
from .record_controls import RecordControls
from .settings_pane import OBSSettingsPane
from .stats_display import StatsDisplay
\ No newline at end of file
logger=getLogger(__name__)
class RecordControls(ScrollableContainer):
+ """Holds BoolControls for several OBS WebSocket functions
+
+ # Reactives
+ |name |type |description|
+ |--- |--- |--- |
+ |recording|bool|Whether recording is active|
+ |paused|bool|Whether recording is paused|
+ |streaming|bool|Whether streaming is active|
+ |obsws_connected|bool|Whether obs-ctl is connected to OBS WebSocket|
+ # Messages
+ |name |description|members|member description |
+ |--- |--- |--- |--- |
+ |RecordStarted|Posted when recording is set True.|||
+ |RecordStopped|Posted when recording is set False.|||
+ |RecordPaused|Posted when paused is set True.|||
+ |RecordUnpaused|Posted when paused is set False.|||
+ |StreamStarted|Posted when streaming is set True.|||
+ |StreamStopped|Posted when streaming is set False.|||
+ |OBSWSConnected|Posted when obsws_connected is set True.|||
+ |OBSWSDisconnected|Posted when obsws_disconnected is set False.|||
+ """
DEFAULT_CSS = """
Grid {
grid-size:2;
class StatsDisplay(Container):
+ """Displays information about the OBS WebSocket connection.
+
+ # Component Classes
+ stats_display--cpu
+ stats_display--ram
+ stats_display--hdd
+ stats_display--fps
+ stats_display--dropped_net
+ stats_display--dropped_ren
+ stats_display--dropped_enc
+ """
DEFAULT_CSS="""
StatsDisplay {
Grid {
+"""Provides the OBS WebSocket API widget, 'API', and OBSStats dataclass"""
from obs import API, OBSStats
\ No newline at end of file