Qt keyboard (#2381)
* add keyboard * put widget in settings * port a keyboard * forgot git add * reduce diff * submodules * fix macOS and reduce diff * cleanup * little more cleanup * test input * not working yet * compiles now * add stuff * add keyboard on panel 3 * works now * small layout improvements * cleanup * styling * cleanup Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Willem Melching <willem.melching@gmail.com>pull/2586/head
parent
7f3bf2093f
commit
7478b21e2e
|
@ -71,7 +71,7 @@ else:
|
|||
else:
|
||||
qt_libs += [f"Qt5{m}" for m in qt_modules]
|
||||
|
||||
qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc"] + src
|
||||
qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt//offroad/keyboard.cc", "qt/offroad/input_field.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc"] + src
|
||||
qt_env.Program("_ui", qt_src, LIBS=qt_libs + libs)
|
||||
|
||||
# spinner and text window
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#include <QEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "input_field.hpp"
|
||||
#include "keyboard.hpp"
|
||||
|
||||
InputField::InputField(QWidget *parent): QWidget(parent) {
|
||||
l = new QVBoxLayout();
|
||||
QHBoxLayout *r = new QHBoxLayout();
|
||||
label = new QLabel(this);
|
||||
label->setText("password");
|
||||
r->addWidget(label);
|
||||
QPushButton* cancel = new QPushButton("cancel");
|
||||
QObject::connect(cancel, SIGNAL(released()), this, SLOT(emitEmpty()));
|
||||
cancel->setFixedHeight(150);
|
||||
cancel->setFixedWidth(300);
|
||||
r->addWidget(cancel);
|
||||
l->addLayout(r);
|
||||
l->addSpacing(80);
|
||||
|
||||
line = new QLineEdit("");
|
||||
l->addWidget(line);
|
||||
l->addSpacing(200);
|
||||
|
||||
k = new Keyboard(this);
|
||||
QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(getText(QString)));
|
||||
l->addWidget(k);
|
||||
setLayout(l);
|
||||
}
|
||||
|
||||
void InputField::emitEmpty(){
|
||||
emitText("");
|
||||
line->setText("");
|
||||
}
|
||||
void InputField::getText(QString s){
|
||||
if(!QString::compare(s,"⌫")){
|
||||
line->backspace();
|
||||
}
|
||||
|
||||
if(!QString::compare(s,"⏎")){
|
||||
emitText(line->text());
|
||||
line->setText("");
|
||||
}
|
||||
|
||||
QVector<QString> control_buttons {"⇧", "↑", "ABC", "⏎", "#+=", "⌫", "123"};
|
||||
for(QString c :control_buttons){
|
||||
if(!QString::compare(s, c)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
line->insert(s.left(1));
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "keyboard.hpp"
|
||||
|
||||
class InputField : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputField(QWidget* parent = 0);
|
||||
QLabel *label;
|
||||
|
||||
private:
|
||||
QLineEdit *line;
|
||||
Keyboard *k;
|
||||
QVBoxLayout *l;
|
||||
|
||||
public slots:
|
||||
void emitEmpty();
|
||||
void getText(QString s);
|
||||
|
||||
signals:
|
||||
void emitText(QString s);
|
||||
};
|
|
@ -0,0 +1,117 @@
|
|||
#include <QDebug>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QStackedLayout>
|
||||
|
||||
#include "keyboard.hpp"
|
||||
|
||||
KeyboardLayout::KeyboardLayout(QWidget* parent, std::vector<QVector<QString>> layout) : QWidget(parent) {
|
||||
QVBoxLayout* vlayout = new QVBoxLayout;
|
||||
QButtonGroup* btn_group = new QButtonGroup(this);
|
||||
|
||||
QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*)));
|
||||
|
||||
int i = 0;
|
||||
for(auto s : layout){
|
||||
QHBoxLayout *hlayout = new QHBoxLayout;
|
||||
|
||||
if (i == 1){
|
||||
hlayout->addSpacing(50);
|
||||
}
|
||||
|
||||
for(QString p : s){
|
||||
QPushButton* btn = new QPushButton(p);
|
||||
btn->setFixedHeight(100);
|
||||
|
||||
if (p == QString(" ")){
|
||||
btn->setFixedWidth(1024);
|
||||
}
|
||||
|
||||
btn_group->addButton(btn);
|
||||
hlayout->addSpacing(5);
|
||||
hlayout->addWidget(btn);
|
||||
}
|
||||
|
||||
if (i == 1){
|
||||
hlayout->addSpacing(50);
|
||||
}
|
||||
|
||||
vlayout->addLayout(hlayout);
|
||||
i++;
|
||||
}
|
||||
|
||||
setLayout(vlayout);
|
||||
}
|
||||
|
||||
Keyboard::Keyboard(QWidget *parent) : QWidget(parent) {
|
||||
main_layout = new QStackedLayout;
|
||||
|
||||
// lowercase
|
||||
std::vector<QVector<QString>> lowercase = {
|
||||
{"q","w","e","r","t","y","u","i","o","p"},
|
||||
{"a","s","d","f","g","h","j","k","l"},
|
||||
{"⇧","z","x","c","v","b","n","m","⌫"},
|
||||
{"123"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, lowercase));
|
||||
|
||||
// uppercase
|
||||
std::vector<QVector<QString>> uppercase = {
|
||||
{"Q","W","E","R","T","Y","U","I","O","P"},
|
||||
{"A","S","D","F","G","H","J","K","L"},
|
||||
{"↑","Z","X","C","V","B","N","M","⌫"},
|
||||
{"123"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, uppercase));
|
||||
|
||||
// 1234567890
|
||||
std::vector<QVector<QString>> numbers = {
|
||||
{"1","2","3","4","5","6","7","8","9","0"},
|
||||
{"-","/",":",";","(",")","$","&&","@","\""},
|
||||
{"#+=",".",",","?","!","`","⌫"},
|
||||
{"ABC"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, numbers));
|
||||
|
||||
// Special characters
|
||||
std::vector<QVector<QString>> specials = {
|
||||
{"[","]","{","}","#","%","^","*","+","="},
|
||||
{"_","\\","|","~","<",">","€","£","¥"," "},
|
||||
{"123",".",",","?","!","`","⌫"},
|
||||
{"ABC"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, specials));
|
||||
|
||||
setLayout(main_layout);
|
||||
main_layout->setCurrentIndex(0);
|
||||
|
||||
setStyleSheet(R"(
|
||||
QPushButton { font-size: 40px }
|
||||
* {
|
||||
background-color: #99777777;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
|
||||
void Keyboard::handleButton(QAbstractButton* m_button){
|
||||
QString id = m_button->text();
|
||||
if(!QString::compare(m_button->text(),"↑")||!QString::compare(m_button->text(),"ABC")){
|
||||
main_layout->setCurrentIndex(0);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"⇧")){
|
||||
main_layout->setCurrentIndex(1);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"123")){
|
||||
main_layout->setCurrentIndex(2);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"#+=")){
|
||||
main_layout->setCurrentIndex(3);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"⏎")){
|
||||
main_layout->setCurrentIndex(0);
|
||||
}
|
||||
emit emitButton(m_button->text());
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QStackedLayout>
|
||||
#include <QAbstractButton>
|
||||
|
||||
class KeyboardLayout : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout);
|
||||
};
|
||||
|
||||
class Keyboard : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Keyboard(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QStackedLayout* main_layout;
|
||||
|
||||
private slots:
|
||||
void handleButton(QAbstractButton* m_button);
|
||||
|
||||
signals:
|
||||
void emitButton(QString s);
|
||||
};
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "wifi.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "input_field.hpp"
|
||||
|
||||
#include "common/params.h"
|
||||
|
||||
|
@ -167,7 +168,7 @@ QWidget * device_panel() {
|
|||
}
|
||||
|
||||
QWidget * developer_panel() {
|
||||
QVBoxLayout *developer_layout = new QVBoxLayout;
|
||||
QVBoxLayout *main_layout = new QVBoxLayout;
|
||||
|
||||
// TODO: enable SSH toggle and github keys
|
||||
|
||||
|
@ -182,11 +183,11 @@ QWidget * developer_panel() {
|
|||
|
||||
for (auto l : labels) {
|
||||
QString text = QString::fromStdString(l.first + ": " + l.second);
|
||||
developer_layout->addWidget(new QLabel(text));
|
||||
main_layout->addWidget(new QLabel(text));
|
||||
}
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(developer_layout);
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
#include <QLineEdit>
|
||||
#include <QCoreApplication>
|
||||
#include <QButtonGroup>
|
||||
#include <QStackedLayout>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include "wifi.hpp"
|
||||
#include "wifiManager.hpp"
|
||||
#include "input_field.hpp"
|
||||
|
||||
CustomConnectButton::CustomConnectButton(QString text, int iid){
|
||||
setText(text);
|
||||
id=iid;
|
||||
|
@ -31,30 +33,37 @@ void clearLayout(QLayout* layout){
|
|||
}
|
||||
|
||||
WifiUI::WifiUI(QWidget *parent) : QWidget(parent) {
|
||||
vlayout = new QVBoxLayout;
|
||||
wifi = new WifiManager;
|
||||
refresh();
|
||||
setLayout(vlayout);
|
||||
|
||||
setStyleSheet(R"(
|
||||
QLabel { font-size: 40px }
|
||||
QPushButton:enabled {
|
||||
background-color: #114265;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
background-color: #323C43;
|
||||
}
|
||||
* {
|
||||
background-color: #114265;
|
||||
}
|
||||
)");
|
||||
QVBoxLayout * top_layout = new QVBoxLayout;
|
||||
swidget = new QStackedWidget;
|
||||
|
||||
// Networks page
|
||||
wifi_widget = new QWidget;
|
||||
vlayout = new QVBoxLayout;
|
||||
wifi_widget->setLayout(vlayout);
|
||||
swidget->addWidget(wifi_widget);
|
||||
|
||||
// Keyboard page
|
||||
a = new InputField();
|
||||
QObject::connect(a, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString)));
|
||||
swidget->addWidget(a);
|
||||
swidget->setCurrentIndex(0);
|
||||
|
||||
top_layout->addWidget(swidget);
|
||||
setLayout(top_layout);
|
||||
a->setStyleSheet(R"(
|
||||
QLineEdit {
|
||||
background-color: #114265;
|
||||
}
|
||||
)");
|
||||
|
||||
// TODO: implement (not) connecting with wrong password
|
||||
|
||||
// Update network list every second
|
||||
// Update network list
|
||||
timer = new QTimer(this);
|
||||
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
|
||||
timer->start(1000);
|
||||
timer->start(400);
|
||||
|
||||
// Scan on startup
|
||||
wifi->request_scan();
|
||||
|
@ -91,7 +100,25 @@ void WifiUI::refresh(){
|
|||
|
||||
hlayout->addWidget(m_button);
|
||||
hlayout->addSpacing(20);
|
||||
vlayout->addLayout(hlayout);
|
||||
|
||||
QWidget * w = new QWidget;
|
||||
w->setLayout(hlayout);
|
||||
vlayout->addWidget(w);
|
||||
|
||||
w->setStyleSheet(R"(
|
||||
QLabel {
|
||||
font-size: 40px
|
||||
}
|
||||
QPushButton:enabled {
|
||||
background-color: #114265;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
background-color: #323C43;
|
||||
}
|
||||
* {
|
||||
background-color: #114265;
|
||||
}
|
||||
)");
|
||||
i+=1;
|
||||
}
|
||||
}
|
||||
|
@ -99,26 +126,34 @@ void WifiUI::refresh(){
|
|||
void WifiUI::handleButton(QAbstractButton* button){
|
||||
CustomConnectButton* m_button = static_cast<CustomConnectButton*>(button);
|
||||
int id = m_button->id;
|
||||
qDebug()<<id;
|
||||
Network n = wifi->seen_networks[id];
|
||||
// qDebug() << "Clicked a button:" << id;
|
||||
// qDebug() << n.ssid;
|
||||
a->label->setText("Password for "+n.ssid);
|
||||
if(n.security_type==SecurityType::OPEN){
|
||||
wifi->connect(n);
|
||||
} else if (n.security_type==SecurityType::WPA){
|
||||
bool ok = false;
|
||||
QString password;
|
||||
|
||||
#ifdef QCOM2
|
||||
// TODO: implement touch keyboard
|
||||
#else
|
||||
password = QInputDialog::getText(this, "Password for "+n.ssid, "Password", QLineEdit::Normal, "", &ok);
|
||||
#endif
|
||||
if (ok){
|
||||
QString password = getStringFromUser();
|
||||
if(password != ""){
|
||||
wifi->connect(n, password);
|
||||
}
|
||||
|
||||
} else {
|
||||
qDebug() << "Cannot determine a network's security type";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString WifiUI::getStringFromUser(){
|
||||
swidget->setCurrentIndex(1);
|
||||
|
||||
loop.exec();
|
||||
|
||||
swidget->setCurrentIndex(0);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
void WifiUI::receiveText(QString t){
|
||||
loop.quit();
|
||||
text = t;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,46 @@
|
|||
#pragma once
|
||||
#include "wifiManager.hpp"
|
||||
#include "input_field.hpp"
|
||||
#include <QWidget>
|
||||
#include <QtDBus>
|
||||
#include <QPushButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
class CustomConnectButton : public QPushButton{
|
||||
|
||||
public:
|
||||
explicit CustomConnectButton(QString text, int iid);
|
||||
int id;
|
||||
explicit CustomConnectButton(QString text, int iid);
|
||||
int id;
|
||||
};
|
||||
|
||||
class WifiUI : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
WifiManager* wifi;
|
||||
QVBoxLayout* vlayout;
|
||||
QTimer * timer;
|
||||
private:
|
||||
WifiManager* wifi;
|
||||
|
||||
public:
|
||||
explicit WifiUI(QWidget *parent = 0);
|
||||
QStackedWidget* swidget;
|
||||
QVBoxLayout* vlayout;
|
||||
QWidget * wifi_widget;
|
||||
|
||||
private slots:
|
||||
void handleButton(QAbstractButton* m_button);
|
||||
void refresh();
|
||||
InputField *a;
|
||||
QEventLoop loop;
|
||||
QTimer * timer;
|
||||
QString text;
|
||||
QString getStringFromUser();
|
||||
|
||||
public:
|
||||
explicit WifiUI(QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void handleButton(QAbstractButton* m_button);
|
||||
void refresh();
|
||||
void receiveText(QString text);
|
||||
signals:
|
||||
void gotText();
|
||||
};
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <QMouseEvent>
|
||||
|
||||
#include "window.hpp"
|
||||
#include "offroad/input_field.hpp"
|
||||
#include "offroad/settings.hpp"
|
||||
#include "offroad/onboarding.hpp"
|
||||
|
||||
#include "paint.hpp"
|
||||
#include "common/util.h"
|
||||
|
@ -56,6 +59,9 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
|
|||
onboardingWindow = new OnboardingWindow(this);
|
||||
main_layout->addWidget(onboardingWindow);
|
||||
|
||||
InputField *inputField = new InputField(this);
|
||||
main_layout->addWidget(inputField);
|
||||
|
||||
main_layout->setMargin(0);
|
||||
setLayout(main_layout);
|
||||
QObject::connect(glWindow, SIGNAL(openSettings()), this, SLOT(openSettings()));
|
||||
|
|
Loading…
Reference in New Issue