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.

155 lines
3.5KB

  1. #include <FL/Fl.H>
  2. #include "Fl_Osc_Dial.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. static void callback_fn_dial(Fl_Widget *w, void *)
  11. {
  12. ((Fl_Osc_Dial*)w)->cb();
  13. }
  14. Fl_Osc_Pane *fetch_osc_pane(Fl_Widget *w)
  15. {
  16. if(!w)
  17. return NULL;
  18. Fl_Osc_Pane *pane = dynamic_cast<Fl_Osc_Pane*>(w->parent());
  19. if(pane)
  20. return pane;
  21. return fetch_osc_pane(w->parent());
  22. }
  23. Fl_Osc_Dial::Fl_Osc_Dial(int X, int Y, int W, int H, const char *label)
  24. :WidgetPDial(X,Y,W,H, label), Fl_Osc_Widget(this), alt_style(false), dead(false)
  25. {
  26. bounds(0.0, 127.0f);
  27. WidgetPDial::callback(callback_fn_dial);
  28. }
  29. void Fl_Osc_Dial::init(std::string path_)
  30. {
  31. assert(osc);
  32. ext = path_;
  33. oscRegister(path_.c_str());
  34. };
  35. void Fl_Osc_Dial::alt_init(std::string base, std::string path_)
  36. {
  37. Fl_Osc_Pane *pane = fetch_osc_pane(this);
  38. assert(pane);
  39. osc = pane->osc;
  40. assert(osc);
  41. loc = base;
  42. oscRegister(path_.c_str());
  43. ext = path_;
  44. alt_style = true;
  45. }
  46. Fl_Osc_Dial::~Fl_Osc_Dial(void)
  47. {}
  48. void Fl_Osc_Dial::callback(Fl_Callback *cb, void *p)
  49. {
  50. cb_data.first = cb;
  51. cb_data.second = p;
  52. }
  53. int Fl_Osc_Dial::handle(int ev)
  54. {
  55. bool middle_mouse = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && !Fl::event_shift());
  56. bool ctl_click = (ev == FL_PUSH && Fl::event_state(FL_BUTTON1) && Fl::event_ctrl());
  57. bool shift_middle = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && Fl::event_shift());
  58. if(middle_mouse || ctl_click) {
  59. printf("Trying to learn...\n");
  60. osc->write("/learn", "s", (loc+ext).c_str());
  61. return 1;
  62. } else if(shift_middle) {
  63. osc->write("/unlearn", "s", (loc+ext).c_str());
  64. return 1;
  65. }
  66. return WidgetPDial::handle(ev);
  67. }
  68. void Fl_Osc_Dial::OSC_value(int v)
  69. {
  70. value(v + value() - floorf(value()) +
  71. (minimum() == 64 ? 0 : minimum()));
  72. }
  73. void Fl_Osc_Dial::OSC_value(char v)
  74. {
  75. value(v + value() - floorf(value()) +
  76. minimum());
  77. }
  78. void Fl_Osc_Dial::update(void)
  79. {
  80. osc->requestValue(loc+ext);
  81. }
  82. void Fl_Osc_Dial::cb(void)
  83. {
  84. assert(osc);
  85. if(64 != (int)minimum())
  86. oscWrite(ext, "i", (int)(value()-minimum()));
  87. else
  88. oscWrite(ext, "i", (int)(value()));
  89. if(cb_data.first)
  90. cb_data.first(this, cb_data.second);
  91. }
  92. void Fl_Osc_Dial::mark_dead(void)
  93. {
  94. dead = true;
  95. }
  96. #define VEL_PFX "VelocityScale"
  97. void Fl_Osc_Dial::rebase(std::string new_base)
  98. {
  99. if(dead || loc == "/")
  100. return;
  101. if(!alt_style) {
  102. Fl_Osc_Widget::rebase(new_base);
  103. return;
  104. }
  105. //ok, for a simple hack here lets just assume that there is one branch
  106. //missing
  107. int depth = 0;
  108. for(int i=0; i<(int)loc.size(); ++i)
  109. depth += loc[i] == '/';
  110. int match_depth = 0;
  111. int match_pos = 0;
  112. for(int i=0; i<(int)new_base.size(); ++i) {
  113. match_depth += new_base[i] == '/';
  114. if(match_depth == depth) {
  115. match_pos = i;
  116. break;
  117. }
  118. }
  119. if(match_pos == 0) {
  120. //well, that didn't work
  121. assert(!"good enough hack");
  122. }
  123. std::string new_loc = new_base.substr(0, match_pos+1);
  124. if (!strncmp(ext.c_str(), VEL_PFX, sizeof(VEL_PFX)-1) &&
  125. strstr(loc.c_str(), "/VoicePar"))
  126. new_loc = new_loc + "PFilter";
  127. // printf("Moving '%s' to\n", (loc+ext).c_str());
  128. // printf(" '%s'\n", (new_loc+ext).c_str());
  129. // printf("Ext: %s\n", ext.c_str());
  130. oscMove(loc+ext, new_loc+ext);
  131. loc = new_loc;
  132. }