vial/src/main/python/layout_editor.py

140 lines
3.7 KiB
Python
Raw Normal View History

2020-12-20 19:29:48 -05:00
# SPDX-License-Identifier: GPL-2.0-or-later
from PyQt5.QtCore import pyqtSignal
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, cb, container, label):
self.cb = cb
self.choice = False
self.widget_label = QLabel(label)
self.widget_checkbox = QCheckBox()
self.widget_checkbox.stateChanged.connect(self.on_checkbox)
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)
def on_checkbox(self):
self.choice = self.widget_checkbox.isChecked()
self.cb()
class SelectChoice:
def __init__(self, cb, container, label, options):
self.cb = cb
self.choice = 0
self.options = options
self.widget_label = QLabel(label)
self.widget_options = QComboBox()
self.widget_options.addItems(options)
self.widget_options.currentIndexChanged.connect(self.on_selection)
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)
def on_selection(self):
self.choice = self.widget_options.currentIndex()
self.cb()
2020-12-20 19:29:48 -05:00
class LayoutEditor(BasicEditor):
changed = pyqtSignal()
2020-12-20 19:29:48 -05:00
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):
choice = BooleanChoice(self.on_changed, self.container, item)
else:
choice = SelectChoice(self.on_changed, self.container, item[0], item[1:])
self.choices.append(choice)
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)
def on_changed(self):
self.changed.emit()