171 lines
4.1 KiB
C++
171 lines
4.1 KiB
C++
#include "virtual_keyboard.h"
|
|
|
|
#include "ui_virtual_keyboard.h"
|
|
#include "virtual_keyboard_layout.h"
|
|
#include "virtual_keyboard_layout_page.h"
|
|
|
|
#include <QFile>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QStyle>
|
|
#include <QStyleFactory>
|
|
#include <pibase.h>
|
|
#include <picout.h>
|
|
#include <piliterals_time.h>
|
|
|
|
|
|
VirtualKeyboard::VirtualKeyboard(QWidget * parent): QWidget(parent) {
|
|
ui = new Ui::VirtualKeyboard();
|
|
ui->setupUi(this);
|
|
ui->stackedPages->setStyle(QStyleFactory::create("Fusion"));
|
|
connect(qApp, &QApplication::focusChanged, this, [this](QWidget * old, QWidget * now) {
|
|
if (watched) {
|
|
watched->removeEventFilter(this);
|
|
watched = nullptr;
|
|
}
|
|
if (!now || !layout) {
|
|
setKeyboardVisible(false);
|
|
return;
|
|
}
|
|
if (!now->inputMethodQuery(Qt::ImCursorPosition).isValid()) {
|
|
setKeyboardVisible(false);
|
|
return;
|
|
}
|
|
watched = now;
|
|
auto imh = Qt::InputMethodHints(watched->inputMethodQuery(Qt::ImHints).toInt());
|
|
layout->setDefaultPage();
|
|
setKeyboardVisible(true);
|
|
layout->applyHints(imh);
|
|
watched->installEventFilter(this);
|
|
});
|
|
hide();
|
|
}
|
|
|
|
|
|
VirtualKeyboard::~VirtualKeyboard() {
|
|
if (watched) {
|
|
watched->removeEventFilter(this);
|
|
watched = nullptr;
|
|
}
|
|
destroy();
|
|
delete ui;
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::init(QString layout_path) {
|
|
destroy();
|
|
QFile f(layout_path);
|
|
if (!f.open(QIODevice::ReadOnly)) return;
|
|
QJsonDocument doc = QJsonDocument::fromJson(f.readAll());
|
|
layout = new VirtualKeyboardLayout(doc.object());
|
|
auto pages = layout->getPages();
|
|
for (auto p: pages)
|
|
ui->stackedPages->addWidget(p);
|
|
connect(layout, &VirtualKeyboardLayout::gotoPageRequest, this, [this](QString pagename) {
|
|
auto page = layout->getPageByName(pagename);
|
|
if (!page) return;
|
|
ui->stackedPages->setCurrentWidget(page);
|
|
layout->setCurrentPage(page);
|
|
});
|
|
connect(layout, &VirtualKeyboardLayout::hideRequest, this, [this]() { setKeyboardVisible(false); });
|
|
layout->setDefaultPage();
|
|
// piCout << pages.size();
|
|
adjust();
|
|
}
|
|
|
|
|
|
bool VirtualKeyboard::eventFilter(QObject * o, QEvent * e) {
|
|
if (e->type() == QEvent::MouseButtonPress) setKeyboardVisible(true);
|
|
return QWidget::eventFilter(o, e);
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::changeEvent(QEvent * e) {
|
|
QWidget::changeEvent(e);
|
|
switch (e->type()) {
|
|
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
|
case QEvent::Show: ui->retranslateUi(this); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::resizeEvent(QResizeEvent * e) {
|
|
if (prev_width == width()) return;
|
|
prev_width = width();
|
|
adjust();
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::showEvent(QShowEvent * e) {
|
|
if (first_show) {
|
|
first_show = false;
|
|
if (layout_path_.isEmpty()) init(":/virtual_keyboard/default.json");
|
|
}
|
|
QWidget::showEvent(e);
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::destroy() {
|
|
piDeleteSafety(layout);
|
|
while (ui->stackedPages->count() > 0)
|
|
delete ui->stackedPages->widget(0);
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::adjust() {
|
|
if (!layout) return;
|
|
auto pages = layout->getPages();
|
|
int cols = 0;
|
|
for (auto p: pages)
|
|
cols = piMaxi(cols, p->buttonColumns());
|
|
if (cols < 1) return;
|
|
int spacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, nullptr, this);
|
|
int m[4] = {0, 0, 0, 0};
|
|
ui->verticalLayout->getContentsMargins(&m[0], &m[1], &m[2], &m[3]);
|
|
int pixel_width = width() - spacing * (cols - 1) - m[0] * 2;
|
|
int bw = piMaxi(2, pixel_width / cols);
|
|
ui->stackedPages->setStyleSheet(QString("font:%1px").arg(bw / 2));
|
|
for (auto p: pages)
|
|
p->setButtonsSize(bw);
|
|
// piCout << cols << spacing << bw;
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::setKeyboardVisible(bool yes) {
|
|
if (always_visible || !isEnabled()) return;
|
|
if (yes) {
|
|
stopIndexedTimer(0);
|
|
setVisible(true);
|
|
} else
|
|
startIndexedTimer(0, 10_Hz, [this] {
|
|
if (QApplication::mouseButtons() != 0) return;
|
|
stopIndexedTimer(0);
|
|
setVisible(false);
|
|
});
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::setLayoutPath(const QString & path) {
|
|
layout_path_ = path;
|
|
init(layout_path_);
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::setAlwaysVisible(bool yes) {
|
|
always_visible = yes;
|
|
if (yes) show();
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::setEnabled(bool yes) {
|
|
if (!yes) hide();
|
|
QWidget::setEnabled(yes);
|
|
}
|
|
|
|
|
|
void VirtualKeyboard::setDisabled(bool yes) {
|
|
if (yes) hide();
|
|
QWidget::setDisabled(yes);
|
|
}
|