LEDControl / RGBControl: render as Gtk.Switch instead of a 2-option combo (#3215)
LED Control on both 0x8070 (COLOR_LED_EFFECTS) and 0x8071 (RGB_EFFECTS) features is a ChoicesValidator with exactly two values, Device=0 and Solaar=1 — semantically a binary toggle dressed up as a dropdown. Render both as a Gtk.Switch (Solaar=on, Device=off) by swapping ChoicesValidator for BooleanValidator with true_value=1 / false_value=0. BooleanValidator's kind is TOGGLE, which the existing config_panel dispatcher already maps to ToggleControl (Gtk.Switch). No UI plumbing changes required. Add a small _pre_read override to migrate persister entries from the old ChoicesValidator (stored as int 0/1) to bool, so the switch widget gets a value it can pass to Gtk.Switch.set_state(). Tooltip cleanup to match the new styling: - "Switch control of LED zones between device and Solaar" → "Allow Solaar to control LED zones." on both control rows. - "LED Control needs to be set to Solaar to be effective." → "LED Control needs to be enabled." on every dependent setting's tooltip. Setting names (led_control / rgb_control) and persister keys are unchanged; only the YAML value type migrates from int to bool on the next read.
This commit is contained in:
parent
d159081893
commit
fc62ef00ad
|
|
@ -1815,12 +1815,20 @@ class BrightnessControl(settings.Setting):
|
|||
class LEDControl(settings.Setting):
|
||||
name = "led_control"
|
||||
label = _("LED Control")
|
||||
description = _("Switch control of LED zones between device and Solaar")
|
||||
description = _("Allow Solaar to control LED zones.")
|
||||
feature = _F.COLOR_LED_EFFECTS
|
||||
rw_options = {"read_fnid": 0x70, "write_fnid": 0x80}
|
||||
choices_universe = common.NamedInts(Device=0, Solaar=1)
|
||||
validator_class = settings_validator.ChoicesValidator
|
||||
validator_options = {"choices": choices_universe}
|
||||
# Two-state setting — render as a Gtk.Switch rather than a 2-option combo.
|
||||
# true_value=1 / false_value=0 are the wire bytes for Solaar / Device mode.
|
||||
validator_class = settings_validator.BooleanValidator
|
||||
validator_options = {"true_value": 1, "false_value": 0}
|
||||
|
||||
def _pre_read(self, cached, key=None):
|
||||
# Migrate legacy int values (0/1) stored under the old ChoicesValidator
|
||||
# to bool so the switch widget gets a value it can set_state() on.
|
||||
super()._pre_read(cached, key)
|
||||
if isinstance(self._value, int) and not isinstance(self._value, bool):
|
||||
self._value = self._value != 0
|
||||
|
||||
|
||||
colors = special_keys.COLORS
|
||||
|
|
@ -1831,7 +1839,7 @@ _LEDP = hidpp20.LEDParam
|
|||
class LEDZoneSetting(settings.Setting):
|
||||
name = "led_zone_" # the trailing underscore signals that this setting creates other settings
|
||||
label = _("LED Zone Effects")
|
||||
description = _("Set effect for LED Zone") + "\n" + _("LED Control needs to be set to Solaar to be effective.")
|
||||
description = _("Set effect for LED Zone") + "\n" + _("LED Control needs to be enabled.")
|
||||
feature = _F.COLOR_LED_EFFECTS
|
||||
color_field = {"name": _LEDP.color, "kind": settings.Kind.COLOR, "label": _("Color")}
|
||||
speed_field = {"name": _LEDP.speed, "kind": settings.Kind.RANGE, "label": _("Speed"), "min": 0, "max": 255}
|
||||
|
|
@ -1868,18 +1876,27 @@ class LEDZoneSetting(settings.Setting):
|
|||
class RGBControl(settings.Setting):
|
||||
name = "rgb_control"
|
||||
label = _("LED Control")
|
||||
description = _("Switch control of LED zones between device and Solaar")
|
||||
description = _("Allow Solaar to control LED zones.")
|
||||
feature = _F.RGB_EFFECTS
|
||||
rw_options = {"read_fnid": 0x50, "write_fnid": 0x50}
|
||||
choices_universe = common.NamedInts(Device=0, Solaar=1)
|
||||
validator_class = settings_validator.ChoicesValidator
|
||||
validator_options = {"choices": choices_universe, "write_prefix_bytes": b"\x01", "read_skip_byte_count": 1}
|
||||
# Two-state setting — render as a Gtk.Switch rather than a 2-option combo.
|
||||
# true_value=1 / false_value=0 are the wire bytes for Solaar / Device mode
|
||||
# returned by GetSWControl after the 1-byte sub-fn echo.
|
||||
validator_class = settings_validator.BooleanValidator
|
||||
validator_options = {"true_value": 1, "false_value": 0, "write_prefix_bytes": b"\x01", "read_skip_byte_count": 1}
|
||||
|
||||
def _pre_read(self, cached, key=None):
|
||||
# Migrate legacy int values (0/1) stored under the old ChoicesValidator
|
||||
# to bool so the switch widget gets a value it can set_state() on.
|
||||
super()._pre_read(cached, key)
|
||||
if isinstance(self._value, int) and not isinstance(self._value, bool):
|
||||
self._value = self._value != 0
|
||||
|
||||
|
||||
class RGBEffectSetting(LEDZoneSetting):
|
||||
name = "rgb_zone_" # the trailing underscore signals that this setting creates other settings
|
||||
label = _("LED Zone Effects")
|
||||
description = _("Set effect for LED Zone") + "\n" + _("LED Control needs to be set to Solaar to be effective.")
|
||||
description = _("Set effect for LED Zone") + "\n" + _("LED Control needs to be enabled.")
|
||||
feature = _F.RGB_EFFECTS
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ simple_tests = [
|
|||
fake_hidpp.Response("0A", 0x0420, "0A"),
|
||||
),
|
||||
Setup(
|
||||
FeatureTest(settings_templates.LEDControl, 0, 1),
|
||||
FeatureTest(settings_templates.LEDControl, False, True),
|
||||
fake_hidpp.Response("00", 0x0470),
|
||||
fake_hidpp.Response("01", 0x0480, "01"),
|
||||
),
|
||||
|
|
@ -295,7 +295,7 @@ simple_tests = [
|
|||
fake_hidpp.Response("000000000000000101500000", 0x0430, "000000000000000101500000"),
|
||||
),
|
||||
Setup(
|
||||
FeatureTest(settings_templates.RGBControl, 0, 1),
|
||||
FeatureTest(settings_templates.RGBControl, False, True),
|
||||
fake_hidpp.Response("0000", 0x0450),
|
||||
fake_hidpp.Response("010100", 0x0450, "0101"),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue