Files
qad/libs/virtual_keyboard/virtual_keyboard_layout_page.cpp

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());
}