Subversion Repositories DIN Is Noise

Rev

Rev 2172 | Rev 2201 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* ui.cc
2097 jag 3
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
#include "ui_list.h"
9
#include "din.h"
10
#include "morse_code.h"
11
#include "console.h"
12
#include "curve_editor.h"
13
#include "tcl_interp.h"
14
#include "command.h"
15
#include "chrono.h"
16
#include "keyboard_keyboard.h"
17
#include "viewwin.h"
18
#include "authors_note.h"
19
#include "fft.h"
20
#include "main.h"
21
#include "curve_picker.h"
1130 jag 22
#include "capturer.h"
964 jag 23
#include "fractaliser.h"
24
#include "warper.h"
25
#include "mondrian.h"
26
#include "binaural_drones.h"
27
#include "spiraler.h"
28
#include "circler.h"
29
#include "rose_milker.h"
30
#include "sine_mixer.h"
31
#include <fstream>
32
#include <string>
1060 jag 33
#include "container.h"
2049 jag 34
#define NO_NEED_TO 0
964 jag 35
 
36
using namespace std;
37
 
38
extern string user_data_dir;
2134 jag 39
extern curve_editor waved, comed, octed, veled, drone_mod_ed, ran_mod_ed, ran_wh_ed, pitch_vol_ed, pomo_ed, delayed, drone_pend_ed;
40
extern font_editor fed;
964 jag 41
extern int mousex, mousey, mouseyy;
42
extern string INSTRUMENT;
43
extern oscilloscope scope;
44
extern int line_height;
45
extern sine_mixer sinemixer;
1438 jag 46
extern const char* voice_is_lbls[];
1449 jag 47
extern const int NUM_INSTRUMENTS;
964 jag 48
 
49
ui_list::ui_list () :
50
vlis (&cb_voice, &fdr_voice, &din0.dinfo.voice),
51
glis (&cb_gater, &fdr_gater, &din0.dinfo.gater),
52
dlis (&cb_delay, &fdr_delay, &din0.dinfo.delay)
53
{
54
  current = 0;
55
  prev = 0;
56
  crved = 0;
57
  esct = -1;
58
  rmb_clicked = 0;
1438 jag 59
  LISTEN (ol_voice_is, &vivl);
964 jag 60
}
61
 
62
void ui_list::set_current (ui* u) {
63
 
64
  if (current) {
65
    current->leave ();
1539 jag 66
    ui::over = prev = current;
964 jag 67
  }
68
 
69
  current = u;
70
  cons << YELLOW << "@ " << current->name << eol;
71
 
1561 jag 72
  if (u->ed)
1395 jag 73
    crved = dynamic_cast<curve_editor*>(u);
1561 jag 74
  else
75
    uis[0] = current;
964 jag 76
 
1128 jag 77
  current->enter ();
78
 
964 jag 79
}
80
 
1517 jag 81
void ui_list::load_editor (ui* ed) {
1529 jag 82
  main_menu.setup_tabs (ed);
1517 jag 83
  set_current (ed);
84
}
85
 
964 jag 86
void ui_list::bg () {
87
 
88
  current->calc_win_mouse ();
89
 
90
  for (vector<ui*>::size_type i = 1, j = uis.size(); i < j; ++i) uis[i]->bg (); // bg for instruments and editors
91
 
92
  // fade fx for voice, gater & delay
93
  eval_fade (fdr_voice, cb_voice);
94
  flash_gater (); // flashes in sync with gater value
95
  eval_fade (fdr_delay, cb_delay);
96
 
97
}
98
 
99
float ui_list::eval_fade (fader& fdr, checkbutton& cb) {
100
  if (fdr.eval ()) cb.blend_on_off_color (fdr.alpha);
101
  return fdr.amount;
102
}
103
 
104
void ui_list::flash_gater () {
105
 
106
  static color clr [2] = {color (1, 0, 0), color (0, 1, 0)};
107
  float dg = aout.gatr [aout.last_sample];
108
  if (fdr_gater.eval ()) {
109
    cb_gater.blend_on_off_color (fdr_gater.alpha);
110
    color& c = const_cast<color&> (cb_gater.clr);
111
    c *= dg;
112
  } else {
113
    int gi = din0.dinfo.gater;
114
    cb_gater.set_color (dg * clr [gi].r, dg * clr [gi].g, dg * clr[gi].b);
115
  }
116
 
117
}
118
 
119
int ui_list::is_widget_on_screen (widget* w, ui* scr) {
120
  vector<widget*>& widgets = widgets_of [scr];
121
  for (int i = 0, j = widgets.size (); i < j; ++i) if (w == widgets[i]) return 1;
122
  return 0;
123
}
124
 
125
 
126
int ui_list::set_editor (const string& name, int screen) {
127
  if (screen > 0) {
128
    ui* ei = 0;
129
    for (int i = 0, j = uis.size(); i < j; ++i) {
130
      if (uis[i]->name == name) {
131
        ei = uis[i];
132
        break;
133
      }
134
    }
135
    if (ei) {
136
      ed [screen - 2] = ei;
137
      return 1;
138
    } else {
139
      cmdlst.result = "bad editor name";
140
      return 0;
141
    }
142
  } else {
143
    cmdlst.result = "bad screen number (valid: 2 to 8)";
144
    return 0;
145
  }
146
}
147
 
148
void ui_list::draw () {
149
  glClear (GL_COLOR_BUFFER_BIT);
150
  glMatrixMode (GL_MODELVIEW);
151
  glLoadIdentity ();
152
  current->draw ();
153
  glMatrixMode (GL_PROJECTION);
154
  glLoadIdentity ();
155
  glOrtho (0, view.xmax, 0, view.ymax, 0, 1);
156
  vector<widget*> widgets = widgets_of [current];
157
  for (vector<widget*>::size_type i = 0, j = widgets.size (); i < j; ++i) {
158
    widget* wi = widgets[i];
159
    if (wi->visible) wi->draw ();
160
  }
161
}
162
 
163
// all screens
164
ui* SCREENS [] = {
1449 jag 165
  &keybd2,
166
  &mondrian0,
167
  &din0,
168
  &binaural_drones0,
964 jag 169
  &din0.waved,
1449 jag 170
  &din0.droneed,
171
  &drone_mod_ed,
964 jag 172
  &din0.moded,
173
  &din0.gated,
1449 jag 174
  &keybd2.waved,
175
  &keybd2.attacked,
176
  &keybd2.decayed,
177
  &keybd2.veled,
964 jag 178
  &delayed,
179
  &octed,
180
  &comed,
181
  &mc.ed,
1449 jag 182
  &mondrian0.waved,
183
  &mondrian0.attacked,
184
  &mondrian0.decayed,
185
  &binaural_drones0.waved,
186
  &ran_mod_ed,
187
  &ran_wh_ed,
188
  &pitch_vol_ed,
189
  &pomo_ed,
190
  &noiser::ed,
1475 jag 191
  &drone_pend_ed,
1883 jag 192
  &drone::modvt::ed,
1789 jag 193
  &fed,
964 jag 194
  &fractaliser_.ed,
195
  &warper_.ed,
196
  &spiraler_.scr.sin_ed,
197
  &spiraler_.scr.cos_ed,
198
  &spiraler_.scr.rad_ed,
199
  &rosemilker.scr.sin_ed,
200
  &rosemilker.scr.cos_ed,
201
  &circler_.scr.sin_ed,
202
  &circler_.scr.cos_ed,
203
  &circler_.scr.rad_ed,
204
  &sinemixer.sin_ed,
1188 jag 205
  &rosemilker.scr.rad_ed,
964 jag 206
 
207
};
208
 
1213 jag 209
void ui_list::show_hide_widgets (int sh) {
210
  for (ui** p = SCREENS; *p != 0; ++p) {
211
    ui* u = *p;
212
    vector<widget*>& vu = widgets_of [u];
213
    int j = vu.size ();
214
    if (j) {
1404 jag 215
      if (sh)
1213 jag 216
        for (int i = 0; i < j; ++i) vu[i]->show();
217
      else
218
        for (int i = 0; i < j; ++i) vu[i]->hide();
219
    }
220
  }
221
  curve_picker.hide ();
222
}
223
 
964 jag 224
void ui_list::add_widgets () {
225
 
1492 jag 226
  widget* wall [] = {&cons, &main_menu, &b_settings}; // appears on all screens
227
  for (ui** p = SCREENS; *p != 0; ++p) for (int i = 0; i < 3; ++i) widgets_of[*p].push_back (wall[i]);
228
 
1489 jag 229
  // add selectors to microtonal keyboard and mondrian
230
  mkb_selector.set_listener (&din0);
231
  mon_selector.set_listener (&mondrian0);
232
 
964 jag 233
  // add fft display on waveform editors
234
  ui* uwav [] = {&din0.waved, &keybd2.waved, &din0.droneed, &mondrian0.waved, &binaural_drones0.waved};
235
  for (int i = 0; i < 5; ++i) widgets_of[uwav[i]].push_back (&fft0);
236
 
237
  // add plugin browser to these editors
238
  ui* ueds [] = {
239
    &din0.waved,
240
    &din0.moded,
241
    &din0.droneed,
242
    &drone_mod_ed,
243
    &keybd2.waved,
244
    &fractaliser_.ed,
245
    &warper_.ed,
246
    &mondrian0.waved,
247
    &din0.gated,
248
    &binaural_drones0.waved,
1539 jag 249
    &ran_mod_ed,
250
    &pitch_vol_ed,
251
    &pomo_ed,
252
    &drone_pend_ed,
253
    &noiser::ed,
1640 jag 254
  };
255
 
1906 jag 256
  for (int i = 0; i < 15; ++i) widgets_of[ueds[i]].push_back (&plugin__browser);
964 jag 257
 
1535 jag 258
  // depth, bpm spinners to drone pendulum editor
1503 jag 259
  widget* dpeuw [] = {&dpeu.depth, &dpeu.bpm};
260
  widget_load ("d_dpeu", dpeuw, 2);
1567 jag 261
  dpeu.depth.set ("Depth", 1.0f, -MILLION, MILLION, &dpeul, 0);
262
  dpeu.bpm.set ("BPM", 1.0f, -MILLION, MILLION, &dpeul, 0);
1503 jag 263
  widgets_of [&drone_pend_ed].push_back (&dpeu.depth);
264
  widgets_of [&drone_pend_ed].push_back (&dpeu.bpm);
1508 jag 265
 
1489 jag 266
  // add widgets for curve editors only
1449 jag 267
  for (ui** p = SCREENS + NUM_INSTRUMENTS; *p != 0; ++p) {
964 jag 268
    ui* u = *p;
1449 jag 269
    vector<widget*>& wu = widgets_of [u];
270
    curve_editor* ce = dynamic_cast<curve_editor*>(u);
271
    wu.insert (wu.begin(), &ce->capturer);
272
    wu.insert (wu.begin(), &ce->pomo);
1535 jag 273
    wu.push_back (&curve_picker);
1449 jag 274
    ce->capturer.setup (ce);
275
    ce->pomo.setup (ce);
964 jag 276
  }
277
 
1149 jag 278
  // add scope to all instruments
1145 jag 279
  extern instrument* INSTRUMENT_PTR[];
1149 jag 280
  for (int i = 0; i < NUM_INSTRUMENTS; ++i) widgets_of[(ui *)INSTRUMENT_PTR[i]].push_back (&scope);
1145 jag 281
 
964 jag 282
  // no menu on author's note & settings screen
283
  widgets_of[&anote].push_back(&cons);
284
  widgets_of[&settings_scr].push_back (&cons);
285
 
286
  widget* wdin [] = {
1438 jag 287
    &ol_voice_is,
964 jag 288
    &cb_voice,
289
    &cb_gater,
290
    &cb_delay,
291
    &cb_compress,
292
    &ab_scroll_left,
293
    &ab_scroll_right,
294
    &ab_scroll_up,
295
    &ab_scroll_down,
296
    &cb_show_pitch_volume_board,
297
    &cb_show_pitch_volume_drones,
298
    &cb_record,
299
    &din0.dinfo.gravity,
1672 jag 300
    &mkb_selector,
964 jag 301
 };
1695 jag 302
 for (int i = 0, j = 14; i < j; ++i) widgets_of [&din0].push_back (wdin[i]);
964 jag 303
 
304
  widget* wkeybd2 [] = {
305
    &cb_delay,
306
    &cb_compress,
1053 jag 307
    &sp_attack_time,
308
    &sp_decay_time,
1368 jag 309
    &sp_voices,
964 jag 310
    &sp_pitch_bend,
1368 jag 311
    &cb_show_nearby_notes,
964 jag 312
    &d_parameters,
313
    &ab_parameters,
314
    &l_waveform_display,
315
    &ab_prev_wav,
316
    &ab_next_wav,
317
    &cd_waveform_display,
318
    &l_octave_shift,
319
    &ab_octave_down,
320
    &ab_octave_up,
1368 jag 321
    &sp_octave_shift_bpm,
1519 jag 322
    &b_abort_octave_shift,
1422 jag 323
    &cb_record,
324
    &ol_trig_what
1449 jag 325
  };
326
 
1519 jag 327
  for (int i = 0, j = 20; i < j; ++i) widgets_of [&keybd2].push_back (wkeybd2[i]);
964 jag 328
 
329
  widget* wmondrian [] = {
330
    &l_mondrian_voices,
331
    &cb_delay,
332
    &cb_compress,
333
    &cb_record,
334
    &mon_selector,
335
  };
1449 jag 336
  for (int i = 0, j = 5; i < j; ++i) widgets_of [&mondrian0].push_back (wmondrian[i]);
337
  l_mondrian_voices.set_text ("Voices: ** / **");
964 jag 338
 
339
  widget* wsbd [] = {
340
    &cb_delay,
341
    &cb_compress,
342
    &cb_record,
343
  };
1489 jag 344
 
987 jag 345
  for (int i = 0, j = 3; i < j; ++i) widgets_of [&binaural_drones0].push_back (wsbd[i]);
964 jag 346
 
347
}
348
 
349
 
350
void ui_list::update_widgets (int wnow, int hnow, int wprev, int hprev) {
351
 
352
  main_menu.update ();
1447 jag 353
 
964 jag 354
  plugin__browser.update ();
355
 
2153 jag 356
  cb_gater.set_text ("Beater");
1120 jag 357
  cb_delay.set_text ("Delay");
358
  cb_compress.set_text ("Compressor");
359
  b_settings.set_text ("Settings");
360
  cb_record.set_text ("Record");
964 jag 361
  l_mondrian_voices.update ();
1053 jag 362
 
964 jag 363
  int lh = line_height;
364
  int y = update_bottom_line ();
365
  y += lh;
366
 
367
  arrow_button* scrl [] = {&ab_scroll_left, &ab_scroll_right, &ab_scroll_up, &ab_scroll_down};
368
  int nscrls = 4;
369
  int w = ab_scroll_left.extents.width;
370
  int dw [] = {5, 7, 0, 0};
371
  int x = (view.xmax - nscrls * w) / 2;
372
  for (int i = 0; i < nscrls; ++i) {
373
    arrow_button* ab = scrl[i];
374
    ab->set_pos (x, y);
375
    x = x + w + dw[i];
376
  }
377
 
378
  x += w;
379
  cb_show_pitch_volume_board.set_pos (x, ab_scroll_down.extents.bottom - fnt.lift);
1120 jag 380
  cb_show_pitch_volume_board.set_text ("i");
964 jag 381
 
382
  x += w;
383
  cb_show_pitch_volume_drones.set_pos (x + 1, ab_scroll_down.extents.bottom - fnt.lift);
1120 jag 384
  cb_show_pitch_volume_drones.set_text ("j");
964 jag 385
 
386
  d_parameters.set_text ("Parameters");
387
 
1053 jag 388
  sp_attack_time.update ();
389
  sp_decay_time.update ();
390
  sp_voices.update ();
964 jag 391
  sp_pitch_bend.update ();
1120 jag 392
  cb_show_nearby_notes.set_text ("Show nearby notes");
964 jag 393
 
394
  l_waveform_display.update ();
395
 
396
  l_octave_shift.update ();
397
  ab_octave_up.update ();
398
  ab_octave_down.update ();
399
  sp_octave_shift_bpm.update ();
400
 
401
  settings_scr.update_widgets ();
402
 
403
}
404
 
405
void ui_list::dofft () {
1966 jag 406
  if (!fft0.folded () && crved == current) fft0.go (crved->curveinfo[0].curve);
964 jag 407
}
408
 
409
void fade_button_listener::after_fade (fader& f) {
410
  cb->enabled = 1;
411
  f.afl = 0;
412
}
413
 
1439 jag 414
void voice_listener::changed (checkbutton& cb) {
415
  fade_button_listener::changed (cb);
1406 jag 416
  MENU.next_tab = MENUP.cb_mkb_voice;
417
  MENU.next_tab_instr = &din0;
1393 jag 418
}
419
 
964 jag 420
fade_button_listener::fade_button_listener (checkbutton* _cb, fader* _f, int* _t) {cb = _cb; f = _f; target = _t; lsnr = 0;}
421
 
422
void fade_button_listener::changed (checkbutton& cb) {
423
  if (f->on == 0) {
2077 jag 424
    int on = cb.state;
964 jag 425
    *target = on;
426
    if (on) f->set (0, 1); else f->set (1, 0);
427
    cb.enabled = 0;
428
    f->afl = this;
429
  }
430
}
431
 
432
void compress__listener::changed (checkbutton& cb) {
2077 jag 433
  din0.dinfo.compress = cb.state;
964 jag 434
}
435
 
436
void settings__listener::clicked (button& b) {
437
  uis.set_current (&uis.settings_scr);
438
}
439
 
440
void pitch_bend_listener::changed (field& f) {
2108 jag 441
  PITCH_BEND_PER_PIXEL = uis.sp_pitch_bend.value;
964 jag 442
  PITCH_BEND = PITCH_BEND_PER_PIXEL * 100;
443
}
444
 
445
void pitch_bend_listener::changed (checkbutton& cb) {
446
  keybd2.show_nearby_notes = cb.state;
447
}
448
 
449
void waveform_display_listener::clicked (button& b) {
1507 jag 450
  CRVED = &keybd2.waved;
964 jag 451
  if (&b == &uis.ab_prev_wav) {
1507 jag 452
    CRVED->win.calc ();
453
    CRVED->load_curve (-1);
964 jag 454
  } else {
1507 jag 455
    CRVED->win.calc ();
456
    CRVED->load_curve (+1);
964 jag 457
  }
458
}
459
 
460
void parameters_listener::clicked (button& b) {
461
  arrow_button& ab = dynamic_cast<arrow_button&> (b);
1015 jag 462
  if (ab.dir == arrow_button::down) {
463
    ab.set_dir (arrow_button::right);
964 jag 464
    uis.d_parameters.hide (widget::only_children);
465
  } else {
466
    uis.d_parameters.show ();
1015 jag 467
    ab.set_dir (arrow_button::down);
964 jag 468
  }
469
  ab.show ();
470
}
471
 
472
ui_list::~ui_list () {
473
 
474
  dlog << "--- destroying uis ---" << endl;
475
 
1519 jag 476
  DEFINE_PARAMETERS
477
  widget_save ("d_parameters", pw, npars);
964 jag 478
 
1503 jag 479
  widget* dpeuw [] = {&dpeu.depth, &dpeu.bpm};
480
  widget_save ("d_dpeu", dpeuw, 2);
481
 
964 jag 482
  dlog << "--- destroyed uis ---" << endl;
483
 
484
}
485
 
486
void ui::enter () {
2173 jag 487
  /*if (prev_mousex == -1 && prev_mousey == -1) {
2172 jag 488
    prev_mousex = view.midx;
489
    prev_mousey = view.midy;
2173 jag 490
  }*/
964 jag 491
  warp_mouse (prev_mousex, prev_mousey);
492
}
493
 
494
void ui::leave () {
2049 jag 495
  if (MENU.b_close.visible) MENU.b_close.call_listener ();
496
  if (NO_NEED_TO == hide_menu ()) {
964 jag 497
    prev_mousex = mousex;
498
    prev_mousey = mousey;
499
  }
500
  if (!ed) scope.save_current_instrument ();
1578 jag 501
  mouse_slider0.deactivate ();
964 jag 502
}
503
 
504
extern const float MIN_TIME;
505
 
1053 jag 506
void attack_val::changed (field& F) {
2108 jag 507
  float f = uis.sp_attack_time.value;
1507 jag 508
  if (equals (f, 0.0f)) ATTACK_TIME = MIN_TIME; else ATTACK_TIME = f;
964 jag 509
}
510
 
1053 jag 511
void decay_val::changed (field& F) {
2108 jag 512
  float f = uis.sp_decay_time.value;
1507 jag 513
  if (equals (f, 0.0f)) DECAY_TIME = MIN_TIME; else DECAY_TIME = f;
964 jag 514
}
515
 
1053 jag 516
void voices_val::changed (field& F) {
2108 jag 517
  int i = uis.sp_voices.value;
964 jag 518
  int j = i; if (i < 1) j = 1;
519
  NOTE_VOLUME = 1.0f / j;
520
  keybd2.calc_visual_params ();
521
}
522
 
523
void scroll_arrow_listener::clicked (button& b) {
524
  if (&b == &uis.ab_scroll_left) {
525
    din0.scroll (-din0.dinfo.scroll.dx, 0, 0);
526
  } else if (&b == &uis.ab_scroll_right) {
527
    din0.scroll (din0.dinfo.scroll.dx, 0, 0);
528
  } else if (&b == &uis.ab_scroll_up) {
529
    din0.scroll (0, -din0.dinfo.scroll.dy, 0);
530
  } else {
531
    din0.scroll (0, din0.dinfo.scroll.dy, 0);
532
  }
533
}
534
 
535
void show_pitch_volume_listener::changed (checkbutton& cb) {
536
  if (&cb == &uis.cb_show_pitch_volume_board)
537
    din0.dinfo.show_pitch_volume.board = cb.state;
538
  else
539
    din0.dinfo.show_pitch_volume.drones = cb.state;
540
}
541
 
542
void fft::clicked (button& b) {
1015 jag 543
  if (ab_fold.dir == arrow_button::down) {
544
    ab_fold.set_dir (arrow_button::right);
964 jag 545
    l_title.hide (widget::only_children);
546
    ab_fold.show ();
547
  } else {
1015 jag 548
    ab_fold.set_dir (arrow_button::down);
964 jag 549
    l_title.show ();
1966 jag 550
    fft0.go (uis.crved->curveinfo[0].curve);
964 jag 551
  }
552
}
553
 
554
int fft::folded () {
1015 jag 555
  return (ab_fold.dir == arrow_button::right);
964 jag 556
}
557
 
558
void ui_list::handle_plugin (widget* which, int what) {
559
  enum {INSTALL = 1, REMOVE = 0};
560
  ui* ueds [] = {
561
    &din0.waved,
562
    &din0.moded,
563
    &din0.droneed,
564
    &keybd2.waved,
565
    &fractaliser_.ed
566
  };
567
 
568
  int num_editors = 5;
569
  if (what == INSTALL) {
570
    for (int i = 0; i < num_editors; ++i) widgets_of[ueds[i]].push_back (which);
571
  } else {
572
    for (int i = 0; i < num_editors; ++i) {
573
      vector<widget*>& widgets = widgets_of [ueds[i]];
574
      vector<widget*>::iterator iter = find (widgets.begin (), widgets.end(), which);
575
      if (iter != widgets.end()) widgets.erase (iter);
576
    }
577
  }
578
  main_menu.toggle ();
579
}
580
 
581
int ui_list::update_bottom_line () {
582
  widget** winst = 0;
583
  widget* wdin[] = {&cb_voice, &cb_gater, &cb_delay, &cb_compress, &main_menu.b_menu, &b_settings, &cb_record};
584
  widget* wmon[] = {&l_mondrian_voices, &cb_delay, &cb_compress,  &main_menu.b_menu, &b_settings, &cb_record};
585
  widget* wcom[] = {&cb_delay, &cb_compress, &main_menu.b_menu, &b_settings, &cb_record};
586
  widget* wed [] = {&main_menu.b_menu, &b_settings};
587
  instrument* inst = get_current_instrument ();
588
  int n = 0;
589
  if (inst == &din0) {
590
    winst = wdin;
591
    n = 7;
592
  } else if (inst == &mondrian0) {
593
    winst = wmon;
594
    n = 6;
595
  } else if (inst == &binaural_drones0 || inst == &keybd2) {
596
    winst = wcom;
597
    n = 5;
598
  } else {
599
    winst = wed;
600
    n = 2;
601
  }
602
  int dx = 25, w = 0;
603
  for (int i = 0; i < n; ++i) w += winst[i]->extents.width;
604
  w += n * dx;
605
  int x = (view.xmax - w) / 2, y = 2; //(int)(0.25f * get_line_height() + 0.5);
606
  for (int i = 0; i < n; ++i) {
607
    widget& b = *winst[i];
608
    const box<int>& e = b.extents;
609
    b.set_extents (x, y, x + e.width, y + e.height);
610
    b.set_pos (x, y);
611
    x = e.right + dx;
612
  }
1438 jag 613
 
614
  ol_voice_is.set_pos (cb_voice.posx - 3 * ol_voice_is.left.extents.width - 2, cb_voice.posy);
964 jag 615
  return y;
616
}
617
 
1495 jag 618
int ui_list::remove (widget* w) {
619
  return erase (widgets_of [current], w);
620
}
1496 jag 621
 
1495 jag 622
void ui_list::add (ui* u, widget* w) { widgets_of [u].push_back (w); }
964 jag 623
 
624
int ui_list::escape_from_things () {
1674 jag 625
 
964 jag 626
  int ret = 1;
1495 jag 627
  if (UI_OFF) turn_on_ui ();
1963 jag 628
  else if (mouse_slider0.deactivate ()) ;
629
  else if (current->ed) ret = current->esc();
1489 jag 630
  else if (mkb_selector()) mkb_selector.abort ();
1112 jag 631
  else if (mon_selector()) mon_selector.abort ();
1552 jag 632
  else if (esc_octave_shift (get_current_instrument()));
633
  else if (main_menu.b_close.visible) main_menu.b_close.call_listener ();
1115 jag 634
  else if (main_menu.show) main_menu.toggle ();
1519 jag 635
  else if (current == &din0) {
1552 jag 636
    if (din0.gab.n) din0.gab.abort ();
637
    else if (din0.moving_drones) din0.toggle_moving_drones ();
1674 jag 638
    else if (din0.adding) {
639
      din0.adding = 0;
1677 jag 640
      cons << RED << "Stopped adding drones!" << eol;
1675 jag 641
      add (&din0, &mkb_selector);
1835 jag 642
    }
643
    else if (din0.stopwanding()) ;
644
    else if (din0.meshh.create) din0.stop_creating_mesh ();
1519 jag 645
    else if (din0.create_drone_pend) din0.stop_creating_drone_pendulum ();  
646
    else if (din0.finish_phrase_recording());
647
    else if (din0.dinfo.gravity.stop_editing ());
648
    else ret = 0;
649
  }
1255 jag 650
  else if (keybd2.turn_off_bend ());
1100 jag 651
  else if (mondrian0.stop_doing_stuff ());
1112 jag 652
  else if (binaural_drones0.aborted ());
1519 jag 653
  else if (current == &settings_scr) settings_scr.clicked (settings_scr.b_go_back);
964 jag 654
  else ret = 0;
655
  return ret;
656
}
657
 
658
int is_menu_visible () {
659
  return uis.main_menu.show;
660
}
661
 
662
void abort_selectors () {
663
  mon_selector.abort ();
664
  mkb_selector.abort ();
665
}
1422 jag 666
 
667
PICKED_OPTION (ui_list,trig_what_lis) {
668
  int& tw = keybd2.trig_what;
669
  tw = !tw;
670
  extern const char* keys_trig_what [];
671
  set_label (l, keys_trig_what, tw);
672
}
1438 jag 673
 
674
PICKED_OPTION (ui_list, ol_voice_is_lis) {
1439 jag 675
  din0.dinfo.voice_is_voice = !din0.dinfo.voice_is_voice;
2015 jag 676
  const char* viv = voice_is_lbls [din0.dinfo.voice_is_voice];
1438 jag 677
  extern ui_list uis;
1441 jag 678
  uis.cb_voice.set_text (viv);
679
  MENU.handle_voice_tab_items (viv);
1438 jag 680
}
1503 jag 681
 
682
VALUE_CHANGED (ui_list, dpeu_lis) {
683
  din0.update_drone_pendulums ();
684
}
1887 jag 685
 
686
void oscilloscope::show () {
687
  visible = MENU.cb_scope.state;
688
}