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.

1478 lines
43KB

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