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

optionproperty.h 11.3 KB
Newer Older
1
2
3
4
// ================================================================================================
// 
// This file is part of the CAMPVis Software Framework.
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
6
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
11
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
// 
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
25
26
27
// 
// ================================================================================================

#ifndef OPTIONPROPERTY_H__
#define OPTIONPROPERTY_H__

28
#include "cgt/vector.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "core/properties/numericproperty.h"

#include <string>
#include <vector>

namespace campvis {

    /**
     * Abstract Base class for Option properties, so that they can easily be identified in widget factory.
     */
    class AbstractOptionProperty : public IntProperty {
    public:
        /**
         * Creates a new AbstractOptionProperty.
         * \param name      Property name
         * \param title     Property title (e.g. used for GUI)
         */
46
47
        AbstractOptionProperty(const std::string& name, const std::string& title)
            : IntProperty(name, title, -1, -1, -1, 1)
48
49
50
51
52
53
        {            
        };

        /**
         * Pure virtual destructor.
         */
schultezub's avatar
schultezub committed
54
        virtual ~AbstractOptionProperty() {};
Hossain Mahmud's avatar
Hossain Mahmud committed
55
56
57
58
59
60
61
62
63
64
65
66
67
        
        /**
         * Returns the id of the currently selected option.
         * \return  _options[_value]._id
         */
        virtual const std::string& getOptionId() = 0;

        /**
         * Sets the selected option to the first option with the given id.
         * If no such option is found, the selected option will not change.
         * \param   id  Id of the option to select.
         */
        virtual void selectById(const std::string& id) = 0;
68
69
70
71
72
73

        /**
         * Returns all Options als pair of std::strings.
         * \return  A vector of the options encoded as pair (id, title).
         */
        virtual std::vector< std::pair<std::string, std::string> > getOptionsAsPairOfStrings() const = 0;
74
75
76
77
78
79
80
81
82
83
    };

    template<typename T>
    struct GenericOption {
    public:
        GenericOption(const std::string& id, const std::string& title, T value)
            : _id(id)
            , _title(title)
            , _value(value)
        {};
Hossain Mahmud's avatar
Hossain Mahmud committed
84
        
85
86
87
88
89
90
91
92
        std::string _id;
        std::string _title;
        T _value;
    };

    template<>
    struct GenericOption<std::string> {
    public:
93
94
95
96
97
98
        GenericOption(const std::string& id, const std::string& title, const std::string& value)
            : _id(id)
            , _title(title)
            , _value(value)
        {};

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        GenericOption(const std::string& id, const std::string& title)
            : _id(id)
            , _title(title)
            , _value(id)
        {};

        std::string _id;
        std::string _title;
        std::string _value;
    };

    /**
     * Property for selecting a single item of a set of generic options.
     * \tparam  T   Type of the options.
     */
    template<typename T>
    class GenericOptionProperty : public AbstractOptionProperty {
    public:
        /**
         * Creates a new GenericOptionProperty.
         * \param name      Property name
         * \param title     Property title (e.g. used for GUI)
         * \param options   Array of the options for this property, must not be 0, must not be empty.
         * \param count     Number of items in \a options (number of options), must be greater 0.
123

124
125
126
127
128
         */
        GenericOptionProperty(
            const std::string& name, 
            const std::string& title, 
            const GenericOption<T>* options,
129
            int count);
130
131
132
133
134
135
136
137
138
139
140
141
142

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


        /**
         * Returns the vector of options of this property.
         * \return  _options
         */
        const std::vector< GenericOption<T> >& getOptions() const;

143
144
145
        /// \see AbstractOptionProperty::getOptionsAsPairOfStrings()
        virtual std::vector< std::pair<std::string, std::string> > getOptionsAsPairOfStrings() const;

146
147
148
149
150
        /**
         * Returns the currently selected option.
         * \return  _options[_value]
         */
        const GenericOption<T>& getOption() const;
Hossain Mahmud's avatar
Hossain Mahmud committed
151
        
152
153
154
155
        /**
         * Returns the value of the currently selected option.
         * \return  _options[_value]._value
         */
156
        T getOptionValue() const;
157

Hossain Mahmud's avatar
Hossain Mahmud committed
158
159
160
161
        /**
         * Returns the id of the currently selected option.
         * \return  _options[_value]._id
         */
Hossain Mahmud's avatar
Hossain Mahmud committed
162
        const std::string& getOptionId();
Hossain Mahmud's avatar
Hossain Mahmud committed
163

164
165
166
167
168
169
170
171
172
173
174
175

        /**
         * Sets the selected option to the first option with the given id.
         * If no such option is found, the selected option will not change.
         * \param   id  Id of the option to select.
         */
        void selectById(const std::string& id);

        /**
         * Sets the selected option to the option with the given index.
         * \param   index   Index of the option to select in the option array.
         */
176
        void selectByIndex(int index);
177

178
179
180
181
182
        /**
         * Sets the selected option to \a option.
         * \param   option  Option to set.
         */
        void selectByOption(T option);
Hossain Mahmud's avatar
Hossain Mahmud committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
        
        /** 
         * Add a new Option
         * \param option New option to add
         * returns Number of items
         */
        size_t addOption(GenericOption<T> option);

        /** 
         * Update current option
         * \param copy Data to copy from
         * returns Number of items
         */
        size_t updateCurrent(GenericOption<T> copy);
        size_t updateCurrent(T& copy);
        
        /** 
         * Remove current copy, except the last one
         * returns Number of items
         */
        size_t removeCurrent();

        /** 
         * Returns a non-const reference of current option's value
         * \param index Position to 
         * \note With great power comes great responsibility
         * returns Number of items
         */
        T& getOptionReference(int index = -1);

        /** 
         * Get Option count
         * returns Number of items
         */
        size_t getOptionCount();
218

219
220
221
222
223
224
225
    protected:
        std::vector< GenericOption<T> > _options;
    };

// = Template Implementation ======================================================================

    template<typename T>
226
227
    campvis::GenericOptionProperty<T>::GenericOptionProperty(const std::string& name, const std::string& title, const GenericOption<T>* options, int count)
        : AbstractOptionProperty(name, title)
228
229
    {
        _options.assign(options, options + count);
230
        setMaxValue(std::max(count - 1, 0));
231
        setValue(0);
232
        setMinValue(0);
233
234
235
236
237
238
239
240
241
242
243
244
    }

    template<typename T>
    campvis::GenericOptionProperty<T>::~GenericOptionProperty() {

    }

    template<typename T>
    const std::vector< GenericOption<T> >& campvis::GenericOptionProperty<T>::getOptions() const {
        return _options;
    }

245
246
247
    template<typename T>
    std::vector< std::pair<std::string, std::string> > campvis::GenericOptionProperty<T>::getOptionsAsPairOfStrings() const {
        std::vector< std::pair<std::string, std::string> > toReturn;
schultezub's avatar
schultezub committed
248
        for (typename std::vector< GenericOption<T> >::const_iterator it = _options.begin(); it != _options.end(); ++it) {
249
250
251
252
253
            toReturn.push_back(std::make_pair(it->_id, it->_title));
        }
        return toReturn;
    }

254
255
    template<typename T>
    const GenericOption<T>& campvis::GenericOptionProperty<T>::getOption() const {
256
        return _options[_value];
257
258
259
    }

    template<typename T>
260
    T campvis::GenericOptionProperty<T>::getOptionValue() const {
261
        return _options[_value]._value;
262
263
    }

Hossain Mahmud's avatar
Hossain Mahmud committed
264
    template<typename T>
Hossain Mahmud's avatar
Hossain Mahmud committed
265
    const std::string& campvis::GenericOptionProperty<T>::getOptionId() {
Hossain Mahmud's avatar
Hossain Mahmud committed
266
267
268
        return _options[_value]._id;
    }

269
270
271
272
    template<typename T>
    void campvis::GenericOptionProperty<T>::selectById(const std::string& id) {
        for (size_t i = 0; i < _options.size(); ++i) {
            if (_options[i]._id == id) {
273
                setValue(static_cast<int>(i));
274
275
276
277
278
279
280
                return;
            }
        }
        LERROR("Could not find option with id '" + id + "'");
    }

    template<typename T>
281
    void campvis::GenericOptionProperty<T>::selectByIndex(int index) {
282
        cgtAssert(index >= 0 && index < static_cast<int>(_options.size()), "Index out of bounds.");
283
284
285
        setValue(index);
    }

286
287
288
289
290
291
292
293
294
295
296
    template<typename T>
    void campvis::GenericOptionProperty<T>::selectByOption(T option) {
        for (size_t i = 0; i < _options.size(); ++i) {
            if (_options[i]._value == option) {
                setValue(static_cast<int>(i));
                return;
            }
        }
        LERROR("Could not find specified option.");
    }

Hossain Mahmud's avatar
Hossain Mahmud committed
297
298
299
300
301
302
303
304
305
    template<typename T>
    size_t campvis::GenericOptionProperty<T>::addOption(GenericOption<T> option) {
        this->_options.push_back(option);
        setMaxValue(static_cast<int>(this->_options.size()) - 1);
        return this->_options.size();
    }

    template<typename T>
    size_t campvis::GenericOptionProperty<T>::removeCurrent() {
306
        size_t index = getValue();
Hossain Mahmud's avatar
Hossain Mahmud committed
307
        if (index == 0) return 0;
308
        if (index <= this->_options.size()-1)
Hossain Mahmud's avatar
Hossain Mahmud committed
309
            this->_options.erase(this->_options.begin() + index);
310
311
        selectByIndex((index <= this->_options.size() - 1) ? static_cast<int>(index) : static_cast<int>(this->_options.size() - 1));
        return (index <= this->_options.size() - 1) ? index : this->_options.size() - 1;
Hossain Mahmud's avatar
Hossain Mahmud committed
312
313
314
315
    }

    template<typename T>
    size_t campvis::GenericOptionProperty<T>::updateCurrent(GenericOption<T> copy) {
316
        GenericOption<T>* it = &this->_options[getValue()];
Hossain Mahmud's avatar
Hossain Mahmud committed
317
318
319
320
321
322
323
324
        it->_id = copy._id;
        it->_title = copy._title;
        it->_value = copy._value;
        return this->_options.size();
    }

    template<typename T>
    size_t campvis::GenericOptionProperty<T>::updateCurrent(T& copy) {
325
        GenericOption<T>* it = &this->_options[getValue()];
Hossain Mahmud's avatar
Hossain Mahmud committed
326
327
328
329
330
331
        it->_value = copy;
        return this->_options.size();
    }

    template<typename T>
    T& campvis::GenericOptionProperty<T>::getOptionReference(int index) {
332
        return (index == -1) ? _options[_value]._value : _options[index]._value;
Hossain Mahmud's avatar
Hossain Mahmud committed
333
334
335
336
337
338
    }

    template<typename T>
    size_t campvis::GenericOptionProperty<T>::getOptionCount() {
        return _options.size();
    }
339
340
341
}

#endif // OPTIONPROPERTY_H__