12.2b: the Keyboard Shortcuts window and remapped keys everywhere (Compositor 1.1.6)

This commit is contained in:
雷电芽衣 committed 2026-09-26 19:17:50 -04:00
1 parent f1b2c65c1e
commit 4bfc6c237e
29 files changed
+1645 -164

No files matched your search

+133
View File
@@ -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;
};