Audio plugin host https://kx.studio/carla
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.

268 lines
7.2KB

  1. // generated by Fast Light User Interface Designer (fluid) version 1.0107f
  2. #include <cmath>
  3. #include <FL/fl_draw.H>
  4. #include "../Misc/Util.h"
  5. #include "WidgetPDial.h"
  6. //Copyright (c) 2003-2005 Nasca Octavian Paul
  7. //License: GNU GPL version 2 or later
  8. //static int numobj = 0;
  9. static float identity(float value)
  10. {
  11. return value;
  12. }
  13. WidgetPDial::WidgetPDial(int x, int y, int w, int h, const char *label)
  14. :Fl_Dial(x, y, w, h, label), reset_value(0), integer_step(true),
  15. use_rounding(false), oldvalue(0.0f), pos(false), textset(false),
  16. transform(identity)
  17. {
  18. //cout << "[" << label << "] There are now " << ++numobj << endl;
  19. Fl_Group *save = Fl_Group::current();
  20. tipwin = new TipWin();
  21. tipwin->hide();
  22. Fl_Group::current(save);
  23. }
  24. WidgetPDial::~WidgetPDial()
  25. {
  26. //cout << "There are now " << --numobj << endl;
  27. delete tipwin;
  28. }
  29. void WidgetPDial::set_rounding(unsigned int digits)
  30. {
  31. tipwin->set_rounding(digits);
  32. }
  33. #define MOD_MASK (FL_CTRL | FL_SHIFT)
  34. int WidgetPDial::handle(int event)
  35. {
  36. double dragsize, min = minimum(), max = maximum(), result;
  37. int dy;
  38. if (event == FL_RELEASE && Fl::event_clicks() == 1) {
  39. Fl::event_clicks(0);
  40. value(reset_value);
  41. tipwin->hide();
  42. value_damage();
  43. if (this->when() != 0)
  44. do_callback();
  45. return 1;
  46. }
  47. int old_mod_state;
  48. switch(event) {
  49. case FL_PUSH:
  50. mod_state = Fl::event_state() & MOD_MASK;
  51. if (!use_rounding) {
  52. if (integer_step)
  53. set_rounding(0);
  54. else if (mod_state == MOD_MASK)
  55. set_rounding(5);
  56. else if (mod_state == FL_SHIFT)
  57. set_rounding(4);
  58. else
  59. set_rounding((Fl::event_button3() || mod_state & FL_CTRL)
  60. ? 3 : 2);
  61. }
  62. oldvalue = value();
  63. old_y = Fl::event_y();
  64. case FL_DRAG:
  65. getPos();
  66. old_mod_state = mod_state;
  67. mod_state = Fl::event_state() & MOD_MASK;
  68. if (old_mod_state != mod_state) {
  69. oldvalue = value();
  70. old_y = Fl::event_y();
  71. if (!use_rounding) {
  72. if (integer_step)
  73. set_rounding(0);
  74. else if (mod_state == MOD_MASK)
  75. set_rounding(5);
  76. else if (mod_state == FL_SHIFT)
  77. set_rounding(4);
  78. else
  79. set_rounding((Fl::event_button3() ||
  80. mod_state & FL_CTRL)
  81. ? 3 : 2);
  82. }
  83. break;
  84. }
  85. dy = old_y - Fl::event_y();
  86. if (dy < -1 || dy > 1)
  87. Fl::event_clicks(0);
  88. if (!integer_step && mod_state == MOD_MASK)
  89. dragsize = 200000.0f;
  90. else if (!integer_step && mod_state == FL_SHIFT)
  91. dragsize = 20000.0f;
  92. else
  93. dragsize = (Fl::event_button3() || mod_state & MOD_MASK)
  94. ? 1000.0f : 200.0f;
  95. value(clamp(oldvalue + dy / dragsize * (max - min)));
  96. tipwin->showValue(transform(value()));
  97. value_damage();
  98. if(this->when() != 0)
  99. do_callback();
  100. return 1;
  101. case FL_MOUSEWHEEL:
  102. if (Fl::event_buttons() || Fl::belowmouse() != this)
  103. return 1;
  104. mod_state = Fl::event_state() & MOD_MASK;
  105. dy = - Fl::event_dy();
  106. if (integer_step) {
  107. if (!use_rounding) set_rounding(0);
  108. result = (int)(value() +
  109. dy * ((Fl::event_ctrl() ||
  110. Fl::event_shift()) ? 1 : 8));
  111. } else {
  112. float dragsize;
  113. if (mod_state == MOD_MASK) {
  114. dragsize = 100000.0;
  115. if (!use_rounding) set_rounding(5);
  116. } else if (mod_state == FL_SHIFT) {
  117. dragsize = 10000.0;
  118. if (!use_rounding) set_rounding(4);
  119. } else if (mod_state == FL_CTRL) {
  120. dragsize = 1000.0;
  121. if (!use_rounding) set_rounding(3);
  122. } else {
  123. dragsize = 100.0;
  124. if (!use_rounding) set_rounding(2);
  125. }
  126. result = value() + dy / dragsize * (max - min);
  127. }
  128. value(clamp(result));
  129. tipwin->showValue(transform(value()));
  130. value_damage();
  131. if(this->when() != 0)
  132. do_callback();
  133. return 1;
  134. case FL_ENTER:
  135. getPos();
  136. tipwin->showText();
  137. return 1;
  138. case FL_HIDE:
  139. case FL_LEAVE:
  140. tipwin->hide();
  141. resetPos();
  142. break;
  143. case FL_RELEASE:
  144. if (integer_step) {
  145. float rounded = floorf(value() + 0.5);
  146. value(clamp(rounded));
  147. }
  148. tipwin->hide();
  149. resetPos();
  150. if(this->when() == 0)
  151. do_callback();
  152. return 1;
  153. }
  154. return 0;
  155. //#endif
  156. }
  157. void WidgetPDial::draw()
  158. {
  159. #ifdef NTK_GUI
  160. box( FL_NO_BOX );
  161. Fl_Dial::draw();
  162. return;
  163. #else
  164. const int cx = x(), cy = y(), sx = w(), sy = h();
  165. const double a1 = angle1(), a2 = angle2();
  166. const double val = (value() - minimum()) / (maximum() - minimum());
  167. // even radius produces less artifacts if no antialiasing is avail
  168. const int rad = (sx > sy ? sy : sx) &~1;
  169. /* clears the button background */
  170. pdialcolor(160, 160, 160);
  171. fl_pie(cx - 2, cy - 2, rad + 4, rad + 4, 0, 360);
  172. /* dark outline */
  173. fl_color(60, 60, 60);
  174. fl_pie(cx - 1, cy - 1, rad + 2, rad + 2, 0, 360);
  175. /* Draws the button faceplate, min/max */
  176. pdialcolor(110, 110, 115);
  177. fl_pie(cx, cy, rad, rad, 270 - a2, 270 - a1);
  178. /* knob center */
  179. if (rad > 8) {
  180. pdialcolor(140, 140, 145);
  181. fl_pie(cx + 4, cy + 4, rad - 8, rad - 8, 0, 360);
  182. }
  183. /* value circle */
  184. double a = -(a2 - a1) * val - a1;
  185. fl_line_style(0, 2, 0);
  186. pdialcolor(0, 200, 0);
  187. fl_arc(cx + 1, cy + 1, rad - 2, rad - 2, a - 90, a1 - 180);
  188. fl_line_style(0);
  189. /* draw value line */
  190. int ll = rad/4;
  191. if (ll < 2) ll = 2;
  192. fl_push_matrix();
  193. fl_translate(cx + rad / 2, cy + rad / 2);
  194. fl_rotate(a - 90.0f);
  195. fl_translate(rad / 2, 0);
  196. fl_begin_polygon();
  197. pdialcolor(0, 0, 0);
  198. fl_vertex(-ll, 0);
  199. fl_vertex(0, 0);
  200. fl_end_polygon();
  201. fl_pop_matrix();
  202. #endif
  203. }
  204. void WidgetPDial::pdialcolor(int r, int g, int b)
  205. {
  206. if(active_r())
  207. fl_color(r, g, b);
  208. else
  209. fl_color(160 - (160 - r) / 3, 160 - (160 - b) / 3, 160 - (160 - b) / 3);
  210. }
  211. void WidgetPDial::tooltip(const char *c)
  212. {
  213. tipwin->setText(c);
  214. textset = true;
  215. }
  216. void WidgetPDial::getPos()
  217. {
  218. if(!pos) {
  219. tipwin->position(Fl::event_x_root(), Fl::event_y_root() + 20);
  220. pos = true;
  221. }
  222. }
  223. void WidgetPDial::resetPos()
  224. {
  225. pos = false;
  226. }
  227. void WidgetPDial::set_transform(float (*transformer)(float))
  228. {
  229. transform = transformer;
  230. use_rounding = true;
  231. }