12.2b: the Keyboard Shortcuts window and remapped keys everywhere (Compositor 1.1.6)
This commit is contained in:
1 parent
f1b2c65c1e
commit
4bfc6c237e
29 files changed
+1645
-164
No files matched your search
@@ -0,0 +1,133 @@
|
||||
#pragma once
|
||||
#include <QHash>
|
||||
#include <QKeySequence>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
class QAbstractButton;
|
||||
class QKeyEvent;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QShortcut;
|
||||
class QWidget;
|
||||
|
||||
// One key with its modifiers, stored as Swift stores it.
|
||||
struct ShortcutChord {
|
||||
// One character; Backspace is 0x7f, the arrows Cocoa's F700s.
|
||||
QString key;
|
||||
// Bits: Ctrl 1, Alt 2, Meta 4, Shift 8.
|
||||
int modifiers = 0;
|
||||
|
||||
ShortcutChord() = default;
|
||||
ShortcutChord(QString key, int modifiers = 0) : key(std::move(key)), modifiers(modifiers) {}
|
||||
explicit ShortcutChord(const QKeyEvent &event);
|
||||
explicit ShortcutChord(QKeyCombination combination);
|
||||
QKeyCombination combination() const;
|
||||
QString label() const;
|
||||
// The same press, as though this chord were typed.
|
||||
std::unique_ptr<QKeyEvent> event(const QKeyEvent &like) const;
|
||||
friend bool operator==(const ShortcutChord &, const ShortcutChord &) = default;
|
||||
};
|
||||
|
||||
struct ShortcutDefinition {
|
||||
QString title;
|
||||
QString group;
|
||||
ShortcutChord original;
|
||||
QString id() const { return group + QLatin1Char(':') + title; }
|
||||
bool isMenu() const { return group == QLatin1String("Menus"); }
|
||||
static const std::vector<ShortcutDefinition> &all();
|
||||
};
|
||||
|
||||
// Swift's ShortcutSettings: overrides, kept in QSettings.
|
||||
class ShortcutSettings : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static ShortcutSettings &shared();
|
||||
static constexpr const char *storageKey = "keyboardShortcuts.v1";
|
||||
const QHash<QString, ShortcutChord> &overrides() const { return m_overrides; }
|
||||
ShortcutChord chord(const ShortcutDefinition &definition) const;
|
||||
// A menu entry's key, or a sheet's, as remapped.
|
||||
QKeySequence menu(const QKeySequence &original) const;
|
||||
ShortcutChord native(const ShortcutChord &original) const;
|
||||
// Saves valid overrides; answers whether it did.
|
||||
bool save(const QHash<QString, ShortcutChord> &values);
|
||||
static std::optional<QString> problem(const QHash<QString, ShortcutChord> &values);
|
||||
// Null swallows the press; else the press to handle.
|
||||
std::unique_ptr<QKeyEvent> canvasEvent(const QKeyEvent &event) const;
|
||||
std::unique_ptr<QKeyEvent> textEvent(const QKeyEvent &event) const;
|
||||
// Reads the stored overrides again, as at launch.
|
||||
void reload();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
ShortcutSettings();
|
||||
QHash<QString, ShortcutChord> m_overrides;
|
||||
};
|
||||
|
||||
// Swift's configuredNativeShortcut on a sheet's button.
|
||||
class NativeShortcut : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NativeShortcut(const ShortcutChord &original, QWidget &scope, QAbstractButton &target);
|
||||
// A sheet's default (Return) and cancel (Escape) buttons.
|
||||
static void bind(QWidget &scope, QAbstractButton *apply, QAbstractButton *cancel);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void synchronize();
|
||||
|
||||
const ShortcutChord m_original;
|
||||
QWidget &m_scope;
|
||||
QPointer<QAbstractButton> m_target;
|
||||
QShortcut *const m_shortcut;
|
||||
};
|
||||
|
||||
// A shortcut's button: click, then press the new keys.
|
||||
class ShortcutRecorder : public QPushButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShortcutRecorder(std::function<void()> start, std::function<void(ShortcutChord)> finish, QWidget *parent);
|
||||
void display(const ShortcutChord &chord, bool recording);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
private:
|
||||
const std::function<void()> m_start;
|
||||
const std::function<void(ShortcutChord)> m_finish;
|
||||
bool m_recording = false;
|
||||
};
|
||||
|
||||
// Swift's KeyboardShortcutsSheet, in the "keyboardShortcuts" panel.
|
||||
class KeyboardShortcutsSheet : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
KeyboardShortcutsSheet(std::function<void()> close, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void synchronize();
|
||||
|
||||
const std::function<void()> m_close;
|
||||
QHash<QString, ShortcutChord> m_draft;
|
||||
std::optional<QString> m_recording;
|
||||
QLineEdit *const m_search;
|
||||
QLabel *const m_problem;
|
||||
QPushButton *const m_save;
|
||||
struct Row {
|
||||
QWidget *row;
|
||||
ShortcutRecorder *recorder;
|
||||
const ShortcutDefinition *definition;
|
||||
};
|
||||
std::vector<Row> m_rows;
|
||||
};
|
||||
Reference in new issue
Block a user