1 /* 2 Wdgts for Foo-YC20 UI 3 Copyright (C) 2010 Sampo Savolainen <v2@iki.fi> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef _FOO_YC20_WDGTS_H 20 #define _FOO_YC20_WDGTS_H 21 22 #include <iostream> 23 #include <stdint.h> 24 #include <math.h> 25 26 #include <wdgt.h> 27 28 #define DRAWBAR_BLACK_EMPHASIS_ALPHA 0.333 29 30 31 namespace Wdgt 32 { 33 34 class Draggable : public Wdgt::Object 35 { 36 public: Draggable()37 Draggable() 38 : minValue(0.0) 39 , maxValue(1.0) 40 , value(-99.9) 41 , zone(NULL) 42 { 43 } 44 45 virtual bool setValue(float v) = 0; 46 virtual bool setValueFromDrag(float prevValue, float startY, float y) = 0; 47 getValue()48 float getValue() const { return value; }; getMinValue()49 float getMinValue() const { return minValue; }; getMaxValue()50 float getMaxValue() const { return maxValue; }; 51 setZone(float * z)52 void setZone(float *z) { zone = z; }; getZone()53 float *getZone() const { return zone; }; 54 setPortIndex(uint32_t p)55 void setPortIndex(uint32_t p) { port = p; } getPortIndex()56 uint32_t getPortIndex() const { return port; } 57 58 protected: setValueForZone()59 void inline setValueForZone() 60 { 61 if (zone) { 62 *zone = value; 63 } 64 } 65 66 float minValue; 67 float maxValue; 68 float value; 69 70 float *zone; 71 uint32_t port; 72 }; 73 74 class Lever : public Draggable 75 { 76 public: Lever(bool notches)77 Lever(bool notches) 78 { 79 notched = notches; 80 81 value = -1.0; 82 setValue(0); 83 } 84 setValueFromDrag(float prevValue,float startY,float y)85 bool setValueFromDrag(float prevValue, float startY, float y) 86 { 87 return setValue(prevValue + (y-startY)/((y2-y1)/2.0)); 88 } 89 setValue(float v)90 virtual bool setValue(float v) 91 { 92 if (v < 0.0) { 93 v = 0.0; 94 } else if (v > 1.0) { 95 v = 1.0; 96 } 97 98 imageNum = round(3.0*v); 99 100 float newvalue; 101 102 if (notched) { 103 newvalue = (float)imageNum / 3.0; 104 } else { 105 newvalue = v; 106 } 107 108 if (value == newvalue) { 109 return false; 110 } 111 112 value = newvalue; 113 setValueForZone(); 114 115 return true; 116 } 117 setPosition(float posX,float posY)118 void setPosition(float posX, float posY) 119 { 120 x1 = posX; 121 y1 = posY; 122 x2 = x1 + 40; 123 y2 = y1 + 90 + 5; 124 } 125 126 protected: 127 128 bool notched; 129 int imageNum; 130 131 }; 132 133 class Drawbar : public Lever 134 { 135 public: Drawbar(float posX,float posY,bool notches,cairo_surface_t ** _images)136 Drawbar(float posX, float posY, bool notches, cairo_surface_t **_images) 137 : Lever(notches) 138 , images(_images) 139 , alpha(0.08) 140 { 141 setPosition(posX, posY); 142 } 143 Drawbar(float posX,float posY,bool notches,float _alpha,cairo_surface_t ** _images)144 Drawbar(float posX, float posY, bool notches, float _alpha, cairo_surface_t **_images) 145 : Lever(notches) 146 , images(_images) 147 , alpha(_alpha) 148 { 149 setPosition(posX, posY); 150 } 151 drawWidget(bool hover,cairo_t * cr)152 virtual void drawWidget(bool hover, cairo_t *cr) const 153 { 154 cairo_set_source_surface(cr, images[imageNum], x1, y1); 155 cairo_paint(cr); 156 157 if (hover) { 158 cairo_set_source_surface(cr, images[imageNum], x1, y1); 159 cairo_set_operator(cr, CAIRO_OPERATOR_ADD); 160 cairo_paint_with_alpha(cr, alpha); 161 cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 162 163 } 164 } 165 166 private: 167 cairo_surface_t **images; 168 float alpha; 169 }; 170 171 class Switch : public Drawbar 172 { 173 public: Switch(float posX,float posY,float alpha,cairo_surface_t ** images)174 Switch(float posX, float posY, float alpha, cairo_surface_t **images) 175 : Drawbar(posX, posY, false, alpha, images) 176 { 177 } 178 setValue(float v)179 virtual bool setValue(float v) 180 { 181 if (v < 0.5) { 182 v = 0.0; 183 } else { 184 v = 1.0; 185 } 186 return Drawbar::setValue(v); 187 } 188 }; 189 190 class Potentiometer : public Draggable 191 { 192 public: Potentiometer(float posX,float posY,float min,float max,cairo_surface_t * _image)193 Potentiometer(float posX, float posY, float min, float max, cairo_surface_t *_image) 194 : image(_image) 195 { 196 minValue = min; 197 maxValue = max; 198 199 value = maxValue / (maxValue - minValue); 200 201 setValue( (min+max)/2.0 ); 202 203 setPosition(posX, posY); 204 } 205 setValue(float v)206 virtual bool setValue(float v) 207 { 208 if (v > maxValue) { 209 v = maxValue; 210 } else if (v < minValue) { 211 v = minValue; 212 } 213 214 if (v == value) { 215 return false; 216 } 217 218 value = v; 219 setValueForZone(); 220 221 return true; 222 } 223 setPosition(float posX,float posY)224 void setPosition(float posX, float posY) 225 { 226 x1 = posX; 227 y1 = posY; 228 x2 = x1 + 72; 229 y2 = y1 + 90; 230 231 origoX = x1 + 72.0/2.0; 232 origoY = y1 + 37.5 + 5.0; 233 } 234 setValueFromDrag(float prevValue,float startY,float y)235 bool setValueFromDrag(float prevValue, float startY, float y) 236 { 237 float v = prevValue + (startY - y)/100.0; 238 239 return setValue(v); 240 241 } 242 drawWidget(bool hover,cairo_t * cr)243 virtual void drawWidget(bool hover, cairo_t *cr) const 244 { 245 cairo_set_source_surface(cr, image, x1, y1); 246 cairo_paint(cr); 247 248 if (hover) { 249 cairo_set_operator(cr, CAIRO_OPERATOR_ADD); 250 cairo_paint_with_alpha(cr, 0.08); 251 cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 252 } 253 254 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); 255 cairo_set_line_width(cr, 2.5); 256 257 float relativeValue = -(maxValue - value) / (maxValue - minValue); 258 relativeValue *= (5.0/6.0); 259 relativeValue += 1.0/6.0; 260 261 float x2offt = 32.0 * cos(M_PI * 2.0 * relativeValue); 262 float y2offt = 32.0 * sin(M_PI * 2.0 * relativeValue); 263 264 float x1offt = 8.0 * cos(M_PI * 2.0 * relativeValue); 265 float y1offt = 8.0 * sin(M_PI * 2.0 * relativeValue); 266 267 cairo_move_to(cr, origoX + x1offt, origoY + y1offt); 268 269 cairo_line_to(cr, origoX + x2offt, origoY + y2offt); 270 271 cairo_stroke(cr); 272 } 273 274 private: 275 float origoX; 276 float origoY; 277 278 cairo_surface_t *image; 279 280 }; 281 282 }; 283 284 285 #endif /* _FOO_YC20_WDGTS_H */ 286 287