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