From 7a575470f586ebbbec5c43fa34a4e6c919835be6 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Thu, 24 Dec 2020 21:28:39 -0500 Subject: [PATCH] macro_recorder: move classes to separate files --- src/main/python/macro_action.py | 145 ++++++++++++++++++ src/main/python/macro_line.py | 94 ++++++++++++ src/main/python/macro_recorder.py | 234 +----------------------------- 3 files changed, 243 insertions(+), 230 deletions(-) create mode 100644 src/main/python/macro_action.py create mode 100644 src/main/python/macro_line.py diff --git a/src/main/python/macro_action.py b/src/main/python/macro_action.py new file mode 100644 index 0000000..125cc25 --- /dev/null +++ b/src/main/python/macro_action.py @@ -0,0 +1,145 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +import struct + +from PyQt5.QtCore import QObject, pyqtSignal, Qt +from PyQt5.QtWidgets import QLineEdit, QToolButton, QHBoxLayout, QComboBox + +from keycodes import KEYCODES_BASIC +from util import tr + + +KC_NO = KEYCODES_BASIC[0] + + +class BasicAction(QObject): + + changed = pyqtSignal() + + def __init__(self, container): + super().__init__() + self.container = container + + +class ActionText(BasicAction): + + def __init__(self, container, text=""): + super().__init__(container) + self.text = QLineEdit() + self.text.setText(text) + self.text.textChanged.connect(self.on_change) + + def insert(self, row): + self.container.addWidget(self.text, row, 2) + + def remove(self): + self.container.removeWidget(self.text) + + def delete(self): + self.text.setParent(None) + self.text.deleteLater() + + def serialize(self): + return self.text.text().encode("utf-8") + + def on_change(self): + self.changed.emit() + + +class ActionSequence(BasicAction): + + def __init__(self, container, sequence=None): + super().__init__(container) + if sequence is None: + sequence = [] + self.sequence = sequence + + self.btn_plus = QToolButton() + self.btn_plus.setText("+") + self.btn_plus.setToolButtonStyle(Qt.ToolButtonTextOnly) + self.btn_plus.clicked.connect(self.on_add) + + self.layout = QHBoxLayout() + self.layout.addStretch() + self.widgets = [] + self.recreate_sequence() + + def recreate_sequence(self): + self.layout.removeWidget(self.btn_plus) + for w in self.widgets: + self.layout.removeWidget(w) + w.deleteLater() + self.widgets.clear() + + for item in self.sequence: + w = QComboBox() + w.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) + w.setStyleSheet("QComboBox { combobox-popup: 0; }") + w.addItem(tr("MacroEditor", "Remove")) + w.insertSeparator(1) + for k in KEYCODES_BASIC: + w.addItem(k.label.replace("\n", "")) + w.setCurrentIndex(2 + KEYCODES_BASIC.index(item)) + w.currentIndexChanged.connect(self.on_change) + self.layout.insertWidget(self.layout.count() - 1, w) + self.widgets.append(w) + self.layout.insertWidget(self.layout.count() - 1, self.btn_plus) + + def insert(self, row): + self.container.addLayout(self.layout, row, 2) + + def remove(self): + self.container.removeItem(self.layout) + + def delete(self): + for w in self.widgets: + w.setParent(None) + w.deleteLater() + self.btn_plus.setParent(None) + self.btn_plus.deleteLater() + self.layout.setParent(None) + self.layout.deleteLater() + + def on_add(self): + self.sequence.append(KC_NO) + self.recreate_sequence() + self.changed.emit() + + def on_change(self): + for x in range(len(self.sequence)): + index = self.widgets[x].currentIndex() + if index == 0: + # asked to remove this item + del self.sequence[x] + self.recreate_sequence() + break + else: + self.sequence[x] = KEYCODES_BASIC[self.widgets[x].currentIndex() - 2] + self.changed.emit() + + def serialize_prefix(self): + raise NotImplementedError + + def serialize(self): + out = b"" + for k in self.sequence: + out += self.serialize_prefix() + out += struct.pack("B", k.code) + return out + + +class ActionDown(ActionSequence): + + def serialize_prefix(self): + return b"\x02" + + +class ActionUp(ActionSequence): + + def serialize_prefix(self): + return b"\x03" + + +class ActionTap(ActionSequence): + + def serialize_prefix(self): + return b"\x01" diff --git a/src/main/python/macro_line.py b/src/main/python/macro_line.py new file mode 100644 index 0000000..c76fb18 --- /dev/null +++ b/src/main/python/macro_line.py @@ -0,0 +1,94 @@ +# coding: utf-8 +# SPDX-License-Identifier: GPL-2.0-or-later +from PyQt5.QtCore import QObject, pyqtSignal, Qt +from PyQt5.QtWidgets import QHBoxLayout, QToolButton, QComboBox + +from macro_action import ActionText, ActionDown, ActionUp, ActionTap + + +class MacroLine(QObject): + + changed = pyqtSignal() + + types = ["Text", "Down", "Up", "Tap"] + type_to_cls = [ActionText, ActionDown, ActionUp, ActionTap] + + def __init__(self, parent, action): + super().__init__() + + self.parent = parent + self.container = parent.container + + self.arrows = QHBoxLayout() + self.btn_up = QToolButton() + self.btn_up.setText("▲") + self.btn_up.setToolButtonStyle(Qt.ToolButtonTextOnly) + self.btn_up.clicked.connect(self.on_move_up) + self.btn_down = QToolButton() + self.btn_down.setText("▼") + self.btn_down.clicked.connect(self.on_move_down) + self.btn_down.setToolButtonStyle(Qt.ToolButtonTextOnly) + + self.arrows.addWidget(self.btn_up) + self.arrows.addWidget(self.btn_down) + + self.select_type = QComboBox() + self.select_type.addItems(self.types) + self.select_type.currentIndexChanged.connect(self.on_change_type) + + self.action = action + self.action.changed.connect(self.on_change) + self.row = -1 + + self.btn_remove = QToolButton() + self.btn_remove.setText("×") + self.btn_remove.setToolButtonStyle(Qt.ToolButtonTextOnly) + self.btn_remove.clicked.connect(self.on_remove_clicked) + + def insert(self, row): + self.row = row + self.container.addLayout(self.arrows, row, 0) + self.container.addWidget(self.select_type, row, 1) + self.container.addWidget(self.btn_remove, row, 3) + self.action.insert(row) + + def remove(self): + self.container.removeItem(self.arrows) + self.container.removeWidget(self.select_type) + self.container.removeWidget(self.btn_remove) + self.action.remove() + + def delete(self): + self.action.delete() + self.btn_remove.setParent(None) + self.btn_remove.deleteLater() + self.select_type.setParent(None) + self.select_type.deleteLater() + self.arrows.setParent(None) + self.arrows.deleteLater() + self.btn_up.setParent(None) + self.btn_up.deleteLater() + self.btn_down.setParent(None) + self.btn_down.deleteLater() + + def on_change_type(self): + self.action.remove() + self.action.delete() + self.action = self.type_to_cls[self.select_type.currentIndex()](self.container) + self.action.changed.connect(self.on_change) + self.action.insert(self.row) + + def on_remove_clicked(self): + self.parent.on_remove(self) + + def on_move_up(self): + self.parent.on_move(self, -1) + + def on_move_down(self): + self.parent.on_move(self, 1) + + def on_change(self): + self.changed.emit() + + def serialize(self): + return self.action.serialize() diff --git a/src/main/python/macro_recorder.py b/src/main/python/macro_recorder.py index 68c88ef..2e5117c 100644 --- a/src/main/python/macro_recorder.py +++ b/src/main/python/macro_recorder.py @@ -1,245 +1,19 @@ -# coding: utf-8 # SPDX-License-Identifier: GPL-2.0-or-later -import struct -from PyQt5.QtCore import Qt, pyqtSignal, QObject -from PyQt5.QtWidgets import QPushButton, QLineEdit, QGridLayout, QHBoxLayout, QComboBox, QToolButton, QVBoxLayout, \ +from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtWidgets import QPushButton, QGridLayout, QHBoxLayout, QToolButton, QVBoxLayout, \ QTabWidget, QWidget, QLabel from basic_editor import BasicEditor -from keycodes import KEYCODES_BASIC +from macro_action import ActionText, ActionSequence from macro_key import KeyString +from macro_line import MacroLine from macro_optimizer import macro_optimize from macro_recorder_linux import LinuxRecorder from util import tr from vial_device import VialKeyboard -KC_NO = KEYCODES_BASIC[0] - - -class BasicAction(QObject): - - changed = pyqtSignal() - - def __init__(self, container): - super().__init__() - self.container = container - - -class ActionText(BasicAction): - - def __init__(self, container, text=""): - super().__init__(container) - self.text = QLineEdit() - self.text.setText(text) - self.text.textChanged.connect(self.on_change) - - def insert(self, row): - self.container.addWidget(self.text, row, 2) - - def remove(self): - self.container.removeWidget(self.text) - - def delete(self): - self.text.setParent(None) - self.text.deleteLater() - - def serialize(self): - return self.text.text().encode("utf-8") - - def on_change(self): - self.changed.emit() - - -class ActionSequence(BasicAction): - - def __init__(self, container, sequence=None): - super().__init__(container) - if sequence is None: - sequence = [] - self.sequence = sequence - - self.btn_plus = QToolButton() - self.btn_plus.setText("+") - self.btn_plus.setToolButtonStyle(Qt.ToolButtonTextOnly) - self.btn_plus.clicked.connect(self.on_add) - - self.layout = QHBoxLayout() - self.layout.addStretch() - self.widgets = [] - self.recreate_sequence() - - def recreate_sequence(self): - self.layout.removeWidget(self.btn_plus) - for w in self.widgets: - self.layout.removeWidget(w) - w.deleteLater() - self.widgets.clear() - - for item in self.sequence: - w = QComboBox() - w.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - w.setStyleSheet("QComboBox { combobox-popup: 0; }") - w.addItem(tr("MacroEditor", "Remove")) - w.insertSeparator(1) - for k in KEYCODES_BASIC: - w.addItem(k.label.replace("\n", "")) - w.setCurrentIndex(2 + KEYCODES_BASIC.index(item)) - w.currentIndexChanged.connect(self.on_change) - self.layout.insertWidget(self.layout.count() - 1, w) - self.widgets.append(w) - self.layout.insertWidget(self.layout.count() - 1, self.btn_plus) - - def insert(self, row): - self.container.addLayout(self.layout, row, 2) - - def remove(self): - self.container.removeItem(self.layout) - - def delete(self): - for w in self.widgets: - w.setParent(None) - w.deleteLater() - self.btn_plus.setParent(None) - self.btn_plus.deleteLater() - self.layout.setParent(None) - self.layout.deleteLater() - - def on_add(self): - self.sequence.append(KC_NO) - self.recreate_sequence() - self.changed.emit() - - def on_change(self): - for x in range(len(self.sequence)): - index = self.widgets[x].currentIndex() - if index == 0: - # asked to remove this item - del self.sequence[x] - self.recreate_sequence() - break - else: - self.sequence[x] = KEYCODES_BASIC[self.widgets[x].currentIndex() - 2] - self.changed.emit() - - def serialize_prefix(self): - raise NotImplementedError - - def serialize(self): - out = b"" - for k in self.sequence: - out += self.serialize_prefix() - out += struct.pack("B", k.code) - return out - - -class ActionDown(ActionSequence): - - def serialize_prefix(self): - return b"\x02" - - -class ActionUp(ActionSequence): - - def serialize_prefix(self): - return b"\x03" - - -class ActionTap(ActionSequence): - - def serialize_prefix(self): - return b"\x01" - - -class MacroLine(QObject): - - changed = pyqtSignal() - - types = ["Text", "Down", "Up", "Tap"] - type_to_cls = [ActionText, ActionDown, ActionUp, ActionTap] - - def __init__(self, parent, action): - super().__init__() - - self.parent = parent - self.container = parent.container - - self.arrows = QHBoxLayout() - self.btn_up = QToolButton() - self.btn_up.setText("▲") - self.btn_up.setToolButtonStyle(Qt.ToolButtonTextOnly) - self.btn_up.clicked.connect(self.on_move_up) - self.btn_down = QToolButton() - self.btn_down.setText("▼") - self.btn_down.clicked.connect(self.on_move_down) - self.btn_down.setToolButtonStyle(Qt.ToolButtonTextOnly) - - self.arrows.addWidget(self.btn_up) - self.arrows.addWidget(self.btn_down) - - self.select_type = QComboBox() - self.select_type.addItems(self.types) - self.select_type.currentIndexChanged.connect(self.on_change_type) - - self.action = action - self.action.changed.connect(self.on_change) - self.row = -1 - - self.btn_remove = QToolButton() - self.btn_remove.setText("×") - self.btn_remove.setToolButtonStyle(Qt.ToolButtonTextOnly) - self.btn_remove.clicked.connect(self.on_remove_clicked) - - def insert(self, row): - self.row = row - self.container.addLayout(self.arrows, row, 0) - self.container.addWidget(self.select_type, row, 1) - self.container.addWidget(self.btn_remove, row, 3) - self.action.insert(row) - - def remove(self): - self.container.removeItem(self.arrows) - self.container.removeWidget(self.select_type) - self.container.removeWidget(self.btn_remove) - self.action.remove() - - def delete(self): - self.action.delete() - self.btn_remove.setParent(None) - self.btn_remove.deleteLater() - self.select_type.setParent(None) - self.select_type.deleteLater() - self.arrows.setParent(None) - self.arrows.deleteLater() - self.btn_up.setParent(None) - self.btn_up.deleteLater() - self.btn_down.setParent(None) - self.btn_down.deleteLater() - - def on_change_type(self): - self.action.remove() - self.action.delete() - self.action = self.type_to_cls[self.select_type.currentIndex()](self.container) - self.action.changed.connect(self.on_change) - self.action.insert(self.row) - - def on_remove_clicked(self): - self.parent.on_remove(self) - - def on_move_up(self): - self.parent.on_move(self, -1) - - def on_move_down(self): - self.parent.on_move(self, 1) - - def on_change(self): - self.changed.emit() - - def serialize(self): - return self.action.serialize() - - class MacroTab(QVBoxLayout): changed = pyqtSignal()