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
......@@ -75,40 +75,40 @@ namespace campvis {
*/
T minimum() const;
/**
* Change the adjuster's minimum value.
* \param minimum new minimum value for the adjuster
*/
void setMinimum(T minimum);
/**
* Return the adjuster's maximum value.
*/
T maximum() const;
/**
* Change the adjuster's maximum value.
* \param maximum new maximum value for the adjuster
*/
void setMaximum(T maximum);
/**
* Return the adjuster's single step value.
*/
T singleStep() const;
/**
* Change the adjuster's single step value.
* \param value new single step value for the adjuster
*/
void setSingleStep(T value);
protected:
/**
* Change the adjuster's current value.
* \param value new value for the adjuster
*/
void setValueImpl(T value);
/**
* Change the adjuster's minimum value.
* \param minimum new minimum value for the adjuster
*/
void setMinimumImpl(T minimum);
/**
* Change the adjuster's maximum value.
* \param maximum new maximum value for the adjuster
*/
void setMaximumImpl(T maximum);
/**
* Change the adjuster's single step value.
* \param value new single step value for the adjuster
*/
void setSingleStepImpl(T value);
/// Slot getting called when the spin box's value changes
void onSpinBoxValueChangedImpl(T value);
......@@ -161,53 +161,45 @@ namespace campvis {
}
template<typename T>
T AbstractAdjusterWidget<T>::value() const
{
T AbstractAdjusterWidget<T>::value() const {
return _spinBox->value();
}
template<typename T>
void AbstractAdjusterWidget<T>::setValueImpl(T value)
{
void AbstractAdjusterWidget<T>::setValueImpl(T value) {
_spinBox->setValue(value);
setSliderValue(value);
}
template<typename T>
T AbstractAdjusterWidget<T>::minimum() const
{
T AbstractAdjusterWidget<T>::minimum() const {
return _spinBox->minimum();
}
template<typename T>
void AbstractAdjusterWidget<T>::setMinimum(T minimum)
{
void AbstractAdjusterWidget<T>::setMinimumImpl(T minimum) {
_spinBox->setMinimum(minimum);
setSliderProperties(_spinBox->singleStep(), minimum, _spinBox->maximum());
}
template<typename T>
T AbstractAdjusterWidget<T>::maximum() const
{
T AbstractAdjusterWidget<T>::maximum() const {
return _spinBox->maximum();
}
template<typename T>
void AbstractAdjusterWidget<T>::setMaximum(T maximum)
{
void AbstractAdjusterWidget<T>::setMaximumImpl(T maximum) {
_spinBox->setMaximum(maximum);
setSliderProperties(_spinBox->singleStep(), _spinBox->minimum(), maximum);
}
template<typename T>
T AbstractAdjusterWidget<T>::singleStep() const
{
T AbstractAdjusterWidget<T>::singleStep() const {
return _spinBox->singleStep();
}
template<typename T>
void AbstractAdjusterWidget<T>::setSingleStep(T value)
{
void AbstractAdjusterWidget<T>::setSingleStepImpl(T value) {
_spinBox->setSingleStep(value);
setSliderProperties(value, _spinBox->minimum(), _spinBox->maximum());
}
......
......@@ -32,21 +32,35 @@ namespace campvis {
{
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(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int)));
}
void DoubleAdjusterWidget::setValue(double value)
{
void DoubleAdjusterWidget::setValue(double value) {
setValueImpl(value);
}
void DoubleAdjusterWidget::setDecimals(int prec)
{
void DoubleAdjusterWidget::setDecimals(int prec) {
_spinBox->setDecimals(prec);
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) {
onSpinBoxValueChangedImpl(value);
emit valueChanged(value);
......@@ -67,4 +81,18 @@ namespace campvis {
AbstractAdjusterWidget<double>::setSliderProperties(1, 0, std::ceil((maxValue - minValue) / stepValue));
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 {
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
*/
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:
/**
* Change the adjuster's current value.
......@@ -65,6 +83,13 @@ namespace campvis {
*/
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:
/**
* Calculate and set the slider's value.
......@@ -94,6 +119,12 @@ namespace campvis {
/// Slot getting called when the slider's value changes
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 {
{
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(_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int)));
}
......@@ -41,6 +45,18 @@ namespace campvis {
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) {
onSpinBoxValueChangedImpl(value);
emit valueChanged(value);
......@@ -51,4 +67,16 @@ namespace campvis {
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 {
* which is better suited for precise adjustments.
*/
class IntAdjusterWidget : public AbstractAdjusterWidget<int> {
Q_OBJECT
public:
......@@ -45,13 +44,30 @@ namespace campvis {
*/
IntAdjusterWidget(QWidget* parent = 0);
public slots:
/**
* Change the adjuster's current value.
* \param value New value for the adjuster
*/
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:
/**
* This signal is emitted whenever the adjuster's value is changed.
......@@ -59,6 +75,14 @@ namespace campvis {
*/
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:
/// Slot getting called when the spin box's value changes
void onSpinBoxValueChanged(int value);
......@@ -66,6 +90,13 @@ namespace campvis {
/// Slot getting called when the slider's value changes
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