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