155 lines
4.5 KiB
C++
155 lines
4.5 KiB
C++
#include "virtual_keyboard_layout_page.h"
|
|
|
|
#include <QApplication>
|
|
#include <QBoxLayout>
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QKeyEvent>
|
|
#include <QTimer>
|
|
|
|
static const char property_role[] = "role";
|
|
static const char property_page[] = "page";
|
|
static const char property_stretch[] = "stretch";
|
|
|
|
|
|
VirtualKeyboardLayoutPage::VirtualKeyboardLayoutPage(QJsonObject root) {
|
|
auto main_lay = new QBoxLayout(QBoxLayout::TopToBottom);
|
|
name_ = root["name"].toString();
|
|
auto rows = root["rows"].toArray();
|
|
for (auto row: rows) {
|
|
auto rowa = row.toArray();
|
|
QBoxLayout * row_lay = nullptr;
|
|
int cur_cols = 0;
|
|
for (auto rb: rowa) {
|
|
auto * b = createButton(rb.toObject());
|
|
if (!b) continue;
|
|
if (!row_lay) row_lay = new QBoxLayout(QBoxLayout::LeftToRight);
|
|
buttons << b;
|
|
row_lay->addWidget(b, b->property(property_stretch).toInt());
|
|
++cur_cols;
|
|
}
|
|
if (row_lay) main_lay->addLayout(row_lay);
|
|
columns = piMaxi(columns, cur_cols);
|
|
}
|
|
// qDebug() << "VirtualKeyboardLayoutPage" << name;
|
|
setLayout(main_lay);
|
|
}
|
|
|
|
|
|
VirtualKeyboardLayoutPage::~VirtualKeyboardLayoutPage() {}
|
|
|
|
|
|
void VirtualKeyboardLayoutPage::setCapital(bool yes) {
|
|
capital = yes;
|
|
for (auto b: buttons) {
|
|
auto role = buttonRole(b);
|
|
if (role == rLetter) {
|
|
b->setText(yes ? b->text().toUpper() : b->text().toLower());
|
|
}
|
|
if (role == rShift) {
|
|
// b->setText(yes ? QString::fromUtf8("⇫") : QString::fromUtf8("⇧"));
|
|
b->setChecked(yes);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void VirtualKeyboardLayoutPage::setGotoEnabled(bool yes) {
|
|
for (auto b: buttons) {
|
|
auto role = buttonRole(b);
|
|
if (role == rGotoPage) b->setEnabled(yes);
|
|
}
|
|
}
|
|
|
|
|
|
void VirtualKeyboardLayoutPage::setCapitalEnabled(bool yes) {
|
|
capital_enabled = yes;
|
|
for (auto b: buttons) {
|
|
auto role = buttonRole(b);
|
|
if (role == rShift) b->setEnabled(yes);
|
|
}
|
|
}
|
|
|
|
|
|
void VirtualKeyboardLayoutPage::setButtonsSize(int h) {
|
|
for (auto b: buttons) {
|
|
b->setFixedHeight(h);
|
|
}
|
|
if (!isVisible()) {
|
|
adjustSize();
|
|
layout()->invalidate();
|
|
}
|
|
}
|
|
|
|
|
|
QToolButton * VirtualKeyboardLayoutPage::createButton(QJsonObject jb) {
|
|
QString role_str = jb["role"].toString();
|
|
if (role_str.isEmpty()) return nullptr;
|
|
auto ret = new QToolButton();
|
|
int role = roleFromText(role_str);
|
|
int stretch = jb["stretch"].toInt();
|
|
if (stretch == 0) stretch = 1;
|
|
auto text = jb["text"].toString();
|
|
ret->setProperty(property_role, role);
|
|
ret->setProperty(property_stretch, stretch);
|
|
ret->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
ret->setFocusPolicy(Qt::NoFocus);
|
|
ret->setMinimumSize(QSize(2, 2));
|
|
ret->setAutoRepeat(true);
|
|
switch (role) {
|
|
case rBackspace: text = QString::fromUtf8("⌫"); break;
|
|
case rReturn: text = QString::fromUtf8("⏎"); break;
|
|
case rSpace: text = QString::fromUtf8("────"); break;
|
|
case rShift:
|
|
text = QString::fromUtf8("⤊");
|
|
ret->setCheckable(true);
|
|
break; // ⇪⇧⇫⇯⇩⬆⌨
|
|
case rHide: text = QString::fromUtf8("⨂"); break;
|
|
case rGotoPage: ret->setProperty(property_page, jb["page"].toString()); break;
|
|
}
|
|
ret->setText(text);
|
|
connect(ret, &QToolButton::clicked, this, [this, role, ret](bool press) {
|
|
int key = 0;
|
|
QString text;
|
|
switch (role) {
|
|
case rLetter:
|
|
text = ret->text();
|
|
if (text.startsWith('&')) text.remove(0, 1);
|
|
break;
|
|
case rBackspace: key = Qt::Key_Backspace; break;
|
|
case rReturn: key = Qt::Key_Return; break;
|
|
case rSpace:
|
|
key = Qt::Key_Space;
|
|
text = " ";
|
|
break;
|
|
case rHide: emit hideRequest(); break;
|
|
case rShift: setCapital(!isCapital()); break;
|
|
case rGotoPage: emit gotoPageRequest(ret->property(property_page).toString()); break;
|
|
}
|
|
if (key == 0 && text.isEmpty()) return;
|
|
QApplication::postEvent(QApplication::focusWidget(), new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, text));
|
|
QApplication::postEvent(QApplication::focusWidget(), new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier, text));
|
|
if (role == rLetter && isCapital() && capital_enabled) setCapital(false);
|
|
});
|
|
return ret;
|
|
}
|
|
|
|
|
|
VirtualKeyboardLayoutPage::Role VirtualKeyboardLayoutPage::roleFromText(QString str) {
|
|
str = str.toLower();
|
|
if (str == "l") return rLetter;
|
|
if (str == "backspace") return rBackspace;
|
|
if (str == "return") return rReturn;
|
|
if (str == "space") return rSpace;
|
|
if (str == "hide") return rHide;
|
|
if (str == "shift") return rShift;
|
|
if (str == "gotopage") return rGotoPage;
|
|
return rInvalid;
|
|
}
|
|
|
|
|
|
VirtualKeyboardLayoutPage::Role VirtualKeyboardLayoutPage::buttonRole(QToolButton * b) const {
|
|
if (!b) return rInvalid;
|
|
return static_cast<Role>(b->property(property_role).toInt());
|
|
}
|