diff --git a/src/main/python/any_keycode_dialog.py b/src/main/python/any_keycode_dialog.py new file mode 100644 index 0000000..69b155a --- /dev/null +++ b/src/main/python/any_keycode_dialog.py @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLineEdit, QLabel + +from simpleeval import simple_eval + +from util import tr + + +class AnyKeycodeDialog(QDialog): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.setWindowTitle(tr("AnyKeycodeDialog", "Enter an arbitrary keycode")) + + self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + self.buttons.accepted.connect(self.accept) + self.buttons.rejected.connect(self.reject) + + self.lbl_computed = QLabel() + self.txt_entry = QLineEdit() + self.txt_entry.textChanged.connect(self.on_change) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.txt_entry) + self.layout.addWidget(self.lbl_computed) + self.layout.addWidget(self.buttons) + self.setLayout(self.layout) + + self.value = -1 + self.on_change() + + def on_change(self): + text = self.txt_entry.text() + value = err = None + try: + value = simple_eval(text) + except Exception as e: + err = str(e) + + if not text: + self.value = -1 + self.lbl_computed.setText(tr("AnyKeycodeDialog", "Enter an expression")) + elif err: + self.value = -1 + self.lbl_computed.setText(tr("AnyKeycodeDialog", "Invalid input: {}").format(err)) + elif isinstance(value, int): + self.value = value + self.lbl_computed.setText(tr("AnyKeycodeDialog", "Computed value: 0x{:X}").format(value)) + else: + self.value = -1 + self.lbl_computed.setText(tr("AnyKeycodeDialog", "Invalid input")) + + self.buttons.button(QDialogButtonBox.Ok).setEnabled(self.value != -1) diff --git a/src/main/python/tabbed_keycodes.py b/src/main/python/tabbed_keycodes.py index cb42261..2acd500 100644 --- a/src/main/python/tabbed_keycodes.py +++ b/src/main/python/tabbed_keycodes.py @@ -4,6 +4,7 @@ from PyQt5.QtCore import Qt, QSize, pyqtSignal from PyQt5.QtWidgets import QTabWidget, QWidget, QPushButton, QScrollArea, QApplication from PyQt5.QtGui import QPalette +from any_keycode_dialog import AnyKeycodeDialog from constants import KEYCODE_BTN_RATIO from flowlayout import FlowLayout from keycodes import keycode_tooltip, KEYCODES_BASIC, KEYCODES_ISO, KEYCODES_MACRO, KEYCODES_LAYERS, KEYCODES_QUANTUM, \ @@ -48,6 +49,13 @@ class TabbedKeycodes(QTabWidget): self.layout_layers = layout elif tab == self.tab_macro: self.layout_macro = layout + elif tab == self.tab_basic: + # create the "Any" keycode button + btn = SquareButton() + btn.setText("Any") + btn.setRelSize(KEYCODE_BTN_RATIO) + btn.clicked.connect(self.on_any_keycode) + layout.addWidget(btn) self.widgets += self.create_buttons(layout, keycodes) @@ -103,3 +111,8 @@ class TabbedKeycodes(QTabWidget): label = widget.keycode.label widget.setStyleSheet("QPushButton {}") widget.setText(label.replace("&", "&&")) + + def on_any_keycode(self): + dlg = AnyKeycodeDialog() + if dlg.exec_() and dlg.value >= 0: + self.keycode_changed.emit(dlg.value)