1 /* VSlider.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 "VSlider.hpp"
19 #include "../BUtilities/to_string.hpp"
20 
21 namespace BWidgets
22 {
VSlider()23 VSlider::VSlider () : VSlider (0.0, 0.0, BWIDGETS_DEFAULT_VSLIDER_WIDTH, BWIDGETS_DEFAULT_VSLIDER_HEIGHT, "vslider",
24 		  	  	  	  	  	   BWIDGETS_DEFAULT_VALUE, BWIDGETS_DEFAULT_RANGE_MIN, BWIDGETS_DEFAULT_RANGE_MAX, BWIDGETS_DEFAULT_RANGE_STEP) {}
25 
VSlider(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 VSlider::VSlider (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 		VScale (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 
VSlider(const VSlider & that)51 VSlider::VSlider (const VSlider& that) :
52 		VScale (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 VSlider & that)61 VSlider& VSlider::operator= (const VSlider& 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 	RangeWidget::operator= (that);
72 	Focusable::operator= (that);
73 
74 	add (knob);
75 	add (focusLabel);
76 
77 	return *this;
78 }
79 
clone() const80 Widget* VSlider::clone () const {return new VSlider (*this);}
81 
setValue(const double val)82 void VSlider::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 VSlider::update ()
91 {
92 	VScale::update ();
93 
94 	// Update Knob
95 	knob.moveTo (knobPosition.x -  knobRadius, knobPosition.y - knobRadius);
96 	knob.resize (2 * knobRadius, 2 * knobRadius);
97 
98 	// Update focusLabel
99 	focusLabel.resize ();
100 }
101 
applyTheme(BStyles::Theme & theme)102 void VSlider::applyTheme (BStyles::Theme& theme) {applyTheme (theme, name_);}
103 
applyTheme(BStyles::Theme & theme,const std::string & name)104 void VSlider::applyTheme (BStyles::Theme& theme, const std::string& name)
105 {
106 	VScale::applyTheme (theme, name);
107 	knob.applyTheme (theme, name);
108 	focusLabel.applyTheme (theme, name + BWIDGETS_DEFAULT_FOCUS_NAME);
109 }
110 
onFocusIn(BEvents::FocusEvent * event)111 void VSlider::onFocusIn (BEvents::FocusEvent* event)
112 {
113 	if (event && event->getWidget())
114 	{
115 		BUtilities::Point pos = event->getPosition();
116 		focusLabel.moveTo (pos.x - 0.5 * focusLabel.getWidth(), pos.y - focusLabel.getHeight());
117 		focusLabel.show();
118 	}
119 	Widget::onFocusIn (event);
120 }
onFocusOut(BEvents::FocusEvent * event)121 void VSlider::onFocusOut (BEvents::FocusEvent* event)
122 {
123 	if (event && event->getWidget()) focusLabel.hide();
124 	Widget::onFocusOut (event);
125 }
126 
updateCoords()127 void VSlider::updateCoords ()
128 {
129 	double w = getEffectiveWidth ();
130 	double h = getEffectiveHeight ();
131 
132 	knobRadius = (w < h ? w / 2 : h / 2);
133 	scaleArea = BUtilities::RectArea
134 	(
135 		getXOffset () + w / 2 - knobRadius / 2,
136 		getYOffset () + knobRadius,
137 		knobRadius,
138 		h - 2 * knobRadius
139 	);
140 	scaleYValue = scaleArea.getY() + (1 - getRelativeValue ()) * scaleArea.getHeight();
141 	knobPosition = BUtilities::Point
142 	(
143 		scaleArea.getX() + scaleArea.getWidth() / 2,
144 		scaleYValue
145 	);
146 }
147 }
148