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.

305 lines
9.8KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2007-2008 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 <cstring>
  19. /* system */
  20. #include <sys/types.h>
  21. #include <unistd.h>
  22. #include "../non.H"
  23. #include "draw.H"
  24. #include "../common.h"
  25. #include "ui.H"
  26. extern UI *ui;
  27. void
  28. async_exec ( const char *cmd )
  29. {
  30. if ( fork() )
  31. {
  32. printf( "Executed command \"%s\"\n", cmd );
  33. return;
  34. }
  35. system( cmd );
  36. exit(0);
  37. }
  38. int
  39. canvas_input_callback ( O_Canvas *widget, Canvas *c, int m )
  40. {
  41. // MESSAGE( "Hello, my name is %s", widget->parent()->label() );
  42. int ow, oh;
  43. int x, y;
  44. int processed = 1;
  45. x = Fl::event_x();
  46. y = Fl::event_y();
  47. ow = c->grid()->viewport.w;
  48. oh = c->grid()->viewport.h;
  49. switch ( m )
  50. {
  51. case FL_KEYBOARD:
  52. {
  53. /* if ( Fl::event_state() & FL_ALT || Fl::event_state() & FL_CTRL ) */
  54. /* // this is more than a simple keypress. */
  55. /* return 0; */
  56. if ( Fl::event_state() & FL_CTRL )
  57. {
  58. switch ( Fl::event_key() )
  59. {
  60. case FL_Delete:
  61. c->delete_time();
  62. break;
  63. case FL_Insert:
  64. c->insert_time();
  65. break;
  66. case FL_Right:
  67. c->pan( TO_NEXT_NOTE, 0 );
  68. break;
  69. case FL_Left:
  70. c->pan( TO_PREV_NOTE, 0 );
  71. break;
  72. default:
  73. return 0;
  74. }
  75. }
  76. else
  77. if ( Fl::event_state() & FL_ALT )
  78. return 0;
  79. switch ( Fl::event_key() )
  80. {
  81. case FL_Left:
  82. c->pan( LEFT, 1 );
  83. break;
  84. case FL_Right:
  85. c->pan( RIGHT, 1 );
  86. break;
  87. case FL_Up:
  88. c->pan( UP, 1 );
  89. break;
  90. case FL_Down:
  91. c->pan( DOWN, 1 );
  92. break;
  93. case FL_Delete:
  94. if ( Fl::event_state() & FL_SHIFT )
  95. c->grid()->clear();
  96. else
  97. c->grid()->delete_selected();
  98. break;
  99. default:
  100. /* have to do this to get shifted keys */
  101. switch ( *Fl::event_text() )
  102. {
  103. case 'f':
  104. c->pan( TO_PLAYHEAD, 0 );
  105. break;
  106. case 'r':
  107. c->select_range();
  108. break;
  109. case 'q':
  110. c->grid()->select_none();
  111. break;
  112. case '1':
  113. c->h_zoom( 2.0f );
  114. break;
  115. case '2':
  116. c->h_zoom( 0.5f );
  117. break;
  118. case '3':
  119. c->v_zoom( 2.0f );
  120. break;
  121. case '4':
  122. c->v_zoom( 0.5f );
  123. break;
  124. case ' ':
  125. transport.toggle();
  126. break;
  127. case '[':
  128. {
  129. Grid *g = NULL;
  130. #define IS_PATTERN (widget->parent() == ui->pattern_tab)
  131. #define IS_PHRASE (widget->parent() == ui->phrase_tab)
  132. #define IS_SEQUENCE (widget->parent() == ui->sequence_tab)
  133. /* is there no nicer way to do this shit in c++? */
  134. g = c->grid()->by_number( c->grid()->number() - 1 );
  135. if ( g )
  136. {
  137. c->grid( g );
  138. processed = 2;
  139. }
  140. break;
  141. }
  142. case ']':
  143. {
  144. Grid *g = NULL;
  145. /* is there no nicer way to do this shit in c++? */
  146. g = c->grid()->by_number( c->grid()->number() + 1 );
  147. if ( g )
  148. {
  149. c->grid( g );
  150. processed = 2;
  151. }
  152. break;
  153. }
  154. case '<':
  155. c->move_selected( LEFT, 1 );
  156. break;
  157. case '>':
  158. c->move_selected( RIGHT, 1 );
  159. break;
  160. case ',':
  161. c->move_selected( UP, 1 );
  162. break;
  163. case '.':
  164. c->move_selected( DOWN, 1 );
  165. break;
  166. case 'C':
  167. c->crop();
  168. break;
  169. case 'c':
  170. {
  171. c->grid( c->grid()->create() );
  172. ui->update_sequence_widgets();
  173. break;
  174. }
  175. case 'd':
  176. {
  177. MESSAGE( "duplicating thing" );
  178. c->grid( c->grid()->clone() );
  179. // number of phrases may have changed.
  180. ui->update_sequence_widgets();
  181. break;
  182. }
  183. case 'D':
  184. c->duplicate_range();
  185. break;
  186. case 't':
  187. c->grid()->trim();
  188. break;
  189. case 'm':
  190. c->grid()->mode( c->grid()->mode() == MUTE ? PLAY : MUTE );
  191. break;
  192. case 's':
  193. c->grid()->mode( c->grid()->mode() == SOLO ? PLAY : SOLO );
  194. break;
  195. default:
  196. processed = 0;
  197. break;
  198. }
  199. break;
  200. }
  201. break;
  202. }
  203. case FL_PUSH:
  204. {
  205. switch ( Fl::event_button() )
  206. {
  207. case 1:
  208. int note;
  209. if ( ( note = c->is_row_name( x, y ) ) >= 0 )
  210. {
  211. DEBUG( "click on row %d", note );
  212. Instrument *i = ((pattern *)c->grid())->mapping.instrument();
  213. if ( i )
  214. {
  215. ui->edit_instrument_row( i, note );
  216. c->changed_mapping();
  217. }
  218. }
  219. else
  220. {
  221. if ( IS_PATTERN && Fl::event_state() & FL_CTRL )
  222. c->randomize_row( y );
  223. else
  224. c->set( x, y );
  225. }
  226. break;
  227. case 3:
  228. c->unset( x, y );
  229. break;
  230. case 2:
  231. c->select( x, y );
  232. break;
  233. default:
  234. processed = 0;
  235. }
  236. break;
  237. }
  238. case FL_RELEASE:
  239. break;
  240. case FL_DRAG:
  241. break;
  242. /* case FL_DRAG: */
  243. /* { */
  244. /* if ( ! lmb_down ) */
  245. /* break; */
  246. /* // c->grid()->move( x, y, nx ); */
  247. /* break; */
  248. /* } */
  249. case FL_MOUSEWHEEL:
  250. {
  251. if ( Fl::event_state() & FL_CTRL )
  252. c->adj_length( x, y, (0 - Fl::event_dy()) );
  253. else
  254. c->adj_color( x, y, (0 - Fl::event_dy()) * 5 );
  255. break;
  256. }
  257. default:
  258. processed = 0;
  259. }
  260. int nw, nh;
  261. nw = c->grid()->viewport.w;
  262. nh = c->grid()->viewport.h;
  263. // layout of canvas changed... requires clearing.
  264. if ( oh != nh || ow != nw )
  265. return 3;
  266. return processed;
  267. }