From 8f4734ab4056870703296775bfe49f00e8aa8de3 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Sat, 3 Jul 2021 16:53:24 -0400 Subject: [PATCH] tap_dance: track state of tab change --- src/main/python/key_widget.py | 8 +++++ src/main/python/tap_dance.py | 56 +++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/main/python/key_widget.py b/src/main/python/key_widget.py index 86f37fd..bf7fd6b 100644 --- a/src/main/python/key_widget.py +++ b/src/main/python/key_widget.py @@ -1,3 +1,5 @@ +from PyQt5.QtCore import pyqtSignal + from any_keycode_dialog import AnyKeycodeDialog from keyboard_widget import KeyboardWidget from kle_serial import Key @@ -7,6 +9,8 @@ from util import KeycodeDisplay class KeyWidget(KeyboardWidget): + changed = pyqtSignal() + def __init__(self): super().__init__(None) @@ -45,6 +49,10 @@ class KeyWidget(KeyboardWidget): self.set_keycode(dlg.value) def set_keycode(self, kc): + if kc == self.keycode: + return self.keycode = kc KeycodeDisplay.display_keycode(self.widgets[0], self.keycode) self.update() + + self.changed.emit() diff --git a/src/main/python/tap_dance.py b/src/main/python/tap_dance.py index 3e9d4ac..cf950b3 100644 --- a/src/main/python/tap_dance.py +++ b/src/main/python/tap_dance.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later from PyQt5 import QtCore +from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtWidgets import QTabWidget, QWidget, QSizePolicy, QGridLayout, QVBoxLayout, QLabel, QLineEdit, QHBoxLayout, \ QPushButton, QSpinBox @@ -9,9 +10,14 @@ from vial_device import VialKeyboard from basic_editor import BasicEditor -class TapDanceEntryUI: +class TapDanceEntryUI(QObject): + + key_changed = pyqtSignal() + timing_changed = pyqtSignal() def __init__(self, idx): + super().__init__() + self.idx = idx self.container = QGridLayout() self.populate_container() @@ -35,18 +41,23 @@ class TapDanceEntryUI: def populate_container(self): self.container.addWidget(QLabel("On tap"), 0, 0) self.kc_on_tap = KeyWidget() + self.kc_on_tap.changed.connect(self.on_key_changed) self.container.addWidget(self.kc_on_tap, 0, 1) self.container.addWidget(QLabel("On hold"), 1, 0) self.kc_on_hold = KeyWidget() + self.kc_on_hold.changed.connect(self.on_key_changed) self.container.addWidget(self.kc_on_hold, 1, 1) self.container.addWidget(QLabel("On double tap"), 2, 0) self.kc_on_double_tap = KeyWidget() + self.kc_on_double_tap.changed.connect(self.on_key_changed) self.container.addWidget(self.kc_on_double_tap, 2, 1) self.container.addWidget(QLabel("On tap + hold"), 3, 0) self.kc_on_tap_hold = KeyWidget() + self.kc_on_tap_hold.changed.connect(self.on_key_changed) self.container.addWidget(self.kc_on_tap_hold, 3, 1) self.container.addWidget(QLabel("Tapping term (ms)"), 4, 0) self.txt_tapping_term = QSpinBox() + self.txt_tapping_term.valueChanged.connect(self.on_timing_changed) self.txt_tapping_term.setMinimum(0) self.txt_tapping_term.setMaximum(10000) self.container.addWidget(self.txt_tapping_term, 4, 1) @@ -55,12 +66,19 @@ class TapDanceEntryUI: return self.w2 def load(self, data): + objs = [self.kc_on_tap, self.kc_on_hold, self.kc_on_double_tap, self.kc_on_tap_hold, self.txt_tapping_term] + for o in objs: + o.blockSignals(True) + self.kc_on_tap.set_keycode(data[0]) self.kc_on_hold.set_keycode(data[1]) self.kc_on_double_tap.set_keycode(data[2]) self.kc_on_tap_hold.set_keycode(data[3]) self.txt_tapping_term.setValue(data[4]) + for o in objs: + o.blockSignals(False) + def save(self): return ( self.kc_on_tap.keycode, @@ -70,6 +88,12 @@ class TapDanceEntryUI: self.txt_tapping_term.value() ) + def on_key_changed(self): + self.key_changed.emit() + + def on_timing_changed(self): + self.timing_changed.emit() + class TapDance(BasicEditor): @@ -81,16 +105,19 @@ class TapDance(BasicEditor): self.tap_dance_entries_available = [] self.tabs = QTabWidget() for x in range(128): - self.tap_dance_entries_available.append(TapDanceEntryUI(x)) + entry = TapDanceEntryUI(x) + entry.key_changed.connect(self.on_key_changed) + entry.timing_changed.connect(self.on_timing_changed) + self.tap_dance_entries_available.append(entry) self.addWidget(self.tabs) buttons = QHBoxLayout() buttons.addStretch() - btn_save = QPushButton(tr("TapDance", "Save")) - btn_save.clicked.connect(self.on_save) + self.btn_save = QPushButton(tr("TapDance", "Save")) + self.btn_save.clicked.connect(self.on_save) btn_revert = QPushButton(tr("TapDance", "Revert")) btn_revert.clicked.connect(self.on_revert) - buttons.addWidget(btn_save) + buttons.addWidget(self.btn_save) buttons.addWidget(btn_revert) self.addLayout(buttons) @@ -105,10 +132,12 @@ class TapDance(BasicEditor): def reload_ui(self): for x, e in enumerate(self.tap_dance_entries): e.load(self.keyboard.tap_dance_get(x)) + self.update_modified_state() def on_save(self): for x, e in enumerate(self.tap_dance_entries): self.keyboard.tap_dance_set(x, self.tap_dance_entries[x].save()) + self.update_modified_state() def on_revert(self): self.keyboard.reload_dynamic() @@ -124,3 +153,20 @@ class TapDance(BasicEditor): return isinstance(self.device, VialKeyboard) and \ (self.device.keyboard and self.device.keyboard.vial_protocol >= 4 and self.device.keyboard.tap_dance_count > 0) + + def on_key_changed(self): + self.on_save() + + def update_modified_state(self): + """ Update indication of which tabs are modified, and keep Save button enabled only if it's needed """ + has_changes = False + for x, e in enumerate(self.tap_dance_entries): + if self.tap_dance_entries[x].save() != self.keyboard.tap_dance_get(x): + has_changes = True + self.tabs.setTabText(x, "{}*".format(x)) + else: + self.tabs.setTabText(x, str(x)) + self.btn_save.setEnabled(has_changes) + + def on_timing_changed(self): + self.update_modified_state()