1 /*
2 * menu.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7
8 #include "main.h"
9 #include "menu.h"
10 #include "ui_list.h"
11 #include "viewwin.h"
12 #include "din.h"
13 #include "keyboard_keyboard.h"
14 #include "mondrian.h"
15 #include "binaural_drones.h"
16 #include "tcl_interp.h"
17 #include "console.h"
18 #include "recorder.h"
19 #include "oscilloscope.h"
20 #include "ball.h"
21 #include "mesh.h"
22 #include "noiser.h"
23 #include "log.h"
24 #include "fft.h"
25 #include "file-utils.h"
26 #include "drawrrow.h"
27 #include "autorotator.h"
28 #include "autoflip.h"
29 #include "defvelaccel.h"
30
31 #include <string>
32 #include <fstream>
33
34 using namespace std;
35
36 extern int mousex, mousey;
37 extern beat2value octave_shift;
38
39 extern std::string INSTRUMENT;
40 extern const char* INSTRUMENTS[];
41 extern int CURRENT_INSTRUMENT, LAST_INSTRUMENT, NUM_INSTRUMENTS;
42
43 extern float VOICE_VOLUME;
44 extern int NUM_OCTAVES;
45 extern void setup_plugin_labels ();
46 extern oscilloscope scope;
47 extern const float PI_BY_180;
48 extern char BUFFER [];
49 extern int wheely;
50 extern int line_height;
51 extern const char *ol_fixed_lbls [];
52 extern plugin_browser plugin__browser;
53
54 #define SECONDS " seconds"
55 #define DEGREES " degrees"
56
menu()57 menu::menu () :
58 diram (modulator::AM), dirfm (modulator::FM),
59 bm_zoom_in(16), pb_zoom_in (16), bm_zoom_out(16), mb_zoom_out (16),
60 abm_left (12), abm_right(12), abm_up(12), abm_down(12),
61 abe_left (12), abe_right(12), abe_up(12), abe_down(12),
62 abl_left (12, arrow_button::left), abl_right (12, arrow_button::right),
63 gater_style_lis (ol_gater_style, "gr", " Style = "),
64 am_style_lis (ol_am_style, "am", " AM style = "),
65 fm_style_lis (ol_fm_style, "fm", " FM style = "),
66 s_phrase_position (256, 16),
67 td_tap_display (36),
68 gc_top(0),
69 gc_bottom(1)
70 {
71 num_tabs = 0;
72 am_depth = fm_depth = 0;
73 dam_depth = dfm_depth = dam_bpm = dfm_bpm = 0;
74
75 cnl.id = 0;
76 cnl.name = "Left Note";
77 cnl.orient = mouse_slider_listener::X;
78
79 cnr.id = 1;
80 cnr.name = "Right Note";
81 cnr.orient = mouse_slider_listener::X;
82
83 arl.name = "Range Left";
84 arl.orient = mouse_slider_listener::X;
85
86 arr.name = "Range Right";
87 arr.orient = mouse_slider_listener::X;
88
89 arb.name = "Range Left & Right";
90 arb.orient = mouse_slider_listener::Y;
91
92 rhl.name = "Range Height";
93 rhl.orient = mouse_slider_listener::Y;
94
95 s_phrase_position.sizer.visible = 1;
96
97 }
98
setup_items()99 void menu::setup_items () {
100
101 b_close.visible = 0;
102
103 button* inst_ed [] = {
104 &b_keyboard_keyboard, // instruments
105 &b_microtonal_keyboard,
106 &b_mondrian,
107 &b_binaural_drones,
108 &b_microtonal_keyboard_waveform, // editors
109 &b_drone_waveform,
110 &b_drone_modulation,
111 &b_voice_modulation,
112 &b_gater,
113 &b_keyboard_keyboard_waveform,
114 &b_attack,
115 &b_decay,
116 &b_midi_velocity,
117 &b_delays,
118 &b_octave_shift,
119 &b_compressor,
120 &b_morse_code,
121 &b_mondrian_waveform,
122 &b_mondrian_attack,
123 &b_mondrian_decay,
124 &b_binaural_drones_waveform,
125 &b_range_modulation,
126 &b_range_width_height,
127 &b_range_pitch_vol,
128 &b_point_modulation,
129 &b_noise_interpolator,
130 &b_drone_pend,
131 };
132
133 // all other menu items
134 widget* mi [] = {
135 &b_exit_din,
136 &l_octave_shift,
137 &ab_octave_down,
138 &ab_octave_up,
139 &sp_octave_shift_bpm,
140 &sp_gater_bpm,
141 &sp_voice_volume,
142 &cb_show_anchors,
143 &sp_change_drone_handle_size,
144 &sp_change_drone_trail_length,
145 &sp_am_depth,
146 &sp_fm_depth,
147 &sp_am_bpm,
148 &sp_fm_bpm,
149 &cb_instrument,
150 &cb_editors,
151 &cb_mkb_drone_params,
152 &cb_file,
153 &ol_gater_style,
154 &l_gater,
155 &ol_am_style,
156 &ol_fm_style,
157 &cb_mkb_drone_tools,
158 &ol_add_wand,
159 &b_move_drones,
160 &b_delete_drones,
161 &b_select_all_drones,
162 &b_invert_drone_selection,
163 &b_record_phrase,
164 &b_clear_phrases,
165 &l_phrase_position,
166 &s_phrase_position,
167 &ol_set_range,
168 &b_default_to_selected,
169 &b_default_to_all,
170 &b_selected_to_all,
171 &b_key_to_pitch_at_cursor,
172 &cb_scope,
173 &sp_scope_height,
174 &sp_scope_samples,
175 &l_tap_bpm,
176 &td_tap_display,
177 &l_tap_bpm_value,
178 &cb_am,
179 &cb_fm,
180 &cb_gater,
181 &cb_octave_shift,
182 &cb_auto_reset,
183 &cb_ed_tools,
184 &abe_left,
185 &abe_right,
186 &abe_up,
187 &abe_down,
188 &b_close,
189 &cb_snapx,
190 &cb_snapy,
191 &cb_snapboth,
192 &cb_snapnone,
193 &l_snap,
194 &pb_zoom_in,
195 &mb_zoom_out,
196 &b_insert_vertex,
197 &b_delete_vertex,
198 &b_fold_tangents,
199 &b_unfold_tangents,
200 &ol_mirror,
201 &ol_vertices_carry_tangents,
202 &ol_mirror_tangents,
203 &cb_selection_only,
204 &b_undo,
205 &b_redo,
206 &b_copy,
207 &b_paste,
208 &b_draw_replacement_curve,
209 &l_library,
210 &abl_left,
211 &abl_right,
212 &lf_curve_name,
213 &b_add_curve,
214 &b_replace_curve,
215 &b_delete_curve,
216 &l_capture,
217 &b_start_capture,
218 &b_assign_capture,
219 &cb_label_vertices,
220 &cb_show_waveform_samples,
221 &sp_waveform_hz,
222 &b_pick_curve,
223 &sp_curve_limit,
224 &sp_waveform_periods,
225 &ol_curve_style,
226 &sp_curve_rpm,
227 &b_stop_rotating,
228 &cb_draw_curve,
229 &cb_record,
230 &b_clear_record,
231 &lf_file,
232 &b_save,
233 &b_select_attractees,
234 &b_select_attractors,
235 &b_orbit_selected_drones,
236 &cb_show_vel,
237 &cb_show_accel,
238 &sp_change_drone_vel,
239 &sp_change_drone_accel,
240 &cb_show_gravity,
241 &balloon,
242 &sp_rotate_drone_vel,
243 &sp_drones_per_min,
244 &b_launch_drones,
245 &b_stop_launching_drones,
246 &ol_create_this,
247 &sp_mesh_rows,
248 &sp_mesh_cols,
249 &b_track_drones,
250 &b_select_tracked_drones,
251 &sp_bounces,
252 &sp_rebound,
253 &b_add_balls,
254 &b_move_selected_balls,
255 &b_delete_selected_targets,
256 &b_delete_all_targets,
257 &b_select_all_targets,
258 &b_invert_selected_targets,
259 &b_select_targets_in_box,
260 &b_split_horizontal,
261 &b_split_vertical,
262 &b_delete_box,
263 &sp_mondrian_min_voices,
264 &sp_mondrian_change_attack_time,
265 &sp_mondrian_change_decay_time,
266 &sp_mondrian_change_speed,
267 &b_freeze_balls,
268 &b_thaw_balls,
269 &abm_left,
270 &abm_right,
271 &abm_up,
272 &abm_down,
273 &bm_zoom_in,
274 &bm_zoom_out,
275 &b_turn_off_ui,
276 &b_set_targets,
277 &b_clear_targets,
278 &sp_drone_lifetime,
279 &sp_orbit_insertion_time,
280 &b_clear_modulations,
281 &b_modulate_balls_up,
282 &b_modulate_balls_down,
283 &cb_binaural_drones_tools,
284 &lf_master_volume,
285 &sp_bd_separation,
286 &b_create_binaurals_on_notes,
287 &b_create_binaurals_from_pitch,
288 &lf_bd_start_pitch,
289 &sp_bd_pairs,
290 &lf_bd_spacing,
291 &cb_close_octave,
292 &lf_vol_fade_time,
293 &sp_mondrian_change_dir,
294 &sp_mondrian_change_trail_size,
295 &sp_mondrian_change_note_poly_points,
296 &sp_mondrian_change_note_poly_radius,
297 &b_auto_change_direction_clockwise,
298 &b_stop_auto_changing_direction,
299 &b_auto_change_direction_anti_clockwise,
300 &b_flip_direction,
301 &b_make_random_color,
302 &ol_justification,
303 &cb_resize_separation,
304 &ol_key_note,
305 &b_add_remove_slits,
306 &b_select_wreckers,
307 &b_select_healers,
308 &b_switch_ball_type,
309 &b_toggle_wreckers,
310 &b_toggle_healers,
311 &b_toggle_bouncers,
312 &sp_mondrian_change_slit_size,
313 &b_remove_slits_on_edge,
314 &b_toggle_slit_anim,
315 &cb_mondrian_auto_adjust_voices,
316 &sp_mondrian_change_vol,
317 &cb_draw_boxes,
318 &cb_fill_boxes,
319 &cb_draw_notes,
320 &cb_label_notes,
321 &ol_ball_types,
322 &ol_split_types_h,
323 &ol_split_types_v,
324 &sp_mondrian_num_boxes,
325 &b_make_note_grid,
326 &b_make_nxn_grid,
327 &b_delete_all_boxes,
328 &cb_mkb_voice,
329 &cb_mkb_misc,
330 &b_select_launchers,
331 &seloncre,
332 &b_freeze_drones,
333 &b_thaw_drones,
334 &sp_dam_depth,
335 &sp_dfm_depth,
336 &sp_dam_bpm,
337 &sp_dfm_bpm,
338 &b_scale_drones,
339 &b_rotate_drones,
340 &ol_selection_targets,
341 &sp_mondrian_change_slit_anim_time,
342 &cb_mark_segments,
343 &cb_auto_split_box,
344 &cb_auto_delete_box,
345 &sp_auto_split_time,
346 &sp_auto_delete_time,
347 &ol_auto_pick_box_split,
348 &ol_auto_split_at,
349 &ol_auto_split_orient,
350 &ol_auto_pick_box_delete,
351 &sp_min_split_size,
352 &cb_speed,
353 &cb_turn,
354 &cb_teleport,
355 &sp_turn_every,
356 &sp_turn_min,
357 &sp_turn_max,
358 &sp_speed_every,
359 &sp_speed_min,
360 &sp_speed_max,
361 &sp_max_speed,
362 &sp_tel_every,
363 &sp_tel_radius,
364 &cb_draw_ball_position,
365 &cb_draw_ball_heading,
366 &cb_draw_ball_trails,
367 &l_draw_ball,
368 &cb_turn_sync,
369 &cb_speed_sync,
370 &sp_clone_every,
371 &sp_max_clones,
372 &sp_clone_offset,
373 &sp_max_balls,
374 &cb_clone,
375 &cb_clone_can_clone,
376 &ol_browse_balls,
377 &cb_mon_tools,
378 &cb_mon_parameters,
379 &cb_mon_ballops,
380 &cb_mon_boxops,
381 &cb_mon_misc,
382 &cb_transform,
383 &sp_transform_every,
384 &ol_bouncer,
385 &ol_healer,
386 &ol_wrecker,
387 &cb_label_hz_vol,
388 &il_binaural_drones,
389 &cb_binaural_drones_edit,
390 &bbd_select_all,
391 &bbd_select_none,
392 &bbd_invert_select,
393 &bbd_delete,
394 &bbd_sync,
395 &lf_pitch_fade_time,
396 &lf_modulation_amount,
397 &bd_modulate_up,
398 &bd_modulate_down,
399 &bbd_modulate,
400 &bbd_select2,
401 &ol_select_what,
402 &ol_select_rule,
403 &bdf_value,
404 &lf_l,
405 &lf_r,
406 &lf_sep,
407 &lf_vol,
408 &ol_just,
409 &bbd_flip,
410 &b_adjust_board_height,
411 &b_adjust_range_left,
412 &b_adjust_range_right,
413 &b_adjust_range_both,
414 &sp_snap_left,
415 &sp_snap_right,
416 &ol_bounce_style,
417 &cb_mod_ran,
418 &sp_range,
419 &sp_ran_mod_width,
420 &sp_ran_mod_width_bpm,
421 &cb_mark_ran,
422 &l_ran_mod,
423 &b_rm_pause_resume,
424 &b_rm_start_all,
425 &b_rm_stop_all,
426 &b_rm_toggle,
427 &b_get_cur_ran,
428 &ol_snap_style,
429 &sp_ran_mod_height,
430 &sp_ran_mod_height_bpm,
431 &cb_mkb_ranges,
432 &l_adjust_range,
433 &l_adjust_height,
434 &b_adjust_range_height,
435 &dronearrow.shoulder.position,
436 &dronearrow.shoulder.width,
437 &l_drone_arrow,
438 &sp_default_width,
439 &sp_default_height,
440 &b_change_note_left,
441 &b_change_note_right,
442 &ol_change_note_style,
443 &ol_set_unset_toggle,
444 &b_set,
445 &b_unset,
446 &b_toggle,
447 &sp_browse_drone,
448 &ol_drone_order,
449 &l_drone_order,
450 &ol_mesh_point,
451 &f_mesh_xy,
452 &cb_sync_rows_cols,
453 &sp_mesh_dur,
454 &b_flip_rows_cols,
455 &cb_overlay,
456 &dp_numdrones,
457 &dp_bpm1,
458 &dp_orient,
459 &b_swap_curves,
460 &cb_pitch_dis,
461 &cb_vol_dis,
462 &sp_lev_sz,
463 &ol_change_note,
464 &b_change_note_both,
465 &sp_drone_master_vol,
466 &l_use_drone_pend,
467 &sp_drones_per_pend,
468 &l_apply_to,
469 &cb_am_bpm,
470 &cb_fm_bpm,
471 &b_set_to_mesh_rows,
472 &b_set_to_mesh_cols,
473 &ol_drone_is,
474 &b_ball_trig,
475 &ol_fixed,
476 &cb_draw_mesh,
477 &lf_conn_steps,
478 &s_red_min,
479 &s_green_min,
480 &s_blue_min,
481 &s_red_max,
482 &s_green_max,
483 &s_blue_max,
484 &cb_conn_wrap,
485 &separators.main,
486 &separators.dp0,
487 &cb_modulation,
488 &cb_motion,
489 &cb_visual,
490 &b_connect,
491 &b_disconnect,
492 &ol_color,
493 &separators.dp1,
494 &b_abort_octave_shift,
495 &sp_stiff,
496 &b_arrow_reset,
497 &b_mute,
498 &b_unmute,
499 &gabt,
500 &sp_drone_vol,
501 &drone2noise,
502 &noise2drone,
503 &b_set_xform_center,
504 &autorotate.title,
505 &autorotate.whichl,
506 &autorotate.start,
507 &autorotate.stop,
508 &autorotate.toggle,
509 &autorotate.clockwise,
510 &autorotate.anticlockwise,
511 &autorotate.rpm,
512 &cb_defaults,
513 &sp_wand_dist,
514 &ol_drones_are,
515 &riset,
516 &fallt,
517 &lifetime,
518 &mortalize,
519 &reincarnate,
520 &immortalize,
521 &diram.vert,
522 &diram.hor,
523 &diram.vel,
524 &diram.accel,
525 &dirfm.vert,
526 &dirfm.hor,
527 &dirfm.vel,
528 &dirfm.accel,
529 &diram.lbl,
530 &dirfm.lbl,
531 &cb_chuck,
532 &chuck,
533 &chspeed,
534 &chflip,
535 &chtog,
536 &chlen,
537 &chapt,
538 &chtrail,
539 &handlesize,
540 &sva.lbl,
541 &sva.whats,
542 &sva.neg,
543 &sva.zero,
544 &sva.vert,
545 &sva.hor,
546 &sva.vel,
547 &sva.accel,
548 &autorotate.autoflip.lbl,
549 &autorotate.autoflip.angle,
550 &autorotate.autoflip.set,
551 &autorotate.autoflip.unset,
552 &autorotate.autoflip.toggle,
553 &dva.whichl,\
554 &dva.ldir,\
555 &dva.odir,\
556 &dva.neg,\
557 &dva.randomize,\
558 &dva.mag,\
559 &dva.clockwise,\
560 &dva.anticlockwise,\
561 &choutline,
562 &chautoresettrails,
563 &anchored,
564 &trailsize,
565 &dronearrow.neck,
566 &dronearrow.cap,
567 &dronearrow.decap,
568 &autorotate.deg,
569 &autorotate.tps,
570 &autorotate.mov,
571 &autorotate.smooth,
572 &autorotate.tick,
573 &dronearrowdefaults.lbl,
574 &dronearrowdefaults.neck,
575 &dronearrowdefaults.shoulder.position,
576 &dronearrowdefaults.shoulder.width,
577 &dronearrowdefaults.cap,
578 &dronearrowdefaults.arrow,
579 &trackcon,
580 &dva.autorotate.cb,
581 &dva.autorotate.mov,
582 &dva.autorotate.dir,
583 &dva.autorotate.rpm,
584 &dva.autorotate.dps,
585 &dva.autorotate.tps,
586 &dva.autoflip.cb,
587 &dva.autoflip.deg,
588 &velgt0,
589 &accelgt0,
590 &dva.sync,
591 // next item here
592 };
593
594 int ii = 0;
595 for (int i = 0; i < NUM_INSTRUMENTS; ++i) {
596 button* ei = inst_ed[i];
597 ei->id = i;
598 #ifndef __WIDGET_MOVE__
599 ei->set_listener (&insl);
600 #endif
601 items[ii++] = ei;
602 }
603 for (int i = NUM_INSTRUMENTS; i < n_inst_ed; ++i) {
604 button* ei = inst_ed[i];
605 ei->id = i + 1; // as 0 is instrument
606 #ifndef __WIDGET_MOVE__
607 ei->set_listener (&edl);
608 #endif
609 items[ii++] = ei;
610 }
611
612 for (int i = n_inst_ed, j = 0; i < nitems; ++i) items[ii++] = mi[j++];
613
614 dlog << "+++ Items list setup +++ " << endl;
615
616 #ifndef __WIDGET_MOVE__
617 {
618 button* btns [] = {&b_set_to_mesh_rows, &b_set_to_mesh_cols, &b_set, &b_unset, &b_toggle};
619 click_listener* cl [] = {&stmrl, &stmcl, &sutl, &sutl, &sutl};
620 checkbutton* cbtns [] = {&cb_am_bpm, &cb_fm_bpm};
621 state_listener* sl [] = {&abl, &fbl};
622 for (int i = 0; i < 5; ++i) btns[i]->set_listener (cl[i]);
623 for (int i = 0; i < 2; ++i) cbtns[i]->set_listener (sl[i]);
624
625 }
626 #endif
627
628 // tabs
629 num_tabs = 0;
630 last_tab = next_tab = cur_tab = 0;
631 next_tab_instr = 0;
632 checkbutton* cb_tabs [] = {
633 &cb_file,
634 &cb_instrument,
635 &cb_editors,
636 &cb_mkb_voice,
637 &cb_mkb_drone_tools,
638 &cb_mkb_drone_params,
639 &cb_mkb_ranges,
640 &cb_mkb_misc,
641 &cb_ed_tools,
642 &cb_mon_tools,
643 &cb_mon_parameters,
644 &cb_mon_ballops,
645 &cb_mon_boxops,
646 &cb_mon_misc,
647 &cb_binaural_drones_tools,
648 &cb_binaural_drones_edit,
649 };
650
651 static const char* const cb_tab_lbls [] = {
652 "File",
653 "Instrument",
654 "Editors",
655 "Voice",
656 "Drone Tools",
657 "Drone Params",
658 "Ranges",
659 "Misc",
660 "Tools",
661 "Tools",
662 "Params",
663 "Ball Ops",
664 "Box Ops",
665 "Misc",
666 "Create",
667 "Edit"
668 };
669
670 for (int i = 0; i < 16; ++i) {
671 checkbutton* ci = cb_tabs[i];
672 ci->set_text (cb_tab_lbls[i]);
673 ci->set_listener (this);
674 }
675
676 widget* wfile [] = {
677 &b_exit_din,
678 &cb_record,
679 &b_clear_record,
680 &b_save,
681 &lf_file,
682 &b_turn_off_ui,
683 &cb_scope,
684 &sp_scope_height,
685 &sp_scope_samples
686 };
687
688 #ifndef __WIDGET_MOVE__
689 cb_record.set_listener (&recl);
690 b_clear_record.set_listener (&recl);
691 b_save.set_listener (&recl);
692 b_exit_din.set_listener (&miscl);
693 b_turn_off_ui.set_listener (&miscl);
694 lf_file.fld.typing_lsnr = &recl;
695 #endif
696
697 lf_file.fld.set_text ("din.wav");
698 lf_file.lbl.set_text ("File on Desktop?");
699
700 widget* winst [] = {
701 &b_microtonal_keyboard,
702 &b_keyboard_keyboard,
703 &b_mondrian,
704 &b_binaural_drones
705 };
706
707 widget* weds [] = {
708 &b_microtonal_keyboard_waveform,
709 &b_drone_waveform,
710 &b_drone_modulation,
711 &b_voice_modulation,
712 &b_range_modulation,
713 &b_range_width_height,
714 &b_range_pitch_vol,
715 &b_gater,
716 &b_keyboard_keyboard_waveform,
717 &b_attack,
718 &b_decay,
719 &b_midi_velocity,
720 &b_mondrian_waveform,
721 &b_mondrian_attack,
722 &b_mondrian_decay,
723 &b_binaural_drones_waveform,
724 &b_delays,
725 &b_octave_shift,
726 &b_compressor,
727 &b_morse_code,
728 &b_point_modulation,
729 &b_noise_interpolator,
730 &b_drone_pend,
731 };
732
733 widget* wvoice [] = {
734 &sp_voice_volume,
735 &b_record_phrase,
736 &b_clear_phrases,
737 &s_phrase_position,
738 &l_phrase_position,
739 &sp_am_depth,
740 &sp_fm_depth,
741 &sp_am_bpm,
742 &sp_fm_bpm,
743 &ol_am_style,
744 &ol_fm_style,
745 };
746
747 #ifndef __WIDGET_MOVE__
748 for (int i = 1; i < 3; ++i) static_cast<button*>(wvoice[i])->set_listener (&pcl); // phrase commands listener
749 #endif
750
751 widget* wdrone_tools [] = {
752 &ol_add_wand,
753 &b_delete_drones,
754 &b_select_all_drones,
755 &b_invert_drone_selection,
756 &b_orbit_selected_drones,
757 &b_select_attractees,
758 &b_select_attractors,
759 &b_launch_drones,
760 &b_stop_launching_drones,
761 &b_track_drones,
762 &b_select_tracked_drones,
763 &b_set_targets,
764 &b_clear_targets,
765 &b_select_launchers,
766 &b_freeze_drones,
767 &b_thaw_drones,
768 &b_flip_rows_cols,
769 &ol_create_this,
770 &sp_mesh_rows,
771 &sp_mesh_cols,
772 &sp_browse_drone,
773 &ol_drone_order,
774 &l_drone_order,
775 &cb_sync_rows_cols,
776 &sp_mesh_dur,
777 &dp_numdrones,
778 &dp_bpm1,
779 &dp_orient,
780 &l_use_drone_pend,
781 &cb_am_bpm,
782 &cb_fm_bpm,
783 &sp_drones_per_pend,
784 &l_apply_to,
785 &b_set_to_mesh_rows,
786 &b_set_to_mesh_cols,
787 &b_move_drones,
788 &b_scale_drones,
789 &b_rotate_drones,
790 &b_connect,
791 &b_disconnect,
792 &lf_conn_steps,
793 &cb_conn_wrap,
794 &b_mute,
795 &b_unmute,
796 &gabt,
797 &drone2noise,
798 &noise2drone,
799 &b_set_xform_center,
800 &mortalize,
801 &reincarnate,
802 &immortalize,
803 &chuck,
804 &trackcon,
805 &balloon,
806 &b_set,\
807 &b_unset,\
808 &b_toggle,\
809 &ol_set_unset_toggle,\
810 };
811
812 LISTEN(ol_add_wand,&awdl)
813 LISTEN(ol_add_wand.option,&dcl)
814 LISTEN(ol_drones_are, &darl)
815
816 #ifndef __WIDGET_MOVE__
817 LISTEN(b_scale_drones,&bsdl)
818 LISTEN(b_rotate_drones,&brdl)
819 LISTEN(b_move_drones,&bmdl)
820 LISTEN(balloon,&dugl)
821 LISTEN(b_mute,&mul)
822 LISTEN(b_unmute,&umul)
823 LISTEN(drone2noise,&d2nl)
824 LISTEN(noise2drone,&n2dl)
825 LISTEN(seloncre,&dcl);
826 LISTEN(cb_conn_wrap, &wrapl)
827 LISTEN(b_connect, &bconl)
828 LISTEN(b_disconnect, &bdconl)
829 LISTEN(b_set_xform_center, &xcl);
830 LISTEN(mortalize,&morl)
831 LISTEN(immortalize,&immorl)
832 LISTEN(reincarnate,&reinl)
833 LISTEN(chuck, &chl)
834 LISTEN(chflip,&flpl)
835 LISTEN(chtog,&ctogl)
836 LISTEN(chautoresettrails,&aurl)
837 #endif
838
839 sp_stiff.set ("Connection stiffness", 0.001f, 0.0f, 1.0f, &stiffl);
840 gabt.set (0.1f, 0, MILLION, &gabtl);
841 gabt.set_text ("In", SECONDS);
842 sp_drones_per_pend.set ("Drones Per Pendulum", 1, 2, MILLION, &dppl, 0);
843 l_use_drone_pend.set_text ("Drone Pendulum's parameters?");
844 l_apply_to.set_text ("Apply to");
845
846 DECL_DRONE_PARAMS
847
848 ol_drone_is.set_listener (this);
849 diram.setup ("Set AM direction to: ");
850 dirfm.setup ("Set FM direction to: ");
851 riset.set ("Rise time", 0.1f, 0, MILLION, &rl, 0);
852 fallt.set ("Fall time", 0.1f, 0, MILLION, &fl, 0);
853 sp_wand_dist.set ("Wand distance", 1, 0, MILLION, &wandl);
854
855 autorotate.setup ();
856
857 sva.setup ();
858 dva.setup ();
859
860 anchored.set_listener (&ancl);
861
862 chspeed.set ("Speed", 1.0f, &spdl); chspeed.limits = 0;
863 chlen.set ("Length", 1.0f, &lenl);
864 chapt.set ("Angle per turn", 0.1f, &apfl); chapt.limits = 0;
865 chtrail.set ("Trail length", 10000, &chtll);
866
867 handlesize.set ("Handle size", 1, 0, MILLION, &handl);
868 trailsize.set ("Trail size", 1, 0, MILLION, &trll);
869 lifetime.set ("Lifetime", 0.1f, 0, MILLION, &lifel, 0);
870
871 #ifndef __WIDGET_MOVE__
872 for (int i = 1; i < 17; ++i) dynamic_cast<button*>(wdrone_tools[i])->set_listener (&dcl);
873 for (int i = 0, j = DRONE_PARAMS_N - 1; i < 4; ++i) dynamic_cast<checkbutton*>(wdrone_params[j--])->set_listener (&dcl);
874 #endif
875
876 static const char* txt [] = {"AM Depth", "FM Depth", "AM BPM", "FM BPM"};
877 spinner<float>* spn [] = {&sp_am_depth, &sp_fm_depth, &sp_am_bpm, &sp_fm_bpm};
878 change_listener<field>* vlis [] = {&amdl, &fmdl, &ambpml, &fmbpml};
879 spinner<float>* dspn [] = {&sp_dam_depth, &sp_dfm_depth, &sp_dam_bpm, &sp_dfm_bpm};
880 change_listener<field>* dlis [] = {&damdl, &dfmdl, &dambpml, &dfmbpml};
881
882 for (int i = 0; i < 4; ++i) {
883 const char* txti = txt[i];
884 spinner<float>* dspni = dspn[i];
885 dspni->set (txti, 1.0f, dlis[i]);
886 dspni->orient = mouse_slider_listener::Y;
887 spinner<float>* spni = spn[i];
888 spni->set_text (txti);
889 spni->set_listener (vlis[i]);
890 spni->orient = mouse_slider_listener::Y;
891 }
892
893 for (int i = 1; i < 4; ++i) spn[i]->set_delta (1.0f);
894 sp_am_depth.set_delta (din0.am_delta.depth);
895 sp_am_bpm.set_limits (0, MILLION);
896 sp_fm_bpm.set_limits (0, MILLION);
897
898 widget* wranges [] = {
899 &b_selected_to_all,
900 &b_default_to_selected,
901 &b_default_to_all,
902 &b_adjust_range_left,
903 &b_adjust_range_right,
904 &b_adjust_range_both,
905 &b_adjust_range_height,
906 &b_adjust_board_height,
907 &b_rm_start_all,
908 &b_rm_stop_all,
909 &b_rm_toggle,
910 &b_rm_pause_resume,
911 &b_get_cur_ran,
912 &cb_mod_ran,
913 &cb_mark_ran,
914 &sp_ran_mod_width,
915 &sp_ran_mod_width_bpm,
916 &sp_ran_mod_height,
917 &sp_ran_mod_height_bpm,
918 &sp_range,
919 &l_ran_mod,
920 &l_adjust_height,
921 &l_adjust_range,
922 &ol_set_range,
923 &sp_default_width,
924 &sp_default_height,
925 &b_change_note_left,
926 &b_change_note_right,
927 &ol_change_note_style,
928 &ol_change_note,
929 &b_change_note_both,
930 &ol_fixed,
931 &sp_snap_left,
932 &sp_snap_right,
933 &ol_snap_style,
934 };
935
936 #ifndef __WIDGET_MOVE__
937 for (int i = 0; i < 3; ++i) static_cast<button*>(wranges[i])->set_listener (&sral);
938 for (int i = 3; i < 6; ++i) static_cast<button*>(wranges[i])->set_listener (&rwl);
939 b_adjust_range_height.set_listener (&rhl);
940 b_adjust_board_height.set_listener (&bhl);
941 for (int i = 8; i < 13; ++i) static_cast<button*>(wranges[i])->set_listener (&rml);
942 cb_mod_ran.set_listener (&rml);
943 cb_mark_ran.set_listener (&rml);
944 b_change_note_left.set_listener (&cnl);
945 b_change_note_right.set_listener (&cnr);
946 b_change_note_both.set_listener (&cnb);
947 #endif
948
949 ol_change_note.set_listener (&cnol);
950 ol_change_note_style.set_listener (&cnsl);
951
952 widget* wmisc [] = {
953 &l_octave_shift,
954 &ab_octave_down,
955 &ab_octave_up,
956 &sp_octave_shift_bpm,
957 &l_gater,
958 &sp_gater_bpm,
959 &ol_gater_style,
960 &b_key_to_pitch_at_cursor,
961 &l_tap_bpm,
962 &td_tap_display,
963 &l_tap_bpm_value,
964 &cb_am,
965 &cb_fm,
966 &cb_gater,
967 &cb_octave_shift,
968 &cb_auto_reset,
969 &cb_pitch_dis,
970 &cb_vol_dis,
971 &sp_lev_sz,
972 &b_abort_octave_shift,
973 };
974
975 #ifndef __WIDGET_MOVE__
976 LISTEN(b_abort_octave_shift, &aosl)
977 cb_draw_mesh.set_listener (&dml);
978 cb_pitch_dis.set_listener (&pvdl);
979 cb_vol_dis.set_listener (&pvdl);
980 #endif
981
982 sp_lev_sz.set ("Level size", 1, 1, MILLION, &pvdl);
983
984 widget* wetools [] = { // curve editors tools
985 &abe_left,
986 &abe_right,
987 &abe_up,
988 &abe_down,
989 &pb_zoom_in,
990 &mb_zoom_out,
991 &l_snap,
992 &cb_snapx,
993 &cb_snapy,
994 &cb_snapboth,
995 &cb_snapnone,
996 &b_pick_curve,
997 &b_insert_vertex,
998 &b_delete_vertex,
999 &b_draw_replacement_curve,
1000 &b_undo,
1001 &b_redo,
1002 &b_copy,
1003 &b_paste,
1004 &b_swap_curves,
1005 &b_fold_tangents,
1006 &b_unfold_tangents,
1007 &ol_mirror,
1008 &cb_selection_only,
1009 &ol_vertices_carry_tangents,
1010 &ol_mirror_tangents,
1011 &lf_curve_name,
1012 &sp_curve_limit,
1013 &ol_curve_style,
1014 &l_library,
1015 &abl_left,
1016 &abl_right,
1017 &b_add_curve,
1018 &b_replace_curve,
1019 &b_delete_curve,
1020 &l_capture,
1021 &b_start_capture,
1022 &b_assign_capture,
1023 &cb_draw_curve,
1024 &cb_label_vertices,
1025 &cb_mark_segments,
1026 &cb_show_waveform_samples,
1027 &sp_waveform_hz,
1028 &sp_waveform_periods,
1029 &sp_curve_rpm,
1030 &b_stop_rotating,
1031 &cb_overlay,
1032 &b_swap_curves
1033 };
1034
1035 widget* wmon [] = { // mondrian tools
1036 &b_add_balls,
1037 &b_move_selected_balls,
1038 &b_delete_selected_targets,
1039 &b_delete_all_targets,
1040 &b_select_all_targets,
1041 &b_invert_selected_targets,
1042 &b_split_horizontal,
1043 &b_split_vertical,
1044 &b_delete_box,
1045 &b_select_targets_in_box,
1046 &b_freeze_balls,
1047 &b_thaw_balls,
1048 &b_clear_modulations,
1049 &b_modulate_balls_up,
1050 &b_modulate_balls_down,
1051 &b_auto_change_direction_clockwise,
1052 &b_auto_change_direction_anti_clockwise,
1053 &b_stop_auto_changing_direction,
1054 &b_flip_direction,
1055 &b_make_random_color,
1056 &b_add_remove_slits,
1057 &b_select_wreckers,
1058 &b_select_healers,
1059 &b_switch_ball_type,
1060 &b_toggle_wreckers,
1061 &b_toggle_healers,
1062 &b_toggle_bouncers,
1063 &b_remove_slits_on_edge,
1064 &b_toggle_slit_anim,
1065 &b_make_note_grid,
1066 &b_make_nxn_grid,
1067 &b_delete_all_boxes,
1068 &b_ball_trig,
1069 &ol_ball_types,
1070 &ol_split_types_h,
1071 &ol_split_types_v,
1072 &sp_mondrian_num_boxes,
1073 &ol_selection_targets,
1074 };
1075
1076
1077 arrow_button* mnav[] = {&abm_left, &abm_down, &abm_right, &abm_up};
1078 int mdirs [] = {arrow_button::left, arrow_button::down, arrow_button::right, arrow_button::up};
1079 for (int i = 0; i < 4; ++i) {
1080 arrow_button* ab = mnav[i];
1081 ab->set_dir (mdirs[i]);
1082 }
1083
1084 widget* wmon_pars [] = { // mondrian parameters
1085 &l_octave_shift,
1086 &ab_octave_down,
1087 &ab_octave_up,
1088 &sp_octave_shift_bpm,
1089 &b_abort_octave_shift,
1090 &sp_mondrian_min_voices,
1091 &sp_mondrian_change_attack_time,
1092 &sp_mondrian_change_decay_time,
1093 &sp_mondrian_change_speed,
1094 &sp_mondrian_change_dir,
1095 &sp_mondrian_change_trail_size,
1096 &sp_mondrian_change_note_poly_points,
1097 &sp_mondrian_change_note_poly_radius,
1098 &sp_mondrian_change_slit_size,
1099 &sp_mondrian_change_slit_anim_time,
1100 &cb_mondrian_auto_adjust_voices,
1101 &sp_mondrian_change_vol
1102 };
1103
1104 widget* wmon_misc [] = { // mondrian misc
1105 &l_draw_ball,
1106 &abm_left,
1107 &abm_right,
1108 &abm_up,
1109 &abm_down,
1110 &bm_zoom_in,
1111 &bm_zoom_out,
1112 &cb_draw_boxes,
1113 &cb_fill_boxes,
1114 &cb_draw_notes,
1115 &cb_label_notes,
1116 &cb_label_hz_vol,
1117 &cb_draw_ball_position,
1118 &cb_draw_ball_heading,
1119 &cb_draw_ball_trails
1120 };
1121
1122 widget* wmon_boxops [] = {
1123 &cb_auto_split_box,
1124 &cb_auto_delete_box,
1125 &sp_auto_split_time,
1126 &sp_auto_delete_time,
1127 &ol_auto_pick_box_split,
1128 &ol_auto_split_at,
1129 &ol_auto_split_orient,
1130 &ol_auto_pick_box_delete,
1131 &sp_min_split_size
1132 };
1133
1134 widget* wmon_ballops [] = {
1135 &cb_turn, &cb_speed, &cb_teleport, &cb_clone, &sp_turn_every, &sp_turn_min, &sp_turn_max,
1136 &sp_speed_every, &sp_speed_min, &sp_speed_max, &sp_max_speed, &sp_tel_every, &sp_tel_radius,
1137 &cb_turn_sync, &cb_speed_sync, &sp_clone_every, &sp_max_clones, &sp_clone_offset, &sp_max_balls,
1138 &cb_clone_can_clone, &ol_browse_balls,
1139 &cb_transform, &sp_transform_every, &ol_bouncer, &ol_healer, &ol_wrecker,
1140 };
1141
1142 spinner<float>* bospn [] = {&sp_turn_every, &sp_speed_every, &sp_tel_every, &sp_clone_every, &sp_transform_every};
1143 float bodta [] = {0.01f, 0.01f, 1.0f, 1.0f, 1.0f};
1144 for (int i = 0; i < ball_op::NUM_OPS; ++i) {
1145 spinner<float>* spni = bospn[i];
1146 spni->set_text ("Every", SECONDS);
1147 spni->set (bodta[i], 0.0f, MILLION, &bolis);
1148 }
1149 sp_turn_min.set_text ("Clockwise Max", DEGREES);
1150 sp_turn_min.set (1, 0, MILLION, &bolis);
1151 sp_turn_max.set_text ("Anti-clockwise Max", DEGREES);
1152 sp_turn_max.set (1, 0, MILLION, &bolis);
1153 sp_speed_min.set ("Brake", 0.1f, 0, MILLION, &bolis);
1154 sp_speed_max.set ("Accelerate", 0.1f, 0, MILLION, &bolis);
1155 sp_max_speed.set ("Max speed", 1, 0, MILLION, &bolis);
1156 sp_tel_radius.set ("Max distance", 1, 0, MILLION, &bolis);
1157 sp_clone_offset.set ("Offset", 1.0f, 0, MILLION, &bolis);
1158 sp_max_clones.set ("Max clones", 1, 1, MILLION, &bolis);
1159 sp_max_balls.set ("Max balls", 1, 0, MILLION,&bolis);
1160
1161 #ifndef __WIDGET_MOVE__
1162 checkbutton* bocbn [] = {&cb_turn, &cb_speed, &cb_teleport, &cb_clone, &cb_transform};
1163 for (int i = 0; i < ball_op::NUM_OPS; ++i) bocbn[i]->set_listener (&bolis);
1164 for (int i = 1; i < 7; ++i) static_cast<button*>(wmon_misc[i])->set_listener (&monl);
1165 for (int i = 7; i < 15; ++i) static_cast<checkbutton*>(wmon_misc[i])->set_listener (&monl);
1166 for (int i = 0; i < 33; ++i) static_cast<button*>(wmon[i])->set_listener (&monl);
1167 for (int i = 0; i < 6; ++i) static_cast<button*>(wetools[i])->set_listener (&pzl);
1168 for (int i = 7; i < 11; ++i) static_cast<checkbutton*>(wetools[i])->set_listener (&snl);
1169
1170 button* crvops [] = {
1171 &b_pick_curve,
1172 &b_insert_vertex,
1173 &b_delete_vertex,
1174 &b_draw_replacement_curve,
1175 &b_fold_tangents,
1176 &b_unfold_tangents,
1177 &ol_mirror.option,
1178 &b_copy,
1179 &b_paste,
1180 &b_swap_curves,
1181 &b_undo,
1182 &b_redo,
1183 &abl_left,
1184 &abl_right,
1185 &b_add_curve,
1186 &b_replace_curve,
1187 &b_delete_curve,
1188 &b_start_capture,
1189 &b_assign_capture,
1190 };
1191
1192 for (int i = 0; i < 19; ++i) crvops[i]->set_listener (&col);
1193
1194 #endif
1195
1196 options_list* oll [] = {&ol_ball_types, &ol_split_types_h, &ol_split_types_v, &ol_selection_targets,
1197 &ol_auto_pick_box_split, &ol_auto_split_at, &ol_auto_split_orient, &ol_auto_pick_box_delete};
1198 for (int i = 0; i < 8; ++i) {
1199 options_list* oli = oll[i];
1200 oli->set_listener (&monl);
1201 }
1202 ol_split_types_h.set_text (mondrian_listener::split_types[monl.hsplit]);
1203 ol_split_types_v.set_text (mondrian_listener::split_types[monl.vsplit]);
1204 ol_selection_targets.set_text (mondrian_listener::selection_targets[mondrian0.sel_tar]);
1205 ol_browse_balls.set_listener (&bolis);
1206
1207 b_undo.click_repeat = b_redo.click_repeat = 1;
1208 abl_left.click_repeat = abl_right.click_repeat = 1;
1209
1210 ol_mirror.set_listener (this);
1211 lf_curve_name.set_listener (&col);
1212 #ifndef __WIDGET_MOVE__
1213 cb_label_vertices.set_listener (&col);
1214 cb_mark_segments.set_listener (&col);
1215 cb_overlay.set_listener (&col);
1216 cb_draw_curve.set_listener (&col);
1217 #endif
1218
1219 widget* wbd [] = { // binaural drones
1220 &b_create_binaurals_on_notes,
1221 &b_create_binaurals_from_pitch,
1222 &sp_bd_separation,
1223 &sp_bd_pairs,
1224 &lf_bd_start_pitch,
1225 &lf_bd_spacing,
1226 &ol_justification,
1227 &ol_key_note,
1228 &cb_resize_separation,
1229 &cb_close_octave,
1230 };
1231
1232 widget* wbde [] = {
1233 &bbd_select_all,
1234 &bbd_select_none,
1235 &bbd_invert_select,
1236 &bbd_delete,
1237 &bbd_sync,
1238 &bbd_select2,
1239 &bd_modulate_up,
1240 &bd_modulate_down,
1241 &bbd_modulate,
1242 &bbd_flip,
1243 &il_binaural_drones,
1244 &lf_vol_fade_time,
1245 &lf_master_volume,
1246 &lf_pitch_fade_time,
1247 &lf_modulation_amount,
1248 &ol_select_what,
1249 &ol_select_rule,
1250 &bdf_value,
1251 &lf_l,
1252 &lf_r,
1253 &lf_sep,
1254 &lf_vol,
1255 &ol_just
1256 };
1257
1258 il_binaural_drones.sel_lis = &bdl;
1259 lf_sep.fld.set_text (0.0f);
1260 ol_just.set_text (binaural_drones_listener::justs[binaural_drone::CENTER]);
1261 ol_just.set_listener (&bdl);
1262
1263 bd_modulate_up.set_size (24);
1264 bd_modulate_down.set_size (24);
1265 bd_modulate_down.set_dir (arrow_button::left);
1266
1267 #ifndef __WIDGET_MOVE__
1268 for (int i = 0; i < 10; ++i) static_cast<button*>(wbde[i])->set_listener (&bdl);
1269 for (int i = 0; i < 2; ++i) static_cast<button*>(wbd[i])->set_listener (&bdl); // binaural drones commands
1270 cb_close_octave.set_listener (&bdl);
1271 cb_resize_separation.set_listener (&bdl);
1272 #endif
1273
1274 ol_select_what.set_listener (&bdl);
1275 ol_select_rule.set_listener (&bdl);
1276 ol_justification.set_listener (&bdl);
1277 ol_key_note.set_listener (&bdl);
1278
1279 label_field* lfb [] = {
1280 &lf_bd_start_pitch, &lf_bd_spacing, &lf_master_volume, &lf_vol_fade_time,
1281 &lf_pitch_fade_time, &lf_modulation_amount, &lf_l, &lf_r, &lf_sep, &lf_vol
1282 };
1283 string lfbs [] = {
1284 "Start Pitch (Hz)", "Spacing (Hz)", "Master volume (%)", "Volume fade time (secs)",
1285 "Pitch fade time (secs)", "Amount", "L (Hz)", "R (Hz)", "Separation (Hz)", "Volume (%)"
1286 };
1287 for (int i = 0; i < 10; ++i) {
1288 label_field* li = lfb[i];
1289 li->set_label (lfbs[i]);
1290 li->set_listener (&bdl);
1291 }
1292
1293 sp_bd_separation.set ("Separation (Hz)", 1.0f, 0.0f, MILLION, 0, 0);
1294 sp_bd_separation.set_value (1.0f);
1295 sp_bd_separation.orient = mouse_slider_listener::NONE;
1296
1297 sp_bd_pairs.set ("Number of Pairs", 1, 1, MILLION, 0, 0);
1298 sp_bd_pairs.set_value (1);
1299 sp_bd_pairs.orient = mouse_slider_listener::NONE;
1300
1301
1302 for (int i = 0; i < 23; ++i) {
1303 editors.push_back (weds[i]);
1304 //weds[i]->set_moveable(1);
1305 }
1306
1307 widget** wmap [] = {
1308 wfile,
1309 winst,
1310 weds,
1311 wvoice,
1312 wdrone_tools,
1313 wdrone_params,
1314 wranges,
1315 wmisc,
1316 wetools,
1317 wmon,
1318 wmon_pars,
1319 wmon_ballops,
1320 wmon_boxops,
1321 wmon_misc,
1322 wbd,
1323 wbde
1324 };
1325 int numw [] = {
1326 9,
1327 4,
1328 23,
1329 11,
1330 58,
1331 DRONE_PARAMS_N,
1332 35,
1333 20,
1334 47,
1335 38,
1336 17,
1337 26,
1338 9,
1339 15,
1340 10,
1341 23
1342 };
1343
1344 lf_conn_steps.set_label ("Steps");
1345 LISTEN(lf_conn_steps, &stepsl)
1346 lf_conn_steps.fld.typing_lsnr = &stepsl;
1347 lf_conn_steps.fld.expr = 0;
1348
1349 DECL_COLOR_SLIDERS
1350 color clrs [] = {color(1.0f, 0.0f, 0.0f), color(0.0f, 1.0f, 0.0f), color(0.0f, 0.0f, 1.0f),
1351 color(1.0f, 0.0f, 0.0f), color(0.0f, 1.0f, 0.0f), color(0.0f, 0.0f, 1.0f)};
1352
1353 float svals [] = {0.1, 0.1, 0.1, 1, 1, 1};
1354 for (int i = 0; i < COLOR_SLIDERS_M; ++i) {
1355 slider<float>& si = dynamic_cast<slider<float>&>(*slrs [i]);
1356 si.set_width_height (128, si.extents.height);
1357 color& ci = clrs [i];
1358 si.set_color (ci.r, ci.g, ci.b);
1359 si.set_limits (0.0f, 1.0f);
1360 #ifndef __WIDGET_MOVE__
1361 si.set_listener (&cscl, &cssl);
1362 #endif
1363 si.set_val (svals[i]);
1364 }
1365
1366 colorer.schemes[0]=&gc_top;
1367 colorer.schemes[1]=&gc_bottom;
1368 colorer.schemes[2]=&gc_blend;
1369 colorer.schemes[3]=&gc_rand;
1370 colorer.i = colorer_t::RANDOM;
1371
1372 LISTEN(ol_color,&ocoll)
1373 LISTEN(ol_fixed,&fxl)
1374 LISTEN(ol_snap_style,&sdl);
1375
1376 separator* seps [] = {&separators.main, &separators.dp0, &separators.dp1};
1377 const char* sepsn [] = {"main", "dp0", "dp1"};
1378 for (int i = 0; i < 3; ++i) {
1379 separator& si = *seps[i];
1380 si.set_name (sepsn[i]);
1381 }
1382
1383 for (int i = 0; i < 16; ++i) {
1384 int n = numw[i];
1385 widget** wmi = wmap[i];
1386 vector<widget*>& vw = tab_members[cb_tabs[i]];
1387 for (int m = 0; m < n; ++m) {
1388 vw.push_back (wmi[m]);
1389 #ifdef __WIDGET_MOVE__
1390 wmi[m]->set_moveable(1); // to move item
1391 #endif
1392 }
1393 vw.push_back (&separators.main);
1394 }
1395
1396 sp_voice_volume.set ("Volume", 0.001f, -MILLION, MILLION, &vvl);
1397 sp_drone_master_vol.set ("Master volume", 0.001f, -MILLION, MILLION, &dmvol);
1398 sp_drone_vol.set ("Volume", 0.01f, -MILLION, MILLION, &dvol);
1399 sp_drone_vol.set_value (0.0f);
1400
1401 l_octave_shift.set_text ("Octave Shift");
1402 ab_octave_down.set_dir (arrow_button::left);
1403 ab_octave_up.set_dir (arrow_button::right);
1404
1405 #ifndef __WIDGET_MOVE__
1406 ab_octave_down.set_listener (&osl);
1407 ab_octave_up.set_listener (&osl);
1408 #endif
1409 int arrow_size = 24;
1410 ab_octave_up.set_size (arrow_size);
1411 ab_octave_down.set_size (arrow_size);
1412 sp_octave_shift_bpm.set ("BPM", 1, 0.0f, MILLION, &osl);
1413
1414 sp_gater_bpm.set ("BPM", 1, 0, MILLION, &gbl);
1415 ol_gater_style.set_text (" style = ");
1416 ol_gater_style.set_listener (&gater_style_lis);
1417
1418 l_gater.set_text ("Gater");
1419 l_gater.add_child (&sp_gater_bpm);
1420 l_gater.add_child (&ol_gater_style);
1421
1422 #ifdef __WIDGET_MOVE__
1423
1424 int wek [] = {7, 13, 2, 3, 6, 3, 3, 3, 2};
1425 for (int i = 0, j = 4, k = 0; i < 9; ++i) {
1426 k = wek[i];
1427 makehier (&wetools[j], k);
1428 j += k;
1429 }
1430
1431 widget* osn [] = {&l_octave_shift, &ab_octave_down, &ab_octave_up, &b_abort_octave_shift, &sp_octave_shift_bpm, 0};
1432 makefam (osn, 5);
1433
1434 widget* brs [] = {&ol_set_range, &b_default_to_selected, &b_default_to_all, &b_selected_to_all, 0};
1435 makehier (brs);
1436
1437 widget* aht [] = {&l_adjust_height, &b_adjust_range_height, &b_adjust_board_height, 0};
1438 makehier (aht);
1439
1440 widget* arb [] = {&l_adjust_range, &b_adjust_range_left, &b_adjust_range_right, &b_adjust_range_both, 0};
1441 makehier (arb);
1442
1443 widget* brm [] = {&l_ran_mod, &b_rm_pause_resume, &b_rm_start_all, &b_rm_stop_all, &b_rm_toggle, 0};
1444 makehier (brm);
1445
1446 widget* brc [] = {&ol_change_note, &b_change_note_left, &b_change_note_right, &b_change_note_both, &ol_change_note_style, 0};
1447 makehier (brc);
1448
1449 widget* wmmv [] = {&cb_modulation, &cb_visual, &cb_motion, &cb_chuck, &cb_defaults, 0};
1450 makehier (wmmv);
1451
1452 widget* dpw0 [] = {&cb_show_vel, &cb_show_accel, &cb_show_gravity, &cb_show_anchors, 0};
1453 makehier (dpw0);
1454
1455 widget* dpw3 [] = {&sp_dam_depth, &sp_dfm_depth, &sp_dam_bpm, &sp_dfm_bpm, 0};
1456 makehier (dpw3);
1457
1458 widget* dpw4 [] = {&sp_drones_per_min, &sp_drone_lifetime, &sp_orbit_insertion_time, 0};
1459 makehier (dpw4);
1460
1461 widget* dpw5 [] = {&sp_change_drone_trail_length, &sp_change_drone_handle_size, 0};
1462 makehier (dpw5);
1463
1464 widget* dpw6 [] = {&ol_set_unset_toggle, &b_toggle, &b_set, &b_unset, 0};
1465 makehier (dpw6);
1466
1467 widget* rmw [] = {&cb_mod_ran, &ol_fixed, &sp_ran_mod_width, &sp_ran_mod_width_bpm, &sp_ran_mod_height, &sp_ran_mod_height_bpm, 0};
1468 makehier (rmw);
1469
1470 widget* dpw [] = {&ol_create_this,&dp_orient,&dp_numdrones,&dp_bpm1, 0};
1471 makehier (dpw);
1472
1473 widget *rcw [] = {&ol_create_this, &sp_mesh_rows, &sp_mesh_cols, &cb_sync_rows_cols, &b_flip_rows_cols, 0};
1474 makehier (rcw, 5);
1475 widget* dow [] = {&l_drone_order, &ol_drone_order, &ol_mesh_point, &f_mesh_xy, 0};
1476 makehier (dow, 4);
1477 widget* mshw [] = {&sp_mesh_rows, &sp_mesh_dur, &l_use_drone_pend, 0,};
1478 makehier (mshw, 3);
1479 sp_mesh_rows.add_child (&l_drone_order);
1480 widget* dpp [] = {&sp_drones_per_pend, &b_set_to_mesh_rows, &b_set_to_mesh_cols, 0};
1481 makehier (dpp);
1482 widget* apt [] = {&l_apply_to, &cb_am_bpm, &cb_fm_bpm, 0};
1483 makehier (apt);
1484 widget* udp [] = {&l_use_drone_pend, &sp_drones_per_pend, &l_apply_to, 0};
1485 makehier (udp);
1486 widget* wsp [] = {&sp_snap_left, &sp_snap_right, &ol_snap_style, 0};
1487 makehier (wsp);
1488 widget* wda [] = {&l_drone_arrow, &b_arrow_reset, &dronearrow.neck, &dronearrow.shoulder.width, &dronearrow.shoulder.position, &dronearrow.cap, &dronearrow.decap, 0};
1489 makehier (wda);
1490 widget* wda2 [] = {
1491 &dronearrowdefaults.lbl,
1492 &dronearrowdefaults.arrow,
1493 &dronearrowdefaults.neck,
1494 &dronearrowdefaults.shoulder.width,
1495 &dronearrowdefaults.shoulder.position,
1496 &dronearrowdefaults.cap,
1497 0,
1498 };
1499 makehier (wda2);
1500 widget* wbo [] = {&sp_bounces, &sp_rebound, &ol_bounce_style, 0};
1501 makehier (wbo);
1502 widget* wconn [] = {&b_disconnect, &b_connect, &lf_conn_steps, &cb_conn_wrap, &trackcon, 0};
1503 makehier (wconn);
1504 widget* wsl [] = {&s_red_min, &s_red_max, &s_green_min, &s_green_max, &s_blue_min, &s_blue_max, &ol_color, 0};
1505 makehier (wsl);
1506
1507 {
1508 widget* w [] = {
1509 &b_select_all_drones,
1510 &b_invert_drone_selection,
1511 &b_select_attractees,
1512 &b_select_attractors,
1513 &b_select_launchers,
1514 &b_select_tracked_drones,
1515 &sp_browse_drone, 0,
1516 };
1517 makehier (w);
1518 }
1519
1520 {
1521 widget* w[] = {
1522 &ol_add_wand,
1523 &b_delete_drones,
1524 &b_move_drones,
1525 &b_scale_drones,
1526 &b_rotate_drones,
1527 &b_set_xform_center,
1528 &b_freeze_drones,
1529 &b_thaw_drones, 0,
1530 };
1531 makehier (w);
1532 }
1533
1534 {
1535 widget* w[] = {
1536 &b_mute,
1537 &b_unmute,
1538 &drone2noise,
1539 &noise2drone,
1540 &gabt, 0,
1541 };
1542 makehier (w);
1543 }
1544
1545 {
1546 widget* w[] = {
1547 &b_launch_drones,
1548 &b_stop_launching_drones,
1549 &b_orbit_selected_drones,
1550 &b_track_drones,
1551 &b_set_targets,
1552 &b_clear_targets, 0,
1553 };
1554 makehier (w);
1555 }
1556
1557 {
1558 widget* w[] = {&riset, &fallt, &lifetime, 0};
1559 makehier (w);
1560 }
1561
1562 {
1563 widget* w[] = {&mortalize, &reincarnate, &immortalize, 0};
1564 makehier (w);
1565 }
1566
1567 {
1568 widget* w[] = {&chflip, &chtog, &chspeed, &chlen, &chtrail, &chapt, &choutline, &chautoresettrails, 0};
1569 makehier (w);
1570 }
1571
1572 /*
1573 {
1574 widget* w[] = {
1575 };
1576 }
1577 */
1578
1579 #endif
1580
1581 sp_range.set ("Range", 1, &ranl);
1582 sp_range.draw_more = sp_range.variance.ui = 0;
1583
1584 const char* rms [] = {"Width", "BPM", "Height", "BPM"};
1585 spinner<float>* srm [] = {&sp_ran_mod_width, &sp_ran_mod_width_bpm, &sp_ran_mod_height, &sp_ran_mod_height_bpm};
1586 int srl [] = {-MILLION, 0, -MILLION, 0};
1587 int sro[] = {mouse_slider_listener::X, mouse_slider_listener::X, mouse_slider_listener::Y, mouse_slider_listener::Y};
1588 change_listener<field>* rlis[] = {&rmwl, &rmwbl, &rmhl, &rmhbl};
1589 for (int i = 0; i < 4; ++i) {
1590 spinner<float>* sp = srm[i];
1591 sp->set (rms[i], 1.0f, srl[i], MILLION, rlis[i]);
1592 sp->orient = sro[i];
1593 }
1594
1595 const char* rde [] = {"Default width", "Default height"};
1596 spinner<int>* sde [] = {&sp_default_width, &sp_default_height};
1597 int msd [] = {mouse_slider_listener::X, mouse_slider_listener::Y};
1598 for (int i = 0; i < 2; ++i) {
1599 spinner<int>& si = *sde[i];
1600 si.set (rde[i], 1, 0, MILLION, &rdel);
1601 si.orient = msd[i];
1602 si.draw_more = si.variance.ui = 0;
1603 }
1604
1605 // drones
1606 //
1607 sp_change_drone_trail_length.set ("Trail length", 1, &dtl);
1608 sp_change_drone_trail_length.set_value (0);
1609
1610 sp_change_drone_handle_size.set ("Handle size", 1, &dhsl);
1611 sp_change_drone_handle_size.set_value (0);
1612
1613 sp_change_drone_vel.set ("Velocity", 0.1f, -MILLION, +MILLION, &dvl);
1614 sp_change_drone_accel.set ("Acceleration", 0.01f, -MILLION, +MILLION, &dal);
1615
1616 sp_rotate_drone_vel.set ("Rotate velocity", 1.0f, &rdvl);
1617 sp_rotate_drone_vel.orient = mouse_slider_listener::X;
1618
1619 sp_drones_per_min.set ("Drones per minute", 1.0f, &dpml);
1620 sp_drone_lifetime.set ("Lifetime", 0.01f, &dlf);
1621
1622 sp_orbit_insertion_time.set ("Orbit insert time", 0.01f, &oil);
1623
1624 sp_browse_drone.set ("Browse drone", 1, &brwdl);
1625 sp_browse_drone.draw_more = sp_browse_drone.variance.ui = 0;
1626
1627 ol_create_this.set_listener (this);
1628
1629 dp_orient.set_listener (this);
1630 dp_numdrones.set ("Number of Drones", 1, 2, MILLION, this);
1631 dp_bpm1.set ("BPM", 1.0f, 0, MILLION, this);
1632
1633 spinner<int>* msh [] = {&sp_mesh_rows, &sp_mesh_cols};
1634 static const char* const mlb [] = {"Rows", "Columns"};
1635 for (int i = 0; i < 2; ++i) {
1636 spinner<int>* sp = msh[i];
1637 sp->set (mlb[i], 1, 2, MILLION, this, 0);
1638 sp->set_value (2);
1639 sp->orient = mouse_slider_listener::NONE;
1640 sp->draw_more = sp->variance.ui = 0;
1641 }
1642
1643 cb_sync_rows_cols.set_text ("Sync");
1644
1645 l_drone_order.set_text ("Create drones");
1646 ol_drone_order.set_listener (this);
1647 ol_mesh_point.set_listener (this);
1648
1649 f_mesh_xy.set_text ("0 0");
1650 f_mesh_xy.change_lsnr = this;
1651
1652 sp_mesh_dur.set (0.1f, 0, MILLION, this);
1653 sp_mesh_dur.set_value (1.0f);
1654 sp_mesh_dur.set_text ("In", SECONDS);
1655
1656 ol_set_unset_toggle.set_text (" Position affects velocity");
1657 ol_set_unset_toggle.set_listener (this);
1658
1659 ol_am_style.set_listener (&am_style_lis); // voice am
1660 ol_fm_style.set_listener (&fm_style_lis); // voice fm
1661
1662 l_phrase_position.set_text ("Phrase position ");
1663 s_phrase_position.set_limits (0.0f, 1.0f);
1664
1665 #ifndef __WIDGET_MOVE__
1666 ol_create_this.option.set_listener (&dcl);
1667 cb_sync_rows_cols.set_listener (&dcl);
1668 s_phrase_position.set_listener (this);
1669 b_key_to_pitch_at_cursor.set_listener (&miscl);
1670 #endif
1671
1672 const char* lrs [] = {"Adjust Height?", "Adjust?", "Modulation?", "Change Note"};
1673 label* lrm [] = {&l_adjust_height, &l_adjust_range, &l_ran_mod, &ol_change_note.option};
1674 for (int i = 0; i < 4; ++i) lrm[i]->set_text (lrs[i]);
1675
1676 ol_set_range.set_listener (&sral);
1677
1678 const char* snp [] = {"Snap left", "Snap right"};
1679 spinner<float>* snsp [] = {&sp_snap_left, &sp_snap_right};
1680 float snv [] = {din0.dinfo.snap.left, din0.dinfo.snap.right};
1681 for (int i = 0; i < 2; ++i) {
1682 spinner<float>* si = snsp[i];
1683 si->set (snp[i], 0.01f, &sdl);
1684 si->draw_more = 0;
1685 si->variance.ui = 0;
1686 si->set_value (snv[i]);
1687 si->orient = mouse_slider_listener::X;
1688 }
1689
1690 l_drone_arrow.set_text ("Drone Arrow");
1691 dronearrowdefaults.lbl.set_text ("Drone Arrow");
1692 spinner<float>* das [] = {&dronearrow.shoulder.position, &dronearrow.neck, &dronearrow.shoulder.width};
1693 spinner2<float>* das2 [] = {&dronearrowdefaults.shoulder.position, &dronearrowdefaults.neck, &dronearrowdefaults.shoulder.width};
1694 const char* dasl [] = {"Shoulder Position", "Neck", "Shoulder Width"};
1695 float vals [] = {drone::arrowt::U, drone::arrowt::K, drone::arrowt::V};
1696 for (int i = 0; i < 3; ++i) {
1697 spinner<float>& si = *das[i];
1698 spinner2<float>& si2 = *das2[i];
1699 si.set (dasl[i], 0.1f, -MILLION, MILLION, &arrowl);
1700 si2.set (dasl[i], 0.1f, -MILLION, MILLION, &defarrowl, 0);
1701 si2.set_value (vals[i]);
1702 si2.orient = mouse_slider_listener::NONE;
1703 }
1704 for (int i = 0; i < 2; ++i) {
1705 spinner<float>& si = *das[i];
1706 spinner2<float>& si2 = *das2[i];
1707 si.updowndecinc ();
1708 si2.updowndecinc ();
1709 }
1710 dronearrowdefaults.cap.set_listener (&defarrowl);
1711 dronearrowdefaults.arrow.calc ();
1712
1713 cb_scope.set_text ("Show oscilloscope");
1714 cb_scope.set_listener (&scol);
1715 sp_scope_height.set ("Height", 1, 0, MILLION, &scol);
1716 sp_scope_samples.set ("Samples", 1, 1, MAX_SAMPLES, &scol);
1717 sp_scope_samples.orient = mouse_slider_listener::X;
1718
1719 l_tap_bpm.set_text ("Tap BPM");
1720 checkbutton* cb_tars [] = {&cb_am, &cb_fm, &cb_gater, &cb_octave_shift, &cb_auto_reset};
1721 static const char* const cb_text [] = {"AM", "FM", "Gater", "Octave Shift", "Auto reset"};
1722
1723 cb_auto_reset.turn_on ();
1724 for (int i = 0; i < 5; ++i) {
1725 checkbutton* cbi = cb_tars[i];
1726 cbi->set (cb_text[i], &tbl);
1727 l_tap_bpm.add_child (cbi);
1728 }
1729 td_tap_display.set_listener (&tbl);
1730
1731 l_tap_bpm.add_child (&td_tap_display);
1732 l_tap_bpm.add_child (&l_tap_bpm_value);
1733
1734 const char* bpmstr [] = {"os", "fm", "am", "gr"};
1735 spinner<float>* bpmspn [] = {&sp_octave_shift_bpm, &sp_fm_bpm, &sp_am_bpm, &sp_gater_bpm};
1736 for (int i = 0; i < 4; ++i) bpm_map[bpmstr[i]] = bpmspn[i];
1737
1738 // editor tools
1739 arrow_button* enav[] = {&abe_left, &abe_down, &abe_right, &abe_up};
1740 int edirs [] = {arrow_button::left, arrow_button::down, arrow_button::right, arrow_button::up};
1741 for (int i = 0; i < 4; ++i) {
1742 arrow_button* ab = enav[i];
1743 ab->set_dir (edirs[i]);
1744 }
1745
1746 l_snap.set_text ("Snap?");
1747 checkbutton* cb_snaps [] = {&cb_snapx, &cb_snapy, &cb_snapboth, &cb_snapnone};
1748 const char* cb_snap_str [] = {"X", "Y", "Both", "None"};
1749 for (int i = 0; i < 4; ++i) {
1750 checkbutton* cbi = cb_snaps[i];
1751 cbi->set_text (cb_snap_str[i]);
1752 }
1753
1754 l_library.set_text ("Library");
1755 lf_curve_name.set_label ("Curve name");
1756 lf_curve_name.fld.expr = 0;
1757 l_capture.set_text ("Mouse capture");
1758
1759 ol_vertices_carry_tangents.set_listener (this);
1760 ol_mirror_tangents.set_listener (this);
1761 ol_curve_style.set_listener (this);
1762
1763 sp_curve_rpm.set ("RPM", 1.0f, 0.0f, MILLION, &col);
1764 sp_curve_rpm.set_value (0.0f);
1765
1766 #ifndef __WIDGET_MOVE__
1767 b_stop_rotating.set_listener (&col);
1768 cb_show_waveform_samples.set_listener (&col);
1769 #endif
1770
1771 sp_waveform_hz.set ("Hz", 1.0f, 0.01f, MILLION, &col);
1772 sp_waveform_hz.orient = mouse_slider_listener::NONE;
1773
1774 sp_waveform_periods.set ("Cycles", 1, 1, MILLION, &col);
1775 sp_waveform_periods.orient = mouse_slider_listener::NONE;
1776
1777 sp_curve_limit.set ("Curve roughness", 0.001f, 0.001f, MILLION, &col);
1778
1779 // button labels
1780 const char* labels [] = {
1781 "Menu",
1782 "Microtonal Keyboard",
1783 "Keyboard Keyboard",
1784 "Mondrian",
1785 "Binaural Drones",
1786 "Waveform",
1787 "Drone Waveform",
1788 "Drone Modulation",
1789 "Voice Modulation",
1790 "Gater",
1791 "Waveform",
1792 "Attack",
1793 "Decay",
1794 "MIDI Velocity",
1795 "Delays",
1796 "Octave Shift",
1797 "Compressor",
1798 "Morse Code",
1799 "Exit DIN Is Noise",
1800 "Show anchors",
1801 "Move",
1802 "Delete",
1803 "Select all",
1804 "Invert selected",
1805 "Record a phrase",
1806 "Clear phrase",
1807 "Default to Selected",
1808 "Default to all",
1809 "Selected to all",
1810 "Set key to pitch at cursor",
1811 "Insert vertex",
1812 "Delete vertex",
1813 "Fold tangents",
1814 "Unfold tangents",
1815 "Undo",
1816 "Redo",
1817 "Copy",
1818 "Paste",
1819 "Draw & replace curve",
1820 "Add",
1821 "Replace",
1822 "Delete",
1823 "Start",
1824 "Assign",
1825 "Label vertices",
1826 "(Selection only)",
1827 "Show waveform",
1828 "Pick curve",
1829 "Stop",
1830 "Draw curve only",
1831 "Clear",
1832 "Record",
1833 "Select attractees",
1834 "Select attractors",
1835 "Orbit",
1836 "Show velocity",
1837 "Show acceleration",
1838 "Show Gravity",
1839 "Balloon",
1840 "Launch",
1841 "Stop launch",
1842 "Track",
1843 "Select tracked",
1844 "Waveform",
1845 "Attack",
1846 "Decay",
1847 "Add ",
1848 "Move balls",
1849 "Delete selected balls",
1850 "Delete all balls",
1851 "Select all balls",
1852 "Invert ball selection",
1853 "Select balls in box",
1854 "Split box horizontally",
1855 "Split box vertically",
1856 "Delete box",
1857 "Freeze balls",
1858 "Thaw balls",
1859 "Turn Off UI",
1860 "Set targets",
1861 "Clear targets",
1862 "Clear modulations",
1863 "Modulate balls up",
1864 "Modulate balls down",
1865 "Create binaural drones on the notes of the scale",
1866 "Create binaural drones using parameters above",
1867 "Waveform",
1868 "Close octave",
1869 "Auto-change ball direction clockwise",
1870 "Auto-change ball direction anti-clockwise",
1871 "Stop auto-changing ball direction",
1872 "Flip ball direction",
1873 "Randomize box color",
1874 "Resize separation",
1875 "Add / Remove slits",
1876 "Toggle wreckers",
1877 "Toggle healers",
1878 "Toggle bouncers",
1879 "Healers <> Wreckers",
1880 "Select wreckers",
1881 "Select healers",
1882 "Remove slits on edge",
1883 "Toggle slit animation",
1884 "Auto adjust voices",
1885 "Draw boxes",
1886 "Fill boxes",
1887 "Draw notes",
1888 "Label notes",
1889 "Position",
1890 "Make note grid",
1891 "Make N x N grid",
1892 "Delete all boxes",
1893 "Select launchers",
1894 "Select on Creation",
1895 "Freeze",
1896 "Thaw",
1897 "Mark segments",
1898 "Auto split box",
1899 "Auto delete box",
1900 "Speed",
1901 "Turn",
1902 "Teleport",
1903 "Heading",
1904 "Trails",
1905 "Draw ball:",
1906 "Sync",
1907 "Sync",
1908 "Clone",
1909 "Clone can clone too",
1910 "Transform",
1911 "Label pitch and volume",
1912 "All",
1913 "None",
1914 "Invert",
1915 "Delete",
1916 "Sync",
1917 "Modulate",
1918 "Select",
1919 "Flip",
1920 "All",
1921 "Left",
1922 "Right",
1923 "Both",
1924 "Modulate",
1925 "Mark",
1926 "Pause/Resume",
1927 "Start",
1928 "Stop",
1929 "Toggle",
1930 "Get",
1931 "Range modulation",
1932 "Selected",
1933 "Left",
1934 "Right",
1935 "Set",
1936 "Unset",
1937 "Toggle",
1938 "Range Width & Height",
1939 "Flip",
1940 "Overlay Instrument/Editor",
1941 "Range Pitch & Volume",
1942 "Swap",
1943 "Overlay pitch distribution",
1944 "Overlay volume distributon",
1945 "Point Modulation",
1946 "Both",
1947 "AM BPM",
1948 "FM BPM",
1949 "Set to Rows",
1950 "Set to Columns",
1951 "Noise Interpolator",
1952 "Ball triggers note <> Ball triggers noise",
1953 "Scale",
1954 "Rotate",
1955 "Draw mesh outline",
1956 "Modulation",
1957 "Motion",
1958 "Visual",
1959 "Connect",
1960 "Disconnect",
1961 "Wrap",
1962 "Drone Pendulum",
1963 "Abort",
1964 "Close",
1965 "Reset",
1966 "Mute",
1967 "Unmute",
1968 "Drone > Noise",
1969 "Noise > Drone",
1970 "Find center",
1971 "Defaults",
1972 "Mortalize",
1973 "Reincarnate",
1974 "Immortalize",
1975 "Chuck",
1976 "Chuck",
1977 "Flip",
1978 "Toggle",
1979 "Draw chuck outline",
1980 "Auto reset trails",
1981 "Cap",
1982 "Decap",
1983 "Cap",
1984 "Track",
1985 "Auto rotate",
1986 "Auto flip",
1987 "-ve",
1988 "Randomize",
1989 "0",
1990 "0",
1991 "Sync",
1992 // next label
1993 };
1994
1995 button* buttons [] = {
1996 &b_menu,
1997 &b_microtonal_keyboard,
1998 &b_keyboard_keyboard,
1999 &b_mondrian,
2000 &b_binaural_drones,
2001 &b_microtonal_keyboard_waveform,
2002 &b_drone_waveform,
2003 &b_drone_modulation,
2004 &b_voice_modulation,
2005 &b_gater,
2006 &b_keyboard_keyboard_waveform,
2007 &b_attack,
2008 &b_decay,
2009 &b_midi_velocity,
2010 &b_delays,
2011 &b_octave_shift,
2012 &b_compressor,
2013 &b_morse_code,
2014 &b_exit_din,
2015 &cb_show_anchors,
2016 &b_move_drones,
2017 &b_delete_drones,
2018 &b_select_all_drones,
2019 &b_invert_drone_selection,
2020 &b_record_phrase,
2021 &b_clear_phrases,
2022 &b_default_to_selected,
2023 &b_default_to_all,
2024 &b_selected_to_all,
2025 &b_key_to_pitch_at_cursor,
2026 &b_insert_vertex,
2027 &b_delete_vertex,
2028 &b_fold_tangents,
2029 &b_unfold_tangents,
2030 &b_undo,
2031 &b_redo,
2032 &b_copy,
2033 &b_paste,
2034 &b_draw_replacement_curve,
2035 &b_add_curve,
2036 &b_replace_curve,
2037 &b_delete_curve,
2038 &b_start_capture,
2039 &b_assign_capture,
2040 &cb_label_vertices,
2041 &cb_selection_only,
2042 &cb_show_waveform_samples,
2043 &b_pick_curve,
2044 &b_stop_rotating,
2045 &cb_draw_curve,
2046 &b_clear_record,
2047 &cb_record,
2048 &b_select_attractees,
2049 &b_select_attractors,
2050 &b_orbit_selected_drones,
2051 &cb_show_vel,
2052 &cb_show_accel,
2053 &cb_show_gravity,
2054 &balloon,
2055 &b_launch_drones,
2056 &b_stop_launching_drones,
2057 &b_track_drones,
2058 &b_select_tracked_drones,
2059 &b_mondrian_waveform,
2060 &b_mondrian_attack,
2061 &b_mondrian_decay,
2062 &b_add_balls,
2063 &b_move_selected_balls,
2064 &b_delete_selected_targets,
2065 &b_delete_all_targets,
2066 &b_select_all_targets,
2067 &b_invert_selected_targets,
2068 &b_select_targets_in_box,
2069 &b_split_horizontal,
2070 &b_split_vertical,
2071 &b_delete_box,
2072 &b_freeze_balls,
2073 &b_thaw_balls,
2074 &b_turn_off_ui,
2075 &b_set_targets,
2076 &b_clear_targets,
2077 &b_clear_modulations,
2078 &b_modulate_balls_up,
2079 &b_modulate_balls_down,
2080 &b_create_binaurals_on_notes,
2081 &b_create_binaurals_from_pitch,
2082 &b_binaural_drones_waveform,
2083 &cb_close_octave,
2084 &b_auto_change_direction_clockwise,
2085 &b_auto_change_direction_anti_clockwise,
2086 &b_stop_auto_changing_direction,
2087 &b_flip_direction,
2088 &b_make_random_color,
2089 &cb_resize_separation,
2090 &b_add_remove_slits,
2091 &b_toggle_wreckers,
2092 &b_toggle_healers,
2093 &b_toggle_bouncers,
2094 &b_switch_ball_type,
2095 &b_select_wreckers,
2096 &b_select_healers,
2097 &b_remove_slits_on_edge,
2098 &b_toggle_slit_anim,
2099 &cb_mondrian_auto_adjust_voices,
2100 &cb_draw_boxes,
2101 &cb_fill_boxes,
2102 &cb_draw_notes,
2103 &cb_label_notes,
2104 &cb_draw_ball_position,
2105 &b_make_note_grid,
2106 &b_make_nxn_grid,
2107 &b_delete_all_boxes,
2108 &b_select_launchers,
2109 &seloncre,
2110 &b_freeze_drones,
2111 &b_thaw_drones,
2112 &cb_mark_segments,
2113 &cb_auto_split_box,
2114 &cb_auto_delete_box,
2115 &cb_speed,
2116 &cb_turn,
2117 &cb_teleport,
2118 &cb_draw_ball_heading,
2119 &cb_draw_ball_trails,
2120 &l_draw_ball,
2121 &cb_turn_sync,
2122 &cb_speed_sync,
2123 &cb_clone,
2124 &cb_clone_can_clone,
2125 &cb_transform,
2126 &cb_label_hz_vol,
2127 &bbd_select_all,
2128 &bbd_select_none,
2129 &bbd_invert_select,
2130 &bbd_delete,
2131 &bbd_sync,
2132 &bbd_modulate,
2133 &bbd_select2,
2134 &bbd_flip,
2135 &b_adjust_board_height,
2136 &b_adjust_range_left,
2137 &b_adjust_range_right,
2138 &b_adjust_range_both,
2139 &cb_mod_ran,
2140 &cb_mark_ran,
2141 &b_rm_pause_resume,
2142 &b_rm_start_all,
2143 &b_rm_stop_all,
2144 &b_rm_toggle,
2145 &b_get_cur_ran,
2146 &b_range_modulation,
2147 &b_adjust_range_height,
2148 &b_change_note_left,
2149 &b_change_note_right,
2150 &b_set,
2151 &b_unset,
2152 &b_toggle,
2153 &b_range_width_height,
2154 &b_flip_rows_cols,
2155 &cb_overlay,
2156 &b_range_pitch_vol,
2157 &b_swap_curves,
2158 &cb_pitch_dis,
2159 &cb_vol_dis,
2160 &b_point_modulation,
2161 &b_change_note_both,
2162 &cb_am_bpm,
2163 &cb_fm_bpm,
2164 &b_set_to_mesh_rows,
2165 &b_set_to_mesh_cols,
2166 &b_noise_interpolator,
2167 &b_ball_trig,
2168 &b_scale_drones,
2169 &b_rotate_drones,
2170 &cb_draw_mesh,
2171 &cb_modulation,
2172 &cb_motion,
2173 &cb_visual,
2174 &b_connect,
2175 &b_disconnect,
2176 &cb_conn_wrap,
2177 &b_drone_pend,
2178 &b_abort_octave_shift,
2179 &b_close,
2180 &b_arrow_reset,
2181 &b_mute,
2182 &b_unmute,
2183 &drone2noise,
2184 &noise2drone,
2185 &b_set_xform_center,
2186 &cb_defaults,
2187 &mortalize,
2188 &reincarnate,
2189 &immortalize,
2190 &cb_chuck,
2191 &chuck,
2192 &chflip,
2193 &chtog,
2194 &choutline,
2195 &chautoresettrails,
2196 &dronearrow.cap,
2197 &dronearrow.decap,
2198 &dronearrowdefaults.cap,
2199 &trackcon,
2200 &dva.autorotate.cb,
2201 &dva.autoflip.cb,
2202 &dva.neg,
2203 &dva.randomize,
2204 &velgt0,
2205 &accelgt0,
2206 &dva.sync,
2207 // next button
2208 };
2209
2210 for (int i = 0; i < 211; ++i) {
2211 button* bi = buttons[i];
2212 bi->set_text (labels[i]);
2213 }
2214
2215 dlog << "+++ Labeled buttons +++" << endl;
2216
2217 LISTEN(cb_modulation,&cmod)
2218 LISTEN(cb_motion,&cmot)
2219 LISTEN(cb_visual,&cvis)
2220 LISTEN(cb_defaults,&cdef)
2221 LISTEN(cb_chuck,&cch)
2222 LISTEN(dronearrow.cap,&arrowl)
2223 LISTEN(dronearrow.decap,&arrowl)
2224
2225
2226 #ifndef __WIDGET_MOVE__
2227 LISTEN (b_arrow_reset,&awl)
2228 #endif
2229
2230 ol_select_what.set_text ("L");
2231 ol_select_rule.set_text (" >= ");
2232 bdf_value.change_lsnr = &bdl;
2233 bdf_value.set_text (bdl.val[binaural_drones_listener::GREATER_THAN_EQUAL]);
2234
2235 sp_bounces.set ("Bounces", 1, 0, MILLION, &bol);
2236 ol_bounce_style.set_listener (this);
2237
2238 sp_rebound.set ("Speed %", 1, 0, MILLION, &rebl);
2239
2240 sp_mondrian_min_voices.set ("Min Voices", 1, 1, MILLION, &monl);
2241 sp_mondrian_min_voices.draw_more = 0;
2242 sp_mondrian_min_voices.variance.ui = 0;
2243
2244 cb_mondrian_auto_adjust_voices.set_listener (&monl);
2245
2246 sp_mondrian_change_attack_time.set ("Ball attack time", 0.01f, &batl);
2247 sp_mondrian_change_decay_time.set ("Ball decay time", 0.01f, &bdtl);
2248
2249 sp_mondrian_change_speed.set_text ("Ball speed");
2250 sp_mondrian_change_speed.set_listener (&bsl);
2251 sp_mondrian_change_speed.set_listener (&monl, 1);
2252
2253 sp_mondrian_change_dir.set ("Ball direction", 1, &brl);
2254 sp_mondrian_change_dir.orient = mouse_slider_listener::X;
2255 sp_mondrian_change_dir.draw_more = 0;
2256 sp_mondrian_change_dir.variance.ui = 0;
2257
2258 sp_mondrian_change_trail_size.set ("Ball trail length", 1, &tll);
2259 sp_mondrian_change_note_poly_points.set ("Note polygon points", 1, 2, MILLION, &nppl);
2260 sp_mondrian_change_note_poly_radius.set ("Note polygon radius", 1, 0, MILLION, &nprl);
2261
2262 sp_mondrian_change_slit_size.set ("Slit size", 1.0f, &ssl);
2263
2264 sp_mondrian_change_slit_anim_time.set ("Slit open/close time", 0.01f, &satl);
2265 sp_mondrian_change_slit_anim_time.set_value (0.0f);
2266
2267 sp_mondrian_change_vol.set ("Ball volume", 0.01f, -MILLION, MILLION, &bvl);
2268 sp_mondrian_change_vol.set_value (0);
2269
2270 sp_mondrian_num_boxes.set ("N", 1, 0, MILLION, &monl);
2271 sp_mondrian_num_boxes.draw_more = 0;
2272 sp_mondrian_num_boxes.variance.ui = 0;
2273
2274 sp_auto_split_time.set ("", 0.1f, 0.01f, MILLION, &monl);
2275 sp_auto_split_time.set_text ("Every", SECONDS);
2276
2277 sp_auto_delete_time.set ("", 0.1f, 0.01f, MILLION, &monl);
2278 sp_auto_delete_time.set_text ("Every", SECONDS);
2279
2280 sp_min_split_size.set ("Min split size", 1, 2, MILLION, &monl);
2281
2282 #ifndef __WIDGET_MOVE__
2283 cb_auto_split_box.set_listener (&monl);
2284 cb_auto_delete_box.set_listener (&monl);
2285 #endif
2286
2287 options_list* olt [] = {&ol_bouncer, &ol_wrecker, &ol_healer};
2288 for (int i = 0; i < 3; ++i) olt[i]->set_listener (&bolis);
2289
2290 button* pb[] = {&sp_mondrian_change_dir.inc, &sp_mondrian_change_dir.dec};
2291 set_repeat (pb, 2, 0.005);
2292
2293 recl.typing (lf_file.fld);
2294
2295 {
2296
2297 nullt* sp [] = {
2298 &sp_change_drone_handle_size,
2299 &sp_change_drone_trail_length,
2300 &autorotate.rpm,
2301 &autorotate.deg,
2302 &autorotate.tps,
2303 &sp_mondrian_change_vol,
2304 &sp_mondrian_change_attack_time,
2305 &sp_mondrian_change_decay_time,
2306 &sp_mondrian_change_speed,
2307 &sp_mondrian_change_slit_size,
2308 &sp_mondrian_change_slit_anim_time,
2309 &sp_mondrian_change_note_poly_radius,
2310 &sp_change_drone_vel,
2311 &sp_change_drone_accel,
2312 &sp_dam_depth,
2313 &sp_dfm_depth,
2314 &sp_dam_bpm,
2315 &sp_dfm_bpm,
2316 &sp_drone_vol,
2317 &dronearrow.shoulder.position,
2318 &dronearrow.shoulder.width,
2319 &sp_rotate_drone_vel,
2320 &sp_drones_per_min,
2321 &sp_drone_lifetime,
2322 &sp_orbit_insertion_time,
2323 &sp_mondrian_change_attack_time,
2324 &sp_mondrian_change_decay_time,
2325 &sp_mondrian_change_speed,
2326 &sp_mondrian_change_dir,
2327 &sp_mondrian_change_trail_size,
2328 &sp_mondrian_change_vol,
2329 &sp_mondrian_change_slit_size,
2330 &sp_mondrian_change_slit_anim_time,
2331 &chspeed,
2332 &chlen,
2333 &chtrail,
2334 &autorotate.autoflip.angle,
2335 &dronearrow.neck,
2336 &dronearrow.shoulder.width,
2337 &dronearrow.shoulder.position,
2338 0
2339 };
2340
2341 int i = 0;
2342 while (sp[i] != 0) sp[i++]->null = 1;
2343
2344 }
2345
2346
2347
2348 }
2349
update()2350 void menu::update () {
2351 position_menu_items ();
2352 position_tabs ();
2353 }
2354
position_menu_items()2355 void menu::position_menu_items () {
2356 static const int lines = 4;
2357 int targety = view.ymax - lines * line_height;
2358 int dy = targety - cb_file.extents.bottom;
2359 for (int p = 0; p < nitems; ++p) items[p]->move (0, dy, 0);
2360 }
2361
loadspinners()2362 void menu::loadspinners () {
2363 file_in fi ("spinners");
2364 ifstream& f = fi ();
2365 f >> handlesize >> trailsize >> dva.mag >> lifetime >> dronearrowdefaults.neck >> dronearrowdefaults.shoulder.width >> dronearrowdefaults.shoulder.position;
2366 f >> dva.autorotate.rpm >> dva.autorotate.dps >> dva.autorotate.tps >> dva.autoflip.deg >> gabt >> din0.dinfo.gravity.mod.depth >> din0.dinfo.gravity.mod.bpm;
2367 f >> riset >> fallt;
2368 f >> sp_bounces >> sp_rebound;
2369 }
2370
savespinners()2371 void menu::savespinners () {
2372 file_out fo ("spinners");
2373 ofstream& f = fo ();
2374 f << handlesize << trailsize << dva.mag << lifetime << dronearrowdefaults.neck << dronearrowdefaults.shoulder.width << dronearrowdefaults.shoulder.position;
2375 f << dva.autorotate.rpm << dva.autorotate.dps << dva.autorotate.tps << dva.autoflip.deg << gabt << din0.dinfo.gravity.mod.depth << din0.dinfo.gravity.mod.bpm;
2376 f << riset << fallt << endl;
2377 f << sp_bounces << sp_rebound;
2378 }
2379
2380
setup()2381 void menu::setup () {
2382 dlog << "*** setting up menu ***" << endl;
2383 show = screen_mousex = screen_mousey = 0;
2384 setup_items ();
2385 widget_load ("d_menu", items, nitems);
2386 loadspinners ();
2387 b_menu.set_listener (&mbl);
2388 dlog << "+++ menu setup complete +++" << endl;
2389 }
2390
set_pos(int x,int y)2391 void menu::set_pos (int x, int y) {
2392 b_menu.set_pos (x, y);
2393 }
2394
draw()2395 void menu::draw () {
2396
2397 b_menu.draw ();
2398
2399 if (show) {
2400
2401 // draw bg
2402 glEnable (GL_BLEND);
2403 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2404 glColor4f (0.0f, 0.0f, 0.0f, opacity);
2405 glRecti (bg_extents.left, bg_extents.bottom, bg_extents.right, bg_extents.top);
2406 glDisable (GL_BLEND);
2407
2408 glPolygonMode (GL_FRONT, GL_LINE);
2409 glColor3f (0.5f, 0.5f, 0.5f);
2410 glRecti (bg_extents.left, bg_extents.bottom, bg_extents.right, bg_extents.top);
2411 glPolygonMode (GL_FRONT, GL_FILL);
2412
2413 // draw items
2414 for (int i = 0; i < num_tabs; ++i) tabs[i]->draw ();
2415 if (cur_tab) {
2416 vector<widget*>& ti = tab_members [cur_tab];
2417 for (int i = 0, j = ti.size (); i < j; ++i) ti[i]->draw ();
2418 if (cur_tab == &cb_mkb_voice && din0.phrasor0.state == phrasor::playing) s_phrase_position.set_val (din0.phrasor0.amount);
2419 }
2420 }
2421 }
2422
setup_tabs(ui * scr)2423 void menu::setup_tabs (ui* scr) {
2424 checkbutton* com [] = {&cb_file, &cb_instrument, &cb_editors};
2425 checkbutton* mkb [] = {&cb_mkb_voice, &cb_mkb_drone_tools, &cb_mkb_drone_params, &cb_mkb_ranges, &cb_mkb_misc};
2426 checkbutton* eds [] = {&cb_ed_tools};
2427 checkbutton* mon [] = {&cb_mon_tools, &cb_mon_parameters, &cb_mon_ballops, &cb_mon_boxops, &cb_mon_misc};
2428 checkbutton* bd [] = {&cb_binaural_drones_tools, &cb_binaural_drones_edit};
2429 int clear_existing_tabs = 1;
2430 setup_tabs (com, 3, clear_existing_tabs);
2431 if (scr == &din0) { // microtonal keyboard
2432 setup_tabs (mkb, 5);
2433 } else if (scr == &keybd2) { // keyboard-keyboard
2434 } else if (scr == &mondrian0) { // mondrian
2435 setup_tabs (mon, 5);
2436 } else if (scr == &binaural_drones0) { // binaural drones
2437 setup_tabs (bd, 2);
2438 } else { // is an editor
2439 setup_tabs (com, 3, clear_existing_tabs);
2440 setup_tabs (eds, 1);
2441 next_tab = &cb_ed_tools;
2442 next_tab_instr = get_current_instrument ();
2443 }
2444 position_tabs ();
2445 }
2446
setup_tabs(checkbutton ** tlist,int n,int clear)2447 void menu::setup_tabs (checkbutton** tlist, int n, int clear) {
2448 if (clear) tabs.clear ();
2449 for (int i = 0; i < n; ++i) tabs.push_back (tlist[i]);
2450 num_tabs = tabs.size ();
2451 }
2452
position_tabs()2453 void menu::position_tabs () {
2454
2455 if (num_tabs) {
2456
2457 int x = cb_file.posx, y = cb_file.posy, spacing = 20;
2458 int i = 1, j = 0;
2459 for (; i < num_tabs;) {
2460 x = x + get_char_width (tabs[j]->text) + spacing;
2461 tabs[i]->set_pos (x, y);
2462 ++i;
2463 j = i - 1;
2464 }
2465
2466 int ss = x + get_char_width (tabs[j]->text) - cb_file.posx;
2467 separators.main.set_extents (ss);
2468 separators.dp0.set_extents (ss);
2469 separators.dp1.set_extents (ss);
2470 calc_bg ();
2471
2472 checkbutton* lt = tabs[num_tabs - 1];
2473 menu_mousex = lt->extents.right + 1;
2474 menu_mousey = view.ymax - lt->posy;
2475
2476 }
2477 }
2478
remove_from_tab(checkbutton * cb,widget * w)2479 void menu::remove_from_tab (checkbutton* cb, widget* w) {
2480 vector<widget*>& tw = tab_members [cb];
2481 vector<widget*>::iterator end = tw.end (), i = find (tw.begin(), end, w);
2482 if (i != end) tw.erase (i);
2483 }
2484
add_to_tab(checkbutton * cb,widget * w)2485 void menu::add_to_tab (checkbutton* cb, widget* w) {
2486 vector<widget*>& tw = tab_members[cb];
2487 vector<widget*>::iterator end = tw.end (), i = find (tw.begin(), end, w);
2488 if (i == end) tw.push_back (w);
2489 }
2490
set_drone_params_items(int s,int e)2491 void menu::set_drone_params_items (int s, int e) {
2492 vector<widget*>& tw = tab_members[&cb_mkb_drone_params];
2493 tw.clear ();
2494 tw.push_back (&separators.main);
2495 DECL_DRONE_PARAMS
2496 for (int i = 0; i < 9; ++i) {
2497 add_to_tab (&cb_mkb_drone_params, wdrone_params[i]);
2498 }
2499 for (int i = s; i < e; ++i) {
2500 add_to_tab (&cb_mkb_drone_params, wdrone_params[i]);
2501 }
2502 calc_bg ();
2503 }
2504
handle_input()2505 int menu::handle_input () {
2506
2507 if (b_menu.handle_input ()) return 1;
2508
2509 if (show) {
2510
2511 if (wheel && !widget::HOVER) move_items (0, wheel * wheely);
2512
2513 // find current tab
2514 for (int i = 0; i < num_tabs; ++i) tabs[i]->handle_input ();
2515
2516 if (cur_tab) { // handle tab's items
2517 vector<widget*>& tm = tab_members [cur_tab];
2518 for (int i = 0, j = tm.size (); i < j; ++i) if (tm[i]->handle_input ()) return 1;
2519 }
2520
2521
2522 }
2523
2524 return 0;
2525
2526 }
2527
init_modulation()2528 void menu::init_modulation () {
2529 spinner<float>* spn [] = {&sp_am_depth, &sp_fm_depth, &sp_am_bpm, &sp_fm_bpm}; // for voice
2530 float vals [] = {din0.am_depth, din0.fm_depth, din0.am.bpm, din0.fm.bpm};
2531 spinner<float>* dspn [] = {&sp_dam_depth, &sp_dfm_depth, &sp_dam_bpm, &sp_dfm_bpm}; // for drones
2532 float* d_prev_vals [] = {&dam_depth, &dfm_depth, &dam_bpm, &dfm_bpm};
2533 for (int i = 0; i < 4; ++i) {
2534 spinner<float>* dspni = dspn[i];
2535 dspni->limits = 0;
2536 dspni->set_value (0);
2537 *d_prev_vals[i] = 0;
2538 spinner<float>* spni = spn[i];
2539 spni->set_value (vals[i]);
2540 }
2541 am_depth = din0.am_depth;
2542 fm_depth = din0.fm_depth;
2543 }
2544
toggle(int mouse_warp)2545 void menu::toggle (int mouse_warp) {
2546
2547 static int removedpluginbrowser;
2548
2549 show = !show;
2550 if (show) {
2551
2552 b_menu.set_text ("Close menu");
2553
2554 if (b_close.visible) b_close.call_listener ();
2555
2556 if (uis.current->inst) {
2557 if (uis.current == &din0) {
2558 uis.remove (&mkb_selector);
2559 if (din0.dinfo.gravity.visible) uis.remove (&din0.dinfo.gravity);
2560 }
2561 else if (uis.current == &mondrian0)
2562 uis.remove (&mon_selector);
2563 } else {
2564 uis.remove (&CRVED->capturer);
2565 uis.remove (&CRVED->pomo);
2566 removedpluginbrowser = uis.remove (&uis.plugin__browser);
2567 if (CRVED->fft_enabled) uis.remove (&fft0);
2568 }
2569
2570 style_listener* sl [] = {&gater_style_lis, &am_style_lis, &fm_style_lis};
2571 for (int i = 0; i < 3; ++i) sl[i]->get_style ();
2572
2573 screen_mousex = mousex;
2574 screen_mousey = mousey;
2575 ::warp_mouse (menu_mousex, menu_mousey);
2576
2577 if (next_tab && (next_tab_instr == get_current_instrument())) {
2578 changed (*next_tab);
2579 cur_tab = next_tab;
2580 next_tab = 0;
2581 next_tab_instr = 0;
2582 }
2583
2584 } else {
2585 b_menu.set_text ("Menu");
2586 menu_mousex = mousex;
2587 menu_mousey = mousey;
2588 if (uis.current->inst) {
2589 if (uis.current == &din0 ) {
2590 if (din0.dinfo.gravity.visible) uis.add (&din0, &din0.dinfo.gravity);
2591 if (!din0.adding && !b_close.visible) uis.add (&din0, &mkb_selector);
2592 }
2593 else if (uis.current == &mondrian0)
2594 uis.widgets_of [&mondrian0].push_back (&mon_selector);
2595 } else {
2596 uis.widgets_of[CRVED].push_back (&CRVED->capturer);
2597 uis.widgets_of[CRVED].push_back (&CRVED->pomo);
2598 if (removedpluginbrowser) uis.widgets_of[CRVED].push_back (&uis.plugin__browser);
2599 if (CRVED->fft_enabled) uis.widgets_of[CRVED].push_back (&fft0);
2600 }
2601 if (mouse_warp) warp_mouse (screen_mousex, screen_mousey);
2602 }
2603
2604 uis.update_bottom_line ();
2605
2606 }
2607
set_ball_ops(ball * b)2608 void menu::set_ball_ops (ball* b) {
2609
2610 ball_op* ops [ball_op::NUM_OPS] = {&b->op_turn, &b->op_speed, &b->op_teleport, &b->op_clone, &b->op_transform};
2611 checkbutton* cbn [ball_op::NUM_OPS] = {&cb_turn, &cb_speed, &cb_teleport, &cb_clone, &cb_transform};
2612 for (int i = 0; i < ball_op::NUM_OPS; ++i) cbn[i]->set_state (ops[i]->alarm.active, 0);
2613
2614 turn& trn = b->op_turn;
2615 sp_turn_min.set_value (-trn.rd.min);
2616 sp_turn_max.set_value (trn.rd.max);
2617
2618 speed& spd = b->op_speed;
2619 sp_speed_min.set_value (-spd.rd.min);
2620 sp_speed_max.set_value (spd.rd.max);
2621 sp_max_speed.set_value (spd.max);
2622
2623 teleport& tel = b->op_teleport;
2624 sp_tel_radius.set_value (tel.radius);
2625
2626 Clone& clo = b->op_clone;
2627 sp_clone_offset.set_value (clo.offset);
2628 sp_max_clones.set_value (clo.max);
2629 sp_max_balls.set_value (Clone::max_balls);
2630 cb_clone_can_clone.set_state (clo.clone_can_clone);
2631
2632 Transform& tf = b->op_transform;
2633
2634 ball_op* bpa [] = {&trn, &spd, &tel, &clo, &tf};
2635 spinner<float>* spa [] = {&sp_turn_every, &sp_speed_every, &sp_tel_every, &sp_clone_every, &sp_transform_every};
2636 for (int i = 0; i < ball_op::NUM_OPS; ++i) spa[i]->set_value (bpa[i]->alarm.triggert);
2637
2638 }
2639
clear_ball_ops()2640 void menu::clear_ball_ops () {
2641 checkbutton* cbn [ball_op::NUM_OPS] = {&cb_turn, &cb_speed, &cb_teleport, &cb_clone, &cb_transform};
2642 for (int i = 0; i < ball_op::NUM_OPS; ++i) cbn[i]->set_state (0, 0);
2643 }
2644
CLICKED_BUTTON(menu,b_menu_lis)2645 CLICKED_BUTTON(menu, b_menu_lis) {
2646 cons << YELLOW << "You can use right click to open / close the menu and mouse wheel to scroll" << eol;
2647 TOGGLEMENU
2648 }
2649
CLICKED_BUTTON(menu,b_inst_lis)2650 CLICKED_BUTTON(menu, b_inst_lis) {
2651 int i = b.id;
2652 scope.save_current_instrument ();
2653 CURRENT_INSTRUMENT = i;
2654 INSTRUMENT = INSTRUMENTS[i];
2655 load_instrument ();
2656 }
2657
CLICKED_BUTTON(menu,b_ed_lis)2658 CLICKED_BUTTON(menu, b_ed_lis) {
2659 int i = b.id;
2660 ui* ed = uis.uis[i];
2661 uis.load_editor (ed);
2662 setup_plugin_labels ();
2663 if (curve_picker.visible) curve_picker.hide();
2664 }
2665
clicked(button & b)2666 void misc_listener::clicked (button& b) {
2667 if (&b == MENUP.b_exit_din)
2668 try_quit ();
2669 else if (&b == MENUP.b_turn_off_ui) {
2670 turn_off_ui ();
2671 return;
2672 } else
2673 din0.set_key_to_pitch_at_cursor ();
2674 TOGGLEMENU
2675 }
2676
move_items(int dx,int dy)2677 void menu::move_items (int dx, int dy) {
2678 for (int i = 0; i < nitems; ++i) {
2679 widget* wi = items[i];
2680 wi->move (dx, dy, 0);
2681 }
2682 calc_bg ();
2683 }
2684
changed(checkbutton & tb)2685 void menu::changed (checkbutton& tb) { // current tab has changed
2686
2687 cur_tab = &tb;
2688 tb.turn_on (DONT_CALL_LISTENER); // must be always on
2689
2690 if (cur_tab == last_tab) return;
2691
2692 if (last_tab) last_tab->turn_off (DONT_CALL_LISTENER);
2693
2694 last_tab = cur_tab;
2695
2696 calc_bg ();
2697
2698 opacity = 0.9f;
2699 if (&tb == &cb_mon_ballops || &tb == &cb_mon_boxops || &tb == &cb_mon_misc) opacity = 0.5f;
2700
2701 // save last tab to reload when loading new instrument
2702 extern checkbutton* LAST_TABS [];
2703 checkbutton* com [] = {&cb_file, &cb_instrument, &cb_editors, &cb_ed_tools}; // ignore these tabs
2704 for (int i = 0; i < 4; ++i) if (com[i] == cur_tab) return;
2705 LAST_TABS [CURRENT_INSTRUMENT] = cur_tab;
2706
2707 }
2708
VALUE_CHANGED(menu,sp_stiff_lis)2709 VALUE_CHANGED(menu,sp_stiff_lis) {
2710 drone::STIFFNESS = f;
2711 clamp (0.0f, drone::STIFFNESS, 1.0f);
2712 cons << "Connection stiffness = " << drone::STIFFNESS << eol;
2713 }
2714
VALUE_CHANGED(menu,gabt_lis)2715 VALUE_CHANGED(menu,gabt_lis) {
2716 drone::gabt = f;
2717 din0.gab.setgabt ();
2718 cons << YELLOW << "Mute/unmute and Drone <> Noise time = " << drone::gabt << SECONDS << eol;
2719 }
2720
VALUE_CHANGED(menu,sp_dam_depth_lis)2721 VALUE_CHANGED(menu,sp_dam_depth_lis) {
2722 din0.change_drone_depth (modulator::AM, MENU.sp_dam_depth);
2723 }
2724
VALUE_CHANGED(menu,sp_dfm_depth_lis)2725 VALUE_CHANGED(menu,sp_dfm_depth_lis) {
2726 din0.change_drone_depth (modulator::FM, MENU.sp_dfm_depth);
2727 }
2728
VALUE_CHANGED(menu,sp_dam_bpm_lis)2729 VALUE_CHANGED(menu,sp_dam_bpm_lis) {
2730 din0.change_drone_bpm (modulator::AM, MENU.sp_dam_bpm);
2731 }
2732
VALUE_CHANGED(menu,sp_dfm_bpm_lis)2733 VALUE_CHANGED(menu,sp_dfm_bpm_lis) {
2734 din0.change_drone_bpm (modulator::FM, MENU.sp_dfm_bpm);
2735 }
2736
VALUE_CHANGED(menu,sp_am_depth_lis)2737 VALUE_CHANGED(menu,sp_am_depth_lis) {
2738 din0.change_depth (din::AM, MENU.sp_am_depth());
2739 }
2740
VALUE_CHANGED(menu,sp_fm_depth_lis)2741 VALUE_CHANGED(menu,sp_fm_depth_lis) {
2742 din0.change_depth (din::FM, MENU.sp_fm_depth());
2743 }
2744
VALUE_CHANGED(menu,sp_am_bpm_lis)2745 VALUE_CHANGED(menu,sp_am_bpm_lis) {
2746 float v = f;
2747 v = din0.am.set_bpm (v);
2748 cons << YELLOW << "Voice AM bpm = " << v << eol;
2749 }
2750
VALUE_CHANGED(menu,sp_fm_bpm_lis)2751 VALUE_CHANGED(menu,sp_fm_bpm_lis) {
2752 float v = f;
2753 v = din0.fm.set_bpm (v);
2754 cons << YELLOW << "Voice FM bpm = " << v << eol;
2755 }
2756
VALUE_CHANGED(menu,sp_browse_drone_lis)2757 VALUE_CHANGED(menu,sp_browse_drone_lis) {
2758 din0.browsed_drone = f;
2759 din0.browse_drone (0);
2760 }
2761
2762
VALUE_CHANGED(menu,sp_bounces_lis)2763 VALUE_CHANGED (menu,sp_bounces_lis) {
2764 din0.dinfo.bounce.n = f;
2765 cons << GREEN << "Max bounces = " << din0.dinfo.bounce.n << eol;
2766 }
2767
VALUE_CHANGED(menu,sp_rebound_lis)2768 VALUE_CHANGED(menu,sp_rebound_lis) {
2769 din0.dinfo.bounce.speed = f;
2770 cons << GREEN << "Max speed% = " << din0.dinfo.bounce.speed << eol;
2771 }
2772
changed(field & f)2773 void menu::changed (field& f) {
2774
2775 if (&f == &sp_mesh_rows.f_value) {
2776 din0.dinfo.rows = f;
2777 if (cb_sync_rows_cols.state) {
2778 din0.dinfo.cols = din0.dinfo.mesh_vars.dpp = din0.dinfo.rows;
2779 sp_mesh_cols.set_value (din0.dinfo.cols);
2780 sp_drones_per_pend.set_value (din0.dinfo.mesh_vars.dpp);
2781 }
2782 mkb_selector.set_mesh (din0.meshh.create, din0.dinfo.rows, din0.dinfo.cols);
2783 picked (ol_mesh_point.option, 0);
2784 } else if (&f == &sp_mesh_cols.f_value) {
2785 din0.dinfo.cols = f;
2786 if (cb_sync_rows_cols.state) {
2787 din0.dinfo.rows = din0.dinfo.mesh_vars.dpp = din0.dinfo.cols;
2788 sp_mesh_rows.set_value (din0.dinfo.rows);
2789 sp_drones_per_pend.set_value (din0.dinfo.mesh_vars.dpp);
2790 }
2791 mkb_selector.set_mesh (din0.meshh.create, din0.dinfo.rows, din0.dinfo.cols);
2792 picked (ol_mesh_point.option, 0);
2793 } else if (&f == &sp_mesh_dur.f_value) {
2794 float t = f;
2795 din0.dinfo.mesh_vars.duration = t;
2796 cons << "Make mesh in " << t << SECONDS << eol;
2797 } else if (&f == &f_mesh_xy) {
2798 int r, c;
2799 tokenizer z (f.text);
2800 z >> r >> c;
2801 if (clamp (0, r, din0.dinfo.rows-1) || clamp (0, c, din0.dinfo.cols-1) ) {
2802 sprintf (BUFFER, "%d %d", r, c);
2803 f_mesh_xy.set_text(BUFFER);
2804 }
2805 proximity_orderer::ROW = r;
2806 proximity_orderer::COL = c;
2807 } else if (&f == &dp_numdrones.f_value) {
2808 din0.dinfo.drone_pend.n = int(f);
2809 cons << YELLOW << "Number of Drones = " << din0.dinfo.drone_pend.n << eol;
2810 } else if (&f == &dp_bpm1.f_value) {
2811 din0.dinfo.drone_pend.bpm = float(f);
2812 cons << YELLOW << "Drone Pendulum BPM = " << din0.dinfo.drone_pend.bpm << eol;
2813 }
2814 }
2815
changed(slider<float> & s)2816 void menu::changed (slider<float>& s) {
2817 din0.phrasor0.set_cur (s());
2818 }
2819
picked(label & lbl,int dir)2820 void menu::picked (label& lbl, int dir) {
2821 const static char* vct [] = {" Vertices desert tangents", " Vertices carry tangents"};
2822 const static char* mit [] = {" Tangents are not mirrored", " Tangents are mirrored"};
2823 const static char* bbs [] = {" Drones bounce ahead", " Drones bounce back", " Drones bounce ahead or back"};
2824 const static char *sut [] = {" Snap drones to notes", " Position affects velocity"};
2825 const static char *ofl [] = {" in ascending rows", " in descending rows"," in ascending columns", " in descending columns", " randomly", " nearest to", " farthest from" };
2826 const static char *wpt [] = {"bottom left", "bottom right", "top left", "top right", "center", "random point", "custom point"};
2827 const static char *cwt [] = {" Create Drone Mesh", " Create Drone Pendulum"};
2828 const static char *ort [] = {" Orientation = Horizontal", " Orientation = Vertical"};
2829 const static char *mir [] = {" Horizontal Flip", " Vertical Flip", " Horizontal Flip (Local)", " Vertical Flip (Local)" };
2830 const static char *dris [] = {" Drone is Drone", " Drone is Noise", " Drone is Drone or Noise"};
2831
2832 static const int npt = 7, npt_1 = npt-1;
2833 static widget* mshw [] = {
2834 &sp_mesh_rows,
2835 &sp_mesh_cols,
2836 &cb_sync_rows_cols,
2837 &l_drone_order,
2838 &sp_mesh_dur,
2839 &b_flip_rows_cols,
2840 &ol_drone_order,
2841 &l_use_drone_pend,
2842 &sp_drones_per_pend,
2843 &l_apply_to,
2844 &cb_am_bpm,
2845 &cb_fm_bpm,
2846 &b_set_to_mesh_rows,
2847 &b_set_to_mesh_cols,
2848 &ol_mesh_point,
2849 &f_mesh_xy,
2850 };
2851 static widget* dpw [] = {
2852 &dp_orient,
2853 &dp_numdrones,
2854 &dp_bpm1,
2855 };
2856
2857 if (&lbl == &ol_vertices_carry_tangents.option) {
2858 CRVED->carry_tangents = !CRVED->carry_tangents;
2859 lbl.set_text (vct[CRVED->carry_tangents]);
2860 } else if (&lbl == &ol_mirror_tangents.option) {
2861 CRVED->mirror_tangents = !CRVED->mirror_tangents;
2862 lbl.set_text (mit[CRVED->mirror_tangents]);
2863 } else if (&lbl == &ol_curve_style.option) {
2864 CRVED->toggle_curve_style ();
2865 } else if (&lbl == &ol_bounce_style.option) {
2866 din0.dinfo.bounce.style += dir;
2867 wrap<int> (din_info::bouncet::AHEAD, din0.dinfo.bounce.style, din_info::bouncet::RANDOM);
2868 lbl.set_text (bbs[din0.dinfo.bounce.style]);
2869 } else if (&lbl == &ol_set_unset_toggle.option) {
2870 din0.dinfo.set_unset_toggle = !din0.dinfo.set_unset_toggle;
2871 lbl.set_text (sut[din0.dinfo.set_unset_toggle]);
2872 b_toggle.set_pos (lbl.extents.right + 20, b_toggle.posy);
2873 b_set.set_pos (b_toggle.extents.right + 10, b_toggle.posy);
2874 b_unset.set_pos (b_set.extents.right + 10, b_toggle.posy);
2875 } else if (&lbl == &ol_drone_order.option) {
2876 din0.dinfo.mesh_vars.order += dir;
2877 wrap (0, din0.dinfo.mesh_vars.order, LAST_ORDERER);
2878 lbl.set_text (ofl[din0.dinfo.mesh_vars.order]);
2879 if (din0.dinfo.mesh_vars.order > 4) {
2880 add_to_tab (&cb_mkb_drone_tools, &ol_mesh_point);
2881 add_to_tab (&cb_mkb_drone_tools, &f_mesh_xy);
2882 ol_mesh_point.set_pos (lbl.extents.right + 10, lbl.extents.bottom);
2883 f_mesh_xy.set_pos (ol_mesh_point.option.extents.right + 10, f_mesh_xy.extents.bottom);
2884 } else {
2885 remove_from_tab (&cb_mkb_drone_tools, &ol_mesh_point);
2886 remove_from_tab (&cb_mkb_drone_tools, &f_mesh_xy);
2887 }
2888 } else if (&lbl == &ol_mesh_point.option) {
2889 din0.dinfo.mesh_vars.point += dir;
2890 wrap (0, din0.dinfo.mesh_vars.point, npt_1);
2891 sprintf (BUFFER, " %s @ ", wpt[din0.dinfo.mesh_vars.point]);
2892 lbl.set_text (BUFFER);
2893 int cols_1 = din0.dinfo.cols - 1;
2894 int rows_1 = din0.dinfo.rows - 1;
2895 rnd<int> rdr (0, rows_1), rdc (0, cols_1);
2896 int ROW [] = {0, 0, rows_1, rows_1, din0.dinfo.rows / 2, rdr(), proximity_orderer::ROW};
2897 int COL [] = {0, cols_1, 0, cols_1, din0.dinfo.cols / 2, rdc(), proximity_orderer::COL};
2898 proximity_orderer::ROW = ROW [din0.dinfo.mesh_vars.point];
2899 proximity_orderer::COL = COL [din0.dinfo.mesh_vars.point];
2900 sprintf (BUFFER, "%d %d", proximity_orderer::ROW, proximity_orderer::COL);
2901 f_mesh_xy.set_text (BUFFER);
2902 f_mesh_xy.set_pos (lbl.extents.right + 10, f_mesh_xy.extents.bottom);
2903 } else if (&lbl == &ol_create_this.option) {
2904 din0.dinfo.create_this += dir;
2905 wrap (0, din0.dinfo.create_this, 1);
2906 int cw = din0.dinfo.create_this;
2907 lbl.set_text (cwt[cw]);
2908 if (cw) { // drone pendulum
2909 for (int i = 0; i < 16; ++i) remove_from_tab (&cb_mkb_drone_tools, mshw[i]);
2910 for (int i = 0; i < 3; ++i) add_to_tab (&cb_mkb_drone_tools, dpw[i]);
2911 } else { // mesh
2912 for (int i = 0; i < 3; ++i) remove_from_tab (&cb_mkb_drone_tools, dpw[i]);
2913 int j = 14; if (din0.dinfo.mesh_vars.order > 4) j = 16;
2914 for (int i = 0; i < j; ++i) add_to_tab (&cb_mkb_drone_tools, mshw[i]);
2915 }
2916 calc_bg ();
2917 } else if (&lbl == &dp_orient.option) {
2918 din0.dinfo.drone_pend.orient += dir;
2919 wrap (0, din0.dinfo.drone_pend.orient, 1);
2920 int o = din0.dinfo.drone_pend.orient;
2921 lbl.set_text (ort[o]);
2922 } else if (&lbl == &ol_mirror.option) {
2923 CRVED->axis += dir;
2924 wrap<int> (curve_editor::MIRROR_X, CRVED->axis, curve_editor::MIRROR_BBY);
2925 lbl.set_text (mir[CRVED->axis]);
2926 cb_selection_only.set_pos (lbl.extents.right + 5, lbl.extents.bottom);
2927 calc_bg ();
2928 } else if (&lbl == &ol_drone_is.option) {
2929 drone::IS += dir;
2930 wrap<int> (drone::DRONE, drone::IS, drone::DRONE_OR_NOISE);
2931 const char* di = dris [drone::IS];
2932 lbl.set_text (di);
2933 }
2934 }
2935
calc_bg()2936 void menu::calc_bg () {
2937 if (cur_tab && num_tabs) {
2938 vector<widget*>& v = tab_members [cur_tab];
2939 if (v.size () == 0) return;
2940 widget* w0 = v[0];
2941 bg_extents.left = cb_file.extents.left;
2942 bg_extents.right = bg_extents.left;
2943 bg_extents.bottom = w0->extents.bottom;
2944 bg_extents.top = tabs[0]->extents.top;
2945 for (int i = 0, j = v.size (); i < j; ++i) {
2946 widget* wi = v[i];
2947 if (wi->extents.left < bg_extents.left) bg_extents.left = wi->extents.left;
2948 if (wi->extents.right > bg_extents.right) bg_extents.right = wi->extents.right;
2949 if (wi->extents.bottom < bg_extents.bottom) bg_extents.bottom = wi->extents.bottom;
2950 if (wi->extents.top > bg_extents.top) bg_extents.top = wi->extents.top;
2951 }
2952 static const int GUTTER = 5;
2953 bg_extents.resize (GUTTER, GUTTER);
2954 }
2955
2956 }
2957
show_editors(ui * inst)2958 void menu::show_editors (ui* inst) {
2959 int starts [] = {8, 0, 12, 15};
2960 int ends [] = {12, 8, 15, 16};
2961 int starti = starts[CURRENT_INSTRUMENT], endi = ends[CURRENT_INSTRUMENT];
2962 vector<widget*>& tw = tab_members [&cb_editors];
2963 for (int i = starti; i < endi; ++i) {
2964 widget* ei = editors[i];
2965 tw.push_back (ei);
2966 }
2967 }
2968
hide_editors()2969 void menu::hide_editors () {
2970 vector<widget*>& tw = tab_members [&cb_editors];
2971 for (int i = 0; i < 16; ++i) {
2972 widget* ei = editors[i];
2973 vector<widget*>::iterator itr = find (tw.begin(), tw.end(), ei);
2974 if (itr != tw.end()) tw.erase (itr);
2975 }
2976 }
2977
update_bpm(const string & name,float value)2978 void menu::update_bpm (const string& name, float value) {
2979 spinner<float>* psp = bpm_map [name];
2980 if (psp) psp->set_value (value);
2981 }
2982
mark_tap_target()2983 void menu::mark_tap_target () {
2984 interpreter ("set taptarget");
2985 tokenizer tz (interpreter.result);
2986 while (1) {
2987 string target; tz >> target;
2988 if (target == "") break;
2989 if (target == "gr") cb_gater.turn_on (DONT_CALL_LISTENER);
2990 else if (target == "am") cb_am.turn_on (DONT_CALL_LISTENER);
2991 else if (target == "fm") cb_fm.turn_on (DONT_CALL_LISTENER);
2992 else if (target == "os") cb_octave_shift.turn_on (DONT_CALL_LISTENER);
2993 }
2994 }
2995
~menu()2996 menu::~menu () {
2997 dlog << "--- destroying menu ---" << endl;
2998 widget_save ("d_menu", items, nitems);
2999 savespinners ();
3000 dlog << "--- destroyed menu ---" << endl;
3001 }
3002
clicked(button & b)3003 void octave_shift_listener::clicked (button& b) {
3004 if (&b == MENUP.ab_octave_up || &b == &uis.ab_octave_up) modulate_up (); else modulate_down ();
3005 }
3006
changed(field & f)3007 void octave_shift_listener::changed (field& f) {
3008 float v = f;
3009 v = octave_shift.set_bpm (v);
3010 static const string los = "Octave shift BPM = ";
3011 cons << YELLOW << los << v << eol;
3012 }
3013
changed(field & f)3014 void voice_volume_listener::changed (field& f) {
3015 VOICE_VOLUME = f;
3016 static const string vv ("Volume = ");
3017 cons << YELLOW << vv << VOICE_VOLUME << eol;
3018 }
3019
changed(field & f)3020 void drone_master_volume_listener::changed (field& f) {
3021 float dmv = f;
3022 din0.setdronemastervolume (dmv);
3023 }
3024
changed(field & f)3025 void gater_bpm_listener::changed (field& f) {
3026 float v = f;
3027 v = din0.gatr.set_bpm (v);
3028 static const string gt = "Gater BPM = ";
3029 cons << YELLOW << gt << v << eol;
3030 }
3031
changed(field & f)3032 void drone_handle_size_listener::changed (field& f) {
3033 din0.change_drone_handle_size (MENU.sp_change_drone_handle_size);
3034 }
3035
changed(field & f)3036 void drone_trail_length_listener::changed (field& f) {
3037 din0.change_drone_trail_points (MENU.sp_change_drone_trail_length);
3038 }
3039
changed(field & f)3040 void change_drone_vel_listener::changed (field& f) {
3041 din0.change_drone_vel (MENU.sp_change_drone_vel);
3042 }
3043
changed(field & f)3044 void change_drone_accel_listener::changed (field& f) {
3045 din0.change_drone_accel (MENU.sp_change_drone_accel);
3046 }
3047
changed(field & f)3048 void rotate_drone_vel_listener::changed (field& f) {
3049 din0.rotate_drone_vel (MENU.sp_rotate_drone_vel);
3050 }
3051
changed(field & f)3052 void drones_per_min_listener::changed (field& f) {
3053 din0.change_drones_per_min (MENU.sp_drones_per_min);
3054 }
3055
changed(field & f)3056 void drone_lifetime_listener::changed (field& f) {
3057 din0.change_drone_lifetime (MENU.sp_drone_lifetime);
3058 }
3059
changed(field & f)3060 void orbit_insertion_time_listener::changed (field& f) {
3061 din0.change_orbit_insertion_time (MENU.sp_orbit_insertion_time);
3062 }
3063
set_style(const string & style)3064 void style_listener::set_style (const string& style) {
3065 for (int i = 0; i < num_styles; ++i) {
3066 if (styles[i] == style) {
3067 id = i;
3068 string command ("set-style " + what + " " + style);
3069 interpreter (command);
3070 oplist.set_text (prefix + style);
3071 }
3072 }
3073 }
3074
get_style()3075 void style_listener::get_style () {
3076 string command ("get-style " + what);
3077 interpreter (command);
3078 oplist.set_text (prefix + interpreter.result);
3079 }
3080
next_style(int dir)3081 void style_listener::next_style (int dir) {
3082 id += dir;
3083 if (id < 0) id = last_style; else if (id >= num_styles) id = 0;
3084 set_style (styles[id]);
3085 }
3086
picked(label & lbl,int dir)3087 void style_listener::picked (label& lbl, int dir) {
3088 next_style (dir);
3089 }
3090
changed(checkbutton & cb)3091 void drone_commands_listener::changed (checkbutton& cb) {
3092 int state = cb.state;
3093 if (&cb == MENUP.cb_show_vel) din0.dinfo.vel = state; else
3094 if (&cb == MENUP.cb_show_accel) din0.dinfo.accel = state; else
3095 if (&cb == MENUP.cb_show_gravity) {if (state) din0.dinfo.gravity.show (); else din0.dinfo.gravity.hide ();} else
3096 if (&cb == MENUP.cb_show_anchors) din0.dinfo.anchor = state; else
3097 if (&cb == MENUP.seloncre) din0.dinfo.seloncre = state;
3098 else din0.dinfo.mesh_vars.sync = cb.state;
3099 }
3100
clicked(button & b)3101 void phrase_commands_listener::clicked (button& b) {
3102 TOGGLEMENU
3103 if (&b == MENUP.b_record_phrase) din0.do_phrase_recording ();
3104 else if (&b == MENUP.b_clear_phrases) din0.clear_all_phrases ();
3105 }
3106
read_mod()3107 void range_data::read_mod () {
3108 int& a = din0.ranges[din0.dinfo.sel_range].mod.active;
3109 mod = a;
3110 a = 0;
3111 }
3112
write_mod()3113 void range_data::write_mod () {
3114 din0.ranges[din0.dinfo.sel_range].mod.active = mod;
3115 }
3116
clicked(button & b)3117 void range_height_listener::clicked (button& b) {
3118 mouse_slider0.add (MENUP.rhl);
3119 MENU.rhl.read_mod ();
3120 activate_mouse_slider ();
3121 }
3122
moused(int dh,double scl)3123 void range_height_listener::moused (int dh, double scl) {
3124 din0.height_changed (din0.dinfo.sel_range, dh);
3125 }
3126
after_slide()3127 void range_height_listener::after_slide () {
3128 MENU.rhl.write_mod ();
3129 }
3130
read_mod()3131 void board_height_listener::read_mod () {
3132 int n = din0.num_ranges;
3133 moda.resize (n);
3134 for (int i = 0; i < n; ++i) {
3135 int& a = din0.ranges[i].mod.active;
3136 moda[i]=a;
3137 a = 0;
3138 }
3139 }
3140
write_mod()3141 void board_height_listener::write_mod () {
3142 int n = din0.num_ranges;
3143 for (int i = 0; i < n; ++i) din0.ranges[i].mod.active = moda[i];
3144 }
3145
moused(int dh,double scl)3146 void board_height_listener::moused (int dh, double scl) {
3147 din0.height_changed (-1, dh);
3148 }
3149
clicked(button & b)3150 void board_height_listener::clicked (button& b) {
3151 MENU.bhl.name = "Board height";
3152 MENU.bhl.orient = mouse_slider_listener::Y;
3153 mouse_slider0.add (MENUP.bhl);
3154 MENU.bhl.read_mod ();
3155 activate_mouse_slider ();
3156 }
3157
after_slide()3158 void board_height_listener::after_slide () {
3159 MENU.bhl.write_mod ();
3160 }
3161
clicked(button & b)3162 void set_range_listener::clicked (button& b) {
3163 if (&b == MENUP.b_selected_to_all) {
3164 din0.selected_range_to_all (i);
3165 } else if (&b == MENUP.b_default_to_selected) {
3166 din0.default_range_to_selected (i);
3167 } else if (&b == MENUP.b_default_to_all) {
3168 din0.default_range_to_all (i);
3169 }
3170 }
3171
picked(label & lbl,int dir)3172 void set_range_listener::picked (label& lbl, int dir) {
3173 i = !i;
3174 static const char* opts [] = {" Set Width?", " Set Height?"};
3175 lbl.set_text (opts[i]);
3176 }
3177
clicked(button & b)3178 void range_width_listener::clicked (button& b) {
3179 if (&b == MENUP.b_adjust_range_left) {
3180 MENU.arl.range = din0.dinfo.sel_range;
3181 MENU.arl.read_mod ();
3182 mouse_slider0.add (MENUP.arl);
3183 activate_mouse_slider ();
3184 } else if (&b == MENUP.b_adjust_range_right) {
3185 MENU.arr.range = din0.dinfo.sel_range;
3186 MENU.arr.read_mod ();
3187 mouse_slider0.add (MENUP.arr);
3188 activate_mouse_slider ();
3189 } else {
3190 MENU.arb.range = din0.dinfo.sel_range;
3191 MENU.arb.read_mod ();
3192 mouse_slider0.add (MENUP.arb);
3193 activate_mouse_slider ();
3194 }
3195 din0.adjustranges.set ();
3196 }
3197
moused(int dir,double scl)3198 void adjust_range_left_listener::moused (int dir, double scl) {
3199 if (din0.range_left_changed (range, dir, 1)) {
3200 din0.refresh_drones (0, range);
3201 din0.find_visible_ranges ();
3202 }
3203 }
3204
after_slide()3205 void adjust_range_left_listener::after_slide () {
3206 MENU.arl.write_mod ();
3207 din0.adjustranges.unset ();
3208 }
3209
moused(int dir,double scl)3210 void adjust_range_right_listener::moused (int dir, double scl) {
3211 if (din0.range_right_changed (range, dir, 1)) {
3212 din0.refresh_drones (range, din0.last_range);
3213 din0.find_visible_ranges ();
3214 }
3215 }
3216
after_slide()3217 void adjust_range_right_listener::after_slide () {
3218 MENU.arr.write_mod ();
3219 din0.adjustranges.unset ();
3220 }
3221
moused(int dir,double scl)3222 void adjust_range_both_listener::moused (int dir, double scl) {
3223 int rl = din0.range_left_changed (range, -dir, 1);
3224 int rr = din0.range_right_changed (range, dir, 1);
3225 if (rl || rr) {
3226 din0.refresh_all_drones ();
3227 din0.find_visible_ranges ();
3228 }
3229 }
3230
after_slide()3231 void adjust_range_both_listener::after_slide () {
3232 MENU.arb.write_mod ();
3233 din0.adjustranges.unset ();
3234 }
3235
VALUE_CHANGED(menu,sp_range_lis)3236 VALUE_CHANGED(menu, sp_range_lis) {
3237 din0.dinfo.sel_range = f;
3238 MENU.load_range_mod (din0.dinfo.sel_range);
3239 }
3240
VALUE_CHANGED(menu,sp_ran_mod_width_lis)3241 VALUE_CHANGED(menu, sp_ran_mod_width_lis) {
3242 float v = f;
3243 din0.ranges[din0.dinfo.sel_range].mod.fm.depth = v;
3244 sprintf (BUFFER, "Range %d, Modulation Width = %0.3f", din0.dinfo.sel_range, v);
3245 cons << BUFFER << eol;
3246 }
3247
VALUE_CHANGED(menu,sp_ran_mod_width_bpm_lis)3248 VALUE_CHANGED(menu, sp_ran_mod_width_bpm_lis) {
3249 float v = f;
3250 din0.ranges[din0.dinfo.sel_range].mod.fm.bv.set_bpm (v);
3251 sprintf (BUFFER, "Range %d, Modulation Width BPM = %0.3f", din0.dinfo.sel_range, v);
3252 cons << BUFFER << eol;
3253 }
3254
VALUE_CHANGED(menu,sp_ran_mod_height_lis)3255 VALUE_CHANGED(menu, sp_ran_mod_height_lis) {
3256 float v = f;
3257 din0.ranges[din0.dinfo.sel_range].mod.am.depth = v;
3258 sprintf (BUFFER, "Range %d, Modulation Height = %0.3f", din0.dinfo.sel_range, v);
3259 cons << BUFFER << eol;
3260 }
3261
VALUE_CHANGED(menu,sp_ran_mod_height_bpm_lis)3262 VALUE_CHANGED(menu, sp_ran_mod_height_bpm_lis) {
3263 float v = f;
3264 din0.ranges[din0.dinfo.sel_range].mod.am.bv.set_bpm (v);
3265 sprintf (BUFFER, "Range %d, Modulation Height BPM = %0.3f", din0.dinfo.sel_range, v);
3266 cons << BUFFER << eol;
3267 }
3268
edited(curve_editor * ed,int i)3269 void range_mod_lis::edited (curve_editor* ed, int i) {
3270 din0.update_range_mod_solvers (i, ed->mix);
3271 curve_listener::edited (ed, i);
3272 }
3273
load_range(int r)3274 void menu::load_range (int r) {
3275 sp_range.set_value (r);
3276 load_range_mod (r);
3277 }
3278
load_range_mod(int r)3279 void menu::load_range_mod (int r) {
3280 range& ri = din0.ranges [r];
3281 cb_mod_ran.set_state (ri.mod.active, 0);
3282 sp_ran_mod_width.set_value (ri.mod.fm.depth);
3283 sp_ran_mod_width_bpm.set_value (ri.mod.fm.bv.bpm);
3284 sp_ran_mod_height.set_value (ri.mod.am.depth);
3285 sp_ran_mod_height_bpm.set_value (ri.mod.am.bv.bpm);
3286 ol_fixed.set_text (ol_fixed_lbls [ri.fixed]);
3287 print_range_info (ri);
3288 }
3289
picked(label & l,int dir)3290 void snap_drones_listener::picked (label& l, int dir) {
3291 din0.dinfo.snap.style += dir;
3292 static const char* ss [] = {" Free", " Slide", " Lock", " Mirror"};
3293 wrap<int> (din_info::snap_t::FREE, din0.dinfo.snap.style, din_info::snap_t::MIRROR);
3294 l.set_text (ss[din0.dinfo.snap.style]);
3295 }
3296
changed(field & f)3297 void snap_drones_listener::changed (field& f) {
3298 float v = f;
3299 if (&f == MENUP.sp_snap_left.f_value) {
3300 float dl = v - din0.dinfo.snap.left;
3301 din0.dinfo.snap.left = v;
3302 if (din0.dinfo.snap.style > din_info::snap_t::FREE) {
3303 if (din0.dinfo.snap.style == din_info::snap_t::SLIDE) {
3304 din0.dinfo.snap.right += dl;
3305 }
3306 else if (din0.dinfo.snap.style == din_info::snap_t::LOCK) {
3307 din0.dinfo.snap.right = din0.dinfo.snap.left;
3308 }
3309 else {
3310 din0.dinfo.snap.right = 1.0f - din0.dinfo.snap.left;
3311 }
3312 MENU.sp_snap_right.set_value (din0.dinfo.snap.right);
3313 }
3314 } else if (&f == MENUP.sp_snap_right.f_value) {
3315 float dr = v - din0.dinfo.snap.right;
3316 din0.dinfo.snap.right = v;
3317 if (din0.dinfo.snap.style > din_info::snap_t::FREE) {
3318 if (din0.dinfo.snap.style == din_info::snap_t::LOCK) {
3319 din0.dinfo.snap.left = din0.dinfo.snap.right;
3320 } else if (din0.dinfo.snap.style == din_info::snap_t::SLIDE) {
3321 din0.dinfo.snap.left += dr;
3322 } else {
3323 din0.dinfo.snap.left = 1.0f - din0.dinfo.snap.right; // mirror
3324 }
3325 MENU.sp_snap_left.set_value (din0.dinfo.snap.left);
3326 }
3327 }
3328
3329 if (din0.dinfo.snap.left > din0.dinfo.snap.right || din0.dinfo.snap.left < 0.0f || din0.dinfo.snap.right > 1.0f)
3330 cons << RED;
3331 else
3332 cons << GREEN;
3333 sprintf (BUFFER, "Snap left = %0.3f, Snap right = %0.3f", din0.dinfo.snap.left, din0.dinfo.snap.right);
3334 cons << BUFFER << eol;
3335 }
3336
changed(field & f)3337 void scope_listener::changed (field& f) {
3338 int n = f;
3339 if (&f == MENUP.sp_scope_height.f_value) {
3340 scope.set_height (n);
3341 static const string ht = "Height = ";
3342 cons << YELLOW << ht << n << eol;
3343 } else {
3344 scope.set_num_samples (n);
3345 static const string ns = "Samples = ";
3346 cons << YELLOW << ns << n << eol;
3347 }
3348 }
3349
changed(checkbutton & cb)3350 void scope_listener::changed (checkbutton& cb) {
3351 scope.visible = cb.state;
3352 }
3353
setup()3354 void scope_listener::setup () {
3355 if (scope.visible) MENU.cb_scope.turn_on (0); else MENU.cb_scope.turn_off (0);
3356 MENU.sp_scope_height.set_value (scope.height);
3357 MENU.sp_scope_samples.set_value (scope.num_samples);
3358 }
3359
changed(tap_display & td)3360 void tap_bpm_listener::changed (tap_display& td) {
3361 sprintf (BUFFER, "%.3f", td.bpm);
3362 MENU.l_tap_bpm_value.set_text (BUFFER);
3363 extern double TAP_BPM; TAP_BPM = td.bpm;
3364 Tcl_UpdateLinkedVar (interpreter.interp, "tapbpm");
3365 }
3366
changed(checkbutton & cb)3367 void tap_bpm_listener::changed (checkbutton& cb) {
3368 checkbutton* cbs [] = {MENUP.cb_am, MENUP.cb_fm, MENUP.cb_gater, MENUP.cb_octave_shift};
3369 const char* targets [] = {"am", "fm", "gr", "os"};
3370 for (int i = 0; i < 4; ++i) {
3371 checkbutton* cbi = cbs[i];
3372 if (&cb == cbi) {
3373 if (cbi->state)
3374 sprintf (BUFFER, "add-tap-target %s", targets[i]);
3375 else
3376 sprintf (BUFFER, "remove-tap-target %s", targets[i]);
3377 interpreter (BUFFER);
3378 return;
3379 }
3380 }
3381 if (&cb == MENUP.cb_auto_reset) {
3382 if (MENU.cb_auto_reset.state) interpreter ("set resetbeat 1"); else interpreter ("set resetbeat 0");
3383 }
3384 }
3385
clicked(button & b)3386 void pan_zoom_listener::clicked (button& b) {
3387 if (&b == MENUP.abe_left) {CRVED->do_panx (1); cons << YELLOW << "You can press a to move curves left" << eol;}
3388 else if (&b == MENUP.abe_right) {CRVED->do_panx (-1); cons << YELLOW << "You can press d to move curves right"<< eol;}
3389 else if (&b == MENUP.abe_up) {CRVED->do_pany (-1); cons << YELLOW << "You can press w to move curves up" << eol;}
3390 else if (&b == MENUP.abe_down) {CRVED->do_pany (+1); cons << YELLOW << "You can press s to move curves down" << eol;}
3391 else if (&b == MENUP.pb_zoom_in) {CRVED->do_zoom (-1); cons << YELLOW << "You can press e to zoom in" << eol;}
3392 else {CRVED->do_zoom (+1);cons << YELLOW << "You can press q to zoom out" << eol;}
3393 }
3394
changed(checkbutton & cb)3395 void snap_listener::changed (checkbutton& cb) {
3396 checkbutton* snaps [] = {MENUP.cb_snapnone, MENUP.cb_snapx, MENUP.cb_snapy, MENUP.cb_snapboth};
3397 int ids [] = {basic_editor::SNAP_NONE, basic_editor::SNAP_X, basic_editor::SNAP_Y, basic_editor::SNAP_BOTH};
3398 const char* mesgs [] = {"You can press n to turn off snapping", "You can press x to snap X",
3399 "You can press y to snap Y", "You can press b to snap both X and Y"};
3400 for (int i = 0; i < 4; ++i) snaps[i]->turn_off (DONT_CALL_LISTENER);
3401 for (int i = 0; i < 4; ++i) {
3402 if (&cb == snaps[i]) {
3403 CRVED->set_snap (ids[i]);
3404 cons << YELLOW << mesgs[i] << eol;
3405 break;
3406 }
3407 }
3408 }
3409
set_snap(int what)3410 void menu::set_snap (int what) {
3411 checkbutton* snaps [] = {&cb_snapnone, &cb_snapx, &cb_snapy, &cb_snapboth};
3412 int ids [] = {basic_editor::SNAP_NONE, basic_editor::SNAP_X, basic_editor::SNAP_Y, basic_editor::SNAP_BOTH};
3413 for (int i = 0; i < 4; ++i) {
3414 checkbutton* si = snaps[i];
3415 if (what == ids[i])
3416 si->turn_on (DONT_CALL_LISTENER);
3417 else
3418 si->turn_off (DONT_CALL_LISTENER);
3419 }
3420 }
3421
set_vertices_carry_tangents(int i)3422 void menu::set_vertices_carry_tangents (int i) {
3423 const static char* vct [] = {" Vertices desert tangents", " Vertices carry tangents"};
3424 ol_vertices_carry_tangents.option.set_text (vct[i]);
3425 }
3426
set_mirror_tangents(int i)3427 void menu::set_mirror_tangents (int i) {
3428 const static char* mit [] = {" Tangents are not mirrored", " Tangents are mirrored"};
3429 ol_mirror_tangents.option.set_text (mit[i]);
3430 }
3431
set_repeat(button ** B,int n,double dt)3432 void menu::set_repeat (button** B, int n, double dt) {
3433 for (int i = 0; i < n; ++i) {
3434 button* bi = B[i];
3435 bi->click_repeat = 1;
3436 bi->first_repeat_time = bi->subsequent_repeat_time = dt;
3437 }
3438 }
3439
set_pan_repeat(double dt)3440 void menu::set_pan_repeat (double dt) {
3441 button* ab [] = {&abe_left, &abe_right, &abe_up, &abe_down, &abm_left, &abm_right, &abm_up, &abm_down};
3442 set_repeat (ab, 8, dt);
3443 }
3444
set_zoom_repeat(double dt)3445 void menu::set_zoom_repeat (double dt) {
3446 button* zb [] = {&pb_zoom_in, &mb_zoom_out, &bm_zoom_in, &bm_zoom_out};
3447 set_repeat (zb, 4, dt);
3448 }
3449
clicked(button & b)3450 void menu::curve_ops_listener::clicked (button& b) {
3451 int toggle = 1;
3452 if (&b == MENUP.b_undo) {
3453 cons << YELLOW << "You can press z to undo!" << eol;
3454 CRVED->do_undo ();
3455 toggle = 0;
3456 } else
3457 if (&b == MENUP.b_redo) {
3458 cons << YELLOW << "You can press LSHIFT + z to redo!" << eol;
3459 CRVED->do_redo ();
3460 toggle = 0;
3461 } else
3462 if (&b == MENUP.abl_left) {
3463 cons << YELLOW << "You can press 9 to load previous curve from library" << eol;
3464 CRVED->do_load_curve (-1);
3465 toggle = 0;
3466 } else
3467 if (&b == MENUP.abl_right) {
3468 cons << YELLOW << "You can press 0 to load next curve from library" << eol;
3469 CRVED->do_load_curve (+1);
3470 toggle = 0;
3471 }
3472 if (&b == MENUP.b_insert_vertex) {
3473 CRVED->insert_using_menu ();
3474 } else if (&b == MENUP.b_delete_vertex) {
3475 CRVED->remove_using_menu ();
3476 } else if (&b == MENUP.b_fold_tangents) {
3477 CRVED->fold_tangents_using_menu ();
3478 } else if (&b == MENUP.b_unfold_tangents) {
3479 CRVED->unfold_tangents_using_menu ();
3480 } else if (&b == MENUP.ol_mirror.option) {
3481 CRVED->mirror_using_menu ();
3482 } else if (&b == MENUP.b_copy) {
3483 CRVED->copy_using_menu ();
3484 } else if (&b == MENUP.b_paste) {
3485 CRVED->paste_using_menu ();
3486 } else if (&b == MENUP.b_swap_curves) {
3487 CRVED->swap ();
3488 } else if (&b == MENUP.b_pick_curve) {
3489 CRVED->do_pick_curve ();
3490 }
3491 // to library
3492 else if (&b == MENUP.b_add_curve) {
3493 CRVED->add_curve ();
3494 } else if (&b == MENUP.b_replace_curve) {
3495 CRVED->replace_curve ();
3496 } else if (&b == MENUP.b_delete_curve) {
3497 CRVED->delete_curve ();
3498 } else if (&b == MENUP.b_draw_replacement_curve) {
3499 CRVED->draw_replacement_curve_using_menu ();
3500 } else if (&b == MENUP.b_start_capture) {
3501 CRVED->start_mouse_capture_from_menu ();
3502 } else if (&b == MENUP.b_assign_capture) {
3503 CRVED->assign_mouse_capture_from_menu ();
3504 } else if (&b == MENUP.b_stop_rotating) {
3505 MENU.sp_curve_rpm.set_value (0);
3506 CRVED->set_rpm (0);
3507 }
3508 if (toggle) TOGGLEMENU
3509 }
3510
changed(checkbutton & cb)3511 void menu::curve_ops_listener::changed (checkbutton& cb) {
3512 int tog = 0;
3513 if (&cb == MENUP.cb_mark_segments) {
3514 CRVED->mark_segments = cb.state;
3515 } else if (&cb == MENUP.cb_label_vertices) {
3516 CRVED->label_vertices = cb.state;
3517 } else if (&cb == MENUP.cb_show_waveform_samples) {
3518 CRVED->toggle_waveform_samples_display ();
3519 } else if (&cb == MENUP.cb_draw_curve) {
3520 CRVED->draw_curve_only = cb.state;
3521 } else {
3522 CRVED->overlay = cb.state;
3523 string n (get_current_instrument()->name);
3524 if (cb.state)
3525 cons << GREEN << "Overlaid the " << n << eol;
3526 else
3527 cons << RED << "Removed " << n << " from overlay." << eol;
3528 tog = 1;
3529 }
3530 if (tog) TOGGLEMENU
3531 }
3532
changed(field & f)3533 void menu::curve_ops_listener::changed (field& f) {
3534 if (&f == MENUP.sp_waveform_hz.f_value) {
3535 CRVED->set_hz (f);
3536 } else if (&f == MENUP.sp_waveform_periods.f_value) {
3537 CRVED->set_periods (f);
3538 } else if (&f == MENUP.sp_curve_rpm.f_value) {
3539 CRVED->set_rpm (f);
3540 } else if (&f == MENUP.sp_curve_limit.f_value) {
3541 CRVED->set_limit (f);
3542 } else {
3543 if (f.text == "") f.set_text ("nameless");
3544 CRVED->set_picked_curve_name (f.text);
3545 }
3546 }
3547
3548
typing(field & f)3549 void recording_listener::typing (field& f) {
3550 string fname (recorder0.folder + f.text);
3551 string cmd ("file exists " + fname);
3552 interpreter (cmd); int result; stringstream ss; ss << interpreter.result; ss >> result;
3553 if (result) MENU.b_save.set_text ("Overwrite"); else MENU.b_save.set_text ("Save");
3554 recorder0.fname = f.text;
3555 }
3556
changed(checkbutton & cb)3557 void recording_listener::changed (checkbutton& cb) {
3558 int state = cb.state;
3559 if (state == 0) { // show recording save section of file menu
3560 MENU.changed (MENU.cb_file);
3561 if (MENU.show == 0) TOGGLEMENU
3562 } else { // close file menu
3563 if (MENU.show == 1) TOGGLEMENU
3564 }
3565 dont_call_listener (uis.cb_record, state);
3566 dont_call_listener (MENU.cb_record, state);
3567 }
3568
handle_split(int & var,int dir,float t)3569 void mondrian_listener::handle_split (int& var, int dir, float t) {
3570 switch (var) {
3571 case 0: // into 2 boxes
3572 mondrian0.split_rect (dir, t);
3573 break;
3574 case 1: // into notes
3575 mondrian0.multi_split_rect (dir);
3576 break;
3577 case 2: // into n x n grid
3578 mondrian0.multi_split_rect (mondrian0.num_boxes, dir);
3579 }
3580 }
3581
clicked(button & b)3582 void mondrian_listener::clicked (button& b) {
3583 int toggle = 1;
3584 if (&b == MENUP.b_split_horizontal) handle_split (hsplit, split::HORIZONTAL, mondrian0.win.mousey);
3585 else if (&b == MENUP.b_split_vertical) handle_split (vsplit, split::VERTICAL, mondrian0.win.mousex);
3586 else if (&b == MENUP.b_add_balls) mondrian0.do_add_balls (mondrian0.added_ball_type);
3587 else if (&b == MENUP.b_add_remove_slits) mondrian0.start_slitting ();
3588 else if (&b == MENUP.b_modulate_balls_up) {if (!mondrian0.modulate_balls (+1)) cons << RED << "Please select some balls!" << eol;}
3589 else if (&b == MENUP.b_modulate_balls_down) {if (!mondrian0.modulate_balls (-1)) cons << RED << "Please select some balls!" << eol;}
3590 else if (&b == MENUP.b_select_all_targets) {mondrian0.select_all_targets ();toggle=0;}
3591 else if (&b == MENUP.b_invert_selected_targets) {mondrian0.invert_selected_targets ();toggle=0;}
3592 else if (&b == MENUP.b_select_targets_in_box) {mondrian0.select_box_targets ();toggle=0;}
3593 else if (&b == MENUP.b_delete_box) mondrian0.delete_current_rect ();
3594 else if (&b == MENUP.b_delete_all_boxes) mondrian0.delete_all_rects = 1;
3595 else if (&b == MENUP.b_freeze_balls) mondrian0.freeze_balls (mondrian0.get_balls());
3596 else if (&b == MENUP.b_thaw_balls) mondrian0.thaw_balls (mondrian0.get_balls());
3597 else if (&b == MENUP.b_delete_all_targets) mondrian0.delete_all_targets ();
3598 else if (&b == MENUP.b_delete_selected_targets) mondrian0.delete_selected_targets ();
3599 else if (&b == MENUP.b_move_selected_balls) mondrian0.do_move_balls ();
3600 else if (&b == MENUP.b_toggle_wreckers) mondrian0.toggle_balls_type (ball::WRECKER);
3601 else if (&b == MENUP.b_toggle_healers) mondrian0.toggle_balls_type (ball::HEALER);
3602 else if (&b == MENUP.b_toggle_bouncers) mondrian0.toggle_balls_type (ball::BOUNCER);
3603 else if (&b == MENUP.b_switch_ball_type) mondrian0.switch_balls_type ();
3604 else if (&b == MENUP.b_select_wreckers) mondrian0.select_type (ball::WRECKER);
3605 else if (&b == MENUP.b_select_healers) mondrian0.select_type (ball::HEALER);
3606 else if (&b == MENUP.b_remove_slits_on_edge) mondrian0.remove_slits_on_current_edge ();
3607 else if (&b == MENUP.b_toggle_slit_anim) mondrian0.toggle_slit_anim ();
3608 else if (&b == MENUP.b_clear_modulations) mondrian0.clear_modulations (mondrian0.get_balls());
3609 else if (&b == MENUP.b_auto_change_direction_clockwise) {mondrian0.set_auto_rotate (-1);}
3610 else if (&b == MENUP.b_auto_change_direction_anti_clockwise) {mondrian0.set_auto_rotate (1);}
3611 else if (&b == MENUP.b_stop_auto_changing_direction) {mondrian0.set_auto_rotate (0);}
3612 else if (&b == MENUP.b_flip_direction) {mondrian0.flip_velocity();}
3613 else if (&b == MENUP.b_make_random_color) mondrian0.randomise_box_color();
3614 else if (&b == MENUP.b_make_note_grid) mondrian0.make_note_grid ();
3615 else if (&b == MENUP.b_make_nxn_grid) mondrian0.make_nxn_grid ();
3616 else if (&b == MENUP.b_ball_trig) mondrian0.toggle_triggered_sound ();
3617 else if (&b == MENUP.abm_left) {mondrian0.do_panx (1); toggle=0;}
3618 else if (&b == MENUP.abm_right) {mondrian0.do_panx (-1); toggle=0;}
3619 else if (&b == MENUP.abm_up) {mondrian0.do_pany (+1);toggle=0;}
3620 else if (&b == MENUP.abm_down) {mondrian0.do_pany (-1); toggle=0;}
3621 else if (&b == MENUP.bm_zoom_in) {mondrian0.do_zoom(-1); toggle=0;}
3622 else if (&b == MENUP.bm_zoom_out) {mondrian0.do_zoom(+1); toggle=0;}
3623 if (toggle) TOGGLEMENU
3624 }
3625
changed(checkbutton & cb)3626 void mondrian_listener::changed (checkbutton& cb) {
3627 if (&cb == MENUP.cb_auto_split_box) {
3628 mondrian0.auto_split_rect.active = cb.state;
3629 } else if (&cb == MENUP.cb_auto_delete_box) {
3630 mondrian0.auto_del_rect.active = cb.state;
3631 } else if (&cb == MENUP.cb_draw_boxes) {
3632 mondrian0.draw__boxes = cb.state;
3633 } else if (&cb == MENUP.cb_fill_boxes) {
3634 mondrian0.fill_boxes = cb.state;
3635 } else if (&cb == MENUP.cb_draw_notes) {
3636 mondrian0.draw__notes = cb.state;
3637 } else if (&cb == MENUP.cb_label_notes) {
3638 mondrian0.label_notes = cb.state;
3639 } else if (&cb == MENUP.cb_label_hz_vol) {
3640 mondrian0.label_hz_vol = cb.state;
3641 } else if (&cb == MENUP.cb_draw_ball_position) {
3642 mondrian0.draw_ball.position = cb.state;
3643 } else if (&cb == MENUP.cb_draw_ball_heading) {
3644 mondrian0.draw_ball.heading = cb.state;
3645 } else if (&cb == MENUP.cb_draw_ball_trails) {
3646 mondrian0.draw_ball.trails = cb.state;
3647 } else if (&cb == MENUP.cb_mondrian_auto_adjust_voices) {
3648 mondrian0.auto_adjust_voices = cb.state;
3649 }
3650 }
3651
changed(field & f)3652 void ball_speed_listener::changed (field& f) {
3653 mondrian0.change_speed (MENU.sp_mondrian_change_speed, MENU.sp_mondrian_change_speed.dir_delta ());
3654 }
3655
changed(field & f)3656 void ball_direction_listener::changed (field& f) {
3657 mondrian0.rotate_velocity (MENU.sp_mondrian_change_dir.dir);
3658 }
3659
changed(field & f)3660 void ball_volume_listener::changed (field& f) {
3661 mondrian0.change_ball_vol_mult (MENU.sp_mondrian_change_vol);
3662 }
3663
changed(field & f)3664 void trail_length_listener:: changed (field& f) {
3665 mondrian0.change_trail_size (MENU.sp_mondrian_change_trail_size);
3666 }
3667
changed(field & f)3668 void ball_attack_time_listener:: changed (field& f) {
3669 mondrian0.change_attack_time_kb (MENU.sp_mondrian_change_attack_time);
3670 }
3671
changed(field & f)3672 void ball_decay_time_listener:: changed (field& f) {
3673 mondrian0.change_decay_time_kb (MENU.sp_mondrian_change_decay_time);
3674 }
3675
changed(field & f)3676 void slit_size_listener:: changed (field& f) {
3677 mondrian0.change_slit_size (MENU.sp_mondrian_change_slit_size);
3678 }
3679
changed(field & f)3680 void slit_anim_time_listener:: changed (field& f) {
3681 mondrian0.change_slit_anim_time (MENU.sp_mondrian_change_slit_anim_time);
3682 }
3683
changed(field & f)3684 void note_poly_radius_listener::changed (field& f) {
3685 mondrian0.set_note_poly_radius (float(f));
3686 }
3687
changed(field & f)3688 void note_poly_points_listener::changed (field& f) {
3689 mondrian0.set_note_poly_points (int(f));
3690 }
3691
changed(field & f)3692 void mondrian_listener::changed (field& f) {
3693 /*if (&f == MENUP.sp_mondrian_change_dir.f_delta) {
3694 mondrian0.delta_rotate_velocity = float (MENU.sp_mondrian_change_dir.f_delta);
3695 button* pb[] = {MENUP.sp_mondrian_change_dir.inc, MENUP.sp_mondrian_change_dir.dec};
3696 MENU.set_repeat (pb, 2, 0.005 * mondrian0.delta_rotate_velocity);
3697 }
3698 else */
3699 if (&f == MENUP.sp_mondrian_change_speed.f_delta) mondrian0.delta_speed = f;
3700 else if (&f == MENUP.sp_mondrian_min_voices.f_value) {
3701 mondrian0.min_voices = f;
3702 uis.update_bottom_line ();
3703 cons << YELLOW << "Min voices = " << mondrian0.min_voices << eol;
3704 } else if (&f == MENUP.sp_mondrian_num_boxes.f_value) {
3705 mondrian0.num_boxes = f;
3706 cons << YELLOW << "Number of boxes = " << mondrian0.num_boxes << eol;
3707 } else if (&f == MENUP.sp_auto_split_time.f_value) {
3708 mondrian0.auto_split_rect.triggert = f;
3709 cons << YELLOW << "Split box every = " << mondrian0.auto_split_rect.triggert << " secs" << eol;
3710 } else if (&f == MENUP.sp_auto_delete_time.f_value) {
3711 mondrian0.auto_del_rect.triggert = f;
3712 cons << YELLOW << "Delete box every = " << mondrian0.auto_del_rect.triggert << " secs" << eol;
3713 } else {
3714 mondrian::min_split_size = f;
3715 cons << YELLOW << "Min split size = " << mondrian::min_split_size << eol;
3716 }
3717 }
3718
handle_auto_pick_box(options_list & ol,int dir,int & v)3719 void mondrian_listener::handle_auto_pick_box (options_list& ol, int dir, int& v) {
3720 v += dir;
3721 wrap<int> (rect::EARLIEST, v, rect::BALLED);
3722 ol.set_text (pick_box_types[v]);
3723 }
3724
picked(label & lbl,int dir)3725 void mondrian_listener::picked (label& lbl, int dir) {
3726 if (&lbl == MENUP.ol_auto_pick_box_split.option) {
3727 handle_auto_pick_box (MENU.ol_auto_pick_box_split, dir, mondrian0.split_leaf);
3728 } else if (&lbl == MENUP.ol_auto_pick_box_delete.option) {
3729 handle_auto_pick_box (MENU.ol_auto_pick_box_delete, dir, mondrian0.delete_leaf);
3730 } else if (&lbl == MENUP.ol_auto_split_at.option) {
3731 mondrian0.auto_split_at += dir;
3732 if (mondrian0.auto_split_at < split::NOTES) mondrian0.auto_split_at = split::ANYWHERE;
3733 else if (mondrian0.auto_split_at > split::ANYWHERE) mondrian0.auto_split_at = split::NOTES;
3734 MENU.ol_auto_split_at.set_text (auto_split_at_types [mondrian0.auto_split_at]);
3735 } else if (&lbl == MENUP.ol_auto_split_orient.option) {
3736 mondrian0.auto_split_orient += dir;
3737 if (mondrian0.auto_split_orient < split::HORIZONTAL) mondrian0.auto_split_orient = split::BOTH;
3738 else if (mondrian0.auto_split_orient > split::BOTH) mondrian0.auto_split_orient = split::HORIZONTAL;
3739 MENU.ol_auto_split_orient.set_text (auto_split_orient_types [mondrian0.auto_split_orient]);
3740 } else if (&lbl == MENUP.ol_ball_types.option) {
3741 mondrian0.added_ball_type += dir;
3742 if (mondrian0.added_ball_type < ball::BOUNCER)
3743 mondrian0.added_ball_type = ball::HEALER;
3744 else if (mondrian0.added_ball_type > ball::HEALER)
3745 mondrian0.added_ball_type = ball::BOUNCER;
3746 MENU.ol_ball_types.set_text (ball::types_str[mondrian0.added_ball_type]);
3747 } else if (&lbl == MENUP.ol_split_types_h.option) {
3748 hsplit += dir;
3749 check_split_type (MENU.ol_split_types_h, hsplit);
3750 } else if (&lbl == MENUP.ol_split_types_v.option) {
3751 vsplit += dir;
3752 check_split_type (MENU.ol_split_types_v, vsplit);
3753 } else if (&lbl == MENUP.ol_selection_targets.option) {
3754 mondrian0.clear_selected_targets ();
3755 mondrian0.sel_tar = !mondrian0.sel_tar;
3756 MENU.ol_selection_targets.set_text (selection_targets[mondrian0.sel_tar]);
3757 static const char* bb [] = {"Select all balls", "Select balls in box", "Invert selected balls", "Delete all balls", "Delete selected balls"};
3758 static const char* bs [] = {"Select all slits", "Select slits in box", "Invert selected slits", "Remove all slits", "Remove selected slits"};
3759 const char** pb [] = {bs, bb};
3760 button* bt [] = {
3761 MENUP.b_select_all_targets, MENUP.b_select_targets_in_box,
3762 MENUP.b_invert_selected_targets, MENUP.b_delete_all_targets,
3763 MENUP.b_delete_selected_targets
3764 };
3765 const char** cb = pb[mondrian0.sel_tar];
3766 for (int i = 0; i < 5; ++i) bt[i]->set_text (cb[i]);
3767 }
3768 }
3769
check_split_type(options_list & ol,int & o)3770 void mondrian_listener::check_split_type (options_list& ol, int& o) {
3771 if (o < 0) o = MAX_SPLIT_TYPES; else if (o > MAX_SPLIT_TYPES) o = 0;
3772 ol.set_text (split_types[o]);
3773 }
3774
3775
binaural_drones_listener()3776 binaural_drones_listener::binaural_drones_listener () : select_rule (GREATER_THAN_EQUAL), select_what (0) {
3777 val[EQUAL] = "0";
3778 val[GREATER_THAN_EQUAL] = val[LESSER_THAN_EQUAL]= "100";
3779 val[ID] = "1 2 1";
3780 val[RANGE] = "100 200";
3781 just = binaural_drone::CENTER;
3782 }
3783
changed(field & f)3784 void binaural_drones_listener::changed (field& f) {
3785 float v = float(f);
3786 if (&f == MENUP.lf_bd_start_pitch.fld) {
3787 binaural_drones0.starting_pitch = v;
3788 } else if (&f == MENUP.lf_master_volume.fld) {
3789 float ov = binaural_drones0.master_volume * 100.0f;
3790 float mv = v / 100.0f;
3791 binaural_drones0.master_volume = mv;
3792 stringstream cmd;
3793 cmd << "set-all-binaurals-volume " << mv;
3794 interpreter (cmd.str());
3795 sprintf (BUFFER, "Master Volume from %0.2f%% to %0.2f%% : please wait or ESC to abort", ov, v);
3796 cons << YELLOW << BUFFER << eol;
3797 } else if (&f == MENUP.lf_vol_fade_time.fld) {
3798 binaural_drones0.vol_fader.set_duration (v);
3799 } else if (&f == MENUP.lf_pitch_fade_time.fld) {
3800 binaural_drones0.pitch_fader.set_duration (v);
3801 } else if (&f == MENUP.lf_modulation_amount.fld) {
3802 if (v < 1.0f) {
3803 v = 1.0f;
3804 MENU.lf_modulation_amount.fld.set_text (v);
3805 }
3806 binaural_drones0.modulation_amount = v;
3807 } else if (&f == MENUP.lf_bd_spacing.fld) {
3808 binaural_drones0.spacing = v;
3809 } else if (&f == MENUP.bdf_value) {
3810 val[select_rule] = MENU.bdf_value.text;
3811 MENU.bdl.clicked (MENU.bbd_select2);
3812 } else if (&f == MENUP.lf_vol.fld) {
3813 float vp = v / 100.0f;
3814 sprintf (BUFFER, "set-selected-binaurals-volume %f", vp);
3815 interpreter (BUFFER);
3816 } else if (&f == MENUP.lf_l.fld) {
3817 set_hz (binaural_drone::LEFT, v);
3818 } else if (&f == MENUP.lf_r.fld) {
3819 set_hz (binaural_drone::RIGHT, v);
3820 } else if (&f == MENUP.lf_sep.fld) {
3821 int j = 0;
3822 for (int i = 0; i < MENU.il_binaural_drones.n; ++i) {
3823 if (MENU.il_binaural_drones.items[i].sel) {
3824 binaural_drone* bi = binaural_drones0.binaural_drones[i];
3825 bi->set_sep (v);
3826 ++j;
3827 }
3828 }
3829 if (j)
3830 binaural_drones0.pitch_fader.start ("Separation Hz set");
3831 else
3832 cons << RED << "Please select some binaural drone pairs" << eol;
3833 }
3834 }
3835
set_hz(int w,float v)3836 void binaural_drones_listener::set_hz (int w, float v) {
3837
3838 int n = MENU.il_binaural_drones.num_selected ();
3839 if (n == 0) {
3840 cons << RED << "Please select some binaural drone pairs" << eol;
3841 return;
3842 }
3843
3844 if (n == 1) {
3845 int i = MENU.il_binaural_drones.get_first ();
3846 binaural_drone* bi = binaural_drones0.binaural_drones[i];
3847 bi->set_hz (w, v); // v is absolute
3848 binaural_drones0.pitch_fader.start ("Hz set");
3849 } else {
3850 for (int i = 0; i < MENU.il_binaural_drones.n; ++i) {
3851 if (MENU.il_binaural_drones.items[i].sel) {
3852 binaural_drone* bi = binaural_drones0.binaural_drones[i];
3853 float ohz [] = {bi->l_hz, bi->r_hz};
3854 bi->set_hz (w, ohz[w] + v); // v is relative
3855 }
3856 }
3857 binaural_drones0.pitch_fader.start ("Hz change");
3858 }
3859 }
3860
picked(label & lbl,int dir)3861 void binaural_drones_listener::picked (label& lbl, int dir) {
3862 if (&lbl == MENUP.ol_justification.option) {
3863 int j = binaural_drones0.change_justification (dir);
3864 MENU.ol_justification.set_text (justs[j]);
3865 } else if (&lbl == MENUP.ol_key_note.option) {
3866 int k = binaural_drones0.change_key_note (dir);
3867 const string kn [] = {"start pitch", "from scale"};
3868 MENU.ol_key_note.set_text (" Key note is " + kn[k]);
3869 } else if (&lbl == MENUP.ol_select_what.option) {
3870 select_what += dir;
3871 wrap<int> (binaural_drone::LEFT, select_what, binaural_drone::VOLUME);
3872 const string sc [] = {"L ", "R ", "Separation ", "Volume "};
3873 MENU.ol_select_what.set_text (sc[select_what]);
3874 MENU.ol_select_rule.set_pos (MENU.ol_select_what.extents.right, MENU.ol_select_rule.posy);
3875 MENU.bdf_value.set_pos (MENU.ol_select_rule.extents.right, MENU.bdf_value.posy);
3876 } else if (&lbl == MENUP.ol_select_rule.option) {
3877 select_rule += dir;
3878 wrap<int> (EQUAL, select_rule, ID);
3879 const string sr [] = {" = ", " >= ", " <= ", " <> ", " id "};
3880 MENU.ol_select_rule.set_text (sr[select_rule]);
3881 MENU.bdf_value.set_text (val[select_rule]);
3882 MENU.bdf_value.set_pos (MENU.ol_select_rule.extents.right, MENU.bdf_value.posy);
3883 } else if (&lbl == MENUP.ol_just.option) {
3884 just += dir;
3885 wrap<int> (binaural_drone::LEFT, just, binaural_drone::CENTER);
3886 MENU.ol_just.set_text (justs[just]);
3887 for (int i = 0; i < MENU.il_binaural_drones.n; ++i) {
3888 if (MENU.il_binaural_drones.items[i].sel) {
3889 binaural_drone* bi = binaural_drones0.binaural_drones[i];
3890 bi->set_just (just);
3891 }
3892 }
3893 }
3894 }
3895
selected(item_list & il,int s)3896 void binaural_drones_listener::selected (item_list& il, int s) {
3897 int ns = il.num_selected ();
3898 if (ns == 1) {
3899 binaural_drone* bs = binaural_drones0.binaural_drones[il.get_first()];
3900 bs->sel = 1;
3901 sprintf (BUFFER, "%0.3f", bs->vol*100.0);
3902 MENU.lf_vol.set_text (BUFFER);
3903 sprintf (BUFFER, "%0.3f", bs->l_hz);
3904 MENU.lf_l.set_text (BUFFER);
3905 sprintf (BUFFER, "%0.3f", bs->r_hz);
3906 MENU.lf_r.set_text (BUFFER);
3907 sprintf (BUFFER, "%0.3f", bs->sep);
3908 MENU.lf_sep.set_text (BUFFER);
3909 MENU.lf_l.set_label ("L (Hz) ");
3910 MENU.lf_r.set_label ("R (Hz) ");
3911 just = bs->just;
3912 MENU.ol_just.set_text (justs[just]);
3913 } else {
3914 if (ns) {
3915 MENU.lf_l.set_label ("dL (Hz) ");
3916 MENU.lf_r.set_label ("dR (Hz) ");
3917 }
3918 MENU.lf_vol.fld.set_text (0.0f);
3919 MENU.lf_l.fld.set_text (0.0f);
3920 MENU.lf_r.fld.set_text (0.0f);
3921 MENU.lf_sep.fld.set_text (0.0f);
3922 just = binaural_drone::CENTER;
3923 MENU.ol_just.set_text (justs[just]);
3924 for (int i = 0, n = il.n; i < n; ++i) {
3925 binaural_drone* bi = binaural_drones0.binaural_drones[i];
3926 bi->sel = il.items[i].sel;
3927 }
3928 }
3929 cons << GREEN << "Selected " << ns << " binaural drone pairs" << eol;
3930 }
3931
changed(checkbutton & cb)3932 void binaural_drones_listener::changed (checkbutton& cb) {
3933 binaural_drones0.close_octave = MENU.cb_close_octave.state;
3934 }
3935
update_binaurals_list()3936 void menu::update_binaurals_list () {
3937 il_binaural_drones.set_pos (cb_file.extents.left, bbd_select_all.extents.bottom);
3938 calc_bg ();
3939 }
3940
ball_ops_listener()3941 ball_ops_listener::ball_ops_listener () {
3942 op_id = 0;
3943 }
3944
picked(label & lbl,int dir)3945 void ball_ops_listener::picked (label& lbl, int dir) {
3946 if (&lbl == MENUP.ol_browse_balls.option) {
3947 mondrian0.browse_ball (dir);
3948 return;
3949 } else {
3950 label* olt [] = {MENUP.ol_bouncer.option, MENUP.ol_wrecker.option, MENUP.ol_healer.option};
3951 for (int i = 0; i < 3; ++i) {
3952 if (&lbl == olt[i]) {
3953 int& t = Transform::rules [i];
3954 t += dir;
3955 if (t < ball::BOUNCER) t = ball::INVALID;
3956 else if (t > ball::INVALID) t = ball::BOUNCER;
3957 sprintf (BUFFER, "%s becomes %s", ball::types_str[i], ball::types_str[t]);
3958 olt[i]->set_text (BUFFER);
3959 return;
3960 }
3961 }
3962 }
3963 }
3964
clicked(button & b)3965 void ball_ops_listener::clicked (button& b) {
3966 }
3967
changed(checkbutton & cb)3968 void ball_ops_listener::changed (checkbutton& cb) {
3969 ball* b = mondrian0.get_one_selected_ball ();
3970 if (b) {
3971 ball_op* ops [] = {&b->op_turn, &b->op_speed, &b->op_teleport, &b->op_clone, &b->op_transform};
3972 checkbutton* cbn [] = {MENUP.cb_turn, MENUP.cb_speed, MENUP.cb_teleport, MENUP.cb_clone, MENUP.cb_transform};
3973 for (int i = 0; i < ball_op::NUM_OPS; ++i) {
3974 if (&cb == cbn[i]) {
3975 ball_op* opi = ops[i];
3976 // if (cb.state) opi->alarm.start (); else opi->alarm.stop ();
3977 if (cb.state) opi->start (b); else opi->alarm.stop ();
3978
3979 break;
3980 }
3981 }
3982
3983 /*if (cb.state && (&cb == MENUP.cb_speed)) {
3984 MENU.sp_max_speed.set_value (b->V);
3985 b->op_speed.max = b->V;
3986 }*/
3987
3988 b->op_clone.clone_can_clone = MENU.cb_clone_can_clone.state;
3989
3990 } else {
3991 cons << RED << "Please select a ball!" << eol;
3992 }
3993 }
3994
changed(field & f)3995 void ball_ops_listener::changed (field& f) {
3996 if (&f == MENUP.sp_max_balls.f_value) {
3997 int i = f;
3998 Clone::max_balls = i;
3999 cons << YELLOW << "Max balls = " << Clone::max_balls << eol;
4000 } else {
4001 ball* b = mondrian0.get_one_selected_ball ();
4002 if (b) {
4003 if (&f == MENUP.sp_turn_every.f_value) {
4004 float t = f;
4005 b->op_turn.alarm.triggert = t;
4006 sprintf (BUFFER, "Turn every %0.3f seconds", t);
4007 cons << YELLOW << BUFFER << eol;
4008 } else
4009 if (&f == MENUP.sp_turn_min.f_value) {
4010 float minn = f, maxx;
4011 if (MENU.cb_turn_sync.state) {
4012 maxx = minn;
4013 MENU.sp_turn_max.set_value (maxx);
4014 } else maxx = b->op_turn.rd.max;
4015 b->op_turn.rd.set (-minn, maxx);
4016 sprintf (BUFFER, "Turn Clockwise upto %0.3f degrees | Anti-clockwise upto %0.3f degrees", minn, maxx);
4017 cons << YELLOW << BUFFER << eol;
4018 } else
4019 if (&f == MENUP.sp_turn_max.f_value) {
4020 float minn, maxx = f;
4021 if (MENU.cb_turn_sync.state) {
4022 MENU.sp_turn_min.set_value (maxx);
4023 minn = -maxx;
4024 } else minn = b->op_turn.rd.min;
4025 b->op_turn.rd.set (minn, maxx);
4026 sprintf (BUFFER, "Turn Clockwise upto %0.3f degrees | Anti-clockwise upto %0.3f degrees", -minn, maxx);
4027 cons << YELLOW << BUFFER << eol;
4028 } else
4029 if (&f == MENUP.sp_speed_min.f_value) {
4030 float minn = f, maxx;
4031 if (MENU.cb_speed_sync.state) {
4032 maxx = minn;
4033 MENU.sp_speed_max.set_value (maxx);
4034 } else maxx = b->op_speed.rd.max;
4035 b->op_speed.rd.set (-minn, maxx);
4036 sprintf (BUFFER, "Accelerate = %0.3f | Brake = %0.3f", maxx, minn);
4037 cons << YELLOW << BUFFER << eol;
4038 } else
4039 if (&f == MENUP.sp_speed_max.f_value) {
4040 float minn, maxx = f;
4041 if (MENU.cb_speed_sync.state) {
4042 MENU.sp_speed_min.set_value (maxx);
4043 minn = -maxx;
4044 } else minn = b->op_speed.rd.min;
4045 b->op_speed.rd.set (minn, maxx);
4046 sprintf (BUFFER, "Accelerate = %0.3f | Brake = %0.3f", maxx, -minn);
4047 cons << YELLOW << BUFFER << eol;
4048 } else
4049 if (&f == MENUP.sp_speed_every.f_value) {
4050 float m = f;
4051 b->op_speed.alarm.triggert = m;
4052 sprintf (BUFFER, "Speed every %0.3f seconds", m);
4053 cons << YELLOW << BUFFER << eol;
4054 } else
4055 if (&f == MENUP.sp_max_speed.f_value) {
4056 float m = f;
4057 b->op_speed.max = m;
4058 sprintf (BUFFER, "Max speed = %0.3f", m);
4059 cons << YELLOW << BUFFER << eol;
4060 } else
4061 if (&f == MENUP.sp_tel_every.f_value) {
4062 float s = f;
4063 b->op_teleport.alarm.triggert = s;
4064 sprintf (BUFFER, "Teleport every %0.3f seconds", s);
4065 cons << YELLOW << BUFFER << eol;
4066 } else
4067 if (&f == MENUP.sp_tel_radius.f_value) {
4068 float r = f;
4069 b->op_teleport.radius = r;
4070 sprintf (BUFFER, "Max Teleport distance = %0.3f", r);
4071 cons << YELLOW << BUFFER << eol;
4072 } else
4073 if (&f == MENUP.sp_clone_every.f_value) {
4074 float m = f;
4075 b->op_clone.alarm.triggert = m;
4076 sprintf (BUFFER, "Clone every %0.3f seconds", m);
4077 cons << YELLOW << BUFFER << eol;
4078 } else
4079 if (&f == MENUP.sp_max_clones.f_value) {
4080 int i = f;
4081 b->op_clone.n = b->op_clone.max = i;
4082 cons << "Max clones = " << i << eol;
4083 } else
4084 if (&f == MENUP.sp_clone_offset.f_value) {
4085 float m = f;
4086 b->op_clone.offset = m;
4087 cons << YELLOW << "Clone offset = " << m << eol;
4088 } else
4089 if (&f == MENUP.sp_transform_every.f_value) {
4090 float m = f;
4091 b->op_transform.alarm.triggert = m;
4092 sprintf (BUFFER, "Transform every %0.3f seconds", m);
4093 cons << YELLOW << BUFFER << eol;
4094 }
4095 } else {
4096 cons << RED << "Please select a ball! " << eol;
4097 }
4098 }
4099 }
4100
changed(field & f)4101 void arrowlis::changed (field& f) {
4102 if (&f == MENUP.dronearrow.shoulder.position.f_value) {
4103 din0.change_drone_arrow (MENU.dronearrow.shoulder.position, 0);
4104 } else if (&f == MENUP.dronearrow.shoulder.width.f_value) {
4105 din0.change_drone_arrow (MENU.dronearrow.shoulder.width, 1);
4106 } else {
4107 din0.change_drone_arrow (MENU.dronearrow.neck, 2);
4108 }
4109 }
4110
changed(field & f)4111 void defarrowlis::changed (field& f) {
4112 drone::arrowt::U = MENU.dronearrowdefaults.shoulder.position.value;
4113 drone::arrowt::V = MENU.dronearrowdefaults.shoulder.width.value;
4114 drone::arrowt::K = MENU.dronearrowdefaults.neck.value;
4115 cons << GREEN <<
4116 "Drone arrow defaults: Neck = " << drone::arrowt::K <<
4117 ", Shoulder pos = " << drone::arrowt::U <<
4118 ", Shoulder width = " << drone::arrowt::V << eol;
4119 MENU.dronearrowdefaults.arrow.calc ();
4120 }
4121
changed(checkbutton & cb)4122 void defarrowlis::changed (checkbutton& cb) {
4123 MENU.dronearrowdefaults.arrow.calc ();
4124 }
4125
calc()4126 void drawrrow::calc () {
4127 int cap = MENU.dronearrowdefaults.cap.state;
4128 int n = 12;
4129 make_arrow (pts, 0, cap, n, x, y, ux, uy, vx, vy,
4130 MENU.dronearrowdefaults.shoulder.position.value,
4131 MENU.dronearrowdefaults.shoulder.width.value,
4132 MENU.dronearrowdefaults.neck.value);
4133 npts = n / 2;
4134 }
4135
reset()4136 void drone::arrowt::reset () {
4137 u = MENU.dronearrowdefaults.shoulder.position ();
4138 v = MENU.dronearrowdefaults.shoulder.width ();
4139 t = MENU.dronearrowdefaults.neck ();
4140 cap = MENU.dronearrowdefaults.cap.state;
4141 }
4142
clicked(button & b)4143 void arrowlis::clicked (button& b) {
4144 if (&b == MENUP.dronearrow.cap)
4145 din0.capdronearrows (1);
4146 else
4147 din0.capdronearrows (0);
4148 TOGGLEMENU
4149 }
4150
4151
4152
changed(field & f)4153 void range_defaults_lis::changed (field& f) {
4154 if (&f == MENUP.sp_default_width.f_value) {
4155 extern int WIDTH;
4156 WIDTH = f;
4157 cons << "Default Range Width = " << WIDTH << eol;
4158 } else {
4159 extern int HEIGHT;
4160 HEIGHT = f;
4161 cons << "Default Range Height = " << HEIGHT << eol;
4162 }
4163 }
4164
moused(int dx,double scl)4165 void change_note_listener::moused (int dx, double scl) {
4166 int dir = sign (dx);
4167 din0.change_range_note (id, dir * scl * delta0);
4168 }
4169
clicked(button & b)4170 void change_note_listener::clicked (button& b) {
4171 if (&b == MENUP.b_change_note_left) {
4172 mouse_slider0.add (MENUP.cnl);
4173 } else {
4174 mouse_slider0.add (MENUP.cnr);
4175 }
4176 activate_mouse_slider (0, 0);
4177 }
4178
clicked(button & b)4179 void change_note_both_listener::clicked (button& b) {
4180 mouse_slider0.add (MENUP.cnl);
4181 mouse_slider0.add (MENUP.cnr);
4182 activate_mouse_slider (0, 0);
4183 }
4184
picked(label & lbl,int dir)4185 void change_note_options_listener::picked (label& lbl, int dir) {
4186 if (&lbl == MENUP.ol_change_note.option) {
4187 static const string chg (" Change "), nte ("Note > ");
4188 din0.dinfo.change_note = !din0.dinfo.change_note;
4189 if (din0.dinfo.change_note)
4190 MENU.add_to_tab (MENUP.cb_mkb_ranges, MENUP.ol_change_note_style);
4191 else
4192 MENU.remove_from_tab (MENUP.cb_mkb_ranges, MENUP.ol_change_note_style);
4193 string cn (din_info::cnno[din0.dinfo.change_note]);
4194 lbl.set_text (chg+cn);
4195 print_range_info (din0.ranges[din0.dinfo.sel_range]);
4196 } else {
4197 din0.dinfo.change_note_style = !din0.dinfo.change_note_style;
4198 set (lbl, din0.dinfo.change_note_style);
4199 }
4200 }
4201
set(label & lbl,int v)4202 void change_note_options_listener::set (label& lbl, int v) {
4203 lbl.set_text (din_info::cnn_opts[v]);
4204 extern scale_info all_notes;
4205 scale_info* ptr_si [] = {&din0.scaleinfo, &all_notes};
4206 din0.ptr_scaleinfo = ptr_si[v];
4207 }
4208
changed(checkbutton & cb)4209 void menu::pitch_vol_dis_pix_lis::changed (checkbutton& cb) {
4210 if (&cb == MENUP.cb_pitch_dis) {
4211 din0.dinfo.dist.pitch = cb.state;
4212 } else {
4213 din0.dinfo.dist.vol = cb.state;
4214 }
4215 }
4216
changed(field & f)4217 void menu::pitch_vol_dis_pix_lis::changed (field& f) {
4218 din0.dinfo.dist.pix = f;
4219 cons << "Pixels per level = " << din0.dinfo.dist.pix << eol;
4220 }
4221
prep_drone_xform(mouse_slider_listener * L,int shift=0,int scalestyle=mouse_slider::scalet::CHANGING)4222 void prep_drone_xform (mouse_slider_listener* L, int shift = 0, int scalestyle = mouse_slider::scalet::CHANGING) {
4223 din0.freeze_orbiters ();
4224 mouse_slider0.add (L);
4225 activate_mouse_slider (shift, scalestyle);
4226 }
4227
CLICKED_BUTTON(menu,b_move_drones_lis)4228 CLICKED_BUTTON (menu, b_move_drones_lis) {
4229 din0.start_moving_drones ();
4230 TOGGLEMENU
4231 }
4232
CLICKED_BUTTON(menu,b_set_xform_center_lis)4233 CLICKED_BUTTON (menu, b_set_xform_center_lis) {
4234 din0.calc_drones_centroid ();
4235 TOGGLEMENU
4236 }
4237
CLICKED_BUTTON(menu,b_move_drones_under_gravity_lis)4238 CLICKED_BUTTON (menu, b_move_drones_under_gravity_lis) {
4239 din0.set_drones_under_gravity ();
4240 TOGGLEMENU
4241 }
4242
CLICKED_BUTTON(menu,b_scale_drones_lis)4243 CLICKED_BUTTON (menu,b_scale_drones_lis) {
4244 MENU.ms_sdl.name = "Scale";
4245 if (din0.prep_scale_drones ()) {
4246 int shift = -2; // for 0.01f scaling, assuming base = 10 on mouse slider
4247 prep_drone_xform (MENUP.ms_sdl, shift, mouse_slider::scalet::CHANGING);
4248 } else cons << RED_PSD << eol;
4249 }
4250
AFTER_SLIDE(menu,ms_scale_drones_lis)4251 AFTER_SLIDE (menu,ms_scale_drones_lis) {
4252 din0.thaw_orbiters ();
4253 }
4254
MOUSED(menu,ms_scale_drones_lis)4255 MOUSED (menu,ms_scale_drones_lis) {
4256 din0.scale_drones (dir * scl);
4257 din0.scale_drones ();
4258 }
4259
CLICKED_BUTTON(menu,b_rotate_drones_lis)4260 CLICKED_BUTTON (menu,b_rotate_drones_lis) {
4261 MENU.ms_rdl.name = "Rotate";
4262 if (din0.prep_rotate_drones ()) prep_drone_xform (MENUP.ms_rdl); else cons << RED << "Please select some drones!" << eol;
4263 }
4264
AFTER_SLIDE(menu,ms_rotate_drones_lis)4265 AFTER_SLIDE (menu,ms_rotate_drones_lis) {
4266 din0.thaw_orbiters ();
4267 }
4268
MOUSED(menu,ms_rotate_drones_lis)4269 MOUSED (menu,ms_rotate_drones_lis) {
4270 din0.angle += (dir * scl * PI_BY_180);
4271 din0.rotate_drones ();
4272 }
4273
CLICKED_BUTTON(menu,set_to_mesh_rows_lis)4274 CLICKED_BUTTON (menu,set_to_mesh_rows_lis) {
4275 MENU.sp_drones_per_pend.set_value (din0.dinfo.rows);
4276 MENU.dppl.changed (MENU.sp_drones_per_pend.f_value);
4277 }
4278
CLICKED_BUTTON(menu,set_to_mesh_cols_lis)4279 CLICKED_BUTTON (menu,set_to_mesh_cols_lis) {
4280 MENU.sp_drones_per_pend.set_value (din0.dinfo.cols);
4281 MENU.dppl.changed (MENU.sp_drones_per_pend.f_value);
4282 }
4283
CLICKED_CHECKBUTTON(menu,cb_am_bpm_lis)4284 CLICKED_CHECKBUTTON (menu,cb_am_bpm_lis) {
4285 din0.dinfo.mesh_vars.apply_to.am = cb.state;
4286 din0.dinfo.mesh_vars.apply_to.calc_active ();
4287 }
4288
CLICKED_CHECKBUTTON(menu,cb_fm_bpm_lis)4289 CLICKED_CHECKBUTTON (menu,cb_fm_bpm_lis) {
4290 din0.dinfo.mesh_vars.apply_to.fm = cb.state;
4291 din0.dinfo.mesh_vars.apply_to.calc_active ();
4292 }
4293
CLICKED_BUTTON(menu,b_set_unset_toggle_lis)4294 CLICKED_BUTTON(menu,b_set_unset_toggle_lis) {
4295 if (&b == MENUP.b_toggle) {
4296 if (din0.dinfo.set_unset_toggle) din0.pos_afx_vel (-1); else din0.snap_drones (-1);
4297 } else if (&b == MENUP.b_set) {
4298 if (din0.dinfo.set_unset_toggle) din0.pos_afx_vel (1); else din0.snap_drones (1);
4299 } else {
4300 if (din0.dinfo.set_unset_toggle) din0.pos_afx_vel (0); else din0.snap_drones (0);
4301 }
4302 TOGGLEMENU
4303 }
4304
VALUE_CHANGED(menu,drones_per_pend_lis)4305 VALUE_CHANGED (menu,drones_per_pend_lis) {
4306 din0.dinfo.mesh_vars.dpp = int (f);
4307 cons << "Drones per pendulum = " << din0.dinfo.mesh_vars.dpp << eol;
4308 }
4309
PICKED_OPTION(menu,ol_fixed_lis)4310 PICKED_OPTION (menu, ol_fixed_lis) {
4311 range& rs = din0.ranges [din0.dinfo.sel_range];
4312 rs.fixed += dir;
4313 wrap<int> (range::LEFT, rs.fixed, range::RIGHT);
4314 MENU.ol_fixed.set_text (ol_fixed_lbls[rs.fixed]);
4315 }
4316
CLICKED_CHECKBUTTON(menu,cb_draw_mesh_lis)4317 CLICKED_CHECKBUTTON (menu,cb_draw_mesh_lis) {
4318 din0.meshh.draw = cb.state;
4319 TOGGLEMENU
4320 }
4321
VALUE_CHANGED(menu,lf_conn_steps_lis)4322 VALUE_CHANGED (menu,lf_conn_steps_lis) {
4323 din0.calc_stepz (f.text);
4324 cons << YELLOW << "Click connect to connect drones" << eol;
4325 }
4326
typing(field & f)4327 void menu::lf_conn_steps_lis::typing (field& f) {
4328 static const int d = 12;
4329 MENU.cb_conn_wrap.set_pos (f.extents.right + d, MENU.cb_conn_wrap.posy);
4330 MENU.trackcon.set_pos (MENU.cb_conn_wrap.extents.right + d, MENU.trackcon.posy);
4331 }
4332
CLICKED_CHECKBUTTON(menu,cb_conn_wrap_lis)4333 CLICKED_CHECKBUTTON (menu, cb_conn_wrap_lis) {
4334 cons << YELLOW << "Click connect to connect drones" << eol;
4335 }
4336
CLICKED_BUTTON(menu,b_connect_lis)4337 CLICKED_BUTTON (menu, b_connect_lis) {
4338 if (din0.connect_drones ()) TOGGLEMENU
4339 }
4340
CLICKED_BUTTON(menu,b_disconnect_lis)4341 CLICKED_BUTTON (menu, b_disconnect_lis) {
4342 if (din0.disconnect_drones ()) TOGGLEMENU
4343 }
4344
update_data()4345 void get_color::update_data () {
4346 data.clr[0] = color (MENU.s_red_min(), MENU.s_green_min(), MENU.s_blue_min());
4347 data.clr[1] = color (MENU.s_red_max(), MENU.s_green_max(), MENU.s_blue_max());
4348 }
4349
SLIDER_CHANGED(menu,sc_color_lis)4350 SLIDER_CHANGED(menu,sc_color_lis) {
4351 get_color::update_data ();
4352 din0.color_selected_drones ();
4353 MENU.b_close.set_pos (mousex, MENU.b_close.posy);
4354 }
4355
START_SLIDE(menu,ss_color_lis,slider<float>)4356 START_SLIDE(menu, ss_color_lis, slider<float>) {
4357 if (MENU.b_close.visible == 0) {
4358 DECL_COLOR_SLIDERS
4359 button& b_close = detach_from_menu (slrs, COLOR_SLIDERS_N, MENU.s_red_max.posx, MENU.s_red_max.posy);
4360 LISTEN (b_close, MENUP.cscll)
4361 }
4362 }
4363
CLICKED_BUTTON(menu,sc_close_lis)4364 CLICKED_BUTTON(menu, sc_close_lis) {
4365 DECL_COLOR_SLIDERS
4366 attach_to_menu (slrs, COLOR_SLIDERS_N);
4367 }
4368
PICKED_OPTION(menu,ol_color_lis)4369 PICKED_OPTION(menu,ol_color_lis) {
4370 colorer_t& colorer = MENU.colorer;
4371 colorer += dir;
4372 l.set_text (colorer_t::s_schemes[colorer.i]);
4373 din0.color_selected_drones ();
4374 }
4375
CLICKED_CHECKBUTTON(menu,cb_modulation_lis)4376 CLICKED_CHECKBUTTON (menu,cb_modulation_lis) {
4377 MENU.cb_visual.set_state (0,0);
4378 MENU.cb_motion.set_state (0,0);
4379 MENU.cb_chuck.set_state (0,0);
4380 MENU.cb_defaults.set_state (0,0);
4381 cb.set_state (1, 0);
4382 MENU.set_drone_params_items (9, 23);
4383 }
4384
CLICKED_CHECKBUTTON(menu,cb_motion_lis)4385 CLICKED_CHECKBUTTON (menu,cb_motion_lis) {
4386 MENU.cb_modulation.set_state (0,0);
4387 MENU.cb_visual.set_state (0,0);
4388 MENU.cb_chuck.set_state (0,0);
4389 MENU.cb_defaults.set_state (0,0);
4390 cb.set_state (1, 0);
4391 MENU.set_drone_params_items (23, 57);
4392 }
4393
CLICKED_CHECKBUTTON(menu,cb_defaults_lis)4394 CLICKED_CHECKBUTTON (menu,cb_defaults_lis) {
4395 MENU.cb_modulation.set_state (0,0);
4396 MENU.cb_visual.set_state (0,0);
4397 MENU.cb_motion.set_state (0,0);
4398 MENU.cb_chuck.set_state (0,0);
4399 cb.set_state (1, 0);
4400 MENU.set_drone_params_items (57, 93);
4401 }
4402
CLICKED_CHECKBUTTON(menu,cb_chuck_lis)4403 CLICKED_CHECKBUTTON (menu,cb_chuck_lis) {
4404 MENU.cb_modulation.set_state (0,0);
4405 MENU.cb_visual.set_state (0,0);
4406 MENU.cb_motion.set_state (0,0);
4407 MENU.cb_defaults.set_state (0,0);
4408 cb.set_state (1, 0);
4409 MENU.set_drone_params_items (93, 101);
4410 }
4411
CLICKED_CHECKBUTTON(menu,cb_visual_lis)4412 CLICKED_CHECKBUTTON (menu,cb_visual_lis) {
4413 MENU.cb_modulation.set_state (0,0);
4414 MENU.cb_motion.set_state (0,0);
4415 MENU.cb_chuck.set_state (0,0);
4416 MENU.cb_defaults.set_state (0,0);
4417 cb.set_state (1, 0);
4418 MENU.set_drone_params_items (101, DRONE_PARAMS_N);
4419 }
4420
CLICKED_BUTTON(menu,b_abort_octave_shift_lis)4421 CLICKED_BUTTON (menu, b_abort_octave_shift_lis) {
4422 abort_octave_shift (get_current_instrument());
4423 }
4424
CLICKED_BUTTON(menu,b_arrow_reset_lis)4425 CLICKED_BUTTON (menu, b_arrow_reset_lis) {
4426 din0.reset_drone_arrows ();
4427 }
4428
handle_voice_tab_items(const char * viv)4429 void menu::handle_voice_tab_items (const char* viv) {
4430
4431 cb_mkb_voice.set_text (viv);
4432
4433 widget* wvoice [] = {
4434 &sp_am_depth,
4435 &sp_fm_depth,
4436 &sp_am_bpm,
4437 &sp_fm_bpm,
4438 &ol_am_style,
4439 &ol_fm_style,
4440 };
4441
4442 if (din0.dinfo.voice_is_voice) {
4443 for (int i = 0; i < 6; ++i) add_to_tab (&cb_mkb_voice, wvoice[i]);
4444 } else {
4445 for (int i = 0; i < 6; ++i) remove_from_tab (&cb_mkb_voice, wvoice[i]);
4446 }
4447
4448 calc_bg ();
4449
4450 }
4451
print_range_info(range & ri)4452 void print_range_info (range& ri) {
4453 note& L = ri.notes[0];
4454 note& R = ri.notes[1];
4455 sprintf (BUFFER, "Note > %s | Left = %s @ %0.3f Hz, Right = %s @ %0.3f Hz | Range %d", din_info::cnno[din0.dinfo.change_note], L.name.c_str(), L.hz, R.name.c_str(), R.hz, din0.dinfo.sel_range);
4456 cons << CYAN << BUFFER << eol;
4457 }
4458
detach_from_menu(widget ** wa,int n,int posx,int posy)4459 button& detach_from_menu (widget** wa, int n, int posx, int posy) {
4460
4461 button& close = MENU.b_close;
4462 close.set_pos (posx, posy - line_height);
4463 close.show ();
4464
4465 if (MENU.show) MENU.toggle (0);
4466
4467 vector<widget*>& vw = uis.widgets_of [uis.current];
4468 vw.insert (vw.begin(), &close);
4469
4470 if (n == 1)
4471 vw.insert (vw.begin(), wa[0]);
4472 else
4473 for (int i = 0; i < n; ++i) vw.insert (vw.begin(), wa[i]);
4474
4475 warp_mouse (MENU.menu_mousex, MENU.menu_mousey);
4476
4477 return close;
4478
4479 }
4480
attach_to_menu(widget ** wa,int n)4481 void attach_to_menu (widget** wa, int n) {
4482 MENU.b_close.hide ();
4483 uis.remove (MENUP.b_close);
4484 if (n == 1) uis.remove (wa[0]); else for (int i = 0; i < n; ++i) uis.remove (wa[i]);
4485 if (uis.current == &din0) uis.add (&din0, &mkb_selector); //uis.widgets_of [&din0].push_back (&mkb_selector);
4486 }
4487
CLICKED_BUTTON(menu,b_mute_lis)4488 CLICKED_BUTTON (menu, b_mute_lis) {
4489 din0.gab.set (&din0, 0.0f, "muting drones");
4490 TOGGLEMENU
4491 }
4492
CLICKED_BUTTON(menu,b_unmute_lis)4493 CLICKED_BUTTON (menu, b_unmute_lis) {
4494 din0.gab.set (&din0, 1.0f, "unmuting drones");
4495 TOGGLEMENU
4496 }
4497
VALUE_CHANGED(menu,sp_drone_vol_lis)4498 VALUE_CHANGED (menu, sp_drone_vol_lis) {
4499 din0.setdronevol (MENU.sp_drone_vol);
4500 }
4501
CLICKED_BUTTON(menu,drone2noiselis)4502 CLICKED_BUTTON (menu, drone2noiselis) {
4503 din0.drone2noise ();
4504 TOGGLEMENU
4505 }
4506
CLICKED_BUTTON(menu,noise2dronelis)4507 CLICKED_BUTTON (menu, noise2dronelis) {
4508 din0.noise2drone ();
4509 TOGGLEMENU
4510 }
4511
setup()4512 void menu::setvelaccel::setup () {
4513 lbl.set_text ("Set");
4514 whats.option.set_text (" Velocity");
4515 whats.set_listener (this);
4516 button* b[] = {&zero, &vert, &hor, &vel, &accel};
4517 const char* l[] = {"Vertical", "Horizontal", "Velocity", "Acceleration", "Zero"};
4518 for (int i = 0; i < 5; ++i) {
4519 button& bi = *b[i];
4520 bi.id = i;
4521 bi.set_listener (this);
4522 bi.set_text (l[i]);
4523 }
4524 neg.set_text ("-ve");
4525 #ifdef __WIDGET_MOVE__
4526 widget* w[] = {&lbl, &whats, &neg, &zero, &vert, &hor, &vel, &accel};
4527 makehier (w, 8);
4528 for (int i = 0; i < 8; ++i) w[i]->set_moveable(1);
4529 #endif
4530 }
4531
clicked(button & b)4532 void menu::setvelaccel::clicked (button& b) {
4533 din0.setvelaccel (what, b.id, neg.state);
4534 TOGGLEMENU
4535 }
4536
picked(label & l,int dir)4537 void menu::setvelaccel::picked (label& l, int dir) {
4538 static const char* lbl [] = {" Velocity", " Acceleration", " Both"};
4539 what += dir;
4540 wrap<int> (menu::autorott::VELOCITY, what, menu::autorott::BOTH);
4541 l.set_text (lbl[what]);
4542 }
4543
setup()4544 void menu::autorott::setup () {
4545
4546 title.set_text ("Auto rotate");
4547 which = VELOCITY;
4548 whichl.option.set_text (" Velocity");
4549 whichl.set_listener (this);
4550 mov.set_text ("Movement?");
4551 button* b[] = {&start, &stop, &toggle, &clockwise, &anticlockwise, &autoflip.set, &autoflip.unset, &autoflip.toggle, &smooth, &tick};
4552 const char* l [] = {"Start", "Stop", "Toggle", "Clockwise", "Anti-clockwise", "Set", "Unset", "Toggle", "Smooth", "Ticked"};
4553 click_listener* clk [] = {&startl, &stopl, &togl, &clkl, &aclkl, &autoflip.setl, &autoflip.unsetl, &autoflip.togl, this, this};
4554 for (int i = 0; i < 10; ++i) {
4555 button& bi = *b[i];
4556 bi.set_text (l[i]);
4557 bi.set_listener (clk[i]);
4558 }
4559
4560 autoflip.lbl.set_text ("Auto flip");
4561 rpm.set ("RPM", 1.0f, 0.0f, MILLIONF, &rpml);
4562 deg.set ("Degrees per Second", 1.0f, -MILLIONF, MILLIONF, °l);
4563 tps.set ("Ticks per Second", 1.0f, -MILLIONF, MILLIONF, &tpsl);
4564 autoflip.angle.set (1.0f, 0.0f, MILLIONF, &autoflip.angl);
4565 autoflip.angle.set_text ("Every", DEGREES);
4566
4567 #ifdef __WIDGET_MOVE__
4568 widget* w[] = {
4569 &title, &whichl, &rpm, &start, &stop, &toggle, &clockwise, &anticlockwise,
4570 &autoflip.lbl, &autoflip.set, &autoflip.unset, &autoflip.toggle, &autoflip.angle,
4571 0
4572 };
4573 makehier (w);
4574 #endif
4575 }
4576
clicked(button & b)4577 void menu::autorott::clicked (button& b) {
4578 if (&b == &smooth) {
4579 mov.id = autorotator::SMOOTH;
4580 din0.setautorotparam (MENU.autorotate.which, autorott::MOVEMENT);
4581 } else {
4582 mov.id = autorotator::TICK;
4583 din0.setautorotparam (MENU.autorotate.which, autorott::MOVEMENT);
4584 }
4585 TOGGLEMENU
4586 }
4587
picked(label & lbl,int dir)4588 void menu::autorott::picked (label& lbl, int dir) {
4589 static const char* strs [] = {" Velocity", " Acceleration", " Both"};
4590 which += dir;
4591 wrap<int> (menu::autorott::VELOCITY, which, menu::autorott::BOTH);
4592 lbl.set_text (strs[which]);
4593 }
4594
checksync(float v,anglet & t,spinner<float> & sp)4595 void menu::defvelaccelui::checksync (float v, anglet& t, spinner<float>& sp) {
4596 if (sync.state) {
4597 t = v;
4598 sp.set_value (v);
4599 }
4600 }
4601
setup()4602 void menu::defvelaccelui::setup () {
4603
4604 whichl.set_listener (this);
4605
4606 spinner2<float>* sp [] = {
4607 &mag,
4608 &autorotate.rpm,
4609 &autorotate.dps,
4610 &autorotate.tps,
4611 &autoflip.deg,
4612 };
4613
4614 const char* nam [] = {
4615 "Magnitude",
4616 "RPM",
4617 "Degrees Per Second",
4618 "Ticks Per Second",
4619 "Every"
4620 };
4621
4622 change_listener<field>* chgl [] = {
4623 &magl,
4624 &rpml,
4625 &dpsl,
4626 &tpsl,
4627 °l
4628 };
4629
4630 int nsp = 5;
4631 for (int i = 0; i < nsp; ++i) {
4632 spinner2<float>& spi = *sp[i];
4633 spi.set (nam[i], 1.0f, 0.0f, MILLIONF, chgl[i]);
4634 spi.lis[2] = &varl;
4635 spi.variance.cb.id = i;
4636 spi.variance.fld.id = i;
4637 spi.variance.cb.set_listener (&chkl);
4638 }
4639
4640 clockwise.set (1.0f, 0.0f, MILLIONF, &clockl);
4641 anticlockwise.set (1.0f, 0.0f, MILLIONF, &aclockl);
4642 clockwise.set_text ("Clockwise", DEGREES);
4643 anticlockwise.set_text ("Anti-clockwise", DEGREES);
4644 autoflip.deg.set_text ("Every", DEGREES);
4645
4646 ldir.set_text ("Direction");
4647 odir.set_listener (&dirl);
4648
4649 checkbutton* cb [] = {
4650 &neg,
4651 &randomize,
4652 &autorotate.cb,
4653 &autoflip.cb
4654 };
4655
4656 for (int i = 0, j = nsp; i < 4; ++i, ++j) {
4657 checkbutton& cbi = *cb[i];
4658 cbi.id = j;
4659 cbi.set_listener (&chkl);
4660 }
4661
4662 autorotate.setup ();
4663
4664 #ifdef __WIDGET_MOVE__
4665 autoflip.setup ();
4666 widget* w[] = {
4667 &whichl,
4668 &mag,
4669 &ldir, &neg, &odir,
4670 &randomize, &clockwise, &anticlockwise, &sync,
4671 0
4672 };
4673 makehier (w);
4674 #endif
4675
4676 }
4677
load()4678 void menu::defvelaccelui::load () {
4679
4680 defvelaccel* dval [] = {&drone::v0, &drone::a0};
4681 cur = dval [which];
4682 whichl.set_text (cur->name);
4683
4684 neg.set_state (cur->neg, 0);
4685 static const char* s [] = {" Horizontal", " Vertical", " Mouse"};
4686 odir.set_text (s[cur->dir]);
4687 MENU.dva.idir = cur->dir;
4688
4689 randomize.set_state (cur->rndrot, 0);
4690 clockwise.set_value (cur->clock.deg);
4691 anticlockwise.set_value (cur->anticlock.deg);
4692 sync.set_state (cur->sync, 0);
4693
4694 spinner2<float>* sp [] = {
4695 &MENU.dva.mag,
4696 &MENU.dva.autorotate.rpm,
4697 &MENU.dva.autorotate.dps,
4698 &MENU.dva.autorotate.tps,
4699 &MENU.dva.autoflip.deg,
4700 };
4701
4702 valt* vt [] = {
4703 &cur->mag,
4704 &cur->autos.rot.rpm,
4705 &cur->autos.rot.dps,
4706 &cur->autos.rot.tps,
4707 &cur->autos.flip.deg,
4708 };
4709
4710 for (int i = 0; i < 5; ++i) {
4711 spinner2<float>& spi = *sp[i];
4712 valt& vti = *vt[i];
4713 spi.set_value (vti.val);
4714 spi.variance.rd = vti.rd;
4715 spi.variance.setfld ();
4716 spi.variance.cb.set_state (vti.rndrd, 0);
4717 }
4718
4719 autorotate.load ();
4720 autoflip.cb.set_state (cur->autos.flip.yes);
4721
4722
4723 }
4724
picked(label & lbl,int p)4725 void menu::defvelaccelui::picked (label& lbl, int p) {
4726 which = !which;
4727 load ();
4728 }
4729
VALUE_CHANGED(menu::defvelaccelui,varlis)4730 VALUE_CHANGED (menu::defvelaccelui, varlis) {
4731 spinner2<float>* sp [] = {
4732 &MENU.dva.mag,
4733 &MENU.dva.autorotate.rpm,
4734 &MENU.dva.autorotate.dps,
4735 &MENU.dva.autorotate.tps,
4736 &MENU.dva.autoflip.deg,
4737 };
4738
4739 defvelaccel& dva = *MENU.dva.cur;
4740 valt* vt [] = {
4741 &dva.mag,
4742 &dva.autos.rot.rpm,
4743 &dva.autos.rot.dps,
4744 &dva.autos.rot.tps,
4745 &dva.autos.flip.deg,
4746 };
4747
4748 int id = f.id;
4749 vt[id]->rd = sp[id]->variance.rd;
4750 }
4751
VALUE_CHANGED(menu::defvelaccelui,maglis)4752 VALUE_CHANGED (menu::defvelaccelui, maglis) {
4753 float v = float (f);
4754 MENU.dva.cur->mag.val = v;
4755 cons << "Default Drone " << MENU.dva.cur->name << " = " << v << eol;
4756 }
4757
getdva()4758 defvelaccel& getdva () {
4759 defvelaccel* dval [] = {&drone::v0, &drone::a0};
4760 return *dval [MENU.dva.which];
4761 }
4762
VALUE_CHANGED(menu::defvelaccelui,rpmlis)4763 VALUE_CHANGED (menu::defvelaccelui, rpmlis) {
4764 float v = f;
4765 defvelaccel& dva = getdva ();
4766 dva.autos.rot.rpm = v;
4767 cons << dva.name << " Auto rotate RPM = " << v << eol;
4768 }
4769
VALUE_CHANGED(menu::defvelaccelui,dpslis)4770 VALUE_CHANGED (menu::defvelaccelui, dpslis) {
4771 float v = f;
4772 defvelaccel& dva = getdva ();
4773 dva.autos.rot.dps = v;
4774 cons << dva.name << " Degrees per Second = " << v << eol;
4775 }
VALUE_CHANGED(menu::defvelaccelui,tpslis)4776 VALUE_CHANGED (menu::defvelaccelui, tpslis) {
4777 float v = f;
4778 defvelaccel& dva = getdva ();
4779 dva.autos.rot.tps = v;
4780 cons << dva.name << " Ticks per Second = " << v << eol;
4781 }
4782
VALUE_CHANGED(menu::defvelaccelui,deglis)4783 VALUE_CHANGED (menu::defvelaccelui, deglis) {
4784 float v = f;
4785 defvelaccel& dva = getdva ();
4786 dva.autos.flip.deg = v;
4787 cons << dva.name << " Auto flip every " << v << DEGREES << eol;
4788 }
4789
VALUE_CHANGED(menu::defvelaccelui,clocklis)4790 VALUE_CHANGED (menu::defvelaccelui, clocklis) {
4791 float v = float (f);
4792 MENU.dva.cur->clock = v;
4793 MENU.dva.checksync (v, MENU.dva.cur->anticlock, MENU.dva.anticlockwise);
4794 MENU.dva.cur->setrotrd ();
4795 cons << "Default Drone Random" << MENU.dva.cur->name << " Clockwise Rotation = " << v << DEGREES << eol;
4796 }
4797
VALUE_CHANGED(menu::defvelaccelui,anticlocklis)4798 VALUE_CHANGED (menu::defvelaccelui, anticlocklis) {
4799 float v = float(f);
4800 MENU.dva.cur->anticlock = v;
4801 MENU.dva.checksync (v, MENU.dva.cur->clock, MENU.dva.clockwise);
4802 MENU.dva.cur->setrotrd ();
4803 cons << "Default Drone Random" << MENU.dva.cur->name << " Anti-clockwise Rotation = " << v << DEGREES << eol;
4804 }
4805
PICKED_OPTION(menu::defvelaccelui,dirlis)4806 PICKED_OPTION (menu::defvelaccelui, dirlis) {
4807 int& idir = MENU.dva.idir;
4808 idir += dir;
4809 wrap<int> (menu::defvelaccelui::HORIZONTAL, idir, menu::defvelaccelui::MOUSE);
4810 MENU.dva.cur->dir = idir;
4811 static const char* s [] = {" Horizontal", " Vertical", " Mouse"};
4812 MENU.dva.odir.set_text (s[idir]);
4813 }
4814
get(float & g,float & ux,float & uy,defvelaccel & dva)4815 void get (float& g, float& ux, float& uy, defvelaccel& dva) {
4816 g = dva.mag ();
4817 point<int> mous (din0.delta_mousex, din0.delta_mousey);
4818 if (mous.x == 0 && mous.y == 0) {
4819 ux = 0;
4820 uy = 1;
4821 } else {
4822 unit_vector<float> (ux, uy, mous.x, -mous.y);
4823 }
4824 float dirxa [] = {1, 0, ux};
4825 float dirya [] = {0, 1, uy};
4826 float nega [] = {1, -1};
4827 float neg = nega [dva.neg];
4828 ux = neg * dirxa [dva.dir];
4829 uy = neg * dirya [dva.dir];
4830 if (dva.rndrot) rotate_vector (ux, uy, dva.rotrd());
4831 }
4832
gethandlesize()4833 int gethandlesize () { return MENU.handlesize();}
gettrailsize()4834 int gettrailsize () {return MENU.trailsize();}
4835
CLICKED_CHECKBUTTON(menu::defvelaccelui,chklis)4836 CLICKED_CHECKBUTTON (menu::defvelaccelui, chklis) {
4837 defvelaccel& dva = *MENU.dva.cur;
4838 int* val [] = {
4839 &dva.mag.rndrd,
4840 &dva.autos.rot.rpm.rndrd,
4841 &dva.autos.rot.dps.rndrd,
4842 &dva.autos.rot.tps.rndrd,
4843 &dva.autos.flip.deg.rndrd,
4844 &dva.neg,
4845 &dva.rndrot,
4846 &dva.autos.rot.yes,
4847 &dva.autos.flip.yes,
4848 };
4849 *val[cb.id] = cb.state;
4850 }
4851
CLICKED_BUTTON(menu::autorott,startlis)4852 CLICKED_BUTTON (menu::autorott, startlis) {
4853 din0.setautorot (MENU.autorotate.which, 1);
4854 }
4855
CLICKED_BUTTON(menu::autorott,stoplis)4856 CLICKED_BUTTON (menu::autorott, stoplis) {
4857 din0.setautorot (MENU.autorotate.which, 0);
4858 }
4859
CLICKED_BUTTON(menu::autorott,togglis)4860 CLICKED_BUTTON (menu::autorott, togglis) {
4861 din0.setautorot (MENU.autorotate.which, 0, 1);
4862 }
4863
CLICKED_BUTTON(menu::autorott,clockwiselis)4864 CLICKED_BUTTON (menu::autorott, clockwiselis) {
4865 din0.setautorotdir (MENU.autorotate.which, -1);
4866 }
4867
CLICKED_BUTTON(menu::autorott,anticlockwiselis)4868 CLICKED_BUTTON (menu::autorott, anticlockwiselis) {
4869 din0.setautorotdir (MENU.autorotate.which, 1);
4870 }
4871
VALUE_CHANGED(menu::autorott,rpmlis)4872 VALUE_CHANGED (menu::autorott, rpmlis) {
4873 din0.setautorotparam (MENU.autorotate.which, menu::autorott::RPM);
4874 }
4875
VALUE_CHANGED(menu::autorott,deglis)4876 VALUE_CHANGED (menu::autorott, deglis) {
4877 din0.setautorotparam (MENU.autorotate.which, menu::autorott::DEG);
4878 }
4879
VALUE_CHANGED(menu::autorott,tpslis)4880 VALUE_CHANGED (menu::autorott, tpslis) {
4881 din0.setautorotparam (MENU.autorotate.which, menu::autorott::TPS);
4882 }
4883
CLICKED_BUTTON(menu::autorott::autoflipt,setlis)4884 CLICKED_BUTTON (menu::autorott::autoflipt, setlis) {
4885 din0.setautoflip (MENU.autorotate.which, 1);
4886 }
4887
CLICKED_BUTTON(menu::autorott::autoflipt,unsetlis)4888 CLICKED_BUTTON (menu::autorott::autoflipt, unsetlis) {
4889 din0.setautoflip (MENU.autorotate.which, 0);
4890 }
4891
CLICKED_BUTTON(menu::autorott::autoflipt,toglis)4892 CLICKED_BUTTON (menu::autorott::autoflipt, toglis) {
4893 din0.setautoflip (MENU.autorotate.which, 0, 1);
4894 }
4895
VALUE_CHANGED(menu::autorott::autoflipt,anglis)4896 VALUE_CHANGED (menu::autorott::autoflipt, anglis) {
4897 din0.setautoflipangle (MENU.autorotate.which);
4898 }
4899
PICKED_OPTION(menu,ol_add_wand_lis)4900 PICKED_OPTION (menu, ol_add_wand_lis) {
4901 static const char* aws [] = {" Add", " Wand"};
4902 din0.dinfo.wand = !din0.dinfo.wand;
4903 MENU.ol_add_wand.set_text (aws[din0.dinfo.wand]);
4904 }
4905
PICKED_OPTION(menu,ol_drones_are_lis)4906 PICKED_OPTION (menu, ol_drones_are_lis) {
4907 static const char* das [] = {"are immortal", "are mortal", "reincarnate"};
4908 drone::ARE += dir;
4909 wrap<int> (drone::IMMORTAL, drone::ARE, drone::REINCARNATE);
4910 sprintf (BUFFER, " Drones %s", das[drone::ARE]);
4911 MENU.ol_drones_are.set_text (BUFFER);
4912 }
4913
VALUE_CHANGED(menu,sp_wand_dist_lis)4914 VALUE_CHANGED (menu,sp_wand_dist_lis) {
4915 int d = f;
4916 drone::wand.set (d);
4917 cons << YELLOW << "Wand distance = " << d << eol;
4918 }
4919
VALUE_CHANGED(menu,risel)4920 VALUE_CHANGED (menu,risel) {
4921 din0.dinfo.drone_rise_time = f;
4922 cons << "Drone rise time = " << din0.dinfo.drone_rise_time << eol;
4923 }
4924
VALUE_CHANGED(menu,falll)4925 VALUE_CHANGED (menu,falll) {
4926 din0.dinfo.drone_fall_time = f;
4927 cons << "Drone fall time = " << din0.dinfo.drone_fall_time << eol;
4928 }
4929
VALUE_CHANGED(menu,lifetimel)4930 VALUE_CHANGED(menu,lifetimel) {
4931 drone::LIFETIME = f;
4932 cons << "Drone life time = " << drone::LIFETIME << SECONDS << eol;
4933 }
4934
VALUE_CHANGED(menu,speedl)4935 VALUE_CHANGED(menu,speedl) {
4936 din0.changechuckspeed (MENU.chspeed);
4937 }
4938
VALUE_CHANGED(menu,lengthl)4939 VALUE_CHANGED(menu,lengthl) {
4940 din0.changechucklength (MENU.chlen);
4941 }
4942
VALUE_CHANGED(menu,traill)4943 VALUE_CHANGED(menu,traill) {
4944 din0.change_drone_trail_points (MENU.chtrail);
4945 }
4946
VALUE_CHANGED(menu,handlesizel)4947 VALUE_CHANGED(menu,handlesizel) {
4948 drone::HANDLESIZE = MENU.handlesize.f_value;
4949 cons << GREEN << "Default drone handle size = " << drone::HANDLESIZE << eol;
4950 }
4951
VALUE_CHANGED(menu,trailsizel)4952 VALUE_CHANGED(menu,trailsizel) {
4953 TRAILSIZE = MENU.trailsize.f_value;
4954 cons << GREEN << "Default Drone/Ball trail size = " << TRAILSIZE << eol;
4955 }
4956
VALUE_CHANGED(menu,angleperframel)4957 VALUE_CHANGED(menu,angleperframel) {
4958 drone::chuckt::apt += MENU.chapt();
4959 RESETALLCHUCKTRAILS
4960 cons << YELLOW << "Angle per turn = " << drone::chuckt::apt.deg << DEGREES << eol;
4961 }
4962
CLICKED_BUTTON(menu,mortalizel)4963 CLICKED_BUTTON(menu,mortalizel) {
4964 din0.mortalize_drones ();
4965 TOGGLEMENU
4966 }
4967
CLICKED_BUTTON(menu,reincarnatel)4968 CLICKED_BUTTON(menu,reincarnatel) {
4969 #define REINCARNATE 1
4970 din0.mortalize_drones (REINCARNATE);
4971 TOGGLEMENU
4972 }
4973
CLICKED_BUTTON(menu,immortalizel)4974 CLICKED_BUTTON(menu,immortalizel) {
4975 din0.immortalize_drones ();
4976 TOGGLEMENU
4977 }
4978
CLICKED_BUTTON(menu,chuckl)4979 CLICKED_BUTTON(menu,chuckl) {
4980 din0.chuck ();
4981 TOGGLEMENU
4982 }
4983
CLICKED_BUTTON(menu,chflipl)4984 CLICKED_BUTTON(menu,chflipl) {
4985 din0.flipchuckspeed ();
4986 TOGGLEMENU
4987 }
4988
CLICKED_BUTTON(menu,chtogl)4989 CLICKED_BUTTON(menu,chtogl) {
4990 din0.togchuckspeed ();
4991 TOGGLEMENU
4992 }
4993
CLICKED_CHECKBUTTON(menu,autoresettrailslis)4994 CLICKED_CHECKBUTTON(menu,autoresettrailslis) {
4995 drone::chuckt::autoresettrails = cb.state;
4996 RESETALLCHUCKTRAILS
4997 }
4998
PICKED_OPTION(menu,anchoredl)4999 PICKED_OPTION(menu,anchoredl) {
5000 drone::anchored = !drone::anchored;
5001 static const char* lbl [] = {" Drone is launched", " Drone is anchored"};
5002 MENU.anchored.set_text (lbl[drone::anchored]);
5003 }
5004
clicked(button & cb)5005 void menu::moddirs::clicked (button& cb) {
5006 DECL_BUTTONS
5007 for (int i = 0; i < 4; ++i) {
5008 if (&cb == b[i]) {
5009 din0.setmoddir (what, i);
5010 break;
5011 }
5012 }
5013 TOGGLEMENU
5014 }
5015
setup(const string & l)5016 void menu::moddirs::setup (const string& l) {
5017 DECL_BUTTONS
5018 lbl.set_text (l);
5019 const char* lbl [] = {"Vertical", "Horizontal", "Velocity", "Acceleration"};
5020 for (int i = 0; i < 4; ++i) b[i]->set_text (lbl[i]);
5021 #ifdef __WIDGET_MOVE__
5022 makehier ((widget**) b, 4);
5023 #endif
5024 }
5025
setup()5026 void menu::defvelaccelui::autorotatet::setup () {
5027 dir.set_listener (&dirl);
5028 mov.set_listener (&movl);
5029 #ifdef __WIDGET_MOVE__
5030 widget* w[] = {
5031 &cb,
5032 &dir,
5033 &mov,
5034 &rpm,
5035 &dps,
5036 &tps,
5037 0
5038 };
5039 makehier (w);
5040 #endif
5041 }
5042
load()5043 void menu::defvelaccelui::autorotatet::load () {
5044 defvelaccel& dva = getdva ();
5045 defvelaccel::autost::rott& rot = dva.autos.rot;
5046 cb.set_state (rot.yes, 0);
5047 dir.set_text (diropts[rot.dir]);
5048 mov.set_text (movopts[rot.mov]);
5049 }
5050
5051 #ifdef __WIDGET_MOVE__
setup()5052 void menu::defvelaccelui::autoflipt::setup () {
5053 widget* w[] = {
5054 &cb,
5055 °,
5056 0
5057 };
5058 makehier (w);
5059 }
5060 #endif
5061
PICKED_OPTION(menu::defvelaccelui::autorotatet,dirlis)5062 PICKED_OPTION (menu::defvelaccelui::autorotatet, dirlis) {
5063 defvelaccel& dva = getdva ();
5064 dva.autos.rot.dir += dir;
5065 wrap<int> (autorotator::CLOCKWISE, dva.autos.rot.dir, autorotator::RANDOM);
5066 static const char* opts [] = {" Clockwise", " Anti clockwise", " Clockwise or Anti-clockwise"};
5067 l.set_text (opts[dva.autos.rot.dir]);
5068 }
5069
PICKED_OPTION(menu::defvelaccelui::autorotatet,movlis)5070 PICKED_OPTION (menu::defvelaccelui::autorotatet, movlis) {
5071 defvelaccel& dva = getdva ();
5072 dva.autos.rot.mov += dir;
5073 wrap<int> (autorotator::TICK, dva.autos.rot.mov, autorotator::RANDOM);
5074 static const char* opts [] = {" Ticked", " Smooth", " Smooth or Ticked"};
5075 l.set_text (opts[dva.autos.rot.mov]);
5076 }
5077
CLICKED_CHECKBUTTON(menu::defvelaccelui::autorotatet,chklis)5078 CLICKED_CHECKBUTTON (menu::defvelaccelui::autorotatet, chklis) {
5079 defvelaccel& dva = getdva ();
5080 dva.autos.rot.yes = cb.state;
5081 }
5082
CLICKED_CHECKBUTTON(menu::defvelaccelui::autoflipt,chklis)5083 CLICKED_CHECKBUTTON (menu::defvelaccelui::autoflipt, chklis) {
5084 defvelaccel& dva = getdva ();
5085 dva.autos.flip.yes = cb.state;
5086 }
5087
bouncet()5088 drone::bouncet::bouncet () {
5089 n = 0;
5090 max = MENU.sp_bounces ();
5091 }
5092