Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
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.

380 lines
11KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2009 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <math.h>
  22. #include <FL/fl_draw.H>
  23. #include <FL/Fl_Pack.H>
  24. #include <FL/Fl_Box.H>
  25. #include <FL/Fl_Menu_Button.H>
  26. #include <FL/Fl_Counter.H>
  27. #include "FL/Boxtypes.H"
  28. #include "FL/Fl_Flowpack.H"
  29. #include "FL/Fl_Labelpad_Group.H"
  30. #include "FL/Fl_Value_SliderX.H"
  31. #include "FL/Fl_Arc_Dial.H"
  32. #include "Module.H"
  33. #include "Module_Parameter_Editor.H"
  34. #include "Controller_Module.H"
  35. #include "Chain.H"
  36. #include "Panner.H"
  37. #include "debug.h"
  38. Module_Parameter_Editor::Module_Parameter_Editor ( Module *module ) : Fl_Double_Window( 0, 0, 800, 600 )
  39. {
  40. _module = module;
  41. _resized = false;
  42. char lab[256];
  43. if ( strcmp( module->name(), module->label() ) )
  44. {
  45. snprintf( lab, sizeof( lab ), "%s : %s", module->name(), module->label() );
  46. }
  47. else
  48. strcpy( lab, module->label() );
  49. char title[512];
  50. snprintf( title, sizeof( title ), "%s - %s - %s", "Mixer", module->chain()->name(), lab );
  51. copy_label( title );
  52. { Fl_Pack *o = main_pack = new Fl_Pack( 0, y(), w(), h() - 10 );
  53. o->type( FL_VERTICAL );
  54. /* o->label( strdup( lab ) ); */
  55. /* o->labeltype( FL_SHADOW_LABEL ); */
  56. /* o->labelsize( 18 ); */
  57. /* o->align( FL_ALIGN_TOP | FL_ALIGN_RIGHT | FL_ALIGN_INSIDE ); */
  58. { Fl_Pack *o = new Fl_Pack( 0, 0, 50, 25 );
  59. o->type( FL_HORIZONTAL );
  60. o->spacing( 20 );
  61. { Fl_Menu_Button *o = mode_choice = new Fl_Menu_Button( 0, 0, 25, 25 );
  62. o->add( "Knobs" );
  63. o->add( "Horizontal Sliders" );
  64. o->add( "Vertical Sliders" );
  65. o->label( NULL );
  66. o->value( 0 );
  67. o->when( FL_WHEN_CHANGED );
  68. o->callback( cb_mode_handle, this );
  69. }
  70. /* { Fl_Box *o = new Fl_Box( 0, 0, 300, 25 ); */
  71. /* o->box( FL_ROUNDED_BOX ); */
  72. /* o->color( FL_YELLOW ); */
  73. /* o->label( strdup( lab ) ); */
  74. /* o->labeltype( FL_SHADOW_LABEL ); */
  75. /* o->labelsize( 18 ); */
  76. /* o->align( (Fl_Align)(FL_ALIGN_TOP | FL_ALIGN_RIGHT | FL_ALIGN_INSIDE ) ); */
  77. /* // Fl_Group::current()->resizable( o ); */
  78. /* } */
  79. o->end();
  80. }
  81. { Fl_Group *o = new Fl_Group( 0, 0, w(), h() );
  82. { Fl_Flowpack *o = control_pack = new Fl_Flowpack( 50, 0, w() - 100, h() );
  83. /* o->box( FL_ROUNDED_BOX ); */
  84. /* o->color( FL_GRAY ); */
  85. o->vspacing( 10 );
  86. o->hspacing( 10 );
  87. o->end();
  88. }
  89. o->resizable( 0 );
  90. o->end();
  91. }
  92. o->end();
  93. }
  94. end();
  95. // draw();
  96. make_controls();
  97. }
  98. Module_Parameter_Editor::~Module_Parameter_Editor ( )
  99. {
  100. }
  101. void
  102. Module_Parameter_Editor::make_controls ( void )
  103. {
  104. Module *module = _module;
  105. control_pack->clear();
  106. /* these are for detecting related parameter groups which can be
  107. better represented by a single control */
  108. int azimuth_port_number = -1;
  109. float azimuth_value = 0.0f;
  110. int elevation_port_number = -1;
  111. float elevation_value = 0.0f;
  112. for ( unsigned int i = 0; i < module->control_input.size(); ++i )
  113. {
  114. Fl_Widget *w;
  115. Module::Port *p = &module->control_input[i];
  116. if ( !strcasecmp( "Azimuth", p->name() ) &&
  117. 180.0f == p->hints.maximum &&
  118. -180.0f == p->hints.minimum )
  119. {
  120. azimuth_port_number = i;
  121. azimuth_value = p->control_value();
  122. continue;
  123. }
  124. else if ( !strcasecmp( "Elevation", p->name() ) &&
  125. 90.0f == p->hints.maximum &&
  126. -90.0f == p->hints.minimum )
  127. {
  128. elevation_port_number = i;
  129. elevation_value = p->control_value();
  130. continue;
  131. }
  132. if ( p->hints.type == Module::Port::Hints::BOOLEAN )
  133. {
  134. Fl_Button *o = new Fl_Button( 0, 0, 30, 30, p->name() );
  135. w = o;
  136. o->selection_color( FL_GREEN );
  137. o->type( FL_TOGGLE_BUTTON );
  138. o->value( p->control_value() );
  139. }
  140. else if ( p->hints.type == Module::Port::Hints::INTEGER )
  141. {
  142. Fl_Counter *o = new Fl_Counter(0, 0, 58, 24, p->name() );
  143. w = o;
  144. o->type(1);
  145. o->step(1);
  146. if ( p->hints.ranged )
  147. {
  148. o->minimum( p->hints.minimum );
  149. o->maximum( p->hints.maximum );
  150. }
  151. o->value( p->control_value() );
  152. }
  153. else
  154. {
  155. if ( mode_choice->value() == 0 )
  156. {
  157. Fl_Arc_Dial *o = new Fl_Arc_Dial( 0, 0, 50, 50, p->name() );
  158. w = o;
  159. if ( p->hints.ranged )
  160. {
  161. DMESSAGE( "Min: %f, max: %f", p->hints.minimum, p->hints.maximum );
  162. o->minimum( p->hints.minimum );
  163. o->maximum( p->hints.maximum );
  164. }
  165. o->box( FL_BURNISHED_OVAL_BOX );
  166. o->color( fl_darker( fl_darker( FL_GRAY ) ) );
  167. o->selection_color( FL_WHITE );
  168. o->value( p->control_value() );
  169. // o->step( fabs( ( o->maximum() - o->minimum() ) ) / 32.0f );
  170. }
  171. else
  172. {
  173. Fl_Value_SliderX *o = new Fl_Value_SliderX( 0, 0, 120, 24, p->name() );
  174. w = o;
  175. if ( mode_choice->value() == 1 )
  176. {
  177. o->type( FL_HORIZONTAL );
  178. o->size( 120, 24 );
  179. if ( p->hints.ranged )
  180. {
  181. o->minimum( p->hints.minimum );
  182. o->maximum( p->hints.maximum );
  183. }
  184. }
  185. else
  186. {
  187. o->type( FL_VERTICAL );
  188. o->size( 32, 120 );
  189. /* have to reverse the meaning of these to get the
  190. * orientation of the slider right */
  191. o->maximum( p->hints.minimum );
  192. o->minimum( p->hints.maximum );
  193. }
  194. // o->step( fabs( ( o->maximum() - o->minimum() ) ) / 32.0f );
  195. o->slider( FL_THIN_UP_BOX );
  196. o->color( fl_darker( fl_darker( FL_GRAY ) ) );
  197. o->selection_color( FL_WHITE );
  198. o->value( p->control_value() );
  199. }
  200. }
  201. Fl_Button *bound;
  202. w->align(FL_ALIGN_TOP);
  203. w->labelsize( 10 );
  204. w->callback( cb_value_handle, new callback_data( this, i ) );
  205. { Fl_Group *o = new Fl_Group( 0, 0, 50, 75 );
  206. {
  207. Fl_Labelpad_Group *flg = new Fl_Labelpad_Group( w );
  208. { Fl_Button *o = bound = new Fl_Button( 0, 50, 14, 14 );
  209. o->selection_color( FL_YELLOW );
  210. o->type( 0 );
  211. o->labelsize( 8 );
  212. o->value( p->connected() );
  213. o->callback( cb_bound_handle, new callback_data( this, i ) );
  214. }
  215. o->resizable( 0 );
  216. o->end();
  217. o->set_visible_focus();
  218. flg->set_visible_focus();
  219. flg->position( o->x(), o->y() );
  220. bound->position( o->x(), flg->y() + flg->h() );
  221. o->size( flg->w(), flg->h() + bound->h() );
  222. o->init_sizes();
  223. }
  224. control_pack->add( o );
  225. }
  226. }
  227. if ( azimuth_port_number >= 0 && elevation_port_number >= 0 )
  228. {
  229. Panner *o = new Panner( 0,0, 300, 300 );
  230. o->box(FL_THIN_UP_BOX);
  231. o->color(FL_GRAY0);
  232. o->selection_color(FL_BACKGROUND_COLOR);
  233. o->labeltype(FL_NORMAL_LABEL);
  234. o->labelfont(0);
  235. o->labelcolor(FL_FOREGROUND_COLOR);
  236. o->align(FL_ALIGN_TOP);
  237. o->when(FL_WHEN_CHANGED);
  238. o->label( "Spatialization" );
  239. o->align(FL_ALIGN_TOP);
  240. o->labelsize( 10 );
  241. o->callback( cb_panner_value_handle, new callback_data( this, azimuth_port_number, elevation_port_number ) );
  242. o->point( 0 )->azimuth( azimuth_value );
  243. o->point( 0 )->elevation( elevation_value );
  244. Fl_Labelpad_Group *flg = new Fl_Labelpad_Group( o );
  245. control_pack->add( flg );
  246. }
  247. int width = control_pack->max_width() + 100;
  248. int height = control_pack->h() + 50;
  249. main_pack->size( width, height );
  250. size( width, height );
  251. }
  252. void
  253. Module_Parameter_Editor::cb_value_handle ( Fl_Widget *w, void *v )
  254. {
  255. callback_data *cd = (callback_data*)v;
  256. cd->base_widget->set_value( cd->port_number[0], ((Fl_Valuator*)w)->value() );
  257. }
  258. void
  259. Module_Parameter_Editor::cb_panner_value_handle ( Fl_Widget *w, void *v )
  260. {
  261. callback_data *cd = (callback_data*)v;
  262. cd->base_widget->set_value( cd->port_number[0], ((Panner*)w)->point( 0 )->azimuth() );
  263. cd->base_widget->set_value( cd->port_number[1], ((Panner*)w)->point( 0 )->elevation() );
  264. }
  265. void
  266. Module_Parameter_Editor::cb_mode_handle ( Fl_Widget *, void *v )
  267. {
  268. ((Module_Parameter_Editor*)v)->make_controls();
  269. }
  270. void
  271. Module_Parameter_Editor::cb_bound_handle ( Fl_Widget *w, void *v )
  272. {
  273. callback_data *cd = (callback_data*)v;
  274. Fl_Button *fv = (Fl_Button*)w;
  275. fv->value( 1 );
  276. cd->base_widget->bind_control( cd->port_number[0] );
  277. }
  278. void
  279. Module_Parameter_Editor::bind_control ( int i )
  280. {
  281. Module::Port *p = &_module->control_input[i];
  282. if ( p->connected() )
  283. /* can only bind once */
  284. return;
  285. Controller_Module *o = new Controller_Module();
  286. o->label( p->name() );
  287. o->chain( _module->chain() );
  288. o->connect_to( p );
  289. _module->chain()->add_control( o );
  290. _module->redraw();
  291. }
  292. void
  293. Module_Parameter_Editor::set_value (int i, float value )
  294. {
  295. _module->control_input[i].control_value( value );
  296. if ( _module->control_input[i].connected() )
  297. _module->control_input[i].connected_port()->module()->handle_control_changed( _module->control_input[i].connected_port() );
  298. // _module->handle_control_changed( &_module->control_input[i] );
  299. }