Subversion Repositories DIN Is Noise

Rev

Rev 2300 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* ui.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 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 () {
2201 jag 149
 
964 jag 150
  glClear (GL_COLOR_BUFFER_BIT);
2201 jag 151
 
152
  // graphics drawing
964 jag 153
  glMatrixMode (GL_MODELVIEW);
154
  glLoadIdentity ();
2201 jag 155
 
156
    current->draw ();
157
 
158
  // ui drawing
964 jag 159
  glMatrixMode (GL_PROJECTION);
160
  glLoadIdentity ();
161
  glOrtho (0, view.xmax, 0, view.ymax, 0, 1);
2201 jag 162
 
163
    vector<widget*> widgets = widgets_of [current];
164
    for (vector<widget*>::size_type i = 0, j = widgets.size (); i < j; ++i) {
165
      widget* wi = widgets[i];
166
      if (wi->visible) wi->draw ();
167
    }
168
 
964 jag 169
}
170
 
171
// all screens
172
ui* SCREENS [] = {
1449 jag 173
  &keybd2,
174
  &mondrian0,
175
  &din0,
176
  &binaural_drones0,
964 jag 177
  &din0.waved,
1449 jag 178
  &din0.droneed,
179
  &drone_mod_ed,
964 jag 180
  &din0.moded,
181
  &din0.gated,
1449 jag 182
  &keybd2.waved,
183
  &keybd2.attacked,
184
  &keybd2.decayed,
185
  &keybd2.veled,
964 jag 186
  &delayed,
187
  &octed,
188
  &comed,
189
  &mc.ed,
1449 jag 190
  &mondrian0.waved,
191
  &mondrian0.attacked,
192
  &mondrian0.decayed,
193
  &binaural_drones0.waved,
194
  &ran_mod_ed,
195
  &ran_wh_ed,
196
  &pitch_vol_ed,
197
  &pomo_ed,
198
  &noiser::ed,
1475 jag 199
  &drone_pend_ed,
1883 jag 200
  &drone::modvt::ed,
1789 jag 201
  &fed,
964 jag 202
  &fractaliser_.ed,
203
  &warper_.ed,
204
  &spiraler_.scr.sin_ed,
205
  &spiraler_.scr.cos_ed,
206
  &spiraler_.scr.rad_ed,
207
  &rosemilker.scr.sin_ed,
208
  &rosemilker.scr.cos_ed,
209
  &circler_.scr.sin_ed,
210
  &circler_.scr.cos_ed,
211
  &circler_.scr.rad_ed,
212
  &sinemixer.sin_ed,
1188 jag 213
  &rosemilker.scr.rad_ed,
964 jag 214
 
215
};
216
 
1213 jag 217
void ui_list::show_hide_widgets (int sh) {
218
  for (ui** p = SCREENS; *p != 0; ++p) {
219
    ui* u = *p;
220
    vector<widget*>& vu = widgets_of [u];
221
    int j = vu.size ();
222
    if (j) {
1404 jag 223
      if (sh)
1213 jag 224
        for (int i = 0; i < j; ++i) vu[i]->show();
225
      else
226
        for (int i = 0; i < j; ++i) vu[i]->hide();
227
    }
228
  }
229
  curve_picker.hide ();
230
}
231
 
964 jag 232
void ui_list::add_widgets () {
233
 
1492 jag 234
  widget* wall [] = {&cons, &main_menu, &b_settings}; // appears on all screens
235
  for (ui** p = SCREENS; *p != 0; ++p) for (int i = 0; i < 3; ++i) widgets_of[*p].push_back (wall[i]);
236
 
1489 jag 237
  // add selectors to microtonal keyboard and mondrian
238
  mkb_selector.set_listener (&din0);
239
  mon_selector.set_listener (&mondrian0);
240
 
964 jag 241
  // add fft display on waveform editors
242
  ui* uwav [] = {&din0.waved, &keybd2.waved, &din0.droneed, &mondrian0.waved, &binaural_drones0.waved};
243
  for (int i = 0; i < 5; ++i) widgets_of[uwav[i]].push_back (&fft0);
244
 
245
  // add plugin browser to these editors
246
  ui* ueds [] = {
247
    &din0.waved,
248
    &din0.moded,
249
    &din0.droneed,
250
    &drone_mod_ed,
251
    &keybd2.waved,
252
    &fractaliser_.ed,
253
    &warper_.ed,
254
    &mondrian0.waved,
255
    &din0.gated,
256
    &binaural_drones0.waved,
1539 jag 257
    &ran_mod_ed,
258
    &pitch_vol_ed,
259
    &pomo_ed,
260
    &drone_pend_ed,
261
    &noiser::ed,
1640 jag 262
  };
263
 
1906 jag 264
  for (int i = 0; i < 15; ++i) widgets_of[ueds[i]].push_back (&plugin__browser);
964 jag 265
 
1535 jag 266
  // depth, bpm spinners to drone pendulum editor
1503 jag 267
  widget* dpeuw [] = {&dpeu.depth, &dpeu.bpm};
268
  widget_load ("d_dpeu", dpeuw, 2);
1567 jag 269
  dpeu.depth.set ("Depth", 1.0f, -MILLION, MILLION, &dpeul, 0);
270
  dpeu.bpm.set ("BPM", 1.0f, -MILLION, MILLION, &dpeul, 0);
1503 jag 271
  widgets_of [&drone_pend_ed].push_back (&dpeu.depth);
272
  widgets_of [&drone_pend_ed].push_back (&dpeu.bpm);
1508 jag 273
 
1489 jag 274
  // add widgets for curve editors only
1449 jag 275
  for (ui** p = SCREENS + NUM_INSTRUMENTS; *p != 0; ++p) {
964 jag 276
    ui* u = *p;
1449 jag 277
    vector<widget*>& wu = widgets_of [u];
278
    curve_editor* ce = dynamic_cast<curve_editor*>(u);
279
    wu.insert (wu.begin(), &ce->capturer);
280
    wu.insert (wu.begin(), &ce->pomo);
1535 jag 281
    wu.push_back (&curve_picker);
1449 jag 282
    ce->capturer.setup (ce);
283
    ce->pomo.setup (ce);
964 jag 284
  }
285
 
1149 jag 286
  // add scope to all instruments
1145 jag 287
  extern instrument* INSTRUMENT_PTR[];
1149 jag 288
  for (int i = 0; i < NUM_INSTRUMENTS; ++i) widgets_of[(ui *)INSTRUMENT_PTR[i]].push_back (&scope);
1145 jag 289
 
964 jag 290
  // no menu on author's note & settings screen
291
  widgets_of[&anote].push_back(&cons);
292
  widgets_of[&settings_scr].push_back (&cons);
293
 
294
  widget* wdin [] = {
1438 jag 295
    &ol_voice_is,
964 jag 296
    &cb_voice,
297
    &cb_gater,
298
    &cb_delay,
299
    &cb_compress,
300
    &ab_scroll_left,
301
    &ab_scroll_right,
302
    &ab_scroll_up,
303
    &ab_scroll_down,
304
    &cb_show_pitch_volume_board,
305
    &cb_show_pitch_volume_drones,
306
    &cb_record,
1672 jag 307
    &mkb_selector,
964 jag 308
 };
2201 jag 309
 for (int i = 0, j = 13; i < j; ++i) widgets_of [&din0].push_back (wdin[i]);
964 jag 310
 
311
  widget* wkeybd2 [] = {
312
    &cb_delay,
313
    &cb_compress,
1053 jag 314
    &sp_attack_time,
315
    &sp_decay_time,
1368 jag 316
    &sp_voices,
964 jag 317
    &sp_pitch_bend,
1368 jag 318
    &cb_show_nearby_notes,
964 jag 319
    &d_parameters,
320
    &ab_parameters,
321
    &l_waveform_display,
322
    &ab_prev_wav,
323
    &ab_next_wav,
324
    &cd_waveform_display,
325
    &l_octave_shift,
326
    &ab_octave_down,
327
    &ab_octave_up,
1368 jag 328
    &sp_octave_shift_bpm,
1519 jag 329
    &b_abort_octave_shift,
1422 jag 330
    &cb_record,
331
    &ol_trig_what
1449 jag 332
  };
333
 
1519 jag 334
  for (int i = 0, j = 20; i < j; ++i) widgets_of [&keybd2].push_back (wkeybd2[i]);
964 jag 335
 
336
  widget* wmondrian [] = {
337
    &l_mondrian_voices,
338
    &cb_delay,
339
    &cb_compress,
340
    &cb_record,
341
    &mon_selector,
342
  };
1449 jag 343
  for (int i = 0, j = 5; i < j; ++i) widgets_of [&mondrian0].push_back (wmondrian[i]);
344
  l_mondrian_voices.set_text ("Voices: ** / **");
964 jag 345
 
346
  widget* wsbd [] = {
347
    &cb_delay,
348
    &cb_compress,
349
    &cb_record,
350
  };
1489 jag 351
 
987 jag 352
  for (int i = 0, j = 3; i < j; ++i) widgets_of [&binaural_drones0].push_back (wsbd[i]);
964 jag 353
 
354
}
355
 
356
 
357
void ui_list::update_widgets (int wnow, int hnow, int wprev, int hprev) {
358
 
359
  main_menu.update ();
1447 jag 360
 
964 jag 361
  plugin__browser.update ();
362
 
2153 jag 363
  cb_gater.set_text ("Beater");
1120 jag 364
  cb_delay.set_text ("Delay");
365
  cb_compress.set_text ("Compressor");
366
  b_settings.set_text ("Settings");
367
  cb_record.set_text ("Record");
2300 jag 368
 
964 jag 369
  l_mondrian_voices.update ();
1053 jag 370
 
964 jag 371
  int lh = line_height;
372
  int y = update_bottom_line ();
373
  y += lh;
374
 
375
  arrow_button* scrl [] = {&ab_scroll_left, &ab_scroll_right, &ab_scroll_up, &ab_scroll_down};
376
  int nscrls = 4;
377
  int w = ab_scroll_left.extents.width;
378
  int dw [] = {5, 7, 0, 0};
379
  int x = (view.xmax - nscrls * w) / 2;
380
  for (int i = 0; i < nscrls; ++i) {
381
    arrow_button* ab = scrl[i];
382
    ab->set_pos (x, y);
383
    x = x + w + dw[i];
384
  }
385
 
386
  x += w;
387
  cb_show_pitch_volume_board.set_pos (x, ab_scroll_down.extents.bottom - fnt.lift);
1120 jag 388
  cb_show_pitch_volume_board.set_text ("i");
964 jag 389
 
390
  x += w;
391
  cb_show_pitch_volume_drones.set_pos (x + 1, ab_scroll_down.extents.bottom - fnt.lift);
1120 jag 392
  cb_show_pitch_volume_drones.set_text ("j");
964 jag 393
 
394
  d_parameters.set_text ("Parameters");
395
 
1053 jag 396
  sp_attack_time.update ();
397
  sp_decay_time.update ();
398
  sp_voices.update ();
964 jag 399
  sp_pitch_bend.update ();
1120 jag 400
  cb_show_nearby_notes.set_text ("Show nearby notes");
964 jag 401
 
402
  l_waveform_display.update ();
403
 
404
  l_octave_shift.update ();
405
  ab_octave_up.update ();
406
  ab_octave_down.update ();
407
  sp_octave_shift_bpm.update ();
408
 
409
  settings_scr.update_widgets ();
410
 
411
}
412
 
413
void ui_list::dofft () {
1966 jag 414
  if (!fft0.folded () && crved == current) fft0.go (crved->curveinfo[0].curve);
964 jag 415
}
416
 
417
void fade_button_listener::after_fade (fader& f) {
418
  cb->enabled = 1;
419
  f.afl = 0;
420
}
421
 
1439 jag 422
void voice_listener::changed (checkbutton& cb) {
423
  fade_button_listener::changed (cb);
1406 jag 424
  MENU.next_tab = MENUP.cb_mkb_voice;
425
  MENU.next_tab_instr = &din0;
1393 jag 426
}
427
 
964 jag 428
fade_button_listener::fade_button_listener (checkbutton* _cb, fader* _f, int* _t) {cb = _cb; f = _f; target = _t; lsnr = 0;}
429
 
430
void fade_button_listener::changed (checkbutton& cb) {
431
  if (f->on == 0) {
2077 jag 432
    int on = cb.state;
964 jag 433
    *target = on;
434
    if (on) f->set (0, 1); else f->set (1, 0);
435
    cb.enabled = 0;
436
    f->afl = this;
437
  }
438
}
439
 
440
void compress__listener::changed (checkbutton& cb) {
2077 jag 441
  din0.dinfo.compress = cb.state;
964 jag 442
}
443
 
444
void settings__listener::clicked (button& b) {
445
  uis.set_current (&uis.settings_scr);
446
}
447
 
448
void pitch_bend_listener::changed (field& f) {
2108 jag 449
  PITCH_BEND_PER_PIXEL = uis.sp_pitch_bend.value;
964 jag 450
  PITCH_BEND = PITCH_BEND_PER_PIXEL * 100;
451
}
452
 
453
void pitch_bend_listener::changed (checkbutton& cb) {
454
  keybd2.show_nearby_notes = cb.state;
455
}
456
 
457
void waveform_display_listener::clicked (button& b) {
1507 jag 458
  CRVED = &keybd2.waved;
964 jag 459
  if (&b == &uis.ab_prev_wav) {
1507 jag 460
    CRVED->win.calc ();
461
    CRVED->load_curve (-1);
964 jag 462
  } else {
1507 jag 463
    CRVED->win.calc ();
464
    CRVED->load_curve (+1);
964 jag 465
  }
466
}
467
 
468
void parameters_listener::clicked (button& b) {
469
  arrow_button& ab = dynamic_cast<arrow_button&> (b);
1015 jag 470
  if (ab.dir == arrow_button::down) {
471
    ab.set_dir (arrow_button::right);
964 jag 472
    uis.d_parameters.hide (widget::only_children);
473
  } else {
474
    uis.d_parameters.show ();
1015 jag 475
    ab.set_dir (arrow_button::down);
964 jag 476
  }
477
  ab.show ();
478
}
479
 
480
ui_list::~ui_list () {
481
 
482
  dlog << "--- destroying uis ---" << endl;
483
 
1519 jag 484
  DEFINE_PARAMETERS
485
  widget_save ("d_parameters", pw, npars);
964 jag 486
 
1503 jag 487
  widget* dpeuw [] = {&dpeu.depth, &dpeu.bpm};
488
  widget_save ("d_dpeu", dpeuw, 2);
489
 
964 jag 490
  dlog << "--- destroyed uis ---" << endl;
491
 
492
}
493
 
494
void ui::enter () {
2173 jag 495
  /*if (prev_mousex == -1 && prev_mousey == -1) {
2172 jag 496
    prev_mousex = view.midx;
497
    prev_mousey = view.midy;
2173 jag 498
  }*/
964 jag 499
  warp_mouse (prev_mousex, prev_mousey);
500
}
501
 
502
void ui::leave () {
2049 jag 503
  if (MENU.b_close.visible) MENU.b_close.call_listener ();
504
  if (NO_NEED_TO == hide_menu ()) {
964 jag 505
    prev_mousex = mousex;
506
    prev_mousey = mousey;
507
  }
508
  if (!ed) scope.save_current_instrument ();
1578 jag 509
  mouse_slider0.deactivate ();
964 jag 510
}
511
 
512
extern const float MIN_TIME;
513
 
1053 jag 514
void attack_val::changed (field& F) {
2108 jag 515
  float f = uis.sp_attack_time.value;
1507 jag 516
  if (equals (f, 0.0f)) ATTACK_TIME = MIN_TIME; else ATTACK_TIME = f;
964 jag 517
}
518
 
1053 jag 519
void decay_val::changed (field& F) {
2108 jag 520
  float f = uis.sp_decay_time.value;
1507 jag 521
  if (equals (f, 0.0f)) DECAY_TIME = MIN_TIME; else DECAY_TIME = f;
964 jag 522
}
523
 
1053 jag 524
void voices_val::changed (field& F) {
2108 jag 525
  int i = uis.sp_voices.value;
964 jag 526
  int j = i; if (i < 1) j = 1;
527
  NOTE_VOLUME = 1.0f / j;
528
  keybd2.calc_visual_params ();
529
}
530
 
531
void scroll_arrow_listener::clicked (button& b) {
532
  if (&b == &uis.ab_scroll_left) {
533
    din0.scroll (-din0.dinfo.scroll.dx, 0, 0);
534
  } else if (&b == &uis.ab_scroll_right) {
535
    din0.scroll (din0.dinfo.scroll.dx, 0, 0);
536
  } else if (&b == &uis.ab_scroll_up) {
537
    din0.scroll (0, -din0.dinfo.scroll.dy, 0);
538
  } else {
539
    din0.scroll (0, din0.dinfo.scroll.dy, 0);
540
  }
541
}
542
 
543
void show_pitch_volume_listener::changed (checkbutton& cb) {
544
  if (&cb == &uis.cb_show_pitch_volume_board)
545
    din0.dinfo.show_pitch_volume.board = cb.state;
546
  else
547
    din0.dinfo.show_pitch_volume.drones = cb.state;
548
}
549
 
550
void fft::clicked (button& b) {
1015 jag 551
  if (ab_fold.dir == arrow_button::down) {
552
    ab_fold.set_dir (arrow_button::right);
964 jag 553
    l_title.hide (widget::only_children);
554
    ab_fold.show ();
555
  } else {
1015 jag 556
    ab_fold.set_dir (arrow_button::down);
964 jag 557
    l_title.show ();
1966 jag 558
    fft0.go (uis.crved->curveinfo[0].curve);
964 jag 559
  }
560
}
561
 
562
int fft::folded () {
1015 jag 563
  return (ab_fold.dir == arrow_button::right);
964 jag 564
}
565
 
566
void ui_list::handle_plugin (widget* which, int what) {
567
  enum {INSTALL = 1, REMOVE = 0};
568
  ui* ueds [] = {
569
    &din0.waved,
570
    &din0.moded,
571
    &din0.droneed,
572
    &keybd2.waved,
573
    &fractaliser_.ed
574
  };
575
 
576
  int num_editors = 5;
577
  if (what == INSTALL) {
578
    for (int i = 0; i < num_editors; ++i) widgets_of[ueds[i]].push_back (which);
579
  } else {
580
    for (int i = 0; i < num_editors; ++i) {
581
      vector<widget*>& widgets = widgets_of [ueds[i]];
582
      vector<widget*>::iterator iter = find (widgets.begin (), widgets.end(), which);
583
      if (iter != widgets.end()) widgets.erase (iter);
584
    }
585
  }
586
  main_menu.toggle ();
587
}
588
 
589
int ui_list::update_bottom_line () {
590
  widget** winst = 0;
591
  widget* wdin[] = {&cb_voice, &cb_gater, &cb_delay, &cb_compress, &main_menu.b_menu, &b_settings, &cb_record};
592
  widget* wmon[] = {&l_mondrian_voices, &cb_delay, &cb_compress,  &main_menu.b_menu, &b_settings, &cb_record};
593
  widget* wcom[] = {&cb_delay, &cb_compress, &main_menu.b_menu, &b_settings, &cb_record};
594
  widget* wed [] = {&main_menu.b_menu, &b_settings};
595
  instrument* inst = get_current_instrument ();
596
  int n = 0;
597
  if (inst == &din0) {
598
    winst = wdin;
599
    n = 7;
600
  } else if (inst == &mondrian0) {
601
    winst = wmon;
602
    n = 6;
603
  } else if (inst == &binaural_drones0 || inst == &keybd2) {
604
    winst = wcom;
605
    n = 5;
606
  } else {
607
    winst = wed;
608
    n = 2;
609
  }
610
  int dx = 25, w = 0;
611
  for (int i = 0; i < n; ++i) w += winst[i]->extents.width;
612
  w += n * dx;
613
  int x = (view.xmax - w) / 2, y = 2; //(int)(0.25f * get_line_height() + 0.5);
614
  for (int i = 0; i < n; ++i) {
615
    widget& b = *winst[i];
616
    const box<int>& e = b.extents;
617
    b.set_extents (x, y, x + e.width, y + e.height);
618
    b.set_pos (x, y);
619
    x = e.right + dx;
620
  }
1438 jag 621
 
622
  ol_voice_is.set_pos (cb_voice.posx - 3 * ol_voice_is.left.extents.width - 2, cb_voice.posy);
964 jag 623
  return y;
624
}
625
 
1495 jag 626
int ui_list::remove (widget* w) {
627
  return erase (widgets_of [current], w);
628
}
1496 jag 629
 
1495 jag 630
void ui_list::add (ui* u, widget* w) { widgets_of [u].push_back (w); }
964 jag 631
 
632
int ui_list::escape_from_things () {
1674 jag 633
 
964 jag 634
  int ret = 1;
1495 jag 635
  if (UI_OFF) turn_on_ui ();
1963 jag 636
  else if (mouse_slider0.deactivate ()) ;
637
  else if (current->ed) ret = current->esc();
1489 jag 638
  else if (mkb_selector()) mkb_selector.abort ();
1112 jag 639
  else if (mon_selector()) mon_selector.abort ();
1552 jag 640
  else if (esc_octave_shift (get_current_instrument()));
641
  else if (main_menu.b_close.visible) main_menu.b_close.call_listener ();
1115 jag 642
  else if (main_menu.show) main_menu.toggle ();
1519 jag 643
  else if (current == &din0) {
1552 jag 644
    if (din0.gab.n) din0.gab.abort ();
645
    else if (din0.moving_drones) din0.toggle_moving_drones ();
1674 jag 646
    else if (din0.adding) {
647
      din0.adding = 0;
1677 jag 648
      cons << RED << "Stopped adding drones!" << eol;
1675 jag 649
      add (&din0, &mkb_selector);
1835 jag 650
    }
651
    else if (din0.stopwanding()) ;
652
    else if (din0.meshh.create) din0.stop_creating_mesh ();
1519 jag 653
    else if (din0.create_drone_pend) din0.stop_creating_drone_pendulum ();  
654
    else if (din0.finish_phrase_recording());
655
    else if (din0.dinfo.gravity.stop_editing ());
656
    else ret = 0;
657
  }
1255 jag 658
  else if (keybd2.turn_off_bend ());
1100 jag 659
  else if (mondrian0.stop_doing_stuff ());
1112 jag 660
  else if (binaural_drones0.aborted ());
1519 jag 661
  else if (current == &settings_scr) settings_scr.clicked (settings_scr.b_go_back);
964 jag 662
  else ret = 0;
663
  return ret;
664
}
665
 
666
int is_menu_visible () {
667
  return uis.main_menu.show;
668
}
669
 
670
void abort_selectors () {
671
  mon_selector.abort ();
672
  mkb_selector.abort ();
673
}
1422 jag 674
 
675
PICKED_OPTION (ui_list,trig_what_lis) {
676
  int& tw = keybd2.trig_what;
677
  tw = !tw;
678
  extern const char* keys_trig_what [];
679
  set_label (l, keys_trig_what, tw);
680
}
1438 jag 681
 
682
PICKED_OPTION (ui_list, ol_voice_is_lis) {
1439 jag 683
  din0.dinfo.voice_is_voice = !din0.dinfo.voice_is_voice;
2015 jag 684
  const char* viv = voice_is_lbls [din0.dinfo.voice_is_voice];
1438 jag 685
  extern ui_list uis;
1441 jag 686
  uis.cb_voice.set_text (viv);
687
  MENU.handle_voice_tab_items (viv);
1438 jag 688
}
1503 jag 689
 
690
VALUE_CHANGED (ui_list, dpeu_lis) {
691
  din0.update_drone_pendulums ();
692
}
1887 jag 693
 
694
void oscilloscope::show () {
695
  visible = MENU.cb_scope.state;
696
}