Consolidate legacy pattern ids into meteor, particles, sparkle, chase, and colour_cycle with n6/mode style selection; add pattern_modes helper, self-contained tests/all.py, and preset mode alias on wire. Co-authored-by: Cursor <cursoragent@cursor.com>
145 lines
4.1 KiB
Python
145 lines
4.1 KiB
Python
class Preset:
|
|
def __init__(self, data):
|
|
# Set default values for all preset attributes
|
|
self.p = "off"
|
|
self.d = 100
|
|
self.b = 127
|
|
self.c = [(255, 255, 255)]
|
|
self.a = True
|
|
self.n1 = 0
|
|
self.n2 = 0
|
|
self.n3 = 0
|
|
self.n4 = 0
|
|
self.n5 = 0
|
|
self.n6 = 0
|
|
self.bg = (0, 0, 0)
|
|
|
|
# Override defaults with provided data
|
|
self.edit(data)
|
|
|
|
def edit(self, data=None):
|
|
if not data:
|
|
return False
|
|
aliases = {
|
|
"pattern": "p",
|
|
"colors": "c",
|
|
"delay": "d",
|
|
"brightness": "b",
|
|
"auto": "a",
|
|
"background": "bg",
|
|
"mode": "n6",
|
|
}
|
|
int_fields = {"d", "b", "n1", "n2", "n3", "n4", "n5", "n6"}
|
|
allowed_fields = {"p", "c", "d", "b", "a", "bg", "n1", "n2", "n3", "n4", "n5", "n6"}
|
|
for key, value in data.items():
|
|
key = aliases.get(key, key)
|
|
if key not in allowed_fields:
|
|
continue
|
|
if key in int_fields:
|
|
try:
|
|
parsed = int(value)
|
|
if key == "b":
|
|
parsed = max(0, min(255, parsed))
|
|
elif key in ("d", "n1", "n2", "n3", "n4", "n5", "n6"):
|
|
parsed = max(0, parsed)
|
|
setattr(self, key, parsed)
|
|
except (TypeError, ValueError):
|
|
continue
|
|
elif key == "a":
|
|
if isinstance(value, bool):
|
|
self.a = value
|
|
elif isinstance(value, int):
|
|
self.a = bool(value)
|
|
elif isinstance(value, str):
|
|
lowered = value.lower()
|
|
if lowered in ("true", "1", "yes", "on"):
|
|
self.a = True
|
|
elif lowered in ("false", "0", "no", "off"):
|
|
self.a = False
|
|
elif key == "c":
|
|
if isinstance(value, (list, tuple)):
|
|
self.c = value
|
|
elif key == "bg":
|
|
if isinstance(value, str) and value.startswith("#") and len(value) == 7:
|
|
try:
|
|
self.bg = (
|
|
int(value[1:3], 16),
|
|
int(value[3:5], 16),
|
|
int(value[5:7], 16),
|
|
)
|
|
except (TypeError, ValueError):
|
|
continue
|
|
elif isinstance(value, (list, tuple)) and len(value) == 3:
|
|
try:
|
|
self.bg = tuple(max(0, min(255, int(x))) for x in value)
|
|
except (TypeError, ValueError):
|
|
continue
|
|
else:
|
|
setattr(self, key, value)
|
|
return True
|
|
|
|
@property
|
|
def pattern(self):
|
|
return self.p
|
|
|
|
@pattern.setter
|
|
def pattern(self, value):
|
|
self.p = value
|
|
|
|
@property
|
|
def delay(self):
|
|
return self.d
|
|
|
|
@delay.setter
|
|
def delay(self, value):
|
|
self.d = value
|
|
|
|
@property
|
|
def brightness(self):
|
|
return self.b
|
|
|
|
@brightness.setter
|
|
def brightness(self, value):
|
|
self.b = value
|
|
|
|
@property
|
|
def colors(self):
|
|
return self.c
|
|
|
|
@colors.setter
|
|
def colors(self, value):
|
|
self.c = value
|
|
|
|
@property
|
|
def auto(self):
|
|
return self.a
|
|
|
|
@auto.setter
|
|
def auto(self, value):
|
|
self.a = value
|
|
|
|
def background_or(self, colors=None, default=(0, 0, 0)):
|
|
bg = getattr(self, "bg", None)
|
|
if isinstance(bg, (list, tuple)) and len(bg) == 3:
|
|
try:
|
|
return tuple(max(0, min(255, int(x))) for x in bg)
|
|
except (TypeError, ValueError):
|
|
return default
|
|
return default
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"p": self.p,
|
|
"d": self.d,
|
|
"b": self.b,
|
|
"c": self.c,
|
|
"a": self.a,
|
|
"bg": self.bg,
|
|
"n1": self.n1,
|
|
"n2": self.n2,
|
|
"n3": self.n3,
|
|
"n4": self.n4,
|
|
"n5": self.n5,
|
|
"n6": self.n6,
|
|
}
|