intpropertywidget.h 11.1 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
22
23
24
// 
// ================================================================================================

schultezub's avatar
schultezub committed
25
26
27
#ifndef INTPROPERTYWIDGET_H__
#define INTPROPERTYWIDGET_H__

28
#include "application/gui/adjusterwidgets/intadjusterwidget.h"
schultezub's avatar
schultezub committed
29
#include "application/gui/properties/abstractpropertywidget.h"
30
#include "application/gui/properties/propertywidgetfactory.h"
schultezub's avatar
schultezub committed
31
32
#include "core/properties/numericproperty.h"

33
class QCheckBox;
34
class QPushButton;
35
36
class QTimer;

schultezub's avatar
schultezub committed
37
namespace campvis {
schultezub's avatar
schultezub committed
38
39
40
41
42
43
44
45
46
    /**
     * Widget for a IntProperty
     */
    class IntPropertyWidget : public AbstractPropertyWidget {
        Q_OBJECT;

    public:
        /**
         * Creates a new IntPropertyWidget for the property \a property.
47
48
49
         * \param   property        The property the widget shall handle
         * \param   dataContainer   DataContainer to use (optional), defaults to nullptr.
         * \param   parent          Parent Qt widget
schultezub's avatar
schultezub committed
50
         */
51
        IntPropertyWidget(IntProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
schultezub's avatar
schultezub committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65

        /**
         * Destructor
         */
        virtual ~IntPropertyWidget();

    protected:
        /**
         * Gets called when the property has changed, so that widget can update its state.
         */
        virtual void updateWidgetFromProperty();

    private slots:
        void onValueChanged(int value);
66
67
68
        void onIntervalValueChanged(int value);
        void onEnableTimerChanged(int state);
        void onTimer();
69
        void onBtnSHTClicked();
schultezub's avatar
schultezub committed
70
71
72
73
74

    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);

75
76
77
        /// Slot getting called when the property's step value has changed, so that the widget can be updated.
        virtual void onPropertyStepChanged(const AbstractProperty* property);

78
        IntAdjusterWidget* _adjuster;
schultezub's avatar
schultezub committed
79

80
        QPushButton* _btnShowHideTimer;
81
82
83
84
        QTimer* _timer;
        QCheckBox* _cbEnableTimer;
        QSpinBox* _sbInterval;

schultezub's avatar
schultezub committed
85
    };
schultezub's avatar
schultezub committed
86

87
88
89
    // explicitly instantiate template, so that it gets registered also over DLL boundaries.
    template class PropertyWidgetRegistrar<IntPropertyWidget, IntProperty>;

90
// ================================================================================================
schultezub's avatar
schultezub committed
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    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;
        };
    }
schultezub's avatar
schultezub committed
114

115
// ================================================================================================
schultezub's avatar
schultezub committed
116

117
118
119
120
121
122
123
    /**
     * 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 {
schultezub's avatar
schultezub committed
124
    public:
125
126
127
        enum { size = SIZE };
        typedef typename IVecPropertyWidgetTraits<SIZE>::PropertyType PropertyType;

schultezub's avatar
schultezub committed
128
        /**
129
         * Creates a new IVecPropertyWidget for the property \a property.
schultezub's avatar
schultezub committed
130
131
132
         * \param   property    The property the widget shall handle
         * \param   parent      Parent Qt widget
         */
133
        IVecPropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
schultezub's avatar
schultezub committed
134
135
136
137

        /**
         * Destructor
         */
138
        virtual ~IVecPropertyWidget();
schultezub's avatar
schultezub committed
139
140
141
142
143
144
145

    protected:
        /**
         * Gets called when the property has changed, so that widget can update its state.
         */
        virtual void updateWidgetFromProperty();

146
        void onValueChangedImpl();
schultezub's avatar
schultezub committed
147
148
149
150

        /// 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);

151
152
153
        /// Slot getting called when the property's step value has changed, so that the widget can be updated.
        virtual void onPropertyStepChanged(const AbstractProperty* property);

154
        IntAdjusterWidget* _adjusters[size];
schultezub's avatar
schultezub committed
155
    };
156
157
158
159

// ================================================================================================

    template<size_t SIZE>
160
161
    campvis::IVecPropertyWidget<SIZE>::IVecPropertyWidget(PropertyType* property, DataContainer* dataContainer, QWidget* parent /*= 0*/)
        : AbstractPropertyWidget(property, true, dataContainer, parent)
162
163
    {
        for (size_t i = 0; i < size; ++i) {
164
165
166
            _adjusters[i] = new IntAdjusterWidget;
            _adjusters[i]->setMinimum(property->getMinValue()[i]);
            _adjusters[i]->setMaximum(property->getMaxValue()[i]);
167
            _adjusters[i]->setSingleStep(property->getStepValue()[i]);
168
169
            _adjusters[i]->setValue(property->getValue()[i]);
            addWidget(_adjusters[i]);
170
171
172
        }

        property->s_minMaxChanged.connect(this, &IVecPropertyWidget::onPropertyMinMaxChanged);
173
        property->s_stepChanged.connect(this, &IVecPropertyWidget::onPropertyStepChanged);
174
175
176
    }

    template<size_t SIZE>
schultezub's avatar
schultezub committed
177
    campvis::IVecPropertyWidget<SIZE>::~IVecPropertyWidget() {
178
        static_cast<PropertyType*>(_property)->s_minMaxChanged.disconnect(this);
179
        static_cast<PropertyType*>(_property)->s_stepChanged.disconnect(this);
180
181
182
    }

    template<size_t SIZE>
schultezub's avatar
schultezub committed
183
    void campvis::IVecPropertyWidget<SIZE>::updateWidgetFromProperty() {
184
185
        PropertyType* prop = static_cast<PropertyType*>(_property);
        for (size_t i = 0; i < size; ++i) {
186
187
188
            _adjusters[i]->blockSignals(true);
            _adjusters[i]->setValue(prop->getValue()[i]);
            _adjusters[i]->blockSignals(false);
189
190
191
192
        }
    }

    template<size_t SIZE>
schultezub's avatar
schultezub committed
193
    void campvis::IVecPropertyWidget<SIZE>::onValueChangedImpl() {
schultezub's avatar
schultezub committed
194
        ++_ignorePropertyUpdates;
195
196
197
        PropertyType* prop = static_cast<PropertyType*>(_property);
        typename IVecPropertyWidgetTraits<SIZE>::BaseType newValue;
        for (size_t i = 0; i < size; ++i)
198
            newValue[i] = _adjusters[i]->value();
199
        prop->setValue(newValue);
schultezub's avatar
schultezub committed
200
        --_ignorePropertyUpdates;
201
202
203
    }

    template<size_t SIZE>
schultezub's avatar
schultezub committed
204
    void campvis::IVecPropertyWidget<SIZE>::onPropertyMinMaxChanged(const AbstractProperty* property) {
schultezub's avatar
schultezub committed
205
        if (_ignorePropertyUpdates == 0) {
206
207
            PropertyType* prop = static_cast<PropertyType*>(_property);
            for (size_t i = 0; i < size; ++i) {
208
209
                _adjusters[i]->setMinimum(prop->getMinValue()[i]);
                _adjusters[i]->setMaximum(prop->getMaxValue()[i]);
210
211
212
213
            }
        }
    }

214
215
216
217
218
219
220
221
222
223
    template<size_t SIZE>
    void campvis::IVecPropertyWidget<SIZE>::onPropertyStepChanged(const AbstractProperty* property) {
        if (_ignorePropertyUpdates == 0) {
            PropertyType* prop = static_cast<PropertyType*>(_property);
            for (size_t i = 0; i < size; ++i) {
                _adjusters[i]->setSingleStep(prop->getStepValue()[i]);
            }
        }
    }

224
225
226
227
228
// ================================================================================================

    class IVec2PropertyWidget : public IVecPropertyWidget<2> {
        Q_OBJECT
    public:
229
230
        IVec2PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
            : IVecPropertyWidget<2>(property, dataContainer, parent)
231
232
        {
            for (size_t i = 0; i < size; ++i) {
233
                connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
234
235
236
237
238
239
240
241
242
243
244
245
            }
        }

    private slots:
        void onValueChanged(int value) { onValueChangedImpl(); };
    }; 

// ================================================================================================
    
    class IVec3PropertyWidget : public IVecPropertyWidget<3> {
        Q_OBJECT
    public:
246
247
        IVec3PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
            : IVecPropertyWidget<3>(property, dataContainer, parent)
248
249
        {
            for (size_t i = 0; i < size; ++i) {
250
                connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
251
252
253
254
255
256
257
258
259
260
261
262
            }
        }

        private slots:
            void onValueChanged(int value) { onValueChangedImpl(); };
    }; 

// ================================================================================================

    class IVec4PropertyWidget : public IVecPropertyWidget<4> {
        Q_OBJECT
    public:
263
264
        IVec4PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0)
            : IVecPropertyWidget<4>(property, dataContainer, parent)
265
266
        {
            for (size_t i = 0; i < size; ++i) {
267
                connect(_adjusters[i], SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int)));
268
269
270
271
272
273
274
            }
        }

        private slots:
            void onValueChanged(int value) { onValueChangedImpl(); };
    }; 

275
276
277
278
279
280
281
// ================================================================================================

    // explicitly instantiate template, so that it gets registered also over DLL boundaries.
    template class PropertyWidgetRegistrar<IVec2PropertyWidget, typename IVecPropertyWidgetTraits<2>::PropertyType, 5>;
    template class PropertyWidgetRegistrar<IVec3PropertyWidget, typename IVecPropertyWidgetTraits<3>::PropertyType, 5>;
    template class PropertyWidgetRegistrar<IVec4PropertyWidget, typename IVecPropertyWidgetTraits<4>::PropertyType, 5>;

schultezub's avatar
schultezub committed
282
283
}
#endif // INTPROPERTYWIDGET_H__