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.

351 lines
8.1KB

  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 "Module.H"
  19. #include <FL/fl_draw.H>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include "Module_Parameter_Editor.H"
  24. #include "Chain.H"
  25. Module::Module ( int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L )
  26. {
  27. init();
  28. log_create();
  29. }
  30. Module::Module ( bool is_default, int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L ), Loggable( !is_default )
  31. {
  32. this->is_default( is_default );
  33. init();
  34. log_create();
  35. }
  36. Module::Module ( ) : Fl_Group( 0, 0, 0, 50, "Unnamed" )
  37. {
  38. init();
  39. log_create();
  40. }
  41. Module::~Module ( )
  42. {
  43. for ( unsigned int i = 0; i < audio_input.size(); ++i )
  44. audio_input[i].disconnect();
  45. for ( unsigned int i = 0; i < audio_output.size(); ++i )
  46. audio_output[i].disconnect();
  47. for ( unsigned int i = 0; i < control_input.size(); ++i )
  48. control_input[i].disconnect();
  49. for ( unsigned int i = 0; i < control_output.size(); ++i )
  50. control_output[i].disconnect();
  51. audio_input.clear();
  52. audio_output.clear();
  53. control_input.clear();
  54. control_output.clear();
  55. }
  56. void
  57. Module::init ( void )
  58. {
  59. _is_default = false;
  60. _editor = 0;
  61. _chain = 0;
  62. _instances = 1;
  63. box( FL_UP_BOX );
  64. labeltype( FL_NO_LABEL );
  65. clip_children( 1 );
  66. }
  67. void
  68. Module::get ( Log_Entry &e ) const
  69. {
  70. // e.add( ":name", label() );
  71. // e.add( ":color", (unsigned long)color());
  72. {
  73. char *s = get_parameters();
  74. if ( strlen( s ) )
  75. e.add( ":parameter_values", s );
  76. delete[] s;
  77. }
  78. e.add( ":is_default", is_default() );
  79. e.add( ":chain", chain() );
  80. e.add( ":active", active() );
  81. }
  82. void
  83. Module::set ( Log_Entry &e )
  84. {
  85. for ( int i = 0; i < e.size(); ++i )
  86. {
  87. const char *s, *v;
  88. e.get( i, &s, &v );
  89. if ( ! strcmp( s, ":chain" ) )
  90. {
  91. /* This trickiness is because we may need to know the name of
  92. our chain before we actually get added to it. */
  93. int i;
  94. sscanf( v, "%X", &i );
  95. Chain *t = (Chain*)Loggable::find( i );
  96. assert( t );
  97. chain( t );
  98. }
  99. }
  100. for ( int i = 0; i < e.size(); ++i )
  101. {
  102. const char *s, *v;
  103. e.get( i, &s, &v );
  104. /* if ( ! strcmp( s, ":name" ) ) */
  105. /* label( v ); */
  106. if ( ! strcmp( s, ":parameter_values" ) )
  107. {
  108. set_parameters( v );
  109. }
  110. else if ( ! ( strcmp( s, ":is_default" ) ) )
  111. {
  112. is_default( atoi( v ) );
  113. }
  114. else if ( ! ( strcmp( s, ":active" ) ) )
  115. {
  116. if ( atoi( v ) )
  117. activate();
  118. else
  119. deactivate();
  120. }
  121. else if ( ! strcmp( s, ":chain" ) )
  122. {
  123. int i;
  124. sscanf( v, "%X", &i );
  125. Chain *t = (Chain*)Loggable::find( i );
  126. assert( t );
  127. t->add( this );
  128. }
  129. }
  130. }
  131. /* return a string serializing this module's parameter settings. The
  132. format is 1.0:2.0:... Where 1.0 is the value of the first control
  133. input, 2.0 is the value of the second control input etc.
  134. */
  135. char *
  136. Module::get_parameters ( void ) const
  137. {
  138. char *s = new char[1024];
  139. s[0] = 0;
  140. char *sp = s;
  141. if ( control_input.size() )
  142. {
  143. for ( unsigned int i = 0; i < control_input.size(); ++i )
  144. sp += snprintf( sp, 1024 - (sp - s),"%f:", control_input[i].control_value() );
  145. *(sp - 1) = '\0';
  146. }
  147. return s;
  148. }
  149. void
  150. Module::set_parameters ( const char *parameters )
  151. {
  152. char *s = strdup( parameters );
  153. char *sp = s;
  154. char *start = s;
  155. int i = 0;
  156. for ( char *sp = s; ; ++sp )
  157. {
  158. if ( ':' == *sp || '\0' == *sp )
  159. {
  160. char was = *sp;
  161. *sp = '\0';
  162. DMESSAGE( start );
  163. if ( i < control_input.size() )
  164. control_input[i].control_value( atof( start ) );
  165. else
  166. {
  167. WARNING( "Module has no parameter at index %i", i );
  168. break;
  169. }
  170. i++;
  171. if ( '\0' == was )
  172. break;
  173. start = sp + 1;
  174. }
  175. }
  176. free( s );
  177. }
  178. void
  179. Module::draw_box ( void )
  180. {
  181. fl_color( FL_WHITE );
  182. int tw, th, tx, ty;
  183. tw = w();
  184. th = h();
  185. ty = y();
  186. tx = x();
  187. // bbox( tx, ty, tw, th );
  188. fl_push_clip( tx, ty, tw, th );
  189. Fl_Color c = is_default() ? FL_BLACK : color();
  190. int spacing = w() / instances();
  191. for ( int i = instances(); i--; )
  192. {
  193. fl_draw_box( box(), tx + (spacing * i), ty, tw / instances(), th, Fl::belowmouse() == this ? fl_lighter( c ) : c );
  194. }
  195. if ( audio_input.size() && audio_output.size() )
  196. {
  197. /* maybe draw control indicators */
  198. if ( control_input.size() )
  199. fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 4, 5, 5, is_being_controlled() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
  200. if ( control_output.size() )
  201. fl_draw_box( FL_ROUNDED_BOX, tx + tw - 8, ty + 4, 5, 5, is_controlling() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
  202. }
  203. fl_pop_clip();
  204. // box( FL_NO_BOX );
  205. Fl_Group::draw_children();
  206. }
  207. void
  208. Module::draw_label ( void )
  209. {
  210. int tw, th, tx, ty;
  211. bbox( tx, ty, tw, th );
  212. const char *lp = label();
  213. int l = strlen( label() );
  214. fl_color( FL_FOREGROUND_COLOR );
  215. char *s = NULL;
  216. if ( l > 10 )
  217. {
  218. s = new char[l];
  219. char *sp = s;
  220. for ( ; *lp; ++lp )
  221. switch ( *lp )
  222. {
  223. case 'i': case 'e': case 'o': case 'u': case 'a':
  224. break;
  225. default:
  226. *(sp++) = *lp;
  227. }
  228. *sp = '\0';
  229. }
  230. if ( l > 20 )
  231. fl_font( FL_HELVETICA, 10 );
  232. else
  233. fl_font( FL_HELVETICA, 14 );
  234. fl_draw( s ? s : lp, tx, ty, tw, th, (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP ) );
  235. if ( s )
  236. delete[] s;
  237. }
  238. #include "FL/test_press.H"
  239. int
  240. Module::handle ( int m )
  241. {
  242. switch ( m )
  243. {
  244. case FL_PUSH:
  245. {
  246. if ( test_press( FL_BUTTON1 ) )
  247. {
  248. if ( _editor )
  249. {
  250. _editor->show();
  251. }
  252. else if ( ncontrol_inputs() )
  253. {
  254. DMESSAGE( "Opening module parameters for \"%s\"", label() );
  255. _editor = new Module_Parameter_Editor( this );
  256. _editor->show();
  257. do { Fl::wait(); }
  258. while ( _editor->shown() );
  259. DMESSAGE( "Module parameters for \"%s\" closed",label() );
  260. delete _editor;
  261. _editor = NULL;
  262. }
  263. return 1;
  264. }
  265. break;
  266. }
  267. }
  268. return Fl_Group::handle( m );
  269. }