forked from qt-creator/qt-creator
Spinner: Add SpinnerWidget
Move it from spinner example and make it a reusable widget. Change-Id: I3d74ec491f5d1cb7d012551f624cff2c618952ca Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -5,19 +5,21 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace SpinnerSolution {
|
||||
|
||||
class OverlayWidget : public QWidget
|
||||
class WidgetOverlay : public QWidget
|
||||
{
|
||||
public:
|
||||
using PaintFunction = std::function<void(QWidget *, QPainter &, QPaintEvent *)>;
|
||||
|
||||
explicit OverlayWidget(QWidget *parent = nullptr)
|
||||
explicit WidgetOverlay(QWidget *parent = nullptr)
|
||||
{
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
if (parent)
|
||||
@@ -151,11 +153,11 @@ void SpinnerPainter::paint(QPainter &painter, const QRect &rect) const
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
class SpinnerWidget : public OverlayWidget
|
||||
class SpinnerOverlay : public WidgetOverlay
|
||||
{
|
||||
public:
|
||||
explicit SpinnerWidget(SpinnerSize size, QWidget *parent = nullptr)
|
||||
: OverlayWidget(parent)
|
||||
explicit SpinnerOverlay(SpinnerSize size, QWidget *parent = nullptr)
|
||||
: WidgetOverlay(parent)
|
||||
, m_paint(size)
|
||||
{
|
||||
setPaintFunction(
|
||||
@@ -219,7 +221,7 @@ private:
|
||||
*/
|
||||
Spinner::Spinner(SpinnerSize size, QWidget *parent)
|
||||
: QObject(parent)
|
||||
, m_widget(new SpinnerWidget(size, parent)) {}
|
||||
, m_widget(new SpinnerOverlay(size, parent)) {}
|
||||
|
||||
/*!
|
||||
Sets the size of the spinner to the given \a size.
|
||||
@@ -263,4 +265,83 @@ void Spinner::setVisible(bool visible)
|
||||
m_widget->setVisible(visible);
|
||||
}
|
||||
|
||||
static QString colorButtonStyleSheet(const QColor &bgColor)
|
||||
{
|
||||
QString rc("border-width: 1px; border-radius: 1px; border-color: black; ");
|
||||
rc += bgColor.isValid() ? "border-style: solid; background:" + bgColor.name() + ";"
|
||||
: QString("border-style: dotted;");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static QColor stateToColor(SpinnerState state)
|
||||
{
|
||||
switch (state) {
|
||||
case SpinnerState::NotRunning: return Qt::gray;
|
||||
case SpinnerState::Running: return Qt::yellow;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
class SpinnerWidgetPrivate : public QLabel
|
||||
{
|
||||
public:
|
||||
SpinnerWidgetPrivate(QWidget *parent = nullptr)
|
||||
: QLabel(parent)
|
||||
, m_spinner(new Spinner(SpinnerSize::Small, this))
|
||||
{
|
||||
updateState();
|
||||
}
|
||||
|
||||
void setState(SpinnerState state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
m_state = state;
|
||||
updateState();
|
||||
}
|
||||
|
||||
void setDecorated(bool on)
|
||||
{
|
||||
if (m_decorated == on)
|
||||
return;
|
||||
m_decorated = on;
|
||||
updateState();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateState()
|
||||
{
|
||||
const int size = m_decorated ? 26 : 24;
|
||||
setFixedSize(size, size);
|
||||
setStyleSheet(m_decorated ? colorButtonStyleSheet(stateToColor(m_state)) : QString());
|
||||
if (m_state == SpinnerState::Running)
|
||||
m_spinner->show();
|
||||
else
|
||||
m_spinner->hide();
|
||||
}
|
||||
bool m_decorated = true;
|
||||
SpinnerState m_state = SpinnerState::NotRunning;
|
||||
Spinner *m_spinner = nullptr;
|
||||
};
|
||||
|
||||
SpinnerWidget::SpinnerWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, d(new SpinnerWidgetPrivate(this))
|
||||
{
|
||||
QBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(d);
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
void SpinnerWidget::setState(SpinnerState state)
|
||||
{
|
||||
d->setState(state);
|
||||
}
|
||||
|
||||
void SpinnerWidget::setDecorated(bool on)
|
||||
{
|
||||
d->setDecorated(on);
|
||||
}
|
||||
|
||||
} // namespace SpinnerSolution
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "spinner_global.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
namespace SpinnerSolution {
|
||||
|
||||
@@ -15,11 +15,15 @@ Q_NAMESPACE_EXPORT(SPINNER_EXPORT)
|
||||
enum class SpinnerSize { Small, Medium, Large };
|
||||
Q_ENUM_NS(SpinnerSize)
|
||||
|
||||
enum class SpinnerState { NotRunning, Running };
|
||||
Q_ENUM_NS(SpinnerState)
|
||||
|
||||
// TODO: SpinnerOverlay and SpinnerWidget?
|
||||
|
||||
class SPINNER_EXPORT Spinner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Spinner(SpinnerSize size, QWidget *parent = nullptr);
|
||||
void setSize(SpinnerSize size);
|
||||
@@ -29,7 +33,20 @@ public:
|
||||
void setVisible(bool visible);
|
||||
|
||||
private:
|
||||
class SpinnerWidget *m_widget = nullptr;
|
||||
class SpinnerOverlay *m_widget = nullptr;
|
||||
};
|
||||
|
||||
class SPINNER_EXPORT SpinnerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SpinnerWidget(QWidget *parent = nullptr);
|
||||
void setState(SpinnerState state);
|
||||
void setDecorated(bool on);
|
||||
|
||||
private:
|
||||
class SpinnerWidgetPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace SpinnerSolution
|
||||
|
@@ -14,82 +14,12 @@
|
||||
|
||||
using namespace SpinnerSolution;
|
||||
|
||||
enum class State {
|
||||
NotRunning,
|
||||
Running
|
||||
};
|
||||
|
||||
static QString colorButtonStyleSheet(const QColor &bgColor)
|
||||
{
|
||||
QString rc("border-width: 2px; border-radius: 2px; border-color: black; ");
|
||||
rc += bgColor.isValid() ? "border-style: solid; background:" + bgColor.name() + ";"
|
||||
: QString("border-style: dotted;");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static QColor stateToColor(State state)
|
||||
{
|
||||
switch (state) {
|
||||
case State::NotRunning: return Qt::gray;
|
||||
case State::Running: return Qt::yellow;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
class StateIndicator : public QLabel
|
||||
{
|
||||
public:
|
||||
StateIndicator(QWidget *parent = nullptr)
|
||||
: QLabel(parent)
|
||||
{
|
||||
setFixedSize(30, 30);
|
||||
m_spinner = new Spinner(SpinnerSize::Small, this);
|
||||
m_spinner->hide();
|
||||
updateState();
|
||||
}
|
||||
|
||||
void setState(State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
m_state = state;
|
||||
updateState();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateState()
|
||||
{
|
||||
setStyleSheet(colorButtonStyleSheet(stateToColor(m_state)));
|
||||
if (m_state == State::Running)
|
||||
m_spinner->show();
|
||||
else
|
||||
m_spinner->hide();
|
||||
}
|
||||
State m_state = State::NotRunning;
|
||||
Spinner *m_spinner = nullptr;
|
||||
};
|
||||
|
||||
class StateWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
StateWidget() : m_stateIndicator(new StateIndicator(this)) {
|
||||
QBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_stateIndicator);
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
}
|
||||
void setState(State state) { m_stateIndicator->setState(state); }
|
||||
|
||||
protected:
|
||||
StateIndicator *m_stateIndicator = nullptr;
|
||||
};
|
||||
|
||||
QGroupBox *createGroupBox(SpinnerSize size, QWidget *widget)
|
||||
{
|
||||
const QMetaEnum spinnerSize = QMetaEnum::fromType<SpinnerSize>();
|
||||
QGroupBox *groupBox = new QGroupBox(spinnerSize.valueToKey(int(size)));
|
||||
|
||||
StateWidget *stateWidget = new StateWidget;
|
||||
SpinnerWidget *spinnerWidget = new SpinnerWidget;
|
||||
QToolButton *startButton = new QToolButton;
|
||||
startButton->setText("Start");
|
||||
QToolButton *stopButton = new QToolButton;
|
||||
@@ -97,7 +27,7 @@ QGroupBox *createGroupBox(SpinnerSize size, QWidget *widget)
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(groupBox);
|
||||
QHBoxLayout *topLayout = new QHBoxLayout();
|
||||
topLayout->addWidget(stateWidget);
|
||||
topLayout->addWidget(spinnerWidget);
|
||||
topLayout->addWidget(startButton);
|
||||
topLayout->addWidget(stopButton);
|
||||
topLayout->addStretch();
|
||||
@@ -108,12 +38,12 @@ QGroupBox *createGroupBox(SpinnerSize size, QWidget *widget)
|
||||
spinner->hide(); // TODO: make the default hidden?
|
||||
|
||||
QObject::connect(startButton, &QAbstractButton::clicked, groupBox, [=] {
|
||||
stateWidget->setState(State::Running);
|
||||
spinnerWidget->setState(SpinnerState::Running);
|
||||
spinner->show();
|
||||
widget->setEnabled(false);
|
||||
});
|
||||
QObject::connect(stopButton, &QAbstractButton::clicked, groupBox, [=] {
|
||||
stateWidget->setState(State::NotRunning);
|
||||
spinnerWidget->setState(SpinnerState::NotRunning);
|
||||
spinner->hide();
|
||||
widget->setEnabled(true);
|
||||
});
|
||||
|
Reference in New Issue
Block a user