diff --git a/src/Cutter.pro b/src/Cutter.pro index cd630d16..dba1439d 100644 --- a/src/Cutter.pro +++ b/src/Cutter.pro @@ -168,7 +168,8 @@ SOURCES += \ widgets/BacktraceWidget.cpp \ dialogs/OpenFileDialog.cpp \ utils/StringsTask.cpp \ - utils/CommandTask.cpp + utils/CommandTask.cpp \ + utils/ProgressIndicator.cpp HEADERS += \ Cutter.h \ @@ -251,7 +252,8 @@ HEADERS += \ widgets/BacktraceWidget.h \ dialogs/OpenFileDialog.h \ utils/StringsTask.h \ - utils/CommandTask.h + utils/CommandTask.h \ + utils/ProgressIndicator.h FORMS += \ dialogs/AboutDialog.ui \ diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 0bb8494e..207c320e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -36,6 +36,7 @@ #include "utils/HexAsciiHighlighter.h" #include "utils/Helpers.h" #include "utils/SvgIconEngine.h" +#include "utils/ProgressIndicator.h" #include "dialogs/NewFileDialog.h" #include "dialogs/OptionsDialog.h" @@ -143,8 +144,14 @@ void MainWindow::initUI() spacer->setMinimumSize(20, 20); ui->mainToolBar->addWidget(spacer); - tasksIndicator = new QLabel(this); - ui->mainToolBar->addWidget(tasksIndicator); + tasksProgressIndicator = new ProgressIndicator(); + ui->mainToolBar->addWidget(tasksProgressIndicator); + + QWidget *spacerEnd = new QWidget(); + spacerEnd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + spacerEnd->setMinimumSize(4, 0); + spacerEnd->setMaximumWidth(4); + ui->mainToolBar->addWidget(spacerEnd); // Visual navigation tool bar this->visualNavbar = new VisualNavbar(this); @@ -237,9 +244,7 @@ void MainWindow::initUI() void MainWindow::updateTasksIndicator() { bool running = Core()->getAsyncTaskManager()->getTasksRunning(); - QLabel *l = static_cast(tasksIndicator); - l->setText(running ? "running" : ""); - //tasksIndicator->setVisible(running); + tasksProgressIndicator->setProgressIndicatorVisible(running); } void MainWindow::on_actionExtraGraph_triggered() diff --git a/src/MainWindow.h b/src/MainWindow.h index 782521e4..b6baf649 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -19,6 +19,7 @@ class CutterCore; class Omnibar; +class ProgressIndicator; class PreviewWidget; class Highlighter; class AsciiHighlighter; @@ -183,7 +184,7 @@ private: AsciiHighlighter *hex_highlighter; VisualNavbar *visualNavbar; Omnibar *omnibar; - QWidget *tasksIndicator; + ProgressIndicator *tasksProgressIndicator; Configuration *configuration; diff --git a/src/utils/ProgressIndicator.cpp b/src/utils/ProgressIndicator.cpp new file mode 100644 index 00000000..e28b1b96 --- /dev/null +++ b/src/utils/ProgressIndicator.cpp @@ -0,0 +1,89 @@ + +#include "ProgressIndicator.h" + +#include + +static const int lineWidth = 3; +static const int paddingOuter = lineWidth + 2; +static const int paddingInner = 8; +static const int arms = 12; +static const int timerInterval = 50; + +ProgressIndicator::ProgressIndicator(QWidget *parent) + : QWidget(parent) +{ + updateAnimationTimer(); +} + +ProgressIndicator::~ProgressIndicator() +{ +} + +void ProgressIndicator::setProgressIndicatorVisible(bool visible) +{ + bool change = progressIndicatorVisible != visible; + progressIndicatorVisible = visible; + if (change) { + update(); + } + updateAnimationTimer(); +} + +void ProgressIndicator::setAnimating(bool animating) +{ + this->animating = animating; + updateAnimationTimer(); +} + +void ProgressIndicator::updateAnimationTimer() +{ + bool shouldBeAnimating = animating && progressIndicatorVisible; + if (shouldBeAnimating && !animationTimerId) { + animationTimerId = startTimer(timerInterval); + } else { + killTimer(animationTimerId); + animationTimerId = 0; + } +} + +QSize ProgressIndicator::minimumSizeHint() const +{ + return QSize(16, 16); +} + +QSize ProgressIndicator::sizeHint() const +{ + return QSize(32, 32); +} + +void ProgressIndicator::timerEvent(QTimerEvent *) +{ + animationState = (animationState + 1) % arms; + update(); +} +void ProgressIndicator::paintEvent(QPaintEvent *) +{ + if (!getProgressIndicatorVisible()) { + return; + } + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + QPen pen(palette().windowText(), lineWidth, Qt::SolidLine, Qt::RoundCap); + painter.setPen(pen); + + QPointF origin(width() * 0.5, height() * 0.5); + QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0); + + qreal angle = 360.0 / arms; + for (int i=0; i + +class ProgressIndicator: public QWidget +{ +public: + ProgressIndicator(QWidget *parent = nullptr); + virtual ~ProgressIndicator(); + + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + + bool getProgressIndicatorVisible() const { return progressIndicatorVisible; } + void setProgressIndicatorVisible(bool visible); + + bool getAnimating() const { return animating; } + void setAnimating(bool animating); + +protected: + void timerEvent(QTimerEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private: + bool animating = true; + bool progressIndicatorVisible = true; + + int animationTimerId = 0; + int animationState = 0; + + void updateAnimationTimer(); +}; + + +#endif //PROGRESSINDICATOR_H