Non reinvents the DAW. Powerful enough to form a complete studio, fast and light enough to run on low-end hardware like the eeePC or Raspberry Pi, and so reliable that it can be used live https://non.tuxfamily.org/
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.

235 lines
7.0KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2012 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include "Fl_Value_SliderX.H"
  19. #include <FL/Fl.H>
  20. #include <FL/fl_draw.H>
  21. #include <math.h>
  22. void Fl_Value_SliderX::input_cb(Fl_Widget*, void* v) {
  23. Fl_Value_SliderX& t = *(Fl_Value_SliderX*)v;
  24. double nv;
  25. if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0)
  26. nv = strtod(t.input.value(), 0);
  27. else
  28. nv = strtol(t.input.value(), 0, 0);
  29. if (nv != t.value() || t.when() & FL_WHEN_NOT_CHANGED) {
  30. if ( ! t.soft())
  31. nv = t.clamp(nv);
  32. t.set_value(nv);
  33. t.set_changed();
  34. if (t.when())
  35. {
  36. t.value_damage();
  37. t.do_callback();
  38. }
  39. }
  40. }
  41. void Fl_Value_SliderX::value_damage() {
  42. char buf[128];
  43. format(buf);
  44. input.value(buf);
  45. input.mark(input.position()); // turn off selection highlight
  46. redraw();
  47. }
  48. Fl_Value_SliderX::~Fl_Value_SliderX ( void )
  49. {
  50. if (input.parent() == (Fl_Group *)this)
  51. input.parent(0); // *revert* ctor kludge!
  52. }
  53. /**
  54. Creates a new Fl_Value_SliderX widget using the given
  55. position, size, and label string. The default boxtype is FL_DOWN_BOX.
  56. */
  57. Fl_Value_SliderX::Fl_Value_SliderX(int X, int Y, int W, int H, const char*l)
  58. : Fl_SliderX(X,Y,W,H,l),input(X, Y, W, H, 0) {
  59. step(1,100);
  60. soft_ = 0;
  61. if (input.parent()) // defeat automatic-add
  62. input.parent()->remove(input);
  63. input.parent((Fl_Group *)this); // kludge!
  64. input.callback(input_cb, this);
  65. input.when(FL_WHEN_ENTER_KEY);
  66. align(FL_ALIGN_LEFT);
  67. value_damage();
  68. textsize(9);
  69. set_flag(SHORTCUT_LABEL);
  70. }
  71. void Fl_Value_SliderX::draw() {
  72. int sxx = x(), syy = y(), sww = w(), shh = h();
  73. int bxx = x(), byy = y(), bww = w(), bhh = h();
  74. if (horizontal()) {
  75. input.resize(x(), y(), 35, h());
  76. bww = 35; sxx += 35; sww -= 35;
  77. } else {
  78. input.resize(x(), y(), w(), 25 );
  79. syy += 25; bhh = 25; shh -= 25;
  80. }
  81. if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color());
  82. Fl_SliderX::draw(sxx+Fl::box_dx(box()),
  83. syy+Fl::box_dy(box()),
  84. sww-Fl::box_dw(box()),
  85. shh-Fl::box_dh(box()));
  86. draw_box(box(),bxx,byy,bww,bhh,color());
  87. if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
  88. input.box(box());
  89. input.color(color(), selection_color());
  90. Fl_Widget *i = &input; i->draw(); // calls protected input.draw()
  91. input.clear_damage();
  92. }
  93. int Fl_Value_SliderX::handle(int event) {
  94. if (event == FL_PUSH && Fl::visible_focus()) {
  95. Fl::focus(this);
  96. redraw();
  97. }
  98. int sxx = x(), syy = y(), sww = w(), shh = h();
  99. if (horizontal()) {
  100. sxx += 35; sww -= 35;
  101. } else {
  102. syy += 25; shh -= 25;
  103. }
  104. double v;
  105. int delta;
  106. int mx = Fl::event_x_root();
  107. static int ix, drag;
  108. // input.when(when());
  109. switch (event) {
  110. case FL_ENTER:
  111. return 1;
  112. case FL_LEAVE:
  113. if ( ! drag )
  114. fl_cursor( FL_CURSOR_DEFAULT );
  115. return 1;
  116. case FL_MOVE:
  117. if ( drag || Fl::event_inside( &input ) )
  118. fl_cursor( FL_CURSOR_WE );
  119. else
  120. fl_cursor( FL_CURSOR_DEFAULT );
  121. return 1;
  122. case FL_PUSH:
  123. // if (!step()) goto DEFAULT;
  124. if ( Fl::event_inside(&input) )
  125. {
  126. input.handle(event);
  127. ix = mx;
  128. drag = Fl::event_button();
  129. handle_push();
  130. return 1;
  131. }
  132. goto DEFAULT;
  133. break;
  134. case FL_DRAG:
  135. {
  136. if ( ! drag )
  137. goto DEFAULT;
  138. fl_cursor( FL_CURSOR_WE );
  139. // if (!step()) goto DEFAULT;
  140. delta = mx-ix;
  141. if (!horizontal())
  142. delta = -delta;
  143. if (delta > 5) delta -= 5;
  144. else if (delta < -5) delta += 5;
  145. else delta = 0;
  146. float S = fabs( maximum() - minimum() );
  147. switch (drag) {
  148. case 3: v = previous_value() + ( S * delta * 0.0100f); break;
  149. case 2: v = previous_value() + ( S * delta * 0.0010f); break;
  150. default:v = previous_value() + ( S * delta * 0.0005f); break;
  151. }
  152. v = round(v);
  153. v = soft()?softclamp(v):clamp(v);
  154. handle_drag(v);
  155. value_damage();
  156. return 1;
  157. }
  158. case FL_RELEASE:
  159. if ( ! drag )
  160. goto DEFAULT;
  161. // if (!step()) goto DEFAULT;
  162. if (value() != previous_value() || !Fl::event_is_click())
  163. handle_release();
  164. drag = 0;
  165. fl_cursor( FL_CURSOR_DEFAULT );
  166. /* else { */
  167. /* Fl_Widget_Tracker wp(&input); */
  168. /* input.handle(FL_PUSH); */
  169. /* if (wp.exists()) */
  170. /* input.handle(FL_RELEASE); */
  171. /* } */
  172. return 1;
  173. case FL_FOCUS:
  174. return input.take_focus();
  175. case FL_UNFOCUS:
  176. {
  177. input_cb(&input,this);
  178. return 1;
  179. }
  180. case FL_PASTE:
  181. return 0;
  182. case FL_SHORTCUT:
  183. return input.handle(event);
  184. }
  185. DEFAULT:
  186. int r = Fl_SliderX::handle(event,
  187. sxx+Fl::box_dx(box()),
  188. syy+Fl::box_dy(box()),
  189. sww-Fl::box_dw(box()),
  190. shh-Fl::box_dh(box()));
  191. if ( r )
  192. {
  193. return r;
  194. }
  195. else
  196. {
  197. input.type(((step() - floor(step()))>0.0 || step() == 0.0) ? FL_FLOAT_INPUT : FL_INT_INPUT);
  198. return input.handle(event);
  199. }
  200. }