vial/src/main/python/layout_editor.py

121 lines
3.2 KiB
Python
Raw Normal View History

2020-12-20 19:29:48 -05:00
# SPDX-License-Identifier: GPL-2.0-or-later
from PyQt5.QtWidgets import QLabel, QCheckBox, QComboBox, QGridLayout
2020-12-20 19:29:48 -05:00
from basic_editor import BasicEditor
from vial_device import VialKeyboard
class BooleanChoice:
def __init__(self, container, label):
self.choice = False
self.widget_label = QLabel(label)
self.widget_checkbox = QCheckBox()
row = container.rowCount()
container.addWidget(self.widget_label, row, 0)
container.addWidget(self.widget_checkbox, row, 1)
def delete(self):
self.widget_label.deleteLater()
self.widget_checkbox.deleteLater()
def pack(self):
return str(int(self.choice))
def unpack(self, value):
self.change(int(value))
def change(self, value):
self.choice = bool(value)
self.widget_checkbox.setChecked(self.choice)
class SelectChoice:
def __init__(self, container, label, options):
self.choice = 0
self.options = options
self.widget_label = QLabel(label)
self.widget_options = QComboBox()
self.widget_options.addItems(options)
row = container.rowCount()
container.addWidget(self.widget_label, row, 0)
container.addWidget(self.widget_options, row, 1)
def delete(self):
self.widget_label.deleteLater()
self.widget_options.deleteLater()
def pack(self):
val = bin(self.choice)[2:]
val = "0" * ((len(self.options) - 1).bit_length() - len(val)) + val
return val
def unpack(self, value):
self.change(int(value, 2))
def change(self, value):
self.choice = value
self.widget_options.setCurrentIndex(self.choice)
2020-12-20 19:29:48 -05:00
class LayoutEditor(BasicEditor):
def __init__(self, parent=None):
super().__init__(parent)
self.device = None
self.choices = []
self.widgets = []
self.container = QGridLayout()
self.addLayout(self.container)
2020-12-20 19:29:48 -05:00
def rebuild(self, device):
super().rebuild(device)
if not self.valid:
return
for choice in self.choices:
choice.delete()
self.choices = []
for item in device.keyboard.layouts["labels"]:
if isinstance(item, str):
self.choices.append(BooleanChoice(self.container, item))
else:
self.choices.append(SelectChoice(self.container, item[0], item[1:]))
self.unpack(self.device.keyboard.layout_options)
2020-12-20 19:29:48 -05:00
def valid(self):
return isinstance(self.device, VialKeyboard) and self.device.keyboard.layouts
def pack(self):
val = ""
for choice in self.choices[::-1]:
val += choice.pack()
return int(val, 2)
def unpack(self, value):
# we operate on bit strings
value = "0" * 100 + bin(value)[2:]
# VIA stores option choices backwards, we need to parse the input in reverse
for choice in self.choices[::-1]:
sz = len(choice.pack())
choice.unpack(value[-sz:])
value = value[:-sz]
def get_choice(self, index):
return int(self.choices[index].pack(), 2)
def set_choice(self, index, value):
self.choices[index].change(value)