#include "virtual_keyboard_layout_page.h" #include #include #include #include #include #include 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(b->property(property_role).toInt()); }