DPF Plugin examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
9.3KB

  1. /*
  2. * Author: Harry van Haaren 2013
  3. * harryhaaren@gmail.com
  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 2 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, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18. * MA 02110-1301, USA.
  19. *
  20. */
  21. #ifndef AVTK_DELAY_GRAPH_H
  22. #define AVTK_DELAY_GRAPH_H
  23. #include <FL/Fl_Widget.H>
  24. #include <FL/Fl_Slider.H>
  25. #include <FL/Fl_Menu_Item.H>
  26. #include <valarray>
  27. #include <string>
  28. namespace Avtk
  29. {
  30. class Delaygraph : public Fl_Slider
  31. {
  32. public:
  33. Delaygraph(int _x, int _y, int _w, int _h, const char *_label = 0):
  34. Fl_Slider(_x, _y, _w, _h, _label)
  35. {
  36. x = _x;
  37. y = _y;
  38. w = _w;
  39. h = _h;
  40. label = _label;
  41. mouseClickedX = 0;
  42. mouseClickedY = 0;
  43. mouseClicked = false;
  44. active = true;
  45. highlight = false;
  46. volume = 0.5;
  47. waveshapeType = 0.f;
  48. feedback = 0.0;
  49. }
  50. /// holds the preset: used from callback() to write value
  51. float waveshapeType;
  52. void type(float t) {waveshapeType = t; redraw();}
  53. bool active;
  54. bool highlight;
  55. int x, y, w, h;
  56. const char* label;
  57. int mouseClickedX;
  58. int mouseClickedY;
  59. bool mouseClicked;
  60. bool mouseRightClicked;
  61. float feedback;
  62. float volume;
  63. void setFeedback(float f)
  64. {
  65. feedback = f;
  66. redraw();
  67. }
  68. void setVolume(float e)
  69. {
  70. volume = e;
  71. redraw();
  72. }
  73. float getVolume()
  74. {
  75. return volume;
  76. }
  77. void setActive(bool a)
  78. {
  79. active = a;
  80. redraw();
  81. }
  82. bool getActive()
  83. {
  84. return active;
  85. }
  86. void draw()
  87. {
  88. if (damage() & FL_DAMAGE_ALL)
  89. {
  90. cairo_t *cr = Fl::cairo_cc();
  91. cairo_save( cr );
  92. cairo_set_line_width(cr, 1.5);
  93. // fill background
  94. cairo_rectangle( cr, x, y, w, h);
  95. cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f );
  96. cairo_fill_preserve( cr );
  97. cairo_clip( cr );
  98. // set up dashed lines, 1 px off, 1 px on
  99. double dashes[1];
  100. dashes[0] = 2.0;
  101. cairo_set_dash ( cr, dashes, 1, 0.0);
  102. cairo_set_line_width( cr, 1.0);
  103. // loop over each 2nd line, drawing dots
  104. cairo_set_line_width(cr, 1.0);
  105. cairo_set_source_rgb(cr, 0.4,0.4,0.4);
  106. for ( int i = 0; i < 4; i++ )
  107. {
  108. cairo_move_to( cr, x + ((w / 4.f)*i), y );
  109. cairo_line_to( cr, x + ((w / 4.f)*i), y + h );
  110. }
  111. for ( int i = 0; i < 4; i++ )
  112. {
  113. cairo_move_to( cr, x , y + ((h / 4.f)*i) );
  114. cairo_line_to( cr, x + w, y + ((h / 4.f)*i) );
  115. }
  116. cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 );
  117. cairo_stroke(cr);
  118. cairo_set_dash ( cr, dashes, 0, 0.0);
  119. // curved waveshape
  120. /*
  121. float distort = value();
  122. cairo_move_to( cr, x , y + h );
  123. cairo_curve_to( cr, x + w * distort, y+h, // control point 1
  124. x + w - (w * distort), y, // control point 2
  125. x + w, y ); // end of curve 1, start curve 2
  126. cairo_line_to ( cr, x + w, y + h );
  127. cairo_close_path(cr);
  128. cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
  129. cairo_fill_preserve(cr);
  130. cairo_set_line_width(cr, 2.0);
  131. cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
  132. cairo_stroke(cr);
  133. */
  134. float delay = 0;
  135. int delTimeQuantized = int(value() * 3.99f);
  136. switch( delTimeQuantized )
  137. {
  138. case 0:
  139. delay = 0.125;
  140. break;
  141. case 1:
  142. delay = 0.25;
  143. break;
  144. case 2:
  145. delay = 0.5;
  146. break;
  147. case 3:
  148. delay = 1;
  149. break;
  150. }
  151. // Actual audio bar
  152. cairo_move_to( cr, x + w/4, y + h - 2 );
  153. cairo_line_to( cr, x + w/4, y + h - h * 0.75 );
  154. cairo_set_line_width(cr, 18);
  155. cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND );
  156. cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
  157. //cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
  158. cairo_stroke(cr);
  159. // feedback pointer
  160. cairo_move_to( cr, x + w/4 + w/2*delay, y + h * 3.5 / 4 );
  161. cairo_line_to( cr, x + w*3.5/4 , y + h * 3.5 / 4 );
  162. cairo_line_to( cr, x + w*3.5/4 , y + h * 1.0 / 4 );
  163. cairo_line_to( cr, x + w*3.5/4 - ((w/2.)*feedback), y + h * 1.0 / 4 );
  164. cairo_set_source_rgba( cr, 255 / 255.f, 0 / 255.f , 0 / 255.f , 1 );
  165. cairo_set_line_width(cr, 1.5);
  166. cairo_stroke( cr );
  167. cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-10, y + h * 1.0 / 4 );
  168. cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-2 , (y + h * 1.0 / 4)+8 );
  169. cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-2 , (y + h * 1.0 / 4)-8 );
  170. cairo_close_path( cr );
  171. cairo_fill( cr );
  172. // changing delay bar
  173. cairo_move_to( cr, x + w/4 + w/2*delay, y + h - 2 );
  174. cairo_line_to( cr, x + w/4 + w/2*delay, y + h*7/8 - (h*1.5/3.0 * volume) );
  175. cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND );
  176. cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
  177. cairo_fill_preserve(cr);
  178. cairo_set_line_width(cr, 18);
  179. cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
  180. cairo_stroke(cr);
  181. // stroke outline
  182. cairo_rectangle(cr, x+1, y+1, w-2, h-2);
  183. cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 );
  184. cairo_set_line_width(cr, 1.0);
  185. cairo_stroke( cr );
  186. if ( !active )
  187. {
  188. // big grey X
  189. cairo_set_line_width(cr, 20.0);
  190. cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7);
  191. cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) );
  192. cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) );
  193. cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) );
  194. cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) );
  195. cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT);
  196. cairo_stroke( cr );
  197. }
  198. cairo_restore( cr );
  199. }
  200. }
  201. void resize(int X, int Y, int W, int H)
  202. {
  203. Fl_Widget::resize(X,Y,W,H);
  204. x = X;
  205. y = Y;
  206. w = W;
  207. h = H;
  208. redraw();
  209. }
  210. int handle(int event)
  211. {
  212. switch(event)
  213. {
  214. case FL_PUSH:
  215. highlight = 0;
  216. mouseRightClicked = false;
  217. mouseClickedX = Fl::event_x();
  218. mouseClickedY = Fl::event_y();
  219. if ( Fl::event_button() == FL_RIGHT_MOUSE )
  220. {
  221. active = !active;
  222. redraw();
  223. mouseRightClicked = true;
  224. do_callback();
  225. }
  226. return 1;
  227. case FL_DRAG:
  228. {
  229. if ( Fl::event_state(FL_BUTTON1) )
  230. {
  231. if ( mouseClicked == false ) // catch the "click" event
  232. {
  233. mouseClickedX = Fl::event_x();
  234. mouseClickedY = Fl::event_y();
  235. mouseClicked = true;
  236. }
  237. float deltaX = mouseClickedX - Fl::event_x();
  238. float deltaY = mouseClickedY - Fl::event_y();
  239. float valX = value() ;
  240. valX -= deltaX / 100.f;
  241. float valY = volume;
  242. valY += deltaY / 100.f;
  243. if ( valX > 1.0 ) valX = 1.0;
  244. if ( valX < 0.0 ) valX = 0.0;
  245. if ( valY > 1.0 ) valY = 1.0;
  246. if ( valY < 0.0 ) valY = 0.0;
  247. //handle_drag( value + deltaY );
  248. set_value( valX );
  249. volume = valY;
  250. mouseClickedX = Fl::event_x();
  251. mouseClickedY = Fl::event_y();
  252. redraw();
  253. do_callback();
  254. }
  255. }
  256. return 1;
  257. case FL_RELEASE:
  258. mouseRightClicked = false;
  259. if (highlight) {
  260. highlight = 0;
  261. redraw();
  262. do_callback();
  263. }
  264. mouseClicked = false;
  265. return 1;
  266. case FL_SHORTCUT:
  267. if ( test_shortcut() )
  268. {
  269. do_callback();
  270. return 1;
  271. }
  272. return 0;
  273. default:
  274. return Fl_Widget::handle(event);
  275. }
  276. return 0;
  277. }
  278. private:
  279. };
  280. } // Avtk
  281. #endif // AVTK_DELAY_GRAPH_H