Support saving and restoring macros into .vil
parent
db69e1cd8d
commit
280f981bd9
|
|
@ -383,8 +383,11 @@ class Keyboard:
|
||||||
return json.dumps(data).encode("utf-8")
|
return json.dumps(data).encode("utf-8")
|
||||||
|
|
||||||
def save_macro(self):
|
def save_macro(self):
|
||||||
# TODO: decouple macros from GUI, should be able to serialize/deserialize just with keyboard interface
|
macros = self.macros_deserialize(self.macro)
|
||||||
return []
|
out = []
|
||||||
|
for macro in macros:
|
||||||
|
out.append([act.save() for act in macro])
|
||||||
|
return out
|
||||||
|
|
||||||
def restore_layout(self, data):
|
def restore_layout(self, data):
|
||||||
""" Restores saved layout """
|
""" Restores saved layout """
|
||||||
|
|
@ -407,10 +410,29 @@ class Keyboard:
|
||||||
self.set_layout_options(data["layout_options"])
|
self.set_layout_options(data["layout_options"])
|
||||||
self.restore_macros(data.get("macro"))
|
self.restore_macros(data.get("macro"))
|
||||||
|
|
||||||
def restore_macro(self, macro):
|
def restore_macros(self, macros):
|
||||||
if not isinstance(macro, list):
|
if not isinstance(macros, list):
|
||||||
return
|
return
|
||||||
print(macro)
|
tag_to_action = {
|
||||||
|
"down": ActionDown,
|
||||||
|
"up": ActionUp,
|
||||||
|
"tap": ActionTap,
|
||||||
|
"text": ActionText,
|
||||||
|
"delay": ActionDelay,
|
||||||
|
}
|
||||||
|
full_macro = []
|
||||||
|
for macro in macros:
|
||||||
|
actions = []
|
||||||
|
for act in macro:
|
||||||
|
if act[0] in tag_to_action:
|
||||||
|
obj = tag_to_action[act[0]]()
|
||||||
|
obj.restore(act)
|
||||||
|
actions.append(obj)
|
||||||
|
full_macro.append(actions)
|
||||||
|
if len(full_macro) < self.macro_count:
|
||||||
|
full_macro += [[] for x in range(self.macro_count - len(full_macro))]
|
||||||
|
full_macro = full_macro[:self.macro_count]
|
||||||
|
self.set_macro(self.macros_serialize(full_macro))
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.usb_send(self.dev, struct.pack("B", 0xB))
|
self.usb_send(self.dev, struct.pack("B", 0xB))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
from keycodes import Keycode
|
||||||
|
|
||||||
SS_QMK_PREFIX = 1
|
SS_QMK_PREFIX = 1
|
||||||
|
|
||||||
SS_TAP_CODE = 1
|
SS_TAP_CODE = 1
|
||||||
|
|
@ -10,11 +12,23 @@ SS_DELAY_CODE = 4
|
||||||
|
|
||||||
|
|
||||||
class BasicAction:
|
class BasicAction:
|
||||||
pass
|
|
||||||
|
tag = "unknown"
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
return [self.tag]
|
||||||
|
|
||||||
|
def restore(self, act):
|
||||||
|
if self.tag != act[0]:
|
||||||
|
raise RuntimeError("cannot restore {}: expected tag={} got tag={}".format(
|
||||||
|
self, self.tag, act[0]
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class ActionText(BasicAction):
|
class ActionText(BasicAction):
|
||||||
|
|
||||||
|
tag = "text"
|
||||||
|
|
||||||
def __init__(self, text=""):
|
def __init__(self, text=""):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.text = text
|
self.text = text
|
||||||
|
|
@ -22,9 +36,18 @@ class ActionText(BasicAction):
|
||||||
def serialize(self, vial_protocol):
|
def serialize(self, vial_protocol):
|
||||||
return self.text.encode("utf-8")
|
return self.text.encode("utf-8")
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
return super().save() + [self.text]
|
||||||
|
|
||||||
|
def restore(self, act):
|
||||||
|
super().restore(act)
|
||||||
|
self.text = act[1]
|
||||||
|
|
||||||
|
|
||||||
class ActionSequence(BasicAction):
|
class ActionSequence(BasicAction):
|
||||||
|
|
||||||
|
tag = "unknown-sequence"
|
||||||
|
|
||||||
def __init__(self, sequence=None):
|
def __init__(self, sequence=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
if sequence is None:
|
if sequence is None:
|
||||||
|
|
@ -43,27 +66,46 @@ class ActionSequence(BasicAction):
|
||||||
out += struct.pack("B", k.code)
|
out += struct.pack("B", k.code)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
out = super().save()
|
||||||
|
for k in self.sequence:
|
||||||
|
out.append(k.qmk_id)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def restore(self, act):
|
||||||
|
super().restore(act)
|
||||||
|
for qmk_id in act[1:]:
|
||||||
|
self.sequence.append(Keycode.find_by_qmk_id(qmk_id))
|
||||||
|
|
||||||
|
|
||||||
class ActionDown(ActionSequence):
|
class ActionDown(ActionSequence):
|
||||||
|
|
||||||
|
tag = "down"
|
||||||
|
|
||||||
def serialize_prefix(self):
|
def serialize_prefix(self):
|
||||||
return b"\x02"
|
return b"\x02"
|
||||||
|
|
||||||
|
|
||||||
class ActionUp(ActionSequence):
|
class ActionUp(ActionSequence):
|
||||||
|
|
||||||
|
tag = "up"
|
||||||
|
|
||||||
def serialize_prefix(self):
|
def serialize_prefix(self):
|
||||||
return b"\x03"
|
return b"\x03"
|
||||||
|
|
||||||
|
|
||||||
class ActionTap(ActionSequence):
|
class ActionTap(ActionSequence):
|
||||||
|
|
||||||
|
tag = "tap"
|
||||||
|
|
||||||
def serialize_prefix(self):
|
def serialize_prefix(self):
|
||||||
return b"\x01"
|
return b"\x01"
|
||||||
|
|
||||||
|
|
||||||
class ActionDelay(BasicAction):
|
class ActionDelay(BasicAction):
|
||||||
|
|
||||||
|
tag = "delay"
|
||||||
|
|
||||||
def __init__(self, delay=0):
|
def __init__(self, delay=0):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
|
@ -73,3 +115,10 @@ class ActionDelay(BasicAction):
|
||||||
raise RuntimeError("ActionDelay can only be used with vial_protocol>=2")
|
raise RuntimeError("ActionDelay can only be used with vial_protocol>=2")
|
||||||
delay = self.delay
|
delay = self.delay
|
||||||
return struct.pack("BBBB", SS_QMK_PREFIX, SS_DELAY_CODE, (delay % 255) + 1, (delay // 255) + 1)
|
return struct.pack("BBBB", SS_QMK_PREFIX, SS_DELAY_CODE, (delay % 255) + 1, (delay // 255) + 1)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
return super().save() + [self.delay]
|
||||||
|
|
||||||
|
def restore(self, act):
|
||||||
|
super().restore(act)
|
||||||
|
self.delay = act[1]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue