Add Github SSH keys (#19879)
parent
80799c7272
commit
7408569c1b
|
@ -140,6 +140,7 @@ def flash_agnos_update(manifest_path, cloudlog, spinner=None):
|
|||
break
|
||||
|
||||
except requests.exceptions.RequestException:
|
||||
cloudlog.exception("Failed")
|
||||
spinner.update("Waiting for internet...")
|
||||
cloudlog.info(f"Failed to download {partition['name']}, retrying ({retries})")
|
||||
time.sleep(10)
|
||||
|
|
|
@ -18,8 +18,8 @@ else:
|
|||
qt_libs = qt_env["LIBS"] + libs + ["pthread", "ssl", "crypto"]
|
||||
|
||||
widgets = qt_env.Library("qt_widgets",
|
||||
["qt/qt_window.cc", "qt/qt_sound.cc", "qt/widgets/keyboard.cc", "qt/widgets/input_field.cc", "qt/widgets/drive_stats.cc",
|
||||
"qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc", "qt/widgets/toggle.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc"],
|
||||
["qt/qt_window.cc", "qt/qt_sound.cc", "qt/widgets/keyboard.cc", "qt/widgets/input_field.cc", "qt/widgets/drive_stats.cc", "qt/widgets/ssh_keys.cc",
|
||||
"qt/offroad/networking.cc", "qt/offroad/wifiManager.cc", "qt/widgets/toggle.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc"],
|
||||
LIBS=qt_libs)
|
||||
qt_libs.append(widgets)
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#include <QLineEdit>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include "wifi.hpp"
|
||||
#include "widgets/toggle.hpp"
|
||||
#include "networking.hpp"
|
||||
|
||||
void clearLayout(QLayout* layout) {
|
||||
while (QLayoutItem* item = layout->takeAt(0)) {
|
||||
|
@ -27,6 +26,20 @@ QWidget* layoutToWidget(QLayout* l, QWidget* parent){
|
|||
return q;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/478898/how-do-i-execute-a-command-and-get-the-output-of-the-command-within-c-using-po
|
||||
std::string exec(const char* cmd) {
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
|
||||
if (!pipe) {
|
||||
throw std::runtime_error("popen() failed!");
|
||||
}
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
|
||||
result += buffer.data();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Networking functions
|
||||
|
||||
Networking::Networking(QWidget* parent) : QWidget(parent){
|
||||
|
@ -179,7 +192,7 @@ QFrame* hline(QWidget* parent = 0){
|
|||
// AdvancedNetworking functions
|
||||
|
||||
AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){
|
||||
s = new QStackedLayout;// inputField and settings
|
||||
s = new QStackedLayout;// inputField, mainPage, SSH settings
|
||||
inputField = new InputField(this, 8);
|
||||
connect(inputField, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString)));
|
||||
connect(inputField, SIGNAL(cancel()), this, SLOT(abortTextInput()));
|
||||
|
@ -191,7 +204,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
|
|||
//Back button
|
||||
QHBoxLayout* backLayout = new QHBoxLayout;
|
||||
QPushButton* back = new QPushButton("BACK");
|
||||
back->setFixedWidth(500);
|
||||
back->setFixedSize(500, 100);
|
||||
connect(back, &QPushButton::released, [=](){emit backPress();});
|
||||
backLayout->addWidget(back, 0, Qt::AlignLeft);
|
||||
vlayout->addWidget(layoutToWidget(backLayout, this), 0, Qt::AlignLeft);
|
||||
|
@ -222,28 +235,36 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
|
|||
|
||||
//IP adress
|
||||
QHBoxLayout* IPlayout = new QHBoxLayout;
|
||||
IPlayout->addWidget(new QLabel("IP address: "), 0);
|
||||
IPlayout->addWidget(new QLabel("IP address"), 0);
|
||||
ipLabel = new QLabel(wifi->ipv4_address);
|
||||
ipLabel->setStyleSheet("color: #aaaaaa");
|
||||
IPlayout->addWidget(ipLabel, 0, Qt::AlignRight);
|
||||
vlayout->addWidget(layoutToWidget(IPlayout, this), 0);
|
||||
vlayout->addWidget(hline(), 0);
|
||||
vlayout->addSpacing(300);
|
||||
|
||||
// //Enable SSH
|
||||
// QHBoxLayout* enableSSHLayout = new QHBoxLayout(this);
|
||||
// enableSSHLayout->addWidget(new QLabel("Enable SSH", this));
|
||||
// Toggle* toggle_switch_SSH = new Toggle(this);
|
||||
// toggle_switch_SSH->setFixedSize(150, 100);
|
||||
// enableSSHLayout->addWidget(toggle_switch_SSH);
|
||||
// vlayout->addWidget(layoutToWidget(enableSSHLayout, this));
|
||||
//Enable SSH
|
||||
QHBoxLayout* enableSSHLayout = new QHBoxLayout(this);
|
||||
enableSSHLayout->addWidget(new QLabel("Enable SSH", this));
|
||||
toggle_switch_SSH = new Toggle(this);
|
||||
toggle_switch_SSH->immediateOffset = 40;
|
||||
toggle_switch_SSH->setFixedSize(150, 100);
|
||||
if (isSSHEnabled()) {
|
||||
toggle_switch_SSH->togglePosition();
|
||||
}
|
||||
QObject::connect(toggle_switch_SSH, SIGNAL(stateChanged(int)), this, SLOT(toggleSSH(int)));
|
||||
enableSSHLayout->addWidget(toggle_switch_SSH);
|
||||
vlayout->addWidget(layoutToWidget(enableSSHLayout, this));
|
||||
vlayout->addWidget(hline(), 0);
|
||||
|
||||
// //Authorized SSH keys
|
||||
// QHBoxLayout* authSSHLayout = new QHBoxLayout(this);
|
||||
// authSSHLayout->addWidget(new QLabel("Authorized SSH keys", this));
|
||||
// QPushButton* editAuthSSHButton = new QPushButton("EDIT", this);
|
||||
// authSSHLayout->addWidget(editAuthSSHButton);
|
||||
// vlayout->addWidget(layoutToWidget(authSSHLayout, this));
|
||||
//Authorized SSH keys
|
||||
QHBoxLayout* authSSHLayout = new QHBoxLayout(this);
|
||||
authSSHLayout->addWidget(new QLabel("Authorized SSH keys", this));
|
||||
QPushButton* editAuthSSHButton = new QPushButton("EDIT", this);
|
||||
editAuthSSHButton->setFixedWidth(500);
|
||||
connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentIndex(2);});
|
||||
authSSHLayout->addWidget(editAuthSSHButton);
|
||||
vlayout->addWidget(layoutToWidget(authSSHLayout, this));
|
||||
vlayout->addSpacing(50);
|
||||
|
||||
// //Disconnect or delete connections
|
||||
// QHBoxLayout* dangerZone = new QHBoxLayout(this);
|
||||
|
@ -258,11 +279,24 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
|
|||
settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;");
|
||||
s->addWidget(settingsWidget);
|
||||
s->setCurrentIndex(1);
|
||||
|
||||
ssh = new SSH;
|
||||
connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentIndex(1);});
|
||||
s->addWidget(ssh);
|
||||
|
||||
setLayout(s);
|
||||
}
|
||||
|
||||
bool AdvancedNetworking::isSSHEnabled(){
|
||||
QString response = QString::fromStdString(exec("systemctl is-active ssh"));
|
||||
return response.startsWith("active");
|
||||
}
|
||||
|
||||
void AdvancedNetworking::refresh(){
|
||||
ipLabel->setText(wifi->ipv4_address);
|
||||
if (toggle_switch_SSH->on != isSSHEnabled()) {
|
||||
toggle_switch_SSH->togglePosition();
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedNetworking::toggleTethering(int enable) {
|
||||
|
@ -273,7 +307,16 @@ void AdvancedNetworking::toggleTethering(int enable) {
|
|||
}
|
||||
editPasswordButton->setEnabled(!enable);
|
||||
}
|
||||
void AdvancedNetworking::toggleSSH(int enable) {
|
||||
if (enable) {
|
||||
system("sudo systemctl enable ssh");
|
||||
system("sudo systemctl start ssh");
|
||||
} else {
|
||||
system("sudo systemctl stop ssh");
|
||||
system("sudo systemctl disable ssh");
|
||||
|
||||
}
|
||||
}
|
||||
void AdvancedNetworking::receiveText(QString text){
|
||||
wifi->changeTetheringPassword(text);
|
||||
s->setCurrentIndex(1);
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
#include "wifiManager.hpp"
|
||||
#include "widgets/input_field.hpp"
|
||||
|
||||
#include "widgets/ssh_keys.hpp"
|
||||
#include "widgets/toggle.hpp"
|
||||
|
||||
class WifiUI : public QWidget {
|
||||
Q_OBJECT
|
||||
|
@ -49,10 +50,12 @@ private:
|
|||
InputField* inputField;
|
||||
QLabel* ipLabel;
|
||||
QPushButton* editPasswordButton;
|
||||
|
||||
SSH* ssh;
|
||||
Toggle* toggle_switch_SSH;
|
||||
|
||||
WifiManager* wifi = nullptr;
|
||||
|
||||
bool isSSHEnabled();
|
||||
signals:
|
||||
void openKeyboard();
|
||||
void closeKeyboard();
|
||||
|
@ -62,6 +65,7 @@ public slots:
|
|||
void receiveText(QString text);
|
||||
void abortTextInput();
|
||||
void toggleTethering(int enable);
|
||||
void toggleSSH(int enable);
|
||||
void refresh();
|
||||
};
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "wifi.hpp"
|
||||
#include "networking.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "widgets/toggle.hpp"
|
||||
#include "widgets/offroad_alerts.hpp"
|
||||
|
@ -145,7 +145,7 @@ QWidget * device_panel() {
|
|||
//}
|
||||
|
||||
for (auto &l : labels) {
|
||||
device_layout->addWidget(labelWidget(QString::fromStdString(l.first+":"), QString::fromStdString(l.second)), 0, Qt::AlignTop);
|
||||
device_layout->addWidget(labelWidget(QString::fromStdString(l.first), QString::fromStdString(l.second)), 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
// TODO: show current calibration values
|
||||
|
@ -206,7 +206,7 @@ QWidget * developer_panel() {
|
|||
|
||||
for (int i = 0; i<labels.size(); i++) {
|
||||
auto l = labels[i];
|
||||
main_layout->addWidget(labelWidget(QString::fromStdString(l.first+":"), QString::fromStdString(l.second)));
|
||||
main_layout->addWidget(labelWidget(QString::fromStdString(l.first), QString::fromStdString(l.second)));
|
||||
|
||||
if(i+1<labels.size()) {
|
||||
main_layout->addWidget(horizontal_line());
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <QButtonGroup>
|
||||
#include <QStackedLayout>
|
||||
|
||||
#include "wifi.hpp"
|
||||
#include "networking.hpp"
|
||||
|
||||
// *** settings widgets ***
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) {
|
|||
// Special characters
|
||||
std::vector<QVector<QString>> specials = {
|
||||
{"[","]","{","}","#","%","^","*","+","="},
|
||||
{"_","\\","|","~","<",">","€","£","¥"," "},
|
||||
{"_","\\","|","~","<",">","€","£","¥","•"},
|
||||
{"123",".",",","?","!","`","⌫"},
|
||||
{"ABC"," ","⏎"},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QState>
|
||||
#include <QStateMachine>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "widgets/ssh_keys.hpp"
|
||||
#include "widgets/input_field.hpp"
|
||||
#include "common/params.h"
|
||||
|
||||
QWidget* layout_to_widget(QLayout* l){
|
||||
QWidget* q = new QWidget;
|
||||
q->setLayout(l);
|
||||
return q;
|
||||
}
|
||||
|
||||
SSH::SSH(QWidget* parent) : QWidget(parent){
|
||||
// init variables
|
||||
manager = new QNetworkAccessManager(this);
|
||||
networkTimer = new QTimer(this);
|
||||
networkTimer->setSingleShot(true);
|
||||
networkTimer->setInterval(5000);
|
||||
connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
|
||||
|
||||
// Construct the layouts to display
|
||||
slayout = new QStackedLayout(this); // Initial screen, input, waiting for response
|
||||
|
||||
//Layout on entering
|
||||
QVBoxLayout* initialLayout = new QVBoxLayout;
|
||||
initialLayout->setContentsMargins(80, 80, 80, 80);
|
||||
|
||||
QHBoxLayout* header = new QHBoxLayout;
|
||||
QPushButton* exitButton = new QPushButton("BACK", this);
|
||||
exitButton->setFixedSize(500, 100);
|
||||
header->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop);
|
||||
initialLayout->addWidget(layout_to_widget(header));
|
||||
|
||||
QLabel* title = new QLabel("Authorize SSH keys");
|
||||
title->setStyleSheet(R"(font-size: 75px;)");
|
||||
header->addWidget(title, 0, Qt::AlignRight | Qt::AlignTop);
|
||||
|
||||
QLabel* wallOfText = new QLabel("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A Comma employee will NEVER ask you to add their GitHub username.");
|
||||
wallOfText->setWordWrap(true);
|
||||
wallOfText->setStyleSheet(R"(font-size: 60px;)");
|
||||
initialLayout->addWidget(wallOfText, 0);
|
||||
|
||||
QPushButton* actionButton = new QPushButton;
|
||||
actionButton->setFixedHeight(100);
|
||||
initialLayout->addWidget(actionButton, 0, Qt::AlignBottom);
|
||||
|
||||
slayout->addWidget(layout_to_widget(initialLayout));
|
||||
|
||||
InputField* input = new InputField;
|
||||
slayout->addWidget(input);
|
||||
|
||||
QLabel* loading = new QLabel("Loading SSH keys from GitHub.");
|
||||
slayout->addWidget(loading);
|
||||
setStyleSheet(R"(
|
||||
QPushButton {
|
||||
font-size: 60px;
|
||||
margin: 0px;
|
||||
padding: 15px;
|
||||
border-radius: 25px;
|
||||
color: #dddddd;
|
||||
background-color: #444444;
|
||||
}
|
||||
)");
|
||||
setLayout(slayout);
|
||||
|
||||
|
||||
//Initialize the state machine and states
|
||||
QStateMachine* state = new QStateMachine(this);
|
||||
QState* initialState = new QState(); //State when entering the widget
|
||||
QState* initialStateNoGithub = new QState(); //Starting state, key not connected
|
||||
QState* initialStateConnected = new QState(); //Starting state, ssh connected
|
||||
QState* quitState = new QState(); // State when exiting the widget
|
||||
QState* removeSSH_State = new QState(); // State when user wants to remove the SSH keys
|
||||
QState* defaultInputFieldState = new QState(); // State when we want the user to give us the username
|
||||
QState* loadingState = new QState(); // State while waiting for the network response
|
||||
|
||||
|
||||
// Adding states to the state machine and adding the transitions
|
||||
state->addState(initialState);
|
||||
connect(initialState, &QState::entered, [=](){checkForSSHKey(); slayout->setCurrentIndex(0);});
|
||||
initialState->addTransition(this, &SSH::NoSSHAdded, initialStateNoGithub);
|
||||
initialState->addTransition(this, &SSH::SSHAdded, initialStateConnected);
|
||||
|
||||
|
||||
state->addState(quitState);
|
||||
connect(quitState, &QState::entered, [=](){emit closeSSHSettings();});
|
||||
quitState->addTransition(quitState, &QState::entered, initialState);
|
||||
|
||||
state->addState(initialStateConnected);
|
||||
connect(initialStateConnected, &QState::entered, [=](){actionButton->setText("Remove GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #750c0c;)");});
|
||||
initialStateConnected->addTransition(exitButton, &QPushButton::released, quitState);
|
||||
initialStateConnected->addTransition(actionButton, &QPushButton::released, removeSSH_State);
|
||||
|
||||
state->addState(removeSSH_State);
|
||||
connect(removeSSH_State, &QState::entered, [=](){Params().delete_db_value("GithubSshKeys");});
|
||||
removeSSH_State->addTransition(removeSSH_State, &QState::entered, initialState);
|
||||
|
||||
state->addState(initialStateNoGithub);
|
||||
connect(initialStateNoGithub, &QState::entered, [=](){actionButton->setText("Link GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #444444;)");});
|
||||
initialStateNoGithub->addTransition(exitButton, &QPushButton::released, quitState);
|
||||
initialStateNoGithub->addTransition(actionButton, &QPushButton::released, defaultInputFieldState);
|
||||
connect(actionButton, &QPushButton::released, [=](){input->setPromptText("Enter your GitHub username");});
|
||||
|
||||
state->addState(defaultInputFieldState);
|
||||
connect(defaultInputFieldState, &QState::entered, [=](){slayout->setCurrentIndex(1);});
|
||||
connect(input, &InputField::emitText, [=](QString a){usernameGitHub = a;}); // Store the string the user provided
|
||||
defaultInputFieldState->addTransition(input, &InputField::cancel, initialState);
|
||||
defaultInputFieldState->addTransition(input, &InputField::emitText, loadingState);
|
||||
|
||||
state->addState(loadingState);
|
||||
connect(loadingState, &QState::entered, [=](){slayout->setCurrentIndex(2); getSSHKeys();});
|
||||
connect(this, &SSH::failedResponse, [=](QString message){input->setPromptText(message);});
|
||||
loadingState->addTransition(this, &SSH::failedResponse, defaultInputFieldState);
|
||||
loadingState->addTransition(this, &SSH::gotSSHKeys, initialState);
|
||||
|
||||
|
||||
state->setInitialState(initialState);
|
||||
state->start();
|
||||
}
|
||||
|
||||
void SSH::checkForSSHKey(){
|
||||
QString SSHKey = QString::fromStdString(Params().get("GithubSshKeys"));
|
||||
if (SSHKey.length()) {
|
||||
emit SSHAdded();
|
||||
} else {
|
||||
emit NoSSHAdded();
|
||||
}
|
||||
}
|
||||
|
||||
void SSH::getSSHKeys(){
|
||||
QString url = "https://github.com/" + usernameGitHub + ".keys";
|
||||
aborted = false;
|
||||
reply = manager->get(QNetworkRequest(QUrl(url)));
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(parseResponse()));
|
||||
networkTimer->start();
|
||||
}
|
||||
|
||||
void SSH::timeout(){
|
||||
aborted = true;
|
||||
reply->abort();
|
||||
}
|
||||
|
||||
void SSH::parseResponse(){
|
||||
if (!aborted) {
|
||||
networkTimer->stop();
|
||||
QString response = reply->readAll();
|
||||
if (reply->error() == QNetworkReply::NoError && response.length()) {
|
||||
Params().write_db_value("GithubSshKeys", response.toStdString());
|
||||
emit gotSSHKeys();
|
||||
} else {
|
||||
emit failedResponse("Username "+usernameGitHub+" doesn't exist");
|
||||
}
|
||||
}else{
|
||||
emit failedResponse("Request timed out");
|
||||
}
|
||||
reply->deleteLater();
|
||||
reply = NULL;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QButtonGroup>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStackedWidget>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include "widgets/input_field.hpp"
|
||||
|
||||
class SSH : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SSH(QWidget* parent = 0);
|
||||
|
||||
private:
|
||||
InputField* inputField;
|
||||
QStackedLayout* slayout;
|
||||
QString usernameGitHub;
|
||||
QNetworkAccessManager* manager;
|
||||
QNetworkReply* reply;
|
||||
QTimer* networkTimer;
|
||||
bool aborted;
|
||||
|
||||
signals:
|
||||
void closeSSHSettings();
|
||||
void openKeyboard();
|
||||
void closeKeyboard();
|
||||
void NoSSHAdded();
|
||||
void SSHAdded();
|
||||
void failedResponse(QString errorString);
|
||||
void gotSSHKeys();
|
||||
|
||||
private slots:
|
||||
void checkForSSHKey();
|
||||
void getSSHKeys();
|
||||
void timeout();
|
||||
void parseResponse();
|
||||
};
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
Toggle::Toggle(QWidget *parent) : QAbstractButton(parent),
|
||||
_height(80),
|
||||
_height_rect(60),
|
||||
_on(false),
|
||||
on(false),
|
||||
_anim(new QPropertyAnimation(this, "offset_circle", this))
|
||||
{
|
||||
_radius = _height / 2;
|
||||
|
@ -32,20 +32,27 @@ void Toggle::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void Toggle::mouseReleaseEvent(QMouseEvent *e) {
|
||||
const int left = _radius;
|
||||
const int right = width() - _radius;
|
||||
if(_x_circle != left && _x_circle != right){
|
||||
//Don't parse touch events, while the animation is running
|
||||
return;
|
||||
}
|
||||
if (e->button() & Qt::LeftButton) {
|
||||
togglePosition();
|
||||
emit stateChanged(_on);
|
||||
emit stateChanged(on);
|
||||
}
|
||||
}
|
||||
|
||||
void Toggle::togglePosition() {
|
||||
_on = !_on;
|
||||
on = !on;
|
||||
const int left = _radius;
|
||||
const int right = width() - _radius;
|
||||
_anim->setStartValue(_on ? left : right);
|
||||
_anim->setEndValue(_on ? right : left);
|
||||
_anim->setDuration(120);
|
||||
_anim->setStartValue(on ? left + immediateOffset : right - immediateOffset);
|
||||
_anim->setEndValue(on ? right : left);
|
||||
_anim->setDuration(animation_duration);
|
||||
_anim->start();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void Toggle::enterEvent(QEvent *e) {
|
||||
|
|
|
@ -8,7 +8,9 @@ class Toggle : public QAbstractButton {
|
|||
public:
|
||||
Toggle(QWidget* parent = nullptr);
|
||||
void togglePosition();
|
||||
|
||||
bool on;
|
||||
int animation_duration = 250;
|
||||
int immediateOffset = 0;
|
||||
int offset_circle() const {
|
||||
return _x_circle;
|
||||
}
|
||||
|
@ -18,13 +20,13 @@ public:
|
|||
update();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
void mouseReleaseEvent(QMouseEvent*) override;
|
||||
void enterEvent(QEvent*) override;
|
||||
|
||||
private:
|
||||
bool _on;
|
||||
int _x_circle, _y_circle;
|
||||
int _height, _radius;
|
||||
int _height_rect, _y_rect;
|
||||
|
|
Loading…
Reference in New Issue