24.09., 9:00 - 11:00: Due to updates GitLab will be unavailable for some minutes between 09:00 and 11:00.

intpropertywidget.h 9.61 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-2015, 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 30 31
#include "application/gui/properties/abstractpropertywidget.h"
#include "core/properties/numericproperty.h"

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

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

    public:
        /**
         * Creates a new IntPropertyWidget for the property \a property.
46 47 48
         * \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
49
         */
50
        IntPropertyWidget(IntProperty* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
schultezub's avatar
schultezub committed
51 52 53 54 55 56 57 58 59 60

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

    protected:
        /**
         * Gets called when the property has changed, so that widget can update its state.
         */
Jakob Weiss's avatar
Jakob Weiss committed
61
        virtual void updateWidgetFromProperty() override;
schultezub's avatar
schultezub committed
62 63 64

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

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

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

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

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

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

86
// ================================================================================================
schultezub's avatar
schultezub committed
87

88 89 90 91 92 93 94
    namespace {
        template<size_t SIZE>
        struct IVecPropertyWidgetTraits {};

        template<>
        struct IVecPropertyWidgetTraits<2> {
            typedef IVec2Property PropertyType;
95
            typedef cgt::ivec2 BaseType;
96 97 98 99 100
        };

        template<>
        struct IVecPropertyWidgetTraits<3> {
            typedef IVec3Property PropertyType;
101
            typedef cgt::ivec3 BaseType;
102 103 104 105 106
        };

        template<>
        struct IVecPropertyWidgetTraits<4> {
            typedef IVec4Property PropertyType;
107
            typedef cgt::ivec4 BaseType;
108 109
        };
    }
schultezub's avatar
schultezub committed
110

111
// ================================================================================================
schultezub's avatar
schultezub committed
112

113 114 115 116 117 118 119
    /**
     * 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
120
    public:
121 122 123
        enum { size = SIZE };
        typedef typename IVecPropertyWidgetTraits<SIZE>::PropertyType PropertyType;

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

        /**
         * Destructor
         */
134
        virtual ~IVecPropertyWidget();
schultezub's avatar
schultezub committed
135 136 137 138 139

    protected:
        /**
         * Gets called when the property has changed, so that widget can update its state.
         */
Jakob Weiss's avatar
Jakob Weiss committed
140
        virtual void updateWidgetFromProperty() override;
schultezub's avatar
schultezub committed
141

142
        void onValueChangedImpl();
schultezub's avatar
schultezub committed
143 144 145 146

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

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

150
        IntAdjusterWidget* _adjusters[size];
schultezub's avatar
schultezub committed
151
    };
152 153 154 155

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

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

        property->s_minMaxChanged.connect(this, &IVecPropertyWidget::onPropertyMinMaxChanged);
169
        property->s_stepChanged.connect(this, &IVecPropertyWidget::onPropertyStepChanged);
170 171 172
    }

    template<size_t SIZE>
schultezub's avatar
schultezub committed
173
    campvis::IVecPropertyWidget<SIZE>::~IVecPropertyWidget() {
174
        static_cast<PropertyType*>(_property)->s_minMaxChanged.disconnect(this);
175
        static_cast<PropertyType*>(_property)->s_stepChanged.disconnect(this);
176 177 178
    }

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

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

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

210 211 212 213 214 215 216 217 218 219
    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]);
            }
        }
    }

220 221 222 223 224
// ================================================================================================

    class IVec2PropertyWidget : public IVecPropertyWidget<2> {
        Q_OBJECT
    public:
225
        IVec2PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
226 227 228 229 230 231 232 233 234 235

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

// ================================================================================================
    
    class IVec3PropertyWidget : public IVecPropertyWidget<3> {
        Q_OBJECT
    public:
236
        IVec3PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
237 238 239 240 241 242 243 244 245 246

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

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

    class IVec4PropertyWidget : public IVecPropertyWidget<4> {
        Q_OBJECT
    public:
247
        IVec4PropertyWidget(PropertyType* property, DataContainer* dataContainer = nullptr, QWidget* parent = 0);
248 249 250 251 252

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

schultezub's avatar
schultezub committed
253 254
}
#endif // INTPROPERTYWIDGET_H__