diff --git a/headers/backend/linbobackend.h b/headers/backend/linbobackend.h index 5cdcee3..595bb17 100644 --- a/headers/backend/linbobackend.h +++ b/headers/backend/linbobackend.h @@ -43,6 +43,15 @@ class LinboBackend : public QObject public: explicit LinboBackend(QObject *parent = nullptr); + enum LinboState { + Idle, + Root, + Partitioning, + Starting, + Syncing, + Installing + }; + LinboConfig* getConfig(); QList getOperatingSystems(); diff --git a/headers/backend/linboconfig.h b/headers/backend/linboconfig.h index 9ec5daf..933835e 100644 --- a/headers/backend/linboconfig.h +++ b/headers/backend/linboconfig.h @@ -24,8 +24,6 @@ class LinboConfig : public QObject { Q_OBJECT public: - explicit LinboConfig(QObject *parent = nullptr); - friend class LinboBackend; const QString& getServer() const {return this->server;} @@ -50,6 +48,8 @@ public: const bool& getAutoFormat() {return this->autoFormat;} protected: + explicit LinboConfig(QObject *parent = nullptr); + void setServer( const QString& server ) {this->server = server;} void setIpAddress( const QString& ipAddress ) {this->ipAddress = ipAddress;} void setMacAddress( const QString& macAddress ) {this->macAddress = macAddress;} diff --git a/headers/backend/linbodiskpartition.h b/headers/backend/linbodiskpartition.h index b6b09eb..b2170e2 100644 --- a/headers/backend/linbodiskpartition.h +++ b/headers/backend/linbodiskpartition.h @@ -25,8 +25,6 @@ class LinboDiskPartition : public QObject { Q_OBJECT public: - explicit LinboDiskPartition(QObject *parent = nullptr); - friend class LinboBackend; const QString& getPath() const {return this->path;} @@ -36,6 +34,8 @@ public: const bool& getBootable() const {return this->bootable;} protected: + explicit LinboDiskPartition(QObject *parent = nullptr); + void setPath( const QString& path ) {this->path = path;} void setId( const QString& id ) {this->id = id;} void setFstype( const QString& fstype ) {this->fstype = fstype;} diff --git a/headers/backend/linboimage.h b/headers/backend/linboimage.h index afb1975..1f7c69e 100644 --- a/headers/backend/linboimage.h +++ b/headers/backend/linboimage.h @@ -25,14 +25,14 @@ class LinboImage : public QObject { Q_OBJECT public: - explicit LinboImage(QString name, QObject *parent = nullptr); - friend class LinboBackend; const QString& getDescription() const {return this->description;} const QString& getName() const {return this->name;} protected: + explicit LinboImage(QString name, QObject *parent = nullptr); + void setDescription (const QString& description) {this->description = description;} void setName(const QString& name) {this->name = name;} diff --git a/headers/backend/linboos.h b/headers/backend/linboos.h index 37e20c5..4f4a324 100644 --- a/headers/backend/linboos.h +++ b/headers/backend/linboos.h @@ -27,8 +27,6 @@ class LinboOs : public QObject { Q_OBJECT public: - explicit LinboOs(QObject *parent = nullptr); - friend class LinboBackend; const QString& getName() const {return this->name;} @@ -51,6 +49,8 @@ public: const bool& getHidden() const {return this->hidden;} protected: + explicit LinboOs(QObject *parent = nullptr); + void setName( const QString& name ) {this->name = name;} void setDescription ( const QString& description ) {this->description = description;} void setVersion( const QString& version ) {this->version = version;} diff --git a/headers/linbogui.h b/headers/linbogui.h index 14dc5e3..1b15ee2 100644 --- a/headers/linbogui.h +++ b/headers/linbogui.h @@ -39,9 +39,8 @@ public: private: LinboBackend* backend; + LinboStartPage* startPage; -private slots: - void startOs(); }; #endif // LINBOGUI_H diff --git a/headers/linboosselectbutton.h b/headers/linboosselectbutton.h index 97f1890..0cb5431 100644 --- a/headers/linboosselectbutton.h +++ b/headers/linboosselectbutton.h @@ -20,18 +20,32 @@ #define LINBOOSSELECTBUTTON_H #include +#include +#include +#include +#include +#include #include "qmodernpushbutton.h" #include "linboos.h" -class LinboOsSelectButton : public QModernPushButton +class LinboOsSelectButton : public QWidget { Q_OBJECT public: - LinboOsSelectButton(QString icon, LinboOs* os, QWidget* parent = nullptr); + friend class LinboOsSelectionRow; - LinboOs* getOs(); + +protected: + void resizeEvent(QResizeEvent *event) override; private: + LinboOsSelectButton(QString icon, LinboOs* os, QButtonGroup* buttonGroup, QWidget* parent = nullptr); + + LinboOs* getOs(); + void setVisible(bool visible) override; + + QModernPushButton* button; + QButtonGroup* buttonGroup; LinboOs* os; }; diff --git a/headers/linboosselectionrow.h b/headers/linboosselectionrow.h new file mode 100644 index 0000000..6d93b65 --- /dev/null +++ b/headers/linboosselectionrow.h @@ -0,0 +1,36 @@ +#ifndef LINBOOSSELECTIONROW_H +#define LINBOOSSELECTIONROW_H + +#include +#include +#include + +#include "linbobackend.h" +#include "linboosselectbutton.h" + +class LinboOsSelectionRow : public QWidget +{ + Q_OBJECT +public: + explicit LinboOsSelectionRow(LinboBackend* backend, QWidget *parent = nullptr); + + LinboOs* getSelectedOs(); + void setShowOnlySelectedButton(bool value); + +protected: + void resizeEvent(QResizeEvent *event) override; + +private: + LinboBackend* backend; + QList osButtons; + QButtonGroup* osButtonGroup; + bool showOnlySelectedButton; + +private slots: + void resizeAndPositionAllButtons(); + +signals: + +}; + +#endif // LINBOOSSELECTIONROW_H diff --git a/headers/linbostartactions.h b/headers/linbostartactions.h new file mode 100644 index 0000000..c5c320a --- /dev/null +++ b/headers/linbostartactions.h @@ -0,0 +1,47 @@ +#ifndef LINBOSTARTACTIONS_H +#define LINBOSTARTACTIONS_H + +#include +#include +#include +#include + +#include "linbobackend.h" +#include "linboosselectionrow.h" +#include "qmodernstackedwidget.h" +#include "qmodernpushbutton.h" +#include "qmodernprogressbar.h" + +class LinboStartActions : public QWidget +{ + Q_OBJECT +public: + explicit LinboStartActions(LinboBackend* backend, LinboOsSelectionRow* osSelectionRow, QWidget *parent = nullptr); + +protected: + void resizeEvent(QResizeEvent *event) override; + +private: + LinboBackend* backend; + LinboOsSelectionRow* osSelectionRow; + + QModernStackedWidget* stackView; + + QWidget* buttonWidget; + QModernPushButton* defaultActionButton; + QModernPushButton* secondActionButton; + QModernPushButton* thirdActionButton; + + QWidget* progressBarWidget; + QModernProgressBar* progressBar; + + void resizeAndPositionAllItems(); + +private slots: + void startOs(); + +signals: + +}; + +#endif // LINBOSTARTACTIONS_H diff --git a/headers/linbostartpage.h b/headers/linbostartpage.h index e6e24e0..4452dd9 100644 --- a/headers/linbostartpage.h +++ b/headers/linbostartpage.h @@ -21,14 +21,32 @@ #include #include +#include +#include +#include +#include +#include +#include "linboGUIImpl.hh" +#include "linbobackend.h" #include "linboosselectbutton.h" +#include "qmodernprogressbar.h" +#include "linboosselectionrow.h" +#include "linbostartactions.h" -class linboStartPage : public QWidget +class LinboStartPage : public QWidget { Q_OBJECT public: - explicit linboStartPage(QWidget *parent = nullptr); + explicit LinboStartPage(LinboBackend* backend, QWidget *parent = nullptr); + +private: + LinboBackend* backend; + LinboOsSelectionRow* osSelectionRow; + LinboStartActions* startActionsWidget; + +private slots: + void startOs(); signals: diff --git a/headers/qmodernprogressbar.h b/headers/qmodernprogressbar.h new file mode 100644 index 0000000..ac9ed23 --- /dev/null +++ b/headers/qmodernprogressbar.h @@ -0,0 +1,36 @@ +#ifndef QMODERNPROGRESSBAR_H +#define QMODERNPROGRESSBAR_H + +#include +#include +#include +#include +#include +#include +#include + +class QModernProgressBar : public QProgressBar +{ + Q_OBJECT +public: + QModernProgressBar(QWidget* parent = nullptr); + + void setIndeterminate(bool indeterminate); + bool getIndeterminate(); + +protected: + QTimer* refreshTimer; + QPropertyAnimation* indeterminateAnimtion; + + void paintEvent(QPaintEvent *e) override; + +private: + bool indeterminate; + int preIndeterminateValue; + +protected slots: + void updateIndeterminate(); + +}; + +#endif // QMODERNPROGRESSBAR_H diff --git a/headers/qmodernpushbutton.h b/headers/qmodernpushbutton.h index 1e19a79..bc48845 100644 --- a/headers/qmodernpushbutton.h +++ b/headers/qmodernpushbutton.h @@ -26,7 +26,11 @@ #include #include #include +#include #include +#include + +#include "qmodernpushbuttonoverlay.h" class QModernPushButton : public QAbstractButton { @@ -34,6 +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); + protected: void resizeEvent(QResizeEvent *event) override; void paintEvent(QPaintEvent *e) override; @@ -45,18 +52,11 @@ protected: void mouseReleaseEvent(QMouseEvent *e) override; private: - QSvgWidget* svgWidget; - QSvgWidget* overlayHoveredWidget; - QGraphicsOpacityEffect* overlayHoveredEffect; - QSvgWidget* overlayPressedWidget; - QGraphicsOpacityEffect* overlayPressedEffect; - QSvgWidget* overlayCheckedWidget; - QGraphicsOpacityEffect* overlayCheckedEffect; - + QGraphicsOpacityEffect* opacityEffect; + QList overlays; private slots: void handleToggled(bool checked); - }; #endif // QMODERNPUSHBUTTON_H diff --git a/headers/qmodernpushbuttonoverlay.h b/headers/qmodernpushbuttonoverlay.h new file mode 100644 index 0000000..120bee3 --- /dev/null +++ b/headers/qmodernpushbuttonoverlay.h @@ -0,0 +1,38 @@ +#ifndef QMODERNPUSHBUTTONOVERLAY_H +#define QMODERNPUSHBUTTONOVERLAY_H + +#include +#include +#include +#include +#include + +// This class automatically enables and disabled the QGraphicsOpacityEffect as needed, to prevent +// "QPainter::begin: A paint device can only be painted by one painter at a time." Error messages +// When applying a QGraphicalEffect to the parent +class QModernPushButtonOverlay : public QObject +{ + Q_OBJECT +public: + friend class QModernPushButton; + +private: + + explicit QModernPushButtonOverlay(QWidget* overlayWidget, QObject *parent = nullptr); + + QWidget* widget; + QGraphicsOpacityEffect* effect; + QPropertyAnimation* animation; + + void setAnimationDuration(int duration); + void setVisible(bool visible); + void setEffectEnabled(bool enabled); + +private slots: + void handleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State); + +signals: + +}; + +#endif // QMODERNPUSHBUTTONOVERLAY_H diff --git a/headers/qmodernstackedwidget.h b/headers/qmodernstackedwidget.h new file mode 100644 index 0000000..e8c5606 --- /dev/null +++ b/headers/qmodernstackedwidget.h @@ -0,0 +1,26 @@ +#ifndef QMODERNSTACKEDWIDGET_H +#define QMODERNSTACKEDWIDGET_H + +#include +#include +#include +#include +#include + +class QModernStackedWidget : public QStackedWidget +{ + Q_OBJECT +public: + QModernStackedWidget(QWidget* parent = nullptr); + + void setCurrentWidgetAnimated(QWidget* widget); + +private: + QWidget* newWidget; + QPropertyAnimation* opacityAnimation; + +private slots: + void handleAnimationFinished(); +}; + +#endif // QMODERNSTACKEDWIDGET_H diff --git a/linboGUI.pro b/linboGUI.pro index 67b2eeb..6454074 100644 --- a/linboGUI.pro +++ b/linboGUI.pro @@ -5,6 +5,9 @@ CFLAGS += -DQWS -static QT += \ qt3support \ widgets \ + widgets \ + widgets \ + widgets \ svg QMAKE_POST_LINK=strip $(TARGET) @@ -42,8 +45,13 @@ HEADERS += \ headers/backend/linbobackend.h \ headers/linbogui.h \ headers/linboosselectbutton.h \ + headers/linboosselectionrow.h \ + headers/linbostartactions.h \ headers/linbostartpage.h \ - headers/qmodernpushbutton.h + headers/qmodernprogressbar.h \ + headers/qmodernpushbutton.h \ + headers/qmodernpushbuttonoverlay.h \ + headers/qmodernstackedwidget.h SOURCES += \ sources/backend/linboconfig.cpp \ @@ -70,9 +78,14 @@ SOURCES += \ sources/backend/linbobackend.cpp \ sources/linbogui.cpp \ sources/linboosselectbutton.cpp \ + sources/linboosselectionrow.cpp \ + sources/linbostartactions.cpp \ sources/linbostartpage.cpp \ sources/main.cpp \ - sources/qmodernpushbutton.cpp + sources/qmodernprogressbar.cpp \ + sources/qmodernpushbutton.cpp \ + sources/qmodernpushbuttonoverlay.cpp \ + sources/qmodernstackedwidget.cpp FORMS += \ forms/linboConsole.ui \ diff --git a/resources/linbo.qrc b/resources/linbo.qrc index d43cf78..be7e1a6 100644 --- a/resources/linbo.qrc +++ b/resources/linbo.qrc @@ -21,7 +21,7 @@ svgIcons/startAction.svg svgIcons/syncAction.svg svgIcons/resetAction.svg - svgIcons/overlayNormal.svg + svgIcons/overlayHovered.svg svgIcons/overlayPressed.svg svgIcons/shutdownAction.svg svgIcons/rebootAction.svg diff --git a/resources/svgIcons/resetAction.svg b/resources/svgIcons/resetAction.svg index b0a7d37..d3c0109 100644 --- a/resources/svgIcons/resetAction.svg +++ b/resources/svgIcons/resetAction.svg @@ -43,20 +43,20 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1245" - inkscape:window-height="1376" + inkscape:window-width="1850" + inkscape:window-height="1016" id="namedview6" showgrid="false" inkscape:zoom="1" - inkscape:cx="256" + inkscape:cx="46" inkscape:cy="256" inkscape:window-x="70" inkscape:window-y="27" - inkscape:window-maximized="0" + inkscape:window-maximized="1" inkscape:current-layer="svg4" inkscape:document-rotation="0" /> + style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:5.32926;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/sources/backend/linbobackend.cpp b/sources/backend/linbobackend.cpp index 0570221..9154c8d 100644 --- a/sources/backend/linbobackend.cpp +++ b/sources/backend/linbobackend.cpp @@ -81,6 +81,11 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) // load global config QStringList command; this->process = new QProcess(); + /* connect( process, SIGNAL(readyReadStandardOutput()), + this, SLOT(readFromStdout()) ); + connect( process, SIGNAL(readyReadStandardError()), + this, SLOT(readFromStderr()) ); + */ // client ip command = LINBO_CMD("ip"); @@ -148,7 +153,6 @@ LinboBackend::LinboBackend(QObject *parent) : QObject(parent) // - Public functions - // -------------------- - void LinboBackend::executeAutostart() { } @@ -207,6 +211,8 @@ void LinboBackend::executeCommand(QStringList commandArgs, bool waitForFinished) qDebug() << "Executing: " << command << " " << commandArgs.join(" "); + return; + process->start(command, commandArgs); process->waitForStarted(); diff --git a/sources/legacy/linboGUIImpl.cc b/sources/legacy/linboGUIImpl.cc index 657c47e..31ce4a1 100644 --- a/sources/legacy/linboGUIImpl.cc +++ b/sources/legacy/linboGUIImpl.cc @@ -1504,7 +1504,7 @@ void linboGUIImpl::resetButtons() { } void linboGUIImpl::executeAutostart() { - + return; // autostart is handles by new GUI // if there is "autopartition" set, execute the hidden button if( autopartition ) autopartition->lclicked(); diff --git a/sources/linbogui.cpp b/sources/linbogui.cpp index 135a346..373c122 100644 --- a/sources/linbogui.cpp +++ b/sources/linbogui.cpp @@ -29,111 +29,18 @@ LinboGui::LinboGui() this->setFixedHeight(QApplication::desktop()->screenGeometry().height()); this->setFixedWidth(QApplication::desktop()->screenGeometry().width()); - // black bakground + qDebug() << this->geometry(); + + // white bakground // linuxmuster background color: #394f5e this->setStyleSheet( "QDialog { background: white }"); - // create an instance of the old GUI (as a backup) - linboGUIImpl* legacyGui = new linboGUIImpl(this); - legacyGui->setStyleSheet( "QDialog { background: white }"); - // create the backend this->backend = new LinboBackend(this); - qDebug() << this->backend->getOperatingSystems()[0]->getName(); + // create start page + this->startPage = new LinboStartPage(this->backend, this); - // create the main layout - - // OS Buttons - LinboOsSelectButton* osButton = new LinboOsSelectButton(":/svgIcons/ubuntu.svg", nullptr, this); - osButton->setFixedHeight(250); - osButton->setFixedWidth(250); - osButton->setChecked(true); - - - LinboOsSelectButton* osButton_1 = new LinboOsSelectButton(":/svgIcons/windows.svg", nullptr, this); - osButton_1->setFixedHeight(250); - osButton_1->setFixedWidth(250); - - QButtonGroup* group = new QButtonGroup(); - group->setExclusive(true); - group->addButton(osButton); - group->addButton(osButton_1); - - // OS Button Layout - QHBoxLayout* osButtonRow = new QHBoxLayout(); - osButtonRow->addWidget(osButton); - osButtonRow->addWidget(osButton_1); - - // action buttons - QModernPushButton* defaultActionButton = new QModernPushButton(":/svgIcons/startAction.svg"); - defaultActionButton->setFixedHeight(110); - defaultActionButton->setFixedWidth(110); - connect(defaultActionButton, SIGNAL(clicked()), this, SLOT(startOs())); - - QModernPushButton* secondActionButton = new QModernPushButton(":/svgIcons/syncAction.svg"); - secondActionButton->setFixedHeight(50); - secondActionButton->setFixedWidth(50); - - QModernPushButton* thirdActionButton = new QModernPushButton(":/svgIcons/resetAction.svg"); - thirdActionButton->setFixedHeight(50); - thirdActionButton->setFixedWidth(50); - - QHBoxLayout* actionButtonLayout = new QHBoxLayout(); - actionButtonLayout->addItem(new QSpacerItem(10,10, QSizePolicy::Expanding, QSizePolicy::Minimum)); - actionButtonLayout->addWidget(secondActionButton); - actionButtonLayout->addWidget(thirdActionButton); - actionButtonLayout->addItem(new QSpacerItem(10,10, QSizePolicy::Expanding, QSizePolicy::Minimum)); - - QLabel* versionLabel = new QLabel(backend->getConfig()->getVersion()); - - // main layout - QWidget* mainLayoutWidget = new QWidget(this); - mainLayoutWidget->setGeometry(this->geometry()); - QVBoxLayout* mainLayout = new QVBoxLayout(mainLayoutWidget); - mainLayout->addItem(new QSpacerItem(10,10, QSizePolicy::Minimum, QSizePolicy::Expanding)); - mainLayout->addLayout(osButtonRow); - //mainLayout->addItem(new QSpacerItem(10,10, QSizePolicy::Minimum, QSizePolicy::Expanding)); - mainLayout->addWidget(defaultActionButton); - mainLayout->setAlignment(defaultActionButton, Qt::AlignHCenter); - mainLayout->addLayout(actionButtonLayout); - mainLayout->addItem(new QSpacerItem(10,10, QSizePolicy::Minimum, QSizePolicy::Expanding)); - mainLayout->addWidget(versionLabel); - - // power and settings Buttons - QWidget* powerActionsLayoutWidget = new QWidget(this); - int height = this->height() * 0.25; - int width = height / 3; - int buttonWidth = width * 0.8; - powerActionsLayoutWidget->setGeometry(QRect(this->width() - width * 1.1, this->height() - height + width * 0.1, width, height)); - - QModernPushButton* settingsActionButton = new QModernPushButton(":/svgIcons/settingsAction.svg"); - connect(settingsActionButton, SIGNAL(clicked()), legacyGui, SLOT(open())); - settingsActionButton->setFixedHeight(buttonWidth); - settingsActionButton->setFixedWidth(buttonWidth); - - QModernPushButton* rebootActionButton = new QModernPushButton(":/svgIcons/rebootAction.svg"); - connect(rebootActionButton, SIGNAL(clicked()), this->backend, SLOT(reboot())); - rebootActionButton->setFixedHeight(buttonWidth); - rebootActionButton->setFixedWidth(buttonWidth); - - QModernPushButton* shutdownActionButton = new QModernPushButton(":/svgIcons/shutdownAction.svg"); - connect(shutdownActionButton, SIGNAL(clicked()), this->backend, SLOT(shutdown())); - shutdownActionButton->setFixedHeight(buttonWidth); - shutdownActionButton->setFixedWidth(buttonWidth); - - QVBoxLayout* powerActionsLayout = new QVBoxLayout(powerActionsLayoutWidget); - powerActionsLayout->setSpacing(0); - powerActionsLayout->addWidget(settingsActionButton); - powerActionsLayout->addWidget(rebootActionButton); - powerActionsLayout->addWidget(shutdownActionButton); - -} - - -void LinboGui::startOs() { - qDebug() << "starting: " << this->backend->getOperatingSystems()[1]->getName(); - this->backend->startOs(this->backend->getOperatingSystems()[1]); } // prevent closing (eg. by pressing escape key) diff --git a/sources/linboosselectbutton.cpp b/sources/linboosselectbutton.cpp index f2c7d41..44c0fd8 100644 --- a/sources/linboosselectbutton.cpp +++ b/sources/linboosselectbutton.cpp @@ -18,12 +18,28 @@ #include "linboosselectbutton.h" -LinboOsSelectButton::LinboOsSelectButton(QString icon, LinboOs* os, QWidget* parent) : QModernPushButton(icon, parent) +LinboOsSelectButton::LinboOsSelectButton(QString icon, LinboOs* os, QButtonGroup* buttonGroup, QWidget* parent) : QWidget(parent) { - this->setCheckable(true); + this->buttonGroup = buttonGroup; + + this->button = new QModernPushButton(icon, this); + this->button->setCheckable(true); + this->buttonGroup->addButton(this->button); + this->os = os; + + QWidget::setVisible(true); } LinboOs* LinboOsSelectButton::getOs() { return this->os; } + +void LinboOsSelectButton::setVisible(bool visible) { + this->button->setVisible(visible, true, true); +} + +void LinboOsSelectButton::resizeEvent(QResizeEvent *event) { + 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 new file mode 100644 index 0000000..4ddcc96 --- /dev/null +++ b/sources/linboosselectionrow.cpp @@ -0,0 +1,71 @@ +#include "../headers/linboosselectionrow.h" + +LinboOsSelectionRow::LinboOsSelectionRow(LinboBackend* backend, QWidget *parent) : QWidget(parent) +{ + this->backend = backend; + 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); + this->osButtons.append(osButton); + } + + // TODO: figure out by autostart + this->osButtonGroup->buttons()[0]->setChecked(true); +} + +void LinboOsSelectionRow::resizeAndPositionAllButtons() { + qDebug() << "Resizing all Buttons"; + if(this->showOnlySelectedButton) { + int buttonWidth = this->width() / this->osButtonGroup->buttons().length(); + for(int i = 0; i < this->osButtons.length(); i++) { + if(!this->osButtons[i]->button->isChecked()) + this->osButtons[i]->hide(); + else { + QPropertyAnimation* moveAnimation = new QPropertyAnimation(this->osButtons[i], "geometry"); + moveAnimation->setEasingCurve(QEasingCurve::InOutQuad); + moveAnimation->setDuration(400); + moveAnimation->setStartValue(this->osButtons[i]->geometry()); + moveAnimation->setEndValue(QRect(buttonWidth / 2, 0, buttonWidth, this->height())); + moveAnimation->start(); + } + } + } + else { + int buttonWidth = this->width() / this->osButtonGroup->buttons().length(); + for(int i = 0; i < this->osButtons.length(); i++) { + this->osButtons[i]->setGeometry(buttonWidth * i, 0, buttonWidth, this->height()); + } + } +} + +LinboOs* LinboOsSelectionRow::getSelectedOs() { + for(LinboOsSelectButton* button : this->osButtons) { + if(button->button->isChecked()) + return button->getOs(); + } + return nullptr; +} + +void LinboOsSelectionRow::setShowOnlySelectedButton(bool value) { + // find selected button + // set its x so it is in the middle (animated) + // set Opacity of all other buttons to 0 (animated) + if(value == this->showOnlySelectedButton) + return; + + this->showOnlySelectedButton = value; + + this->resizeAndPositionAllButtons(); +} + +void LinboOsSelectionRow::resizeEvent(QResizeEvent *event) { + QWidget::resizeEvent(event); + qDebug() << "RESIZE EVENT: width: " << width() << " height: " << height(); + this->resizeAndPositionAllButtons(); +} diff --git a/sources/linbostartactions.cpp b/sources/linbostartactions.cpp new file mode 100644 index 0000000..3567111 --- /dev/null +++ b/sources/linbostartactions.cpp @@ -0,0 +1,69 @@ +#include "../headers/linbostartactions.h" + +LinboStartActions::LinboStartActions(LinboBackend* backend, LinboOsSelectionRow* osSelectionRow, QWidget *parent) : QWidget(parent) +{ + this->backend = backend; + this->osSelectionRow = osSelectionRow; + + stackView = new QModernStackedWidget(this); + + // Action Buttons + this->buttonWidget = new QWidget(); + defaultActionButton = new QModernPushButton(":/svgIcons/startAction.svg", this->buttonWidget); + connect(defaultActionButton, SIGNAL(clicked()), this, SLOT(startOs())); + secondActionButton = new QModernPushButton(":/svgIcons/syncAction.svg", this->buttonWidget); + thirdActionButton = new QModernPushButton(":/svgIcons/resetAction.svg", this->buttonWidget); + this->stackView->addWidget(this->buttonWidget); + + // Progress bar + this->progressBarWidget = new QWidget(); + progressBar = new QModernProgressBar(this->progressBarWidget); + progressBar->setIndeterminate(true); + this->stackView->addWidget(this->progressBarWidget); + + this->stackView->setCurrentWidget(this->buttonWidget); +} + +void LinboStartActions::resizeAndPositionAllItems() { + + // stack view + this->stackView->setFixedSize(this->size()); + + // Action buttons + this->buttonWidget->setFixedSize(this->size()); + int buttonSpacing = this->height() * 0.1; + int defaultButtonHeight = this->height() * 0.6; + defaultActionButton->setGeometry((this->width() - defaultButtonHeight) / 2, 0,defaultButtonHeight, defaultButtonHeight); + int secondaryButtonHeight = this->height() * 0.3; + secondActionButton->setGeometry( + this->width() / 2 - secondaryButtonHeight - buttonSpacing / 2, + defaultButtonHeight + buttonSpacing, + secondaryButtonHeight, + secondaryButtonHeight + ); + + thirdActionButton->setGeometry( + this->width() / 2 + buttonSpacing / 2, + defaultButtonHeight + buttonSpacing, + secondaryButtonHeight, + secondaryButtonHeight + ); + + // Progress bar + this->progressBarWidget->setFixedSize(this->size()); + int progressBarHeight = this->height() * 0.1; + int progressBarWidth = this->width() * 0.5; + progressBar->setGeometry((this->width() - progressBarWidth) / 2, (this->height() - progressBarHeight) / 2, progressBarWidth, progressBarHeight); +} + +void LinboStartActions::resizeEvent(QResizeEvent *event) { + this->resizeAndPositionAllItems(); + QWidget::resizeEvent(event); +} + +void LinboStartActions::startOs() { + this->stackView->setCurrentWidgetAnimated(this->progressBarWidget); + this->osSelectionRow->setShowOnlySelectedButton(true); + this->backend->startOs(this->osSelectionRow->getSelectedOs()); + //this->progressBar->show(); +} diff --git a/sources/linbostartpage.cpp b/sources/linbostartpage.cpp index e606f9b..243f53b 100644 --- a/sources/linbostartpage.cpp +++ b/sources/linbostartpage.cpp @@ -18,7 +18,92 @@ #include "../headers/linbostartpage.h" -linboStartPage::linboStartPage(QWidget *parent) : QWidget(parent) +LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget(parent) { + this->backend = backend; + this->setGeometry(QRect(0,0,parent->width(), parent->height())); + + // create an instance of the old GUI (as a backup) + linboGUIImpl* legacyGui = new linboGUIImpl(this); + legacyGui->setStyleSheet( "QDialog { background: white }"); + + // 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()); + QVBoxLayout* mainLayout = new QVBoxLayout(mainLayoutWidget); + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0,0,0,0); + mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + mainLayout->addWidget(osSelectionRow); + mainLayout->addWidget(this->startActionsWidget); + mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + mainLayout->addWidget(versionLabel); + + + // power and settings Buttons + QWidget* powerActionsLayoutWidget = new QWidget(this); + int height = this->height() * 0.2; + int width = height / 3; + int margins = width * 0.1; + int buttonWidth = width * 0.8; + powerActionsLayoutWidget->setGeometry(QRect(this->width() - (width + margins), this->height() - (height + margins), width * 1.1, height)); + + QModernPushButton* settingsActionButton = new QModernPushButton(":/svgIcons/settingsAction.svg"); + connect(settingsActionButton, SIGNAL(clicked()), legacyGui, SLOT(open())); + settingsActionButton->setFixedHeight(buttonWidth); + settingsActionButton->setFixedWidth(buttonWidth); + + QModernPushButton* rebootActionButton = new QModernPushButton(":/svgIcons/rebootAction.svg"); + connect(rebootActionButton, SIGNAL(clicked()), this->backend, SLOT(reboot())); + rebootActionButton->setFixedHeight(buttonWidth); + rebootActionButton->setFixedWidth(buttonWidth); + + QModernPushButton* shutdownActionButton = new QModernPushButton(":/svgIcons/shutdownAction.svg"); + connect(shutdownActionButton, SIGNAL(clicked()), this->backend, SLOT(shutdown())); + shutdownActionButton->setFixedHeight(buttonWidth); + shutdownActionButton->setFixedWidth(buttonWidth); + + QVBoxLayout* powerActionsLayout = new QVBoxLayout(powerActionsLayoutWidget); + powerActionsLayout->setSpacing(0); + powerActionsLayout->addWidget(settingsActionButton); + powerActionsLayout->addWidget(rebootActionButton); + 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(); + + 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)); + } + + //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/main.cpp b/sources/main.cpp index 573c1e1..2d26e24 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -16,7 +16,6 @@ int main( int argc, char* argv[] ) { - QApplication linboGuiApp( argc, argv ); QWSServer* wsServer = QWSServer::instance(); diff --git a/sources/qmodernprogressbar.cpp b/sources/qmodernprogressbar.cpp new file mode 100644 index 0000000..928ec8e --- /dev/null +++ b/sources/qmodernprogressbar.cpp @@ -0,0 +1,74 @@ +#include "../headers/qmodernprogressbar.h" + +QModernProgressBar::QModernProgressBar(QWidget* parent) : QProgressBar(parent) +{ + this->refreshTimer = new QTimer(); + this->refreshTimer->setSingleShot(false); + this->refreshTimer->setInterval(400); + connect(this->refreshTimer, SIGNAL(timeout()), this, SLOT(updateIndeterminate())); + + + this->indeterminateAnimtion = new QPropertyAnimation(this, "value"); + this->indeterminateAnimtion->setDuration(2000); + this->indeterminateAnimtion->setStartValue(0); + this->indeterminateAnimtion->setEndValue(1000); + this->indeterminateAnimtion->setEasingCurve(QEasingCurve(QEasingCurve::InOutQuad)); + this->indeterminateAnimtion->setLoopCount(-1); + + this->setValue(0); +} + +void QModernProgressBar::setIndeterminate(bool indeterminate) { + if(this->indeterminate == indeterminate) + return; + + this->indeterminate = indeterminate; + + if(this->indeterminate) { + this->preIndeterminateValue = this->value(); + // finer steps, so the Animation is fluid + this->setMinimum(0); + this->setMaximum(1000); + this->indeterminateAnimtion->start(); + } + else { + // reset minimum and maximum + this->setMinimum(0); + this->setMaximum(100); + this->setValue(this->preIndeterminateValue); + this->indeterminateAnimtion->stop(); + } +} + +bool QModernProgressBar::getIndeterminate() { + return this->indeterminate; +} + +void QModernProgressBar::updateIndeterminate() { + qDebug() << "update indeterminate"; +} + +void QModernProgressBar::paintEvent(QPaintEvent *e) { + QPainter painter; + painter.begin(this); + // background + painter.fillRect(e->rect(), QColor("#c7c7c7")); + + // progress + if(this->indeterminate) { + int maximum = this->maximum() / 2; + if(this->value() <= maximum) + // for the first half -> fill from left + painter.fillRect(QRect(0,0, e->rect().width() * double(double(this->value()) / double(maximum)), e->rect().height()), QColor(0,0,0)); + else + // for the second half -> empty from right + painter.fillRect(QRect(e->rect().width() * double(double(this->value()- (maximum)) / double(maximum)),0, e->rect().width(), e->rect().height()), QColor(0,0,0)); + } + else + painter.fillRect(QRect(0,0, e->rect().width() * float(float(this->value()) / float(this->maximum())), e->rect().height()), QColor(0,0,0)); + + painter.end(); + + QWidget::paintEvent(e); +} + diff --git a/sources/qmodernpushbutton.cpp b/sources/qmodernpushbutton.cpp index 2b49769..6f0de68 100644 --- a/sources/qmodernpushbutton.cpp +++ b/sources/qmodernpushbutton.cpp @@ -20,60 +20,66 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractButton(parent) { - this->svgWidget = new QSvgWidget(this); - this->svgWidget->load(QString(icon)); this->setMouseTracking(true); - this->overlayHoveredWidget = new QSvgWidget(this->svgWidget); - this->overlayHoveredEffect = new QGraphicsOpacityEffect(this); - this->overlayHoveredEffect->setOpacity(0); - this->overlayHoveredWidget->setGraphicsEffect(this->overlayHoveredEffect); + QStringList overlays; + overlays.append(icon); + overlays.append(":svgIcons/overlayHovered.svg"); + overlays.append(":svgIcons/overlayPressed.svg"); + overlays.append(":svgIcons/overlayChecked.svg"); - this->overlayPressedWidget = new QSvgWidget(this->svgWidget); - this->overlayPressedWidget->load(QString(":svgIcons/overlayPressed.svg")); - this->overlayPressedEffect = new QGraphicsOpacityEffect(this); - this->overlayPressedEffect->setOpacity(0); - this->overlayPressedWidget->setGraphicsEffect(this->overlayPressedEffect); + for(QString overlayName : overlays) { - this->overlayCheckedWidget = new QSvgWidget(this->svgWidget); - this->overlayCheckedWidget->load(QString(":svgIcons/overlayChecked.svg")); - this->overlayCheckedEffect = new QGraphicsOpacityEffect(this); - this->overlayCheckedEffect->setOpacity(0); - this->overlayCheckedWidget->setGraphicsEffect(this->overlayCheckedEffect); + QSvgWidget* overlayWidget = new QSvgWidget(this); + overlayWidget->load(overlayName); + + QModernPushButtonOverlay* overlay = new QModernPushButtonOverlay(overlayWidget, this); + this->overlays.append(overlay); + } + + this->overlays[0]->setVisible(true); + this->overlays[1]->setAnimationDuration(200); + this->overlays[2]->setAnimationDuration(100); connect(this, SIGNAL(toggled(bool)), this, SLOT(handleToggled(bool))); } void QModernPushButton::handleToggled(bool checked) { - int startValue = 1; - if(checked) { - startValue = 0; - } - - QPropertyAnimation *animation = new QPropertyAnimation(this->overlayCheckedEffect, "opacity"); - animation->setDuration(400); - animation->setStartValue(startValue); - animation->setEndValue(1-startValue); - animation->setEasingCurve(QEasingCurve(QEasingCurve::InOutQuad)); - animation->start(); + if(this->overlays.length() >= 4) + this->overlays[3]->setVisible(checked); } void QModernPushButton::resizeEvent(QResizeEvent *event) { - this->svgWidget->setGeometry(QRect(0, 0, event->size().width(), event->size().height())); - // make border width match button size - QFile file(":svgIcons/overlayNormal.svg"); - file.open(QFile::ReadOnly); - QString overlayNormalString = file.readAll(); + //QFile file(":svgIcons/overlayNormal.svg"); + //file.open(QFile::ReadOnly); + //QString overlayNormalString = file.readAll(); //overlayNormalString.replace("stroke-width:15px", "stroke-width:" + QString::number(500/event->size().width() * 5) + "px"); - this->overlayHoveredWidget->load(overlayNormalString.toUtf8()); - this->overlayHoveredWidget->setGeometry(QRect(0, 0, event->size().width(), event->size().height())); + //this->overlayHoveredWidget->load(overlayNormalString.toUtf8()); - this->overlayCheckedWidget->setGeometry(QRect(0, 0, event->size().width(), event->size().height())); + for(QModernPushButtonOverlay* overlay : this->overlays) { + overlay->widget->setGeometry(QRect(0, 0, event->size().width(), event->size().height())); + } +} + +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::setVisible(bool visible) { + QAbstractButton::setVisible(visible); } void QModernPushButton::paintEvent(QPaintEvent *e) { - Q_UNUSED(e) + QWidget::paintEvent(e); } @@ -89,21 +95,26 @@ void QModernPushButton::keyReleaseEvent(QKeyEvent *e) { } void QModernPushButton::enterEvent(QEvent *e) { - this->overlayHoveredEffect->setOpacity(1); + + if(this->overlays.length() >= 2) + this->overlays[1]->setVisible(true); return QAbstractButton::enterEvent(e); } void QModernPushButton::leaveEvent(QEvent *e) { - this->overlayHoveredEffect->setOpacity(0); + if(this->overlays.length() >= 2) + this->overlays[1]->setVisible(false); return QAbstractButton::leaveEvent(e); } void QModernPushButton::mousePressEvent(QMouseEvent *e) { - this->overlayPressedEffect->setOpacity(1); + if(this->overlays.length() >= 3) + this->overlays[2]->setVisible(true); return QAbstractButton::mousePressEvent(e); } void QModernPushButton::mouseReleaseEvent(QMouseEvent *e) { - this->overlayPressedEffect->setOpacity(0); + if(this->overlays.length() >= 3) + this->overlays[2]->setVisible(false); return QAbstractButton::mouseReleaseEvent(e); } diff --git a/sources/qmodernpushbuttonoverlay.cpp b/sources/qmodernpushbuttonoverlay.cpp new file mode 100644 index 0000000..bfa4cd4 --- /dev/null +++ b/sources/qmodernpushbuttonoverlay.cpp @@ -0,0 +1,59 @@ +#include "../headers/qmodernpushbuttonoverlay.h" + +QModernPushButtonOverlay::QModernPushButtonOverlay(QWidget* overlayWidget, QObject *parent) : QObject(parent) +{ + this->widget = overlayWidget; + this->widget->setVisible(false); + + this->effect = new QGraphicsOpacityEffect(overlayWidget); + this->effect->setOpacity(0); + this->effect->setEnabled(false); + this->widget->setGraphicsEffect(this->effect); + + this->animation = new QPropertyAnimation(this->effect, "opacity"); + this->animation->setDuration(400); + this->animation->setEasingCurve(QEasingCurve(QEasingCurve::InOutQuad)); + + this->setEffectEnabled(false); + + connect(this->animation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), this, SLOT(handleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); +} + + +void QModernPushButtonOverlay::setAnimationDuration(int duration) { + this->animation->setDuration(duration); +} + +void QModernPushButtonOverlay::setVisible(bool visible) { + if(this->widget->isVisible() == visible) + return; + + int startValue = visible ? 0:1; + this->animation->setStartValue(startValue); + this->animation->setEndValue(1-startValue); + this->animation->start(); +} + +void QModernPushButtonOverlay::setEffectEnabled(bool enabled) { + if(enabled) { + this->effect->setEnabled(true); + this->widget->setVisible(true); + } + else { + this->widget->setVisible(this->effect->opacity() > 0); + this->effect->setEnabled(false); + } +} + +void QModernPushButtonOverlay::handleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State) { + switch (newState) { + case QAbstractAnimation::Running: + this->setEffectEnabled(true); + break; + case QAbstractAnimation::Stopped: + this->setEffectEnabled(false); + break; + default: + break; + } +} diff --git a/sources/qmodernstackedwidget.cpp b/sources/qmodernstackedwidget.cpp new file mode 100644 index 0000000..623858f --- /dev/null +++ b/sources/qmodernstackedwidget.cpp @@ -0,0 +1,52 @@ +#include "../headers/qmodernstackedwidget.h" + +QModernStackedWidget::QModernStackedWidget(QWidget* parent) : QStackedWidget(parent) +{ + opacityAnimation = new QPropertyAnimation(); + opacityAnimation->setPropertyName("opacity"); + opacityAnimation->setEasingCurve(QEasingCurve::InOutQuad); + opacityAnimation->setDuration(400); + opacityAnimation->setLoopCount(1); + connect(opacityAnimation, SIGNAL(finished()), this, SLOT(handleAnimationFinished())); +} + +void QModernStackedWidget::setCurrentWidgetAnimated(QWidget* widget) { + if(widget == nullptr) + return; + + this->newWidget = widget; + + // fade old widget out + QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this); + this->currentWidget()->setGraphicsEffect(opacityEffect); + opacityEffect->setOpacity(1); + + opacityAnimation->setStartValue(1); + opacityAnimation->setEndValue(0); + opacityAnimation->setTargetObject(opacityEffect); + opacityAnimation->start(); +} + +void QModernStackedWidget::handleAnimationFinished() { + // disable graphical effect to prevent errors + this->currentWidget()->graphicsEffect()->setEnabled(false); + + if(this->newWidget == nullptr) { + return; + } + + // hide new widget + QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this); + this->newWidget->setGraphicsEffect(opacityEffect); + opacityEffect->setOpacity(0); + + // set new widget + this->setCurrentWidget(this->newWidget); + this->newWidget = nullptr; + + // fade new widget in + opacityAnimation->setTargetObject(opacityEffect); + opacityAnimation->setStartValue(0); + opacityAnimation->setEndValue(1); + opacityAnimation->start(); +}