Untangle main_window some more
parent
80492bc940
commit
2e0de37b77
|
|
@ -3,6 +3,7 @@
|
||||||
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QLineEdit, QToolButton, QPlainTextEdit, QProgressBar
|
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QLineEdit, QToolButton, QPlainTextEdit, QProgressBar
|
||||||
|
|
||||||
from util import tr
|
from util import tr
|
||||||
|
from vial_device import VialBootloader
|
||||||
|
|
||||||
|
|
||||||
class FirmwareFlasher(QVBoxLayout):
|
class FirmwareFlasher(QVBoxLayout):
|
||||||
|
|
@ -23,3 +24,11 @@ class FirmwareFlasher(QVBoxLayout):
|
||||||
btn_flash.setText(tr("Flasher", "Flash"))
|
btn_flash.setText(tr("Flasher", "Flash"))
|
||||||
progress_flash.addWidget(btn_flash)
|
progress_flash.addWidget(btn_flash)
|
||||||
self.addLayout(progress_flash)
|
self.addLayout(progress_flash)
|
||||||
|
|
||||||
|
self.device = None
|
||||||
|
|
||||||
|
def rebuild(self, device):
|
||||||
|
self.device = device
|
||||||
|
|
||||||
|
def valid(self):
|
||||||
|
return isinstance(self.device, VialBootloader)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
if sys.platform.startswith("linux"):
|
||||||
|
import hidraw as hid
|
||||||
|
else:
|
||||||
|
import hid
|
||||||
|
|
@ -5,6 +5,7 @@ from PyQt5.QtWidgets import QVBoxLayout
|
||||||
from keyboard_container import KeyboardContainer
|
from keyboard_container import KeyboardContainer
|
||||||
from keycodes import recreate_layer_keycodes
|
from keycodes import recreate_layer_keycodes
|
||||||
from tabbed_keycodes import TabbedKeycodes
|
from tabbed_keycodes import TabbedKeycodes
|
||||||
|
from vial_device import VialKeyboard
|
||||||
|
|
||||||
|
|
||||||
class LayoutEditor(QVBoxLayout):
|
class LayoutEditor(QVBoxLayout):
|
||||||
|
|
@ -21,6 +22,8 @@ class LayoutEditor(QVBoxLayout):
|
||||||
self.addWidget(self.keyboard_container)
|
self.addWidget(self.keyboard_container)
|
||||||
self.addWidget(self.tabbed_keycodes)
|
self.addWidget(self.tabbed_keycodes)
|
||||||
|
|
||||||
|
self.device = None
|
||||||
|
|
||||||
def on_number_layers_changed(self):
|
def on_number_layers_changed(self):
|
||||||
recreate_layer_keycodes(self.keyboard_container.keyboard.layers)
|
recreate_layer_keycodes(self.keyboard_container.keyboard.layers)
|
||||||
self.tabbed_keycodes.recreate_layer_keycode_buttons()
|
self.tabbed_keycodes.recreate_layer_keycode_buttons()
|
||||||
|
|
@ -28,8 +31,13 @@ class LayoutEditor(QVBoxLayout):
|
||||||
def on_keycode_changed(self, code):
|
def on_keycode_changed(self, code):
|
||||||
self.keyboard_container.set_key(code)
|
self.keyboard_container.set_key(code)
|
||||||
|
|
||||||
def rebuild(self, keyboard):
|
def rebuild(self, device):
|
||||||
self.keyboard_container.rebuild(keyboard)
|
self.device = device
|
||||||
|
if isinstance(self.device, VialKeyboard):
|
||||||
|
self.keyboard_container.rebuild(device.keyboard)
|
||||||
|
|
||||||
|
def valid(self):
|
||||||
|
return isinstance(self.device, VialKeyboard)
|
||||||
|
|
||||||
def save_layout(self):
|
def save_layout(self):
|
||||||
return self.keyboard_container.save_layout()
|
return self.keyboard_container.save_layout()
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,15 @@ from PyQt5.QtWidgets import QWidget, QComboBox, QToolButton, QHBoxLayout, QVBoxL
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from firmware_flasher import FirmwareFlasher
|
from firmware_flasher import FirmwareFlasher
|
||||||
from keyboard import Keyboard
|
|
||||||
from layout_editor import LayoutEditor
|
from layout_editor import LayoutEditor
|
||||||
from util import tr, find_vial_keyboards, open_device
|
from util import tr, find_vial_devices
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.keyboard = None
|
self.current_device = None
|
||||||
self.devices = []
|
self.devices = []
|
||||||
self.sideload_json = None
|
self.sideload_json = None
|
||||||
self.sideload_vid = self.sideload_pid = -1
|
self.sideload_vid = self.sideload_pid = -1
|
||||||
|
|
@ -34,17 +33,14 @@ class MainWindow(QMainWindow):
|
||||||
layout_combobox.addWidget(btn_refresh_devices)
|
layout_combobox.addWidget(btn_refresh_devices)
|
||||||
|
|
||||||
self.layout_editor = LayoutEditor()
|
self.layout_editor = LayoutEditor()
|
||||||
flasher = FirmwareFlasher()
|
self.firmware_flasher = FirmwareFlasher()
|
||||||
|
|
||||||
tabs = QTabWidget()
|
self.tabs = QTabWidget()
|
||||||
for container, lbl in [(self.layout_editor, "Layout"), (flasher, "Firmware updater")]:
|
self.refresh_tabs()
|
||||||
w = QWidget()
|
|
||||||
w.setLayout(container)
|
|
||||||
tabs.addTab(w, tr("MainWindow", lbl))
|
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
layout.addLayout(layout_combobox)
|
layout.addLayout(layout_combobox)
|
||||||
layout.addWidget(tabs)
|
layout.addWidget(self.tabs)
|
||||||
w = QWidget()
|
w = QWidget()
|
||||||
w.setLayout(layout)
|
w.setLayout(layout)
|
||||||
self.setCentralWidget(w)
|
self.setCentralWidget(w)
|
||||||
|
|
@ -99,27 +95,37 @@ class MainWindow(QMainWindow):
|
||||||
outf.write(self.layout_editor.save_layout())
|
outf.write(self.layout_editor.save_layout())
|
||||||
|
|
||||||
def on_click_refresh(self):
|
def on_click_refresh(self):
|
||||||
self.devices = find_vial_keyboards(self.sideload_vid, self.sideload_pid)
|
self.devices = find_vial_devices(self.sideload_vid, self.sideload_pid)
|
||||||
self.combobox_devices.clear()
|
self.combobox_devices.clear()
|
||||||
|
|
||||||
for dev in self.devices:
|
for dev in self.devices:
|
||||||
title = "{} {}".format(dev["manufacturer_string"], dev["product_string"])
|
self.combobox_devices.addItem(dev.title())
|
||||||
if dev["vendor_id"] == self.sideload_vid and dev["product_id"] == self.sideload_pid:
|
|
||||||
title += " [sideload]"
|
|
||||||
self.combobox_devices.addItem(title)
|
|
||||||
|
|
||||||
def on_device_selected(self):
|
def on_device_selected(self):
|
||||||
if self.keyboard is not None:
|
if self.current_device is not None:
|
||||||
self.keyboard.dev.close()
|
self.current_device.close()
|
||||||
|
self.current_device = None
|
||||||
idx = self.combobox_devices.currentIndex()
|
idx = self.combobox_devices.currentIndex()
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
dev = self.devices[idx]
|
self.current_device = self.devices[idx]
|
||||||
self.keyboard = Keyboard(open_device(dev))
|
|
||||||
if dev["vendor_id"] == self.sideload_vid and dev["product_id"] == self.sideload_pid:
|
if self.current_device is not None:
|
||||||
self.keyboard.reload(self.sideload_json)
|
self.current_device.open(self.sideload_json if self.current_device.sideload else None)
|
||||||
else:
|
|
||||||
self.keyboard.reload()
|
self.layout_editor.rebuild(self.current_device)
|
||||||
self.layout_editor.rebuild(self.keyboard)
|
self.firmware_flasher.rebuild(self.current_device)
|
||||||
|
|
||||||
|
self.refresh_tabs()
|
||||||
|
|
||||||
|
def refresh_tabs(self):
|
||||||
|
self.tabs.clear()
|
||||||
|
for container, lbl in [(self.layout_editor, "Layout"), (self.firmware_flasher, "Firmware updater")]:
|
||||||
|
if not container.valid():
|
||||||
|
continue
|
||||||
|
|
||||||
|
w = QWidget()
|
||||||
|
w.setLayout(container)
|
||||||
|
self.tabs.addTab(w, tr("MainWindow", lbl))
|
||||||
|
|
||||||
def on_sideload_json(self):
|
def on_sideload_json(self):
|
||||||
dialog = QFileDialog()
|
dialog = QFileDialog()
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,17 @@
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
|
|
||||||
import sys
|
from hidproxy import hid
|
||||||
|
|
||||||
if sys.platform.startswith("linux"):
|
|
||||||
import hidraw as hid
|
|
||||||
else:
|
|
||||||
import hid
|
|
||||||
|
|
||||||
|
|
||||||
tr = QCoreApplication.translate
|
tr = QCoreApplication.translate
|
||||||
|
|
||||||
|
# For Vial keyboard
|
||||||
VIAL_SERIAL_NUMBER_MAGIC = "vial:f64c2b3c"
|
VIAL_SERIAL_NUMBER_MAGIC = "vial:f64c2b3c"
|
||||||
|
|
||||||
|
# For bootloader
|
||||||
|
VIBL_SERIAL_NUMBER_MAGIC = "vibl:d4f8159c"
|
||||||
|
|
||||||
MSG_LEN = 32
|
MSG_LEN = 32
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -33,18 +32,15 @@ def is_rawhid(dev):
|
||||||
return dev["interface_number"] == 1
|
return dev["interface_number"] == 1
|
||||||
|
|
||||||
|
|
||||||
def find_vial_keyboards(sideload_vid, sideload_pid):
|
def find_vial_devices(sideload_vid, sideload_pid):
|
||||||
|
from vial_device import VialBootloader, VialKeyboard
|
||||||
|
|
||||||
filtered = []
|
filtered = []
|
||||||
for dev in hid.enumerate():
|
for dev in hid.enumerate():
|
||||||
if VIAL_SERIAL_NUMBER_MAGIC in dev["serial_number"] and is_rawhid(dev):
|
if VIAL_SERIAL_NUMBER_MAGIC in dev["serial_number"] and is_rawhid(dev):
|
||||||
filtered.append(dev)
|
filtered.append(VialKeyboard(dev))
|
||||||
|
elif VIBL_SERIAL_NUMBER_MAGIC in dev["serial_number"]:
|
||||||
|
filtered.append(VialBootloader(dev))
|
||||||
elif dev["vendor_id"] == sideload_vid and dev["product_id"] == sideload_pid and is_rawhid(dev):
|
elif dev["vendor_id"] == sideload_vid and dev["product_id"] == sideload_pid and is_rawhid(dev):
|
||||||
filtered.append(dev)
|
filtered.append(VialKeyboard(dev, sideload=True))
|
||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
def open_device(desc):
|
|
||||||
# TODO: error handling here
|
|
||||||
dev = hid.device()
|
|
||||||
dev.open_path(desc["path"])
|
|
||||||
return dev
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
from hidproxy import hid
|
||||||
|
from keyboard import Keyboard
|
||||||
|
|
||||||
|
|
||||||
|
class VialDevice:
|
||||||
|
|
||||||
|
def __init__(self, dev):
|
||||||
|
self.desc = dev
|
||||||
|
self.dev = None
|
||||||
|
self.sideload = False
|
||||||
|
|
||||||
|
def open(self, override_json=None):
|
||||||
|
# TODO: error handling here
|
||||||
|
self.dev = hid.device()
|
||||||
|
self.dev.open_path(self.desc["path"])
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.dev.close()
|
||||||
|
|
||||||
|
|
||||||
|
class VialKeyboard(VialDevice):
|
||||||
|
|
||||||
|
def __init__(self, dev, sideload=False):
|
||||||
|
super().__init__(dev)
|
||||||
|
self.sideload = sideload
|
||||||
|
self.keyboard = None
|
||||||
|
|
||||||
|
def open(self, override_json=None):
|
||||||
|
super().open(override_json)
|
||||||
|
self.keyboard = Keyboard(self.dev)
|
||||||
|
self.keyboard.reload(override_json)
|
||||||
|
|
||||||
|
def title(self):
|
||||||
|
s = "{} {}".format(self.desc["manufacturer_string"], self.desc["product_string"])
|
||||||
|
if self.sideload:
|
||||||
|
s += " [sideload]"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
class VialBootloader(VialDevice):
|
||||||
|
|
||||||
|
def title(self):
|
||||||
|
return "Vial Bootloader [{:04X}:{:04X}]".format(self.desc["vendor_id"], self.desc["product_id"])
|
||||||
Loading…
Reference in New Issue