diff --git a/src/main/python/keyboard.py b/src/main/python/keyboard.py index 986bd88..9b9dcc9 100644 --- a/src/main/python/keyboard.py +++ b/src/main/python/keyboard.py @@ -28,7 +28,7 @@ class Keyboard: # n.b. using OrderedDict here to make order of layout requests consistent for tests self.rowcol = OrderedDict() self.layout = dict() - self.layers = 0 + self.rows = self.cols = self.layers = 0 self.keys = [] def reload(self): @@ -65,6 +65,10 @@ class Keyboard: sz -= MSG_LEN payload = json.loads(lzma.decompress(payload)) + + self.rows = payload["matrix"]["rows"] + self.cols = payload["matrix"]["cols"] + serial = KleSerial() kb = serial.deserialize(payload["layouts"]["keymap"]) @@ -93,3 +97,32 @@ class Keyboard: if self.layout[key] != code: self.usb_send(self.dev, struct.pack(">BBBBH", CMD_VIA_SET_KEYCODE, layer, row, col, code)) self.layout[key] = code + + def save_layout(self): + """ Serializes current layout to a binary """ + + # TODO: increase version before release + data = {"version": "0"} + layout = [] + for l in range(self.layers): + layer = [] + layout.append(layer) + for r in range(self.rows): + row = [] + layer.append(row) + for c in range(self.cols): + val = self.layout.get((l, r, c), -1) + row.append(val) + data["layout"] = layout + # TODO: this should also save/restore macros, when implemented + return json.dumps(data).encode("utf-8") + + def restore_layout(self, data): + """ Restores saved layout """ + + data = json.loads(data.decode("utf-8")) + for l, layer in enumerate(data["layout"]): + for r, row in enumerate(layer): + for c, col in enumerate(row): + if (l, r, c) in self.layout: + self.set_key(l, r, c, col) diff --git a/src/main/python/test/test_keyboard.py b/src/main/python/test/test_keyboard.py index 7bb48eb..8c970b3 100644 --- a/src/main/python/test/test_keyboard.py +++ b/src/main/python/test/test_keyboard.py @@ -123,3 +123,19 @@ class TestKeyboard(unittest.TestCase): self.assertEqual(kb.layout[(1, 1, 0)], 9) dev.finish() + + def test_layout_save_restore(self): + """ Tests that layout saving and restore works """ + + kb, dev = self.prepare_keyboard(LAYOUT_2x2, [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + dev.expect("05010100000A", "") + kb.set_key(1, 1, 0, 10) + self.assertEqual(kb.layout[(1, 1, 0)], 10) + data = kb.save_layout() + dev.finish() + + kb, dev = self.prepare_keyboard(LAYOUT_2x2, [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + dev.expect("05010100000A", "") + kb.restore_layout(data) + self.assertEqual(kb.layout[(1, 1, 0)], 10) + dev.finish()