diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-03-18 20:52:36 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-03-18 20:52:36 +0530 |
| commit | 056b0b16947ac19a0c425aa9d2ff8f589378d3bc (patch) | |
| tree | d062dc2de09711c1f7e980fc8475c19a97ff7d99 /include/keymap | |
| parent | dd6590a0fda614fa2fb0ca9e4ad11b086393372e (diff) | |
| download | null-browser-056b0b16947ac19a0c425aa9d2ff8f589378d3bc.tar.gz null-browser-056b0b16947ac19a0c425aa9d2ff8f589378d3bc.zip | |
Add keymap evaluation with strict event filter
Diffstat (limited to '')
| -rw-r--r-- | include/keymap/KeySeqParser.hpp | 26 | ||||
| -rw-r--r-- | include/keymap/KeymapEvaluator.hpp | 71 |
2 files changed, 96 insertions, 1 deletions
diff --git a/include/keymap/KeySeqParser.hpp b/include/keymap/KeySeqParser.hpp index aefcb62..fac2546 100644 --- a/include/keymap/KeySeqParser.hpp +++ b/include/keymap/KeySeqParser.hpp @@ -2,6 +2,7 @@ #include <QtCore/qnamespace.h> #include <QtCore> +#include <cmath> struct KeyChord { Qt::KeyboardModifiers mod; @@ -9,11 +10,34 @@ struct KeyChord { }; bool operator==(const KeyChord a, const KeyChord b); +typedef QList<KeyChord> KeySequence; + +enum KeyMatchType { + NoMatch, + Match, + Pending, +}; + class KeySeqParser { public: + static const KeyMatchType keySequenceMatch(const KeySequence target, + const KeySequence current) { + for (int i = 0; i < target.length(); i++) { + if (current.length() <= i) + return KeyMatchType::Pending; + + if (target[i].key != current[i].key || + !target[i].mod.testFlags(current[i].mod)) + return KeyMatchType::NoMatch; + } + + return KeyMatchType::Match; + } + +public: KeySeqParser(); - QList<KeyChord> parse(QString keySequence); + KeySequence parse(QString keySequence); private: Qt::Key parseKey(QString keyName); diff --git a/include/keymap/KeymapEvaluator.hpp b/include/keymap/KeymapEvaluator.hpp new file mode 100644 index 0000000..ed468d2 --- /dev/null +++ b/include/keymap/KeymapEvaluator.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include "keymap/KeySeqParser.hpp" +#include <QWidget> +#include <QtCore/qmap.h> +#include <QtCore/qnamespace.h> +#include <QtCore> +#include <algorithm> + +struct KeyMap { + KeySequence keySequence; + QString action; // TODO: string for testing +}; + +class KeymapEvaluator : public QObject { + Q_OBJECT + +public: + KeymapEvaluator(); + + void addKeymap(QString mode, QString key, QString action) { + if (!modalKeys.contains(mode)) + modalKeys.insert(mode, {}); + + auto keySeq = keySeqParser.parse(key); + // TODO: Add actions + modalKeys[mode].append((KeyMap){.keySequence = keySeq, .action = action}); + } + + void evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key) { + if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta || + key == Qt::Key_Alt) + return; + + auto keymaps = currentModeKeys(); + auto foundPendingMatches = false; + + activeKeySequence.append((KeyChord){.mod = modifiers, .key = key}); + + for (auto &keymap : *keymaps) { + auto matchType = + KeySeqParser::keySequenceMatch(keymap.keySequence, activeKeySequence); + + if (matchType == KeyMatchType::Match) { + qDebug() << "Matched!" << keymap.action; + activeKeySequence.clear(); + return; + } else if (matchType == KeyMatchType::Pending) { + foundPendingMatches = true; + } + } + + if (!foundPendingMatches) + activeKeySequence.clear(); + } + +private: + const QList<KeyMap> *currentModeKeys() { + if (!modalKeys.contains(currentMode)) + return new QList<KeyMap>(); + + return &modalKeys[currentMode]; + } + +private: + QMap<QString, QList<KeyMap>> modalKeys; + KeySeqParser keySeqParser; + QString currentMode = "default"; + + KeySequence activeKeySequence; +}; |
