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.

1471 lines
44KB

  1. /* LADSPAPluginGUI.C
  2. * Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
  3. * LADSPA Plugin by Nicolas Noble <nicolas@nobis-crew.org>
  4. * Modified by Mike Rawes <myk@waxfrenzy.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. #include <cstdio>
  21. #include <cmath>
  22. #include <cstring>
  23. #include <dlfcn.h>
  24. #include <vector>
  25. #include <algorithm>
  26. #include <FL/fl_draw.H>
  27. #include <FL/Fl_Tooltip.H>
  28. #include "LADSPAPluginGUI.h"
  29. #include "LADSPAInfo.h"
  30. #include "../../SpiralInfo.h"
  31. LADSPAPluginGUI::LADSPAPluginGUI(int w, int h,
  32. LADSPAPlugin *o,
  33. ChannelHandler *ch,
  34. const HostInfo *Info,
  35. const vector<LADSPAInfo::PluginEntry> &PVec) :
  36. SpiralPluginGUI(w,h,o,ch)
  37. {
  38. m_GUIColour = (Fl_Color)Info->GUI_COLOUR;
  39. m_PluginList = PVec;
  40. // Get maximum input port count
  41. m_GUICH->GetData("GetMaxInputPortCount",&(m_MaxInputPortCount));
  42. // Set up buffers for data transfer via ChannelHandler
  43. m_InputPortNames = (char *)malloc(256 * m_MaxInputPortCount);
  44. m_InputPortSettings = (PortSetting *)malloc(sizeof(PortSetting) * m_MaxInputPortCount);
  45. m_InputPortValues = (PortValue *)calloc(m_MaxInputPortCount, sizeof(PortValue));
  46. m_InputPortDefaults = (float *)calloc(m_MaxInputPortCount, sizeof(float));
  47. if (!(m_InputPortNames && m_InputPortSettings &&
  48. m_InputPortValues && m_InputPortDefaults)) {
  49. cerr<<"LADSPA Plugin (GUI): Memory allocation error\n"<<endl;
  50. }
  51. m_InputPortCount = 0;
  52. m_UnconnectedInputs = 0;
  53. m_PortIndex = 0;
  54. // Set up widgets
  55. m_BKnob = new Fl_Button(5,15,50,20,"Knobs");
  56. m_BKnob->labelsize (10);
  57. m_BKnob->type(FL_TOGGLE_BUTTON);
  58. m_BKnob->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  59. m_BKnob->color(Info->GUI_COLOUR);
  60. m_BKnob->selection_color(m_GUIColour);
  61. m_BKnob->callback((Fl_Callback *)cb_BKnob);
  62. add(m_BKnob);
  63. m_BSlider = new Fl_Button(60,15,50,20,"Sliders");
  64. m_BSlider->labelsize (10);
  65. m_BSlider->type(FL_TOGGLE_BUTTON);
  66. m_BSlider->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  67. m_BSlider->color(m_GUIColour);
  68. m_BSlider->selection_color(m_GUIColour);
  69. m_BSlider->callback((Fl_Callback *)cb_BSlider);
  70. add(m_BSlider);
  71. m_BSetup = new Fl_Button(w - 55,15,50,20,"Setup...");
  72. m_BSetup->labelsize (10);
  73. m_BSetup->type(FL_TOGGLE_BUTTON);
  74. m_BSetup->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  75. m_BSetup->color(m_GUIColour);
  76. m_BSetup->selection_color(m_GUIColour);
  77. m_BSetup->callback((Fl_Callback *)cb_BSetup);
  78. add(m_BSetup);
  79. m_KnobGroup = new Fl_Group(5, 35, w - 10, h - 40, "");
  80. add(m_KnobGroup);
  81. m_SliderGroup = new Fl_Group(5, 35, 490, 275, "");
  82. add(m_SliderGroup);
  83. m_SetupGroup = new Fl_Group(5, 35, 490, 275, "");
  84. m_NameLabel = new Fl_Box(10,45,480,15,"None");
  85. m_NameLabel->align(FL_ALIGN_LEFT|FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
  86. m_NameLabel->labelsize(12);
  87. m_SetupGroup->add(m_NameLabel);
  88. m_MakerLabel = new Fl_Box(10,65,480,15,"None");
  89. m_MakerLabel->align(FL_ALIGN_LEFT|FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
  90. m_MakerLabel->labelsize(12);
  91. m_SetupGroup->add(m_MakerLabel);
  92. m_Browser = new Fl_Choice(50, 90, 440, 22,"Plugin:");
  93. m_Browser->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  94. m_Browser->labelsize(12);
  95. m_Browser->textsize(12);
  96. m_Browser->callback((Fl_Callback *)cb_Select);
  97. m_Browser->add("(None)");
  98. m_PluginIDLookup.push_back(0);
  99. // The plugin list is already formatted for addition to our drop-down,
  100. // so just add all items as they are
  101. unsigned long size = m_Browser->size();
  102. int depth = 1;
  103. for (vector<LADSPAInfo::PluginEntry>::iterator i=m_PluginList.begin();
  104. i!=m_PluginList.end(); i++)
  105. {
  106. m_Browser->add(i->Name.c_str());
  107. unsigned int dsize = m_Browser->size() - size;
  108. int ddepth = i->Depth - depth;
  109. size = m_Browser->size();
  110. depth = i->Depth;
  111. // Add blanks to ID Lookup vector to account for sub-menus
  112. for (unsigned long j = 1; j < (dsize - ddepth); j++) {
  113. m_PluginIDLookup.push_back(0);
  114. }
  115. // Add to ID Lookup vector (this maps Menu Items to Unique IDs)
  116. m_PluginIDLookup.push_back(i->UniqueID);
  117. }
  118. m_Browser->value(0);
  119. m_SetupGroup->add(m_Browser);
  120. m_InputScroll = new Fl_Scroll(10,135,480,145);
  121. m_InputScroll->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  122. m_InputScroll->color((Fl_Color)SpiralInfo::GUICOL_Device);
  123. m_InputScroll->labelsize(12);
  124. m_InputScroll->align(FL_ALIGN_TOP_LEFT);
  125. m_InputScroll->type(Fl_Scroll::VERTICAL);
  126. m_InputPack = new Fl_Pack(15,140,470,135,"");
  127. m_InputPack->color((Fl_Color)SpiralInfo::GUICOL_Device);
  128. m_InputScroll->add(m_InputPack);
  129. m_SetupGroup->add(m_InputScroll);
  130. m_ValueLabel = new Fl_Box(15,120,60,15,"Value");
  131. m_ValueLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  132. m_ValueLabel->labelsize(12);
  133. m_SetupGroup->add(m_ValueLabel);
  134. m_DefaultLabel = new Fl_Box(77,120,60,15,"Default");
  135. m_DefaultLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  136. m_DefaultLabel->labelsize(12);
  137. m_SetupGroup->add(m_DefaultLabel);
  138. m_MinLabel = new Fl_Box(139,120,60,15,"Min");
  139. m_MinLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  140. m_MinLabel->labelsize(12);
  141. m_SetupGroup->add(m_MinLabel);
  142. m_MaxLabel = new Fl_Box(201,120,60,15,"Max");
  143. m_MaxLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  144. m_MaxLabel->labelsize(12);
  145. m_SetupGroup->add(m_MaxLabel);
  146. m_ClampLabel = new Fl_Box(275,120,10,15,"Clamp?");
  147. m_ClampLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  148. m_ClampLabel->labelsize(12);
  149. m_SetupGroup->add(m_ClampLabel);
  150. m_PortLabel = new Fl_Box(335,120,60,15,"Port Name");
  151. m_PortLabel->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  152. m_PortLabel->labelsize(12);
  153. m_SetupGroup->add(m_PortLabel);
  154. m_UpdateInputs = new Fl_LED_Button (10, 282, 25, 25, "Update input values?");
  155. m_UpdateInputs->labelsize(12);
  156. m_UpdateInputs->value(true);
  157. m_UpdateInputs->callback((Fl_Callback *)cb_UpdateInputs);
  158. m_SetupGroup->add(m_UpdateInputs);
  159. add(m_SetupGroup);
  160. m_PortIndex = 0;
  161. SetPage(2);
  162. end();
  163. }
  164. LADSPAPluginGUI::~LADSPAPluginGUI(void)
  165. {
  166. if (m_InputPortNames) free(m_InputPortNames);
  167. if (m_InputPortSettings) free(m_InputPortSettings);
  168. if (m_InputPortValues) free(m_InputPortValues);
  169. if (m_InputPortDefaults) free(m_InputPortDefaults);
  170. m_PluginIDLookup.clear();
  171. Fl::check();
  172. }
  173. // This is done all the time
  174. void LADSPAPluginGUI::Update(void)
  175. {
  176. char temp[256];
  177. bool state_changed = false;
  178. m_GUICH->GetData("GetInputPortCount", &(m_InputPortCount));
  179. m_GUICH->GetData("GetInputPortValues", m_InputPortValues);
  180. m_GUICH->GetData("GetInputPortDefaults", m_InputPortDefaults);
  181. // Need to show that a connection is present
  182. // regardless of Refresh being set
  183. for (unsigned long p = 0; p < m_InputPortCount; p++) {
  184. // Check if plugin connect state is different to GUI state
  185. // A readonly default implies connection
  186. if ((m_InputPortValues[p].Connected &&
  187. !(m_PortDefault[p]->readonly())) ||
  188. (m_PortDefault[p]->readonly() &&
  189. !(m_InputPortValues[p].Connected))) {
  190. if (m_InputPortValues[p].Connected) {
  191. // Disable
  192. m_PortDefault[p]->readonly(1);
  193. m_PortDefault[p]->color(FL_BACKGROUND_COLOR);
  194. } else {
  195. // Enable
  196. m_PortDefault[p]->readonly(0);
  197. m_PortDefault[p]->color(FL_BACKGROUND2_COLOR);
  198. // Update knob and slider inputs to new value
  199. sprintf(temp,"%.4f", m_InputPortDefaults[p]);
  200. m_KnobDefaults[p]->value(temp);
  201. m_SliderDefaults[p]->value(temp);
  202. }
  203. sprintf(temp,"%.4f", m_InputPortDefaults[p]);
  204. m_PortDefault[p]->value(temp);
  205. SetControlValue(p, BOTH);
  206. state_changed = true;
  207. }
  208. // Only update values if Refresh is set
  209. if (m_UpdateInputs->value()) {
  210. sprintf(temp,"%.4f", m_InputPortValues[p].Value);
  211. m_PortValue[p]->value(temp);
  212. if (m_InputPortValues[p].Connected) {
  213. sprintf(temp,"%.4f", m_InputPortDefaults[p]);
  214. m_PortDefault[p]->value(temp);
  215. }
  216. }
  217. }
  218. // If a connection has been added/removed, we need to
  219. // rearrange the knobs
  220. if (state_changed) {
  221. // Count the unconnected ports
  222. m_UnconnectedInputs = 0;
  223. for (unsigned long p = 0; p < m_InputPortCount; p++) {
  224. if (!(m_InputPortValues[p].Connected)) m_UnconnectedInputs++;
  225. }
  226. UpdateKnobs();
  227. UpdateSliders();
  228. m_BKnob->resize(x()+5, y()+15, 50, 20);
  229. m_BSlider->resize(x()+60, y()+15, 50, 20);
  230. m_BSetup->resize(x() + w() - 55, y()+15, 50, 20);
  231. }
  232. }
  233. // This lot is only done on patch load
  234. void LADSPAPluginGUI::UpdateValues(SpiralPlugin *o)
  235. {
  236. LADSPAPlugin* Plugin = (LADSPAPlugin*)o;
  237. SetUniqueID(Plugin->GetUniqueID());
  238. SetName(Plugin->GetName());
  239. SetMaker(Plugin->GetMaker());
  240. SetUpdateInputs(Plugin->GetUpdateInputs());
  241. m_InputPortCount = Plugin->GetInputPortCount();
  242. m_UnconnectedInputs = Plugin->GetUnconnectedInputs();
  243. const char *name;
  244. for (unsigned long p = 0; p < m_InputPortCount; p++) {
  245. name = Plugin->GetInputPortName(p);
  246. strncpy((char *)(m_InputPortNames + p * 256), name, 256);
  247. m_InputPortSettings[p] = Plugin->GetInputPortSetting(p);
  248. m_InputPortDefaults[p] = Plugin->GetInputPortDefault(p);
  249. m_InputPortValues[p] = Plugin->GetInputPortValue(p);
  250. AddPortInfo(p);
  251. SetPortSettings(p);
  252. SetControlValue(p, BOTH);
  253. }
  254. SetPage(Plugin->GetPage());
  255. m_PortIndex = m_InputPortCount;
  256. }
  257. // ****************************************************************************
  258. // ** Protected Member Functions **
  259. // ****************************************************************************
  260. const string LADSPAPluginGUI::GetHelpText(const string &loc)
  261. {
  262. // if (loc == "DE") {
  263. // } else if (loc == "FR") {
  264. // } else {
  265. // Default to English?
  266. return string("LADSPA Plugin\n")
  267. + "\n"
  268. + "This plugin allows you to use any LADSPA plugin in SSM.\n"
  269. + "\n"
  270. + "It grows or shrinks the device GUI to allow you to connect\n"
  271. + "up the ports as any other native SSM plugin, so you can\n"
  272. + "seamlessly use the plugins as part of your layouts.\n"
  273. + "\n"
  274. + "The GUI window has two tabbed sections, Control and Setup.\n"
  275. + "\n"
  276. + "Setup is used to choose which LADSPA plugin to use, and\n"
  277. + "allows you to configure port information.\n"
  278. + "\n"
  279. + "Once you have chosen a plugin, a row will appear for each\n"
  280. + "input port:\n"
  281. + "\n"
  282. + "Value\n"
  283. + " The value being input to the port from a connection.\n"
  284. + "Default\n"
  285. + " The value used as input if there is no connection. If\n"
  286. + " the port is connected, the default will use the value.\n"
  287. + " Upon disconnection, it will retain the last value\n"
  288. + " received.\n"
  289. + "Min, Max\n"
  290. + " The range of values to scale a connected signal to,\n"
  291. + " assuming the signal is in the range -1.0 to +1.0.\n"
  292. + "Clamp\n"
  293. + " Whether to scale inputs - if unchecked, the input is\n"
  294. + " not scaled.\n"
  295. + "Port Name\n"
  296. + " The name of the port, as supplied by the plugin.\n"
  297. + "\n"
  298. + "The Control tab will display a control knob for each port\n"
  299. + "that is not connected. This allows adjustment of input\n"
  300. + "directly.";
  301. // }
  302. }
  303. // ****************************************************************************
  304. // ** Private Member Functions **
  305. // ****************************************************************************
  306. // Clear plugin selection and all related stuff
  307. void LADSPAPluginGUI::ClearPlugin(void)
  308. {
  309. m_InputPortCount = 0;
  310. m_UnconnectedInputs = 0;
  311. m_PortIndex = 0;
  312. m_GUICH->SetCommand(LADSPAPlugin::CLEARPLUGIN);
  313. m_GUICH->Wait();
  314. // Clear out setup scroll
  315. while (m_InputPack->children() > 0) {
  316. Fl_Group *g = (Fl_Group *)m_InputPack->child(0);
  317. while (g->children() > 0) {
  318. Fl_Widget *w = g->child(0);
  319. g->remove(w);
  320. }
  321. m_InputPack->remove(g);
  322. delete g;
  323. }
  324. // Clear out Knob and Slider groups
  325. while (m_KnobGroup->children() > 0) m_KnobGroup->remove(m_KnobGroup->child(0));
  326. while (m_SliderGroup->children() > 0) m_SliderGroup->remove(m_SliderGroup->child(0));
  327. // Clear out all port widgets
  328. for (vector<Fl_Output *>::iterator i = m_PortValue.begin(); i != m_PortValue.end(); i++) delete *i;
  329. m_PortValue.clear();
  330. for (vector<Fl_Input *>::iterator i = m_PortMin.begin(); i != m_PortMin.end(); i++) delete *i;
  331. m_PortMin.clear();
  332. for (vector<Fl_Input *>::iterator i = m_PortMax.begin(); i != m_PortMax.end(); i++) delete *i;
  333. m_PortMax.clear();
  334. for (vector<Fl_Check_Button *>::iterator i = m_PortClamp.begin(); i != m_PortClamp.end(); i++) delete *i;
  335. m_PortClamp.clear();
  336. for (vector<Fl_Input *>::iterator i = m_PortDefault.begin(); i != m_PortDefault.end(); i++) delete *i;
  337. m_PortDefault.clear();
  338. for (vector<Fl_Knob *>::iterator i = m_Knobs.begin(); i != m_Knobs.end(); i++) delete *i;
  339. m_Knobs.clear();
  340. for (vector<Fl_Slider *>::iterator i = m_Sliders.begin(); i != m_Sliders.end(); i++) delete *i;
  341. m_Sliders.clear();
  342. for (vector<Fl_Input *>::iterator i = m_KnobDefaults.begin(); i != m_KnobDefaults.end(); i++) delete *i;
  343. m_KnobDefaults.clear();
  344. for (vector<Fl_Input *>::iterator i = m_SliderDefaults.begin(); i != m_SliderDefaults.end(); i++) delete *i;
  345. m_SliderDefaults.clear();
  346. for (vector<Fl_Box *>::iterator i = m_KnobLabels.begin(); i != m_KnobLabels.end(); i++) delete *i;
  347. m_KnobLabels.clear();
  348. for (vector<Fl_Box *>::iterator i = m_SliderLabels.begin(); i != m_SliderLabels.end(); i++) delete *i;
  349. m_SliderLabels.clear();
  350. // Free label buffers
  351. for (vector<char *>::iterator i = m_KnobLabelBuffers.begin(); i != m_KnobLabelBuffers.end(); i++) {
  352. if (*i) free (*i);
  353. }
  354. m_KnobLabelBuffers.clear();
  355. for (vector<char *>::iterator i = m_SliderLabelBuffers.begin(); i != m_SliderLabelBuffers.end(); i++) {
  356. if (*i) free (*i);
  357. }
  358. m_SliderLabelBuffers.clear();
  359. m_SetupGroup->redraw();
  360. }
  361. // Setup from selected plugin
  362. void LADSPAPluginGUI::SelectPlugin(void)
  363. {
  364. // Now get the new values to populate GUI controls
  365. m_GUICH->GetData("GetName", m_Name);
  366. m_GUICH->GetData("GetMaker", m_Maker);
  367. m_GUICH->GetData("GetInputPortCount", &(m_InputPortCount));
  368. m_GUICH->GetData("GetInputPortNames", m_InputPortNames);
  369. m_GUICH->GetData("GetInputPortSettings", m_InputPortSettings);
  370. m_GUICH->GetData("GetInputPortDefaults", m_InputPortDefaults);
  371. SetName((const char *)m_Name);
  372. SetMaker((const char *)m_Maker);
  373. for (unsigned long p = 0; p < m_InputPortCount; p++) {
  374. AddPortInfo(p);
  375. SetPortSettings(p);
  376. SetControlValue(p, BOTH);
  377. }
  378. m_PortIndex = m_InputPortCount;
  379. m_UnconnectedInputs = m_InputPortCount;
  380. m_SetupGroup->redraw();
  381. }
  382. // Change current page (Knobs/Sliders/Setup), resizing window
  383. // to fit the contents
  384. void LADSPAPluginGUI::SetPage(int index)
  385. {
  386. m_Page = index;
  387. switch (m_Page) {
  388. case 0:
  389. {
  390. m_BKnob->value(1);
  391. m_BKnob->deactivate();
  392. m_BSlider->value(0);
  393. m_BSlider->activate();
  394. m_BSetup->value(0);
  395. m_BSetup->activate();
  396. m_KnobGroup->show();
  397. m_SliderGroup->hide();
  398. m_SetupGroup->hide();
  399. UpdateKnobs();
  400. break;
  401. }
  402. case 1:
  403. {
  404. m_BKnob->value(0);
  405. m_BKnob->activate();
  406. m_BSlider->value(1);
  407. m_BSlider->deactivate();
  408. m_BSetup->value(0);
  409. m_BSetup->activate();
  410. m_KnobGroup->hide();
  411. m_SliderGroup->show();
  412. m_SetupGroup->hide();
  413. UpdateSliders();
  414. break;
  415. }
  416. default:
  417. {
  418. m_BKnob->value(0);
  419. m_BKnob->activate();
  420. m_BSlider->value(0);
  421. m_BSlider->activate();
  422. m_BSetup->value(1);
  423. m_BSetup->deactivate();
  424. m_KnobGroup->hide();
  425. m_SliderGroup->hide();
  426. m_SetupGroup->show();
  427. resize(x(), y(), 500, 320);
  428. m_KnobGroup->resize(x()+5, y()+35, w()-10, h()-40);
  429. m_SliderGroup->resize(x()+5, y()+35, w()-10, h()-40);
  430. m_SetupGroup->resize(x()+5, y()+35, w()-10, h()-40);
  431. }
  432. }
  433. m_BKnob->resize(x()+5, y()+15, 50, 20);
  434. m_BSlider->resize(x()+60, y()+15, 50, 20);
  435. m_BSetup->resize(x() + w() - 55, y()+15, 50, 20);
  436. }
  437. void LADSPAPluginGUI::SetUniqueID(unsigned long n)
  438. {
  439. m_UniqueID = n;
  440. vector<unsigned long>::iterator i = std::find(m_PluginIDLookup.begin(), m_PluginIDLookup.end(), m_UniqueID);
  441. if (i != m_PluginIDLookup.end()) {
  442. m_Browser->value(i - m_PluginIDLookup.begin());
  443. } else {
  444. m_Browser->value(0);
  445. }
  446. }
  447. void LADSPAPluginGUI::SetName(const char *s)
  448. {
  449. m_NameLabel->label(s);
  450. }
  451. void LADSPAPluginGUI::SetMaker(const char *s)
  452. {
  453. char temp[256];
  454. unsigned int len = strlen(s);
  455. strncpy(temp, s, len);
  456. // If this has got an "@" in it FLTK thinks it's a special character not an E.mail address
  457. int t=0;
  458. for (unsigned int f=0; f<len; f++) {
  459. if (t==255) break;
  460. if (temp[f]=='@') m_Maker[t++]='@';
  461. m_Maker[t++]=temp[f];
  462. }
  463. m_Maker[t]=0;
  464. m_MakerLabel->label (m_Maker);
  465. }
  466. void LADSPAPluginGUI::SetPortSettings(unsigned long p)
  467. {
  468. char temp[256];
  469. sprintf(temp,"%.4f", m_InputPortSettings[p].Min);
  470. m_PortMin[p]->value(temp);
  471. sprintf(temp,"%.4f", m_InputPortSettings[p].Max);
  472. m_PortMax[p]->value(temp);
  473. sprintf(temp, "%d", m_InputPortSettings[p].Clamp);
  474. m_PortClamp[p]->value(atoi(temp));
  475. sprintf(temp, "%.4f", m_InputPortDefaults[p]);
  476. m_PortDefault[p]->value(temp);
  477. m_KnobDefaults[p]->value(temp);
  478. m_SliderDefaults[p]->value(temp);
  479. }
  480. void LADSPAPluginGUI::SetUpdateInputs(bool state)
  481. {
  482. m_UpdateInputState = state;
  483. m_UpdateInputs->value(m_UpdateInputState);
  484. }
  485. // Setup all controls (Knob, Slider, Settings) for given port
  486. void LADSPAPluginGUI::AddPortInfo(unsigned long p)
  487. {
  488. Fl_Group* NewGroup = new Fl_Group(0,0,460,24,"");
  489. NewGroup->box(FL_FLAT_BOX);
  490. m_InputPack->add(NewGroup);
  491. // Value
  492. Fl_Output* NewOutput = new Fl_Output(0,0,60,18,"");
  493. NewOutput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  494. NewOutput->value(0);
  495. NewOutput->textsize(10);
  496. NewOutput->color(FL_BACKGROUND_COLOR);
  497. NewOutput->readonly(1);
  498. NewGroup->add(NewOutput);
  499. m_PortValue.push_back(NewOutput);
  500. // Fixed Value/Default
  501. Fl_Input* NewInput = new Fl_Input(62,0,60,18,"");
  502. NewInput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  503. NewInput->value(0);
  504. NewInput->textsize(10);
  505. NewInput->callback((Fl_Callback *)cb_Default);
  506. NewGroup->add(NewInput);
  507. m_PortDefault.push_back(NewInput);
  508. // Min
  509. NewInput = new Fl_Input(124,0,60,18,"");
  510. NewInput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  511. NewInput->value(0);
  512. NewInput->textsize(10);
  513. NewInput->callback((Fl_Callback *)cb_Min);
  514. NewGroup->add(NewInput);
  515. m_PortMin.push_back(NewInput);
  516. // Max
  517. NewInput = new Fl_Input(186,0,60,18,"");
  518. NewInput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  519. NewInput->value(0);
  520. NewInput->textsize(10);
  521. NewInput->callback((Fl_Callback *)cb_Max);
  522. NewGroup->add(NewInput);
  523. m_PortMax.push_back(NewInput);
  524. // Clamp
  525. Fl_Check_Button* NewCheckButton = new Fl_Check_Button(255,0,10,18,"");
  526. NewCheckButton->value(0);
  527. NewCheckButton->callback((Fl_Callback *)cb_Clamp);
  528. NewGroup->add(NewCheckButton);
  529. m_PortClamp.push_back(NewCheckButton);
  530. // Port Name
  531. Fl_Box* NewText = new Fl_Box(315,0,10,18,"");
  532. NewText->label((const char *)(m_InputPortNames + p * 256));
  533. NewText->labelsize(10);
  534. NewText->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
  535. NewGroup->add(NewText);
  536. NewGroup->redraw();
  537. m_InputPack->redraw();
  538. m_InputScroll->redraw();
  539. // Control knobs and sliders - these aren't positoned or displayed yet,
  540. // as this will depend on what is connected. All that is decided in
  541. // UpdateKnobs()
  542. // Knob
  543. Fl_Knob* NewKnob = new Fl_Knob(0,0,40,40,"");
  544. NewKnob->color(m_GUIColour);
  545. NewKnob->callback((Fl_Callback *)cb_Knob);
  546. NewKnob->hide();
  547. m_KnobGroup->add(NewKnob);
  548. m_Knobs.push_back(NewKnob);
  549. // Direct input box for knob
  550. NewInput = new Fl_Input(0,0,60,16);
  551. NewInput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  552. NewInput->value(0);
  553. NewInput->textsize(10);
  554. NewInput->callback((Fl_Callback *)cb_KnobValue);
  555. NewInput->hide();
  556. m_KnobGroup->add(NewInput);
  557. m_KnobDefaults.push_back(NewInput);
  558. // Knob Label
  559. // Get maximum 19 characters (excluding "(AU)"/"(CV)" bit)
  560. size_t len = strlen((const char *)(m_InputPortNames + p * 256));
  561. len = len > 24 ? 19 : len - 5;
  562. char *kl = (char *)malloc(len+1);
  563. if (kl) {
  564. strncpy(kl, (const char *)(m_InputPortNames + p * 256), len);
  565. kl[len] = '\0';
  566. m_KnobLabelBuffers.push_back(kl);
  567. }
  568. NewText = new Fl_Box(0,0,100,12,(const char *)kl);
  569. NewText->align(FL_ALIGN_CENTER|FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
  570. NewText->labelfont(FL_COURIER);
  571. NewText->labelsize(9);
  572. NewText->hide();
  573. m_KnobGroup->add(NewText);
  574. m_KnobLabels.push_back(NewText);
  575. // Slider
  576. Fl_Slider* NewSlider = new Fl_Slider(0,0,20,100,"");
  577. NewSlider->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  578. NewSlider->type(FL_VERT_NICE_SLIDER);
  579. NewSlider->selection_color(m_GUIColour);
  580. NewSlider->callback((Fl_Callback *)cb_Slider);
  581. NewSlider->hide();
  582. m_SliderGroup->add(NewSlider);
  583. m_Sliders.push_back(NewSlider);
  584. // Direct input box for slider
  585. NewInput = new Fl_Input(0,0,56,16);
  586. NewInput->box((Fl_Boxtype)SpiralInfo::GUIDEVICE_Box);
  587. NewInput->value(0);
  588. NewInput->textsize(10);
  589. NewInput->callback((Fl_Callback *)cb_SliderValue);
  590. NewInput->hide();
  591. m_SliderGroup->add(NewInput);
  592. m_SliderDefaults.push_back(NewInput);
  593. // Slider Label
  594. // Copy and truncate knob label to 11 chars for slider
  595. len = len > 11 ? 11 : len;
  596. char *sl = (char *)malloc(len+1);
  597. if (kl && sl) {
  598. strncpy(sl, (const char *)kl, len);
  599. sl[len] = '\0';
  600. m_SliderLabelBuffers.push_back(sl);
  601. }
  602. NewText = new Fl_Box(0,0,60,12,(const char *)sl);
  603. NewText->align(FL_ALIGN_CENTER|FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
  604. NewText->labelfont(FL_COURIER);
  605. NewText->labelsize(9);
  606. NewText->hide();
  607. m_SliderGroup->add(NewText);
  608. m_SliderLabels.push_back(NewText);
  609. // Set the range values
  610. SetControlRange(p, m_InputPortSettings[p].Min, m_InputPortSettings[p].Max);
  611. }
  612. // Rearrange knobs depending on connections
  613. // Knobs corresponding to connected ports are hidden,
  614. // the rest are shown
  615. void LADSPAPluginGUI::UpdateKnobs(void)
  616. {
  617. float sqrcount = sqrtf((float)m_UnconnectedInputs);
  618. float fsqrcount = floorf(sqrcount);
  619. float diff = sqrcount - fsqrcount;
  620. int cols = (int)fsqrcount;
  621. int rows = (int)fsqrcount;
  622. rows += diff > 0.0f ? 1 : 0;
  623. cols += diff > 0.5f ? 1 : 0;
  624. if (m_Page == 0) {
  625. // Size window to fit if current page is showing knobs
  626. int width;
  627. int height;
  628. if (m_UnconnectedInputs == 0) {
  629. // No knobs - minimal size
  630. width = 170;
  631. height = 80;
  632. } else if (m_UnconnectedInputs < 3) {
  633. // Single row for one or two knobs
  634. width = 10+m_UnconnectedInputs*100;
  635. height = 45+80;
  636. width = width < 170 ? 170 : width;
  637. } else {
  638. // Auto arrange
  639. width = 10+cols*100;
  640. height = 45+rows*80;
  641. width = width < 170 ? 170 : width;
  642. }
  643. resize(x(), y(), width, height);
  644. // Resize all groups to fit
  645. m_KnobGroup->resize(x()+5, y()+35, w()-10, h()-40);
  646. m_SliderGroup->resize(x()+5, y()+35, w()-10, h()-40);
  647. m_SetupGroup->resize(x()+5, y()+35, w()-10, h()-40);
  648. redraw();
  649. }
  650. // Add knobs into group
  651. int column = 0;
  652. int row = 0;
  653. for (unsigned long p = 0; p < m_InputPortCount; p++)
  654. {
  655. if (!m_InputPortValues[p].Connected) {
  656. if (m_UnconnectedInputs == 1) {
  657. // Single knob - centre
  658. m_Knobs[p]->resize(x()+35+30,y()+45,40,40);
  659. m_KnobDefaults[p]->resize(x()+35+20,y()+45+40,60,16);
  660. m_KnobLabels[p]->resize(x()+5+30,y()+45+55,100,15);
  661. } else if (m_UnconnectedInputs == 2) {
  662. // Two knobs - put in single row
  663. column = row;
  664. m_Knobs[p]->resize(x()+35+column*100,y()+45,40,40);
  665. m_KnobDefaults[p]->resize(x()+25+column*100,y()+45+40,60,16);
  666. m_KnobLabels[p]->resize(x()+5+column*100,y()+45+55,100,15);
  667. } else {
  668. // Auto arrange
  669. m_Knobs[p]->resize(x()+35+column*100, y()+45+row*80,40,40);
  670. m_KnobDefaults[p]->resize(x()+25+column*100,y()+45+40+row*80,60,16);
  671. m_KnobLabels[p]->resize(x()+5+column*100,y()+45+55+row*80,100,15);
  672. }
  673. if (++column==cols) {
  674. column = 0;
  675. row++;
  676. }
  677. m_Knobs[p]->show();
  678. m_KnobDefaults[p]->show();
  679. m_KnobLabels[p]->show();
  680. } else {
  681. m_Knobs[p]->hide();
  682. m_KnobDefaults[p]->hide();
  683. m_KnobLabels[p]->hide();
  684. }
  685. }
  686. }
  687. // Rearrange sliders depending on connections
  688. // Sliders corresponding to connected ports are hidden,
  689. // the rest are shown
  690. void LADSPAPluginGUI::UpdateSliders(void)
  691. {
  692. int cols;
  693. int rows;
  694. int fullrows = 0;
  695. if (m_UnconnectedInputs < 9) {
  696. cols = m_UnconnectedInputs;
  697. rows = 1;
  698. fullrows = 1;
  699. } else {
  700. float sqrcount = sqrt((float)m_UnconnectedInputs);
  701. float aspect;
  702. int diff;
  703. cols = (int)floorf(sqrcount * 2.0f);
  704. rows = (int)floorf(sqrcount * 0.5f);
  705. aspect = (float)cols / (float)rows;
  706. diff = cols * rows - m_UnconnectedInputs;
  707. if (diff < 0) {
  708. if (aspect > 4.0f) {
  709. rows++;
  710. diff += cols;
  711. }
  712. if (diff > rows - 1) {
  713. cols -= (int)floorf((float)diff / (float)rows);
  714. } else if (diff < 0) {
  715. cols += (int)ceilf(fabsf((float)diff) / (float)rows);
  716. }
  717. }
  718. fullrows = rows - (cols * rows - m_UnconnectedInputs);
  719. }
  720. if (m_Page == 1) {
  721. // Size window to fit if current page is showing sliders
  722. int width;
  723. int height;
  724. if (m_UnconnectedInputs == 0) {
  725. // No sliders - minimal size
  726. width = 170;
  727. height = 80;
  728. } else if (m_UnconnectedInputs < 3) {
  729. // Single row of centred sliders if less than three
  730. width = 170;
  731. height = 45+140;
  732. } else if (m_UnconnectedInputs < 9) {
  733. // Single row for up to eight sliders
  734. width = 10+m_UnconnectedInputs*60;
  735. height = 45+140;
  736. width = width < 170 ? 170 : width;
  737. } else {
  738. // Auto arrange
  739. width = 10+cols*60;
  740. height = 45+rows*140;
  741. width = width < 170 ? 170 : width;
  742. }
  743. resize(x(), y(), width, height);
  744. // Resize all groups to fit
  745. m_KnobGroup->resize(x()+5, y()+35, w()-10, h()-40);
  746. m_SliderGroup->resize(x()+5, y()+35, w()-10, h()-40);
  747. m_SetupGroup->resize(x()+5, y()+35, w()-10, h()-40);
  748. }
  749. // Add sliders into group
  750. int column = 0;
  751. int row = 0;
  752. for (unsigned long p = 0; p < m_InputPortCount; p++)
  753. {
  754. if (!m_InputPortValues[p].Connected) {
  755. if (m_UnconnectedInputs == 0) {
  756. // Nothing
  757. } else if (m_UnconnectedInputs < 3) {
  758. // Single row of centred sliders if less than three
  759. // Width is 170, with 5 pixel 'border'
  760. int offset=(160-m_UnconnectedInputs*60)/2;
  761. m_Sliders[p]->resize(x()+25+offset+column*60, y()+45,20,100);
  762. m_SliderDefaults[p]->resize(x()+7+offset+column*60,y()+45+101,56,16);
  763. m_SliderLabels[p]->resize(x()+5+offset+column*60, y()+45+116,60,15);
  764. } else {
  765. // Arrange as per columns and rows
  766. m_Sliders[p]->resize(x()+25+column*60, y()+45+row*140,20,100);
  767. m_SliderDefaults[p]->resize(x()+7+column*60,y()+45+101+row*140,56,16);
  768. m_SliderLabels[p]->resize(x()+5+column*60, y()+45+116+row*140,60,15);
  769. }
  770. if (++column==(cols - (row < fullrows ? 0 : 1))) {
  771. column = 0;
  772. row++;
  773. }
  774. m_Sliders[p]->show();
  775. m_SliderDefaults[p]->show();
  776. m_SliderLabels[p]->show();
  777. } else {
  778. m_Sliders[p]->hide();
  779. m_SliderDefaults[p]->hide();
  780. m_SliderLabels[p]->hide();
  781. }
  782. }
  783. }
  784. // Set value of slider and/or knob (both use the same settings)
  785. void LADSPAPluginGUI::SetControlValue(unsigned long p, WhichControl wc)
  786. {
  787. float min = atof(m_PortMin[p]->value());
  788. float max = atof(m_PortMax[p]->value());
  789. float value = atof(m_PortDefault[p]->value());
  790. float logbase = m_InputPortSettings[p].LogBase;
  791. if (logbase > 1.0f) {
  792. // Logarithmic control - requires conversion
  793. if (fabsf(value) > logbase) {
  794. if (value > 0.0f) {
  795. value = logf(value) / logf(logbase);
  796. } else {
  797. value = -logf(-value) / logf(logbase);
  798. }
  799. } else {
  800. value /= logbase;
  801. }
  802. }
  803. if (wc == KNOB || wc == BOTH) m_Knobs[p]->value(value);
  804. // Invert slider value, as sliders are upside down
  805. if (wc == SLIDER || wc == BOTH) m_Sliders[p]->value(m_Sliders[p]->maximum() - value + m_Sliders[p]->minimum());
  806. }
  807. // Set range of slider and knob (both use the same settings)
  808. void LADSPAPluginGUI::SetControlRange(unsigned long p, float min, float max)
  809. {
  810. if (m_InputPortSettings[p].Integer) {
  811. // Integer control - integer steps between minimum and maximum
  812. min = floorf(min + 0.5f);
  813. max = floorf(max + 0.5f);
  814. // Change steps to map to integers
  815. m_Knobs[p]->step(1.0f);
  816. m_Knobs[p]->scaleticks((int)(max - min));
  817. m_Sliders[p]->step(1.0f / (max - min));
  818. } else {
  819. float logbase = m_InputPortSettings[p].LogBase;
  820. if (logbase > 1.0f) {
  821. // Continuous logarithmic control
  822. float loglogbase = logf(logbase);
  823. if (fabsf(min) > logbase) {
  824. if (min > logbase) {
  825. min = logf(min) / loglogbase;
  826. } else {
  827. min = -logf(-min) / loglogbase;
  828. }
  829. } else {
  830. min /= logbase;
  831. }
  832. if (fabsf(max) > logbase) {
  833. if (max > logbase) {
  834. max = logf(max) / loglogbase;
  835. } else {
  836. max = -logf(-max) / loglogbase;
  837. }
  838. } else {
  839. max /= logbase;
  840. }
  841. } else {
  842. // Continuous linear control
  843. // Same as given min and max
  844. }
  845. m_Knobs[p]->step((max - min) / 10000.0f);
  846. m_Sliders[p]->step((max - min) / 10000.0f);
  847. }
  848. m_Knobs[p]->minimum(min);
  849. m_Knobs[p]->maximum(max);
  850. m_Sliders[p]->minimum(min);
  851. m_Sliders[p]->maximum(max);
  852. }
  853. // The current value ('Default') can be changed from all three pages
  854. void LADSPAPluginGUI::SetPortValue(unsigned long p, float value, int frompage)
  855. {
  856. m_Default = value;
  857. m_Min = atof(m_PortMin[p]->value());
  858. m_Max = atof(m_PortMax[p]->value());
  859. // Pass current port index
  860. m_GUICH->SetData("SetInputPortIndex", &p);
  861. // If default is out of [Min, Max] range, stretch range
  862. if (m_Default < m_Min) {
  863. m_PortMin[p]->value(m_PortDefault[p]->value());
  864. m_Min = m_Default;
  865. // Pass new Minimum to plugin
  866. m_GUICH->SetData("SetInputPortMin", &m_Min);
  867. m_GUICH->SetCommand(LADSPAPlugin::SETMAX);
  868. m_GUICH->Wait();
  869. // Reconfigure knob range
  870. SetControlRange(m_PortIndex, m_Min, m_Max);
  871. } else if (m_Default > m_Max) {
  872. m_PortMax[p]->value(m_PortDefault[p]->value());
  873. m_Max = m_Default;
  874. // Pass new Maximum to plugin
  875. m_GUICH->SetData("SetInputPortMax", &m_Max);
  876. m_GUICH->SetCommand(LADSPAPlugin::SETMAX);
  877. m_GUICH->Wait();
  878. // Reconfigure knob and slider range
  879. SetControlRange(p, m_Min, m_Max);
  880. }
  881. // Pass new default to plugin
  882. m_GUICH->SetData("SetInputPortDefault", &m_Default);
  883. m_GUICH->SetCommand(LADSPAPlugin::SETDEFAULT);
  884. // Update other two default input boxes
  885. char temp[256];
  886. sprintf(temp, "%.4f", m_Default);
  887. switch (frompage)
  888. {
  889. case 0:
  890. {
  891. // Set from knob page - update slider and setup defaults
  892. m_SliderDefaults[p]->value(temp);
  893. m_PortDefault[p]->value(temp);
  894. break;
  895. }
  896. case 1:
  897. {
  898. // Set from slider page - update knob and setup defaults
  899. m_KnobDefaults[p]->value(temp);
  900. m_PortDefault[p]->value(temp);
  901. break;
  902. }
  903. default:
  904. {
  905. // Set from setup page - update knob and slider defaults
  906. m_KnobDefaults[p]->value(temp);
  907. m_SliderDefaults[p]->value(temp);
  908. }
  909. }
  910. // Set knob and slider to corresponding position
  911. SetControlValue(p, BOTH);
  912. }
  913. // Convert value supplied by a control (knob/slider) to actual
  914. // value in range
  915. float LADSPAPluginGUI::ConvertControlValue(unsigned long p, float value)
  916. {
  917. float logbase = m_InputPortSettings[p].LogBase;
  918. if (logbase > 1.0f) {
  919. // Logarithmic control - convert back to actual value
  920. if (fabsf(value) > 1.0f) {
  921. if (value > 0.0f) {
  922. value = powf(logbase, value);
  923. } else {
  924. value = -powf(logbase, -value);
  925. }
  926. } else {
  927. value *= logbase;
  928. }
  929. }
  930. return value;
  931. }
  932. // ****************************************************************************
  933. // ** Widget Callback Functions **
  934. // ****************************************************************************
  935. inline void LADSPAPluginGUI::cb_BKnob_i(Fl_Button* o)
  936. {
  937. SetPage(0);
  938. m_GUICH->SetData("SetPage", &m_Page);
  939. m_GUICH->SetCommand(LADSPAPlugin::SETPAGE);
  940. }
  941. void LADSPAPluginGUI::cb_BKnob(Fl_Button* o)
  942. { // GUI
  943. ((LADSPAPluginGUI*)(o->parent()))->cb_BKnob_i(o);
  944. }
  945. inline void LADSPAPluginGUI::cb_BSlider_i(Fl_Button* o)
  946. {
  947. SetPage(1);
  948. m_GUICH->SetData("SetPage", &m_Page);
  949. m_GUICH->SetCommand(LADSPAPlugin::SETPAGE);
  950. }
  951. void LADSPAPluginGUI::cb_BSlider(Fl_Button* o)
  952. { // GUI
  953. ((LADSPAPluginGUI*)(o->parent()))->cb_BSlider_i(o);
  954. }
  955. inline void LADSPAPluginGUI::cb_BSetup_i(Fl_Button* o)
  956. {
  957. SetPage(2);
  958. m_GUICH->SetData("SetPage", &m_Page);
  959. m_GUICH->SetCommand(LADSPAPlugin::SETPAGE);
  960. }
  961. void LADSPAPluginGUI::cb_BSetup(Fl_Button* o)
  962. { // GUI
  963. ((LADSPAPluginGUI*)(o->parent()))->cb_BSetup_i(o);
  964. }
  965. inline void LADSPAPluginGUI::cb_Select_i(Fl_Choice* o)
  966. {
  967. ClearPlugin();
  968. unsigned long m_UniqueID = m_PluginIDLookup[o->value()];
  969. if (m_UniqueID != 0) {
  970. // Plugin selected
  971. m_GUICH->SetData("SetUniqueID",&m_UniqueID);
  972. m_GUICH->SetCommand(LADSPAPlugin::SELECTPLUGIN);
  973. m_GUICH->Wait();
  974. }
  975. SelectPlugin();
  976. needs_resize (true);
  977. }
  978. void LADSPAPluginGUI::cb_Select(Fl_Choice* o)
  979. { // Group GUI
  980. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_Select_i(o);
  981. }
  982. inline void LADSPAPluginGUI::cb_UpdateInputs_i(Fl_LED_Button* o)
  983. {
  984. m_UpdateInputState = (bool)(o->value());
  985. m_GUICH->SetData("SetUpdateInputs", &m_UpdateInputState);
  986. m_GUICH->SetCommand(LADSPAPlugin::SETUPDATEINPUTS);
  987. }
  988. void LADSPAPluginGUI::cb_UpdateInputs(Fl_LED_Button* o)
  989. { // Group GUI
  990. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_UpdateInputs_i(o);
  991. }
  992. inline void LADSPAPluginGUI::cb_Default_i(Fl_Input* o)
  993. {
  994. // Which Default was changed?
  995. bool do_search = false;
  996. if (m_PortIndex == m_PortDefault.size()) { do_search = true; }
  997. if (!do_search) { do_search = (o != (m_PortDefault[m_PortIndex])) ? true : false; }
  998. if (do_search) {
  999. // Only bother to re-query if it is different from last one changed
  1000. vector<Fl_Input *>::iterator i = std::find(m_PortDefault.begin(),
  1001. m_PortDefault.end(),
  1002. o);
  1003. m_PortIndex = distance(m_PortDefault.begin(), i);
  1004. }
  1005. float value = atof(o->value());
  1006. SetPortValue(m_PortIndex, value, 2);
  1007. }
  1008. void LADSPAPluginGUI::cb_Default(Fl_Input* o)
  1009. { // Group Pack Scroll Group GUI
  1010. ((LADSPAPluginGUI*)(o->parent()->parent()->parent()->parent()->parent()))->cb_Default_i(o);
  1011. }
  1012. inline void LADSPAPluginGUI::cb_Min_i(Fl_Input* o)
  1013. {
  1014. // Which Min was changed?
  1015. bool do_search = false;
  1016. if (m_PortIndex == m_PortMin.size()) { do_search = true; }
  1017. if (!do_search) { do_search = (o != (m_PortMin[m_PortIndex])) ? true : false; }
  1018. if (do_search) {
  1019. // Only bother to re-query if it is different from last one changed
  1020. vector<Fl_Input *>::iterator i = std::find(m_PortMin.begin(),
  1021. m_PortMin.end(),
  1022. o);
  1023. m_PortIndex = distance(m_PortMin.begin(), i);
  1024. }
  1025. // Pass current port index
  1026. m_GUICH->SetData("SetInputPortIndex", &m_PortIndex);
  1027. // Check that min is really min and max is really max
  1028. m_Min = atof(o->value());
  1029. m_Max = atof(m_PortMax[m_PortIndex]->value());
  1030. if (m_Min > m_Max) {
  1031. // Swap min and max (need to set max as well)
  1032. float min = m_Min;
  1033. m_Min = m_Max;
  1034. m_Max = min;
  1035. m_GUICH->SetData("SetInputPortMax", &m_Max);
  1036. m_GUICH->SetCommand(LADSPAPlugin::SETMAX);
  1037. m_GUICH->Wait();
  1038. // Swap displayed min and max
  1039. char temp[256];
  1040. strncpy(temp, m_PortMin[m_PortIndex]->value(), 256);
  1041. m_PortMin[m_PortIndex]->value(m_PortMax[m_PortIndex]->value());
  1042. m_PortMax[m_PortIndex]->value(temp);
  1043. m_PortMin[m_PortIndex]->redraw();
  1044. m_PortMax[m_PortIndex]->redraw();
  1045. }
  1046. m_GUICH->SetData("SetInputPortMin", &m_Min);
  1047. m_GUICH->SetCommand(LADSPAPlugin::SETMIN);
  1048. // Clip default to range
  1049. m_Default = atof(m_PortDefault[m_PortIndex]->value());
  1050. if (m_Default < m_Min) {
  1051. m_Default = m_Min;
  1052. m_GUICH->SetData("SetInputPortDefault",&m_Default);
  1053. m_GUICH->Wait();
  1054. m_GUICH->SetCommand(LADSPAPlugin::SETDEFAULT);
  1055. // Print to default input box, and the input boxes on the
  1056. // knob and slider pages
  1057. char temp[256];
  1058. sprintf(temp, "%.4f", m_Default);
  1059. m_PortDefault[m_PortIndex]->value(temp);
  1060. m_KnobDefaults[m_PortIndex]->value(temp);
  1061. m_SliderDefaults[m_PortIndex]->value(temp);
  1062. }
  1063. // Reposition and reconfigure knob and slider to reflect new range
  1064. SetControlValue(m_PortIndex, BOTH);
  1065. SetControlRange(m_PortIndex, m_Min, m_Max);
  1066. }
  1067. void LADSPAPluginGUI::cb_Min(Fl_Input* o)
  1068. { // Group Pack Scroll Group GUI
  1069. ((LADSPAPluginGUI*)(o->parent()->parent()->parent()->parent()->parent()))->cb_Min_i(o);
  1070. }
  1071. inline void LADSPAPluginGUI::cb_Max_i(Fl_Input* o)
  1072. {
  1073. // Which Max was changed?
  1074. bool do_search = false;
  1075. if (m_PortIndex == m_PortMax.size()) { do_search = true; }
  1076. if (!do_search) { do_search = (o != (m_PortMax[m_PortIndex])) ? true : false; }
  1077. if (do_search) {
  1078. // Only bother to re-query if it is different from last one changed
  1079. vector<Fl_Input *>::iterator i = std::find(m_PortMax.begin(),
  1080. m_PortMax.end(),
  1081. o);
  1082. m_PortIndex = distance(m_PortMax.begin(), i);
  1083. }
  1084. // Pass value to plugin
  1085. m_GUICH->SetData("SetInputPortIndex", &m_PortIndex);
  1086. // Check that min is really min and max is really max
  1087. m_Max = atof(o->value());
  1088. m_Min = atof(m_PortMin[m_PortIndex]->value());
  1089. if (m_Min > m_Max) {
  1090. // Swap min and max (need to set max as well)
  1091. float max = m_Min;
  1092. m_Min = m_Max;
  1093. m_Max = max;
  1094. m_GUICH->SetData("SetInputPortMin", &m_Min);
  1095. m_GUICH->SetCommand(LADSPAPlugin::SETMIN);
  1096. m_GUICH->Wait();
  1097. // Swap displayed min and max
  1098. char temp[256];
  1099. strncpy(temp, m_PortMax[m_PortIndex]->value(), 256);
  1100. m_PortMax[m_PortIndex]->value(m_PortMin[m_PortIndex]->value());
  1101. m_PortMin[m_PortIndex]->value(temp);
  1102. m_PortMax[m_PortIndex]->redraw();
  1103. m_PortMin[m_PortIndex]->redraw();
  1104. }
  1105. m_GUICH->SetData("SetInputPortMax", &m_Max);
  1106. m_GUICH->SetCommand(LADSPAPlugin::SETMAX);
  1107. // Clip default to range
  1108. m_Default = atof(m_PortDefault[m_PortIndex]->value());
  1109. if (m_Default > m_Max) {
  1110. m_Default = m_Max;
  1111. m_GUICH->SetData("SetInputPortDefault",&m_Default);
  1112. m_GUICH->Wait();
  1113. m_GUICH->SetCommand(LADSPAPlugin::SETDEFAULT);
  1114. // Print to displayed default
  1115. char temp[256];
  1116. sprintf(temp, "%.4f", m_Default);
  1117. m_PortDefault[m_PortIndex]->value(temp);
  1118. m_KnobDefaults[m_PortIndex]->value(temp);
  1119. m_SliderDefaults[m_PortIndex]->value(temp);
  1120. }
  1121. // Reposition and reconfigure knob to reflect new range
  1122. SetControlValue(m_PortIndex, BOTH);
  1123. SetControlRange(m_PortIndex, m_Min, m_Max);
  1124. }
  1125. void LADSPAPluginGUI::cb_Max(Fl_Input* o)
  1126. { // Group Pack Scroll Group GUI
  1127. ((LADSPAPluginGUI*)(o->parent()->parent()->parent()->parent()->parent()))->cb_Max_i(o);
  1128. }
  1129. inline void LADSPAPluginGUI::cb_Clamp_i(Fl_Check_Button* o)
  1130. {
  1131. // Which Clamp was changed?
  1132. bool do_search = false;
  1133. if (m_PortIndex == m_PortClamp.size()) { do_search = true; }
  1134. if (!do_search) { do_search = (o != (m_PortClamp[m_PortIndex])) ? true : false; }
  1135. if (do_search) {
  1136. // Only bother to re-query if it is different from last one changed
  1137. vector<Fl_Check_Button *>::iterator i = std::find(m_PortClamp.begin(),
  1138. m_PortClamp.end(),
  1139. o);
  1140. m_PortIndex = distance(m_PortClamp.begin(), i);
  1141. }
  1142. m_Clamp = (bool)(o->value());
  1143. // Pass value to plugin
  1144. m_GUICH->SetData("SetInputPortIndex", &m_PortIndex);
  1145. m_GUICH->SetData("SetInputPortClamp", &m_Clamp);
  1146. m_GUICH->SetCommand(LADSPAPlugin::SETCLAMP);
  1147. }
  1148. void LADSPAPluginGUI::cb_Clamp(Fl_Check_Button* o)
  1149. { // Group Pack Scroll Group GUI
  1150. ((LADSPAPluginGUI*)(o->parent()->parent()->parent()->parent()->parent()))->cb_Clamp_i(o);
  1151. }
  1152. inline void LADSPAPluginGUI::cb_Knob_i(Fl_Knob *o)
  1153. {
  1154. // First, find which knob is being adjusted
  1155. bool do_search = false;
  1156. if (m_PortIndex == m_Knobs.size()) { do_search = true; }
  1157. if (!do_search) { do_search = (o != (m_Knobs[m_PortIndex])) ? true : false; }
  1158. if (do_search) {
  1159. // Only bother to re-query knob if it is different from last one adjusted
  1160. vector<Fl_Knob *>::iterator i = std::find(m_Knobs.begin(),
  1161. m_Knobs.end(),
  1162. o);
  1163. m_PortIndex = distance(m_Knobs.begin(), i);
  1164. }
  1165. // Get value
  1166. m_Default = ConvertControlValue(m_PortIndex, o->value());
  1167. // Pass value to plugin
  1168. m_GUICH->SetData("SetInputPortIndex", &m_PortIndex);
  1169. m_GUICH->SetData("SetInputPortDefault", &m_Default);
  1170. m_GUICH->SetCommand(LADSPAPlugin::SETDEFAULT);
  1171. // Copy to Default field in Port Setup list
  1172. char temp[256];
  1173. sprintf(temp, "%.4f", m_Default);
  1174. m_PortDefault[m_PortIndex]->value(temp);
  1175. m_KnobDefaults[m_PortIndex]->value(temp);
  1176. m_SliderDefaults[m_PortIndex]->value(temp);
  1177. // Set corresponding slider
  1178. SetControlValue(m_PortIndex, SLIDER);
  1179. }
  1180. void LADSPAPluginGUI::cb_Knob(Fl_Knob *o)
  1181. { // Group GUI
  1182. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_Knob_i(o);
  1183. }
  1184. inline void LADSPAPluginGUI::cb_KnobValue_i(Fl_Input *o)
  1185. {
  1186. // Which Knob Value was changed?
  1187. bool do_search = false;
  1188. if (m_PortIndex == m_KnobDefaults.size()) { do_search = true; }
  1189. if (!do_search) { do_search = (o != (m_KnobDefaults[m_PortIndex])) ? true : false; }
  1190. if (do_search) {
  1191. // Only bother to re-query if it is different from last one changed
  1192. vector<Fl_Input *>::iterator i = std::find(m_KnobDefaults.begin(),
  1193. m_KnobDefaults.end(),
  1194. o);
  1195. m_PortIndex = distance(m_KnobDefaults.begin(), i);
  1196. }
  1197. float value = atof(o->value());
  1198. SetPortValue(m_PortIndex, value, 0);
  1199. }
  1200. void LADSPAPluginGUI::cb_KnobValue(Fl_Input *o)
  1201. { // Group GUI
  1202. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_KnobValue_i(o);
  1203. }
  1204. inline void LADSPAPluginGUI::cb_Slider_i(Fl_Slider *o)
  1205. {
  1206. // First, find which slider is being adjusted
  1207. bool do_search = false;
  1208. if (m_PortIndex == m_Sliders.size()) { do_search = true; }
  1209. if (!do_search) { do_search = (o != (m_Sliders[m_PortIndex])) ? true : false; }
  1210. if (do_search) {
  1211. // Only bother to re-query slider if it is different from last one adjusted
  1212. vector<Fl_Slider *>::iterator i = std::find(m_Sliders.begin(),
  1213. m_Sliders.end(),
  1214. o);
  1215. m_PortIndex = distance(m_Sliders.begin(), i);
  1216. }
  1217. // Get value (Invert it, as sliders are upside down)
  1218. m_Default = ConvertControlValue(m_PortIndex, o->maximum() - o->value() + o->minimum());
  1219. // Pass value to plugin
  1220. m_GUICH->SetData("SetInputPortIndex", &m_PortIndex);
  1221. m_GUICH->SetData("SetInputPortDefault", &m_Default);
  1222. m_GUICH->SetCommand(LADSPAPlugin::SETDEFAULT);
  1223. // Copy to Default field in Port Setup list
  1224. char temp[256];
  1225. sprintf(temp, "%.4f", m_Default);
  1226. m_PortDefault[m_PortIndex]->value(temp);
  1227. m_KnobDefaults[m_PortIndex]->value(temp);
  1228. m_SliderDefaults[m_PortIndex]->value(temp);
  1229. // Set corresponding knob
  1230. SetControlValue(m_PortIndex, KNOB);
  1231. }
  1232. void LADSPAPluginGUI::cb_Slider(Fl_Slider *o)
  1233. { // Group GUI
  1234. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_Slider_i(o);
  1235. }
  1236. inline void LADSPAPluginGUI::cb_SliderValue_i(Fl_Input *o)
  1237. {
  1238. // Which Slider Value was changed?
  1239. bool do_search = false;
  1240. if (m_PortIndex == m_SliderDefaults.size()) { do_search = true; }
  1241. if (!do_search) { do_search = (o != (m_SliderDefaults[m_PortIndex])) ? true : false; }
  1242. if (do_search) {
  1243. // Only bother to re-query if it is different from last one changed
  1244. vector<Fl_Input *>::iterator i = std::find(m_SliderDefaults.begin(),
  1245. m_SliderDefaults.end(),
  1246. o);
  1247. m_PortIndex = distance(m_SliderDefaults.begin(), i);
  1248. }
  1249. float value = atof(o->value());
  1250. SetPortValue(m_PortIndex, value, 1);
  1251. }
  1252. void LADSPAPluginGUI::cb_SliderValue(Fl_Input *o)
  1253. { // Group GUI
  1254. ((LADSPAPluginGUI*)(o->parent()->parent()))->cb_SliderValue_i(o);
  1255. }