1 /* HSlider.cpp
2  * Copyright (C) 2018, 2019  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 "HSlider.hpp"
19 #include "../BUtilities/to_string.hpp"
20 
21 namespace BWidgets
22 {
HSlider()23 HSlider::HSlider () : HSlider (0.0, 0.0, BWIDGETS_DEFAULT_HSLIDER_WIDTH, BWIDGETS_DEFAULT_HSLIDER_HEIGHT, "hslider",
24 		  	  	  	  	  	   BWIDGETS_DEFAULT_VALUE, BWIDGETS_DEFAULT_RANGE_MIN, BWIDGETS_DEFAULT_RANGE_MAX, BWIDGETS_DEFAULT_RANGE_STEP) {}
25 
HSlider(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)26 HSlider::HSlider (const double  x, const double y, const double width, const double height, const std::string& name,
27 				  const double value, const double min, const double max, const double step) :
28 		HScale (x, y, width, height, name, value, min, max, step),
29 		Focusable (std::chrono::milliseconds (BWIDGETS_DEFAULT_FOCUS_IN_MS),
30 			std::chrono::milliseconds (BWIDGETS_DEFAULT_FOCUS_OUT_MS)),
31 		knob (0, 0, 0, 0, BWIDGETS_DEFAULT_KNOB_DEPTH, name),
32 		focusLabel(0 ,0, 40, 20, name_ + BWIDGETS_DEFAULT_FOCUS_NAME, ""),
33 		knobRadius (0), knobPosition ()
34 {
35 	setFocusable (true);
36 
37 	knob.setClickable (false);
38 	knob.setDraggable (false);
39 	knob.setScrollable (false);
40 	knob.setFocusable (false);
41 	add (knob);
42 
43 	std::string valstr = BUtilities::to_string (getValue());
44 	focusLabel.setText (valstr);
45 	focusLabel.setStacking (STACKING_OVERSIZE);
46 	focusLabel.resize ();
47 	focusLabel.hide ();
48 	add (focusLabel);
49 }
50 
HSlider(const HSlider & that)51 HSlider::HSlider (const HSlider& that) :
52 		HScale (that), Focusable (that),
53 		knob (that.knob), focusLabel (that.focusLabel),
54 		knobRadius (that.knobRadius), knobPosition (that.knobPosition)
55 {
56 	add (knob);
57 	focusLabel.hide();
58 	add (focusLabel);
59 }
60 
operator =(const HSlider & that)61 HSlider& HSlider::operator= (const HSlider& that)
62 {
63 	release (&knob);
64 	release (&focusLabel);
65 
66 	knob = that.knob;
67 	focusLabel = that.focusLabel;
68 	focusLabel.hide();
69 	knobRadius = that.knobRadius;
70 	knobPosition = that.knobPosition;
71 	HScale::operator= (that);
72 	Focusable::operator= (that);
73 
74 	add (knob);
75 	add (focusLabel);
76 
77 	return *this;
78 }
79 
clone() const80 Widget* HSlider::clone () const {return new HSlider (*this);}
81 
setValue(const double val)82 void HSlider::setValue (const double val)
83 {
84 	RangeWidget::setValue (val);
85 	std::string valstr = BUtilities::to_string (value);
86 	focusLabel.setText(valstr);
87 	focusLabel.resize ();
88 }
89 
update()90 void HSlider::update ()
91 {
92 	HScale::update ();
93 
94 	// Update Knob
95 	knob.moveTo (knobPosition.x - knobRadius, knobPosition.y - knobRadius);
96 	knob.setWidth (2 * knobRadius);
97 	knob.setHeight (2 * knobRadius);
98 
99 	// Update focusLabel
100 	focusLabel.resize ();
101 }
102 
applyTheme(BStyles::Theme & theme)103 void HSlider::applyTheme (BStyles::Theme& theme) {applyTheme (theme, name_);}
104 
applyTheme(BStyles::Theme & theme,const std::string & name)105 void HSlider::applyTheme (BStyles::Theme& theme, const std::string& name)
106 {
107 	HScale::applyTheme (theme, name);
108 	knob.applyTheme (theme, name);
109 	focusLabel.applyTheme (theme, name + BWIDGETS_DEFAULT_FOCUS_NAME);
110 }
111 
onFocusIn(BEvents::FocusEvent * event)112 void HSlider::onFocusIn (BEvents::FocusEvent* event)
113 {
114 	if (event && event->getWidget())
115 	{
116 		BUtilities::Point pos = event->getPosition();
117 		focusLabel.moveTo (pos.x - 0.5 * focusLabel.getWidth(), pos.y - focusLabel.getHeight());
118 		focusLabel.show();
119 	}
120 	Widget::onFocusIn (event);
121 }
onFocusOut(BEvents::FocusEvent * event)122 void HSlider::onFocusOut (BEvents::FocusEvent* event)
123 {
124 	if (event && event->getWidget()) focusLabel.hide();
125 	Widget::onFocusOut (event);
126 }
127 
updateCoords()128 void HSlider::updateCoords ()
129 {
130 	double w = getEffectiveWidth ();
131 	double h = getEffectiveHeight ();
132 
133 	knobRadius = (h < w / 2 ? h / 2 : w / 4);
134 	scaleArea = BUtilities::RectArea
135 	(
136 		getXOffset () + knobRadius,
137 		getYOffset () + h / 2 - knobRadius / 2,
138 		w - 2 * knobRadius,
139 		knobRadius
140 	);
141 	scaleXValue = scaleArea.getX() + getRelativeValue () * scaleArea.getWidth();
142 	knobPosition = BUtilities::Point (scaleXValue, scaleArea.getY() + scaleArea.getHeight() / 2);
143 }
144 }
145