keyboard_comm: save and restore layout/macros in save_layout/restore_layout

main
Ilya Zhuravlev 2020-12-26 20:29:22 -05:00
parent 5d40bec15b
commit b11e0be700
2 changed files with 22 additions and 13 deletions

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import base64
import struct
import json
import lzma
@ -175,15 +175,16 @@ class Keyboard:
self.macro_memory = struct.unpack(">H", data[1:3])[0]
self.macro = b""
# now retrieve the entire buffer, MACRO_CHUNK bytes at a time, as that is what fits into a packet
for x in range(0, self.macro_memory, BUFFER_FETCH_CHUNK):
sz = min(BUFFER_FETCH_CHUNK, self.macro_memory - x)
data = self.usb_send(self.dev, struct.pack(">BHB", CMD_VIA_MACRO_GET_BUFFER, x, sz))
self.macro += data[4:4+sz]
# macros are stored as NUL-separated strings, so let's clean up the buffer
# ensuring we only get macro_count strings after we split by NUL
macros = self.macro.split(b"\x00") + [b""] * self.macro_count
self.macro = b"\x00".join(macros[:self.macro_count]) + b"\x00"
if self.macro_memory:
# now retrieve the entire buffer, MACRO_CHUNK bytes at a time, as that is what fits into a packet
for x in range(0, self.macro_memory, BUFFER_FETCH_CHUNK):
sz = min(BUFFER_FETCH_CHUNK, self.macro_memory - x)
data = self.usb_send(self.dev, struct.pack(">BHB", CMD_VIA_MACRO_GET_BUFFER, x, sz))
self.macro += data[4:4+sz]
# macros are stored as NUL-separated strings, so let's clean up the buffer
# ensuring we only get macro_count strings after we split by NUL
macros = self.macro.split(b"\x00") + [b""] * self.macro_count
self.macro = b"\x00".join(macros[:self.macro_count]) + b"\x00"
def set_key(self, layer, row, col, code):
key = (layer, row, col)
@ -216,6 +217,7 @@ class Keyboard:
""" Serializes current layout to a binary """
# TODO: increase version before release
# TODO: store keyboard UID here as well
data = {"version": 0}
layout = []
for l in range(self.layers):
@ -228,7 +230,8 @@ class Keyboard:
val = self.layout.get((l, r, c), -1)
row.append(val)
data["layout"] = layout
# TODO: this should also save/restore macros, when implemented
data["layout_options"] = self.layout_options
data["macro"] = base64.b64encode(self.macro).decode("utf-8")
return json.dumps(data).encode("utf-8")
def restore_layout(self, data):
@ -240,3 +243,5 @@ class Keyboard:
for c, col in enumerate(row):
if (l, r, c) in self.layout:
self.set_key(l, r, c, col)
self.set_layout_options(data["layout_options"])
self.set_macro(base64.b64decode(data["macro"]))

View File

@ -90,6 +90,7 @@ class MainWindow(QMainWindow):
with open(dialog.selectedFiles()[0], "rb") as inf:
data = inf.read()
self.keymap_editor.restore_layout(data)
self.rebuild()
def on_layout_save(self):
dialog = QFileDialog()
@ -118,11 +119,14 @@ class MainWindow(QMainWindow):
if self.current_device is not None:
self.current_device.open(self.sideload_json if self.current_device.sideload else None)
for e in [self.layout_editor, self.keymap_editor, self.firmware_flasher, self.macro_recorder]:
e.rebuild(self.current_device)
self.rebuild()
self.refresh_tabs()
def rebuild(self):
for e in [self.layout_editor, self.keymap_editor, self.firmware_flasher, self.macro_recorder]:
e.rebuild(self.current_device)
def refresh_tabs(self):
self.tabs.clear()
for container, lbl in self.editors: