Rev 543 |
Rev 657 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* ui.cc
* DIN Is Noise is copyright (c) 2006-2018 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "ui_list.h"
#include "din.h"
#include "morse_code.h"
#include "console.h"
#include "curve_editor.h"
#include "tcl_interp.h"
#include "command.h"
#include "chrono.h"
#include "keyboard_keyboard.h"
#include "viewwin.h"
#include "authors_note.h"
#include "fft.h"
#include "main.h"
#include "curve_picker.h"
#include "fractaliser.h"
#include "warper.h"
#include "recorder.h"
#include "mondrian.h"
#include "binaural_drones.h"
#include "spiraler.h"
#include "circler.h"
#include "rose_milker.h"
#include "sine_mixer.h"
#include <fstream>
#include <string>
using namespace std;
extern string user_data_dir;
extern curve_editor waved, comed, octed, veled, dmod_ed, delayed;
extern int mousex, mousey, mouseyy;
extern string INSTRUMENT;
extern int rmb;
extern const int MILLION;
extern oscilloscope scope;
template <typename S, typename T> static void load_parameter_limits (ifstream& fptr, T** lfs, int n) {
S lo, hi;
string name;
for (int i = 0; i < n; ++i) {
fptr >> name >> lo >> hi;
T* t = lfs[i];
t->set_name (name);
t->set_limits (lo, hi);
}
}
template <typename S, typename T> static void save_parameter_limits (ofstream& fptr, T** lfs, int n) {
S lo, hi;
for (int i = 0; i < n; ++i) {
T* t = lfs[i];
t->get_limits (lo, hi);
fptr << t->name << ' ' << lo << ' ' << hi << endl;
}
}
ui_list::ui_list () :
fed (fnt, "font.ed", "font.hlp"),
lfs_attack_time ("Attack Time", 70, 15, atv),
lfs_decay_time ("Decay Time", 70, 15, dkv),
lfs_num_voices ("Voices", 70, 15, nvv),
d_min_max("Min/Max"), mml_min ("Min"), mml_max ("Max"),
lmm_attack (lfs_attack_time),
lmm_decay (lfs_decay_time),
lmm_num_voices (lfs_num_voices) {
current = 0;
prev = 0;
crved = 0;
esct = -1;
rmb_clicked = 0;
}
void ui_list::set_current (ui* u) {
if (current) {
current->leave ();
prev = current;
}
current = u;
cons << YELLOW << "@ " << current->name << eol;
current->enter ();
if (u->ed) {
crved = static_cast<curve_editor*>(u);
if (crved->is_waveform_editor) dofft ();
} else {
//crved = 0;
uis[0] = current;
//if (_is_inst) uis[0] = current;
}
}
void ui_list::bg () {
current->calc_win_mouse ();
for (vector<ui*>::size_type i = 1, j = uis.size(); i < j; ++i) uis[i]->bg (); // bg for instruments and editors
// fade fx for voice, gater & delay
eval_fade (fdr_voice, cb_voice);
flash_gater (); // flashes in sync with gater value
eval_fade (fdr_delay, cb_delay);
}
int ui_list::is_widget_on_screen (widget* w, ui* scr) {
vector<widget*>& widgets = widgets_of [scr];
for (int i = 0, j = widgets.size (); i < j; ++i) if (w == widgets[i]) return 1;
return 0;
}
int ui_list::handle_input () {
// handle quit
//
#ifdef __MACOSX_CORE__
if (keydown (SDLK_LMETA) && keydown (SDLK_q)) { // command key + q on mac os x
quit = IMMEDIATE;
return 1;
}
#else
if (alt_down () && keydown (SDLK_F4)) { // alt + f4 on windows & linux
quit = IMMEDIATE;
return 1;
}
#endif
// toggle menu
//
#ifdef __EVALUATION__
if (current != &anote) { // no menu on author's note
#endif
if (rmb) {
if (!rmb_clicked) {
rmb_clicked = 1;
if (escape_from_things ());
else main_menu.toggle ();
}
} else rmb_clicked = 0;
#ifdef __EVALUATION__
}
#endif
// handle widgets
//
basic_editor::hide_cursor = mouse_slider0.active;
if (widget::focus == 0) { // find a widget that has focus
vector<widget*> widgets = widgets_of [current];
for (vector<widget*>::size_type i = 0, j = widgets.size (); i < j; ++i) {
widget* wi = widgets[i];
if (wi->visible && wi->enabled) wi->handle_input ();
if (widget::focus) return 1;
}
} else { // handle input of widget with focus
widget::focus->handle_input ();
return 1;
}
// handle current screen
current->handle_input ();
// handle common
if (keypressed (SDLK_1)) {
if (current->ed == 0) goto_next_instrument (); // switch instrument
load_instrument ();
} else { // switch to editor
for (int i = 0; i < MAX_EDITORS; ++i) {
if (keypressed (key[i])) {
ui* edi = ed[i];
if (edi) {
main_menu.setup_tabs (edi);
set_current (edi);
return 1;
}
}
}
}
if (keypressed(SDLK_RETURN)) {
if (alt_down ()) { // clear recording
main_menu.recl.clicked (main_menu.b_clear_record);
} else if (ctrl_down()) { // start recording
if (cb_record.state == 0) cb_record.turn_on (); else cb_record.turn_off ();
}
}
if (keypressed (SDLK_F2)) {if (TURN_OFF_UI) turn_on_ui (); else turn_off_ui ();}
if (keypressed (SDLK_PAUSE)) {
scope.visible = !scope.visible;
main_menu.cb_scope.set_state (scope.visible, 0);
}
if (keypressed (SDLK_MENU)) main_menu.clicked (main_menu.b_menu);
if (keypressed (SDLK_ESCAPE)) {
if (TURN_OFF_UI) turn_on_ui ();
else if (escape_from_things()) ;
else if (current->ed) {
if (crved->todo != curve_editor::NOTHING) {
crved->do_nothing ();
return 1;
} else load_instrument ();
} else if (current == &settings_scr) {
load_instrument ();
} else { // ask to press esc again to really quit
esc:
if (esct == -1) {
cons << console::red << "Press ESC again to quit" << eol;
esct = ui_clk();
} else {
static const float ESC_TIMEOUT = 1; // in seconds
double dt = ui_clk() - esct;
if (dt > ESC_TIMEOUT) {
esct = -1;
goto esc;
} else if (quit != TRY) try_quit ();
}
}
}
return 1;
}
int ui_list::set_editor (const string& name, int screen) {
if (screen > 0) {
ui* ei = 0;
for (int i = 0, j = uis.size(); i < j; ++i) {
if (uis[i]->name == name) {
ei = uis[i];
break;
}
}
if (ei) {
ed [screen - 2] = ei;
return 1;
} else {
cmdlst.result = "bad editor name";
return 0;
}
} else {
cmdlst.result = "bad screen number (valid: 2 to 8)";
return 0;
}
}
void ui_list::draw () {
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
current->draw ();
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, view.xmax, 0, view.ymax, 0, 1);
vector<widget*> widgets = widgets_of [current];
for (vector<widget*>::size_type i = 0, j = widgets.size (); i < j; ++i) {
widget* wi = widgets[i];
if (wi->visible) wi->draw ();
}
}
// all screens
ui* SCREENS [] = {
&din0.waved,
&din0.moded,
&din0.gated,
&delayed,
&octed,
&din0.droneed,
&keybd2,
&keybd2.waved,
&keybd2.attacked,
&keybd2.decayed,
&keybd2.veled,
&comed,
&mc.ed,
&dmod_ed,
&uis.fed,
&fractaliser_.ed,
&warper_.ed,
&mondrian0,
&din0,
&mondrian0.waved,
&mondrian0.attacked,
&mondrian0.decayed,
&binaural_drones0,
&binaural_drones0.waved,
&spiraler_.scr.sin_ed,
&spiraler_.scr.cos_ed,
&spiraler_.scr.rad_ed,
&rosemilker.scr.sin_ed,
&rosemilker.scr.cos_ed,
&circler_.scr.sin_ed,
&circler_.scr.cos_ed,
&circler_.scr.rad_ed,
&sinemixer.sin_ed,
0
};
void ui_list::add_widgets () {
// add fft display on waveform editors
ui* uwav [] = {&din0.waved, &keybd2.waved, &din0.droneed, &mondrian0.waved, &binaural_drones0.waved};
for (int i = 0; i < 5; ++i) widgets_of[uwav[i]].push_back (&fft0);
// add plugin browser to these editors
ui* ueds [] = {
&din0.waved,
&din0.moded,
&din0.droneed,
&dmod_ed,
&keybd2.waved,
&fractaliser_.ed,
&warper_.ed,
&mondrian0.waved,
&din0.gated,
&binaural_drones0.waved,
&circler_.scr.sin_ed,
&circler_.scr.cos_ed,
&sinemixer.sin_ed,
&rosemilker.scr.sin_ed,
&rosemilker.scr.cos_ed,
&spiraler_.scr.sin_ed,
&spiraler_.scr.cos_ed
};
for (int i = 0; i < 17; ++i) widgets_of[ueds[i]].push_back (&plugin__browser);
// add oscilloscope to all instruments
extern const int NUM_INSTRUMENTS;
extern instrument* INSTRUMENT_PTR[];
for (int i = 0; i < NUM_INSTRUMENTS; ++i) widgets_of[(ui *)INSTRUMENT_PTR[i]].push_back (&scope);
// add selectors to microtonal keyboard and mondrian
mkb_selector.set_listener (&din0);
mon_selector.set_listener (&mondrian0);
widget* wall [] = {&cons, &main_menu, &b_close}; // appears on everything
for (ui** p = SCREENS; *p != 0; ++p) {
ui* u = *p;
if (is_instrument (u) == 0) widgets_of[u].push_back (&curve_picker); // picker on all editors
for (int i = 0; i < 3; ++i) widgets_of[u].push_back (wall[i]);
}
b_close.hide ();
// no menu on author's note & settings screen
widgets_of[&anote].push_back(&cons);
widgets_of[&settings_scr].push_back (&cons);
widget* wdin [] = {
&cb_voice,
&cb_gater,
&cb_delay,
&cb_compress,
&b_settings,
&ab_scroll_left,
&ab_scroll_right,
&ab_scroll_up,
&ab_scroll_down,
&cb_show_pitch_volume_board,
&cb_show_pitch_volume_drones,
&cb_record,
&din0.dinfo.gravity,
&mkb_selector
};
widget* wkeybd2 [] = {
&cb_delay,
&cb_compress,
&b_settings,
&lfs_attack_time,
&lfs_decay_time,
&lfs_num_voices,
&l_pitch_bend,
&sp_pitch_bend,
&cb_show_nearby_notes,
&d_parameters,
&ab_parameters,
&l_waveform_display,
&ab_prev_wav,
&ab_next_wav,
&cd_waveform_display,
&d_min_max,
&l_octave_shift,
&ab_octave_down,
&ab_octave_up,
&sp_octave_shift_bpm,
&cb_record
};
widget* wmondrian [] = {
&l_mondrian_voices,
&cb_delay,
&cb_compress,
&b_settings,
&cb_record,
&mon_selector,
};
widget* wsbd [] = {
&cb_delay,
&cb_compress,
&b_settings,
&cb_record
};
for (int i = 0, j = 14; i < j; ++i) widgets_of [&din0].push_back (wdin[i]);
for (int i = 0, j = 21; i < j; ++i) widgets_of [&keybd2].push_back (wkeybd2[i]);
for (int i = 0, j = 6; i < j; ++i) widgets_of [&mondrian0].push_back (wmondrian[i]); l_mondrian_voices.set_label ("Voices: ** / **");
for (int i = 0, j = 4; i < j; ++i) widgets_of [&binaural_drones0].push_back (wsbd[i]);
// min/max for sliders
widget* wmmx [] = {&mml_min, &mml_max, &mmf_min, &mmf_max};
for (int i = 0; i < 4; ++i) {
widget* w = wmmx [i];
widgets_of[&keybd2].push_back(w);
}
}
void ui_list::setup () {
uis.push_back (0); // will be filled by load_instrument later
for (ui** p = SCREENS; *p != 0; ++p) {
ui* u = *p;
uis.push_back (u);
}
int dirs [] = {arrow_button::left, arrow_button::right, arrow_button::up, arrow_button::down};
arrow_button* scrl [] = {&ab_scroll_left, &ab_scroll_right, &ab_scroll_up, &ab_scroll_down};
for (int i = 0; i < 4; ++i) {
arrow_button* si = scrl[i];
si->set_direction (dirs[i]);
si->set_size (12);
si->set_listener (&sal);
si->click_repeat = 1;
si->first_repeat_time = 0.005;
si->subsequent_repeat_time = 0.015;
}
cb_voice.set_listener (&vlis);
cb_voice.colorize (0);
cb_gater.set_listener (&glis);
cb_gater.colorize (0);
cb_delay.set_listener (&dlis);
cb_delay.colorize (0);
cb_compress.set_listener (&clis);
b_settings.set_listener (&slis);
cb_record.set_listener (&main_menu.recl);
// min/max for sliders
widget* wmmx [] = {&mml_min, &mml_max, &mmf_min, &mmf_max};
for (int i = 0; i < 4; ++i) {
widget* w = wmmx [i];
d_min_max.add_child (w);
}
//d_min_max.set_moveable (1);
d_min_max.hide ();
widget* pw1[5] = {&d_min_max, &mml_min, &mml_max, &mmf_min, &mmf_max};
widget_load ("d_min_max", pw1, 5);
// pitch bend
//
l_pitch_bend.set_text ("Pitch Bend");
l_pitch_bend.add_child (&sp_pitch_bend);
sp_pitch_bend.set_label ("Hz/Pixel");
sp_pitch_bend.set_delta (0.01f);
sp_pitch_bend.set_limits (0.0f, MILLION); // upto 1 MILLION hz/pixel
widget* wpb [] = {&l_pitch_bend, &sp_pitch_bend, &cb_show_nearby_notes};
widget_load ("d_pitch_bend", wpb, 3);
sp_pitch_bend.add_child (&cb_show_nearby_notes);
sp_pitch_bend.set_listener (&pbl);
cb_show_nearby_notes.set_listener (&pbl);
cb_show_nearby_notes.turn_off ();
d_parameters.add_child (&l_pitch_bend);
// waveform display
//
l_waveform_display.set_text ("Waveform");
ab_prev_wav.set_direction (arrow_button::left);
ab_prev_wav.set_listener (&wdl);
ab_next_wav.set_direction (arrow_button::right);
ab_next_wav.set_listener (&wdl);
ab_prev_wav.click_repeat = ab_next_wav.click_repeat = 1;
ab_prev_wav.first_repeat_time = ab_next_wav.first_repeat_time = 0.33;
ab_prev_wav.subsequent_repeat_time = ab_next_wav.subsequent_repeat_time = 1/20.;
widget* wwd [] = {&l_waveform_display, &cd_waveform_display, &ab_prev_wav, &ab_next_wav};
widget_load ("d_waveform_display", wwd, 4);
//l_waveform_display.set_moveable (1);
cd_waveform_display.set_size (96, 96);
cd_waveform_display.crv = &keybd2.wave; // keyboard-keyboard's waveform
cd_waveform_display.calc_bbox ();
for (int i = 1; i < 4; ++i) l_waveform_display.add_child (wwd[i]);
d_parameters.add_child (&l_waveform_display);
l_octave_shift.set_text ("Octave Shift");
d_parameters.add_child (&l_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};
for (int i = 1; i < 4; ++i) l_octave_shift.add_child (wos[i]);
sp_octave_shift_bpm.set_limits (0.0f, MILLION); // max 1 MILLION beats/min
label_field_slider<float>* lfs1 [2] = {&lfs_attack_time, &lfs_decay_time};
label_field_slider<int>* lfs2 [1] = {&lfs_num_voices};
ifstream fptr ((user_data_dir + "d_parameter_limits").c_str(), ios::in);
load_parameter_limits<float, label_field_slider<float> > (fptr, lfs1, 2);
load_parameter_limits<int, label_field_slider<int> > (fptr, lfs2, 1);
d_parameters.add_child (&d_min_max);
d_parameters.add_child (&lfs_attack_time);
d_parameters.add_child (&lfs_decay_time);
d_parameters.add_child (&lfs_num_voices);
d_parameters.add_child (&ab_parameters);
widget* pw2[9] = {&d_parameters, &lfs_attack_time, &lfs_decay_time, &lfs_num_voices, &ab_parameters, &l_octave_shift, &ab_octave_up, &ab_octave_down, &sp_octave_shift_bpm};
widget_load ("d_parameters", pw2, 9);
d_parameters.set_moveable (1);
ab_parameters.set_listener (&pal);
d_parameters.set_name ("parameters");
lfs_attack_time.set_name ("attack_time");
lfs_decay_time.set_name ("decay_time");
lfs_num_voices.set_name ("num_voices");
cb_voice.set_state (din0.dinfo.voice);
cb_gater.set_state (din0.dinfo.gater);
cb_delay.set_state (din0.dinfo.delay);
cb_compress.set_state (din0.dinfo.compress);
#ifdef __EVALUATION__
anote.setup ();
#endif
plugin__browser.setup ();
settings_scr.setup ();
main_menu.setup ();
b_close.set_label ("Close");
}
void ui_list::update_widgets (int wnow, int hnow, int wprev, int hprev) {
main_menu.update ();
plugin__browser.update ();
cb_voice.set_label ("Voice");
cb_gater.set_label ("Gater");
cb_delay.set_label ("Delay");
cb_compress.set_label ("Compressor");
b_settings.set_label ("Settings");
cb_record.set_label ("Record");
l_mondrian_voices.update ();
d_min_max.set_text ("Min/Max");
mml_min.set_text ("Min");
mml_max.set_text("Max");
mmf_min.set_text (mmf_min.get_text());
mmf_max.set_text (mmf_max.get_text());
int lh = get_line_height ();
int y = update_bottom_line ();
y += lh;
arrow_button* scrl [] = {&ab_scroll_left, &ab_scroll_right, &ab_scroll_up, &ab_scroll_down};
int nscrls = 4;
int w = ab_scroll_left.extents.width;
int dw [] = {5, 7, 0, 0};
int x = (view.xmax - nscrls * w) / 2;
for (int i = 0; i < nscrls; ++i) {
arrow_button* ab = scrl[i];
ab->set_pos (x, y);
x = x + w + dw[i];
}
x += w;
cb_show_pitch_volume_board.set_pos (x, ab_scroll_down.extents.bottom - fnt.lift);
cb_show_pitch_volume_board.set_label ("i");
cb_show_pitch_volume_board.set_listener (&spvl);
x += w;
cb_show_pitch_volume_drones.set_pos (x + 1, ab_scroll_down.extents.bottom - fnt.lift);
cb_show_pitch_volume_drones.set_label ("j");
cb_show_pitch_volume_drones.set_listener (&spvl);
d_parameters.set_text ("Parameters");
lfs_attack_time.update ();
lfs_decay_time.update ();
lfs_num_voices.update ();
l_pitch_bend.update ();
sp_pitch_bend.update ();
cb_show_nearby_notes.set_label ("Show nearby notes");
l_waveform_display.update ();
l_octave_shift.update ();
ab_octave_up.update ();
ab_octave_down.update ();
sp_octave_shift_bpm.update ();
settings_scr.update_widgets ();
b_close.update ();
}
void ui_list::flash_gater () {
static color clr [2] = {color (1, 0, 0), color (0, 1, 0)};
float dg = aout.gatr [aout.samples_per_channel - 1];
if (fdr_gater.eval ()) {
cb_gater.blend_on_off_color (fdr_gater.alpha);
color& c = const_cast<color&> (cb_gater.clr);
c *= dg;
} else {
int gi = din0.dinfo.gater;
cb_gater.set_color (dg * clr [gi].r, dg * clr [gi].g, dg * clr[gi].b);
}
}
float ui_list::eval_fade (fader& fdr, checkbutton& cb) {
if (fdr.eval ()) cb.blend_on_off_color (fdr.alpha);
return fdr.amount;
}
void ui_list::dofft () {
if (crved && crved->num_curves && !fft0.folded ()) fft0.go (crved->curveinfo[0].curve);
}
void setup_fade (fader& fdr, int& target, int what) {
if (fdr.on == 0) {
target = what;
if (what) fdr.set (0, 1); else fdr.set (1, 0);
}
}
void voice__listener::changed (checkbutton& cb) {
int what = cb.is_on ();
setup_fade (uis.fdr_voice, din0.dinfo.voice, what);
}
void gater__listener::changed (checkbutton& cb) {
int what = cb.is_on ();
setup_fade (uis.fdr_gater, din0.dinfo.gater, what);
}
void delay__listener::changed (checkbutton& cb) {
int what = cb.is_on ();
setup_fade (uis.fdr_delay, din0.dinfo.delay, what);
}
void compress__listener::changed (checkbutton& cb) {
din0.dinfo.compress = cb.is_on ();
}
void settings__listener::clicked (button& b) {
uis.set_current (&uis.settings_scr);
}
void pitch_bend_listener::changed (field& f) {
PITCH_BEND_PER_PIXEL = f;
PITCH_BEND = PITCH_BEND_PER_PIXEL * 100;
}
void pitch_bend_listener::changed (checkbutton& cb) {
keybd2.show_nearby_notes = cb.state;
}
void waveform_display_listener::clicked (button& b) {
if (&b == &uis.ab_prev_wav) {
keybd2.waved.win.calc ();
keybd2.waved.load_curve (-1);
} else {
keybd2.waved.win.calc ();
keybd2.waved.load_curve (+1);
}
}
void parameters_listener::clicked (button& b) {
arrow_button& ab = dynamic_cast<arrow_button&> (b);
if (ab.direction == arrow_button::down) {
d_min_max_visible = uis.d_min_max.visible;
ab.set_direction (arrow_button::right);
uis.d_parameters.hide (widget::only_children);
} else {
uis.d_parameters.show ();
ab.set_direction (arrow_button::down);
if (d_min_max_visible == 0) uis.d_min_max.hide ();
}
ab.show ();
}
ui_list::~ui_list () {
widget* pw1[9] = {&d_parameters, &lfs_attack_time, &lfs_decay_time, &lfs_num_voices, &ab_parameters, &l_octave_shift, &ab_octave_up, &ab_octave_down, &sp_octave_shift_bpm};
widget_save ("d_parameters", pw1, 9);
widget* pw2[5] = {&d_min_max, &mml_min, &mml_max, &mmf_min, &mmf_max};
widget_save ("d_min_max", pw2, 5);
widget* wwd [] = {&l_waveform_display, &cd_waveform_display, &ab_prev_wav, &ab_next_wav};
widget_save ("d_waveform_display", wwd, 4);
widget* wpb [] = {&l_pitch_bend, &sp_pitch_bend, &cb_show_nearby_notes};
widget_save ("d_pitch_bend", wpb, 3);
label_field_slider<float>* lfs1 [2] = {&lfs_attack_time, &lfs_decay_time};
label_field_slider<int>* lfs2 [2] = {&lfs_num_voices};
ofstream fptr ((user_data_dir + "d_parameter_limits").c_str(), ios::out);
save_parameter_limits<float, label_field_slider<float> > (fptr, lfs1, 2);
save_parameter_limits<int, label_field_slider<int> > (fptr, lfs2, 1);
}
void ui::enter () {
warp_mouse (prev_mousex, prev_mousey);
if (!ed) scope.load_current_instrument ();
}
void ui::leave () {
if (hide_menu () == 0) {
prev_mousex = mousex;
prev_mousey = mousey;
}
if (!ed) scope.save_current_instrument ();
if (mouse_slider0.active) mouse_slider0.deactivate ();
if (TURN_OFF_UI) turn_on_ui ();
}
extern const float MIN_TIME;
void attack_val::operator() (const float& f) {
if (equals<float> (f, 0.0f)) ATTACK_TIME = MIN_TIME; else ATTACK_TIME = f;
}
void decay_val::operator() (const float& f) {
if (equals<float> (f, 0.0f)) DECAY_TIME = MIN_TIME; else DECAY_TIME = f;
}
void num_voices_val::operator() (const int& i) {
int j = i; if (i < 1) j = 1;
NOTE_VOLUME = 1.0f / j;
keybd2.calc_visual_params ();
}
template <typename T> min_max_clicked<T>::min_max_clicked (label_field_slider<T>& _lfs) : lfs (_lfs) {
lfs.set_button_listener (this);
}
template <typename T> void min_max_clicked<T>::clicked (button& b) {
// toggle
if (uis.d_min_max.visible) {
if (&b == ui_list::mm_last) uis.d_min_max.hide ();
} else {
uis.d_min_max.show ();
}
// label min/max
uis.d_min_max.set_text (lfs.get_text ());
// load min/max fields
T low, high;
lfs.get_limits (low, high);
uis.mmf_min.set_text (low);
uis.mmf_max.set_text (high);
// setup listeners
uis.mmf_min.change_lsnr = this;
uis.mmf_max.change_lsnr = this;
ui_list::mm_last = &b;
}
template <typename T> void min_max_clicked<T>::changed (field& f) {
stringstream ss;
ss << f.get_text ();
T l, h;
if (ss.str () != "") {
T t; ss >> t;
lfs.get_limits (l, h);
if (&f == &uis.mmf_min) {
lfs.set_limits (t, h);
} else {
lfs.set_limits (l, t);
}
}
lfs.get_limits (l, h);
uis.mmf_min.set_text (l);
uis.mmf_max.set_text (h);
}
void widget_load (const string& fname, widget** pw, int n) {
ifstream f ((user_data_dir + fname).c_str(), ios::in);
for (int i = 0; i < n; ++i) pw[i]->load (f);
}
void widget_save (const string& fname, widget** pw, int n) {
ofstream f ((user_data_dir + fname).c_str(), ios::out);
for (int i = 0; i < n; ++i) pw[i]->save (f);
}
void scroll_arrow_listener::clicked (button& b) {
if (&b == &uis.ab_scroll_left) {
din0.scroll (-din0.dinfo.scroll.dx, 0, 0);
cons << console::yellow << "You can press a to scroll left" << eol;
} else if (&b == &uis.ab_scroll_right) {
din0.scroll (din0.dinfo.scroll.dx, 0, 0);
cons << console::yellow << "You can press d to scroll right" << eol;
} else if (&b == &uis.ab_scroll_up) {
din0.scroll (0, -din0.dinfo.scroll.dy, 0);
cons << console::yellow << "You can press s to scroll up" << eol;
} else {
din0.scroll (0, din0.dinfo.scroll.dy, 0);
cons << console::yellow << "You can press w to scroll down" << eol;
}
}
void show_pitch_volume_listener::changed (checkbutton& cb) {
if (&cb == &uis.cb_show_pitch_volume_board)
din0.dinfo.show_pitch_volume.board = cb.state;
else
din0.dinfo.show_pitch_volume.drones = cb.state;
}
void fft::clicked (button& b) {
if (ab_fold.direction == arrow_button::down) {
ab_fold.set_direction (arrow_button::right);
l_title.hide (widget::only_children);
} else {
ab_fold.set_direction (arrow_button::down);
l_title.show ();
uis.dofft ();
}
ab_fold.show ();
ab_fold.update ();
}
int fft::folded () {
return (ab_fold.direction == arrow_button::right);
}
void ui_list::handle_plugin (widget* which, int what) {
enum {INSTALL = 1, REMOVE = 0};
ui* ueds [] = {
&din0.waved,
&din0.moded,
&din0.droneed,
&keybd2.waved,
&fractaliser_.ed
};
int num_editors = 5;
if (what == INSTALL) {
for (int i = 0; i < num_editors; ++i) widgets_of[ueds[i]].push_back (which);
} else {
for (int i = 0; i < num_editors; ++i) {
vector<widget*>& widgets = widgets_of [ueds[i]];
vector<widget*>::iterator iter = find (widgets.begin (), widgets.end(), which);
if (iter != widgets.end()) widgets.erase (iter);
}
}
main_menu.toggle ();
}
int ui_list::update_bottom_line () {
widget** winst = 0;
widget* wdin[] = {&cb_voice, &cb_gater, &cb_delay, &cb_compress, &b_settings, &main_menu.b_menu, &cb_record};
widget* wmon[] = {&l_mondrian_voices, &cb_delay, &cb_compress, &b_settings, &main_menu.b_menu, &cb_record};
widget* wcom[] = {&cb_delay, &cb_compress, &b_settings, &main_menu.b_menu, &cb_record};
instrument* inst = get_current_instrument ();
int n = 0;
if (inst == &din0) {
winst = wdin;
n = 7;
} else if (inst == &mondrian0) {
winst = wmon;
n = 6;
} else {
winst = wcom;
n = 5;
}
int dx = 35, w = 0;
for (int i = 0; i < n; ++i) w += winst[i]->extents.width;
w += n * dx;
int x = (view.xmax - w) / 2, y = (int)(0.25f * get_line_height() + 0.5);
for (int i = 0; i < n; ++i) {
widget& b = *winst[i];
const box<int>& e = b.extents;
b.set_extents (x, y, x + e.width, y + e.height);
b.set_pos (x, y);
x = e.right + dx;
}
return y;
}
void ui_list::remove (widget* w) {
vector<widget*>& current_widgets = widgets_of [current];
vector<widget*>::iterator end = current_widgets.end (), i = find (current_widgets.begin (), end, w);
if (i != end) current_widgets.erase (i);
}
int ui_list::escape_from_things () {
int ret = 1;
if (TURN_OFF_UI) turn_on_ui ();
else if (mkb_selector.exists ()) mkb_selector.abort ();
else if (mon_selector.exists ()) mon_selector.abort ();
else if (mouse_slider0.active) mouse_slider0.deactivate ();
else if (main_menu.filtered) main_menu.unfilter ();
else if (binaural_drones0.aborted ());
else if (main_menu.show) main_menu.toggle ();
else if (din0.moving_drones) din0.toggle_moving_drones ();
else if (din0.adding_drones) din0.toggle_adding_drones ();
else if (din0.create_mesh) { din0.create_mesh = mkb_selector.mesh = 0; cons << RED << "Stopped making drone mesh." << eol;}
else if (mondrian0.stop_doing_stuff ());
else ret = 0;
return ret;
}
int is_menu_visible () {
return uis.main_menu.show;
}
void abort_selectors () {
mon_selector.abort ();
mkb_selector.abort ();
}