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.

175 lines
4.9KB

  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_+value()-floorf(value()));
  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_+value()-floorf(value()));
  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;
  80. float rounded;
  81. if (ev != FL_MOUSEWHEEL)
  82. handled = Fl_Slider::handle(ev, X, Y, W, H);
  83. switch (ev) {
  84. case FL_PUSH:
  85. denominator = 2.0;
  86. old_value = value();
  87. start_pos = horizontal() ? Fl::event_x() : Fl::event_y();
  88. {
  89. float range = maximum() - minimum();
  90. float absrng = range > 0 ? range : -range;
  91. if (absrng / W / step() > 32 && Fl::event_button1())
  92. denominator = 0.25;
  93. if (range < 0)
  94. denominator *= -1;
  95. }
  96. break;
  97. case FL_MOUSEWHEEL:
  98. if (this == Fl::belowmouse() && Fl::e_dy != 0) {
  99. int step = 1, divisor = 16;
  100. switch (Fl::event_state() & ( FL_CTRL | FL_SHIFT)) {
  101. case FL_SHIFT:
  102. step = 8;
  103. case FL_SHIFT | FL_CTRL:
  104. break;
  105. case FL_CTRL:
  106. divisor = 128;
  107. default:
  108. step = (fabs(maximum() - minimum()) + 1) / divisor;
  109. if (step < 1)
  110. step = 1;
  111. }
  112. int dy = minimum() <= maximum() ? -Fl::e_dy : Fl::e_dy;
  113. // Flip sense for vertical sliders.
  114. dy = this->horizontal() ? dy : -dy;
  115. handle_drag(clamp(value() + step * dy));
  116. }
  117. return 1;
  118. case FL_RELEASE:
  119. if (Fl::event_clicks() == 1) {
  120. Fl::event_clicks(0);
  121. value(reset_value);
  122. } else {
  123. rounded = floorf(value() + 0.5);
  124. value(clamp(rounded));
  125. }
  126. value_damage();
  127. do_callback();
  128. break;
  129. case FL_DRAG:
  130. if (Fl::event_shift()) {
  131. int delta = (horizontal() ? Fl::event_x() : Fl::event_y()) -
  132. start_pos;
  133. rounded = floor(clamp(old_value + delta/denominator) + 0.5);
  134. value(rounded);
  135. value_damage();
  136. do_callback();
  137. }
  138. }
  139. return handled;
  140. }
  141. int Fl_Osc_Slider::handle(int ev) {
  142. return handle(ev,
  143. x()+Fl::box_dx(box()),
  144. y()+Fl::box_dy(box()),
  145. w()-Fl::box_dw(box()),
  146. h()-Fl::box_dh(box()));
  147. }
  148. void Fl_Osc_Slider::update(void)
  149. {
  150. oscWrite(ext, "");
  151. }
  152. void Fl_Osc_Slider::_cb(Fl_Widget *w, void *)
  153. {
  154. static_cast<Fl_Osc_Slider*>(w)->cb();
  155. }