rgb_configurator: initial implementation
parent
6ddbce17ec
commit
8aa8e0dab3
|
|
@ -17,6 +17,9 @@ CMD_VIA_GET_KEYBOARD_VALUE = 0x02
|
||||||
CMD_VIA_SET_KEYBOARD_VALUE = 0x03
|
CMD_VIA_SET_KEYBOARD_VALUE = 0x03
|
||||||
CMD_VIA_GET_KEYCODE = 0x04
|
CMD_VIA_GET_KEYCODE = 0x04
|
||||||
CMD_VIA_SET_KEYCODE = 0x05
|
CMD_VIA_SET_KEYCODE = 0x05
|
||||||
|
CMD_VIA_LIGHTING_SET_VALUE = 0x07
|
||||||
|
CMD_VIA_LIGHTING_GET_VALUE = 0x08
|
||||||
|
CMD_VIA_LIGHTING_SAVE = 0x09
|
||||||
CMD_VIA_MACRO_GET_COUNT = 0x0C
|
CMD_VIA_MACRO_GET_COUNT = 0x0C
|
||||||
CMD_VIA_MACRO_GET_BUFFER_SIZE = 0x0D
|
CMD_VIA_MACRO_GET_BUFFER_SIZE = 0x0D
|
||||||
CMD_VIA_MACRO_GET_BUFFER = 0x0E
|
CMD_VIA_MACRO_GET_BUFFER = 0x0E
|
||||||
|
|
@ -28,6 +31,14 @@ CMD_VIA_VIAL_PREFIX = 0xFE
|
||||||
VIA_LAYOUT_OPTIONS = 0x02
|
VIA_LAYOUT_OPTIONS = 0x02
|
||||||
VIA_SWITCH_MATRIX_STATE = 0x03
|
VIA_SWITCH_MATRIX_STATE = 0x03
|
||||||
|
|
||||||
|
QMK_BACKLIGHT_BRIGHTNESS = 0x09
|
||||||
|
QMK_BACKLIGHT_EFFECT = 0x0A
|
||||||
|
|
||||||
|
QMK_RGBLIGHT_BRIGHTNESS = 0x80
|
||||||
|
QMK_RGBLIGHT_EFFECT = 0x81
|
||||||
|
QMK_RGBLIGHT_EFFECT_SPEED = 0x82
|
||||||
|
QMK_RGBLIGHT_COLOR = 0x83
|
||||||
|
|
||||||
CMD_VIAL_GET_KEYBOARD_ID = 0x00
|
CMD_VIAL_GET_KEYBOARD_ID = 0x00
|
||||||
CMD_VIAL_GET_SIZE = 0x01
|
CMD_VIAL_GET_SIZE = 0x01
|
||||||
CMD_VIAL_GET_DEFINITION = 0x02
|
CMD_VIAL_GET_DEFINITION = 0x02
|
||||||
|
|
@ -145,6 +156,7 @@ class Keyboard:
|
||||||
def __init__(self, dev, usb_send=hid_send):
|
def __init__(self, dev, usb_send=hid_send):
|
||||||
self.dev = dev
|
self.dev = dev
|
||||||
self.usb_send = usb_send
|
self.usb_send = usb_send
|
||||||
|
self.definition = None
|
||||||
|
|
||||||
# n.b. using OrderedDict here to make order of layout requests consistent for tests
|
# n.b. using OrderedDict here to make order of layout requests consistent for tests
|
||||||
self.rowcol = OrderedDict()
|
self.rowcol = OrderedDict()
|
||||||
|
|
@ -163,6 +175,10 @@ class Keyboard:
|
||||||
self.vibl = False
|
self.vibl = False
|
||||||
self.custom_keycodes = None
|
self.custom_keycodes = None
|
||||||
|
|
||||||
|
self.lighting_qmk_rgblight = self.lighting_qmk_backlight = False
|
||||||
|
self.underglow_brightness = self.underglow_effect = self.underglow_effect_speed = -1
|
||||||
|
self.underglow_color = (0, 0)
|
||||||
|
|
||||||
self.via_protocol = self.vial_protocol = self.keyboard_id = -1
|
self.via_protocol = self.vial_protocol = self.keyboard_id = -1
|
||||||
|
|
||||||
def reload(self, sideload_json=None):
|
def reload(self, sideload_json=None):
|
||||||
|
|
@ -177,6 +193,7 @@ class Keyboard:
|
||||||
self.reload_layers()
|
self.reload_layers()
|
||||||
self.reload_keymap()
|
self.reload_keymap()
|
||||||
self.reload_macros()
|
self.reload_macros()
|
||||||
|
self.reload_rgb()
|
||||||
|
|
||||||
def reload_layers(self):
|
def reload_layers(self):
|
||||||
""" Get how many layers the keyboard has """
|
""" Get how many layers the keyboard has """
|
||||||
|
|
@ -217,6 +234,8 @@ class Keyboard:
|
||||||
|
|
||||||
payload = json.loads(lzma.decompress(payload))
|
payload = json.loads(lzma.decompress(payload))
|
||||||
|
|
||||||
|
self.definition = payload
|
||||||
|
|
||||||
if "vial" in payload:
|
if "vial" in payload:
|
||||||
vial = payload["vial"]
|
vial = payload["vial"]
|
||||||
self.vibl = vial.get("vibl", False)
|
self.vibl = vial.get("vibl", False)
|
||||||
|
|
@ -313,6 +332,23 @@ class Keyboard:
|
||||||
macros = self.macro.split(b"\x00") + [b""] * self.macro_count
|
macros = self.macro.split(b"\x00") + [b""] * self.macro_count
|
||||||
self.macro = b"\x00".join(macros[:self.macro_count]) + b"\x00"
|
self.macro = b"\x00".join(macros[:self.macro_count]) + b"\x00"
|
||||||
|
|
||||||
|
def reload_rgb(self):
|
||||||
|
if "lighting" in self.definition:
|
||||||
|
self.lighting_qmk_rgblight = self.definition["lighting"] in ["qmk_rgblight", "qmk_backlight_rgblight"]
|
||||||
|
self.lighting_qmk_backlight = self.definition["lighting"] in ["qmk_backlight", "qmk_backlight_rgblight"]
|
||||||
|
|
||||||
|
if self.lighting_qmk_rgblight:
|
||||||
|
self.underglow_brightness = self.usb_send(
|
||||||
|
self.dev, struct.pack(">BB", CMD_VIA_LIGHTING_GET_VALUE, QMK_RGBLIGHT_BRIGHTNESS), retries=20)[2]
|
||||||
|
self.underglow_effect = self.usb_send(
|
||||||
|
self.dev, struct.pack(">BB", CMD_VIA_LIGHTING_GET_VALUE, QMK_RGBLIGHT_EFFECT), retries=20)[2]
|
||||||
|
self.underglow_effect_speed = self.usb_send(
|
||||||
|
self.dev, struct.pack(">BB", CMD_VIA_LIGHTING_GET_VALUE, QMK_RGBLIGHT_EFFECT_SPEED), retries=20)[2]
|
||||||
|
color = self.usb_send(
|
||||||
|
self.dev, struct.pack(">BB", CMD_VIA_LIGHTING_GET_VALUE, QMK_RGBLIGHT_COLOR), retries=20)[2:4]
|
||||||
|
# hue, sat
|
||||||
|
self.underglow_color = (color[0], color[1])
|
||||||
|
|
||||||
def set_key(self, layer, row, col, code):
|
def set_key(self, layer, row, col, code):
|
||||||
if code < 0:
|
if code < 0:
|
||||||
return
|
return
|
||||||
|
|
@ -354,6 +390,24 @@ class Keyboard:
|
||||||
retries=20)
|
retries=20)
|
||||||
self.macro = data
|
self.macro = data
|
||||||
|
|
||||||
|
def set_qmk_rgblight_brightness(self, value):
|
||||||
|
self.underglow_brightness = value
|
||||||
|
self.usb_send(self.dev, struct.pack(">BBB", CMD_VIA_LIGHTING_SET_VALUE, QMK_RGBLIGHT_BRIGHTNESS, value),
|
||||||
|
retries=20)
|
||||||
|
|
||||||
|
def set_qmk_rgblight_effect(self, index):
|
||||||
|
self.underglow_effect = index
|
||||||
|
self.usb_send(self.dev, struct.pack(">BBB", CMD_VIA_LIGHTING_SET_VALUE, QMK_RGBLIGHT_EFFECT, index),
|
||||||
|
retries=20)
|
||||||
|
|
||||||
|
def set_qmk_rgblight_effect_speed(self, value):
|
||||||
|
self.underglow_effect_speed = value
|
||||||
|
self.usb_send(self.dev, struct.pack(">BBB", CMD_VIA_LIGHTING_SET_VALUE, QMK_RGBLIGHT_EFFECT_SPEED, value),
|
||||||
|
retries=20)
|
||||||
|
|
||||||
|
def save_rgb(self):
|
||||||
|
self.usb_send(self.dev, struct.pack(">B", CMD_VIA_LIGHTING_SAVE), retries=20)
|
||||||
|
|
||||||
def save_layout(self):
|
def save_layout(self):
|
||||||
""" Serializes current layout to a binary """
|
""" Serializes current layout to a binary """
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from keymap_editor import KeymapEditor
|
||||||
from keymaps import KEYMAPS
|
from keymaps import KEYMAPS
|
||||||
from layout_editor import LayoutEditor
|
from layout_editor import LayoutEditor
|
||||||
from macro_recorder import MacroRecorder
|
from macro_recorder import MacroRecorder
|
||||||
|
from rgb_configurator import RGBConfigurator
|
||||||
from unlocker import Unlocker
|
from unlocker import Unlocker
|
||||||
from util import tr, find_vial_devices, EXAMPLE_KEYBOARDS
|
from util import tr, find_vial_devices, EXAMPLE_KEYBOARDS
|
||||||
from vial_device import VialKeyboard
|
from vial_device import VialKeyboard
|
||||||
|
|
@ -54,9 +55,12 @@ class MainWindow(QMainWindow):
|
||||||
self.firmware_flasher = FirmwareFlasher(self)
|
self.firmware_flasher = FirmwareFlasher(self)
|
||||||
self.macro_recorder = MacroRecorder()
|
self.macro_recorder = MacroRecorder()
|
||||||
self.matrix_tester = MatrixTest(self.layout_editor)
|
self.matrix_tester = MatrixTest(self.layout_editor)
|
||||||
|
self.rgb_configurator = RGBConfigurator()
|
||||||
|
|
||||||
self.editors = [(self.keymap_editor, "Keymap"), (self.layout_editor, "Layout"), (self.macro_recorder, "Macros"),
|
self.editors = [(self.keymap_editor, "Keymap"), (self.layout_editor, "Layout"), (self.macro_recorder, "Macros"),
|
||||||
(self.matrix_tester, "Matrix tester"), (self.firmware_flasher, "Firmware updater")]
|
(self.matrix_tester, "Matrix tester"), (self.rgb_configurator, "Lighting"),
|
||||||
|
(self.firmware_flasher, "Firmware updater")]
|
||||||
|
|
||||||
Unlocker.global_layout_editor = self.layout_editor
|
Unlocker.global_layout_editor = self.layout_editor
|
||||||
|
|
||||||
self.tabs = QTabWidget()
|
self.tabs = QTabWidget()
|
||||||
|
|
@ -238,7 +242,7 @@ class MainWindow(QMainWindow):
|
||||||
self.current_device.keyboard.reload()
|
self.current_device.keyboard.reload()
|
||||||
|
|
||||||
for e in [self.layout_editor, self.keymap_editor, self.firmware_flasher, self.macro_recorder,
|
for e in [self.layout_editor, self.keymap_editor, self.firmware_flasher, self.macro_recorder,
|
||||||
self.matrix_tester]:
|
self.matrix_tester, self.rgb_configurator]:
|
||||||
e.rebuild(self.current_device)
|
e.rebuild(self.current_device)
|
||||||
|
|
||||||
def refresh_tabs(self):
|
def refresh_tabs(self):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
from PyQt5 import QtCore
|
||||||
|
from PyQt5.QtWidgets import QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QSizePolicy, QGridLayout, QLabel, QSlider, \
|
||||||
|
QComboBox
|
||||||
|
|
||||||
|
from basic_editor import BasicEditor
|
||||||
|
from util import tr
|
||||||
|
from vial_device import VialKeyboard
|
||||||
|
|
||||||
|
|
||||||
|
class QmkRgblightEffect:
|
||||||
|
|
||||||
|
def __init__(self, idx, name, color_picker):
|
||||||
|
self.idx = idx
|
||||||
|
self.name = name
|
||||||
|
self.color_picker = color_picker
|
||||||
|
|
||||||
|
|
||||||
|
QMK_RGBLIGHT_EFFECTS = [
|
||||||
|
QmkRgblightEffect(0, "All Off", False),
|
||||||
|
QmkRgblightEffect(1, "Solid Color", True),
|
||||||
|
QmkRgblightEffect(2, "Breathing 1", True),
|
||||||
|
QmkRgblightEffect(3, "Breathing 2", True),
|
||||||
|
QmkRgblightEffect(4, "Breathing 3", True),
|
||||||
|
QmkRgblightEffect(5, "Breathing 4", True),
|
||||||
|
QmkRgblightEffect(6, "Rainbow Mood 1", False),
|
||||||
|
QmkRgblightEffect(7, "Rainbow Mood 2", False),
|
||||||
|
QmkRgblightEffect(8, "Rainbow Mood 3", False),
|
||||||
|
QmkRgblightEffect(9, "Rainbow Swirl 1", False),
|
||||||
|
QmkRgblightEffect(10, "Rainbow Swirl 2", False),
|
||||||
|
QmkRgblightEffect(11, "Rainbow Swirl 3", False),
|
||||||
|
QmkRgblightEffect(12, "Rainbow Swirl 4", False),
|
||||||
|
QmkRgblightEffect(13, "Rainbow Swirl 5", False),
|
||||||
|
QmkRgblightEffect(14, "Rainbow Swirl 6", False),
|
||||||
|
QmkRgblightEffect(15, "Snake 1", True),
|
||||||
|
QmkRgblightEffect(16, "Snake 2", True),
|
||||||
|
QmkRgblightEffect(17, "Snake 3", True),
|
||||||
|
QmkRgblightEffect(18, "Snake 4", True),
|
||||||
|
QmkRgblightEffect(19, "Snake 5", True),
|
||||||
|
QmkRgblightEffect(20, "Snake 6", True),
|
||||||
|
QmkRgblightEffect(21, "Knight 1", True),
|
||||||
|
QmkRgblightEffect(22, "Knight 2", True),
|
||||||
|
QmkRgblightEffect(23, "Knight 3", True),
|
||||||
|
QmkRgblightEffect(24, "Christmas", True),
|
||||||
|
QmkRgblightEffect(25, "Gradient 1", True),
|
||||||
|
QmkRgblightEffect(26, "Gradient 2", True),
|
||||||
|
QmkRgblightEffect(27, "Gradient 3", True),
|
||||||
|
QmkRgblightEffect(28, "Gradient 4", True),
|
||||||
|
QmkRgblightEffect(29, "Gradient 5", True),
|
||||||
|
QmkRgblightEffect(30, "Gradient 6", True),
|
||||||
|
QmkRgblightEffect(31, "Gradient 7", True),
|
||||||
|
QmkRgblightEffect(32, "Gradient 8", True),
|
||||||
|
QmkRgblightEffect(33, "Gradient 9", True),
|
||||||
|
QmkRgblightEffect(34, "Gradient 10", True),
|
||||||
|
QmkRgblightEffect(35, "RGB Test", True),
|
||||||
|
QmkRgblightEffect(36, "Alternating", True),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class RGBConfigurator(BasicEditor):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.addStretch()
|
||||||
|
|
||||||
|
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(tr("RGBConfigurator", "Underglow Effect")), 0, 0)
|
||||||
|
self.underglow_effect = QComboBox()
|
||||||
|
for ef in QMK_RGBLIGHT_EFFECTS:
|
||||||
|
self.underglow_effect.addItem(ef.name)
|
||||||
|
self.container.addWidget(self.underglow_effect, 0, 1)
|
||||||
|
|
||||||
|
self.container.addWidget(QLabel(tr("RGBConfigurator", "Underglow Brightness")), 1, 0)
|
||||||
|
self.underglow_brightness = QSlider(QtCore.Qt.Horizontal)
|
||||||
|
self.underglow_brightness.setMinimum(0)
|
||||||
|
self.underglow_brightness.setMaximum(255)
|
||||||
|
self.underglow_brightness.valueChanged.connect(self.on_underglow_brightness_changed)
|
||||||
|
self.container.addWidget(self.underglow_brightness, 1, 1)
|
||||||
|
|
||||||
|
# XXX: qmk speed setting does nothing
|
||||||
|
# self.container.addWidget(QLabel(tr("RGBConfigurator", "Underglow Effect Speed")), 2, 0)
|
||||||
|
# self.underglow_effect_speed = QSlider(QtCore.Qt.Horizontal)
|
||||||
|
# self.underglow_effect_speed.setMinimum(0)
|
||||||
|
# self.underglow_effect_speed.setMaximum(3)
|
||||||
|
# self.underglow_effect_speed.valueChanged.connect(self.on_underglow_effect_speed_changed)
|
||||||
|
# self.container.addWidget(self.underglow_effect_speed, 2, 1)
|
||||||
|
|
||||||
|
self.lbl_underglow_color = QLabel(tr("RGBConfigurator", "Underglow Color"))
|
||||||
|
self.container.addWidget(self.lbl_underglow_color, 3, 0)
|
||||||
|
self.underglow_color = QLabel("x")
|
||||||
|
self.container.addWidget(self.underglow_color, 3, 1)
|
||||||
|
|
||||||
|
self.underglow_effect.currentIndexChanged.connect(self.on_underglow_effect_changed)
|
||||||
|
|
||||||
|
self.addStretch()
|
||||||
|
buttons = QHBoxLayout()
|
||||||
|
buttons.addStretch()
|
||||||
|
save_btn = QPushButton(tr("RGBConfigurator", "Save"))
|
||||||
|
buttons.addWidget(save_btn)
|
||||||
|
save_btn.clicked.connect(self.on_save)
|
||||||
|
self.addLayout(buttons)
|
||||||
|
|
||||||
|
def on_underglow_brightness_changed(self, value):
|
||||||
|
self.device.keyboard.set_qmk_rgblight_brightness(value)
|
||||||
|
|
||||||
|
def on_underglow_effect_changed(self, index):
|
||||||
|
self.lbl_underglow_color.setVisible(QMK_RGBLIGHT_EFFECTS[index].color_picker)
|
||||||
|
self.underglow_color.setVisible(QMK_RGBLIGHT_EFFECTS[index].color_picker)
|
||||||
|
|
||||||
|
self.device.keyboard.set_qmk_rgblight_effect(index)
|
||||||
|
|
||||||
|
def on_underglow_effect_speed_changed(self, value):
|
||||||
|
self.device.keyboard.set_qmk_rgblight_effect_speed(value)
|
||||||
|
|
||||||
|
def on_save(self):
|
||||||
|
self.device.keyboard.save_rgb()
|
||||||
|
|
||||||
|
def valid(self):
|
||||||
|
return isinstance(self.device, VialKeyboard) and self.device.keyboard.lighting_qmk_rgblight
|
||||||
|
|
||||||
|
def rebuild(self, device):
|
||||||
|
super().rebuild(device)
|
||||||
|
|
||||||
|
if not self.valid():
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO: this should block signals from the actual combobox/etc sending them
|
||||||
|
# self.blockSignals(True)
|
||||||
|
|
||||||
|
self.underglow_brightness.setValue(device.keyboard.underglow_brightness)
|
||||||
|
self.underglow_effect.setCurrentIndex(device.keyboard.underglow_effect)
|
||||||
|
# self.underglow_effect_speed.setValue(device.keyboard.underglow_effect_speed)
|
||||||
|
|
||||||
|
# TODO: as above
|
||||||
|
# self.blockSignals(False)
|
||||||
Loading…
Reference in New Issue