unlocker: show image of keys to hold

main
Ilya Zhuravlev 2020-12-29 14:47:16 -05:00
parent de476ee63c
commit e5487a0ae6
4 changed files with 67 additions and 8 deletions

View File

@ -298,6 +298,18 @@ class Keyboard:
data = self.usb_send(self.dev, struct.pack("BB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_GET_LOCK))
return data[0]
def get_lock_keys(self):
""" Return keys users have to hold to unlock the keyboard as a list of rowcols """
data = self.usb_send(self.dev, struct.pack("BB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_GET_LOCK))
rowcol = []
for x in range(15):
row = data[2 + x * 2]
col = data[3 + x * 2]
if row != 255 and col != 255:
rowcol.append((row, col))
return rowcol
def unlock_start(self):
self.usb_send(self.dev, struct.pack("BB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_UNLOCK_START))

View File

@ -10,6 +10,8 @@ from constants import KEY_WIDTH, KEY_SPACING, KEY_HEIGHT, KEYBOARD_WIDGET_PADDIN
class KeyWidget:
def __init__(self, desc, shift_x=0, shift_y=0):
self.active = False
self.masked = False
self.desc = desc
self.text = ""
self.mask_text = ""
@ -88,6 +90,9 @@ class KeyWidget:
def setToolTip(self, tooltip):
self.tooltip = tooltip
def setActive(self, active):
self.active = active
class EncoderWidget(KeyWidget):
@ -117,6 +122,10 @@ class KeyboardWidget(QWidget):
def __init__(self, layout_editor):
super().__init__()
self.enabled = True
self.scale = 1
self.setMouseTracking(True)
self.layout_editor = layout_editor
@ -192,8 +201,8 @@ class KeyboardWidget(QWidget):
max_w = max_h = 0
for key in self.widgets:
p = key.polygon.boundingRect().bottomRight()
max_w = max(max_w, p.x())
max_h = max(max_h, p.y())
max_w = max(max_w, p.x() * self.scale)
max_h = max(max_h, p.y() * self.scale)
self.width = max_w + 2 * KEYBOARD_WIDGET_PADDING
self.height = max_h + 2 * KEYBOARD_WIDGET_PADDING
@ -231,11 +240,12 @@ class KeyboardWidget(QWidget):
for idx, key in enumerate(self.widgets):
qp.save()
qp.scale(self.scale, self.scale)
qp.translate(key.rotation_x, key.rotation_y)
qp.rotate(key.rotation_angle)
qp.translate(-key.rotation_x, -key.rotation_y)
if self.active_key == key and not self.active_mask:
if key.active or (self.active_key == key and not self.active_mask):
qp.setPen(active_pen)
qp.setBrush(active_brush)
@ -277,6 +287,9 @@ class KeyboardWidget(QWidget):
return None, False
def mousePressEvent(self, ev):
if not self.enabled:
return
self.active_key, self.active_mask = self.hit_test(ev.pos())
if self.active_key is not None:
self.clicked.emit()
@ -299,6 +312,9 @@ class KeyboardWidget(QWidget):
self.update()
def event(self, ev):
if not self.enabled:
super().event(ev)
if ev.type() == QEvent.ToolTip:
key = self.hit_test(ev.pos())[0]
if key is not None:
@ -306,3 +322,9 @@ class KeyboardWidget(QWidget):
else:
QToolTip.hideText()
return super().event(ev)
def set_enabled(self, val):
self.enabled = val
def set_scale(self, scale):
self.scale = scale

View File

@ -19,8 +19,6 @@ class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.unlocker = Unlocker()
self.current_device = None
self.devices = []
self.sideload_json = None
@ -45,6 +43,7 @@ class MainWindow(QMainWindow):
self.editors = [(self.keymap_editor, "Keymap"), (self.layout_editor, "Layout"), (self.macro_recorder, "Macros"),
(self.firmware_flasher, "Firmware updater")]
self.unlocker = Unlocker(self.layout_editor)
self.tabs = QTabWidget()
self.refresh_tabs()

View File

@ -4,12 +4,13 @@ import time
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QProgressBar
from keyboard_widget import KeyboardWidget
from util import tr
class Unlocker(QWidget):
def __init__(self):
def __init__(self, layout_editor):
super().__init__()
self.keyboard = None
@ -23,7 +24,11 @@ class Unlocker(QWidget):
layout.addWidget(QLabel(tr("Unlocker", "Press and hold the following keys until the progress bar "
"below fills up:")))
# TODO: add image/text reference of keys user needs to hold
self.keyboard_reference = KeyboardWidget(layout_editor)
self.keyboard_reference.set_enabled(False)
self.keyboard_reference.set_scale(0.5)
layout.addWidget(self.keyboard_reference)
layout.setAlignment(self.keyboard_reference, Qt.AlignHCenter)
layout.addWidget(self.progress)
@ -36,11 +41,29 @@ class Unlocker(QWidget):
def get(cls):
return cls.obj
def update_reference(self, keyboard):
""" Updates keycap reference image """
self.keyboard_reference.set_keys(keyboard.keys, keyboard.encoders)
# use "active" background to indicate keys to hold
lock_keys = keyboard.get_lock_keys()
for w in self.keyboard_reference.widgets:
if (w.desc.row, w.desc.col) in lock_keys:
w.setActive(True)
self.keyboard_reference.update_layout()
self.keyboard_reference.update()
self.keyboard_reference.updateGeometry()
def perform_unlock(self, keyboard):
# if it's already unlocked, don't need to do anything
if keyboard.get_lock() == 0:
lock = keyboard.get_lock()
if lock == 0:
return
self.update_reference(keyboard)
self.progress.setMaximum(1)
self.progress.setValue(0)
@ -64,3 +87,6 @@ class Unlocker(QWidget):
# ok all done, the keyboard is now set to insecure state
self.hide()
def closeEvent(self, ev):
ev.ignore()