from fbs_runtime.application_context.PyQt5 import ApplicationContext from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QWidget, QTabWidget, QVBoxLayout, QPushButton, QLabel, QComboBox, QToolButton, QHBoxLayout import sys import json import struct import lzma from flowlayout import FlowLayout from util import tr, find_vial_keyboards, open_device, hid_send, MSG_LEN from kle_serial import Serial as KleSerial class TabbedKeycodes(QTabWidget): def __init__(self, parent=None): super().__init__(parent) self.tab_basic = QWidget() layout = FlowLayout() for lbl in ["", "hello", "Esc", "A", "B", "C", "D", "E", "F"]: btn = QPushButton(lbl) btn.setFixedSize(50, 50) layout.addWidget(btn) self.tab_basic.setLayout(layout) self.tab_media = QWidget() self.tab_macro = QWidget() self.addTab(self.tab_basic, tr("TabbedKeycodes", "Basic")) self.addTab(self.tab_media, tr("TabbedKeycodes", "Media")) self.addTab(self.tab_macro, tr("TabbedKeycodes", "Macro")) KEY_WIDTH = 40 KEY_HEIGHT = KEY_WIDTH KEY_SPACING = 4 class KeyboardContainer(QWidget): def __init__(self, parent=None): super().__init__(parent) self.keys = [] def rebuild(self, data): for key in self.keys: key.deleteLater() self.keys = [] serial = KleSerial() kb = serial.deserialize(data["layouts"]["keymap"]) max_w = max_h = 0 for key in kb.keys: widget = QLabel(str(key.labels[0])) widget.setParent(self) widget.setStyleSheet('background-color:white; border: 1px solid black') widget.setAlignment(Qt.AlignCenter) x = (KEY_WIDTH + KEY_SPACING) * key.x y = (KEY_HEIGHT + KEY_SPACING) * key.y w = (KEY_WIDTH + KEY_SPACING) * key.width - KEY_SPACING h = (KEY_HEIGHT + KEY_SPACING) * key.height - KEY_SPACING widget.setFixedSize(w, h) widget.move(x, y) widget.show() # print("{} {}x{}+{}x{}".format(key.labels, key.x, key.y, key.width, key.height)) max_w = max(max_w, x + w) max_h = max(max_h, y + h) self.keys.append(widget) self.setFixedSize(max_w, max_h) class MainWindow(QWidget): def __init__(self): super().__init__() self.device = None self.devices = [] self.keyboard_container = KeyboardContainer() self.tabbed_keycodes = TabbedKeycodes() self.combobox_devices = QComboBox() self.combobox_devices.currentIndexChanged.connect(self.on_device_selected) btn_refresh_devices = QToolButton() btn_refresh_devices.setToolButtonStyle(Qt.ToolButtonTextOnly) btn_refresh_devices.setText(tr("MainWindow", "Refresh")) btn_refresh_devices.clicked.connect(self.on_click_refresh) layout_combobox = QHBoxLayout() layout_combobox.addWidget(self.combobox_devices) layout_combobox.addWidget(btn_refresh_devices) layout = QVBoxLayout() layout.addLayout(layout_combobox) layout.addWidget(self.keyboard_container) layout.setAlignment(self.keyboard_container, Qt.AlignHCenter) layout.addWidget(self.tabbed_keycodes) self.setLayout(layout) # make sure initial state is valid self.on_click_refresh() self.on_device_selected() def on_click_refresh(self): self.devices = find_vial_keyboards() self.combobox_devices.clear() for dev in self.devices: self.combobox_devices.addItem("{} {}".format(dev["manufacturer_string"], dev["product_string"])) def on_device_selected(self): self.device = None idx = self.combobox_devices.currentIndex() if idx >= 0: self.device = open_device(self.devices[idx]) self.reload_layout() def reload_layout(self): """ Requests layout data from the current device """ # get the size data = hid_send(self.device, b"\xFE\x01") sz = struct.unpack(" 0: data = hid_send(self.device, b"\xFE\x02" + struct.pack("