Commit 9067b4bf authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Fixed possible crashes when updating property min/max settings from non-GUI thread.

Enforced update of min/max/singleStep values in AbstractAdjusterWidget to be performed in Qt main thread through additional indirection via Qt queued signals.
parent 1d009b00
...@@ -76,39 +76,39 @@ namespace campvis { ...@@ -76,39 +76,39 @@ namespace campvis {
T minimum() const; T minimum() const;
/** /**
* Change the adjuster's minimum value. * Return the adjuster's maximum value.
* \param minimum new minimum value for the adjuster
*/ */
void setMinimum(T minimum); T maximum() const;
/** /**
* Return the adjuster's maximum value. * Return the adjuster's single step value.
*/ */
T maximum() const; T singleStep() const;
protected:
/** /**
* Change the adjuster's maximum value. * Change the adjuster's current value.
* \param maximum new maximum value for the adjuster * \param value new value for the adjuster
*/ */
void setMaximum(T maximum); void setValueImpl(T value);
/** /**
* Return the adjuster's single step value. * Change the adjuster's minimum value.
* \param minimum new minimum value for the adjuster
*/ */
T singleStep() const; void setMinimumImpl(T minimum);
/** /**
* Change the adjuster's single step value. * Change the adjuster's maximum value.
* \param value new single step value for the adjuster * \param maximum new maximum value for the adjuster
*/ */
void setSingleStep(T value); void setMaximumImpl(T maximum);
protected:
/** /**
* Change the adjuster's current value. * Change the adjuster's single step value.
* \param value new value for the adjuster * \param value new single step value for the adjuster
*/ */
void setValueImpl(T value); void setSingleStepImpl(T value);
/// Slot getting called when the spin box's value changes /// Slot getting called when the spin box's value changes
void onSpinBoxValueChangedImpl(T value); void onSpinBoxValueChangedImpl(T value);
...@@ -161,53 +161,45 @@ namespace campvis { ...@@ -161,53 +161,45 @@ namespace campvis {
} }
template<typename T> template<typename T>
T AbstractAdjusterWidget<T>::value() const T AbstractAdjusterWidget<T>::value() const {
{
return _spinBox->value(); return _spinBox->value();
} }
template<typename T> template<typename T>
void AbstractAdjusterWidget<T>::setValueImpl(T value) void AbstractAdjusterWidget<T>::setValueImpl(T value) {
{
_spinBox->setValue(value); _spinBox->setValue(value);
setSliderValue(value); setSliderValue(value);
} }
template<typename T> template<typename T>
T AbstractAdjusterWidget<T>::minimum() const T AbstractAdjusterWidget<T>::minimum() const {
{
return _spinBox->minimum(); return _spinBox->minimum();
} }
template<typename T> template<typename T>
void AbstractAdjusterWidget<T>::setMinimum(T minimum) void AbstractAdjusterWidget<T>::setMinimumImpl(T minimum) {
{
_spinBox->setMinimum(minimum); _spinBox->setMinimum(minimum);
setSliderProperties(_spinBox->singleStep(), minimum, _spinBox->maximum()); setSliderProperties(_spinBox->singleStep(), minimum, _spinBox->maximum());
} }
template<typename T> template<typename T>
T AbstractAdjusterWidget<T>::maximum() const T AbstractAdjusterWidget<T>::maximum() const {
{
return _spinBox->maximum(); return _spinBox->maximum();
} }
template<typename T> template<typename T>
void AbstractAdjusterWidget<T>::setMaximum(T maximum) void AbstractAdjusterWidget<T>::setMaximumImpl(T maximum) {
{
_spinBox->setMaximum(maximum); _spinBox->setMaximum(maximum);
setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), maximum); setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), maximum);
} }
template<typename T> template<typename T>
T AbstractAdjusterWidget<T>::singleStep() const T AbstractAdjusterWidget<T>::singleStep() const {
{
return _spinBox->singleStep(); return _spinBox->singleStep();
} }
template<typename T> template<typename T>
void AbstractAdjusterWidget<T>::setSingleStep(T value) void AbstractAdjusterWidget<T>::setSingleStepImpl(T value) {
{
_spinBox->setSingleStep(value); _spinBox->setSingleStep(value);
setSliderProperties(value, _spinBox->minimum(), _spinBox->maximum()); setSliderProperties(value, _spinBox->minimum(), _spinBox->maximum());
} }
......
...@@ -32,21 +32,35 @@ namespace campvis { ...@@ -32,21 +32,35 @@ namespace campvis {
{ {
setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum()); setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum());
connect(this, SIGNAL(s_minChanged(double)), this, SLOT(onMinChanged(double)), Qt::QueuedConnection);
connect(this, SIGNAL(s_maxChanged(double)), this, SLOT(onMaxChanged(double)), Qt::QueuedConnection);
connect(this, SIGNAL(s_singleStepChanged(double)), this, SLOT(onSingleStepChanged(double)), Qt::QueuedConnection);
connect(_spinBox, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged(double))); connect(_spinBox, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged(double)));
connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int)));
} }
void DoubleAdjusterWidget::setValue(double value) void DoubleAdjusterWidget::setValue(double value) {
{
setValueImpl(value); setValueImpl(value);
} }
void DoubleAdjusterWidget::setDecimals(int prec) void DoubleAdjusterWidget::setDecimals(int prec) {
{
_spinBox->setDecimals(prec); _spinBox->setDecimals(prec);
setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum()); setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum());
} }
void DoubleAdjusterWidget::setMinimum(double minimum) {
emit s_minChanged(minimum);
}
void DoubleAdjusterWidget::setMaximum(double maximum) {
emit s_maxChanged(maximum);
}
void DoubleAdjusterWidget::setSingleStep(double value) {
emit s_singleStepChanged(value);
}
void DoubleAdjusterWidget::onSpinBoxValueChanged(double value) { void DoubleAdjusterWidget::onSpinBoxValueChanged(double value) {
onSpinBoxValueChangedImpl(value); onSpinBoxValueChangedImpl(value);
emit valueChanged(value); emit valueChanged(value);
...@@ -67,4 +81,18 @@ namespace campvis { ...@@ -67,4 +81,18 @@ namespace campvis {
AbstractAdjusterWidget<double>::setSliderProperties(1, 0, std::ceil((maxValue - minValue) / stepValue)); AbstractAdjusterWidget<double>::setSliderProperties(1, 0, std::ceil((maxValue - minValue) / stepValue));
setSliderValue(value()); setSliderValue(value());
} }
void DoubleAdjusterWidget::onMinChanged(double minimum) {
setMinimumImpl(minimum);
}
void DoubleAdjusterWidget::onMaxChanged(double maximum) {
setMaximumImpl(maximum);
}
void DoubleAdjusterWidget::onSingleStepChanged(double value) {
setSingleStepImpl(value);
}
} }
...@@ -46,11 +46,29 @@ namespace campvis { ...@@ -46,11 +46,29 @@ namespace campvis {
DoubleAdjusterWidget(QWidget* parent = 0); DoubleAdjusterWidget(QWidget* parent = 0);
/** /**
* Set how many decimals the adjuster will use for displaying and interpreting doubles. * Set how many decimals the adjuster will use for displaying and doubleerpreting doubles.
* \param prec number of decimals the adjuster will use * \param prec number of decimals the adjuster will use
*/ */
void setDecimals(int prec); void setDecimals(int prec);
/**
* Change the adjuster's minimum value.
* \param minimum new minimum value for the adjuster
*/
void setMinimum(double minimum);
/**
* Change the adjuster's maximum value.
* \param maximum new maximum value for the adjuster
*/
void setMaximum(double maximum);
/**
* Change the adjuster's single step value.
* \param value new single step value for the adjuster
*/
void setSingleStep(double value);
public slots: public slots:
/** /**
* Change the adjuster's current value. * Change the adjuster's current value.
...@@ -65,6 +83,13 @@ namespace campvis { ...@@ -65,6 +83,13 @@ namespace campvis {
*/ */
void valueChanged(double value); void valueChanged(double value);
/// Signal emitted when the property's minimum value has changed
void s_minChanged(double minimum);
/// Signal emitted when the property's maximum value has changed
void s_maxChanged(double maximum);
/// Signal emitted when the property's single step value has changed
void s_singleStepChanged(double value);
protected: protected:
/** /**
* Calculate and set the slider's value. * Calculate and set the slider's value.
...@@ -94,6 +119,12 @@ namespace campvis { ...@@ -94,6 +119,12 @@ namespace campvis {
/// Slot getting called when the slider's value changes /// Slot getting called when the slider's value changes
void onSliderValueChanged(int value); void onSliderValueChanged(int value);
/// Slot getting called when the property's minimum value has changed
void onMinChanged(double minimum);
/// Slot getting called when the property's maximum value has changed
void onMaxChanged(double maximum);
/// Slot getting called when the property's single step value has changed
void onSingleStepChanged(double value);
}; };
} }
......
...@@ -32,6 +32,10 @@ namespace campvis { ...@@ -32,6 +32,10 @@ namespace campvis {
{ {
setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum()); setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), _spinBox->maximum());
connect(this, SIGNAL(s_minChanged(int)), this, SLOT(onMinChanged(int)), Qt::QueuedConnection);
connect(this, SIGNAL(s_maxChanged(int)), this, SLOT(onMaxChanged(int)), Qt::QueuedConnection);
connect(this, SIGNAL(s_singleStepChanged(int)), this, SLOT(onSingleStepChanged(int)), Qt::QueuedConnection);
connect(_spinBox, SIGNAL(valueChanged(int)), this, SLOT(onSpinBoxValueChanged(int))); connect(_spinBox, SIGNAL(valueChanged(int)), this, SLOT(onSpinBoxValueChanged(int)));
connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int)));
} }
...@@ -41,6 +45,18 @@ namespace campvis { ...@@ -41,6 +45,18 @@ namespace campvis {
setValueImpl(value); setValueImpl(value);
} }
void IntAdjusterWidget::setMinimum(int minimum) {
emit s_minChanged(minimum);
}
void IntAdjusterWidget::setMaximum(int maximum) {
emit s_maxChanged(maximum);
}
void IntAdjusterWidget::setSingleStep(int value) {
emit s_singleStepChanged(value);
}
void IntAdjusterWidget::onSpinBoxValueChanged(int value) { void IntAdjusterWidget::onSpinBoxValueChanged(int value) {
onSpinBoxValueChangedImpl(value); onSpinBoxValueChangedImpl(value);
emit valueChanged(value); emit valueChanged(value);
...@@ -51,4 +67,16 @@ namespace campvis { ...@@ -51,4 +67,16 @@ namespace campvis {
emit valueChanged(value); emit valueChanged(value);
} }
void IntAdjusterWidget::onMinChanged(int minimum) {
setMinimumImpl(minimum);
}
void IntAdjusterWidget::onMaxChanged(int maximum) {
setMaximumImpl(maximum);
}
void IntAdjusterWidget::onSingleStepChanged(int value) {
setSingleStepImpl(value);
}
} }
...@@ -35,7 +35,6 @@ namespace campvis { ...@@ -35,7 +35,6 @@ namespace campvis {
* which is better suited for precise adjustments. * which is better suited for precise adjustments.
*/ */
class IntAdjusterWidget : public AbstractAdjusterWidget<int> { class IntAdjusterWidget : public AbstractAdjusterWidget<int> {
Q_OBJECT Q_OBJECT
public: public:
...@@ -45,13 +44,30 @@ namespace campvis { ...@@ -45,13 +44,30 @@ namespace campvis {
*/ */
IntAdjusterWidget(QWidget* parent = 0); IntAdjusterWidget(QWidget* parent = 0);
public slots:
/** /**
* Change the adjuster's current value. * Change the adjuster's current value.
* \param value New value for the adjuster * \param value New value for the adjuster
*/ */
void setValue(int value); void setValue(int value);
/**
* Change the adjuster's minimum value.
* \param minimum new minimum value for the adjuster
*/
void setMinimum(int minimum);
/**
* Change the adjuster's maximum value.
* \param maximum new maximum value for the adjuster
*/
void setMaximum(int maximum);
/**
* Change the adjuster's single step value.
* \param value new single step value for the adjuster
*/
void setSingleStep(int value);
signals: signals:
/** /**
* This signal is emitted whenever the adjuster's value is changed. * This signal is emitted whenever the adjuster's value is changed.
...@@ -59,6 +75,14 @@ namespace campvis { ...@@ -59,6 +75,14 @@ namespace campvis {
*/ */
void valueChanged(int value); void valueChanged(int value);
/// Signal emitted when the property's minimum value has changed
void s_minChanged(int minimum);
/// Signal emitted when the property's maximum value has changed
void s_maxChanged(int maximum);
/// Signal emitted when the property's single step value has changed
void s_singleStepChanged(int value);
private slots: private slots:
/// Slot getting called when the spin box's value changes /// Slot getting called when the spin box's value changes
void onSpinBoxValueChanged(int value); void onSpinBoxValueChanged(int value);
...@@ -66,6 +90,13 @@ namespace campvis { ...@@ -66,6 +90,13 @@ namespace campvis {
/// Slot getting called when the slider's value changes /// Slot getting called when the slider's value changes
void onSliderValueChanged(int value); void onSliderValueChanged(int value);
/// Slot getting called when the property's minimum value has changed
void onMinChanged(int minimum);
/// Slot getting called when the property's maximum value has changed
void onMaxChanged(int maximum);
/// Slot getting called when the property's single step value has changed
void onSingleStepChanged(int value);
}; };
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment