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.

348 lines
11KB

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