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.

319 lines
10KB

  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 'i':
  113. c->invert_selection();
  114. break;
  115. case '1':
  116. c->h_zoom( 2.0f );
  117. break;
  118. case '2':
  119. c->h_zoom( 0.5f );
  120. break;
  121. case '3':
  122. c->v_zoom( 2.0f );
  123. break;
  124. case '4':
  125. c->v_zoom( 0.5f );
  126. break;
  127. case ' ':
  128. transport.toggle();
  129. break;
  130. case '[':
  131. {
  132. Grid *g = NULL;
  133. #define IS_PATTERN (widget->parent() == ui->pattern_tab)
  134. #define IS_PHRASE (widget->parent() == ui->phrase_tab)
  135. #define IS_SEQUENCE (widget->parent() == ui->sequence_tab)
  136. /* is there no nicer way to do this shit in c++? */
  137. g = c->grid()->by_number( c->grid()->number() - 1 );
  138. if ( g )
  139. {
  140. c->grid( g );
  141. processed = 2;
  142. }
  143. break;
  144. }
  145. case ']':
  146. {
  147. Grid *g = NULL;
  148. /* is there no nicer way to do this shit in c++? */
  149. g = c->grid()->by_number( c->grid()->number() + 1 );
  150. if ( g )
  151. {
  152. c->grid( g );
  153. processed = 2;
  154. }
  155. break;
  156. }
  157. case '<':
  158. c->move_selected( LEFT, 1 );
  159. break;
  160. case '>':
  161. c->move_selected( RIGHT, 1 );
  162. break;
  163. case ',':
  164. c->move_selected( UP, 1 );
  165. break;
  166. case '.':
  167. c->move_selected( DOWN, 1 );
  168. break;
  169. case 'C':
  170. c->crop();
  171. break;
  172. case 'c':
  173. {
  174. c->grid( c->grid()->create() );
  175. ui->update_sequence_widgets();
  176. break;
  177. }
  178. case 'd':
  179. {
  180. MESSAGE( "duplicating thing" );
  181. c->grid( c->grid()->clone() );
  182. // number of phrases may have changed.
  183. ui->update_sequence_widgets();
  184. break;
  185. }
  186. case 'D':
  187. c->duplicate_range();
  188. break;
  189. case 't':
  190. c->grid()->trim();
  191. break;
  192. case 'm':
  193. c->grid()->mode( c->grid()->mode() == MUTE ? PLAY : MUTE );
  194. break;
  195. case 's':
  196. c->grid()->mode( c->grid()->mode() == SOLO ? PLAY : SOLO );
  197. break;
  198. default:
  199. processed = 0;
  200. break;
  201. }
  202. break;
  203. }
  204. break;
  205. }
  206. case FL_PUSH:
  207. {
  208. switch ( Fl::event_button() )
  209. {
  210. case 1:
  211. int note;
  212. if ( ( note = c->is_row_name( x, y ) ) >= 0 )
  213. {
  214. DMESSAGE( "click on row %d", note );
  215. Instrument *i = ((pattern *)c->grid())->mapping.instrument();
  216. if ( i )
  217. {
  218. ui->edit_instrument_row( i, note );
  219. c->changed_mapping();
  220. }
  221. }
  222. else
  223. {
  224. if ( Fl::event_state() & FL_SHIFT )
  225. {
  226. c->start_cursor( x, y );
  227. break;
  228. }
  229. if ( IS_PATTERN && Fl::event_state() & FL_CTRL )
  230. c->randomize_row( y );
  231. else
  232. c->set( x, y );
  233. }
  234. break;
  235. case 3:
  236. if ( Fl::event_state() & FL_SHIFT )
  237. {
  238. c->end_cursor( x, y );
  239. break;
  240. }
  241. c->unset( x, y );
  242. break;
  243. case 2:
  244. c->select( x, y );
  245. break;
  246. default:
  247. processed = 0;
  248. }
  249. break;
  250. }
  251. case FL_RELEASE:
  252. break;
  253. case FL_DRAG:
  254. break;
  255. /* case FL_DRAG: */
  256. /* { */
  257. /* if ( ! lmb_down ) */
  258. /* break; */
  259. /* // c->grid()->move( x, y, nx ); */
  260. /* break; */
  261. /* } */
  262. case FL_MOUSEWHEEL:
  263. {
  264. if ( Fl::event_state() & FL_CTRL )
  265. c->adj_length( x, y, (0 - Fl::event_dy()) );
  266. else
  267. c->adj_color( x, y, (0 - Fl::event_dy()) * 5 );
  268. break;
  269. }
  270. default:
  271. processed = 0;
  272. }
  273. int nw, nh;
  274. nw = c->grid()->viewport.w;
  275. nh = c->grid()->viewport.h;
  276. // layout of canvas changed... requires clearing.
  277. if ( oh != nh || ow != nw )
  278. return 3;
  279. return processed;
  280. }