@property
def widget(self):
+ """The widget this SettingsType uses"""
return self.value[0]
@property
def type(self):
+ """The type of the reactive this SettingsType interacts with"""
return self.value[1]
@property
def msg(self):
+ """The message this SettingsType's widget posts when user interacts"""
return self.value[2]
@property
def expected_type(self):
+ """The type this SettingsType's widget expects for its value"""
return self.value[3]
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."""
- DEFAULT_CSS = """
- Grid {
- grid-size:2;
- grid-rows:2;
- }
- """
+ row_height = 2
+ loop_tuple = list(zip(settings_list, settings_type_list, defaults_list))
+ DEFAULT_CSS = f"Grid {{grid-size:2;grid-rows:{row_height};min-height:{len(loop_tuple)*row_height}}}"
def watch_func_factory(watch_id: str):
def watch_func(self, value):
input = self.query_exactly_one(watch_id)
def output_func(self):
with ScrollableContainer():
with Grid():
- for setting, control_and_type, setting_default in zip(settings_list, settings_type_list, defaults_list):
- ctrl_id = f"{settings_type.widget.func.__name__.lower()}_{setting}"
+ for setting, control_and_type, setting_default in loop_tuple:
+ ctrl_id = f"{setting_type.widget.func.__name__.lower()}_{setting}"
yield Label(setting)
yield control_and_type.widget(value=control_and_type.expected_type(setting_default), id=ctrl_id)
return output_func
new_dict = dict()
- for setting, control_and_type, setting_default in zip(settings_list, settings_type_list, defaults_list):
- settings_type: SettingsType = control_and_type
- ctrl_id = f"{settings_type.widget.func.__name__.lower()}_{setting}"
- msg_name = f"{snake_to_camel(setting)}Changed"
- watch_x = f"watch_{setting}"
- on_x = f"on_{setting}_changed"
- new_dict[setting] = reactive(settings_type.type(setting_default)) # eg. record_path
- new_dict[watch_x] = watch_func_factory(f"#{ctrl_id}") # watch_record_path
- new_dict[msg_name] = type(msg_name, (SettingsMSGBase, ), {}) # RecordPathChanged
- new_dict[on_x] = on_func_factory(new_dict[setting], settings_type.msg, new_dict[msg_name], f"#{ctrl_id}") # on_record_path_changed
+ for setting_name, setting_type, setting_default in loop_tuple:
+ setting_name: str = setting_name
+ setting_type: SettingsType = setting_type
+ setting_default: Any = setting_default
+ control_setting_id: str = f"{setting_type.widget.func.__name__.lower()}_{setting_name}"
+ 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'):
+ # Set up a reactive named record_path
+ new_dict[setting_name] = reactive(setting_type.type(setting_default))
+ # Set up a watch_record_path function
+ new_dict[watch_setting_name] = watch_func_factory(f"#{control_setting_id}")
+ # Set up a RecordPathChanged for when user interacts with control
+ # (see SettingTypes enum)
+ new_dict[SettingChanged_name] = type(SettingChanged_name, (SettingsMSGBase, ), {})
+ # Set up on_record_path_changed function to update record_path
+ # and post RecordPathChanged
+ new_dict[on_setting_changed_name] = on_func_factory(new_dict[setting_name], setting_type.msg, new_dict[SettingChanged_name], f"#{control_setting_id}") # on_record_path_changed
+ # Set up the default CSS
new_dict["DEFAULT_CSS"] = DEFAULT_CSS
+ # Set up compose()
new_dict["compose"] = compose_factory() # Adds all the Inputs
+ # Construct the actual class and return it
new_pane = type(cls_name, (TabPane,), new_dict)
-
return new_pane
def snake_to_camel(string: str):