Rev 13 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* menu.cc
* DIN Is Noise is copyright (c) 2006-2017 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "menu.h"
#include "menu.h"
#include "ui_list.h"
#include "viewwin.h"
#include "main.h"
#include "din.h"
#include "keyboard_keyboard.h"
#include "mondrian.h"
#include "sounding_board.h"
#include "tcl_interp.h"
#include "console.h"
#include "recorder.h"
#include "oscilloscope.h"
#include <string>
#include <fstream>
using namespace std;
extern ofstream dlog;
extern int mousex, mousey;
extern beat2value octave_shift;
extern std::string INSTRUMENT;
extern int CURRENT_INSTRUMENT;
extern int NUM_INSTRUMENTS;
extern void load_instrument ();
extern float VOICE_VOLUME;
extern int NUM_OCTAVES;
extern float DELTA_DRONE_MASTER_VOLUME;
extern float PHRASE_TEMPO;
extern const int MILLION;
extern void setup_plugin_labels ();
extern oscilloscope scope;
menu::menu () : gater_style_lis (ol_gater_style, "gr", " Style = "), am_style_lis (ol_am_style, "am", " Voice AM style = "), fm_style_lis (ol_fm_style, "fm", " Voice FM style = "), s_phrase_position (192, 16), td_tap_display (36), abe_left (12), abe_right(12), abe_up(12), abe_down(12), pb_zoom_in (16), mb_zoom_out (16), abm_left (12), abm_right(12), abm_up(12), abm_down(12), bm_zoom_in(16), bm_zoom_out(16), abl_left (12, arrow_button::left), abl_right (12, arrow_button::right) {
num_tabs = 0;
filtered = 0;
}
void menu::setup_items () {
// all widgets
widget* im [] = {
&b_keyboard_keyboard,
&b_microtonal_keyboard,
&b_mondrian,
&b_binaural_drones,
&b_microtonal_keyboard_waveform,
&b_drone_waveform,
&b_drone_modulation,
&b_voice_modulation,
&b_gater,
&b_keyboard_keyboard_waveform,
&b_attack,
&b_decay,
&b_midi_velocity,
&b_delays,
&b_octave_shift,
&b_compressor,
&b_morse_code,
&b_mondrian_waveform,
&b_mondrian_attack,
&b_mondrian_decay,
&b_sounding_board_waveform,
&b_exit_din,
&l_octave_shift,
&ab_octave_down,
&ab_octave_up,
&sp_octave_shift_bpm,
&sp_gater_bpm,
&sp_voice_volume,
&cb_drone_anchors,
&sp_change_drone_handle_size,
&sp_change_drone_trail_length,
&ol_modulation,
&sp_am_depth,
&sp_fm_depth,
&sp_am_bpm,
&sp_fm_bpm,
&tab_sep,
&cb_instrument,
&cb_editors,
&cb_parameters,
&cb_file,
&ol_drone_master_volume,
&lf_delta_drone_master_volume,
&b_mute_drones,
&ol_gater_style,
&l_gater,
&ol_am_style,
&ol_fm_style,
&cb_mkb_tools,
&b_add_drones,
&b_move_drones,
&b_delete_drones,
&b_select_all_drones,
&b_invert_drone_selection,
&b_record_phrase,
&b_clear_phrases,
&l_phrase_position,
&s_phrase_position,
&l_range_size,
&b_current_to_all,
&b_default_to_current,
&b_default_to_all,
&cb_snap_drones,
&b_key_to_pitch_at_cursor,
&cb_scope,
&sp_scope_height,
&sp_scope_samples,
&l_tap_bpm,
&td_tap_display,
&l_tap_bpm_value,
&cb_am,
&cb_fm,
&cb_gater,
&cb_octave_shift,
&cb_auto_reset,
&cb_ed_tools,
&abe_left,
&abe_right,
&abe_up,
&abe_down,
&ab_up,
&ab_down,
&b_close,
&cb_snapx,
&cb_snapy,
&cb_snapboth,
&cb_snapnone,
&l_snap,
&pb_zoom_in,
&mb_zoom_out,
&b_insert_vertex,
&b_delete_vertex,
&b_fold_tangents,
&b_unfold_tangents,
&b_mirror_curve,
&ol_vertices_carry_tangents,
&ol_mirror_tangents,
&cb_fold_vertex,
&b_undo,
&b_redo,
&b_copy,
&b_paste,
&b_draw_replacement_curve,
&l_library,
&abl_left,
&abl_right,
&lf_curve_name,
&b_add_curve,
&b_replace_curve,
&b_delete_curve,
&l_capture,
&b_start_capture,
&b_assign_capture,
&b_delete_capture,
&cb_label_vertices,
&cb_show_waveform_samples,
&sp_waveform_hz,
&b_pick_curve,
&sp_curve_resolution,
&sp_waveform_periods,
&ol_curve_style,
&sp_curve_rpm,
&b_stop_rotating,
&cb_draw_curve,
&cb_record,
&b_clear_record,
&lf_file,
&b_save,
&b_select_attractees,
&b_select_attractors,
&b_orbit_selected_drones,
&cb_show_vel,
&cb_show_accel,
&sp_change_drone_vel,
&sp_change_drone_accel,
&cb_show_gravity,
&b_move_drones_under_gravity,
&sp_rotate_drone_vel,
&sp_drones_per_min,
&b_launch_drones,
&b_stop_launching_drones,
&b_create_mesh,
&sp_mesh_rows,
&sp_mesh_cols,
&b_track_drones,
&b_select_tracked_drones,
&sp_bounces,
&sp_rebound,
&b_track_gravity,
&b_add_balls,
&b_move_selected_balls,
&b_delete_selected_balls,
&b_delete_all_balls,
&b_select_all_balls,
&b_invert_selected_balls,
&b_select_balls_in_box,
&b_split_horizontal,
&b_split_vertical,
&b_delete_box,
&sp_mondrian_voices,
&sp_mondrian_change_attack_time,
&sp_mondrian_change_decay_time,
&sp_mondrian_change_vel,
&b_freeze_balls,
&b_thaw_balls,
&abm_left,
&abm_right,
&abm_up,
&abm_down,
&bm_zoom_in,
&bm_zoom_out,
&b_turn_off_ui,
&b_set_targets,
&b_clear_targets,
&sp_drone_lifetime,
&sp_orbit_insertion_time,
&b_clear_modulations,
&b_modulate_balls_up,
&b_modulate_balls_down,
&cb_sounding_board_tools,
&sp_bd_master_volume,
&sp_bd_separation,
&b_create_binaurals_on_notes,
&b_create_binaurals_from_pitch,
&b_sync_all_binaurals,
&b_delete_all_binaurals,
&b_list_all_binaurals,
&lf_bd_start_pitch,
&sp_bd_pairs,
&lf_bd_spacing,
&cb_close_octave,
&sp_bd_fade_time,
&sp_mondrian_change_dir,
&sp_mondrian_change_trail_size,
&sp_mondrian_change_note_poly_points,
&sp_mondrian_change_note_poly_radius,
&b_auto_change_direction_clockwise,
&b_stop_auto_changing_direction,
&b_auto_change_direction_anti_clockwise,
&b_flip_direction,
&b_make_random_color,
&ol_justification,
&cb_resize_separation,
&ol_key_note,
&b_add_remove_slits,
&b_select_wreckers,
&b_select_healers,
&b_switch_ball_type,
&b_toggle_wreckers,
&b_toggle_healers,
&b_toggle_bouncers,
&sp_mondrian_change_slit_size,
&b_remove_current_box_slits,
&b_remove_all_slits
};
// tabs
num_tabs = 0;
last_tab = cur_tab = 0;
checkbutton* cbns [] = {
&cb_file, &cb_instrument, &cb_editors,
&cb_parameters, &cb_mkb_tools,
&cb_ed_tools,
&cb_mon_tools, &cb_mon_parameters,
&cb_sounding_board_tools
};
static const char* const cbn_lbls [] = {
"File", "Instrument", "Editors",
"Parameters", "Tools",
"Tools",
"Tools", "Parameters",
"Tools"
};
for (int i = 0; i < 9; ++i) {
checkbutton* cbni = cbns[i];
cbni->set_label (cbn_lbls[i]);
cbni->set_listener (this);
}
widget* wfile [] = {
&cb_record,
&b_exit_din,
&lf_file,
&b_clear_record,
&b_save,
&b_turn_off_ui,
&cb_scope,
&sp_scope_height,
&sp_scope_samples
}; // file
cb_record.set_listener (&recl);
b_clear_record.set_listener (&recl);
b_save.set_listener (&recl);
lf_file.fld.typing_lsnr = &recl;
lf_file.fld.set_text ("din.wav");
lf_file.lbl.set_text ("File on Desktop:");
widget* winst [] = {
&b_microtonal_keyboard,
&b_keyboard_keyboard,
&b_mondrian,
&b_binaural_drones
}; // instruments
widget* weds [] = { // editors
&b_microtonal_keyboard_waveform,
&b_drone_waveform,
&b_drone_modulation,
&b_voice_modulation,
&b_gater,
&b_keyboard_keyboard_waveform,
&b_attack,
&b_decay,
&b_midi_velocity,
&b_mondrian_waveform,
&b_mondrian_attack,
&b_mondrian_decay,
&b_sounding_board_waveform,
&b_delays,
&b_octave_shift,
&b_compressor,
&b_morse_code,
};
widget* wpars [] = { // microtonal keyboard parameters
&l_octave_shift,
&ab_octave_down,
&ab_octave_up,
&sp_octave_shift_bpm,
&l_gater,
&sp_gater_bpm,
&ol_gater_style,
&sp_voice_volume,
&cb_drone_anchors,
&sp_change_drone_handle_size,
&sp_change_drone_trail_length,
&ol_modulation,
&sp_am_depth,
&sp_fm_depth,
&sp_am_bpm,
&sp_fm_bpm,
&ol_drone_master_volume,
&lf_delta_drone_master_volume,
&b_mute_drones,
&cb_show_vel,
&cb_show_accel,
&sp_change_drone_vel,
&sp_change_drone_accel,
&cb_show_gravity,
&sp_rotate_drone_vel,
&sp_drones_per_min,
&sp_drone_lifetime,
&sp_orbit_insertion_time
};
widget* wtools [] = { // microtonal keyboard tools
&b_add_drones,
&b_move_drones,
&b_move_drones_under_gravity,
&b_delete_drones,
&b_select_all_drones,
&b_invert_drone_selection,
&b_orbit_selected_drones,
&b_select_attractees,
&b_select_attractors,
&b_launch_drones,
&b_stop_launching_drones,
&b_create_mesh,
&b_track_drones,
&b_select_tracked_drones,
&b_track_gravity,
&b_set_targets,
&b_clear_targets,
&b_record_phrase,
&b_clear_phrases,
&l_phrase_position,
&s_phrase_position,
&l_range_size,
&b_current_to_all,
&b_default_to_current,
&b_default_to_all,
&cb_snap_drones,
&b_key_to_pitch_at_cursor,
&l_tap_bpm,
&td_tap_display,
&l_tap_bpm_value,
&cb_am,
&cb_fm,
&cb_gater,
&cb_octave_shift,
&cb_auto_reset,
&sp_mesh_rows,
&sp_mesh_cols,
&sp_bounces,
&sp_rebound,
};
widget* wetools [] = { // curve editors tools
&abe_left,
&abe_right,
&abe_up,
&abe_down,
&pb_zoom_in,
&mb_zoom_out,
&cb_snapx,
&cb_snapy,
&cb_snapboth,
&cb_snapnone,
&l_snap,
&b_pick_curve,
&b_insert_vertex,
&b_delete_vertex,
&b_fold_tangents,
&b_unfold_tangents,
&b_mirror_curve,
&ol_vertices_carry_tangents,
&ol_mirror_tangents,
&b_undo,
&b_redo,
&b_copy,
&b_paste,
&l_library,
&abl_left,
&abl_right,
&lf_curve_name,
&cb_label_vertices,
&ol_curve_style,
&b_add_curve,
&b_replace_curve,
&b_delete_curve,
&b_draw_replacement_curve,
&l_capture,
&b_start_capture,
&b_assign_capture,
&b_delete_capture,
&sp_curve_resolution,
&cb_draw_curve,
&cb_show_waveform_samples,
&sp_waveform_periods,
&sp_waveform_hz,
&sp_curve_rpm,
&b_stop_rotating,
&cb_fold_vertex,
};
widget* wmon [] = { // mondrianic tools
&b_add_balls,
&b_move_selected_balls,
&b_delete_selected_balls,
&b_delete_all_balls,
&b_select_all_balls,
&b_invert_selected_balls,
&b_split_horizontal,
&b_split_vertical,
&b_delete_box,
&b_select_balls_in_box,
&b_freeze_balls,
&b_thaw_balls,
&abm_left,
&abm_right,
&abm_up,
&abm_down,
&bm_zoom_in,
&bm_zoom_out,
&b_clear_modulations,
&b_modulate_balls_up,
&b_modulate_balls_down,
&b_auto_change_direction_clockwise,
&b_auto_change_direction_anti_clockwise,
&b_stop_auto_changing_direction,
&b_flip_direction,
&b_make_random_color,
&b_add_remove_slits,
&b_select_wreckers,
&b_select_healers,
&b_switch_ball_type,
&b_toggle_wreckers,
&b_toggle_healers,
&b_toggle_bouncers,
&b_remove_current_box_slits,
&b_remove_all_slits
};
arrow_button* mnav[] = {&abm_left, &abm_down, &abm_right, &abm_up};
int mdirs [] = {arrow_button::left, arrow_button::bottom, arrow_button::right, arrow_button::top};
for (int i = 0; i < 4; ++i) {
arrow_button* ab = mnav[i];
ab->set_direction (mdirs[i]);
}
widget* wmon_pars [] = {
&l_octave_shift,
&ab_octave_down,
&ab_octave_up,
&sp_octave_shift_bpm,
&sp_mondrian_voices,
&sp_mondrian_change_attack_time,
&sp_mondrian_change_decay_time,
&sp_mondrian_change_vel,
&sp_mondrian_change_dir,
&sp_mondrian_change_trail_size,
&sp_mondrian_change_note_poly_points,
&sp_mondrian_change_note_poly_radius,
&sp_mondrian_change_slit_size
};
unsigned char mr = 0xFA, mg = 0xCA, mb = 0x82;
for (int i = 0; i < 35; ++i) {
widget* wm = wmon[i];
wm->set_color (mr, mg, mb);
static_cast<button*>(wm)->set_listener (&monl);
}
for (int i = 4; i < 13; ++i) wmon_pars[i]->set_color (mr, mg, mb);
for (int i = 0; i < 6; ++i) static_cast<button*>(wetools[i])->set_listener (&pzl);
for (int i = 6; i < 10; ++i) static_cast<checkbutton*>(wetools[i])->set_listener (&snl);
b_undo.click_repeat = b_redo.click_repeat = 1;
abl_left.click_repeat = abl_right.click_repeat = 1;
button* crvops [] = {
&b_insert_vertex,
&b_delete_vertex,
&b_fold_tangents,
&b_unfold_tangents,
&b_mirror_curve,
&b_copy,
&b_paste,
&b_undo,
&b_redo,
&abl_left,
&abl_right,
&b_pick_curve,
&b_add_curve,
&b_replace_curve,
&b_delete_curve,
&b_draw_replacement_curve,
&b_start_capture,
&b_assign_capture,
&b_delete_capture,
};
for (int i = 0; i < 19; ++i) crvops[i]->set_listener (&col);
cb_label_vertices.set_listener (&col);
sp_curve_resolution.set_listener (&col);
lf_curve_name.set_listener (&col);
widget* wsbd [] = { // sounding board
&b_create_binaurals_on_notes,
&b_create_binaurals_from_pitch,
&b_list_all_binaurals,
&b_sync_all_binaurals,
&b_delete_all_binaurals,
&sp_bd_master_volume,
&sp_bd_separation,
&sp_bd_pairs,
&lf_bd_start_pitch,
&lf_bd_spacing,
&sp_bd_fade_time,
&ol_justification,
&ol_key_note,
&cb_resize_separation,
&cb_close_octave
};
for (int i = 0; i < 5; ++i) static_cast<button*>(wsbd[i])->set_listener (&bdl); // binaural drones commands
cb_close_octave.set_listener (&bdl);
cb_resize_separation.set_listener (&bdl);
ol_justification.set_listener (&bdl);
ol_key_note.set_listener (&bdl);
sp_bd_fade_time.set_listener (&bdl);
sp_bd_master_volume.set_listener (&bdl);
sp_bd_master_volume.set_label ("Master volume");
sp_bd_master_volume.set_limits (0.0f, MILLION);
sp_bd_master_volume.set_delta (0.01f);
sp_bd_separation.set_label ("Separation (Hz)");
sp_bd_separation.set_limits (0, MILLION);
sp_bd_separation.set_value (1.0f);
sp_bd_separation.set_delta (1.0f);
sp_bd_pairs.set_label ("Number of Pairs");
sp_bd_pairs.set_value (1);
sp_bd_pairs.set_delta (1);
sp_bd_pairs.set_limits (1, MILLION);
sp_bd_fade_time.set_label ("Fade time");
sp_bd_fade_time.set_limits (0, MILLION);
sp_bd_fade_time.set_delta (1);
lf_bd_spacing.set_label ("Spacing (Hz)");
lf_bd_spacing.set_text ("50");
lf_bd_start_pitch.set_label ("Start Pitch (Hz)");
lf_bd_start_pitch.set_text ("100");
lf_bd_start_pitch.set_listener (&bdl);
int dc = 17;
for (int i = 0; i < dc; ++i) static_cast<button*>(wtools[i])->set_listener (&dcl); // drone commands listener
for (int i = dc, j = i+2; i < j; ++i) static_cast<button*>(wtools[i])->set_listener (&pcl); // phrase commands listener
for (int i = dc+5, j = i+3; i < j; ++i) static_cast<button*>(wtools[i])->set_listener (&rsl); // range size listener
b_mute_drones.set_listener (&dcl);
const int num_editors = 17;
for (int i = 0; i < num_editors; ++i) editors.push_back (weds[i]);
widget** wmap [] = {wfile, winst, weds, wpars, wtools, wetools, wmon, wmon_pars, wsbd};
int numw [] = {9, 4, num_editors, 28, 39, 45, 35, 13, 15};
for (int i = 0; i < 9; ++i) {
int n = numw[i];
widget** wmi = wmap[i];
vector<widget*>& vw = tab_members[cbns[i]];
for (int m = 0; m < n; ++m) {
vw.push_back (wmi[m]);
//wmi[m]->set_moveable(1);
}
vw.push_back (&tab_sep);
tab_sep.set_name ("tab_separator");
}
tab_sep.set_extents (480);
tab_sep.set_color (1.0f, 1.0f, 1.0f);
int si [] = {-1, -1, -1, -1, 1, 6, 14, 2, 3, 8, 9, 10, 11, 4, 5, 12, 13, 20, 21, 22, 24}; // editor indices
unsigned char ir = 0xFA, ig = 0xCA, ib = 0x82;
for (int i = 0; i < num_items; ++i) {
items[i] = im[i];
if (i < n_inst_ed) {
if (i > 3) {
is_inst[i] = 0;
is_ed[i] = 1;
} else {
is_ed[i] = 0;
is_inst[i] = 1;
}
scr_id [i] = si[i];
static_cast<button*>(items[i])->set_listener (this);
items[i]->set_color (ir, ig, ib);
}
}
// voice volume
sp_voice_volume.set_label ("Voice Volume");
sp_voice_volume.set_delta (0.025f);
sp_voice_volume.set_limits (0.f, MILLION);
sp_voice_volume.set_listener (&vvl);
unsigned char vr = 85, vg = 154, vb = 207;
sp_voice_volume.set_color (vr, vg, vb);
ol_am_style.set_color (vr, vg, vb);
ol_fm_style.set_color (vr, vg, vb);
// octave shift
//
l_octave_shift.set_text ("Octave Shift");
ab_octave_down.set_direction (arrow_button::left);
ab_octave_down.set_listener (&osl);
ab_octave_up.set_direction (arrow_button::right);
ab_octave_up.set_listener (&osl);
int arrow_size = 24;
ab_octave_up.set_size (arrow_size);
ab_octave_down.set_size (arrow_size);
sp_octave_shift_bpm.set_label ("BPM");
sp_octave_shift_bpm.set_delta (1);
sp_octave_shift_bpm.set_listener (&osl);
widget* wos [] = {&l_octave_shift, &ab_octave_down, &ab_octave_up, &sp_octave_shift_bpm};
unsigned char osr = 0xfd, osg = 0x63, osb = 0x39;
for (int i = 0; i < 4; ++i) {
widget* w = wos[i];
w->set_color (osr, osg, osb);
//w->set_moveable (1);
}
sp_octave_shift_bpm.set_limits (0.0f, MILLION); // max 1 MILLION beats/min
// gater
l_gater.set_text ("Gater");
//l_gater.set_moveable (1);
sp_gater_bpm.set_label ("BPM");
sp_gater_bpm.set_delta (1);
sp_gater_bpm.set_limits (0, MILLION); // 0 to 1 MILLION beats per minute
sp_gater_bpm.set_listener (&gbl);
ol_gater_style.set_text (" style = ");
//ol_gater_style.set_moveable (1);
ol_gater_style.set_listener (&gater_style_lis);
unsigned char gtr = 0x99, gtg = 0xfd, gtb = 0x63;
l_gater.set_color (gtr, gtg, gtb);
sp_gater_bpm.set_color (gtr, gtg, gtb);
ol_gater_style.set_color (gtr, gtg, gtb);
// drones
//
// ol_drone_master_volume.set_moveable (1);
ol_drone_master_volume.set_text (" Drone Master Volume: ");
ol_drone_master_volume.set_click_repeat (1);
ol_drone_master_volume.set_listener (this);
lf_delta_drone_master_volume.set_label ("@");
lf_delta_drone_master_volume.fld.set_text (DELTA_DRONE_MASTER_VOLUME);
lf_delta_drone_master_volume.fld.change_lsnr = this;
cb_drone_anchors.set_listener (&dcl);
sp_change_drone_handle_size.set_label ("Change drone handle size");
sp_change_drone_trail_length.set_label ("Change drone trail length");
sp_change_drone_handle_size.set_delta (1);
sp_change_drone_handle_size.set_value (0);
sp_change_drone_trail_length.set_value (0);
sp_change_drone_trail_length.set_delta (1);
sp_change_drone_handle_size.set_listener (&dhsl);
sp_change_drone_trail_length.set_listener (&dtl);
unsigned char dr = 249, dg = 232, db = 38;
b_mute_drones.set_color (dr, dg, db);
sp_change_drone_handle_size.set_color (dr, dg, db);
sp_change_drone_trail_length.set_color (dr, dg, db);
sp_change_drone_vel.set_label ("Change drone velocity");
sp_change_drone_vel.set_color (dr, dg, db);
sp_change_drone_vel.set_listener (&dvl);
sp_change_drone_vel.set_delta (0.25);
cb_show_vel.set_listener (&dcl);
sp_change_drone_accel.set_label ("Change drone acceleration");
sp_change_drone_accel.set_color (dr, dg, db);
sp_change_drone_accel.set_listener (&dal);
sp_change_drone_accel.set_delta (0.1);
cb_show_accel.set_listener (&dcl);
cb_show_gravity.set_listener (&dcl);
sp_rotate_drone_vel.set_label ("Rotate drone velocity");
sp_rotate_drone_vel.set_color (dr, dg, db);
sp_rotate_drone_vel.set_listener (&rdvl);
sp_rotate_drone_vel.set_delta (2.0f);
sp_drones_per_min.set_label ("Change drones per minute");
sp_drones_per_min.set_color (dr, dg, db);
sp_drones_per_min.set_delta (5);
sp_drones_per_min.set_listener (&dpml);
sp_drone_lifetime.set_label ("Change drone lifetime");
sp_drone_lifetime.set_delta (0.25);
sp_drone_lifetime.set_color (dr, dg, db);
sp_drone_lifetime.set_listener (&dlf);
sp_orbit_insertion_time.set_label ("Change orbit insertion time");
sp_orbit_insertion_time.set_delta (0.25);
sp_orbit_insertion_time.set_color (dr, dg, db);
sp_orbit_insertion_time.set_listener (&oil);
spinner<int>* msh [] = {&sp_mesh_rows, &sp_mesh_cols};
static const char* const mlb [] = {"Rows", "Columns"};
for (int i = 0; i < 2; ++i) {
spinner<int>* sp = msh[i];
sp->set_value (2);
sp->set_limits (1, MILLION);
sp->set_delta (1);
sp->set_label (mlb[i]);
sp->set_listener (this);
}
lf_delta_drone_master_volume.set_color (dr, dg, db);
ol_drone_master_volume.set_color (dr, dg, db);
// modulation
//
ol_modulation.set_listener (this);
ol_am_style.set_listener (&am_style_lis);
ol_fm_style.set_listener (&fm_style_lis);
/*ol_am_style.set_moveable (1);
ol_fm_style.set_moveable (1);*/
spinner<float>* spn [] = {&sp_am_depth, &sp_fm_depth, &sp_am_bpm, &sp_fm_bpm};
for (int i = 0; i < 4; ++i) {
spinner<float>* spni = spn[i];
spni->set_listener (this);
spni->set_delta (1);
//spni->set_moveable (1);
}
l_phrase_position.set_text ("Phrase position ");
s_phrase_position.set_limits (0.0f, 1.0f);
s_phrase_position.set_listener (this);
for (int i = 1; i < 9; ++i) {
wfile[i]->set_color (ir, ig, ib);
}
b_exit_din.set_listener (&miscl);
b_turn_off_ui.set_listener (&miscl);
b_menu.set_color (ir, ig, ib);
uis.l_mondrian_voices.set_color (ir, ig, ib);
l_range_size.set_text ("Range size?");
cb_snap_drones.set_listener (&sdl);
unsigned char dr1 = 100, dg1 = 200, db1 = 255;
widget* dbt [] = {&b_add_drones, &b_move_drones, &b_move_drones_under_gravity, &b_delete_drones, &b_select_all_drones, &b_invert_drone_selection, &b_select_attractees, &b_select_attractors, &b_orbit_selected_drones, &b_launch_drones, &b_stop_launching_drones, &b_create_mesh, &b_track_drones, &b_select_tracked_drones, &sp_mesh_rows, &sp_mesh_cols, &sp_bounces, &sp_rebound, &b_track_gravity, &b_set_targets, &b_clear_targets,};
for (int i = 0; i < 21; ++i) dbt[i]->set_color (dr1, dg1, db1);
unsigned char pr1 = 200, pg1 = 100, pb1 = 255;
widget* pbt [] = {&b_record_phrase, &b_clear_phrases, &l_phrase_position, &s_phrase_position};
widget* rst [] = {&l_range_size, &b_current_to_all, &b_default_to_current, &b_default_to_all};
unsigned char rsr1 = 200, rsg1 = 240, rsb1 = 80;
for (int i = 0; i < 4; ++i) {
pbt[i]->set_color (pr1, pg1, pb1);
rst[i]->set_color (rsr1, rsg1, rsb1);
}
b_key_to_pitch_at_cursor.set_listener (&miscl);
b_key_to_pitch_at_cursor.set_color (ir, ig, ib);
unsigned char or1 = 255, og1 = 164, ob1 = 0;
cb_scope.set_label ("Show oscilloscope");
cb_scope.set_listener (&scol);
//cb_scope.set_moveable (1);
sp_scope_height.set_label ("Height");
sp_scope_height.set_limits (0, MILLION);
sp_scope_samples.set_label ("Samples");
sp_scope_samples.set_limits (1, oscilloscope::MAX_SAMPLES);
l_tap_bpm.set_text ("Tap BPM");
checkbutton* cb_tars [] = {&cb_am, &cb_fm, &cb_gater, &cb_octave_shift, &cb_auto_reset};
static const char* const cb_text [] = {"AM", "FM", "Gater", "Octave Shift", "Auto reset"};
cb_auto_reset.turn_on ();
for (int i = 0; i < 5; ++i) {
checkbutton* cbi = cb_tars[i];
cbi->set_label (cb_text[i]);
cbi->set_listener (&tbl);
//cbi->set_moveable (1);
}
td_tap_display.set_listener (&tbl);
/*td_tap_display.set_moveable (1);
l_tap_bpm.set_moveable (1);
l_tap_bpm_value.set_moveable (1);*/
float tr = 1.0, tg = 0.6, tb = 0.6;
l_tap_bpm.set_color (tr, tg, tb);
l_tap_bpm_value.set_color (tr, tg, tb);
td_tap_display.set_color (tr, tg, tb);
spinner<int>* sco [] = {&sp_scope_height, &sp_scope_samples};
for (int i = 0; i < 2; ++i) {
spinner<int>* sp = sco[i];
sp->set_delta (16);
sp->set_color(or1, og1, ob1);
sp->set_listener (&scol);
}
char* bpmstr [] = {"os", "fm", "am", "gr"};
spinner<float>* bpmspn [] = {&sp_octave_shift_bpm, &sp_fm_bpm, &sp_am_bpm, &sp_gater_bpm};
for (int i = 0; i < 4; ++i) bpm_map[bpmstr[i]] = bpmspn[i];
// editor tools
arrow_button* enav[] = {&abe_left, &abe_down, &abe_right, &abe_up};
int edirs [] = {arrow_button::left, arrow_button::bottom, arrow_button::right, arrow_button::top};
for (int i = 0; i < 4; ++i) {
arrow_button* ab = enav[i];
ab->set_direction (edirs[i]);
}
l_snap.set_text ("Snap:");
checkbutton* cb_snaps [] = {&cb_snapx, &cb_snapy, &cb_snapboth, &cb_snapnone};
char* cb_snap_str [] = {"X", "Y", "Both", "None"};
for (int i = 0; i < 4; ++i) {
checkbutton* cbi = cb_snaps[i];
cbi->set_label (cb_snap_str[i]);
//l_snap.add_child (cbi);
}
l_library.set_text ("Library");
lf_curve_name.set_label ("Curve name");
l_capture.set_text ("Capture");
ol_vertices_carry_tangents.set_listener (this);
ol_mirror_tangents.set_listener (this);
//ol_curve_style.set_moveable (1);
ol_curve_style.set_text ("Waveform is Classical");
ol_curve_style.set_listener (this);
sp_curve_rpm.set_label ("RPM");
sp_curve_rpm.set_value (0);
sp_curve_rpm.set_delta (1);
sp_curve_rpm.set_limits (0, MILLION);
sp_curve_rpm.set_listener (&col);
sp_curve_rpm.lbl.add_child (&b_stop_rotating);
b_stop_rotating.set_listener (&col);
cb_show_waveform_samples.set_listener (&col);
//cb_show_waveform_samples.set_moveable (1);
sp_waveform_hz.set_label ("Hz");
sp_waveform_hz.set_delta (1);
sp_waveform_hz.set_limits (0.01, MILLION);
sp_waveform_hz.set_listener (&col);
sp_waveform_periods.set_label ("Cycles");
sp_waveform_periods.set_delta (1);
sp_waveform_periods.set_limits (1, MILLION);
sp_waveform_periods.set_listener (&col);
sp_curve_resolution.set_label ("Curve roughness");
sp_curve_resolution.set_limits (0.001, MILLION);
sp_curve_resolution.set_delta (0.001);
cb_draw_curve.set_listener (&col);
//cb_draw_curve.set_moveable(1);
// editor tools color
for (int i = 0; i < 44; ++i) wetools[i]->set_color (ir, ig, ib);
char* labels [] = {
"Menu",
"Microtonal Keyboard",
"Keyboard Keyboard",
"Mondrian",
"Binaural Drones",
"Waveform",
"Drone Waveform",
"Drone Modulation",
"Voice Modulation",
"Gater",
"Waveform",
"Attack",
"Decay",
"MIDI Velocity",
"Delays",
"Octave Shift",
"Compressor",
"Morse Code",
"Exit DIN Is Noise",
"Show anchors",
"Mute",
"Add drones",
"Move drones",
"Delete selected drones",
"Select all drones",
"Invert selected drones",
"Record a phrase",
"Clear phrase",
"Current to all",
"Default to current",
"Default to all",
"Snap drones to notes",
"Set key to pitch at cursor",
"Insert vertex",
"Delete vertex",
"Fold tangents",
"Unfold tangents",
"Mirror about X",
"Undo",
"Redo",
"Copy",
"Paste",
"Draw & replace curve",
"Add",
"Replace",
"Delete",
"Start",
"Assign",
"Delete",
"Label vertices",
"Selection only",
"Show waveform",
"Pick curve",
"Stop",
"Draw curve only",
"Clear",
"Record",
"Select attractees",
"Select attractors",
"Orbit selected drones",
"Show velocity",
"Show acceleration",
"Show gravity",
"Move drones under gravity",
"Launch drones",
"Stop launching drones",
"Create drone mesh",
"Track drones",
"Select tracked drones",
"Track gravity",
"Waveform",
"Attack",
"Decay",
"Add balls",
"Move balls",
"Delete selected balls",
"Delete all balls",
"Select all balls",
"Invert ball selection",
"Select balls in box",
"Split box horizontally",
"Split box vertically",
"Delete box",
"Freeze balls",
"Thaw balls",
"Turn Off UI",
"Set targets",
"Clear targets",
"Clear modulations",
"Modulate balls up",
"Modulate balls down",
"Create binaural drones on the notes of the scale",
"Create binaural drones using parameters above",
"List all binaural drones",
"Sync all binaural drones",
"Delete all binaural drones",
"Waveform",
"Close octave",
"Auto-change ball direction clockwise",
"Auto-change ball direction anti-clockwise",
"Stop auto-changing ball direction",
"Flip ball direction",
"Randomize box color",
"Resize separation",
"Add / Remove slits",
"Toggle wreckers",
"Toggle healers",
"Toggle bouncers",
"Healers <> Wreckers",
"Select wreckers",
"Select healers",
"Remove slits in box",
"Remove all slits"
};
button* buttons [] = {
&b_menu,
&b_microtonal_keyboard,
&b_keyboard_keyboard,
&b_mondrian,
&b_binaural_drones,
&b_microtonal_keyboard_waveform,
&b_drone_waveform,
&b_drone_modulation,
&b_voice_modulation,
&b_gater,
&b_keyboard_keyboard_waveform,
&b_attack,
&b_decay,
&b_midi_velocity,
&b_delays,
&b_octave_shift,
&b_compressor,
&b_morse_code,
&b_exit_din,
&cb_drone_anchors,
&b_mute_drones,
&b_add_drones,
&b_move_drones,
&b_delete_drones,
&b_select_all_drones,
&b_invert_drone_selection,
&b_record_phrase,
&b_clear_phrases,
&b_current_to_all,
&b_default_to_current,
&b_default_to_all,
&cb_snap_drones,
&b_key_to_pitch_at_cursor,
&b_insert_vertex,
&b_delete_vertex,
&b_fold_tangents,
&b_unfold_tangents,
&b_mirror_curve,
&b_undo,
&b_redo,
&b_copy,
&b_paste,
&b_draw_replacement_curve,
&b_add_curve,
&b_replace_curve,
&b_delete_curve,
&b_start_capture,
&b_assign_capture,
&b_delete_capture,
&cb_label_vertices,
&cb_fold_vertex,
&cb_show_waveform_samples,
&b_pick_curve,
&b_stop_rotating,
&cb_draw_curve,
&b_clear_record,
&cb_record,
&b_select_attractees,
&b_select_attractors,
&b_orbit_selected_drones,
&cb_show_vel,
&cb_show_accel,
&cb_show_gravity,
&b_move_drones_under_gravity,
&b_launch_drones,
&b_stop_launching_drones,
&b_create_mesh,
&b_track_drones,
&b_select_tracked_drones,
&b_track_gravity,
&b_mondrian_waveform,
&b_mondrian_attack,
&b_mondrian_decay,
&b_add_balls,
&b_move_selected_balls,
&b_delete_selected_balls,
&b_delete_all_balls,
&b_select_all_balls,
&b_invert_selected_balls,
&b_select_balls_in_box,
&b_split_horizontal,
&b_split_vertical,
&b_delete_box,
&b_freeze_balls,
&b_thaw_balls,
&b_turn_off_ui,
&b_set_targets,
&b_clear_targets,
&b_clear_modulations,
&b_modulate_balls_up,
&b_modulate_balls_down,
&b_create_binaurals_on_notes,
&b_create_binaurals_from_pitch,
&b_list_all_binaurals,
&b_sync_all_binaurals,
&b_delete_all_binaurals,
&b_sounding_board_waveform,
&cb_close_octave,
&b_auto_change_direction_clockwise,
&b_auto_change_direction_anti_clockwise,
&b_stop_auto_changing_direction,
&b_flip_direction,
&b_make_random_color,
&cb_resize_separation,
&b_add_remove_slits,
&b_toggle_wreckers,
&b_toggle_healers,
&b_toggle_bouncers,
&b_switch_ball_type,
&b_select_wreckers,
&b_select_healers,
&b_remove_current_box_slits,
&b_remove_all_slits
};
for (int i = 0; i < 113; ++i) {
button* bi = buttons[i];
bi->set_label (labels[i]);
}
sp_bounces.set_label ("Bounces");
sp_bounces.set_value (0);
sp_bounces.set_limits (0, MILLION);
sp_bounces.set_delta (1);
sp_bounces.set_listener (this);
sp_rebound.set_label ("Speed %");
sp_rebound.set_value (99);
sp_rebound.set_limits (0, MILLION);
sp_rebound.set_delta (1);
sp_rebound.set_listener (this);
sp_mondrian_voices.set_label ("Voices");
sp_mondrian_voices.set_limits (1, MILLION);
sp_mondrian_voices.set_delta (1);
sp_mondrian_voices.set_listener (&monl);
sp_mondrian_change_attack_time.set_label ("Change ball attack time");
sp_mondrian_change_attack_time.set_delta (0.1f);
sp_mondrian_change_attack_time.set_listener (&monl);
sp_mondrian_change_decay_time.set_label ("Change ball decay time");
sp_mondrian_change_decay_time.set_delta (0.1f);
sp_mondrian_change_decay_time.set_listener (&monl);
sp_mondrian_change_vel.set_label ("Change ball speed");
sp_mondrian_change_vel.set_listener (&monl);
sp_mondrian_change_dir.set_label ("Change ball direction");
sp_mondrian_change_dir.set_delta (1.0f);
sp_mondrian_change_dir.set_listener (&monl);
sp_mondrian_change_trail_size.set_label ("Change ball trail length");
sp_mondrian_change_trail_size.set_delta (1);
sp_mondrian_change_trail_size.set_listener (&monl);
sp_mondrian_change_note_poly_points.set_label ("Change note polygon points");
sp_mondrian_change_note_poly_points.set_delta (1);
sp_mondrian_change_note_poly_points.set_listener (&monl);
sp_mondrian_change_note_poly_radius.set_label ("Change note polygon radius");
sp_mondrian_change_note_poly_radius.set_delta (1);
sp_mondrian_change_note_poly_radius.set_listener (&monl);
sp_mondrian_change_slit_size.set_label ("Change slit size");
sp_mondrian_change_slit_size.set_delta (1.0f);
sp_mondrian_change_slit_size.set_listener (&monl);
button* pb[] = {&sp_mondrian_change_dir.increase, &sp_mondrian_change_dir.decrease};
set_repeat (pb, 2, 0.005);
for (int i = 0; i < 13; ++i) {
wsbd[i]->set_color (ir, ig, ib);
//wsbd[i]->set_moveable (1);
}
/*ol_key_note.set_moveable (1);
cb_resize_separation.set_moveable(1);
cb_close_octave.set_moveable(1);*/
uis.b_close.set_listener (&miscl);
recl.typing (lf_file.fld);
}
void menu::update () {
position_menu_items ();
for (int i = 0; i < num_items; ++i) items[i]->update ();
position_tabs ();
}
void menu::setup () {
dlog << "*** setting up menu ***" << endl;
show = 0;
screen_mousex = screen_mousey = 0;
setup_items ();
widget_load ("d_menu", items, num_items);
b_menu.set_listener (this);
dlog << "+++ menu setup complete +++" << endl;
}
void menu::set_pos (int x, int y) {
b_menu.set_pos (x, y);
}
void menu::draw () {
b_menu.draw ();
if (show) {
// draw transparent bg
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (0, 0, 0, 0.9f);
glRecti (bg_extents.left, bg_extents.bottom, bg_extents.right, bg_extents.top); //max (0, bg_bottom), b_stop_launching_drones.extents.right, min (bg_top, view.ymax));
glDisable (GL_BLEND);
glPolygonMode (GL_FRONT, GL_LINE);
glColor3f (0.5, 0.5, 0.5);
glRecti (bg_extents.left, bg_extents.bottom, bg_extents.right, bg_extents.top);
glPolygonMode (GL_FRONT, GL_FILL);
// draw items
for (int i = 0; i < num_tabs; ++i) tabs[i]->draw ();
if (cur_tab) {
vector<widget*>& ti = tab_members [cur_tab];
for (int i = 0, j = ti.size (); i < j; ++i) ti[i]->draw ();
if (cur_tab == &cb_mkb_tools && din0.phrasor0.state == phrasor::playing) s_phrase_position.set_val (din0.phrasor0.amount);
}
}
}
void menu::setup_tabs (ui* scr) {
checkbutton* com [] = {&cb_file, &cb_instrument, &cb_editors};
checkbutton* mkb [] = {&cb_parameters, &cb_mkb_tools};
checkbutton* eds [] = {&cb_ed_tools};
checkbutton* mon [] = {&cb_mon_parameters, &cb_mon_tools};
checkbutton* sbd [] = {&cb_sounding_board_tools};
int clear_existing_tabs = 1;
setup_tabs (com, 3, clear_existing_tabs);
if (scr == &din0) { // microtonal keyboard
setup_tabs (mkb, 2);
} else if (scr == &keybd2) { // keyboard-keyboard
} else if (scr == &mondrian0) { // mondrian
setup_tabs (mon, 2);
} else if (scr == &sounding_board0) { // sounding-board
setup_tabs (sbd, 1);
} else { // is an editor
setup_tabs (com, 3, clear_existing_tabs);
instrument* inst = get_current_instrument ();
if (inst == &mondrian0) setup_tabs (mon, 1);
else if (inst == &sounding_board0);
else setup_tabs (mkb, 1);
setup_tabs (eds, 1);
changed (cb_ed_tools); // focus on tools tab
}
position_tabs ();
}
void menu::setup_tabs (checkbutton** tlist, int n, int clear) {
if (clear) tabs.clear ();
for (int i = 0; i < n; ++i) tabs.push_back (tlist[i]);
num_tabs = tabs.size ();
}
void menu::position_tabs () {
if (num_tabs) {
int x = cb_file.posx, y = cb_file.posy, spacing = 20;
int i = 1, j = 0;
for (; i < num_tabs; ++i, j = i - 1) {
x = x + get_char_width (tabs[j]->label) + spacing;
tabs[i]->set_pos (x, y);
}
tab_sep.set_extents (x + get_char_width (tabs[j]->label) - cb_file.posx);
calc_bg ();
checkbutton* lt = tabs[num_tabs - 1];
menu_mousex = lt->extents.right + 1;
menu_mousey = view.ymax - lt->posy;
}
}
void menu::remove_from_tab (checkbutton* cb, widget* w) {
vector<widget*>& tw = tab_members [cb];
vector<widget*>::iterator end = tw.end (), i = find (tw.begin(), end, w);
if (i != end) tw.erase (i);
}
void menu::add_to_tab (checkbutton* cb, widget* w) {
vector<widget*>& tw = tab_members[cb];
vector<widget*>::iterator end = tw.end (), i = find (tw.begin(), end, w);
if (i == end) tw.push_back (w);
}
int menu::handle_input () {
if (b_menu.handle_input ()) return 1; // menu button present on all screens
if (show) { // menu is visible
// find tab mouse is hovering on
for (int i = 0; i < num_tabs; ++i) tabs[i]->handle_input ();
if (cur_tab) { // handle tab's items
vector<widget*>& tm = tab_members [cur_tab];
for (int i = 0, j = tm.size (); i < j; ++i) if (tm[i]->handle_input ()) return 1;
if (cur_tab == &cb_mkb_tools)
if (b_current_to_all.hover || b_default_to_current.hover || b_default_to_all.hover)
din0.mark_current_range = 1;
else
din0.mark_current_range = 0;
}
}
return 0;
}
void menu::after_drone_selection () {
sp_change_drone_trail_length.set_value (0); dtl.last = 0;
sp_change_drone_handle_size.set_value (0); dhsl.last = 0;
sp_change_drone_vel.set_value (0); dvl.last = 0;
sp_change_drone_accel.set_value (0); dal.last = 0;
sp_rotate_drone_vel.set_value (0); rdvl.last = 0;
sp_drones_per_min.set_value (0); dpml.last = 0;
sp_drone_lifetime.set_value (0); dlf.last = 0;
sp_orbit_insertion_time.set_value (0); oil.last = 0;
init_modulation ();
}
void menu::init_modulation () {
ol_modulation.set_text (modulation_targets[din0.modulate_what]);
spinner<float>* spn [] = {&sp_am_depth, &sp_fm_depth, &sp_am_bpm, &sp_fm_bpm};
static const char* txt [] = {"AM Depth", "FM Depth", "AM BPM", "FM BPM"};
float vals [] = {din0.am_depth, din0.fm_depth, din0.am.get_bpm (), din0.fm.get_bpm ()};
float* pvals[] = {&am_depth, &fm_depth, &am_bpm, &fm_bpm};
static const string change = "Change ";
unsigned char dr = 249, dg = 232, db = 38;
unsigned char vr = 85, vg = 154, vb = 207;
if (din0.modulate_what == din::MODULATE_DRONES) {
for (int i = 0; i < 4; ++i) {
spinner<float>* spni = spn[i];
spni->set_label (change + txt[i]);
spni->set_value (0);
spni->limits = 0;
*pvals[i] = 0;
spni->set_color (dr, dg, db);
ol_modulation.set_color (dr, dg, db);
}
sp_am_depth.set_delta (1.0f);
remove_from_tab (&cb_parameters, &ol_am_style);
remove_from_tab (&cb_parameters, &ol_fm_style);
} else {
for (int i = 0; i < 4; ++i) {
spinner<float>* spni = spn[i];
spni->set_label (txt[i]);
spni->set_value (vals[i]);
*pvals[i] = vals[i];
spni->set_color (vr, vg, vb);
ol_modulation.set_color (vr, vg, vb);
}
sp_am_depth.set_delta (0.01f);
sp_am_bpm.set_limits (0, MILLION);
sp_fm_bpm.set_limits (0, MILLION);
add_to_tab (&cb_parameters, &ol_am_style);
add_to_tab (&cb_parameters, &ol_fm_style);
}
}
void menu::toggle () {
show = !show;
if (show) {
if (filtered) unfilter ();
b_menu.set_label ("Close menu");
style_listener* sl [] = {&gater_style_lis, &am_style_lis, &fm_style_lis};
for (int i = 0; i < 3; ++i) sl[i]->get_style ();
if (uis.crved) uis.crved->setup_tools_menu ();
if (din0.adding_drones) din0.toggle_adding_drones (); else if (din0.moving_drones) din0.toggle_moving_drones ();
din0.stop_creating_mesh ();
din0.finish_phrase_recording ();
keybd2.turn_off_bend ();
screen_mousex = mousex;
screen_mousey = mousey;
SDL_WarpMouse (menu_mousex, menu_mousey);
after_drone_selection ();
spinner<float>* spn [] = {&sp_mondrian_change_vel, &sp_mondrian_change_attack_time, &sp_mondrian_change_decay_time, &sp_mondrian_change_dir};
for (int i = 0; i < 4; ++i) spn[i]->set_value (0.0f);
sp_mondrian_change_trail_size.set_value (0);
sp_mondrian_change_note_poly_points.set_value (0);
sp_mondrian_change_note_poly_radius.set_value (0);
sp_mondrian_change_slit_size.set_value (0);
monl.last = 0;
mondrian0.stop_doing_stuff ();
scol.setup ();
} else {
b_menu.set_label ("Menu");
menu_mousex = mousex;
menu_mousey = mousey;
if (uis.current == &din0)
{if (uis.cb_voice.state || !filtered) warp_mouse ();}
else
{if (!filtered) warp_mouse ();}
din0.mark_current_range = 0;
}
uis.update_bottom_line ();
}
void menu::warp_mouse () {
SDL_WarpMouse (screen_mousex, screen_mousey);
mousex = screen_mousex;
mousey = screen_mousey;
}
void menu::position_menu_items () {
static const int lines = 4;
int targety = view.ymax - lines * get_line_height ();
int dy = targety - cb_file.extents.bottom;
for (int p = 0; p < num_items; ++p) items[p]->move (0, dy);
}
void misc_listener::clicked (button& b) {
if (&b == &uis.main_menu.b_exit_din)
try_quit ();
else if (&b == &uis.main_menu.b_turn_off_ui) {
turn_off_ui ();
return;
} else if (&b == &uis.b_close) {
uis.main_menu.unfilter ();
} else din0.set_key_to_pitch_at_cursor ();
}
void menu::clicked (button& b) {
if (&b == &b_menu) {
cons << console::yellow << "You can right-click to open or close the menu!" << eol;
toggle ();
}
if (show) {
const static char* instruments [] = {"keyboard_keyboard", "microtonal_keyboard", "mondrian", "sounding_board"};
for (int i = 0; i < n_inst_ed; ++i) { // only check for instrument or editors
if (&b == items[i]) { // close menu when instrument or editor selected
if (i < 4) { // an instrument
scope.save_current_instrument ();
CURRENT_INSTRUMENT = i;
INSTRUMENT = instruments[i];
curve_editor* ed = uis.crved;
load_instrument ();
if (ed) cons << console::yellow << "From a curve editor, you can press 1 or ESC to come here!" << eol;
} else { // an editor
ui* ed = uis.uis [scr_id[i]];
setup_tabs (ed);
uis.set_current (ed);
setup_plugin_labels ();
}
return;
}
}
}
}
void menu::changed (checkbutton& tb) { // current tab has changed
int dont_call_listener = 0;
cur_tab = &tb;
tb.turn_on (dont_call_listener);
if (cur_tab == last_tab) return;
if (last_tab) { // hide last tab memebers
last_tab->turn_off (dont_call_listener);
vector<widget*>& v = tab_members [last_tab];
for (int i = 0, j = v.size (); i < j; ++i) v[i]->hide ();
}
vector<widget*>& v = tab_members [cur_tab];
for (int i = 0, j = v.size (); i < j; ++i) v[i]->show ();
last_tab = cur_tab;
calc_bg ();
}
void menu::changed (field& f) {
if (&f == &sp_bounces.f_value) {
filter (&sp_bounces);
} else
if (&f == &sp_rebound.f_value) {
filter (&sp_rebound);
} else
if (&f == &sp_am_depth.f_value) {
float v = f, dv = v - am_depth;
din0.change_am_depth (dv);
am_depth = v;
filter (&sp_am_depth);
} else if (&f == &sp_fm_depth.f_value) {
float v = f, dv = v - fm_depth;
din0.change_fm_depth (dv);
fm_depth = v;
filter (&sp_fm_depth);
} else if (&f == &sp_am_bpm.f_value) {
float v = f, dv = v - am_bpm;
din0.change_am_bpm (dv);
am_bpm = v;
filter (&sp_am_bpm);
} else if (&f == &sp_fm_bpm.f_value) {
float v = f, dv = v - fm_bpm;
din0.change_fm_bpm (dv);
fm_bpm = v;
filter (&sp_fm_bpm);
} else if (&f == &lf_delta_drone_master_volume.fld) {
DELTA_DRONE_MASTER_VOLUME = f;
} else if (&f == &sp_mesh_rows.f_value) {
din0.dinfo.rows = f;
din0.selector.set_mesh (din0.create_mesh, din0.dinfo.rows, din0.dinfo.cols);
} else if (&f == &sp_mesh_cols.f_value) {
din0.dinfo.cols = f;
din0.selector.set_mesh (din0.create_mesh, din0.dinfo.rows, din0.dinfo.cols);
}
}
void menu::changed (slider<float>& s) {
din0.phrasor0.set_cur (s.get_val());
}
void menu::picked (label& lbl, int dir) {
const static char* vct [] = {" Vertices desert tangents", " Vertices carry tangents"};
const static char* mit [] = {" Tangents are not mirrored", " Tangents are mirrored"};
if (&lbl == &ol_modulation.option) {
din0.switch_modulation ();
} else if (&lbl == &ol_drone_master_volume.option) {
din0.update_drone_master_volume (dir * DELTA_DRONE_MASTER_VOLUME);
set_drone_master_volume ();
} else if (&lbl == &ol_vertices_carry_tangents.option) {
uis.crved->carry_tangents = !uis.crved->carry_tangents;
lbl.set_text (vct[uis.crved->carry_tangents]);
} else if (&lbl == &ol_mirror_tangents.option) {
uis.crved->mirror_tangents = !uis.crved->mirror_tangents;
lbl.set_text (mit[uis.crved->mirror_tangents]);
} else if (&lbl == &ol_curve_style.option) {
uis.crved->toggle_curve_style ();
}
}
void menu::calc_bg () {
if (cur_tab && num_tabs) {
vector<widget*>& v = tab_members [cur_tab];
if (v.size () == 0) return;
widget* w0 = v[0];
bg_extents.left = cb_file.extents.left;
bg_extents.right = bg_extents.left;
bg_extents.bottom = w0->extents.bottom;
bg_extents.top = tabs[0]->extents.top;
for (int i = 0, j = v.size (); i < j; ++i) {
widget* wi = v[i];
if (wi->extents.left < bg_extents.left) bg_extents.left = wi->extents.left;
if (wi->extents.right > bg_extents.right) bg_extents.right = wi->extents.right;
if (wi->extents.bottom < bg_extents.bottom) bg_extents.bottom = wi->extents.bottom;
if (wi->extents.top > bg_extents.top) bg_extents.top = wi->extents.top;
}
static const int GUTTER = 5;
bg_extents.resize (GUTTER, GUTTER);
}
}
void menu::set_drone_master_volume () {
sprintf (buf, " Drone Master Volume = %.6f", din0.drone_master_volume);
ol_drone_master_volume.set_text (buf);
}
void menu::show_editors (ui* inst) {
int starts [] = {5, 0, 9, 12};
int ends [] = {9, 5, 12, 13};
int starti = starts[CURRENT_INSTRUMENT], endi = ends[CURRENT_INSTRUMENT];
vector<widget*>& tw = tab_members [&cb_editors];
for (int i = starti; i < endi; ++i) {
widget* ei = editors[i];
tw.push_back (ei);
}
}
void menu::hide_editors () {
vector<widget*>& tw = tab_members [&cb_editors];
for (int i = 0; i < 13; ++i) {
widget* ei = editors[i];
vector<widget*>::iterator itr = find (tw.begin(), tw.end(), ei);
if (itr != tw.end()) tw.erase (itr);
}
}
void menu::update_bpm (const string& name, float value) {
spinner<float>* psp = bpm_map [name];
if (psp) psp->set_value (value);
}
void menu::mark_tap_target () {
interpreter ("set taptarget");
tokenizer tz (interpreter.result);
int dont_call_listener = 0;
while (1) {
string target; tz >> target;
if (target == "") break;
if (target == "gr") cb_gater.turn_on (dont_call_listener);
else if (target == "am") cb_am.turn_on (dont_call_listener);
else if (target == "fm") cb_fm.turn_on (dont_call_listener);
else if (target == "os") cb_octave_shift.turn_on (dont_call_listener);
}
}
menu::~menu () {
widget_save ("d_menu", items, num_items);
}
void octave_shift_listener::clicked (button& b) {
if (&b == &uis.main_menu.ab_octave_up || &b == &uis.ab_octave_up) modulate_up (); else modulate_down ();
}
void octave_shift_listener::changed (field& f) {
octave_shift.set_bpm (f);
if (&f == &uis.sp_octave_shift_bpm.f_value) uis.main_menu.sp_octave_shift_bpm.set_value (f); else uis.sp_octave_shift_bpm.set_value (f);
}
void voice_volume_listener::changed (field& f) {
VOICE_VOLUME = f;
uis.main_menu.filter (&uis.main_menu.sp_voice_volume);
}
void gater_bpm_listener::changed (field& f) {
din0.gatr.set_bpm (f);
uis.main_menu.filter (&uis.main_menu.sp_gater_bpm);
}
void num_octaves_listener::changed (field& f) {
NUM_OCTAVES = f; if (NUM_OCTAVES < 1) NUM_OCTAVES = 1;
din0.setup_ranges (0); // 0 => dont load from disk
din0.update_drone_ranges ();
din0.update_drone_tone ();
}
void drone_handle_size_listener::changed (field& f) {
int now = f;
int d = now - last;
din0.change_drone_handle_size (d);
last = now;
uis.main_menu.filter (&uis.main_menu.sp_change_drone_handle_size);
}
void drone_trail_length_listener::changed (field& f) {
int now = f;
int d = now - last;
din0.change_drone_trail_points (d);
last = now;
uis.main_menu.filter (&uis.main_menu.sp_change_drone_trail_length);
}
void change_drone_vel_listener::changed (field& f) {
float now = f;
float d = now - last;
din0.change_drone_vel (d);
last = now;
uis.main_menu.filter (&uis.main_menu.sp_change_drone_vel);
}
void change_drone_accel_listener::changed (field& f) {
float now = f;
float d = now - last;
din0.change_drone_accel (d);
last = now;
uis.main_menu.filter (&uis.main_menu.sp_change_drone_accel);
}
void rotate_drone_vel_listener::changed (field& f) {
float now = f;
float d = now - last;
din0.rotate_drone_vel (-d);
last = now;
uis.main_menu.filter (&uis.main_menu.sp_rotate_drone_vel);
}
void drones_per_min_listener::changed (field& f) {
int now = f;
int d = now - last;
last = now;
din0.change_drones_per_min (d);
uis.main_menu.filter (&uis.main_menu.sp_drones_per_min);
}
void drone_lifetime_listener::changed (field& f) {
now = f; find_delta ();
din0.change_drone_lifetime (delta);
uis.main_menu.filter (&uis.main_menu.sp_drone_lifetime);
}
void orbit_insertion_time_listener::changed (field& f) {
now = f; find_delta ();
din0.change_orbit_insertion_time (delta);
uis.main_menu.filter (&uis.main_menu.sp_orbit_insertion_time);
}
void style_listener::set_style (const string& style) {
for (int i = 0; i < num_styles; ++i) {
if (styles[i] == style) {
id = i;
string command ("set-style " + what + " " + style);
interpreter (command);
oplist.set_text (prefix + style);
}
}
}
void style_listener::get_style () {
string command ("get-style " + what);
interpreter (command);
oplist.set_text (prefix + interpreter.result);
}
void style_listener::next_style (int dir) {
id += dir;
if (id < 0) id = last_style; else if (id >= num_styles) id = 0;
set_style (styles[id]);
}
void style_listener::picked (label& lbl, int dir) {
next_style (dir);
}
void drone_commands_listener::clicked (button& b) {
int toggle = 0;
if (&b == &uis.main_menu.b_launch_drones) {toggle=1; din0.make_launchers ();} else
if (&b == &uis.main_menu.b_orbit_selected_drones) {toggle=1; din0.orbit_selected_drones ();} else
if (&b == &uis.main_menu.b_select_all_drones) din0.select_all_drones (); else
if (&b == &uis.main_menu.b_add_drones) {toggle = 1; din0.toggle_adding_drones ();} else
if (&b == &uis.main_menu.b_move_drones) {toggle = 1; din0.toggle_moving_drones ();} else
if (&b == &uis.main_menu.b_delete_drones) {toggle = 1; din0.delete_selected_drones ();} else
if (&b == &uis.main_menu.b_set_targets) {toggle = 1; din0.set_targets ();} else
if (&b == &uis.main_menu.b_select_attractees) din0.select_attractees (); else
if (&b == &uis.main_menu.b_select_attractors) din0.select_attractors (); else
if (&b == &uis.main_menu.b_stop_launching_drones) {toggle=1; din0.destroy_launchers ();} else
if (&b == &uis.main_menu.b_move_drones_under_gravity) {toggle = 1; din0.set_drones_under_gravity ();} else
if (&b == &uis.main_menu.b_invert_drone_selection) din0.invert_selected_drones(); else
if (&b == &uis.main_menu.b_track_drones) {toggle=1;din0.make_trackers ();} else
if (&b == &uis.main_menu.b_select_tracked_drones) {toggle=1; din0.select_tracked_drones ();} else
if (&b == &uis.main_menu.b_track_gravity) {toggle=1; din0.set_gravity_to_track_drone ();} else
if (&b == &uis.main_menu.b_create_mesh) {toggle=1; din0.toggle_create_mesh ();} else
if (&b == &uis.main_menu.b_clear_targets) {toggle=1; din0.clear_targets();} else
if (&b == &uis.main_menu.b_mute_drones) {
toggle = 1;
din0.drone_master_volume = 0;
din0.update_drone_tone ();
uis.main_menu.set_drone_master_volume (); // on menu
}
if (toggle) uis.main_menu.toggle ();
}
void drone_commands_listener::changed (checkbutton& cb) {
int state = cb.get_state ();
if (&cb == &uis.main_menu.cb_show_vel) din0.dinfo.vel = state; else
if (&cb == &uis.main_menu.cb_show_accel) din0.dinfo.accel = state; else
if (&cb == &uis.main_menu.cb_show_gravity) {
if (state) din0.dinfo.gravity.show (); else din0.dinfo.gravity.hide ();
} else din0.dinfo.anchor = state;
}
void phrase_commands_listener::clicked (button& b) {
if (&b == &uis.main_menu.b_record_phrase) din0.do_phrase_recording ();
else if (&b == &uis.main_menu.b_clear_phrases) din0.clear_all_phrases ();
uis.main_menu.toggle ();
}
void range_size_listener::clicked (button& b) {
if (&b == &uis.main_menu.b_current_to_all) {
din0.current_range_to_all ();
} else if (&b == &uis.main_menu.b_default_to_current) {
din0.default_range_to_current ();
} else {
din0.default_range_to_all ();
}
}
void snap_drones_listener::changed (checkbutton& cb) {
drone::SNAP_TO_NOTES = cb.get_state ();
}
void scope_listener::changed (field& f) {
int n = f;
if (&f == &uis.main_menu.sp_scope_height.f_value) {
scope.set_height (n);
uis.main_menu.filter (&uis.main_menu.sp_scope_height);
} else {
scope.set_num_samples (n);
uis.main_menu.filter (&uis.main_menu.sp_scope_samples);
}
}
void scope_listener::changed (checkbutton& cb) {
scope.set_visible (cb.get_state());
}
void scope_listener::setup () {
if (scope.visible) uis.main_menu.cb_scope.turn_on (0); else uis.main_menu.cb_scope.turn_off(0);
uis.main_menu.sp_scope_height.set_value (scope.height);
uis.main_menu.sp_scope_samples.set_value (scope.num_samples);
}
void tap_bpm_listener::changed (tap_display& td) {
sprintf (uis.main_menu.buf, "%.3f", td.bpm);
uis.main_menu.l_tap_bpm_value.set_text (uis.main_menu.buf);
extern double TAP_BPM; TAP_BPM = td.bpm;
Tcl_UpdateLinkedVar (interpreter.interp, "tapbpm");
}
void tap_bpm_listener::changed (checkbutton& cb) {
checkbutton* cbs [] = {&uis.main_menu.cb_am, &uis.main_menu.cb_fm, &uis.main_menu.cb_gater, &uis.main_menu.cb_octave_shift};
char* targets [] = {"am", "fm", "gr", "os"};
for (int i = 0; i < 4; ++i) {
checkbutton* cbi = cbs[i];
if (&cb == cbi) {
if (cbi->get_state())
sprintf (uis.main_menu.buf, "add-tap-target %s", targets[i]);
else
sprintf (uis.main_menu.buf, "remove-tap-target %s", targets[i]);
interpreter (uis.main_menu.buf);
return;
}
}
if (&cb == &uis.main_menu.cb_auto_reset) {
if (uis.main_menu.cb_auto_reset.get_state ()) interpreter ("set resetbeat 1"); else interpreter ("set resetbeat 0");
}
}
void pan_zoom_listener::clicked (button& b) {
if (&b == &uis.main_menu.abe_left) {uis.crved->do_panx (1); cons << console::yellow << "You can press a to move curves left" << eol;}
else if (&b == &uis.main_menu.abe_right) {uis.crved->do_panx (-1); cons << console::yellow << "You can press d to move curves right"<< eol;}
else if (&b == &uis.main_menu.abe_up) {uis.crved->do_pany (-1); cons << console::yellow << "You can press w to move curves up" << eol;}
else if (&b == &uis.main_menu.abe_down) {uis.crved->do_pany (+1); cons << console::yellow << "You can press s to move curves down" << eol;}
else if (&b == &uis.main_menu.pb_zoom_in) {uis.crved->do_zoom (-1); cons << console::yellow << "You can press e to zoom in" << eol;}
else {uis.crved->do_zoom (+1);cons << console::yellow << "You can press q to zoom out" << eol;}
}
void snap_listener::changed (checkbutton& cb) {
int dont_call_listener = 0;
checkbutton* snaps [] = {&uis.main_menu.cb_snapnone, &uis.main_menu.cb_snapx, &uis.main_menu.cb_snapy, &uis.main_menu.cb_snapboth};
int ids [] = {basic_editor::SNAP_NONE, basic_editor::SNAP_X, basic_editor::SNAP_Y, basic_editor::SNAP_BOTH};
char* mesgs [] = {"You can press n to turn off snapping", "You can press x to snap in X",
"You can press y to snap in Y", "You can press b to snap in both X and Y"};
for (int i = 0; i < 4; ++i) {
checkbutton* si = snaps[i];
si->turn_off (dont_call_listener);
if (&cb == si) {
uis.crved->set_snap (ids[i]);
cb.turn_on (dont_call_listener);
cons << console::yellow << mesgs[i] << eol;
}
}
}
void menu::set_snap (int what) {
int dont_call_listener = 0;
checkbutton* snaps [] = {&cb_snapnone, &cb_snapx, &cb_snapy, &cb_snapboth};
int ids [] = {basic_editor::SNAP_NONE, basic_editor::SNAP_X, basic_editor::SNAP_Y, basic_editor::SNAP_BOTH};
for (int i = 0; i < 4; ++i) {
checkbutton* si = snaps[i];
si->turn_off (dont_call_listener);
if (what == ids[i]) si->turn_on (dont_call_listener);
}
}
void menu::set_vertices_carry_tangents (int i) {
const static char* vct [] = {" Vertices desert tangents", " Vertices carry tangents"};
ol_vertices_carry_tangents.option.set_text (vct[i]);
}
void menu::set_mirror_tangents (int i) {
const static char* mit [] = {" Tangents are not mirrored", " Tangents are mirrored"};
ol_mirror_tangents.option.set_text (mit[i]);
}
void menu::set_repeat (button** B, int n, double dt) {
for (int i = 0; i < n; ++i) {
button* bi = B[i];
bi->click_repeat = 1;
bi->first_repeat_time = bi->subsequent_repeat_time = dt;
}
}
void menu::set_pan_repeat (double dt) {
button* ab [] = {&abe_left, &abe_right, &abe_up, &abe_down, &abm_left, &abm_right, &abm_up, &abm_down};
set_repeat (ab, 8, dt);
}
void menu::set_zoom_repeat (double dt) {
button* zb [] = {&pb_zoom_in, &mb_zoom_out, &bm_zoom_in, &bm_zoom_out};
set_repeat (zb, 4, dt);
}
void menu::filter (widget* w) {
if (filtered) return;
if (uis.current == &din0) { // on microtonal-keyboard
if (uis.cb_voice.state)
return; // cannot filter when voice is on
}
filtered = w;
uis.widgets_of [uis.current].push_back (w);
uis.b_close.set_pos (w->posx, w->posy - get_line_height ());
uis.b_close.show ();
toggle ();
}
void menu::unfilter () {
uis.remove (filtered);
uis.b_close.hide ();
filtered = 0;
}
void curve_ops_listener::clicked (button& b) {
int toggle = 1;
if (&b == &uis.main_menu.b_undo) {
cons << console::yellow << "You can press z to undo!" << eol;
uis.crved->do_undo ();
toggle = 0;
} else
if (&b == &uis.main_menu.b_redo) {
cons << console::yellow << "You can press LSHIFT + z to redo!" << eol;
uis.crved->do_redo ();
toggle = 0;
} else
if (&b == &uis.main_menu.abl_left) {
uis.crved->do_load_curve (-1);
toggle = 0;
} else
if (&b == &uis.main_menu.abl_right) {
uis.crved->do_load_curve (+1);
toggle = 0;
}
if (&b == &uis.main_menu.b_insert_vertex) {
uis.crved->insert_using_menu ();
} else if (&b == &uis.main_menu.b_delete_vertex) {
uis.crved->remove_using_menu ();
} else if (&b == &uis.main_menu.b_fold_tangents) {
uis.crved->fold_tangents_using_menu ();
} else if (&b == &uis.main_menu.b_unfold_tangents) {
uis.crved->unfold_tangents_using_menu ();
} else if (&b == &uis.main_menu.b_mirror_curve) {
uis.crved->mirror_using_menu ();
} else if (&b == &uis.main_menu.b_copy) {
uis.crved->copy_using_menu ();
} else if (&b == &uis.main_menu.b_paste) {
uis.crved->paste_using_menu ();
} else if (&b == &uis.main_menu.b_pick_curve) {
uis.crved->do_pick_curve ();
}
// to library
else if (&b == &uis.main_menu.b_add_curve) {
uis.crved->add_curve ();
} else if (&b == &uis.main_menu.b_replace_curve) {
uis.crved->replace_curve ();
} else if (&b == &uis.main_menu.b_delete_curve) {
uis.crved->delete_curve ();
} else if (&b == &uis.main_menu.b_draw_replacement_curve) {
uis.crved->draw_replacement_curve_using_menu ();
} else if (&b == &uis.main_menu.b_start_capture) {
uis.crved->start_mouse_capture_from_menu ();
} else if (&b == &uis.main_menu.b_assign_capture) {
uis.crved->assign_mouse_capture_from_menu ();
} else if (&b == &uis.main_menu.b_delete_capture) {
uis.crved->remove_mouse_capture_from_menu ();
} else if (&b == &uis.main_menu.b_stop_rotating) {
uis.main_menu.sp_curve_rpm.set_value (0);
uis.crved->set_rpm (0);
}
if (toggle) uis.main_menu.toggle ();
}
void curve_ops_listener::changed (checkbutton& cb) {
if (&cb == &uis.main_menu.cb_label_vertices) {
uis.crved->label_vertices = cb.get_state ();
} else if (&cb == &uis.main_menu.cb_show_waveform_samples) {
uis.crved->toggle_waveform_samples_display ();
} else if (&cb == &uis.main_menu.cb_draw_curve) {
uis.crved->draw_curve_only = uis.main_menu.cb_draw_curve.get_state ();
}
}
void curve_ops_listener::changed (field& f) {
if (&f == &uis.main_menu.sp_waveform_hz.f_value) {
uis.main_menu.filter (&uis.main_menu.sp_waveform_hz);
uis.crved->set_hz (f);
} else if (&f == &uis.main_menu.sp_waveform_periods.f_value) {
uis.main_menu.filter (&uis.main_menu.sp_waveform_periods);
uis.crved->set_periods (f);
} else if (&f == &uis.main_menu.sp_curve_rpm.f_value) {
uis.main_menu.filter (&uis.main_menu.sp_curve_rpm);
uis.crved->set_rpm (f);
} else if (&f == &uis.main_menu.sp_curve_resolution.f_value) {
uis.main_menu.filter (&uis.main_menu.sp_curve_resolution);
uis.crved->set_resolution (f);
} else {
if (f.text == "") f.set_text ("noname");
uis.crved->set_picked_curve_name (f.text);
}
}
void recording_listener::clicked (button& b) {
if (&b == &uis.main_menu.b_clear_record) {
recorder0.clear ();
uis.cb_record.set_label ("Record");
uis.main_menu.cb_record.set_label ("Record");
if (uis.main_menu.show) uis.main_menu.toggle ();
} else {
recorder0.start_saving ();
}
}
void recording_listener::typing (field& f) {
string fname (recorder0.folder + f.text);
string cmd ("file exists " + fname);
interpreter (cmd); int result; stringstream ss; ss << interpreter.result; ss >> result;
if (result) uis.main_menu.b_save.set_label ("Overwrite"); else uis.main_menu.b_save.set_label ("Save");
recorder0.fname = f.text;
}
void recording_listener::changed (checkbutton& cb) {
int state = cb.get_state ();
if (state == 0) { // show recording save section of file menu
uis.main_menu.changed (uis.main_menu.cb_file);
if (uis.main_menu.show == 0) uis.main_menu.toggle ();
} else { // close file menu
if (uis.main_menu.show == 1) uis.main_menu.toggle ();
}
dont_call_listener (uis.cb_record, state);
dont_call_listener (uis.main_menu.cb_record, state);
}
void mondrian_listener::clicked (button& b) { // for tools of Mondrian
int toggle = 1;
if (&b == &uis.main_menu.b_split_horizontal) mondrian0.split_rect (split::HORIZONTAL, mondrian0.win.mousey);
else if (&b == &uis.main_menu.b_split_vertical) mondrian0.split_rect (split::VERTICAL, mondrian0.win.mousex);
else if (&b == &uis.main_menu.b_add_balls) mondrian0.do_add_balls ();
else if (&b == &uis.main_menu.b_add_remove_slits) mondrian0.start_slitting ();
else if (&b == &uis.main_menu.b_modulate_balls_up) {if (!mondrian0.modulate_balls (+1)) cons << console::red << "Please select some balls!" << eol;}
else if (&b == &uis.main_menu.b_modulate_balls_down) {if (!mondrian0.modulate_balls (-1)) cons << console::red << "Please select some balls!" << eol;}
else if (&b == &uis.main_menu.b_select_all_balls) {mondrian0.select_all_balls ();toggle=0;}
else if (&b == &uis.main_menu.b_invert_selected_balls) {mondrian0.invert_selected_balls ();toggle=0;}
else if (&b == &uis.main_menu.b_select_balls_in_box) {mondrian0.select_box_balls ();toggle=0;}
else if (&b == &uis.main_menu.b_delete_box) mondrian0.delete_rect ();
else if (&b == &uis.main_menu.b_freeze_balls) mondrian0.freeze_balls (mondrian0.get_balls());
else if (&b == &uis.main_menu.b_thaw_balls) mondrian0.thaw_balls (mondrian0.get_balls());
else if (&b == &uis.main_menu.b_delete_all_balls) mondrian0.delete_all_balls ();
else if (&b == &uis.main_menu.b_delete_selected_balls) mondrian0.delete_selected_balls ();
else if (&b == &uis.main_menu.b_move_selected_balls) mondrian0.do_move_balls ();
else if (&b == &uis.main_menu.b_toggle_wreckers) mondrian0.toggle_balls_type (ball::WRECKER);
else if (&b == &uis.main_menu.b_toggle_healers) mondrian0.toggle_balls_type (ball::HEALER);
else if (&b == &uis.main_menu.b_toggle_bouncers) mondrian0.toggle_balls_type (ball::BOUNCER);
else if (&b == &uis.main_menu.b_switch_ball_type) mondrian0.switch_balls_type ();
else if (&b == &uis.main_menu.b_select_wreckers) mondrian0.select_type (ball::WRECKER);
else if (&b == &uis.main_menu.b_select_healers) mondrian0.select_type (ball::HEALER);
else if (&b == &uis.main_menu.b_remove_current_box_slits) mondrian0.remove_slits_on_current_box ();
else if (&b == &uis.main_menu.b_remove_all_slits) mondrian0.remove_all_slits ();
else if (&b == &uis.main_menu.b_clear_modulations) mondrian0.clear_modulations (mondrian0.get_balls());
else if (&b == &uis.main_menu.b_auto_change_direction_clockwise) {mondrian0.set_auto_rotate (-1);}
else if (&b == &uis.main_menu.b_auto_change_direction_anti_clockwise) {mondrian0.set_auto_rotate (1);}
else if (&b == &uis.main_menu.b_stop_auto_changing_direction) {mondrian0.set_auto_rotate (0);}
else if (&b == &uis.main_menu.b_flip_direction) {mondrian0.flip_velocity();}
else if (&b == &uis.main_menu.b_make_random_color) {mondrian0.randomise_box_color();}
else if (&b == &uis.main_menu.abm_left) {mondrian0.do_panx (1); toggle=0;}
else if (&b == &uis.main_menu.abm_right) {mondrian0.do_panx (-1); toggle=0;}
else if (&b == &uis.main_menu.abm_up) {mondrian0.do_pany (+1);toggle=0;}
else if (&b == &uis.main_menu.abm_down) {mondrian0.do_pany (-1); toggle=0;}
else if (&b == &uis.main_menu.bm_zoom_in) {mondrian0.do_zoom(-1); toggle=0;}
else if (&b == &uis.main_menu.bm_zoom_out) {mondrian0.do_zoom(+1); toggle=0;}
if (toggle) uis.main_menu.toggle ();
}
void mondrian_listener::changed (field& f) {
if (&f == &uis.main_menu.sp_mondrian_change_vel.f_value) {
float dv = float (f) - last;
mondrian0.change_vel (dv);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_vel);
}
else if (&f == &uis.main_menu.sp_mondrian_change_attack_time.f_value) {
float dv = float (f) - last;
if (!mondrian0.change_attack_time (dv)) uis.main_menu.sp_mondrian_change_attack_time.set_value (0.0f);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_attack_time);
}
else if (&f == &uis.main_menu.sp_mondrian_change_decay_time.f_value) {
float dv = float (f) - last;
if (!mondrian0.change_decay_time (dv)) uis.main_menu.sp_mondrian_change_decay_time.set_value (0.0f);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_decay_time);
}
else if (&f == &uis.main_menu.sp_mondrian_change_slit_size.f_value) {
float dv = float (f) - last;
mondrian0.change_slit_size (dv);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_slit_size);
}
else if (&f == &uis.main_menu.sp_mondrian_change_dir.f_value) {
float dv = last - float (f);
mondrian0.rotate_velocity (dv);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_dir);
}
else if (&f == &uis.main_menu.sp_mondrian_change_trail_size.f_value) {
int dt = (int)f - last;
mondrian0.change_trail_size (dt);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_trail_size);
}
else if (&f == &uis.main_menu.sp_mondrian_change_note_poly_points.f_value) {
int dp = (int)f - last;
if (!mondrian0.change_poly_points (dp)) uis.main_menu.sp_mondrian_change_note_poly_points.set_value (0);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_note_poly_points);
}
else if (&f == &uis.main_menu.sp_mondrian_change_note_poly_radius.f_value) {
float dr = float(f) - last;
if (!mondrian0.change_poly_radius (dr)) uis.main_menu.sp_mondrian_change_note_poly_radius.set_value (0.0f);
last = f;
uis.main_menu.filter (&uis.main_menu.sp_mondrian_change_note_poly_radius);
}
else if (&f == &uis.main_menu.sp_mondrian_change_dir.f_delta) {
mondrian0.delta_rotate_velocity = float (uis.main_menu.sp_mondrian_change_dir.f_delta);
button* pb[] = {&uis.main_menu.sp_mondrian_change_dir.increase, &uis.main_menu.sp_mondrian_change_dir.decrease};
uis.main_menu.set_repeat (pb, 2, 0.005 * mondrian0.delta_rotate_velocity);
}
else if (&f == &uis.main_menu.sp_mondrian_change_vel.f_delta) mondrian0.delta_velocity = f;
else if (&f == &uis.main_menu.sp_mondrian_voices.f_value) {
mondrian0.voices = f;
mondrian0.print_num_triggered_notes ();
uis.update_bottom_line ();
}
}
void binaural_drones_listener::clicked (button& b) {
if (sounding_board0.fading) {
cons << console::red << "Still executing last command, please try again later!" << console::yellow << eol;
return;
}
sounding_board0.separation = uis.main_menu.sp_bd_separation.f_value;
sounding_board0.master_volume = uis.main_menu.sp_bd_master_volume.f_value;
sounding_board0.pairs = uis.main_menu.sp_bd_pairs.f_value;
#ifdef __EVALUATION__
sounding_board0.pairs = min (1, int(uis.main_menu.sp_bd_pairs.f_value));
#endif
sounding_board0.close_octave = uis.main_menu.cb_close_octave.state;
sounding_board0.resize_separation = uis.main_menu.cb_resize_separation.state;
if (&b == &uis.main_menu.b_create_binaurals_on_notes) {
#ifdef __EVALUATION__
cons << console::red << "This feature is available in the Licensed Version of DIN Is Noise!" << eol;
return;
#endif
cons << console::yellow << "Creating binaural drones [fading in], please wait!" << eol;
float tonic;
if (sounding_board0.keynote == sounding_board::START_PITCH)
tonic = sounding_board0.starting_pitch;
else
tonic = get_tonic (&sounding_board0);
string intervals;
vector<string>& notes = sounding_board0.scaleinfo.notes;
int j = notes.size (); if (sounding_board0.close_octave == 0) --j;
for (int i = 0; i < j; ++i) intervals = intervals + notes[i] + " ";
stringstream cmd;
cmd << "create-binaurals-on-notes " << tonic << ' ' << sounding_board0.separation << " {" << intervals << "}" << ' ' << sounding_board0.resize_separation;
interpreter (cmd.str());
} else if (&b == &uis.main_menu.b_create_binaurals_from_pitch) {
#ifdef __EVALUATION__
if (sounding_board0.num_sounders >= 2) {
cons << console::red << "You can make more than 2 binaural drones in the Licensed Version of DIN Is Noise!" << eol;
return;
}
#endif
cons << console::yellow << "Creating binaural drones [fading in], please wait!" << eol;
stringstream cmd;
string start_pitch = uis.main_menu.lf_bd_start_pitch.fld.text;
string spacing = uis.main_menu.lf_bd_spacing.fld.text;
cmd << "create-binaurals-from-pitch " << start_pitch << ' ' << sounding_board0.separation << ' ' << sounding_board0.pairs << ' ' << spacing;
interpreter (cmd.str());
} else if (&b == &uis.main_menu.b_list_all_binaurals) {
if (sounding_board0.sounders.size ()) {
cons.rollup (0);
interpreter ("list-all-binaurals");
}
} else if (&b == &uis.main_menu.b_sync_all_binaurals) {
cons << console::yellow << "Syncing all binaural drones [fade out + sync + fade in], please wait!" << eol;
interpreter ("sync-all-binaurals");
} else if (&b == &uis.main_menu.b_delete_all_binaurals) {
if (sounding_board0.num_sounders) cons << console::yellow << "Deleting all binaural drones [fade out], please wait!" << eol;
interpreter ("delete-all-binaurals");
}
uis.main_menu.toggle ();
}
void binaural_drones_listener::changed (field& f) {
if (&f == &uis.main_menu.lf_bd_start_pitch.fld) {
sounding_board0.starting_pitch = float(f);
} else if (&f == &uis.main_menu.sp_bd_master_volume.f_value) {
stringstream cmd;
cmd << "set-binaurals-volume " << float(f);
interpreter (cmd.str());
} else if (&f == &uis.main_menu.sp_bd_fade_time.f_value) {
sounding_board0.set_fade_time (float(f));
}
}
void binaural_drones_listener::changed (checkbutton& cb) {
sounding_board0.close_octave = uis.main_menu.cb_close_octave.state;
}
void binaural_drones_listener::picked (label& lbl, int dir) {
if (&lbl == &uis.main_menu.ol_justification.option) {
int j = sounding_board0.change_justification (dir);
string justs [] = {"Left", "Right", "Center"};
uis.main_menu.ol_justification.set_text (" Justification = " + justs[j]);
} else {
int k = sounding_board0.change_key_note (dir);
string kn [] = {"start pitch", "from scale"};
uis.main_menu.ol_key_note.set_text (" Key note is " + kn[k]);
}
}