Untangle main_window some more

main
Ilya Zhuravlev 2020-12-02 10:10:59 -05:00
parent 80492bc940
commit 2e0de37b77
6 changed files with 114 additions and 42 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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"])