- Template sections placed above or to the right of the typing keys; the user picks any mix in settings, typing keys included - keysym keys send XKB keysyms on press, optionally repeating - Geometry lays blocks side by side with one key unit; stretch keys are resolved at layout time so composed blocks line up - Toggling a block resizes the window so keys keep their size Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
2.5 KiB
C
83 lines
2.5 KiB
C
#pragma once
|
|
|
|
#include <QHash>
|
|
#include <QList>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
|
|
enum class KeyType {
|
|
Character,
|
|
Space,
|
|
Backspace,
|
|
Enter,
|
|
Shift,
|
|
LayerSwitch,
|
|
Globe,
|
|
Dismiss,
|
|
Spacer, // empty room, e.g. the half-key indent of the home row
|
|
Letters, // template only: a row of letters from the system keymap
|
|
Keysym, // a non-text key (Home, F5, arrows...): sends `keysym`
|
|
};
|
|
|
|
struct KeyDef {
|
|
KeyType type = KeyType::Character;
|
|
QString label; // shown and typed (for character keys)
|
|
QString shifted; // explicit shifted form; empty means label.toUpper()
|
|
QString flick; // secondary symbol, typed by flicking down
|
|
QStringList alternates; // long-press choices
|
|
QString target; // layer to switch to (LayerSwitch only)
|
|
qreal width = 1.0; // in key units
|
|
bool stretch = false; // grows so the row is as wide as its block's widest
|
|
quint32 keysym = 0; // Keysym keys only
|
|
bool repeat = false; // Keysym keys only: auto-repeat while held
|
|
|
|
// Letters placeholders only.
|
|
int lettersRow = -1; // which keymap row (0 = top)
|
|
QStringList flicks; // flick symbol per letter, left to right
|
|
|
|
// Text this key shows/types; only character keys change case.
|
|
QString text(bool uppercase) const
|
|
{
|
|
if (!uppercase || type != KeyType::Character)
|
|
return label;
|
|
return shifted.isEmpty() ? label.toUpper() : shifted;
|
|
}
|
|
};
|
|
|
|
using Row = QList<KeyDef>;
|
|
|
|
struct Layer {
|
|
QString name;
|
|
QList<Row> rows;
|
|
};
|
|
|
|
// An optional block of keys next to the main one, shown if the user wants it.
|
|
struct Section {
|
|
enum class Placement { Above, Right }; // above the main keys, or a column to their right
|
|
|
|
QString id; // "main" is reserved for the layers
|
|
QString name; // shown in settings
|
|
Placement placement = Placement::Right;
|
|
QList<Row> rows;
|
|
};
|
|
|
|
struct Layout {
|
|
QString id;
|
|
QString name; // human readable, e.g. "Slovak"
|
|
QList<Layer> layers; // the main keys; the first one is shown by default
|
|
QList<Section> sections;
|
|
// Template only: long-press choices for keymap letters, by lowercase letter.
|
|
QHash<QString, QStringList> alternates;
|
|
|
|
const Layer *layer(const QString &layerName) const
|
|
{
|
|
for (const Layer &l : layers) {
|
|
if (l.name == layerName)
|
|
return &l;
|
|
}
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
inline const QString MainSectionId = QStringLiteral("main");
|