Subversion Repositories DIN Is Noise

Rev

Rev 2306 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* menu.h
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#ifndef __menu
#define __menu

#define MENU uis.main_menu
#define MENUP &MENU

#include "button.h"
#include "checkbutton.h"
#include "ui.h"
#include "label.h"
#include "separator.h"
#include "arrow_button.h"
#include "spinner.h"
#include "spinner2.h"
#include "options_list.h"
#include "label_field.h"
#include "slider.h"
#include "tap_bpm.h"
#include "plus_button.h"
#include "minus_button.h"
#include "curve_listener.h"
#include "item_list.h"
#include "instrument.h"
#include "drone.h"
#include "drawrrow.h"

#include <map>
#include <vector>
#include <string>

#define TOGGLEMENU MENU.toggle ();

struct ball;

DECL_CLICK_LISTENER (pan_zoom_listener)

struct snap_listener : click_listener, state_listener {
  void clicked (button& b);
  void changed (checkbutton& cb);
};

DECL_FIELD_LISTENER (gater_bpm_listener)
DECL_FIELD_LISTENER (voice_volume_listener)
DECL_FIELD_LISTENER (drone_master_volume_listener)

struct arrowlis : click_listener, change_listener<field> {
  void clicked (button& b);
  void changed (field& f);
};

struct defarrowlis : state_listener, change_listener<field> {
  void changed (checkbutton& cb);
  void changed (field& f);
};

struct octave_shift_listener : click_listener, change_listener<field> {
  void clicked (button& b);
  void changed (field& f);
};

struct drone_handle_size_listener : change_listener<field> {
  int last;
  drone_handle_size_listener () : last (0) {}
  void changed (field& f);
};

struct binaural_drones_listener : click_listener, change_listener<field>, state_listener, option_listener, selection_listener {

  std::string val[5];

  static const char* justs[];
  int just;

  enum {EQUAL = 0, GREATER_THAN_EQUAL, LESSER_THAN_EQUAL, RANGE, ID};
  int select_rule, select_what;

  void clicked (button& b);
  void changed (field& f);
  void changed (checkbutton& cb);
  void picked (label& lbl, int dir);
  void selected (item_list& il, int i);

  void set_hz (int w, float v);
  binaural_drones_listener ();

};

struct ball_ops_listener : click_listener, state_listener, change_listener<field>, option_listener {
  int op_id;
  ball_ops_listener ();
  void changed (checkbutton& cb);
  void changed (field& f);
  void picked (label& lbl, int dir);
  void clicked (button& b);
};

DECL_FIELD_LISTENER(drone_trail_length_listener)
DECL_FIELD_LISTENER(change_drone_vel_listener)
DECL_FIELD_LISTENER(change_drone_accel_listener)
DECL_FIELD_LISTENER(rotate_drone_vec_listener)
DECL_FIELD_LISTENER(drones_per_min_listener)
DECL_FIELD_LISTENER(orbit_insertion_time_listener)
DECL_FIELD_LISTENER(drone_lifetime_listener)

struct drone_commands_listener : click_listener, state_listener {
  void clicked (button& b);
  void changed (checkbutton& cb);
  void startwanding ();
};

DECL_CLICK_LISTENER(phrase_commands_listener)

struct snap_drones_listener : change_listener<field>, option_listener {
  void changed (field& f);
  void picked (label& l, int dir);
};

DECL_STATE_LISTENER(plugin_listener)

DECL_FIELD_LISTENER (ball_direction_listener)
DECL_FIELD_LISTENER (note_poly_radius_listener)
DECL_FIELD_LISTENER (note_poly_points_listener)
DECL_FIELD_LISTENER (trail_length_listener)
DECL_FIELD_LISTENER (ball_volume_listener)
DECL_FIELD_LISTENER (ball_speed_listener)
DECL_FIELD_LISTENER (slit_size_listener)
DECL_FIELD_LISTENER (slit_anim_time_listener)
DECL_FIELD_LISTENER (ball_attack_time_listener)
DECL_FIELD_LISTENER (ball_decay_time_listener)

struct mondrian_listener : click_listener, change_listener<field>, state_listener, option_listener   {

  void clicked (button& b);
  void changed (field& f);
  void changed (checkbutton& cb);
  void picked (label& l, int dir);

  static const char* split_types [3];
  static const int MAX_SPLIT_TYPES = 2;
  int hsplit, vsplit;
  void check_split_type (options_list& ol, int& o);
  void handle_split (int& var, int dir, float t);
  void handle_auto_pick_box (options_list& ol, int dir, int& v);

  static const char* selection_targets [2];
  static const char* pick_box_types [];
  static const char* auto_split_at_types [];
  static const char* auto_split_orient_types [];

};

struct style_listener :  option_listener {
  static const int num_styles = 2;
  static const int last_style = num_styles - 1;
  static std::string styles [num_styles];
  int id;
  options_list& oplist;
  std::string what;
  std::string prefix;

  style_listener (options_list& ol, const std::string& wh, const std::string& pfx) : oplist(ol), what(wh), prefix(pfx) {id = 0;}
  void set_style (const std::string& style);
  void get_style ();
  void next_style (int dir);
  void picked (label& lbl, int dir);

};

struct read_write_mod {
  virtual void read_mod () = 0;
  virtual void write_mod () = 0;
};

struct range_data : read_write_mod {
  int range;
  int mod;
  range_data () : range(0), mod(0) {}
  void read_mod ();
  void write_mod ();
};

#define MAKE_RANGE_DATA_AND_MOUSE_SLIDER_LISTENER(name) struct name : range_data, mouse_slider_listener { \
  void after_slide (); \
  void moused (int dir, double scl); \
};


MAKE_RANGE_DATA_AND_MOUSE_SLIDER_LISTENER (adjust_range_left_listener)
MAKE_RANGE_DATA_AND_MOUSE_SLIDER_LISTENER (adjust_range_right_listener)
MAKE_RANGE_DATA_AND_MOUSE_SLIDER_LISTENER (adjust_range_both_listener)
MAKE_RANGE_DATA_AND_MOUSE_SLIDER_LISTENER (adjust_range_height_listener)

struct range_height_listener : range_data, click_listener, mouse_slider_listener {
  void clicked (button& b);
  void moused (int dir, double scl);
  void after_slide ();
};

struct change_note_listener : click_listener, mouse_slider_listener {
  int id;
  void moused (int dir, double scl);
  void clicked (button& b);
};

DECL_CLICK_LISTENER (change_note_both_listener)

struct change_note_options_listener : option_listener {
  void picked (label& lbl, int dir);
  void set (label& lbl, int v);
};

struct board_height_listener : read_write_mod, click_listener, mouse_slider_listener {
  vector<int> moda;
  void read_mod ();
  void write_mod ();
  void clicked (button& b);
  void moused (int dir, double scl);
  void after_slide ();
};

DECL_CLICK_LISTENER (range_width_listener)

struct set_range_listener : click_listener, option_listener {
  int i;
  set_range_listener () : i(1) {}
  void clicked (button& b);
  void picked (label& lbl, int dir);
};

struct range_mod_lis : curve_listener, click_listener, state_listener {
  void changed (checkbutton& cb);
  void clicked (button& b);
  void edited (curve_editor* ed, int i);
};

DECL_FIELD_LISTENER (range_defaults_lis)

struct oscilloscope;
struct scope_listener : change_listener<field>, state_listener {
  oscilloscope* oscp;
  void changed (field& f);
  void changed (checkbutton& cb);
  void setup ();
};

struct tap_bpm_listener : change_listener<tap_display>, state_listener {
  void changed (tap_display& td);
  void changed (checkbutton& cb);
};

struct recording_listener : click_listener, typing_listener, state_listener {
  void clicked (button& b);
  void changed (checkbutton& cb);
  void typing (field& f);
};


DECL_CLICK_LISTENER (misc_listener)

#define DRONE_PARAMS_N 158
#define DECL_DRONE_PARAMS \
widget* wdrone_params [] = { \
    &sp_drone_master_vol,\
    &masvol0,\
    &sp_drone_vol,\
    &cb_modulation,\
    &cb_motion,\
    &cb_visual,\
    &cb_chuck,\
    &cb_defaults,\
    &separators.dp0,\
    &separators.dp1,\
    &sp_dam_depth,\
    &damd0,\
    &sp_dfm_depth,\
    &dfmd0,\
    &sp_dam_bpm,\
    &sp_dfm_bpm,\
    &sp_dam_pos,\
    &sp_dfm_pos,\
    &am2fm,\
    &fm2am,\
    &diram.lbl,\
    &diram.hor,\
    &diram.vert,\
    &diram.vel,\
    &diram.accel,\
    &dirfm.lbl,\
    &dirfm.hor,\
    &dirfm.vert,\
    &dirfm.vel,\
    &dirfm.accel,\
    &revmod,\
    &sep_bin,\
    &sep0,\
    &autorotate.title,\
    &autorotate.whichl,\
    &autorotate.start,\
    &autorotate.stop,\
    &autorotate.toggle,\
    &autorotate.clockwise,\
    &autorotate.anticlockwise,\
    &autorotate.rpm,\
    &autorotate.deg,\
    &autorotate.tps,\
    &autorotate.mov,\
    &autorotate.smooth,\
    &autorotate.tick,\
    &autorotate.autoflip.angle,\
    &autorotate.autoflip.lbl,\
    &autorotate.autoflip.set,\
    &autorotate.autoflip.unset,\
    &autorotate.autoflip.toggle,\
    &autorotate.autopause.lbl,\
    &autorotate.autopause.set,\
    &autorotate.autopause.unset,\
    &autorotate.autopause.toggle,\
    &autorotate.autopause.every,\
    &autorotate.autopause.f0r,\
    &autorotate.rndflipause.whichl,\
    &autorotate.rndflipause.set,\
    &autorotate.rndflipause.unset,\
    &autorotate.rndflipause.toggle,\
    &sva.lbl,\
    &sva.whats,\
    &sva.neg,\
    &sva.perp,\
    &sva.zero,\
    &sva.hor,\
    &sva.vert,\
    &sva.vel,\
    &sva.accel,\
    &sp_change_drone_vel,\
    &sp_change_drone_accel,\
    &sp_rotate_drone_vel,\
    &rotaccel,\
    &rdvel,\
    &rdaccel,\
    &sp_drones_per_min,\
    &dpl,\
    &sp_drone_lifetime,\
    &sp_orbit_insertion_time,\
    &vel0,\
    &accel0,\
    &sp_wand_dist,\
    &ol_drones_are,\
    &riset,\
    &fallt,\
    &lifetime,\
    &ol_drone_is,\
    &handlesize,\
    &trailsize,\
    &dva.whichl,\
    &dva.ldir,\
    &dva.odir,\
    &dva.neg,\
    &dva.randomize,\
    &dva.sync,\
    &dva.mag,\
    &dva.clockwise,\
    &dva.anticlockwise,\
    &dva.autorotate.cb,\
    &dva.autorotate.mov,\
    &dva.autorotate.dir,\
    &dva.autorotate.rpm,\
    &dva.autorotate.dps,\
    &dva.autorotate.uet.deg,\
    &dva.autorotate.tps,\
    &dva.autorotate.uet.tps,\
    &dva.autoflip.cb,\
    &dva.autoflip.deg,\
    &dva.autopause.cb,\
    &dva.autopause.tar,\
    &dva.autopause.every,\
    &dva.autopause.f0r,\
    &anchored,\
    &dronearrowdefaults.lbl,\
    &dronearrowdefaults.neck,\
    &dronearrowdefaults.shoulder.width,\
    &dronearrowdefaults.shoulder.position,\
    &dronearrowdefaults.cap,\
    &dronearrowdefaults.arrow,\
    &seloncre,\
    &sp_bounces,\
    &ol_bounce_style,\
    &sp_rebound,\
    &gens,\
    &ddpm,\
    &ddpl,\
    &chapt,\
    &chspeed,\
    &chlen,\
    &chflip,\
    &chtog,\
    &chtrail,\
    &choutline,\
    &chautoresettrails,\
    &sp_change_drone_handle_size,\
    &sp_change_drone_trail_length,\
    &l_drone_arrow,\
    &dronearrow.shoulder.position,\
    &dronearrow.shoulder.width,\
    &dronearrow.neck,\
    &dronearrow.cap,\
    &dronearrow.decap,\
    &cb_draw_mesh,\
    &ol_color,\
    &s_red_min,\
    &s_green_min,\
    &s_blue_min,\
    &s_red_max,\
    &s_green_max,\
    &s_blue_max,\
    &sp_stiff,\
    &b_arrow_reset,\
    &ancopa,\
    &cb_show_anchors,\
    &cb_show_vel,\
    &cb_show_accel,\
    &cb_show_gravity,\
  }; // !actung! new adds above cb_show_anchors




#define COLOR_SLIDERS_M 6
#define COLOR_SLIDERS_N (COLOR_SLIDERS_M + 1)
#define DECL_COLOR_SLIDERS widget* slrs [] = {\
  MENUP.s_red_min, MENUP.s_green_min, MENUP.s_blue_min,\
  MENUP.s_red_max, MENUP.s_green_max, MENUP.s_blue_max, \
  MENUP.ol_color\
  };


// the DIN menu
struct menu : widget, option_listener, change_listener<field>, change_listener< slider<float> >, state_listener {

  checkbutton cb_close_octave\
  , cb_resize_separation\
  , cb_record\
  , cb_show_waveform_samples\
  , cb_draw_curve\
  , cb_overlay\
  , cb_file, cb_instrument, cb_editors, cb_parameters, cb_mkb_drone_tools, \
              cb_mkb_drone_params, cb_mkb_voice, cb_mkb_ranges, cb_mkb_misc, \
              cb_ed_tools, cb_mon_parameters, cb_mon_tools, cb_mon_misc, cb_mon_boxops, \
              cb_mon_ballops, cb_binaural_drones_tools, cb_binaural_drones_edit, cb_ed_curves\
  , cb_label_vertices\
  , cb_mark_segments\
  , cb_selection_only\
  , cb_turn\
  , cb_turn_sync\
  , cb_speed\
  , cb_speed_sync\
  , cb_teleport\
  , cb_clone\
  , cb_clone_can_clone\
  , cb_transform\
  , cb_auto_split_box, cb_auto_delete_box\
  , cb_mondrian_auto_adjust_voices\
  , cb_draw_boxes, cb_fill_boxes, cb_draw_notes, cb_label_notes, cb_label_hz_vol,\
    cb_draw_ball_position, cb_draw_ball_heading, cb_draw_ball_trails\
  , cb_mark_ran\
  , cb_mod_ran\
  , cb_pitch_dis, cb_vol_dis, cb_draw_mesh\
  , cb_scope\
  , cb_am, cb_fm, cb_gater, cb_octave_shift\
  , cb_auto_reset\
  , cb_am_bpm\
  , cb_fm_bpm\
  , cb_sync_rows_cols\
  , seloncre\
  , b_microtonal_keyboard, b_keyboard_keyboard, b_mondrian, b_binaural_drones\
  , cb_show_anchors, cb_show_vel, cb_show_accel, cb_show_gravity, cb_conn_wrap\
  , cb_modulation, cb_motion, cb_visual, cb_defaults, cb_chuck, choutline, chautoresettrails\
  , trackcon, vel0, accel0, cb_ed_autoflip, damd0, dfmd0, masvol0, texture, draweditables\
  , track_phrase_position, viewtoo, drawsnaps, drawcursor, sep0;

  MAKE_STATE_LISTENER (undoredoviewlis, urvl)
  MAKE_STATE_LISTENER (drawcursorlis, cursl);

  rotdir rdvel, rdaccel;

  MAKE_STATE_LISTENER (cb_conn_wrap_lis, wrapl)
  MAKE_STATE_LISTENER (autoresettrailslis, aurl)
  MAKE_STATE_LISTENER (curveslistl, curvesl)

  button \
    bbd_select_all, bbd_select_none, bbd_invert_select, bbd_select, bbd_select2, bbd_sync, bbd_delete, bbd_modulate, bbd_flip\
  , b_create_binaurals_on_notes, b_create_binaurals_from_pitch\
  , b_pick_curve, b_swap_curves, b_insert_vertex, b_delete_vertex, b_undo, b_redo, b_copy, b_fold_tangents\
  , b_draw_replacement_curve, b_add_curve, b_replace_curve, b_delete_curve, b_start_capture, b_assign_capture, b_stop_rotating, ed_flip_rotation\
  , b_turn_off_ui, b_exit_din, b_clear_record\
  , b_save, b_close\
  , l_draw_ball, b_add_balls, b_move_selected_balls, b_select_all_targets, b_invert_selected_targets\
  , b_select_targets_in_box, b_delete_selected_targets, b_delete_all_targets, b_split_horizontal\
  , b_split_vertical, b_delete_box, b_freeze_balls, b_thaw_balls, b_modulate_balls_up, b_modulate_balls_down\
  , b_clear_modulations, b_auto_change_direction_clockwise, b_auto_change_direction_anti_clockwise\
  , b_stop_auto_changing_direction, b_flip_direction, b_actual_voices, b_make_random_color\
  , b_add_remove_slits, b_remove_slits_on_edge, b_toggle_slit_anim, b_toggle_wreckers\
  , b_toggle_healers, b_toggle_bouncers, b_switch_ball_type, b_select_wreckers, b_select_healers\
  , b_make_note_grid, b_make_nxn_grid, b_delete_all_boxes, b_ball_trig\
  , b_selected_to_all, b_default_to_selected, b_default_to_all\
  , b_adjust_range_height, b_adjust_board_height, b_adjust_range_left, b_adjust_range_right, b_adjust_range_both\
  , b_change_note_left, b_change_note_right, b_change_note_both\
  , b_get_cur_ran\
  , b_rm_start_all, b_rm_stop_all, b_rm_toggle, b_rm_pause_resume\
  , b_key_to_pitch_at_cursor\
  , b_orbit_selected_drones, b_select_attractees, b_select_attractors\
  , b_scale_drones\
  , b_set_xform_center\
  , b_rotate_drones\
  , b_launch_drones\
  , b_stop_launching_drones\
  , b_set_targets\
  , b_clear_targets\
  , b_track_drones\
  , b_select_tracked_drones\
  , b_flip_rows_cols\
  , b_set_to_mesh_cols\
  , b_set_to_mesh_rows\
  , b_record_phrase, b_clear_phrases\
  , b_delete_drones\
  , b_select_all_drones, b_invert_drone_selection\
  , balloon\
  , b_select_launchers\
  , b_freeze_drones, b_thaw_drones\
  , b_set, b_unset, b_toggle\
  , b_menu, b_microtonal_keyboard_waveform, b_drone_waveform, b_drone_modulation, b_voice_modulation, \
    b_range_modulation, b_range_width_height, b_range_pitch_vol, b_gater, b_noise_interpolator, \
    b_keyboard_keyboard_waveform, b_attack, b_decay, b_midi_velocity, b_mondrian_waveform, b_mondrian_attack, \
    b_mondrian_decay, b_delays, b_octave_shift, b_compressor, b_morse_code, b_binaural_drones_waveform,\
    b_point_modulation,\
    b_connect, b_disconnect, b_drone_pend, b_abort_octave_shift,\
    b_arrow_reset, b_mute, b_unmute, drone2noise, noise2drone,\
    immortalize, mortalize, reincarnate,\
    chuck, chflip, chtog, edlife2vel,\
    b_snapx, b_snapy, b_snapboth, b_snapnone, am2fm, fm2am, ed_autoflip_reset,\
    size_tangent, pinunpin;

  MAKE_CLICK_LISTENER(am2fm2amlis, am2fm2aml)

 
  struct moddirs : click_listener {
    int what;
    label lbl;
    button vert, hor, vel, accel;
    #define DECL_BUTTONS button* b[] = {&vert, &hor, &vel, &accel, 0};
    moddirs (int w) {
      what = w;
      DECL_BUTTONS
      for (int i = 0; i < 4; ++i) b[i]->set_listener(this);
    }
    void setup (const std::string& l);
    void clicked (button& cb);
  } diram, dirfm;

  MAKE_CLICK_LISTENER(drone2noiselis, d2nl)
  MAKE_CLICK_LISTENER(noise2dronelis, n2dl)
  MAKE_CLICK_LISTENER(b_menu_lis,mbl)
  MAKE_CLICK_LISTENER(b_ed_lis,edl)
  MAKE_CLICK_LISTENER(b_inst_lis,insl)
  MAKE_CLICK_LISTENER(b_connect_lis,bconl)
  MAKE_CLICK_LISTENER(b_disconnect_lis,bdconl)
  MAKE_CLICK_LISTENER(b_abort_octave_shift_lis,aosl)
  MAKE_CLICK_LISTENER(b_arrow_reset_lis,awl)
  MAKE_CLICK_LISTENER (b_mute_lis, mul)
  MAKE_CLICK_LISTENER (b_unmute_lis, umul)
  MAKE_CLICK_LISTENER (b_set_xform_center_lis, xcl)
  MAKE_CLICK_LISTENER (mortalizel, morl)
  MAKE_CLICK_LISTENER (immortalizel, immorl)
  MAKE_CLICK_LISTENER (reincarnatel, reinl)
  MAKE_CLICK_LISTENER (chuckl, chl)
  MAKE_CLICK_LISTENER (chflipl, flpl)
  MAKE_CLICK_LISTENER (chtogl, ctogl)


  label_field lf_bd_start_pitch\
  , lf_curve_name\
  , lf_bd_spacing\
  , lf_vol_fade_time, lf_pitch_fade_time, lf_master_volume, lf_modulation_amount, lf_l, lf_r, lf_sep, lf_vol\
  , lf_file, lf_conn_steps;

  field text_ure;


  struct lf_conn_steps_lis : change_listener<field>, typing_listener {
    void changed (field& f);
    void typing (field& f);
  } stepsl;

  field f_mesh_xy\
  , bdf_value;

  plus_button bm_zoom_in\
  ,pb_zoom_in;

  minus_button bm_zoom_out\
  , mb_zoom_out;

  item_list il_binaural_drones;

  label l_library\
  , l_capture\
  , l_snap\
  , l_ran_mod\
  , l_drone_arrow\
  , l_tap_bpm, l_tap_bpm_value\
  , l_octave_shift, l_gater\
  , l_drone_order\
  , l_use_drone_pend\
  , l_apply_to\
  , l_phrase_position\
  , l_adjust_height, l_adjust_range;

  arrow_button abm_left, abm_right, abm_up, abm_down\
  , ab_octave_down, ab_octave_up\
  , bd_modulate_up, bd_modulate_down\
  , abe_left, abe_right, abe_up, abe_down\
  , abl_left, abl_right;

  struct crvwavt {
    spinner<float> hz, time;
    spinner<int> periods;
  } crvwav;

  spinner<float> sp_bd_separation\
  , sp_curve_limit\
  , sp_curve_rpm\
  , dp_bpm1\
  , sp_turn_every\
  , sp_turn_min, sp_turn_max\
  , sp_speed_every\
  , sp_speed_min, sp_speed_max\
  , sp_max_speed\
  , sp_tel_every\
  , sp_tel_radius\
  , sp_clone_every\
  , sp_clone_offset\
  , sp_transform_every\
  , sp_auto_split_time, sp_auto_delete_time, sp_min_split_size\
  , sp_mondrian_change_vol, sp_mondrian_change_attack_time, sp_mondrian_change_decay_time, sp_mondrian_change_speed,\
    sp_mondrian_change_slit_size, sp_mondrian_change_slit_anim_time, sp_mondrian_change_note_poly_radius\
  , sp_mesh_dur\
  , sp_snap_left, sp_snap_right\
  , sp_ran_mod_width, sp_ran_mod_height\
  , sp_ran_mod_width_bpm, sp_ran_mod_height_bpm\
  , sp_octave_shift_bpm\
  , sp_gater_bpm\
  , sp_voice_volume\
  , sp_drone_master_vol\
  , sp_drone_vol\
  , sp_change_drone_vel\
  , sp_change_drone_accel\
  , sp_drones_per_min\
  , sp_drone_lifetime\
  , sp_orbit_insertion_time\
  , sp_am_depth, sp_fm_depth\
  , sp_am_bpm, sp_fm_bpm\
  , sp_dam_depth, sp_dfm_depth\
  , sp_dam_bpm, sp_dfm_bpm\
  , sp_dam_pos, sp_dfm_pos\
  , sp_stiff\
  , sp_rotate_drone_vel\
  , chapt, chspeed, chlen, scopacity\
  , rotaccel\
  , sep_bin;

  MAKE_FIELD_LISTENER(speedl,spdl)
  MAKE_FIELD_LISTENER(lengthl,lenl)
  MAKE_FIELD_LISTENER(traill, chtll)
  MAKE_FIELD_LISTENER(angleperframel, apfl)


  spinner<int> sp_bd_pairs\
  , sp_default_width, sp_default_height\
  , sp_lev_sz\
  , sp_scope_height\
  , sp_scope_samples\
  , sp_mondrian_num_boxes\
  , sp_max_clones\
  , sp_max_balls\
  , sp_mondrian_min_voices,  sp_mondrian_change_dir, sp_mondrian_change_trail_size, sp_mondrian_change_note_poly_points\
  , sp_mesh_rows, sp_mesh_cols\
  , sp_drones_per_pend\
  , dp_numdrones\
  , sp_browse_drone\
  , sp_range\
  , sp_change_drone_handle_size\
  , sp_change_drone_trail_length\
  , sp_wand_dist, chtrail, dpl;

  spinner2<int> handlesize, trailsize, sp_bounces, sp_rebound, gens, ddpm, ddpl, texstep;
  spinner2<float> lifetime, gabt, riset, fallt, sp_curve_every, ancopa;

  MAKE_FIELD_LISTENER (sep_bin_lis, sepbinl)
  MAKE_FIELD_LISTENER(sp_wand_dist_lis, wandl)
  MAKE_FIELD_LISTENER(risel,rl)
  MAKE_FIELD_LISTENER(falll,fl)
  MAKE_FIELD_LISTENER(lifetimel, lifel)
  MAKE_FIELD_LISTENER(handlesizel, handl)
  MAKE_FIELD_LISTENER(trailsizel, trll)

  MAKE_FIELD_LISTENER(genslis, gensl)
  MAKE_FIELD_LISTENER(ddpmlis, ddpml)
  MAKE_FIELD_LISTENER(ddpllis, ddpll)

  MAKE_FIELD_LISTENER(dpllis, dpll)
  MAKE_FIELD_LISTENER(texsteplis, stepl)

  struct {
    label lbl;
    spinner2<float> neck;
    struct {
      spinner2<float> position, width;
    } shoulder;
    checkbutton cap;
    drawrrow arrow;
  } dronearrowdefaults;

  options_list ol_key_note, ol_justification\
  , ol_select_what, ol_select_rule, ol_just, ol_mirror\
  , ol_mirror_tangents\
  , ol_curve_style\
  , ol_set_range\
  , ol_change_note\
  , ol_change_note_style\
  , ol_fixed\
  , ol_ball_types, ol_split_types_h, ol_split_types_v, ol_selection_targets\
  , ol_auto_pick_box_split, ol_auto_pick_box_delete, ol_auto_split_at, ol_auto_split_orient\
  , ol_browse_balls\
  , ol_bouncer, ol_healer, ol_wrecker\
  , ol_snap_style\
  , dp_orient\
  , ol_drone_is\
  , ol_bounce_style\
  , ol_create_this\
  , ol_drone_order\
  , ol_mesh_point\
  , ol_gater_style\
  , ol_am_style, ol_fm_style\
  , ol_set_unset_toggle\
  , ol_color\
  , ol_add_wand\
  , ol_drones_are\
  , anchored\
  , moverailstrafe\
  , revmod\
  , ol_paste;


  MAKE_OPTION_LISTENER (ol_paste_lis, pastl)
  MAKE_OPTION_LISTENER (ol_color_lis, ocoll)
  MAKE_OPTION_LISTENER (ol_add_wand_lis, awdl)
  MAKE_OPTION_LISTENER (ol_drones_are_lis, darl)
  MAKE_OPTION_LISTENER (anchoredl, ancl)
  MAKE_OPTION_LISTENER (revmodl, revl)

  MAKE_OPTION_LISTENER (moverailstrafelis, mrsl)
  MAKE_CLICK_LISTENER(movlis, bmdl)
  MAKE_CLICK_LISTENER(raillis, raill)
  MAKE_MOUSE_SLIDER_LISTENER (raillis1, raill1)
  MAKE_CLICK_LISTENER(strafelis, strafel)
  MAKE_CLICK_LISTENER(revclkl, revcl)
  MAKE_MOUSE_SLIDER_LISTENER (strafelis1, strafel1)


  octave_shift_listener osl;
  style_listener gater_style_lis;
  gater_bpm_listener gbl;
  voice_volume_listener vvl;
  drone_master_volume_listener dmvol;
  MAKE_FIELD_LISTENER(sp_drone_vol_lis, dvol);
  drone_handle_size_listener dhsl;
  drone_trail_length_listener dtl;
  change_drone_vel_listener dvl;
  change_drone_accel_listener dal;
  rotate_drone_vec_listener rdvl;
  drones_per_min_listener dpml;
  drone_lifetime_listener dlf;
  orbit_insertion_time_listener oil;
  style_listener am_style_lis, fm_style_lis;
  MAKE_CLICK_LISTENER(b_set_unset_toggle_lis, sutl)
  MAKE_CLICK_LISTENER(b_scale_drones_lis, bsdl)
  MAKE_CLICK_LISTENER(b_move_drones_under_gravity_lis, dugl)
  MAKE_MOUSE_SLIDER_LISTENER(ms_scale_drones_lis, ms_sdl)
  MAKE_CLICK_LISTENER(b_rotate_drones_lis, brdl)
  MAKE_MOUSE_SLIDER_LISTENER (ms_rotate_drones_lis, ms_rdl)
  MAKE_STATE_LISTENER(cb_am_bpm_lis, abl)
  MAKE_STATE_LISTENER(cb_fm_bpm_lis, fbl)
  MAKE_FIELD_LISTENER(drones_per_pend_lis, dppl)
  MAKE_FIELD_LISTENER(sp_stiff_lis, stiffl)
  MAKE_FIELD_LISTENER(ancopalis, anchl)
  MAKE_FIELD_LISTENER(gabt_lis, gabtl)
  MAKE_CLICK_LISTENER(set_to_mesh_rows_lis, stmrl)
  MAKE_CLICK_LISTENER(set_to_mesh_cols_lis, stmcl)
  drone_commands_listener dcl;
  snap_drones_listener sdl;
  phrase_commands_listener pcl;
  set_range_listener sral;
  range_width_listener rwl;
  range_height_listener rhl;
  board_height_listener bhl;
  change_note_listener cnl, cnr;
  change_note_both_listener cnb;
  change_note_options_listener cnol, cnsl;
  adjust_range_left_listener arl;
  adjust_range_right_listener arr;
  adjust_range_both_listener arb;
  range_mod_lis rml;
  MAKE_OPTION_LISTENER (ol_fixed_lis, fxl)
  range_defaults_lis rdel;

  struct pitch_vol_dis_pix_lis : state_listener, change_listener<field> {
    void changed (checkbutton& cb);
    void changed (field& f);
  } pvdl;

  MAKE_STATE_LISTENER (cb_draw_mesh_lis, dml)
  scope_listener scol;
  ball_ops_listener bolis;
  ball_attack_time_listener batl;
  ball_decay_time_listener bdtl;
  ball_speed_listener bsl;
  ball_direction_listener brl;
  ball_volume_listener bvl;
  trail_length_listener tll;
  note_poly_radius_listener nprl;
  note_poly_points_listener nppl;
  slit_size_listener ssl;
  slit_anim_time_listener satl;
  mondrian_listener monl;
  binaural_drones_listener bdl;
  pan_zoom_listener pzl;
  snap_listener snl;

  struct curve_ops_listener : click_listener, state_listener, change_listener<field>, mouse_slider_listener {
    void clicked (button& b);
    void changed (checkbutton& cb);
    void changed (field& f);
    void after_slide ();
    void moused (int dir, double scl);
  } col;

  misc_listener miscl;
  recording_listener recl;
  MAKE_FIELD_LISTENER (sp_dam_depth_lis, damdl)
  MAKE_FIELD_LISTENER (sp_dfm_depth_lis, dfmdl)
  MAKE_FIELD_LISTENER (sp_dam_pos_lis, dampl)
  MAKE_FIELD_LISTENER (sp_dfm_pos_lis, dfmpl)
  MAKE_FIELD_LISTENER (sp_dam_bpm_lis, dambpml)
  MAKE_FIELD_LISTENER (sp_dfm_bpm_lis, dfmbpml)
  MAKE_FIELD_LISTENER (sp_browse_drone_lis, brwdl)
  MAKE_FIELD_LISTENER (sp_am_depth_lis, amdl)
  MAKE_FIELD_LISTENER (sp_fm_depth_lis, fmdl)
  MAKE_FIELD_LISTENER (sp_am_bpm_lis, ambpml)
  MAKE_FIELD_LISTENER (sp_fm_bpm_lis, fmbpml)
  MAKE_FIELD_LISTENER (sp_bounces_lis, bol)
  MAKE_FIELD_LISTENER (sp_rebound_lis, rebl)
  MAKE_FIELD_LISTENER (sp_range_lis, ranl)
  MAKE_FIELD_LISTENER (sp_ran_mod_width_lis, rmwl)
  MAKE_FIELD_LISTENER (sp_ran_mod_height_lis, rmhl)
  MAKE_FIELD_LISTENER (sp_ran_mod_width_bpm_lis, rmwbl)
  MAKE_FIELD_LISTENER (sp_ran_mod_height_bpm_lis, rmhbl)


  slider<float> s_phrase_position;
  slider<float> s_red_min, s_green_min, s_blue_min;
  slider<float> s_red_max, s_green_max, s_blue_max;
  MAKE_SLIDER_LISTENER (sc_color_lis, cscl)
  MAKE_START_SLIDE_LISTENER(ss_color_lis, slider<float>, cssl)
  MAKE_CLICK_LISTENER (sc_close_lis, cscll)
  void initcolorsliders ();
  void savecolorsliders ();
 

  float am_depth, fm_depth; // for voice modulation
  float dam_depth, dfm_depth, dam_bpm, dfm_bpm; // for drone modulation

  std::map<std::string, spinner<float>*> bpm_map;
  void update_bpm (const std::string& name, float value);

  void load_range (int r);
  void load_range_mod (int r);

  struct {
    spinner<float> neck;
    struct {
      spinner<float> position, width;
    } shoulder;
    button cap, decap;
  } dronearrow;
  arrowlis arrowl;
  defarrowlis defarrowl;

  tap_display td_tap_display;
  tap_bpm_listener tbl;
  void mark_tap_target ();

  void update_binaurals_list ();

  void set_repeat (button** B, int n, double dt); // to enable click repeat on pan & zoom buttons
  void set_zoom_repeat (double dt);
  void set_pan_repeat (double dt);
  void set_snap (int x, int y);
  void set_mirror_tangents (int i);

  // tabs
  int num_tabs;
  std::vector<checkbutton*> tabs;
  std::map< checkbutton*, std::vector<widget*> > tab_members;
  checkbutton *last_tab, *cur_tab, *next_tab;
  void setup_tabs (ui* scr);
  void setup_tabs (checkbutton** tl, int clear = 0);
  void add_to_tab (checkbutton* cb, widget* w);
  void remove_from_tab (checkbutton* cb, widget* w);
  void position_tabs ();
  void position_menu_items ();
  void handle_voice_tab_items (const char* viv);

  struct separators_t {
    separator main, dp0, dp1;
  } separators;

  instrument* next_tab_instr;

  void move_items (int dx, int dy);
  int show;
  int menu_mousex, menu_mousey; // last mouse position on menu
  int screen_mousex, screen_mousey;  // mouse position on screen when menu becomes visible
  box<int> bg_extents;
  float opacity;
  void calc_bg ();
  void set_pos (int x, int y);
  void setup ();
  void update ();
  int handle_input ();
  void changed (field& f);
  void changed (slider<float>& s);
  void changed (checkbutton& cb);
  void changed (tap_display& tb);
  void picked (label& lbl, int dir);

  static const int nitems = 534;
  static const int n_inst_ed = 28;
  widget* items [nitems];

  void loadspinners ();
  void savespinners ();

  std::vector<widget*> editors;
  void show_editors (ui* inst);
  void hide_editors ();

  menu ();

  void setup_items ();
  void draw ();
  void toggle (int mouse_warp = 1);

  void set_ball_ops (ball* b);
  void clear_ball_ops ();

  get_fixed_color gc_top, gc_bottom;
  get_blend_color gc_blend;
  get_random_color gc_rand;
  colorer_t colorer;

  MAKE_STATE_LISTENER(cb_modulation_lis, cmod)
  MAKE_STATE_LISTENER(cb_motion_lis, cmot)
  MAKE_STATE_LISTENER(cb_visual_lis, cvis)
  MAKE_STATE_LISTENER(cb_defaults_lis, cdef)
  MAKE_STATE_LISTENER(cb_chuck_lis,cch)

  void set_drone_params_items (int s, int e);

  ~menu ();

  void populatecurvestab (curve_editor* ed);
  void destroycurvestab ();

  struct autorott : option_listener, click_listener {

    label title;

    label mov;
    button smooth, tick;

    enum {VELOCITY, ACCELERATION, BOTH};
    options_list whichl;
    int which;

    button start, stop, toggle;
    button clockwise, anticlockwise;

    MAKE_CLICK_LISTENER (startlis,startl)
    MAKE_CLICK_LISTENER (stoplis,stopl)
    MAKE_CLICK_LISTENER (togglis,togl)
    MAKE_CLICK_LISTENER (clockwiselis, clkl)
    MAKE_CLICK_LISTENER (anticlockwiselis, aclkl)

    enum {RPM, DEG, TPS, MOVEMENT};
    spinner<float> rpm;
    MAKE_FIELD_LISTENER (rpmlis, rpml)
    MAKE_FIELD_LISTENER (deglis, degl)
    MAKE_FIELD_LISTENER (tpslis, tpsl)

    spinner<float> deg;
    spinner<float> tps;

    void setup ();
    void picked (label& lbl, int dir);
    void clicked (button& b);

    struct autoflipt {

      label lbl;
      button set, unset, toggle;
      MAKE_CLICK_LISTENER(sutlis, sutl)

      spinner<float> angle;
      MAKE_FIELD_LISTENER (anglis, angl)

    } autoflip;

    struct autopauset {

      label lbl;
      button set, unset, toggle;
      MAKE_CLICK_LISTENER(sutlis, sutl)

      spinner<float> every, f0r;
      MAKE_FIELD_LISTENER (everylis, everyl)
      MAKE_FIELD_LISTENER (f0rlis, f0rl)

    } autopause;

    struct rndflipauset {
      button set, unset, toggle;
      MAKE_CLICK_LISTENER(sutlis, sutl)
      int which;
      options_list whichl;
      MAKE_OPTION_LISTENER (rndflipauselis, optl)
      rndflipauset() : which (0) {}
    } rndflipause;

  } autorotate;

 
  struct setvelaccel : click_listener, option_listener {
    label lbl;
    options_list whats;
    int what;
    button zero, hor, vert, vel, accel;
    checkbutton neg;
    perpbutton perp;
    void setup ();
    void clicked (button& b);
    void picked (label& lbl, int dir);
  } sva;

  struct defvelaccelui : option_listener {

    defvelaccel* cur;

    enum {VELOCITY, ACCELERATION};
    options_list whichl;
    int which;

    label ldir;
    options_list odir;
    int idir;
    enum {HORIZONTAL, VERTICAL, MOUSE};

    spinner2<float> mag;
    spinner<float> clockwise, anticlockwise;
    checkbutton neg;
    checkbutton randomize;
    checkbutton sync;
    void checksync (float v, anglet& t, spinner<float>& sp);

    struct autorotatet {
      checkbutton cb;
      MAKE_STATE_LISTENER (chklis, chkl)
      static const char *diropts[], *movopts[];
      options_list dir;
      options_list mov;
      MAKE_OPTION_LISTENER (dirlis, dirl)
      MAKE_OPTION_LISTENER (movlis, movl)
      spinner2<float> rpm, dps, tps;
      struct {
        checkbutton deg, tps;
      } uet;
      void setup ();
      void load ();
    } autorotate;

    struct autoflipt {
      checkbutton cb;
      spinner2<float> deg;
#ifdef __WIDGET_MOVE__
      void setup ();
#endif
    } autoflip;

    struct autopauset {
      checkbutton cb;
      spinner2<float> every;
      spinner2<float> f0r;
      static const char* tars [];
      options_list tar;
#ifdef __WIDGET_MOVE__
      void setup ();
#endif
    } autopause;

    void picked (label&, int);
    MAKE_OPTION_LISTENER (dirlis, dirl)
    MAKE_FIELD_LISTENER (maglis, magl)
    MAKE_FIELD_LISTENER (rpmlis, rpml)
    MAKE_FIELD_LISTENER (dpslis, dpsl)
    MAKE_FIELD_LISTENER (tpslis, tpsl)
    MAKE_FIELD_LISTENER (deglis, degl)
    MAKE_FIELD_LISTENER (everylis, everyl)
    MAKE_FIELD_LISTENER (f0rlis, f0rl)
    MAKE_OPTION_LISTENER (tarlis, tarl)
    MAKE_FIELD_LISTENER (varlis, varl)
    MAKE_STATE_LISTENER (chklis, chkl)
    MAKE_FIELD_LISTENER (clocklis, clockl)
    MAKE_FIELD_LISTENER (anticlocklis, aclockl)

    void setup ();
    void load ();

  } dva;

  void initdroneparamtabs (checkbutton& cb);

};

#endif