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
grekiki 2020-11-20 16:29:29 +01:00 committed by GitHub
parent 7f3bf2093f
commit 7478b21e2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 333 additions and 45 deletions

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

@ -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;
}

View File

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

View File

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