1 /* B.Harvestr
2  * LV2 Plugin
3  *
4  * Copyright (C) 2018, 2019  Sven Jähnichen
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef VSLIDER_HPP_
21 #define VSLIDER_HPP_
22 
23 #include "BWidgets/RangeWidget.hpp"
24 #include "BUtilities/to_string.hpp"
25 
26 class VSlider : public BWidgets::RangeWidget
27 {
28 public:
VSlider()29 	VSlider () : VSlider (0, 0, 0, 0, "", 0, 0, 0, 0) {}
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,std::string format="",std::function<double (double x)> displayfunc=[](double x){},std::function<double (double x)> func=[](double x){},std::function<double (double x)> revfunc=[](double x){})30 	VSlider (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, std::string format = "",
32 		 std::function<double (double x)> displayfunc = [] (double x) {return x;},
__anon1958b4da0202(double x) 33  	 	 std::function<double (double x)> func = [] (double x) {return x;},
__anon1958b4da0302(double x) 34  		 std::function<double (double x)> revfunc = [] (double x) {return x;}) :
35 		 RangeWidget (x, y, width, height, name, value, min, max, step),
36 		 txColors_ (BWIDGETS_DEFAULT_FGCOLORS),
37 		 fgColors_ (BWIDGETS_DEFAULT_FGCOLORS),
38 		 bgColors_ (BWIDGETS_DEFAULT_FGCOLORS),
39 		 format_ (format),
40 		 display_ (displayfunc),
41 		 transform_ (func),
42 		 reverse_ (revfunc)
43 	{
44 		setDraggable (true);
45 	}
46 
clone() const47 	virtual Widget* clone () const override {return new VSlider (*this);}
48 
applyTheme(BStyles::Theme & theme)49 	virtual void applyTheme (BStyles::Theme& theme) override {applyTheme (theme, name_);}
50 
applyTheme(BStyles::Theme & theme,const std::string & name)51 	virtual void applyTheme (BStyles::Theme& theme, const std::string& name) override
52 	{
53 		Widget::applyTheme (theme, name);
54 
55 		// Text colors
56 		void* txPtr = theme.getStyle(name, BWIDGETS_KEYWORD_TEXTCOLORS);
57 		if (txPtr) txColors_ = *((BColors::ColorSet*) txPtr);
58 
59 		// Foreground colors (scale)
60 		void* fgPtr = theme.getStyle(name, BWIDGETS_KEYWORD_FGCOLORS);
61 		if (fgPtr) fgColors_ = *((BColors::ColorSet*) fgPtr);
62 
63 		// Background colors (scale background, knob)
64 		void* bgPtr = theme.getStyle(name, BWIDGETS_KEYWORD_BGCOLORS);
65 		if (bgPtr) bgColors_ = *((BColors::ColorSet*) bgPtr);
66 
67 		if (fgPtr || bgPtr) update ();
68 
69 	}
70 
onButtonPressed(BEvents::PointerEvent * event)71 	virtual void onButtonPressed (BEvents::PointerEvent* event) override {}
72 
onButtonReleased(BEvents::PointerEvent * event)73 	virtual void onButtonReleased (BEvents::PointerEvent* event) override {}
74 
onPointerDragged(BEvents::PointerEvent * event)75 	virtual void onPointerDragged (BEvents::PointerEvent* event) override
76 	{
77 		if (!event) return;
78 
79 		BUtilities::Point pos = event->getOrigin();
80 		double y0 = getYOffset();
81 		double h = getEffectiveHeight();
82 
83 		if ((h == 0) || (pos.y < y0) || (pos.y > y0 + h) || (getMin() == getMax())) return;
84 
85 		double dist = getMax() - getMin();
86 		double valueTransformed = transform_ ((getValue() - getMin()) / dist);
87 		double nval = LIMIT (valueTransformed - event->getDelta ().y / h, 0.0, 1.0);
88 		setValue (getMin() + reverse_ (nval) * dist);
89 	}
90 
onWheelScrolled(BEvents::WheelEvent * event)91 	virtual void onWheelScrolled (BEvents::WheelEvent* event) override
92 	{
93 		if (!event) return;
94 
95 		BUtilities::Point pos = event->getPosition();
96 		double y0 = getYOffset();
97 		double h = getEffectiveHeight();
98 
99 		if ((h == 0) || (pos.y < y0) || (pos.y > y0 + h) || (getMin() == getMax())) return;
100 
101 		double dist = getMax() - getMin();
102 		double valueTransformed = transform_ ((getValue() - getMin()) / dist);
103 		double nval = LIMIT (valueTransformed + event->getDelta ().y / h, 0.0, 1.0);
104 		setValue (getMin() + reverse_ (nval) * dist);
105 	}
106 
107 protected:
108 	BColors::ColorSet txColors_;
109 	BColors::ColorSet fgColors_;
110 	BColors::ColorSet bgColors_;
111 	std::string format_;
112 	std::function<double(double)> display_;
113 	std::function<double(double)> transform_;
114 	std::function<double(double)> reverse_;
115 
draw(const BUtilities::RectArea & area)116 	virtual void draw (const BUtilities::RectArea& area) override
117 	{
118 		if ((!widgetSurface_) || (cairo_surface_status (widgetSurface_) != CAIRO_STATUS_SUCCESS)) return;
119 
120 		// Draw super class widget elements first
121 		Widget::draw (area);
122 
123 		// Draw scale only if it is not a null widget
124 		if ((getEffectiveHeight() >= 1) && (getEffectiveWidth() >= 1))
125 		{
126 			cairo_surface_clear (widgetSurface_);
127 			cairo_t* cr = cairo_create (widgetSurface_);
128 
129 			if (cairo_status (cr) == CAIRO_STATUS_SUCCESS)
130 			{
131 				// Limit cairo-drawing area
132 				cairo_rectangle (cr, area.getX (), area.getY (), area.getWidth (), area.getHeight ());
133 				cairo_clip (cr);
134 
135 				const double x0 = getXOffset ();
136 				const double y0 = getYOffset ();
137 				const double h = getEffectiveHeight ();
138 				const double w = getEffectiveWidth ();
139 				const double y1 = y0 + (1 - transform_ ((value - getMin()) / (getMax() - getMin()))) * h;;
140 
141 				//BColors::Color bgColor = *bgColors_.getColor (BColors::OFF);
142 				BColors::Color slColor = *fgColors_.getColor (getState ());
143 				//BColors::Color txColor = *txColors_.getColor (getState ());
144 				//BColors::Color frColor= *bgColors_.getColor (getState ());
145 
146 				// Slider bar
147 				cairo_set_line_width (cr, 0.0);
148 				cairo_set_source_rgba (cr, CAIRO_RGBA (slColor));
149 				cairo_pattern_t* pat = cairo_pattern_create_linear (0, y0 + h, 0, y0);
150 				cairo_pattern_add_color_stop_rgba (pat, 0, slColor.getRed (), slColor.getGreen (), slColor.getBlue (), 0);
151 				cairo_pattern_add_color_stop_rgba (pat, 1, slColor.getRed (), slColor.getGreen (), slColor.getBlue (), 0.5 * slColor.getAlpha ());
152 				cairo_set_source (cr, pat);
153 				cairo_rectangle (cr, x0, y1, w, y0 + h - y1);
154 				cairo_fill_preserve (cr);
155 
156 				cairo_set_line_width (cr, 2.0);
157 				cairo_set_source_rgba (cr, CAIRO_RGBA (slColor));
158 				cairo_stroke (cr);
159 			}
160 			cairo_destroy (cr);
161 		}
162 	}
163 };
164 
165 #endif /* VSLIDER_HPP_ */
166