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.

167 lines
4.7KB

  1. #include <FL/Fl.H>
  2. #include "Fl_Osc_Slider.H"
  3. #include "Fl_Osc_Interface.h"
  4. #include "Fl_Osc_Pane.H"
  5. #include <cstdlib>
  6. #include <cstring>
  7. #include <cmath>
  8. #include <cassert>
  9. #include <sstream>
  10. #include "../Misc/Util.h"
  11. static double min__(double a, double b)
  12. {
  13. return a<b?a:b;
  14. }
  15. Fl_Osc_Slider::Fl_Osc_Slider(int X, int Y, int W, int H, const char *label)
  16. :Fl_Slider(X,Y,W,H,label), Fl_Osc_Widget(this), reset_value(0),
  17. cb_data(NULL, NULL)
  18. {
  19. //bounds(0.0f,1.0f);
  20. Fl_Slider::callback(Fl_Osc_Slider::_cb);
  21. }
  22. void Fl_Osc_Slider::init(std::string path_, char type_)
  23. {
  24. osc_type = type_;
  25. ext = path_;
  26. oscRegister(ext.c_str());
  27. }
  28. Fl_Osc_Slider::~Fl_Osc_Slider(void)
  29. {}
  30. void Fl_Osc_Slider::OSC_value(int v)
  31. {
  32. const float min_ = min__(minimum(), maximum());//flipped sliders
  33. Fl_Slider::value(v+min_+fmodf(value(),1.0));
  34. }
  35. void Fl_Osc_Slider::OSC_value(float v)
  36. {
  37. const float min_ = min__(minimum(), maximum());//flipped sliders
  38. Fl_Slider::value(v+min_);
  39. }
  40. void Fl_Osc_Slider::OSC_value(char v)
  41. {
  42. const float min_ = min__(minimum(), maximum());//flipped sliders
  43. Fl_Slider::value(v+min_+fmodf(value(),1.0));
  44. }
  45. void Fl_Osc_Slider::cb(void)
  46. {
  47. const float min_ = min__(minimum(), maximum());//flipped sliders
  48. const float val = Fl_Slider::value();
  49. if(osc_type == 'f')
  50. oscWrite(ext, "f", val-min_);
  51. else if(osc_type == 'i')
  52. oscWrite(ext, "i", (int)(val-min_));
  53. else {
  54. fprintf(stderr, "invalid `c' from slider %s%s, using `i'\n", loc.c_str(), ext.c_str());
  55. oscWrite(ext, "i", (int)(val-min_));
  56. }
  57. //OSC_value(val);
  58. if(cb_data.first)
  59. cb_data.first(this, cb_data.second);
  60. }
  61. void Fl_Osc_Slider::callback(Fl_Callback *cb, void *p)
  62. {
  63. cb_data.first = cb;
  64. cb_data.second = p;
  65. }
  66. int Fl_Osc_Slider::handle(int ev, int X, int Y, int W, int H)
  67. {
  68. bool middle_mouse = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && !Fl::event_shift());
  69. bool ctl_click = (ev == FL_PUSH && Fl::event_state(FL_BUTTON1) && Fl::event_ctrl());
  70. bool shift_middle = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && Fl::event_shift());
  71. if(middle_mouse || ctl_click) {
  72. printf("Trying to learn...\n");
  73. osc->write("/learn", "s", (loc+ext).c_str());
  74. return 1;
  75. } else if(shift_middle) {
  76. osc->write("/unlearn", "s", (loc+ext).c_str());
  77. return 1;
  78. }
  79. int handled, rounded;
  80. bool reset_requested = false;
  81. switch (ev) {
  82. case FL_MOUSEWHEEL:
  83. if (this == Fl::belowmouse() && Fl::e_dy != 0) {
  84. int step = 1, divisor = 16;
  85. switch (Fl::event_state() & ( FL_CTRL | FL_SHIFT)) {
  86. case FL_SHIFT:
  87. step = 8;
  88. case FL_SHIFT | FL_CTRL:
  89. break;
  90. case FL_CTRL:
  91. divisor = 128;
  92. default:
  93. step = (fabs(maximum() - minimum()) + 1) / divisor;
  94. if (step < 1)
  95. step = 1;
  96. }
  97. int dy = minimum() <= maximum() ? -Fl::e_dy : Fl::e_dy;
  98. // Flip sense for vertical sliders.
  99. dy = (this->type() & 1) ? dy : -dy;
  100. handle_drag(clamp(value() + step * dy));
  101. }
  102. return 1;
  103. case FL_RELEASE:
  104. rounded = value() + 0.5;
  105. value(clamp((double)rounded));
  106. if (Fl::event_clicks() == 1) {
  107. Fl::event_clicks(0);
  108. reset_requested = true;
  109. }
  110. }
  111. if (!Fl::event_shift()) {
  112. handled = Fl_Slider::handle(ev, X, Y, W, H);
  113. if (reset_requested) {
  114. value(reset_value);
  115. value_damage();
  116. if (this->when() != 0)
  117. do_callback();
  118. }
  119. return handled;
  120. }
  121. // Slow down the drag.
  122. // Handy if the slider has a large delta bigger than a mouse quantum.
  123. // Somewhat tricky to use with OSC feedback.
  124. // To change direction of movement, one must reclick the handle.
  125. int old_value = value();
  126. handled = Fl_Slider::handle(ev, X, Y, W, H);
  127. int delta = value() - old_value;
  128. if (ev == FL_DRAG && (delta < -1 || delta > 1)) {
  129. value(clamp((old_value + (delta > 0 ? 1 : -1))));
  130. value_damage();
  131. do_callback();
  132. }
  133. return handled;
  134. }
  135. int Fl_Osc_Slider::handle(int ev) {
  136. return handle(ev,
  137. x()+Fl::box_dx(box()),
  138. y()+Fl::box_dy(box()),
  139. w()-Fl::box_dw(box()),
  140. h()-Fl::box_dh(box()));
  141. }
  142. void Fl_Osc_Slider::update(void)
  143. {
  144. oscWrite(ext, "");
  145. }
  146. void Fl_Osc_Slider::_cb(Fl_Widget *w, void *)
  147. {
  148. static_cast<Fl_Osc_Slider*>(w)->cb();
  149. }