Support saving and restoring macros into .vil

main
Ilya Zhuravlev 2021-03-24 00:28:15 -04:00
parent db69e1cd8d
commit 280f981bd9
2 changed files with 77 additions and 6 deletions

View File

@ -383,8 +383,11 @@ class Keyboard:
return json.dumps(data).encode("utf-8")
def save_macro(self):
# TODO: decouple macros from GUI, should be able to serialize/deserialize just with keyboard interface
return []
macros = self.macros_deserialize(self.macro)
out = []
for macro in macros:
out.append([act.save() for act in macro])
return out
def restore_layout(self, data):
""" Restores saved layout """
@ -407,10 +410,29 @@ class Keyboard:
self.set_layout_options(data["layout_options"])
self.restore_macros(data.get("macro"))
def restore_macro(self, macro):
if not isinstance(macro, list):
def restore_macros(self, macros):
if not isinstance(macros, list):
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):
self.usb_send(self.dev, struct.pack("B", 0xB))

View File

@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import struct
from keycodes import Keycode
SS_QMK_PREFIX = 1
SS_TAP_CODE = 1
@ -10,11 +12,23 @@ SS_DELAY_CODE = 4
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):
tag = "text"
def __init__(self, text=""):
super().__init__()
self.text = text
@ -22,9 +36,18 @@ class ActionText(BasicAction):
def serialize(self, vial_protocol):
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):
tag = "unknown-sequence"
def __init__(self, sequence=None):
super().__init__()
if sequence is None:
@ -43,27 +66,46 @@ class ActionSequence(BasicAction):
out += struct.pack("B", k.code)
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):
tag = "down"
def serialize_prefix(self):
return b"\x02"
class ActionUp(ActionSequence):
tag = "up"
def serialize_prefix(self):
return b"\x03"
class ActionTap(ActionSequence):
tag = "tap"
def serialize_prefix(self):
return b"\x01"
class ActionDelay(BasicAction):
tag = "delay"
def __init__(self, delay=0):
super().__init__()
self.delay = delay
@ -73,3 +115,10 @@ class ActionDelay(BasicAction):
raise RuntimeError("ActionDelay can only be used with vial_protocol>=2")
delay = self.delay
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]