1 /* RangeWidget.cpp
2  * Copyright (C) 2018  Sven Jähnichen
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "RangeWidget.hpp"
19 
20 #ifndef LIMIT
21 #define LIMIT(val, min, max) (val < min ? min : (val < max ? val : max))
22 #endif
23 
24 namespace BWidgets
25 {
RangeWidget()26 RangeWidget::RangeWidget () :
27 	RangeWidget (0.0, 0.0, BWIDGETS_DEFAULT_WIDTH, BWIDGETS_DEFAULT_HEIGHT, "rangewidget",
28 		BWIDGETS_DEFAULT_VALUE, BWIDGETS_DEFAULT_RANGE_MIN, BWIDGETS_DEFAULT_RANGE_MAX, BWIDGETS_DEFAULT_RANGE_STEP) {}
29 
RangeWidget(const double x,const double y,const double width,const double height,const std::string & name,const double value,const double min,const double max,const double step)30 RangeWidget::RangeWidget (const double  x, const double y, const double width, const double height, const std::string& name,
31 	const double value, const double min, const double max, const double step) :
32 	ValueWidget (x, y, width, height, name, value), rangeMin (min <= max ? min : max),
33 	rangeMax (max), rangeStep (step)
34 {
35 	this->value = LIMIT (value, min, max);
36 }
37 
RangeWidget(const RangeWidget & that)38 RangeWidget::RangeWidget (const RangeWidget& that) :
39 	ValueWidget (that), rangeMin (that.rangeMin <= that.rangeMax ? that.rangeMin : that.rangeMax), rangeMax (that.rangeMax), rangeStep (that.rangeStep) {}
40 
~RangeWidget()41 RangeWidget::~RangeWidget () {}
42 
operator =(const RangeWidget & that)43 RangeWidget& RangeWidget::operator= (const RangeWidget& that)
44 {
45 	Widget::operator= (that);
46 	rangeMin = that.rangeMin;
47 	rangeMax = that.rangeMax;
48 	rangeStep = that.rangeStep;
49 	setValue (that.value);
50 
51 	return *this;
52 }
53 
clone() const54 Widget* RangeWidget::clone () const {return new RangeWidget (*this);}
55 
setValue(const double val)56 void RangeWidget::setValue (const double val)
57 {
58 	double valRounded = LIMIT (val, rangeMin, rangeMax);
59 	if ((rangeStep != 0.0) && (rangeMax >= rangeMin))
60 	{
61 		if (rangeStep > 0.0) valRounded = LIMIT (rangeMin + round ((val - rangeMin) / rangeStep) * rangeStep, rangeMin, rangeMax);
62 		else valRounded = LIMIT (rangeMax - round ((rangeMax - val) / rangeStep) * rangeStep, rangeMin, rangeMax);
63 	}
64 
65 	if (value != valRounded) ValueWidget::setValue (valRounded);
66 }
67 
getRelativeValue() const68 double RangeWidget::getRelativeValue () const
69 {
70 	double relVal;
71 	if (getMax () != getMin ()) relVal = (getValue () - getMin ()) / (getMax () - getMin ());
72 	else relVal = 0.5;				// min == max doesn't make any sense, but need to be handled
73 	if (getStep() < 0) relVal = 1 - relVal;		// Swap if reverse orientation
74 	return relVal;
75 }
76 
setMin(const double min)77 void RangeWidget::setMin (const double min)
78 {
79 	double newMin = (min <= rangeMax ? min: rangeMax);
80 	if (rangeMin != newMin)
81 	{
82 		rangeMin = newMin;
83 		if (getValue () < rangeMin) setValue (rangeMin);
84 		update ();
85 	}
86 }
87 
getMin() const88 double RangeWidget::getMin () const {return rangeMin;}
89 
setMax(const double max)90 void RangeWidget::setMax (const double max)
91 {
92 	double newMax = (max >= rangeMin ? max: rangeMin);
93 	if (rangeMax != newMax)
94 	{
95 		rangeMax = newMax;
96 		if (getValue () > rangeMax) setValue (rangeMax);
97 		update ();
98 	}
99 }
100 
getMax() const101 double RangeWidget::getMax () const {return rangeMax;}
102 
setStep(const double step)103 void RangeWidget::setStep (const double step) {rangeStep = step;}
104 
getStep() const105 double RangeWidget::getStep () const {return rangeStep;}
106 
setLimits(const double min,const double max,const double step)107 void RangeWidget::setLimits (const double min, const double max, const double step)
108 {
109 	double newMin = min <= max ? min : max;
110 
111 	if ((newMin != rangeMin) || (max != rangeMax) || (step != rangeStep))
112 	{
113 		rangeMin = newMin;
114 		rangeMax = max;
115 		rangeStep = step;
116 		if (getValue () < rangeMin) setValue (rangeMin);
117 		else if (getValue () > rangeMax) setValue (rangeMax);
118 		update ();
119 	}
120 }
121 
122 
123 }
124