type MakeWidgetOutputType = tuple[str, SettingsWidget, Any, ParamsType]
-def make_settings_widget(name: str, type: SettingsWidget, default: Any, *args, **kwargs) -> MakeWidgetOutputType:
+def make_pane_widget(name: str, type: SettingsWidget, default: Any, *args, **kwargs) -> MakeWidgetOutputType:
return (name, type, default, (args, kwargs))
type ParamsType = tuple[ArgsType, KWArgsType] | None
type ParamsListType = Sequence[ParamsType]
type LoopListType = Sequence[MakeWidgetOutputType]
-def make_pane_subclass(
+def make_pane(
cls_name: str,
- settings_name_list: list[str] | LoopListType,
+ *args,
+ names_list: list[str] | LoopListType | None=None,
settings_type_list: list[SettingsWidget] | None=None,
- settings_default_list: list[Any] | None=None,
- settings_type_params_list: ParamsListType | None=None,
+ defaults_list: list[Any] | None=None,
+ params_list: ParamsListType | None=None,
) -> type[PaneBase]:
"""Creates a new TabPane subclass with cls_name as its name.
-
- settings_list should be a list of names for settings.
- settings_type_list should be a list of pane.SettingsType members
- settings_default_list should be a list of defaults, for the settings.
-
- Returned widget will have appropriate messages for each input field.
-
- For example, pane_factory("Settings", ["record_path"], [pane.SettingsType.STRING], [""])
- will return a TabPane with a Label and an Input box, a reactive attribute "record_path",
- a watch_record_path function to update the Input value, and an on_record_path_changed
- function, which emits a RecordPathChanged message containing a value when the user
- submits the input."""
- row_height = 1
- if settings_type_list is None and settings_default_list is None and settings_type_params_list is None:
- loop_list: LoopListType = settings_name_list # type: ignore
+
+ All the arguments must be keyword arguments, or all of the arguments
+ must be positional pane.make_pane_widget() results.
+
+ If provided:
+ **name_list** must be a list of names for settings.
+ **settings_type_list** must be a list of pane.SettingsType members
+ **default_list** must be a list of defaults, for the settings.
+ **params_list** is optionally a tuple of args and kwarg, passed into
+ the constructor for the particular Textual Widget created.
+ eg: (("foo", "bar"), {"buz":5})
+
+ Returned widget will have appropriate messages for each input field.
+
+ For example:
+ ```python
+ >>> pane_factory("Settings",
+ name_list=["record_path"],
+ settings_type_list=[pane.SettingsType.STRING],
+ defaults_list=[""])
+ ... [TabPane Instance]
+ >>> pane_factory("Settings",
+ pane.make_settings_widget(
+ "record_path",
+ pane.SettingsWidget.STRING,
+ ""))
+ ... [Equivalent (But Not Identical) TabPane Instance]
+ ```
+ The returned a TabPane will have:
+ A reactive attribute "record_path"
+ A watch_record_path function to update the Input's value
+ An on_record_path_changed function, which (upon Input submission) emits ...
+ A RecordPathChanged message containing the submitted value.
+ """
+ # Detect whether this is a "looplist" style input or a parameters style input
+ ROW_HEIGHT = 1
+ if names_list is not None:
+ params_list = params_list if params_list is not None else ( ((), dict()), )
+ loop_list: LoopListType = list(zip_longest(names_list, settings_type_list, defaults_list, params_list)) # type: ignore
else:
- settings_type_params_list = settings_type_params_list if settings_type_params_list is not None else ( ((), dict()), )
- loop_list: LoopListType = list(zip_longest(settings_name_list, settings_type_list, settings_default_list, settings_type_params_list)) # type: ignore
+ loop_list: LoopListType = args # type: ignore
- DEFAULT_CSS = f"Grid {{grid-size:2;grid-rows:{row_height};min-height:{len(loop_list)*row_height}}}"
+ DEFAULT_CSS = f"Grid {{grid-size:2;grid-rows:{ROW_HEIGHT};min-height:{len(loop_list)*ROW_HEIGHT}}}"
def make_watch_reactive(watch_id: str):
def watch_func(self: PaneBase, value: Any):
new_dict: dict[str, Any] = dict()
for setting_name, setting_type, setting_default, _ in loop_list:
control_setting_id: str = f"{setting_type.widget.__name__.lower()}_{setting_name}"
- SettingChanged_name: str = f"{snake_to_camel(setting_name)}Changed"
+ SettingChanged_name: str = f"{_snake_to_camel(setting_name)}Changed"
watch_setting_name: str = f"watch_{setting_name}"
on_setting_changed_name: str = f"on_{setting_name}_changed"
# For each desired setting (e.g. 'record_path'):
new_pane: type[PaneBase] = type(cls_name, (PaneBase,), new_dict)
return new_pane
-def snake_to_camel(string: str):
+def _snake_to_camel(string: str):
return str.join("", [str.capitalize(x) for x in string.split("_")])
\ No newline at end of file
type ParamsType = tuple[ArgsType, KWArgsType]
type ParamsListType = Sequence[ParamsType | None]
@overload
-def make_pane_subclass(
+def make_pane(
cls_name: str,
- settings_list: Sequence[str],
+ *,
+ names_list: Sequence[str],
settings_type_list: Sequence[SettingsWidget],
defaults_list: Sequence[Any],
params_list: ParamsListType | None=None,
) -> type[PaneBase]: ...
@overload
-def make_pane_subclass(
+def make_pane(
cls_name: str,
- settings_list: Sequence[MakeWidgetOutputType],
+ *args: MakeWidgetOutputType,
) -> type[PaneBase]: ...
type MakeWidgetOutputType = tuple[str, SettingsWidget, Any, ParamsType]
-def make_settings_widget(name: str, type: SettingsWidget, default: Any, *args: Any, **kwargs: Any) -> MakeWidgetOutputType: ...
\ No newline at end of file
+def make_pane_widget(name: str, type: SettingsWidget, default: Any, *args: Any, **kwargs: Any) -> MakeWidgetOutputType: ...
\ No newline at end of file
logger = getLogger(__name__)
-OBSSettingsPane = pane.make_pane_subclass(
+OBSSettingsPane = pane.make_pane(
"OBSSettingsPane",
- ["record_path"],
- [pane.SettingsWidget.STRING],
- [""],
- [((), {"compact":True}),]
+ names_list=["record_path"],
+ settings_type_list=[pane.SettingsWidget.STRING],
+ defaults_list=[""],
+ params_list=[((), {"compact":True}),]
)
-OBSWebSocketPane = pane.make_pane_subclass(
+OBSWebSocketPane = pane.make_pane(
"OBSWebSocketPane",
- [
- pane.make_settings_widget("host", pane.SettingsWidget.STRING, "localhost", compact=True),
- pane.make_settings_widget("port", pane.SettingsWidget.INT, 4455, compact=True),
- pane.make_settings_widget("password", pane.SettingsWidget.STRING, "", compact=True),
- pane.make_settings_widget("timeout", pane.SettingsWidget.FLOAT, 1.0, compact=True)
- ]
+ pane.make_pane_widget("host", pane.SettingsWidget.STRING, "localhost", compact=True),
+ pane.make_pane_widget("port", pane.SettingsWidget.INT, 4455, compact=True),
+ pane.make_pane_widget("password", pane.SettingsWidget.STRING, "", compact=True),
+ pane.make_pane_widget("timeout", pane.SettingsWidget.FLOAT, 1.0, compact=True),
)
-OBSCTLPane = pane.make_pane_subclass(
+OBSCTLPane = pane.make_pane(
"OBSCTLPane",
- ["nothing"],
- [pane.SettingsWidget.STRING],
- ["zilch"]
+ names_list=["nothing"],
+ settings_type_list=[pane.SettingsWidget.STRING],
+ defaults_list=["zilch"]
)
class SettingsBlock(Container):