From c01d1b884dd00f8bc5dba1800f69ee4ac4cf745b Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Mon, 23 Nov 2020 11:57:51 +0100 Subject: [PATCH] - added some fancy animations to the start action buttons - Made everything depend on the LinboBackend state --- headers/backend/linbobackend.h | 68 +++++--- headers/linboosselectbutton.h | 1 - headers/linboosselectionrow.h | 3 + headers/linbostartactions.h | 11 +- headers/linbostartpage.h | 3 +- headers/qmodernpushbutton.h | 10 +- linboGUI.pro.user | 2 +- sources/backend/linbobackend.cpp | 248 +++++++++++++++------------ sources/legacy/linboGUIImplTmp.cpp | 2 +- sources/linboosselectbutton.cpp | 4 +- sources/linboosselectionrow.cpp | 38 +++- sources/linbostartactions.cpp | 140 ++++++++------- sources/linbostartpage.cpp | 64 +++---- sources/qmodernpushbutton.cpp | 32 ++-- sources/qmodernpushbuttonoverlay.cpp | 2 +- 15 files changed, 369 insertions(+), 259 deletions(-) diff --git a/headers/backend/linbobackend.h b/headers/backend/linbobackend.h index b47fbc5..4184def 100644 --- a/headers/backend/linbobackend.h +++ b/headers/backend/linbobackend.h @@ -40,38 +40,36 @@ using namespace std; class LinboBackend : public QObject { Q_OBJECT - Q_PROPERTY(LinboState state READ getState NOTIFY stateChanged) + Q_PROPERTY(LinboBackend::LinboState state READ getState NOTIFY stateChanged) + Q_PROPERTY(LinboOs* currentOs READ getCurrentOs WRITE setCurrentOs NOTIFY currentOsChanged) + public: explicit LinboBackend(QObject *parent = nullptr); enum LinboState { + Initializing, Idle, - Root, - Partitioning, Starting, Syncing, - Reinstalling + Reinstalling, + Root, + Partitioning, + InitializingCache, + Updating }; LinboState getState(); LinboConfig* getConfig(); QList getOperatingSystems(); + LinboOs* getCurrentOs(); + void setCurrentOs(LinboOs* os); protected: - void read_qstring(ifstream* input, QString& tmp ); - void read_bool( ifstream* input, bool& tmp); bool read_pair(ifstream* input, QString& key, QString& value); bool toBool(const QString& value); LinboOs* read_os(ifstream* input); LinboDiskPartition* read_partition(ifstream* input); void read_globals( ifstream* input, LinboConfig* config ); - void saveappend( QStringList& command, const QString& item ); - QStringList mkpartitioncommand(vector &p); - QStringList mkpartitioncommand_noformat(vector &p); - QStringList mkcacheinitcommand(LinboConfig& config, vector &os, const QString& type); - QStringList mklinboupdatecommand(LinboConfig& config); - - void setState(LinboState state); private: LinboState state; @@ -80,12 +78,26 @@ private: QList operatingSystems; QList diskPartitions; - QProcess* process; + LinboOs* currentOs; - QString executeCommand(bool waitForFinished); + QString const linboCmdCommand = "linbo_cmd"; + + QProcess* asynchronosProcess; + QProcess* synchronosProcess; template QString executeCommand(bool waitForFinished, QString argument, const Strings&... arguments) { + return this->executeCommand(waitForFinished, this->linboCmdCommand, this->buildCommand(argument, arguments ...)); + } + + QStringList buildCommand() { + QStringList tmpArguments = this->linboCommandCache; + this->linboCommandCache.clear(); + return tmpArguments; + } + + template + QStringList buildCommand(QString argument, const Strings&... arguments) { // this appends a quoted space in case item is empty and resolves // problems with linbo_cmd's weird "shift"-usage if (argument.isEmpty()) @@ -93,25 +105,33 @@ private: else this->linboCommandCache.append(argument); - return executeCommand(waitForFinished, arguments...); + return buildCommand(arguments...); } - void readFromStdout(); - void readFromStderr(); - QString executeCommand(bool wait, QString command, QStringList commandArgs); + void setState(LinboState state); + public slots: - void executeAutostart(); void shutdown(); void reboot(); - bool startOs(LinboOs* os); - bool syncOs(LinboOs* os); - bool reinstallOs(LinboOs* os); + bool startCurrentOs(); + bool syncCurrentOs(); + bool reinstallCurrentOs(); + + bool partitionDrive(bool format = true); + bool initializeCache(); + bool updateLinbo(); + +private slots: + void executeAutostart(); + void readFromStdout(); + void readFromStderr(); signals: - void stateChanged(); + void stateChanged(LinboBackend::LinboState state); + void currentOsChanged(LinboOs* os); }; diff --git a/headers/linboosselectbutton.h b/headers/linboosselectbutton.h index 0cb5431..af29440 100644 --- a/headers/linboosselectbutton.h +++ b/headers/linboosselectbutton.h @@ -34,7 +34,6 @@ class LinboOsSelectButton : public QWidget public: friend class LinboOsSelectionRow; - protected: void resizeEvent(QResizeEvent *event) override; diff --git a/headers/linboosselectionrow.h b/headers/linboosselectionrow.h index 6d93b65..a42cf63 100644 --- a/headers/linboosselectionrow.h +++ b/headers/linboosselectionrow.h @@ -28,8 +28,11 @@ private: private slots: void resizeAndPositionAllButtons(); + void handleButtonToggled(bool checked); + void handleLinboStateChanged(LinboBackend::LinboState newState); signals: + void selectedOsChanged(); }; diff --git a/headers/linbostartactions.h b/headers/linbostartactions.h index 8de8fa5..b8d83de 100644 --- a/headers/linbostartactions.h +++ b/headers/linbostartactions.h @@ -17,14 +17,13 @@ class LinboStartActions : public QWidget { Q_OBJECT public: - explicit LinboStartActions(LinboBackend* backend, LinboOsSelectionRow* osSelectionRow, QWidget *parent = nullptr); + explicit LinboStartActions(LinboBackend* backend, QWidget *parent = nullptr); protected: void resizeEvent(QResizeEvent *event) override; private: LinboBackend* backend; - LinboOsSelectionRow* osSelectionRow; QModernStackedWidget* stackView; @@ -37,12 +36,12 @@ private: QWidget* progressBarWidget; QModernProgressBar* progressBar; - void resizeAndPositionAllItems(); + bool inited; private slots: - void executeStartAction(); - void executeSyncAction(); - void executeReinstallAction(); + void resizeAndPositionAllItems(); + void handleCurrentOsChanged(LinboOs* newOs); + void handleLinboStateChanged(LinboBackend::LinboState newState); signals: void selectedOsChanged(); diff --git a/headers/linbostartpage.h b/headers/linbostartpage.h index 4452dd9..f6654f4 100644 --- a/headers/linbostartpage.h +++ b/headers/linbostartpage.h @@ -44,9 +44,10 @@ private: LinboBackend* backend; LinboOsSelectionRow* osSelectionRow; LinboStartActions* startActionsWidget; + QList powerActionButtons; private slots: - void startOs(); + void handleLinboStateChanged(LinboBackend::LinboState newState); signals: diff --git a/headers/qmodernpushbutton.h b/headers/qmodernpushbutton.h index bc48845..2ae054d 100644 --- a/headers/qmodernpushbutton.h +++ b/headers/qmodernpushbutton.h @@ -38,8 +38,9 @@ class QModernPushButton : public QAbstractButton public: QModernPushButton(QString icon, QWidget* parent = nullptr); - void setVisible(bool visible) override; - void setVisible(bool visible, bool animated, bool asynchronos = true); + void setVisibleAnimated(bool visible, bool asynchronos = true); + + void setGeometryAnimated(const QRect& geometry); protected: void resizeEvent(QResizeEvent *event) override; @@ -52,11 +53,14 @@ protected: void mouseReleaseEvent(QMouseEvent *e) override; private: - QGraphicsOpacityEffect* opacityEffect; + QPropertyAnimation* geometryAnimation; QList overlays; private slots: void handleToggled(bool checked); + +signals: + void checked(); }; #endif // QMODERNPUSHBUTTON_H diff --git a/linboGUI.pro.user b/linboGUI.pro.user index 2873e2e..9b93059 100644 --- a/linboGUI.pro.user +++ b/linboGUI.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/sources/backend/linbobackend.cpp b/sources/backend/linbobackend.cpp index b82f901..3b0a253 100644 --- a/sources/backend/linbobackend.cpp +++ b/sources/backend/linbobackend.cpp @@ -24,8 +24,9 @@ using namespace std; LinboBackend::LinboBackend(QObject *parent) : QObject(parent) { - + this->setState(Initializing); this->config = new LinboConfig(this); + this->currentOs = nullptr; // read start.conf qDebug() << "Starting to parse start.conf"; @@ -38,7 +39,10 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) // *** Image description section *** // entry in start tab - read_qstring(&input, tmp_qstring); + char line[500]; + input.getline(line,500,'\n'); + tmp_qstring = QString::fromAscii( line, -1 ).stripWhiteSpace(); + if ( tmp_qstring.startsWith("#") || tmp_qstring.isEmpty() ) continue; tmp_qstring = tmp_qstring.section("#",0,0).stripWhiteSpace(); // Strip comment @@ -46,17 +50,21 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) LinboOs* tmpOs = read_os(&input); if(!tmpOs->getName().isEmpty()) { this->operatingSystems.append(tmpOs); + + if(tmpOs->getAutostart() && this->currentOs == nullptr) + this->currentOs = tmpOs; + // check if this is an additional/incremental image for an existing OS /* TODO unsigned int i; // Being checked later. - for(i = 0; i < elements.size(); i++ ) { - if(tmp_os.get_name().lower().compare(elements[i].get_name().lower()) == 0) { - elements[i].image_history.push_back(tmp_image); break; - } - } - if(i==elements.size()) { // Not included yet -> new image - tmp_os.image_history.push_back(tmp_image); - elements.push_back(tmp_os); - }*/ + for(i = 0; i < elements.size(); i++ ) { + if(tmp_os.get_name().lower().compare(elements[i].get_name().lower()) == 0) { + elements[i].image_history.push_back(tmp_image); break; + } + } + if(i==elements.size()) { // Not included yet -> new image + tmp_os.image_history.push_back(tmp_image); + elements.push_back(tmp_os); + }*/ } else { tmpOs->deleteLater(); @@ -75,17 +83,24 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) } input.close(); + // default select first OS + if(this->operatingSystems.length() > 0 && this->currentOs == nullptr) + this->currentOs = this->operatingSystems[0]; + qDebug() << "Finished parsing start.conf"; qDebug() << "Loading global configuration"; // load global config QStringList command; - this->process = new QProcess(); - /* connect( process, SIGNAL(readyReadStandardOutput()), + // ascynchorons commands are logged to logger + this->asynchronosProcess = new QProcess(); + connect( asynchronosProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()) ); - connect( process, SIGNAL(readyReadStandardError()), + connect( asynchronosProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr()) ); - */ + + // synchronos commands are not logged + this->synchronosProcess = new QProcess(); // client ip this->config->setIpAddress(this->executeCommand(true, "ip")); @@ -109,12 +124,14 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) this->config->setCacheSize(this->executeCommand(true, "size")); // Harddisk Size - QRegExp *removePartition = new QRegExp("[0-9]{1,2}"); + QRegExp *removePartition = new QRegExp("[0-9]{1,2}") ; QString hd = this->config->getCache(); // e.g. turn /dev/sda1 into /dev/sda hd.remove( *removePartition ); - this->config->setHddSize(this->executeCommand(true, "size", hd)); + + qDebug() << "Finished loading global configuration"; + this->setState(Idle); } // -------------------- @@ -133,12 +150,15 @@ void LinboBackend::reboot() { this->executeCommand(false, "busybox", QStringList("reboot")); } -bool LinboBackend::startOs(LinboOs* os) { - if(os == nullptr || this->state != Idle) +bool LinboBackend::startCurrentOs() { + LinboOs* os = this->currentOs; + + if(os == nullptr || this->state != Idle || !this->currentOs->getStartbutton()) return false; this->setState(Starting); + return true; this->executeCommand( false, "start", @@ -153,8 +173,10 @@ bool LinboBackend::startOs(LinboOs* os) { return true; } -bool LinboBackend::syncOs(LinboOs* os) { - if(os == nullptr || this->state != Idle) +bool LinboBackend::syncCurrentOs() { + LinboOs* os = this->currentOs; + + if(os == nullptr || this->state != Idle || !this->currentOs->getSyncbutton()) return false; this->setState(Syncing); @@ -176,8 +198,10 @@ bool LinboBackend::syncOs(LinboOs* os) { return true; } -bool LinboBackend::reinstallOs(LinboOs* os) { - if(os == nullptr || this->state != Idle) +bool LinboBackend::reinstallCurrentOs() { + LinboOs* os = this->currentOs; + + if(os == nullptr || this->state != Idle || !this->currentOs->getNewbutton()) return false; this->setState(Reinstalling); @@ -200,6 +224,66 @@ bool LinboBackend::reinstallOs(LinboOs* os) { return true; } +bool LinboBackend::partitionDrive(bool format) { + if(this->state != Root) + return false; + + this->setState(Partitioning); + + QStringList commandArgs = QStringList(format ? "partition":"partition_noformat"); + for( int i=0; i < this->diskPartitions.length(); i++) { + LinboDiskPartition* p = this->diskPartitions[i]; + commandArgs.append( + this->buildCommand( + p->getPath(), + QString::number(p->getSize()), + p->getId(), + QString((p->getBootable())?"bootable":"\" \""), + p->getFstype() + ) + ); + } + + this->executeCommand(false, this->linboCmdCommand, commandArgs); + + return true; +} + +bool LinboBackend::initializeCache() { + if(this->state != Root) + return false; + + this->setState(InitializingCache); + + QStringList commandArgs = this->buildCommand("initcache", config->getServer(), config->getCache()); + + if( this->config->getDownloadType().isEmpty() ) + commandArgs.append(this->config->getDownloadType()); + else + commandArgs.append("rsync"); + + for(int i = 0; i < this->operatingSystems.length(); i++) { + LinboOs* os = this->operatingSystems[i]; + commandArgs.append(this->buildCommand(os->getBaseImage()->getName(), os->getDifferentialImage()->getName())); + /* TODO ?? for(unsigned int j = 0; j < os[i].image_history.size(); j++) { + saveappend( command, os[i].image_history[j].get_image() ); + }*/ + } + + this->executeCommand(false, this->linboCmdCommand, commandArgs); + + return true; +} + +bool LinboBackend::updateLinbo() { + if(this->state != Root) + return false; + + this->executeCommand("update", this->config->getServer(), this->config->getCache()); + + return true; +} + LinboConfig* LinboBackend::getConfig() { return this->config; } @@ -208,35 +292,51 @@ QList LinboBackend::getOperatingSystems() { return this->operatingSystems; } +LinboOs* LinboBackend::getCurrentOs() { + return this->currentOs; +} + +void LinboBackend::setCurrentOs(LinboOs* os) { + if(this->state != Idle || !this->operatingSystems.contains(os) || this->currentOs == os) + return; + + this->currentOs = os; + emit this->currentOsChanged(os); +} // ----------- // - Helpers - // ----------- -QString LinboBackend::executeCommand(bool waitForFinished) { - QStringList tmpList = this->linboCommandCache; - this->linboCommandCache.clear(); - - return this->executeCommand(waitForFinished, "linbo_cmd", tmpList); -} - QString LinboBackend::executeCommand(bool waitForFinished, QString command, QStringList commandArgs) { - if(waitForFinished) - // clear old output - this->process->readAll(); - - qDebug() << "Executing: " << command << " " << commandArgs.join(" "); - - process->start(command, commandArgs); - process->waitForStarted(); + qDebug() << "Executing " << (waitForFinished ? "synchronos":"asynchronos") << ": " << command << " " << commandArgs.join(" "); if(waitForFinished) { - while( !process->waitForFinished(10000) ) {} - return this->process->readAllStandardOutput(); - } + // clear old output + this->synchronosProcess->readAll(); - return ""; + synchronosProcess->start(command, commandArgs); + synchronosProcess->waitForStarted(); + + while( !synchronosProcess->waitForFinished(10000) ) {} + return this->synchronosProcess->readAllStandardOutput(); + } + else { + asynchronosProcess->start(command, commandArgs); + asynchronosProcess->waitForStarted(); + + return ""; + } +} + + +void LinboBackend::readFromStdout() { + qDebug() << "OUT: " << this->asynchronosProcess->readAllStandardOutput(); +} + +void LinboBackend::readFromStderr() { + qDebug() << "ERR: " << this->asynchronosProcess->readAllStandardError(); } LinboBackend::LinboState LinboBackend::getState() { @@ -248,19 +348,7 @@ void LinboBackend::setState(LinboState state) { return; this->state = state; - emit this->stateChanged(); -} - -void LinboBackend::read_qstring( ifstream* input, QString& tmp ) { - char line[500]; - input->getline(line,500,'\n'); - tmp = QString::fromAscii( line, -1 ).stripWhiteSpace(); -} - -void LinboBackend::read_bool( ifstream* input, bool& tmp) { - char line[500]; - input->getline(line,500,'\n'); - tmp = atoi( line ); + emit this->stateChanged(this->state); } // Return true unless beginning of new section '[' is found. @@ -347,53 +435,3 @@ void LinboBackend::read_globals( ifstream* input, LinboConfig* config ) { else if(key.compare("downloadtype") == 0) config->setDownloadType(value); } } - -QStringList LinboBackend::mkpartitioncommand(vector &p) { - QStringList command = LINBO_CMD("partition"); - for(unsigned int i=0; i &p) { - QStringList command = LINBO_CMD("partition_noformat"); - for(unsigned int i=0; i &os, const QString& type) { - QStringList command = LINBO_CMD("initcache"); - saveappend( command, config.getServer() ); - saveappend( command, config.getCache() ); - if( ! type.isEmpty() ) - command.append(type); - else - command.append("rsync"); - - for(unsigned int i = 0; i < os.size(); i++) { - saveappend( command, os[i].getBaseImage()->getName() ); - /* TODO ?? for(unsigned int j = 0; j < os[i].image_history.size(); j++) { - saveappend( command, os[i].image_history[j].get_image() ); - }*/ - } - return command; -} - -QStringList LinboBackend::mklinboupdatecommand(LinboConfig& config) { - QStringList command = LINBO_CMD("update"); - saveappend( command, config.getServer() ); - saveappend( command, config.getCache() ); - return command; -} diff --git a/sources/legacy/linboGUIImplTmp.cpp b/sources/legacy/linboGUIImplTmp.cpp index 4f0e172..b1fae7e 100644 --- a/sources/legacy/linboGUIImplTmp.cpp +++ b/sources/legacy/linboGUIImplTmp.cpp @@ -1,4 +1,4 @@ -#define NEVERDEF +//#define NEVERDEF #ifdef NEVERDEF /* class building the LINBO GUI diff --git a/sources/linboosselectbutton.cpp b/sources/linboosselectbutton.cpp index 44c0fd8..d044b3e 100644 --- a/sources/linboosselectbutton.cpp +++ b/sources/linboosselectbutton.cpp @@ -36,10 +36,10 @@ LinboOs* LinboOsSelectButton::getOs() { } void LinboOsSelectButton::setVisible(bool visible) { - this->button->setVisible(visible, true, true); + this->button->setVisibleAnimated(visible, true); } void LinboOsSelectButton::resizeEvent(QResizeEvent *event) { - qDebug() << "Resize: width: " << event->size().width() << " height: " << event->size().height(); + //qDebug() << "Resize: width: " << event->size().width() << " height: " << event->size().height(); this->button->setGeometry(QRect(event->size().width() / 2 - event->size().height() / 2 , 0, event->size().height(), event->size().height())); } diff --git a/sources/linboosselectionrow.cpp b/sources/linboosselectionrow.cpp index 01d448f..881c135 100644 --- a/sources/linboosselectionrow.cpp +++ b/sources/linboosselectionrow.cpp @@ -3,24 +3,26 @@ LinboOsSelectionRow::LinboOsSelectionRow(LinboBackend* backend, QWidget *parent) : QWidget(parent) { this->backend = backend; - this->showOnlySelectedButton = false; + connect(this->backend, SIGNAL(stateChanged(LinboBackend::LinboState)), this, SLOT(handleLinboStateChanged(LinboBackend::LinboState))); + this->showOnlySelectedButton = false; this->osButtonGroup = new QButtonGroup(); this->osButtonGroup->setExclusive(true); - for(LinboOs* os : backend->getOperatingSystems()) { LinboOsSelectButton* osButton = new LinboOsSelectButton("/icons/" + os->getIconName(), os, this->osButtonGroup, this); + connect(osButton->button, SIGNAL(toggled(bool)), this, SLOT(handleButtonToggled(bool))); + + // auto select current OS + if(this->backend->getCurrentOs() == os) + osButton->button->setChecked(true); + this->osButtons.append(osButton); } - - // TODO: figure out by autostart - this->osButtonGroup->buttons()[0]->setChecked(true); } void LinboOsSelectionRow::resizeAndPositionAllButtons() { - qDebug() << "Resizing all Buttons"; int buttonWidth = this->width() / this->osButtonGroup->buttons().length(); if(this->showOnlySelectedButton) { for(int i = 0; i < this->osButtons.length(); i++) { @@ -43,6 +45,11 @@ void LinboOsSelectionRow::resizeAndPositionAllButtons() { } } +void LinboOsSelectionRow::handleButtonToggled(bool checked) { + if(checked) + this->backend->setCurrentOs(this->getSelectedOs()); +} + LinboOs* LinboOsSelectionRow::getSelectedOs() { for(LinboOsSelectButton* button : this->osButtons) { if(button->button->isChecked()) @@ -65,6 +72,23 @@ void LinboOsSelectionRow::setShowOnlySelectedButton(bool value) { void LinboOsSelectionRow::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); - qDebug() << "RESIZE EVENT: width: " << width() << " height: " << height(); + //qDebug() << "RESIZE EVENT: width: " << width() << " height: " << height(); this->resizeAndPositionAllButtons(); } + +void LinboOsSelectionRow::handleLinboStateChanged(LinboBackend::LinboState newState) { + switch (newState) { + case LinboBackend::Idle: + this->setShowOnlySelectedButton(false); + break; + + case LinboBackend::Starting: + case LinboBackend::Syncing: + case LinboBackend::Reinstalling: + this->setShowOnlySelectedButton(true); + break; + + default: + break; + } +} diff --git a/sources/linbostartactions.cpp b/sources/linbostartactions.cpp index bd6ef30..382e573 100644 --- a/sources/linbostartactions.cpp +++ b/sources/linbostartactions.cpp @@ -1,30 +1,36 @@ #include "../headers/linbostartactions.h" -LinboStartActions::LinboStartActions(LinboBackend* backend, LinboOsSelectionRow* osSelectionRow, QWidget *parent) : QWidget(parent) +LinboStartActions::LinboStartActions(LinboBackend* backend, QWidget *parent) : QWidget(parent) { this->backend = backend; - this->osSelectionRow = osSelectionRow; + connect(this->backend, SIGNAL(currentOsChanged(LinboOs*)), this, SLOT(handleCurrentOsChanged(LinboOs*))); + connect(this->backend, SIGNAL(stateChanged(LinboBackend::LinboState)), this, SLOT(handleLinboStateChanged(LinboBackend::LinboState))); - stackView = new QModernStackedWidget(this); + this->stackView = new QModernStackedWidget(this); + + this->inited = false; // Action Buttons this->buttonWidget = new QWidget(); - startOsButton = new QModernPushButton(":/svgIcons/startAction.svg", this->buttonWidget); - connect(startOsButton, SIGNAL(clicked()), this, SLOT(executeStartAction())); - syncOsButton = new QModernPushButton(":/svgIcons/syncAction.svg", this->buttonWidget); - reinstallOsButton = new QModernPushButton(":/svgIcons/resetAction.svg", this->buttonWidget); - this->stackView->addWidget(this->buttonWidget); - actionButtons.append(startOsButton); - actionButtons.append(syncOsButton); - actionButtons.append(reinstallOsButton); + this->startOsButton = new QModernPushButton(":/svgIcons/startAction.svg", this->buttonWidget); + connect(this->startOsButton, SIGNAL(clicked()), this->backend, SLOT(startCurrentOs())); + + this->syncOsButton = new QModernPushButton(":/svgIcons/syncAction.svg", this->buttonWidget); + connect(this->syncOsButton, SIGNAL(clicked()), this->backend, SLOT(syncCurrentOs())); + + this->reinstallOsButton = new QModernPushButton(":/svgIcons/resetAction.svg", this->buttonWidget); + connect(this->reinstallOsButton, SIGNAL(clicked()), this->backend, SLOT(reinstallCurrentOs())); + + this->stackView->addWidget(this->buttonWidget); // Progress bar this->progressBarWidget = new QWidget(); - progressBar = new QModernProgressBar(this->progressBarWidget); - progressBar->setIndeterminate(true); + this->progressBar = new QModernProgressBar(this->progressBarWidget); + this->progressBar->setIndeterminate(true); this->stackView->addWidget(this->progressBarWidget); + connect(this->stackView, SIGNAL(currentChanged(int)), this, SLOT(resizeAndPositionAllItems())); this->stackView->setCurrentWidget(this->buttonWidget); } @@ -35,14 +41,14 @@ void LinboStartActions::resizeAndPositionAllItems() { // Action buttons // bring buttons in correct order: - LinboOs* selectedOs = this->osSelectionRow->getSelectedOs(); - LinboOs::LinboOsStartAction defaultAction = selectedOs->getDefaultAction(); + LinboOs* selectedOs = this->backend->getCurrentOs(); + LinboOs::LinboOsStartAction defaultAction = LinboOs::UnknownAction; + if(selectedOs != nullptr) + defaultAction = selectedOs->getDefaultAction(); + int syncOsPosition = 2; int startOsPosition = 0; - int syncOsPosition = 1; - int reinstallOsPosition = 2; - - qDebug() << "Default action is: " << defaultAction; + int reinstallOsPosition = 1; switch (defaultAction) { case LinboOs::StartOs: @@ -53,21 +59,16 @@ void LinboStartActions::resizeAndPositionAllItems() { reinstallOsPosition = 2; break; case LinboOs::ReinstallOs: - reinstallOsPosition = 0; syncOsPosition = 1; startOsPosition = 2; + reinstallOsPosition = 0; break; default: break; } - //this->actionButtons.move(this->actionButtons.indexOf(this->startOsButton), startOsPosition); - //this->actionButtons.move(this->actionButtons.indexOf(this->syncOsButton), syncOsPosition); - //this->actionButtons.move(this->actionButtons.indexOf(this->reinstallOsButton), reinstallOsPosition); - - while (this->actionButtons.length() < 3) { + while (this->actionButtons.length() < 3) this->actionButtons.append(nullptr); - } this->actionButtons[startOsPosition] = this->startOsButton; this->actionButtons[syncOsPosition] = this->syncOsButton; @@ -75,54 +76,66 @@ void LinboStartActions::resizeAndPositionAllItems() { // check for disabled actions QList positionsEnabled; - positionsEnabled.append(true); - positionsEnabled.append(true); - positionsEnabled.append(true); + while(positionsEnabled.length() < 3) + positionsEnabled.append(false); - positionsEnabled[startOsPosition] = selectedOs->getStartbutton(); - positionsEnabled[syncOsPosition] = selectedOs->getSyncbutton(); - positionsEnabled[reinstallOsPosition] = selectedOs->getNewbutton(); + if(selectedOs != nullptr) { + positionsEnabled[startOsPosition] = selectedOs->getStartbutton(); + positionsEnabled[syncOsPosition] = selectedOs->getSyncbutton(); + positionsEnabled[reinstallOsPosition] = selectedOs->getNewbutton(); + } + + QList geometries; + while (geometries.length() < 3) + geometries.append(QRect()); // move buttons into place this->buttonWidget->setFixedSize(this->size()); int buttonSpacing = this->height() * 0.1; int defaultButtonHeight = this->height() * 0.6; - this->actionButtons[0]->setGeometry((this->width() - defaultButtonHeight) / 2, 0,defaultButtonHeight, defaultButtonHeight); + geometries[0] = QRect((this->width() - defaultButtonHeight) / 2, 0,defaultButtonHeight, defaultButtonHeight); + int secondaryButtonHeight = this->height() * 0.3; if(positionsEnabled[1] && positionsEnabled[2]) { - this->actionButtons[1]->setGeometry( + // place buttons besides each other + geometries[1] = QRect( this->width() / 2 - secondaryButtonHeight - buttonSpacing / 2, defaultButtonHeight + buttonSpacing, secondaryButtonHeight, secondaryButtonHeight ); - this->actionButtons[2]->setGeometry( + geometries[2] = QRect( this->width() / 2 + buttonSpacing / 2, defaultButtonHeight + buttonSpacing, secondaryButtonHeight, secondaryButtonHeight ); } - else if(!positionsEnabled[1]) { - this->actionButtons[1]->hide(); - this->actionButtons[2]->setGeometry( + else { + // place buttons on top of each other + geometries[1] = QRect( this->width() / 2 - secondaryButtonHeight / 2, defaultButtonHeight + buttonSpacing, secondaryButtonHeight, secondaryButtonHeight ); + + geometries[2] = geometries[1]; } - else if(!positionsEnabled[2]) { - this->actionButtons[1]->setGeometry( - this->width() / 2 - secondaryButtonHeight / 2, - defaultButtonHeight + buttonSpacing, - secondaryButtonHeight, - secondaryButtonHeight - ); - this->actionButtons[2]->hide(); + + for(int i = 0; i < this->actionButtons.length(); i++) { + if(this->inited) { + this->actionButtons[i]->setVisibleAnimated(positionsEnabled[i]); + this->actionButtons[i]->setGeometryAnimated(geometries[i]); + } + else { + // don't animate the first time + this->actionButtons[i]->setVisible(positionsEnabled[i]); + this->actionButtons[i]->setGeometry(geometries[i]); + } } // Progress bar @@ -130,6 +143,8 @@ void LinboStartActions::resizeAndPositionAllItems() { int progressBarHeight = this->height() * 0.1; int progressBarWidth = this->width() * 0.5; progressBar->setGeometry((this->width() - progressBarWidth) / 2, (this->height() - progressBarHeight) / 2, progressBarWidth, progressBarHeight); + + this->inited = true; } void LinboStartActions::resizeEvent(QResizeEvent *event) { @@ -137,23 +152,24 @@ void LinboStartActions::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); } -void LinboStartActions::executeStartAction() { - this->stackView->setCurrentWidgetAnimated(this->progressBarWidget); - this->osSelectionRow->setShowOnlySelectedButton(true); - this->backend->startOs(this->osSelectionRow->getSelectedOs()); - //this->progressBar->show(); +void LinboStartActions::handleCurrentOsChanged(LinboOs* newOs) { + Q_UNUSED(newOs) + this->resizeAndPositionAllItems(); } -void LinboStartActions::executeSyncAction() { - this->stackView->setCurrentWidgetAnimated(this->progressBarWidget); - this->osSelectionRow->setShowOnlySelectedButton(true); - this->backend->startOs(this->osSelectionRow->getSelectedOs()); - //this->progressBar->show(); -} +void LinboStartActions::handleLinboStateChanged(LinboBackend::LinboState newState) { + switch (newState) { + case LinboBackend::Idle: + this->stackView->setCurrentWidgetAnimated(this->buttonWidget); + break; -void LinboStartActions::executeReinstallAction() { - this->stackView->setCurrentWidgetAnimated(this->progressBarWidget); - this->osSelectionRow->setShowOnlySelectedButton(true); - this->backend->startOs(this->osSelectionRow->getSelectedOs()); - //this->progressBar->show(); + case LinboBackend::Starting: + case LinboBackend::Syncing: + case LinboBackend::Reinstalling: + this->stackView->setCurrentWidgetAnimated(this->progressBarWidget); + break; + + default: + break; + } } diff --git a/sources/linbostartpage.cpp b/sources/linbostartpage.cpp index 66e4045..3f29a7e 100644 --- a/sources/linbostartpage.cpp +++ b/sources/linbostartpage.cpp @@ -22,6 +22,8 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget { this->backend = backend; + connect(this->backend, SIGNAL(stateChanged(LinboBackend::LinboState)), this, SLOT(handleLinboStateChanged(LinboBackend::LinboState))); + this->setGeometry(QRect(0,0,parent->width(), parent->height())); // create an instance of the old GUI (as a backup) @@ -30,19 +32,6 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget // create the main layout - // OS Buttons - osSelectionRow = new LinboOsSelectionRow(this->backend); - osSelectionRow->setFixedHeight(this->height() * 0.25); - osSelectionRow->setFixedWidth(this->width()); - - // action buttons - this->startActionsWidget = new LinboStartActions(this->backend, this->osSelectionRow); - this->startActionsWidget->setFixedHeight(this->height() * 0.15); - this->startActionsWidget->setFixedWidth(this->width()); - - QLabel* versionLabel = new QLabel(backend->getConfig()->getVersion() + " - mod by Dorian Zedler"); - - // main layout QWidget* mainLayoutWidget = new QWidget(this); mainLayoutWidget->setGeometry(this->geometry()); @@ -50,9 +39,22 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget mainLayout->setSpacing(this->height()*0.025); mainLayout->setContentsMargins(0,0,0,0); mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + // OS Buttons + osSelectionRow = new LinboOsSelectionRow(this->backend); mainLayout->addWidget(osSelectionRow); + osSelectionRow->setFixedHeight(this->height() * 0.25); + osSelectionRow->setFixedWidth(this->width()); + + // action buttons + this->startActionsWidget = new LinboStartActions(this->backend, this->osSelectionRow); mainLayout->addWidget(this->startActionsWidget); + this->startActionsWidget->setFixedHeight(this->height() * 0.15); + this->startActionsWidget->setFixedWidth(this->width()); + mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + QLabel* versionLabel = new QLabel(backend->getConfig()->getVersion() + " - mod by Dorian Zedler"); mainLayout->addWidget(versionLabel); @@ -66,16 +68,19 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget QModernPushButton* settingsActionButton = new QModernPushButton(":/svgIcons/settingsAction.svg"); connect(settingsActionButton, SIGNAL(clicked()), legacyGui, SLOT(open())); + this->powerActionButtons.append(settingsActionButton); settingsActionButton->setFixedHeight(buttonWidth); settingsActionButton->setFixedWidth(buttonWidth); QModernPushButton* rebootActionButton = new QModernPushButton(":/svgIcons/rebootAction.svg"); connect(rebootActionButton, SIGNAL(clicked()), this->backend, SLOT(reboot())); + this->powerActionButtons.append(rebootActionButton); rebootActionButton->setFixedHeight(buttonWidth); rebootActionButton->setFixedWidth(buttonWidth); QModernPushButton* shutdownActionButton = new QModernPushButton(":/svgIcons/shutdownAction.svg"); connect(shutdownActionButton, SIGNAL(clicked()), this->backend, SLOT(shutdown())); + this->powerActionButtons.append(shutdownActionButton); shutdownActionButton->setFixedHeight(buttonWidth); shutdownActionButton->setFixedWidth(buttonWidth); @@ -86,24 +91,21 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget powerActionsLayout->addWidget(shutdownActionButton); } -void LinboStartPage::startOs() { - /*progressBar->show(); - defaultActionButton->hide(); - secondActionButton->hide(); - thirdActionButton->hide();*/ - this->osSelectionRow->setShowOnlySelectedButton(true); - /*LinboOs* startOs = static_cast(this->osButtonGroup->checkedButton()->parent())->getOs(); +void LinboStartPage::handleLinboStateChanged(LinboBackend::LinboState newState) { + switch (newState) { + case LinboBackend::Idle: + for(QModernPushButton* powerActionButton : this->powerActionButtons) + powerActionButton->setVisibleAnimated(true); + break; - for(QAbstractButton* abstractButton : this->osButtonGroup->buttons()) { - LinboOsSelectButton* button = static_cast(abstractButton->parent()); - if(button->getOs() != startOs) - button->setFixedWidth(this->width() * 0.1); //hide(); - //button->setMaximumSize(QSize(0, this->height() * 0.25)); + case LinboBackend::Starting: + case LinboBackend::Syncing: + case LinboBackend::Reinstalling: + for(QModernPushButton* powerActionButton : this->powerActionButtons) + powerActionButton->setVisibleAnimated(false); + break; + + default: + break; } - - //this->osButtonGroup->checkedButton()->setFixedWidth(this->width() * 0.8); - //this->osButtonGroup->checkedButton()->setMaximumSize(QSize(this->width(), this->height() * 0.25)); - - qDebug() << "starting: " << startOs->getName(); - this->backend->startOs(startOs);*/ } diff --git a/sources/qmodernpushbutton.cpp b/sources/qmodernpushbutton.cpp index 6f0de68..29d1b57 100644 --- a/sources/qmodernpushbutton.cpp +++ b/sources/qmodernpushbutton.cpp @@ -21,6 +21,9 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractButton(parent) { this->setMouseTracking(true); + this->geometryAnimation = new QPropertyAnimation(this, "geometry", this); + this->geometryAnimation->setDuration(400); + this->geometryAnimation->setEasingCurve(QEasingCurve::InOutQuad); QStringList overlays; overlays.append(icon); @@ -28,6 +31,8 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractB overlays.append(":svgIcons/overlayPressed.svg"); overlays.append(":svgIcons/overlayChecked.svg"); + this->setObjectName(icon); + for(QString overlayName : overlays) { QSvgWidget* overlayWidget = new QSvgWidget(this); @@ -38,6 +43,7 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractB } this->overlays[0]->setVisible(true); + this->overlays[0]->setAnimationDuration(200); this->overlays[1]->setAnimationDuration(200); this->overlays[2]->setAnimationDuration(100); @@ -45,6 +51,8 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractB } void QModernPushButton::handleToggled(bool checked) { + if(checked) + emit this->checked(); if(this->overlays.length() >= 4) this->overlays[3]->setVisible(checked); } @@ -62,30 +70,26 @@ void QModernPushButton::resizeEvent(QResizeEvent *event) { } } -void QModernPushButton::setVisible(bool visible, bool animated, bool asynchronos) { - if(this->isVisible() == visible) - return; - - if(animated) { - this->overlays[0]->setVisible(visible); - } - else { - QWidget::setVisible(visible); - } +void QModernPushButton::setGeometryAnimated(const QRect& geometry) { + this->geometryAnimation->setStartValue(this->geometry()); + this->geometryAnimation->setEndValue(geometry); + this->geometryAnimation->start(); } -void QModernPushButton::setVisible(bool visible) { - QAbstractButton::setVisible(visible); +void QModernPushButton::setVisibleAnimated(bool visible, bool asynchronos) { + if(!this->isVisible()) + this->setVisible(true); + + this->setEnabled(visible); + this->overlays[0]->setVisible(visible); } void QModernPushButton::paintEvent(QPaintEvent *e) { QWidget::paintEvent(e); } - void QModernPushButton::keyPressEvent(QKeyEvent *e) { // TODO - return QAbstractButton::keyPressEvent(e); } diff --git a/sources/qmodernpushbuttonoverlay.cpp b/sources/qmodernpushbuttonoverlay.cpp index bfa4cd4..b9e3219 100644 --- a/sources/qmodernpushbuttonoverlay.cpp +++ b/sources/qmodernpushbuttonoverlay.cpp @@ -1,4 +1,4 @@ -#include "../headers/qmodernpushbuttonoverlay.h" + #include "../headers/qmodernpushbuttonoverlay.h" QModernPushButtonOverlay::QModernPushButtonOverlay(QWidget* overlayWidget, QObject *parent) : QObject(parent) {