Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

Commit bfc7f27e authored by schultezub's avatar schultezub
Browse files

introducing IVecX- and VecXPropertyWidgets

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@280 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 34760cdb
......@@ -36,7 +36,7 @@
namespace TUMVis {
/**
* Widget for a IntProperty
* Widget for a FloatProperty
*/
class FloatPropertyWidget : public AbstractPropertyWidget {
Q_OBJECT;
......@@ -70,6 +70,179 @@ namespace TUMVis {
QDoubleSpinBox* _spinBox;
};
// ================================================================================================
namespace {
template<size_t SIZE>
struct VecPropertyWidgetTraits {};
template<>
struct VecPropertyWidgetTraits<2> {
typedef Vec2Property PropertyType;
typedef tgt::vec2 BaseType;
};
template<>
struct VecPropertyWidgetTraits<3> {
typedef Vec3Property PropertyType;
typedef tgt::vec3 BaseType;
};
template<>
struct VecPropertyWidgetTraits<4> {
typedef Vec4Property PropertyType;
typedef tgt::vec4 BaseType;
};
}
// ================================================================================================
/**
* Generic base class for Vec property widgets.
* Unfortunately Q_OBJECT and templates do not fit together, so we an additional level of
* indirection helps as usual...
*/
template<size_t SIZE>
class VecPropertyWidget : public AbstractPropertyWidget {
public:
enum { size = SIZE };
typedef typename VecPropertyWidgetTraits<SIZE>::PropertyType PropertyType;
/**
* Creates a new VecPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
VecPropertyWidget(PropertyType* property, QWidget* parent = 0);
/**
* Destructor
*/
virtual ~VecPropertyWidget();
protected:
/**
* Gets called when the property has changed, so that widget can update its state.
*/
virtual void updateWidgetFromProperty();
void onValueChangedImpl();
/// Slot getting called when the property's min or max value has changed, so that the widget can be updated.
virtual void onPropertyMinMaxChanged(const AbstractProperty* property);
QDoubleSpinBox* _spinBox[size];
};
// ================================================================================================
template<size_t SIZE>
TUMVis::VecPropertyWidget<SIZE>::VecPropertyWidget(PropertyType* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, parent)
{
for (size_t i = 0; i < size; ++i) {
_spinBox[i] = new QDoubleSpinBox(this);
_spinBox[i]->setMinimum(property->getMinValue()[i]);
_spinBox[i]->setMaximum(property->getMaxValue()[i]);
_spinBox[i]->setDecimals(3);
_spinBox[i]->setSingleStep(0.01);
_spinBox[i]->setValue(property->getValue()[i]);
addWidget(_spinBox[i]);
}
property->s_minMaxChanged.connect(this, &VecPropertyWidget::onPropertyMinMaxChanged);
}
template<size_t SIZE>
TUMVis::VecPropertyWidget<SIZE>::~VecPropertyWidget() {
static_cast<PropertyType*>(_property)->s_minMaxChanged.disconnect(this);
}
template<size_t SIZE>
void TUMVis::VecPropertyWidget<SIZE>::updateWidgetFromProperty() {
PropertyType* prop = static_cast<PropertyType*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->blockSignals(true);
_spinBox[i]->setValue(prop->getValue()[i]);
_spinBox[i]->blockSignals(false);
}
}
template<size_t SIZE>
void TUMVis::VecPropertyWidget<SIZE>::onValueChangedImpl() {
_ignorePropertyUpdates = true;
PropertyType* prop = static_cast<PropertyType*>(_property);
typename VecPropertyWidgetTraits<SIZE>::BaseType newValue;
for (size_t i = 0; i < size; ++i)
newValue[i] = _spinBox[i]->value();
prop->setValue(newValue);
_ignorePropertyUpdates = false;
}
template<size_t SIZE>
void TUMVis::VecPropertyWidget<SIZE>::onPropertyMinMaxChanged(const AbstractProperty* property) {
if (!_ignorePropertyUpdates) {
PropertyType* prop = static_cast<PropertyType*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->setMinimum(prop->getMinValue()[i]);
_spinBox[i]->setMaximum(prop->getMaxValue()[i]);
}
}
}
// ================================================================================================
class Vec2PropertyWidget : public VecPropertyWidget<2> {
Q_OBJECT
public:
Vec2PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<2>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
}
}
private slots:
void onValueChanged(double value) { onValueChangedImpl(); };
};
// ================================================================================================
class Vec3PropertyWidget : public VecPropertyWidget<3> {
Q_OBJECT
public:
Vec3PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<3>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
}
}
private slots:
void onValueChanged(double value) { onValueChangedImpl(); };
};
// ================================================================================================
class Vec4PropertyWidget : public VecPropertyWidget<4> {
Q_OBJECT
public:
Vec4PropertyWidget(PropertyType* property, QWidget* parent = 0)
: VecPropertyWidget<4>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double)));
}
}
private slots:
void onValueChanged(double value) { onValueChangedImpl(); };
};
}
#endif // FLOATPROPERTYWIDGET_H__
......@@ -70,50 +70,4 @@ namespace TUMVis {
}
}
// ================================================================================================
IVec2PropertyWidget::IVec2PropertyWidget(IVec2Property* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, parent)
{
for (size_t i = 0; i < size; ++i) {
_spinBox[i] = new QSpinBox(this);
_spinBox[i]->setMinimum(property->getMinValue()[i]);
_spinBox[i]->setMaximum(property->getMaxValue()[i]);
_spinBox[i]->setValue(property->getValue()[i]);
addWidget(_spinBox[i]);
connect(_spinBox[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
}
property->s_minMaxChanged.connect(this, &IVec2PropertyWidget::onPropertyMinMaxChanged);
}
IVec2PropertyWidget::~IVec2PropertyWidget() {
static_cast<IVec2Property*>(_property)->s_minMaxChanged.disconnect(this);
}
void IVec2PropertyWidget::updateWidgetFromProperty() {
IVec2Property* prop = static_cast<IVec2Property*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->blockSignals(true);
_spinBox[i]->setValue(prop->getValue()[i]);
_spinBox[i]->blockSignals(false);
}
}
void IVec2PropertyWidget::onValueChanged(int value) {
_ignorePropertyUpdates = true;
IVec2Property* prop = static_cast<IVec2Property*>(_property);
prop->setValue(tgt::ivec2(_spinBox[0]->value(), _spinBox[1]->value()));
_ignorePropertyUpdates = false;
}
void IVec2PropertyWidget::onPropertyMinMaxChanged(const AbstractProperty* property) {
if (!_ignorePropertyUpdates) {
IVec2Property* prop = static_cast<IVec2Property*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->setMinimum(prop->getMinValue()[i]);
_spinBox[i]->setMaximum(prop->getMaxValue()[i]);
}
}
}
}
\ No newline at end of file
......@@ -71,28 +71,55 @@ namespace TUMVis {
};
// = TODO: Using templates would make this much more elegant... ===================================
// ================================================================================================
/**
* Widget for a IVec2Property
*/
class IVec2PropertyWidget : public AbstractPropertyWidget {
enum { size = 2 };
namespace {
template<size_t SIZE>
struct IVecPropertyWidgetTraits {};
template<>
struct IVecPropertyWidgetTraits<2> {
typedef IVec2Property PropertyType;
typedef tgt::ivec2 BaseType;
};
template<>
struct IVecPropertyWidgetTraits<3> {
typedef IVec3Property PropertyType;
typedef tgt::ivec3 BaseType;
};
template<>
struct IVecPropertyWidgetTraits<4> {
typedef IVec4Property PropertyType;
typedef tgt::ivec4 BaseType;
};
}
Q_OBJECT;
// ================================================================================================
/**
* Generic base class for IVec property widgets.
* Unfortunately Q_OBJECT and templates do not fit together, so we an additional level of
* indirection helps as usual...
*/
template<size_t SIZE>
class IVecPropertyWidget : public AbstractPropertyWidget {
public:
enum { size = SIZE };
typedef typename IVecPropertyWidgetTraits<SIZE>::PropertyType PropertyType;
/**
* Creates a new IVec2PropertyWidget for the property \a property.
* Creates a new IVecPropertyWidget for the property \a property.
* \param property The property the widget shall handle
* \param parent Parent Qt widget
*/
IVec2PropertyWidget(IVec2Property* property, QWidget* parent = 0);
IVecPropertyWidget(PropertyType* property, QWidget* parent = 0);
/**
* Destructor
*/
virtual ~IVec2PropertyWidget();
virtual ~IVecPropertyWidget();
protected:
/**
......@@ -100,14 +127,119 @@ namespace TUMVis {
*/
virtual void updateWidgetFromProperty();
private slots:
void onValueChanged(int value);
void onValueChangedImpl();
private:
/// Slot getting called when the property's min or max value has changed, so that the widget can be updated.
virtual void onPropertyMinMaxChanged(const AbstractProperty* property);
QSpinBox* _spinBox[2];
QSpinBox* _spinBox[size];
};
// ================================================================================================
template<size_t SIZE>
TUMVis::IVecPropertyWidget<SIZE>::IVecPropertyWidget(PropertyType* property, QWidget* parent /*= 0*/)
: AbstractPropertyWidget(property, parent)
{
for (size_t i = 0; i < size; ++i) {
_spinBox[i] = new QSpinBox(this);
_spinBox[i]->setMinimum(property->getMinValue()[i]);
_spinBox[i]->setMaximum(property->getMaxValue()[i]);
_spinBox[i]->setValue(property->getValue()[i]);
addWidget(_spinBox[i]);
}
property->s_minMaxChanged.connect(this, &IVecPropertyWidget::onPropertyMinMaxChanged);
}
template<size_t SIZE>
TUMVis::IVecPropertyWidget<SIZE>::~IVecPropertyWidget() {
static_cast<PropertyType*>(_property)->s_minMaxChanged.disconnect(this);
}
template<size_t SIZE>
void TUMVis::IVecPropertyWidget<SIZE>::updateWidgetFromProperty() {
PropertyType* prop = static_cast<PropertyType*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->blockSignals(true);
_spinBox[i]->setValue(prop->getValue()[i]);
_spinBox[i]->blockSignals(false);
}
}
template<size_t SIZE>
void TUMVis::IVecPropertyWidget<SIZE>::onValueChangedImpl() {
_ignorePropertyUpdates = true;
PropertyType* prop = static_cast<PropertyType*>(_property);
typename IVecPropertyWidgetTraits<SIZE>::BaseType newValue;
for (size_t i = 0; i < size; ++i)
newValue[i] = _spinBox[i]->value();
prop->setValue(newValue);
_ignorePropertyUpdates = false;
}
template<size_t SIZE>
void TUMVis::IVecPropertyWidget<SIZE>::onPropertyMinMaxChanged(const AbstractProperty* property) {
if (!_ignorePropertyUpdates) {
PropertyType* prop = static_cast<PropertyType*>(_property);
for (size_t i = 0; i < size; ++i) {
_spinBox[i]->setMinimum(prop->getMinValue()[i]);
_spinBox[i]->setMaximum(prop->getMaxValue()[i]);
}
}
}
// ================================================================================================
class IVec2PropertyWidget : public IVecPropertyWidget<2> {
Q_OBJECT
public:
IVec2PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<2>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
}
}
private slots:
void onValueChanged(int value) { onValueChangedImpl(); };
};
// ================================================================================================
class IVec3PropertyWidget : public IVecPropertyWidget<3> {
Q_OBJECT
public:
IVec3PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<3>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
}
}
private slots:
void onValueChanged(int value) { onValueChangedImpl(); };
};
// ================================================================================================
class IVec4PropertyWidget : public IVecPropertyWidget<4> {
Q_OBJECT
public:
IVec4PropertyWidget(PropertyType* property, QWidget* parent = 0)
: IVecPropertyWidget<4>(property, parent)
{
for (size_t i = 0; i < size; ++i) {
connect(_spinBox[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
}
}
private slots:
void onValueChanged(int value) { onValueChangedImpl(); };
};
}
#endif // INTPROPERTYWIDGET_H__
......@@ -52,14 +52,28 @@ namespace TUMVis {
if (IntProperty* tester = dynamic_cast<IntProperty*>(property)) {
return new IntPropertyWidget(tester);
}
if (IVec2Property* tester = dynamic_cast<IVec2Property*>(property)) {
return new IVec2PropertyWidget(tester);
}
if (IVec3Property* tester = dynamic_cast<IVec3Property*>(property)) {
return new IVec3PropertyWidget(tester);
}
if (IVec4Property* tester = dynamic_cast<IVec4Property*>(property)) {
return new IVec4PropertyWidget(tester);
}
if (FloatProperty* tester = dynamic_cast<FloatProperty*>(property)) {
return new FloatPropertyWidget(tester);
}
if (Vec2Property* tester = dynamic_cast<Vec2Property*>(property)) {
return new Vec2PropertyWidget(tester);
}
if (Vec3Property* tester = dynamic_cast<Vec3Property*>(property)) {
return new Vec3PropertyWidget(tester);
}
if (Vec4Property* tester = dynamic_cast<Vec4Property*>(property)) {
return new Vec4PropertyWidget(tester);
}
if (StringProperty* tester = dynamic_cast<StringProperty*>(property)) {
return new StringPropertyWidget(tester);
......
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