JKQtExtras
a library of useful Qt widgets and tools
jkqtemodernprogress.h
1 /*
2  Copyright (c) 2008-2020 Jan W. Krieger (<jan@jkrieger.de>)
3 
4  This software is free software: you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License (LGPL) as
6  published by the Free Software Foundation, either version 2.1 of the License,
7  or (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU Lesser General Public License (LGPL) for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  (LGPL) along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #ifndef JKQTEMODERNPROGRESS_H
19 #define JKQTEMODERNPROGRESS_H
20 
21 #include "jkqtextras_imexport.h"
22 #include <QColor>
23 #include <QDialog>
24 #include <QImage>
25 #include <QLabel>
26 #include <QPushButton>
27 #include <QTextEdit>
28 #include <QTimer>
29 #include <QWidget>
30 
31 /*! \brief a modern progress indicator widget
32  \ingroup JKQtExtrasWidgetsProgress
33 
34  Like <a href="https://doc.qt.io/qt-5/qprogressbar.html">QProgressBar</a>
35  this can be used to display a progress value() between
36  rangeMin() and rangeMax(), but there is also a mode where a colored
37  circle/stroke wanders around the widget to indicate that something is going
38  on, but not giving a real progress.
39 
40 
41  \image html JKQTEModernProgressWidget.png
42 
43  Usage example:
44 
45  \code
46  JKQTEModernProgressWidget* progress=new JKQTEModernProgressWidget(main);
47  // choose a mode
48  progress->setMode(JKQTEModernProgressWidget::Circles);
49  // set the range (these may be any doubles)
50  progress->setRange(0,100);
51  // set the display mode of the text in the center of the widget (here: OFF)
52  progress->setTextDisplayMode(JKQTEModernProgressWidget::NoText);
53  // set the suffix for the text display (e.g. to display "25/100" when JKQTEModernProgressWidget::ValueText is used)
54  progress->setSuffix("/100");
55  // connect to a slider, so we see can change the progress for demonstration
56  connect(slider, &QSlider::valueChanged, progress, &JKQTEModernProgressWidget::setValue);
57  \endcode
58 */
60  Q_OBJECT
61  Q_PROPERTY(QColor innerCircleProgressColor READ innerCircleProgressColor WRITE setInnerCircleProgressColor USER true)
62  Q_PROPERTY(InnerProgressIndicatorMode innerProgressIndicatorMode READ innerProgressIndicatorMode WRITE setInnerProgressIndicatorMode USER true)
63  Q_PROPERTY(TextDisplayMode textDisplayMode READ textDisplayMode WRITE setTextDisplayMode USER true)
64  Q_PROPERTY(Mode mode READ mode WRITE setMode USER true)
65  Q_PROPERTY(int items READ items WRITE setItems USER true)
66  Q_PROPERTY(int spinInterval READ spinInterval WRITE setSpinInterval USER true)
67  Q_PROPERTY(bool spin READ spin WRITE setSpin USER true)
68  Q_PROPERTY(QColor indicatorColor READ indicatorColor WRITE setIndicatorColor USER true)
69  Q_PROPERTY(QColor stopColor READ stopColor WRITE setStopColor USER true)
70  Q_PROPERTY(QColor startColor READ startColor WRITE setStartColor USER true)
71  Q_PROPERTY(QColor innerCircleBackgroundColor READ innerCircleBackgroundColor WRITE setInnerCircleBackgroundColor USER true)
72  Q_PROPERTY(QColor indicatorBackgroundColor READ indicatorBackgroundColor WRITE setIndicatorBackgroundColor USER true)
73  Q_PROPERTY(double nonBackgroundRange READ nonBackgroundRange WRITE setNonBackgroundRange USER true)
74  Q_PROPERTY(double innerRadius READ innerRadius WRITE setInnerRadius USER true)
75  Q_PROPERTY(double outerRadius READ outerRadius WRITE setOuterRadius USER true)
76  Q_PROPERTY(double value READ value WRITE setValue USER true)
77  Q_PROPERTY(double maximum READ maximum WRITE setMaximum USER true)
78  Q_PROPERTY(double minimum READ minimum WRITE setMinimum USER true)
79  Q_PROPERTY(int precision READ precision WRITE setPrecision USER true)
80  Q_PROPERTY(QString suffix READ suffix WRITE setSuffix USER true)
81 public:
82  /** \brief modes of the progress widget */
83  enum Mode {
84  Strokes, /**< a ring of rounded strokes \image html JKQTEModernProgressWidget_Strokes.png */
85  Circles, /**< a ring of circles \image html JKQTEModernProgressWidget_circles.png */
86  Ring, /**< a ring filled with a color \image html JKQTEModernProgressWidget_Ring.png */
87  GradientRing, /**< a ring filled with a color gradient \image html JKQTEModernProgressWidget_GradientRing.png */
88  RoundedStrokeRing, /**< a ring filled with a color \image html JKQTEModernProgressWidget_RoundedStrokeRing.png */
89  Pie, /**< a pie filled with a color \image html JKQTEModernProgressWidget_Pie.png */
90  };
91  Q_ENUM(Mode)
92 
93  /** \brief mode of percentage display */
95  NoText, /**< do not display any text \image html JKQTEModernProgressWidget_NoText.png */
96  PercentText, /**< display the percentage (value() between minimum() and maximum() ) \image html JKQTEModernProgressWidget_PercentText.png */
97  ValueText /**< display the value with the given suffix() (suffix() \c =="/100" in the example image) \image html JKQTEModernProgressWidget_ValueText.png */
98  };
99  Q_ENUM(TextDisplayMode)
100 
101  /** \brief mode of percentage display */
103  NoInnerIndicator, /**< do not display a progress indicator in the center \image html JKQTEModernProgressWidget_NoInnerIndicator.png */
104  InnerProgressBarHorizontal, /**< display a progress bar in the center (below the text) \image html JKQTEModernProgressWidget_InnerProgressBarHorizontal.png */
105  InnerProgressFillVertical, /**< fill the center, depending on the progress, using innerCircleProgressColor() (behind the text) \image html JKQTEModernProgressWidget_InnerProgressFillVertical.png */
106  InnerProgressFillHorizontal, /**< fill the center, depending on the progress, using innerCircleProgressColor() (behind the text) \image html JKQTEModernProgressWidget_InnerProgressFillHorizontal.png */
107  };
108  Q_ENUM(InnerProgressIndicatorMode)
109 
110  JKQTEModernProgressWidget(QWidget *parent = NULL);
112 
113  /** \brief suffix for progress display */
114  QString suffix() const;
115  /** \brief precision for progress display */
116  int precision() const;
117  /** \brief range minimum */
118  double minimum() const;
119  /** \brief range maximum */
120  double maximum() const;
121  /** \brief progress value */
122  double value() const;
123  /** \brief outer radius (0..1) of the displayed circle/stroke ring */
124  double outerRadius() const;
125  /** \brief inner radius (0..1) of the displayed circle/stroke ring */
126  double innerRadius() const;
127  /** \brief color of an indicator, when inactive (usually a bit darker than the
128  * widget background color) */
129  QColor indicatorBackgroundColor() const;
130  /** \brief backround color of the inner circle */
131  QColor innerCircleBackgroundColor() const;
132  /** \brief color of the indicator the furthest away from the main indicator
133  * (usually the same as backgroundColor() ) */
134  QColor startColor() const;
135  /** \brief color just before the current indicator (usually darker than
136  * startColor() ) */
137  QColor stopColor() const;
138  /** \brief color of the current item */
139  QColor indicatorColor() const;
140  /** \brief how many of the indicators (fraction 0..1 of items() ) should
141  * follow current indicator with a different color than backgroundColor() ) */
142  double nonBackgroundRange() const;
143  /** \brief is an automatic spin going on? */
144  bool spin() const;
145  /** \brief interval (milliseconds) of the movement if spin() is \c true */
146  int spinInterval() const;
147  /** \brief number of indicators making up the circle */
148  int items() const;
149  /** \brief type of widget: display a ring of strokes or circles, ...) */
150  Mode mode() const;
151  /** \brief color of the progress text */
152  QColor textColor() const;
153  /** \brief type of text display mode */
154  TextDisplayMode textDisplayMode() const;
155  /** \brief type of inner progress indicator */
156  InnerProgressIndicatorMode innerProgressIndicatorMode() const;
157  /** \brief backround color of the inner circle progress indicator */
158  QColor innerCircleProgressColor() const;
159 
160 
161 public slots:
162  /** \brief range minimum */
163  void setMinimum(double val);
164  /** \brief range maximum */
165  void setMaximum(double val);
166  /** \brief progress value */
167  void setValue(double val);
168  /** \brief set range of progress */
169  void setRange(double min, double max);
170  /** \brief suffix for progress display */
171  void setSuffix(QString s);
172  /** \brief precision for progress display */
173  void setPrecision(int p);
174  /** \brief color of the progress text */
175  void setTextColor(QColor col);
176  /** \brief outer radius (0..1) of the displayed circle/stroke ring */
177  void setOuterRadius(int val);
178  /** \brief inner radius (0..1) of the displayed circle/stroke ring */
179  void setInnerRadius(int val);
180  /** \brief how many of the indicators (fraction 0..1 of items() ) should
181  * follow current indicator with a different color than backgroundColor() ) */
182  void setNonBackgroundRange(double val);
183  /** \brief color of the indicator the furthest away from the main indicator
184  * (usually the same as backgroundColor() ) */
185  void setStartColor(QColor col);
186  /** \brief color just before the current indicator (usually darker than
187  * startColor() ) */
188  void setStopColor(QColor col);
189  /** \brief color of the current item */
190  void setIndicatorColor(QColor col);
191  /** \brief background color behind the indicator items */
192  void setIndicatorBackgroundColor(QColor col);
193  /** \brief color of an indicator, when inactive (usually a bit darker than the
194  * widget background color) */
195  void setBackgroundColor(QColor col);
196  /** \brief backround color of the inner circle */
197  void setInnerCircleBackgroundColor(QColor col);
198  /** \brief backround color of the inner circle progress indicator */
199  void setInnerCircleProgressColor(QColor col);
200  /** \brief is an automatic spin going on? */
201  void setSpin(bool enabled);
202  /** \brief interval (milliseconds) of the movement if spin() is \c true */
203  void setSpinInterval(int msec);
204  /** \brief number of indicators making up the circle */
205  void setItems(int i);
206  /** \brief type of widget: display a ring of strokes or circles, ...) */
207  void setMode(Mode m);
208  /** \brief type of text display mode */
209  void setTextDisplayMode(TextDisplayMode m);
210  /** \brief type of inner progress indicator */
211  void setInnerProgressIndicatorMode(InnerProgressIndicatorMode innerProgressMode);
212 protected:
213  virtual void paintEvent(QPaintEvent *event);
214  virtual void resizeEvent(QResizeEvent *event);
215 protected slots:
216  void doSpin();
217  void updateWidget();
218 
219 private:
220  static int getSmoothItems(int items);
221  TextDisplayMode m_textDisplayMode;
222  QString m_suffix;
223  int m_precision;
224  double m_rangeMin;
225  double m_rangeMax;
226  double m_value;
227  double m_outerRadius;
228  double m_innerRadius;
229  int m_items;
230  int m_spinItem;
231  int m_smoothItems;
232  int m_smoothSpinItem;
233 
234  QColor m_startColor;
235  QColor m_stopColor;
236  QColor m_indicatorBackgroundColor;
237  QColor m_indicatorColor;
238  QColor m_textColor;
239  /** \brief backround color of the inner circle */
240  QColor m_innerCircleBackgroundColor;
241  QColor m_innerCircleProgressColor;
242  double m_nonBackgroundRange;
243  bool m_spin;
244  int m_spinInterval;
245 
246  bool m_doRepaint;
247  bool m_darkCircleBorder;
248 
249  Mode m_mode;
250  InnerProgressIndicatorMode m_innerProgressMode;
251 
252  QTimer timer;
253 };
254 
255 /*! \brief dialog, using JKQTEModernProgressWidget
256  \ingroup JKQtExtrasWidgetsProgress
257 
258  Use open() and hide() to show/hide the dialog and openDelayed() if you wsnt
259  the dialog to appear a given time after you called the function.
260 
261  The dialog is displayed at the screen center if setCentered() is set \c true.
262 
263 
264  \image html JKQTEModernProgressDialog.png
265 
266  Usage example:
267 
268  \snippet jkqtextras_test/testmainwindow.cpp Example: JKQTEModernProgressDialog
269 
270 
271 
272 */
274  Q_OBJECT
275 public:
276  JKQTEModernProgressDialog(QWidget *parent = NULL, Qt::WindowFlags f = 0);
277  JKQTEModernProgressDialog(const QString &labelText,
278  const QString &cancelButtonText,
279  QWidget *parent = NULL,
280  Qt::WindowFlags f = Qt::Window |
281  Qt::WindowTitleHint);
283 
284  /** \brief text in the label of the dialog */
285  QString labelText() const;
286  /** \brief text on the "Cancel" button of the dialog */
287  QString cancelButtonText() const;
288 
289  /** \brief add a line of text to the dialog */
290  void addLongTextLine(const QString &t);
291 
292 
293 
294  /*! \brief display the progress dialog after a delay of \a minimumDuration
295  milliseconds
296 
297  If the dialog has beend closed before the delay runs out, it is never
298  displayed.
299  */
300  void openDelayed(int minimumDuration = 2500);
301  /** \brief returns \c true if the "Cancel" button has been clicked */
302  bool wasCanceled();
303  /** \brief returns the current progress value */
304  double value() const;
305  /** \brief returns the current progress range minimum */
306  double minimum() const;
307  /** \brief returns the current progress range maximum */
308  double maximum() const;
309  /** \brief returns whether the indicator spins */
310  bool spin() const;
311  /** \brief returns the progress widget */
313  /** \brief returns the text label widget */
314  const QLabel *textLabel() const;
315  /** \brief returns the cancel button widget */
316  const QPushButton *cancelButton() const;
317  /** \brief returns the long text lines widget */
318  const QTextEdit *longTextWidth() const;
319  /** \brief returns the progress widget */
321  /** \brief returns the text label widget */
322  QLabel *textLabel();
323  /** \brief returns the cancel button widget */
324  QPushButton *cancelButton();
325  /** \brief returns the long text lines widget */
326  QTextEdit *longTextWidth(); /** \brief en-/disable spin and progress mode */
327  /** \brief set mode of the widget and en/-diable the spin */
329 
330 public slots:
331  /** \brief set the value in progress mode (activate calling setRange() or
332  * setProgress() ) */
333  void setValue(double value);
334  /** \brief set the progress range */
335  void setRange(double min, double max);
336  /** \brief set the progress range */
337  void setMinimum(double min);
338  /** \brief set the progress range */
339  void setMaximum(double max);
340  /** \brief text in the label of the dialog */
341  void setLabelText(const QString &t);
342  /** \brief text on the "Cancel" button of the dialog */
343  void setCancelButtonText(const QString &t);
344  /** \brief indicate whetehr the dialog has a Cancel button (default: \c true )*/
345  void setHasCancel(bool has = true);
346 
347 signals:
348  /** \brief emitted when the "Cancel" button is clicked */
349  void canceled();
350 
351 private:
352  QLabel *label;
353  QTextEdit *longmessage;
355  QPushButton *cancel;
359  QTimer timerDelay;
360 
361 protected:
363  virtual void showEvent(QShowEvent *event);
364  virtual void closeEvent(QCloseEvent *e);
365 protected slots:
367 };
368 
369 #endif // JKQTEMODERNPROGRESS_H
JKQTEModernProgressDialog::longTextWidth
const QTextEdit * longTextWidth() const
returns the long text lines widget
JKQTEModernProgressWidget::RoundedStrokeRing
@ RoundedStrokeRing
Definition: jkqtemodernprogress.h:88
JKQTEModernProgressDialog::cancelButton
QPushButton * cancelButton()
returns the cancel button widget
JKQTEModernProgressWidget::InnerProgressFillHorizontal
@ InnerProgressFillHorizontal
Definition: jkqtemodernprogress.h:106
JKQTEModernProgressDialog::setRange
void setRange(double min, double max)
set the progress range
JKQTEModernProgressDialog::cancelButton
const QPushButton * cancelButton() const
returns the cancel button widget
JKQTEModernProgressWidget::NoText
@ NoText
Definition: jkqtemodernprogress.h:95
JKQTEModernProgressDialog::timerDelay
QTimer timerDelay
Definition: jkqtemodernprogress.h:359
JKQTEModernProgressWidget::PercentText
@ PercentText
Definition: jkqtemodernprogress.h:96
JKQTEModernProgressDialog::setCancelButtonText
void setCancelButtonText(const QString &t)
text on the "Cancel" button of the dialog
JKQTEModernProgressDialog::textLabel
const QLabel * textLabel() const
returns the text label widget
JKQTEModernProgressDialog::openDelayed
void openDelayed(int minimumDuration=2500)
display the progress dialog after a delay of minimumDuration milliseconds
JKQTEModernProgressDialog::setMinimum
void setMinimum(double min)
set the progress range
JKQTEModernProgressDialog::setValue
void setValue(double value)
set the value in progress mode (activate calling setRange() or setProgress() )
JKQTEModernProgressWidget
a modern progress indicator widget
Definition: jkqtemodernprogress.h:59
JKQTEModernProgressDialog::labelText
QString labelText() const
text in the label of the dialog
JKQTEModernProgressWidget::Circles
@ Circles
Definition: jkqtemodernprogress.h:85
JKQTEModernProgressDialog::m_minimumDuration
int m_minimumDuration
Definition: jkqtemodernprogress.h:356
JKQTEModernProgressWidget::Mode
Mode
modes of the progress widget
Definition: jkqtemodernprogress.h:83
JKQTEModernProgressDialog::longTextWidth
QTextEdit * longTextWidth()
returns the long text lines widget
JKQTEXTRAS_LIB_EXPORT
#define JKQTEXTRAS_LIB_EXPORT
Definition: jkqtextras_imexport.h:95
JKQTEModernProgressDialog::progressWidget
const JKQTEModernProgressWidget * progressWidget() const
returns the progress widget
JKQTEModernProgressDialog::progress
JKQTEModernProgressWidget * progress
Definition: jkqtemodernprogress.h:354
JKQTEModernProgressDialog::addLongTextLine
void addLongTextLine(const QString &t)
add a line of text to the dialog
JKQTEModernProgressDialog
dialog, using JKQTEModernProgressWidget
Definition: jkqtemodernprogress.h:273
JKQTEModernProgressDialog::cancelClicked
void cancelClicked()
JKQTEModernProgressDialog::~JKQTEModernProgressDialog
virtual ~JKQTEModernProgressDialog()
JKQTEModernProgressDialog::setMode
void setMode(bool enabledSpin, JKQTEModernProgressWidget::TextDisplayMode mode)
en-/disable spin and progress mode
JKQTEModernProgressDialog::value
double value() const
returns the current progress value
JKQTEModernProgressDialog::cancel
QPushButton * cancel
Definition: jkqtemodernprogress.h:355
JKQTEModernProgressDialog::setLabelText
void setLabelText(const QString &t)
text in the label of the dialog
JKQTEModernProgressDialog::JKQTEModernProgressDialog
JKQTEModernProgressDialog(QWidget *parent=NULL, Qt::WindowFlags f=0)
JKQTEModernProgressDialog::showEvent
virtual void showEvent(QShowEvent *event)
JKQTEModernProgressWidget::InnerProgressIndicatorMode
InnerProgressIndicatorMode
mode of percentage display
Definition: jkqtemodernprogress.h:102
JKQTEModernProgressDialog::setHasCancel
void setHasCancel(bool has=true)
indicate whetehr the dialog has a Cancel button (default: true )
JKQTEModernProgressWidget::Ring
@ Ring
Definition: jkqtemodernprogress.h:86
JKQTEModernProgressDialog::cancelButtonText
QString cancelButtonText() const
text on the "Cancel" button of the dialog
JKQTEModernProgressDialog::textLabel
QLabel * textLabel()
returns the text label widget
JKQTEModernProgressWidget::NoInnerIndicator
@ NoInnerIndicator
Definition: jkqtemodernprogress.h:103
JKQTEModernProgressWidget::GradientRing
@ GradientRing
Definition: jkqtemodernprogress.h:87
JKQTEModernProgressDialog::m_wasCancel
bool m_wasCancel
Definition: jkqtemodernprogress.h:357
JKQTEModernProgressDialog::setMaximum
void setMaximum(double max)
set the progress range
JKQTEModernProgressDialog::canceled
void canceled()
emitted when the "Cancel" button is clicked
JKQTEModernProgressDialog::label
QLabel * label
Definition: jkqtemodernprogress.h:352
JKQTEModernProgressWidget::Strokes
@ Strokes
Definition: jkqtemodernprogress.h:84
JKQTEModernProgressDialog::wasCanceled
bool wasCanceled()
returns true if the "Cancel" button has been clicked
JKQTEModernProgressDialog::m_closedBeforeDelay
bool m_closedBeforeDelay
Definition: jkqtemodernprogress.h:358
JKQTEModernProgressDialog::JKQTEModernProgressDialog
JKQTEModernProgressDialog(const QString &labelText, const QString &cancelButtonText, QWidget *parent=NULL, Qt::WindowFlags f=Qt::Window|Qt::WindowTitleHint)
JKQTEModernProgressDialog::maximum
double maximum() const
returns the current progress range maximum
JKQTEModernProgressWidget::Pie
@ Pie
Definition: jkqtemodernprogress.h:89
JKQTEModernProgressDialog::closeEvent
virtual void closeEvent(QCloseEvent *e)
JKQTEModernProgressDialog::progressWidget
JKQTEModernProgressWidget * progressWidget()
returns the progress widget
JKQTEModernProgressDialog::longmessage
QTextEdit * longmessage
Definition: jkqtemodernprogress.h:353
JKQTEModernProgressDialog::minimum
double minimum() const
returns the current progress range minimum
JKQTEModernProgressDialog::spin
bool spin() const
returns whether the indicator spins
JKQTEModernProgressWidget::InnerProgressBarHorizontal
@ InnerProgressBarHorizontal
Definition: jkqtemodernprogress.h:104
JKQTEModernProgressWidget::InnerProgressFillVertical
@ InnerProgressFillVertical
Definition: jkqtemodernprogress.h:105
JKQTEModernProgressWidget::TextDisplayMode
TextDisplayMode
mode of percentage display
Definition: jkqtemodernprogress.h:94
JKQTEModernProgressDialog::createWidgets
void createWidgets()