qmk_settings: store settings as json

main
Ilya Zhuravlev 2021-06-30 23:20:18 -04:00
parent 49948a7e76
commit 2fd8a0a7d0
4 changed files with 138 additions and 25 deletions

View File

@ -64,7 +64,7 @@ if __name__ == '__main__':
appctxt = ApplicationContext() # 1. Instantiate ApplicationContext appctxt = ApplicationContext() # 1. Instantiate ApplicationContext
init_logger() init_logger()
qt_exception_hook = UncaughtHook() qt_exception_hook = UncaughtHook()
window = MainWindow() window = MainWindow(appctxt)
window.resize(WINDOW_WIDTH, WINDOW_HEIGHT) window.resize(WINDOW_WIDTH, WINDOW_HEIGHT)
window.show() window.show()
exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_()

View File

@ -28,8 +28,9 @@ import themes
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self): def __init__(self, appctx):
super().__init__() super().__init__()
self.appctx = appctx
self.settings = QSettings("Vial", "Vial") self.settings = QSettings("Vial", "Vial")
themes.set_theme(self.get_theme()) themes.set_theme(self.get_theme())
@ -57,7 +58,7 @@ class MainWindow(QMainWindow):
self.keymap_editor = KeymapEditor(self.layout_editor) self.keymap_editor = KeymapEditor(self.layout_editor)
self.firmware_flasher = FirmwareFlasher(self) self.firmware_flasher = FirmwareFlasher(self)
self.macro_recorder = MacroRecorder() self.macro_recorder = MacroRecorder()
self.qmk_settings = QmkSettings() self.qmk_settings = QmkSettings(self.appctx)
self.matrix_tester = MatrixTest(self.layout_editor) self.matrix_tester = MatrixTest(self.layout_editor)
self.rgb_configurator = RGBConfigurator() self.rgb_configurator = RGBConfigurator()

View File

@ -1,41 +1,105 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
import json
import struct import struct
from PyQt5 import QtCore from PyQt5 import QtCore
from PyQt5.QtWidgets import QVBoxLayout, QCheckBox, QGridLayout, QLabel, QWidget, QSizePolicy from PyQt5.QtWidgets import QVBoxLayout, QCheckBox, QGridLayout, QLabel, QWidget, QSizePolicy, QTabWidget, QSpinBox, \
QHBoxLayout, QPushButton
from basic_editor import BasicEditor from basic_editor import BasicEditor
from vial_device import VialKeyboard from vial_device import VialKeyboard
class GenericOption:
def __init__(self, option, container):
self.row = container.rowCount()
self.option = option
self.container = container
self.container.addWidget(QLabel(option["title"]), self.row, 0)
class BooleanOption(GenericOption):
def __init__(self, option, container):
super().__init__(option, container)
self.checkbox = QCheckBox()
self.container.addWidget(self.checkbox, self.row, 1)
class IntegerOption(GenericOption):
def __init__(self, option ,container):
super().__init__(option, container)
self.spinbox = QSpinBox()
self.container.addWidget(self.spinbox, self.row, 1)
class QmkSettings(BasicEditor): class QmkSettings(BasicEditor):
def __init__(self): def __init__(self, appctx):
super().__init__() super().__init__()
self.appctx = appctx
w = QWidget()
w.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
self.container = QGridLayout()
w.setLayout(self.container)
self.addWidget(w)
self.setAlignment(w, QtCore.Qt.AlignHCenter)
self.container.addWidget(QLabel("Always send Escape if Alt is pressed"), 0, 0)
self.container.addWidget(QCheckBox(), 0, 1)
self.container.addWidget(QLabel("Always send Escape if Control is pressed"), 1, 0)
self.chk_ctrl = QCheckBox()
self.chk_ctrl.stateChanged.connect(self.on_checked)
self.container.addWidget(self.chk_ctrl, 1, 1)
self.container.addWidget(QLabel("Always send Escape if GUI is pressed"), 2, 0)
self.container.addWidget(QCheckBox(), 2, 1)
self.container.addWidget(QLabel("Always send Escape if Shift is pressed"), 3, 0)
self.container.addWidget(QCheckBox(), 3, 1)
self.keyboard = None self.keyboard = None
self.tabs_widget = QTabWidget()
self.addWidget(self.tabs_widget)
buttons = QHBoxLayout()
buttons.addStretch()
buttons.addWidget(QPushButton("Save"))
buttons.addWidget(QPushButton("Undo"))
buttons.addWidget(QPushButton("Reset"))
self.addLayout(buttons)
self.tabs = []
self.create_gui()
@staticmethod
def populate_tab(tab, container):
options = []
for field in tab["fields"]:
if field["type"] == "boolean":
options.append(BooleanOption(field, container))
elif field["type"] == "integer":
options.append(IntegerOption(field, container))
else:
raise RuntimeError("unsupported field type: {}".format(field))
return options
def create_gui(self):
with open(self.appctx.get_resource("qmk_settings.json"), "r") as inf:
settings = json.load(inf)
for tab in settings["tabs"]:
w = QWidget()
w.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
container = QGridLayout()
w.setLayout(container)
l = QVBoxLayout()
l.addWidget(w)
l.setAlignment(w, QtCore.Qt.AlignHCenter)
w2 = QWidget()
w2.setLayout(l)
self.tabs_widget.addTab(w2, tab["name"])
self.tabs.append(self.populate_tab(tab, container))
# self.container.addWidget(QLabel("Always send Escape if Alt is pressed"), 0, 0)
# self.container.addWidget(QCheckBox(), 0, 1)
# self.container.addWidget(QLabel("Always send Escape if Control is pressed"), 1, 0)
# self.chk_ctrl = QCheckBox()
# self.chk_ctrl.stateChanged.connect(self.on_checked)
# self.container.addWidget(self.chk_ctrl, 1, 1)
# self.container.addWidget(QLabel("Always send Escape if GUI is pressed"), 2, 0)
# self.container.addWidget(QCheckBox(), 2, 1)
# self.container.addWidget(QLabel("Always send Escape if Shift is pressed"), 3, 0)
# self.container.addWidget(QCheckBox(), 3, 1)
def reload_settings(self): def reload_settings(self):
gresc = self.keyboard.qmk_settings_get(1)[0] gresc = self.keyboard.qmk_settings_get(1)[0]
self.chk_ctrl.setChecked(gresc & 2) # self.chk_ctrl.setChecked(gresc & 2)
def on_checked(self, state): def on_checked(self, state):
data = struct.pack("B", int(self.chk_ctrl.isChecked()) * 2) data = struct.pack("B", int(self.chk_ctrl.isChecked()) * 2)

View File

@ -0,0 +1,48 @@
{
"tabs": [
{
"name": "Grave Escape",
"fields": [
{ "type": "boolean", "title": "Always send Escape if Alt is pressed", "qsid": 1, "bit": 0 },
{ "type": "boolean", "title": "Always send Escape if Control is pressed", "qsid": 1, "bit": 1 },
{ "type": "boolean", "title": "Always send Escape if GUI is pressed", "qsid": 1, "bit": 2 },
{ "type": "boolean", "title": "Always send Escape if Shift is pressed", "qsid": 1, "bit": 3 }
]
},
{
"name": "Debounce",
"fields": [
{ "type": "integer", "title": "Debounce time (ms)", "qsid": 2, "min": 0, "max": 1000 }
]
},
{
"name": "Auto Shift",
"fields": [
{ "type": "boolean", "title": "Enable", "qsid": 3, "bit": 0 },
{ "type": "boolean", "title": "Enable for modifiers", "qsid": 3, "bit": 1 },
{ "type": "integer", "title": "Timeout", "qsid": 4, "min": 0, "max": 1000 },
{ "type": "boolean", "title": "Do not Auto Shift special keys", "qsid": 3, "bit": 2 },
{ "type": "boolean", "title": "Do not Auto Shift numeric keys", "qsid": 3, "bit": 3 },
{ "type": "boolean", "title": "Do not Auto Shift alpha characters", "qsid": 3, "bit": 4 },
{ "type": "boolean", "title": "Enable keyrepeat", "qsid": 3, "bit": 5 },
{ "type": "boolean", "title": "Disable automatically keyrepeating when AUTO_SHIFT_TIMEOUT is exceeded", "qsid": 3, "bit": 6 }
]
},
{
"name": "One Shot Keys",
"fields": [
{ "type": "integer", "title": "Tapping this number of times holds the key until tapped once again", "qsid": 5, "min": 0, "max": 50 },
{ "type": "integer", "title": "Time (in ms) before the one shot key is released", "qsid": 6, "min": 0, "max": 100000 }
]
},
{
"name": "Tap-Hold",
"fields": [
{ "type": "integer", "title": "TAPPING_TERM", "qsid": 7, "min": 0, "max": 10000 },
{ "type": "boolean", "title": "PERMISSIVE_HOLD", "qsid": 8, "bit": 0 },
{ "type": "boolean", "title": "IGNORE_MOD_TAP_INTERRUPT", "qsid": 8, "bit": 1 },
{ "type": "boolean", "title": "TAPPING_FORCE_HOLD", "qsid": 8, "bit": 2 }
]
}
]
}