Fix callback signature, unfortunately scroll events wont work in grab
[terminatorX.git] / src / tX_vttgui.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2016  Alexander K├Ânig
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  
18     File: tX_vttgui.cc
19  
20     Description: This implements the gtk+ GUI for the virtual turntable
21                  class implemented in tX_vtt.cc. This code is not in tX_vtt.cc
22                  for mainly to keep the GUI code divided from the audio-rendering
23                  code and as gtk+ callback to C++ method call wrapper.
24 */    
25
26 #include <gdk/gdk.h>
27 #include <gtk/gtk.h>
28 #include "tX_vttgui.h"
29 #include "tX_vtt.h"
30 #include "tX_widget.h"
31 #include "tX_mastergui.h"
32 #include "tX_loaddlg.h"
33 #include "tX_prelis.h"
34 #include "tX_pbutton.h"
35 #include "tX_global.h"
36 #include "tX_extdial.h"
37 #include "tX_panel.h"
38 #include "tX_ladspa.h"
39 #include "tX_ladspa_class.h"
40 #include "tX_engine.h"
41 #include "tX_ui_interface.h"
42 #include "tX_ui_support.h"
43 #include "tX_dialog.h"
44
45 #ifdef USE_DIAL
46 #include "tX_dial.h"
47 #endif
48
49 #include "tX_flash.h"
50 #include <stdio.h>
51 #include <ctype.h>
52 #include <string.h>
53
54 #define WID_DYN TRUE, TRUE, 0
55 #define WID_FIX FALSE, FALSE, 0
56
57 static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect);
58
59 void nicer_filename(char *dest, char *source)
60 {
61                 char *fn;
62                 char temp[PATH_MAX];
63                 
64                 fn=strrchr(source, '/');
65                 if (fn) fn++;
66                 else fn=source;
67                 
68                 strcpy (temp, fn);
69                 
70                 fn=strrchr(temp, '.');
71                 if (fn) *fn=0;
72                 
73                 if (strlen(temp) > (unsigned int) globals.filename_length) {
74                         temp[globals.filename_length-3]='.';
75                         temp[globals.filename_length-2]='.';
76                         temp[globals.filename_length-1]='.';
77                         temp[globals.filename_length]=0;
78                 } 
79                 strcpy (dest, temp);
80 }
81
82 void name_changed(GtkWidget *wid, vtt_class *vtt)
83 {
84         vtt->set_name((char *) gtk_entry_get_text(GTK_ENTRY(wid)));
85 }
86
87 void volume_changed(GtkWidget *wid, vtt_class *vtt)
88 {
89         vtt->sp_volume.receive_gui_value(2.0-gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
90 }
91
92 void pan_changed(GtkWidget *wid, vtt_class *vtt)
93 {
94       vtt->sp_pan.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
95 }
96
97 void pitch_changed(GtkWidget *wid, vtt_class *vtt)
98 {
99         vtt->sp_pitch.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
100 }
101
102 GCallback chooser_prelis(GtkWidget *w)
103 {
104         GtkFileChooser *fc=GTK_FILE_CHOOSER(gtk_widget_get_toplevel(w));
105         char *filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
106         
107         if (filename) {
108                 prelis_start(filename);
109                 g_free(filename);
110         } else {
111                 prelis_stop();
112         }
113         return NULL;
114 }
115
116 char global_filename_buffer[PATH_MAX];
117
118 void load_part(char *newfile, vtt_class *vtt)
119 {
120         tX_audio_error ret=TX_AUDIO_SUCCESS;
121
122         ld_create_loaddlg(TX_LOADDLG_MODE_SINGLE, 1);
123         ld_set_filename(newfile);
124
125         ret = vtt->load_file(newfile);
126         
127         ld_destroy();
128         if (ret) {
129                 switch(ret) {
130                         case TX_AUDIO_ERR_ALLOC:
131                         tx_note("Failed to load audiofile - there's not enough memory available.", true);
132                         break;
133                         case TX_AUDIO_ERR_PIPE_READ:
134                         tx_note("An error occured on reading from the piped process - probably the file format of the audiofile is not supported by this configuration - please check terminatorX' INSTALL file on howto configure terminatorX for files of this format.", true);
135                         break;
136                         case TX_AUDIO_ERR_SOX:
137                         tx_note("Failed to run sox - to load the given audiofile please ensure that sox is installed correctly.", true);
138                         break;
139                         case TX_AUDIO_ERR_MPG123:
140                         tx_note("Failed to run mpg123 - to load the given mp3 file please ensure that mpg123 (or mpg321) is installed correctly.", true);
141                         break;
142                         case TX_AUDIO_ERR_WAV_NOTFOUND:
143                         tx_note("Couldn't acces the audiofile - file not found.", true);
144                         break;
145                         case TX_AUDIO_ERR_NOT_16BIT:
146                         tx_note("The wav file doesn't use 16 bit wide samples - please compile terminatorX with libaudiofile support to enable loading of such files.", true);
147                         break;
148                         case TX_AUDIO_ERR_NOT_MONO:
149                         tx_note("The wav file is not mono - please compile terminatorX with libaudiofile support to enable loading of such files.", true);
150                         break;
151                         case TX_AUDIO_ERR_WAV_READ:
152                         tx_note("The wav file seems to be corrupt.", true);
153                         break;
154                         case TX_AUDIO_ERR_NOT_SUPPORTED:
155                         tx_note("The file format of the audiofile is not supported - please check terminatorX' INSTALL file on howto configure terminatorX for files of this format.", true);
156                         break;
157                         case TX_AUDIO_ERR_MAD_OPEN:
158                         tx_note("Failed to open this mp3 file - please ensure that the file exists and is readable.", true);
159                         break;  
160                         case TX_AUDIO_ERR_MAD_STAT:
161                         tx_note("Failed to 'stat' this mp3 file - please ensure that the file exists and is readable.", true);
162                         break;
163                         case TX_AUDIO_ERR_MAD_DECODE:
164                         tx_note("Failed to decode the mp3 stream - file is corrupt.", true);
165                         break;
166                         case TX_AUDIO_ERR_MAD_MMAP:
167                         tx_note("Failed to map the audiofile to memory - please ensure the file is readable.", true);
168                         break;
169                         case TX_AUDIO_ERR_MAD_MUNMAP:
170                         tx_note("Failed to unmap audiofile.", true);
171                         break;
172                         case TX_AUDIO_ERR_VORBIS_OPEN:
173                         tx_note("Failed to open ogg file - please ensure the file is an ogg stream and that it is readable.", true);
174                         break;                  
175                         case TX_AUDIO_ERR_VORBIS_NODATA:
176                         tx_note("The vorbis codec failed to decode any data - possibly this ogg stream is corrupt.", true);
177                         break;
178                         case TX_AUDIO_ERR_AF_OPEN:
179                         tx_note("Failed to open this file with libaudiofile - please check terminatorX' INSTALL file on howto configure terminatorX for files of this format.",true);
180                         break;
181                         case TX_AUDIO_ERR_AF_NODATA:
182                         tx_note("libaudiofile failed to decode any data - possilby the audiofile is corrupt.", true);
183                         break;
184                         default:                                        
185                         tx_note("An unknown error occured - if this bug is reproducible please report it, thanks.", true);      
186                 }
187         } else {
188                 nicer_filename(global_filename_buffer, newfile);
189         gtk_button_set_label(GTK_BUTTON(vtt->gui.file), global_filename_buffer);
190         }       
191 }
192
193 void drop_file(GtkWidget *widget, GdkDragContext *context,
194                 gint x, gint y, GtkSelectionData *selection_data,
195                 guint info, guint time, vtt_class *vtt)
196 {
197         char filename[PATH_MAX];
198         char *fn;
199         
200         strncpy(filename, (char *) gtk_selection_data_get_data(selection_data), (size_t) gtk_selection_data_get_length(selection_data));
201         gtk_drag_finish(context, TRUE, FALSE, time);
202         filename[gtk_selection_data_get_length(selection_data)]=0;
203
204         fn = strchr (filename, '\r');
205         *fn=0;  
206         
207         char *realfn=NULL;
208         char *host=NULL;
209         
210         realfn=g_filename_from_uri(filename, &host, NULL);
211         if (realfn) {
212                 fn=realfn;
213         } else {
214                 fn = strchr (filename, ':');
215                 if (fn) fn++; else fn=(char *) gtk_selection_data_get_data(selection_data);
216         }
217
218         load_part(fn, vtt);
219
220         if (realfn) g_free(realfn);
221         if (host) g_free(host);
222 }
223
224 GCallback load_file(GtkWidget *wid, vtt_class *vtt)
225 {
226         const char *extensions[]={ "mp3", "wav", "ogg", "flac", "iff", "aiff", "voc", "au", "spx", NULL };
227         char name_buf[512];
228         sprintf(name_buf, "Select Audio File for %s", vtt->name);
229         
230         GtkWidget * dialog = gtk_file_chooser_dialog_new (name_buf,
231                 GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN, 
232                 "_Cancel", GTK_RESPONSE_CANCEL, 
233                 "_Open", GTK_RESPONSE_ACCEPT, NULL);
234
235                 
236         GtkFileFilter *filter=gtk_file_filter_new();
237         for (int i=0; extensions[i]!=NULL; i++) {
238                 char buffer[32]="*.";
239                 
240                 gtk_file_filter_add_pattern(filter, strcat(buffer, extensions[i]));
241                 for (unsigned int c=0; c<strlen(buffer); c++) {
242                         buffer[c]=toupper(buffer[c]);
243                 }
244                 gtk_file_filter_add_pattern(filter, buffer);
245         }
246         
247         gtk_file_filter_set_name(filter, "Audio Files");
248         gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); 
249
250         filter=gtk_file_filter_new();
251         gtk_file_filter_add_pattern (filter, "*");
252         gtk_file_filter_set_name(filter, "All Files");
253         gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); 
254         
255         if (vtt->audiofile) {
256                 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), vtt->filename); 
257         } else if (strlen(globals.current_path)>0 ) {
258                 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), globals.current_path);
259         }
260         
261         g_signal_connect (G_OBJECT(dialog), "selection-changed", G_CALLBACK(chooser_prelis), vtt);      
262         
263         if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
264         char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
265                 gtk_widget_hide(dialog);
266                 tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
267                 load_part(filename, vtt);
268                 strcpy(globals.current_path, filename);
269                 tX_cursor::reset_cursor();              
270         }       
271         
272         prelis_stop();
273         gtk_widget_destroy(dialog);     
274
275         return NULL;
276 }
277
278 void delete_vtt(GtkWidget *wid, vtt_class *vtt)
279 {
280         if (audioon) tx_note("Sorry, you'll have to stop playback first.");
281         else delete(vtt);
282                 
283         mg_update_status();
284 }
285
286 void edit_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
287 {
288         char command[2*PATH_MAX];
289
290         if (vtt->samples_in_buffer == 0) {
291                 tx_note("No audiofile loaded - so there's nothing to edit.", true);
292         } else if (strlen(globals.file_editor)>0) {
293                 sprintf(command, "%s \"%s\" &", globals.file_editor, vtt->filename);
294                 if (system(command) < 0) {
295                         tx_note("Error running the soundfile editor.");
296                 }
297         } else {
298                 tx_note("No soundfile editor has been configured - to do so enter the soundfile editor of your choice in the options dialog.", true);
299         }
300 }
301
302 void reload_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
303 {
304         char reload_buffer[PATH_MAX];
305         
306         while (gtk_events_pending()) gtk_main_iteration();
307         
308         if (vtt->samples_in_buffer > 0) {
309                 strcpy(reload_buffer, vtt->filename);
310                 load_part(reload_buffer, vtt);
311         }
312         else tx_note("No audiofile loaded - so there's nothing to reload.", true);
313 }
314
315 void clone_vtt(GtkWidget *wid, vtt_class *vtt)
316 {
317         vtt->stop();
318 }
319
320 void trigger_vtt(GtkWidget *wid, vtt_class *vtt)
321 {
322         vtt->sp_trigger.receive_gui_value((float) 1.0);
323 }
324
325 void stop_vtt(GtkWidget *wid, vtt_class *vtt)
326 {
327         vtt->sp_trigger.receive_gui_value((float) 0.0);
328 }
329
330 void autotrigger_toggled(GtkWidget *wid, vtt_class *vtt)
331 {
332         vtt->set_autotrigger(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid)));
333 }
334
335 void loop_toggled(GtkWidget *wid, vtt_class *vtt)
336 {
337         vtt->sp_loop.receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid)));
338 }
339
340 void lp_enabled(GtkWidget *wid, vtt_class *vtt)
341 {
342         vtt->sp_lp_enable.receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid)));
343 }
344
345 void lp_gain_changed(GtkWidget *wid, vtt_class *vtt)
346 {
347         vtt->sp_lp_gain.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
348 }
349
350 void lp_reso_changed(GtkWidget *wid, vtt_class *vtt)
351 {
352         vtt->sp_lp_reso.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
353 }
354
355 void lp_freq_changed(GtkWidget *wid, vtt_class *vtt)
356 {
357         vtt->sp_lp_freq.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
358 }
359
360 void ec_enabled(GtkWidget *wid, vtt_class *vtt)
361 {
362         vtt->sp_ec_enable.receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid)));
363 }
364
365 #ifdef USE_ALSA_MIDI_IN
366 void midi_mapping_clicked(GtkWidget *wid, vtt_class *vtt)
367 {
368         tX_engine::get_instance()->get_midi()->configure_bindings(vtt);
369 }
370 #endif
371
372 void ec_length_changed(GtkWidget *wid, vtt_class *vtt)
373 {
374         vtt->sp_ec_length.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
375 }
376
377 void ec_feedback_changed(GtkWidget *wid, vtt_class *vtt)
378 {
379         vtt->sp_ec_feedback.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
380 }
381
382 void ec_pan_changed(GtkWidget *wid, vtt_class *vtt)
383 {
384         vtt->sp_ec_pan.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
385 }
386
387 void ec_volume_changed(GtkWidget *wid, vtt_class *vtt)
388 {
389         vtt->sp_ec_volume.receive_gui_value(gtk_adjustment_get_value(GTK_ADJUSTMENT(wid)));
390 }
391
392 void master_setup(GtkWidget *wid, vtt_class *vtt)
393 {
394         vtt->set_sync_master(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid)));
395 }
396
397 void client_setup(GtkWidget *wid, vtt_class *vtt)
398 {
399         int client;
400         
401         client=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_client));   
402         vtt->sp_sync_client.receive_gui_value(client);
403 }
404
405 void client_setup_number(GtkWidget *wid, vtt_class *vtt)
406 {
407         int cycles;
408         
409         cycles=(int) gtk_adjustment_get_value(GTK_ADJUSTMENT(vtt->gui.cycles));
410         
411         vtt->sp_sync_cycles.receive_gui_value(cycles);
412 }
413
414 void mute_volume(GtkWidget *widget, vtt_class *vtt)
415 {
416         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
417                 vtt->set_mix_mute(1);
418         } else {
419                 vtt->set_mix_mute(0);
420         }
421 }
422
423 void solo_vtt(GtkWidget *widget, vtt_class *vtt)
424 {
425         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
426                 vtt->set_mix_solo(1);
427         } else {
428                 vtt->set_mix_solo(0);
429         }
430 }      
431
432 void minimize_control_panel(GtkWidget *wid, vtt_class *vtt)
433 {
434         vtt->hide_control(true);
435 }
436
437 void unminimize_control_panel(GtkWidget *wid, vtt_class *vtt)
438 {
439         vtt->hide_control(false);
440 }
441
442 void minimize_audio_panel(GtkWidget *wid, vtt_class *vtt)
443 {
444         vtt->hide_audio(true);
445 }
446
447 void unminimize_audio_panel(GtkWidget *wid, vtt_class *vtt)
448 {
449         vtt->hide_audio(false);
450 }
451
452 void vg_xcontrol_dis(GtkWidget *wid, vtt_class *vtt)
453 {
454         vtt->set_x_input_parameter(NULL);
455 }
456
457 void vg_ycontrol_dis(GtkWidget *wid, vtt_class *vtt)
458 {
459         vtt->set_y_input_parameter(NULL);
460 }
461
462 void vg_xcontrol_set(GtkWidget *wid, tX_seqpar *sp)
463 {
464         vtt_class *vtt=(vtt_class *) sp->vtt;
465         vtt->set_x_input_parameter(sp);
466 }
467
468 void vg_ycontrol_set(GtkWidget *wid, tX_seqpar *sp)
469 {
470         vtt_class *vtt=(vtt_class *) sp->vtt;
471         vtt->set_y_input_parameter(sp);
472 }
473
474 gboolean vg_delete_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
475         vtt->gui.adjust_dialog=NULL;
476         return FALSE;
477 }
478
479 void vg_do_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
480         int master_cycles=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "master_cycles")));
481         int cycles=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "cycles")));
482         bool create_event=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "create_event")));
483
484         vtt->adjust_to_master_pitch(master_cycles, cycles, create_event);
485         
486         gtk_widget_destroy(vtt->gui.adjust_dialog);
487 }
488
489 void vg_cancel_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
490         gtk_widget_destroy(vtt->gui.adjust_dialog);
491 }
492
493 void vg_adjust_pitch_vtt(GtkWidget *wid, vtt_class *vtt) {
494         if (vtt->gui.adjust_dialog) {
495                 gtk_widget_destroy(vtt->gui.adjust_dialog);
496                 return;
497         }
498         
499         if (!vtt_class::sync_master) {
500                 tx_note("No master turntable to adjust pitch to selected.", true);
501                 return;
502         }
503         
504         if (vtt==vtt_class::sync_master) {
505                 tx_note("This is the master turntable - cannot adjust a turntable to itself.", true);
506                 return;
507         }
508         
509         vtt->gui.adjust_dialog=create_tx_adjust();
510         tX_set_icon(vtt->gui.adjust_dialog);
511         gtk_widget_show(vtt->gui.adjust_dialog);
512         
513         GtkWidget *ok_button=lookup_widget(vtt->gui.adjust_dialog, "ok");
514         GtkWidget *cancel_button=lookup_widget(vtt->gui.adjust_dialog, "cancel");
515         
516         g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(vg_do_pitch_adjust), vtt);
517         g_signal_connect(G_OBJECT(vtt->gui.adjust_dialog), "destroy", G_CALLBACK(vg_delete_pitch_adjust), vtt);
518         g_signal_connect(G_OBJECT(cancel_button), "clicked", G_CALLBACK(vg_cancel_pitch_adjust), vtt);
519 }
520
521 static gint vg_mouse_mapping_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt) {
522         if (vtt->gui.mouse_mapping_menu) {
523                 gtk_widget_destroy(vtt->gui.mouse_mapping_menu);
524                 vtt->gui.mouse_mapping_menu=NULL;
525         }
526         /* gtk+ seems to cleanup the submenus automatically */
527         
528         vtt->gui.mouse_mapping_menu=gtk_menu_new();
529         GtkWidget *x_item;
530         GtkWidget *y_item;
531         
532         x_item=gtk_menu_item_new_with_label("X-axis (Left <-> Right)");
533         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu), x_item);
534         gtk_widget_show(x_item);
535
536         y_item=gtk_menu_item_new_with_label("Y-axis (Up <-> Down)");
537         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu), y_item);
538         gtk_widget_show(y_item);
539         
540         vtt->gui.mouse_mapping_menu_x=gtk_menu_new();
541         vtt->gui.mouse_mapping_menu_y=gtk_menu_new();
542         
543         GtkWidget *item;
544         GtkWidget *item_to_activate=NULL;
545         
546         /* Filling the X menu */
547         item = gtk_check_menu_item_new_with_label("Disable");
548         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_x), item);
549         gtk_widget_show(item);
550         g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_xcontrol_dis), vtt);
551         if (vtt->x_par==NULL) item_to_activate=item;
552
553         list <tX_seqpar *> :: iterator sp;
554
555         for (sp=tX_seqpar::all->begin(); sp!=tX_seqpar::all->end(); sp++) {
556                 if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt) {
557                         item=gtk_check_menu_item_new_with_label((*sp)->get_name());
558                         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_x), item);
559                         gtk_widget_show(item);
560                         g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_xcontrol_set), (void*) (*sp));
561                         
562                         if (vtt->x_par==(*sp)) item_to_activate=item;
563                 }
564         }
565
566         if (item_to_activate) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_to_activate), TRUE);
567         
568         /* Filling the Y menu */
569         item_to_activate=NULL;
570         
571         item = gtk_check_menu_item_new_with_label("Disable");
572         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_y), item);
573         gtk_widget_show(item);
574         g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_ycontrol_dis), vtt);
575         if (vtt->y_par==NULL) item_to_activate=item;
576
577         for (sp=tX_seqpar::all->begin(); sp!=tX_seqpar::all->end(); sp++) {
578                 if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt) {
579                         item=gtk_check_menu_item_new_with_label((*sp)->get_name());
580                         gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_y), item);
581                         gtk_widget_show(item);
582                         g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_ycontrol_set), (void*) (*sp));
583                         
584                         if (vtt->y_par==(*sp)) item_to_activate=item;
585                 }
586         }
587
588         if (item_to_activate) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_to_activate), TRUE);
589         
590         gtk_menu_item_set_submenu(GTK_MENU_ITEM(x_item), vtt->gui.mouse_mapping_menu_x);
591         gtk_menu_item_set_submenu(GTK_MENU_ITEM(y_item), vtt->gui.mouse_mapping_menu_y);
592         gtk_menu_popup (GTK_MENU(vtt->gui.mouse_mapping_menu), NULL, NULL, NULL, NULL, 0, 0);
593         
594         g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
595         
596         return TRUE;
597 }
598
599 static gint vg_file_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt) {
600         if (vtt->gui.file_menu==NULL) {
601                 GtkWidget *item;
602                 
603                 vtt->gui.file_menu=gtk_menu_new();
604                 item=gtk_menu_item_new_with_label("Load audio file");
605                 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
606                 gtk_widget_show(item);
607                 
608                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(load_file), vtt);
609                 
610                 item=gtk_menu_item_new_with_label("Edit audio file");
611                 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
612                 gtk_widget_show(item);
613
614                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_vtt_buffer), vtt);
615
616                 item=gtk_menu_item_new_with_label("Reload current audio file");
617                 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
618                 gtk_widget_show(item);
619
620                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(reload_vtt_buffer), vtt);
621         }
622         
623         gtk_menu_popup(GTK_MENU(vtt->gui.file_menu), NULL, NULL, NULL, NULL, 0,0);
624         /* gtk+ is really waiting for this.. */
625         g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
626         
627         return TRUE;
628 }
629
630 void vg_adjust_zoom(GtkWidget *wid, vtt_class *vtt) {   
631         GtkAdjustment *adj=gtk_range_get_adjustment(GTK_RANGE(vtt->gui.zoom));
632         gtk_tx_set_zoom(GTK_TX(vtt->gui.display), gtk_adjustment_get_value(adj)/100.0);
633 }
634
635 static gint fx_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt)
636 {
637         vtt_gui *g=&vtt->gui;
638
639         LADSPA_Class::set_current_vtt(vtt);
640
641         if (g->ladspa_menu) gtk_widget_destroy(GTK_WIDGET(g->ladspa_menu));
642         g->ladspa_menu=LADSPA_Class::get_ladspa_menu();
643         gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
644
645         /* gtk+ is really waiting for this.. */
646         g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
647         
648         return TRUE;
649 }
650
651 static gint stereo_fx_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt)
652 {
653         vtt_gui *g=&vtt->gui;
654
655         LADSPA_Class::set_current_vtt(vtt);
656
657         if (g->ladspa_menu) gtk_widget_destroy(GTK_WIDGET(g->ladspa_menu));
658         g->ladspa_menu=LADSPA_Class::get_stereo_ladspa_menu();
659         gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
660
661         /* gtk+ is really waiting for this.. */
662         g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
663         
664         return TRUE;
665 }
666
667 #define TOOLTIP_LENGTH 2048
668
669 void gui_set_name(vtt_class *vtt, char *newname)
670 {
671         char bold_name[128];
672         strcpy(bold_name, "<b>");
673         strcat(bold_name, newname);
674         strcat(bold_name, "</b>");
675         
676         gtk_label_set_markup(GTK_LABEL(vtt->gui.audio_label), bold_name);
677         gtk_label_set_markup(GTK_LABEL(vtt->gui.control_label), bold_name);
678         gtk_entry_set_text(GTK_ENTRY(vtt->gui.name), newname);
679         char tooltip[2048];
680         
681         if (vtt->gui.audio_minimized_panel_bar_button!=NULL) {
682                 gtk_label_set_text(GTK_LABEL(vtt->gui.audio_minimized_panel_bar_label), newname);
683                 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" audio panel.", newname);
684                 gui_set_tooltip(vtt->gui.audio_minimized_panel_bar_button, tooltip);
685         }
686
687         if (vtt->gui.control_minimized_panel_bar_button!=NULL) {
688                 gtk_label_set_text(GTK_LABEL(vtt->gui.control_minimized_panel_bar_label), newname);
689                 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" control panel.", newname);
690                 gui_set_tooltip(vtt->gui.control_minimized_panel_bar_button, tooltip);
691         }
692 }
693
694 f_prec gui_get_audio_x_zoom(vtt_class *vtt) {
695         return gtk_tx_get_zoom(GTK_TX(vtt->gui.display));
696 }
697
698 int vttgui_zoom_depth=0;
699
700 void gui_set_audio_x_zoom(vtt_class *vtt, f_prec value) {
701         if (vttgui_zoom_depth==0) {
702                 vttgui_zoom_depth=1;
703                 gtk_range_set_value(GTK_RANGE(vtt->gui.zoom), value*100.0);
704                 vttgui_zoom_depth=0;
705         } else {
706                 gtk_tx_set_zoom(GTK_TX(vtt->gui.display), value);
707         }
708 }
709
710 void gui_scroll_callback(GtkWidget *tx, GdkEventScroll *eventScroll, gpointer userdata) {
711         vtt_class *vtt = (vtt_class *) userdata;
712         f_prec zoom = gui_get_audio_x_zoom(vtt);
713
714         if ((eventScroll->direction == GDK_SCROLL_UP) || (eventScroll->direction == GDK_SCROLL_RIGHT)) {
715                 zoom += 0.1;
716         } else if ((eventScroll->direction == GDK_SCROLL_DOWN) || (eventScroll->direction == GDK_SCROLL_LEFT)) {
717                 zoom -= 0.1;
718         }
719         gui_set_audio_x_zoom(vtt, zoom);
720 }
721
722
723 #define connect_entry(wid, func); g_signal_connect(G_OBJECT(g->wid), "activate", G_CALLBACK(func), (void *) vtt);
724 #define connect_adj(wid, func); g_signal_connect(G_OBJECT(g->wid), "value_changed", G_CALLBACK(func), (void *) vtt);
725 #define connect_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "clicked", G_CALLBACK(func), (void *) vtt);
726 #define connect_range(wid, func); g_signal_connect(G_OBJECT(gtk_range_get_adjustment(GTK_RANGE(g->wid))), "value_changed", G_CALLBACK(func), (void *) vtt);
727 #define connect_scale_format(wid, func); g_signal_connect(G_OBJECT(g->wid), "format-value", G_CALLBACK(func), (void *) vtt);
728 #define connect_press_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "button_press_event", G_CALLBACK(func), (void *) vtt);
729 #define connect_rel_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "released", G_CALLBACK(func), (void *) vtt);
730
731 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel);
732
733 gchar dnd_uri[128];
734
735 void gui_connect_signals(vtt_class *vtt)
736 {
737         vtt_gui *g=&vtt->gui;
738         strncpy(dnd_uri, "text/uri-list", 128);
739
740         connect_entry(name, name_changed);
741         connect_adj(volume, volume_changed);
742         connect_adj(pitch, pitch_changed);
743         connect_adj(pan, pan_changed);
744         connect_press_button(file, vg_file_button_pressed);
745         
746         connect_button(del, delete_vtt);
747         connect_button(trigger, trigger_vtt);
748         connect_button(stop, stop_vtt);
749         connect_button(autotrigger, autotrigger_toggled);
750         connect_button(loop, loop_toggled);
751         connect_button(sync_master, master_setup);
752         connect_button(sync_client, client_setup);
753         connect_button(adjust_button, vg_adjust_pitch_vtt);
754         connect_adj(cycles, client_setup_number);
755         connect_press_button(fx_button, fx_button_pressed);
756         connect_press_button(stereo_fx_button, stereo_fx_button_pressed);
757         
758         connect_button(lp_enable, lp_enabled);
759         connect_adj(lp_gain, lp_gain_changed);
760         connect_adj(lp_reso, lp_reso_changed);
761         connect_adj(lp_freq, lp_freq_changed);
762         
763         connect_button(ec_enable, ec_enabled);
764 #ifdef USE_ALSA_MIDI_IN 
765         connect_button(midi_mapping, midi_mapping_clicked);
766 #endif  
767         connect_adj(ec_length, ec_length_changed);
768         connect_adj(ec_feedback, ec_feedback_changed);
769         connect_adj(ec_pan, ec_pan_changed);
770         connect_adj(ec_volume, ec_volume_changed);      
771         connect_range(zoom, vg_adjust_zoom);
772         //connect_scale_format(zoom, vg_format_zoom);
773         connect_press_button(mouse_mapping, vg_mouse_mapping_pressed);
774         connect_button(control_minimize, minimize_control_panel);
775         connect_button(audio_minimize, minimize_audio_panel);
776
777         gtk_widget_add_events(GTK_WIDGET(g->display), GDK_SCROLL_MASK);
778   g_signal_connect(G_OBJECT(g->display), "scroll-event", G_CALLBACK(gui_scroll_callback), vtt);
779
780         static GtkTargetEntry drop_types [] = {
781                 { dnd_uri, 0, 0}
782         };
783         static gint n_drop_types = sizeof (drop_types) / sizeof(drop_types[0]);
784         
785         gtk_drag_dest_set (GTK_WIDGET (g->file), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
786                         drop_types, n_drop_types,
787                         GDK_ACTION_COPY);
788                                                 
789         g_signal_connect (G_OBJECT (g->file), "drag_data_received",
790                         G_CALLBACK(drop_file), (void *) vtt);
791
792         gtk_drag_dest_set (GTK_WIDGET (g->display), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
793                         drop_types, n_drop_types,
794                         GDK_ACTION_COPY);
795                                                 
796         g_signal_connect (G_OBJECT (g->display), "drag_data_received",
797                         G_CALLBACK(drop_file), (void *) vtt);
798         
799 }
800
801 void build_vtt_gui(vtt_class *vtt)
802 {
803         GtkWidget *tempbox;
804         GtkWidget *tempbox2;
805         GtkWidget *tempbox3;
806         GtkWidget *dummy;
807         char nice_name[256];
808         
809         vtt_gui *g;
810         
811         g=&vtt->gui;
812         vtt->have_gui=1;
813         g->par_menu=NULL;
814         g->ladspa_menu=NULL;
815
816         /* Building Audio Box */
817         g->audio_box=gtk_box_new(GTK_ORIENTATION_VERTICAL,2);
818         gtk_widget_show(g->audio_box);
819         
820         tempbox2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,2);
821         gtk_widget_show(tempbox2);
822         gtk_box_pack_start(GTK_BOX(g->audio_box), tempbox2, WID_FIX);
823         
824         tempbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,2);
825         gtk_box_set_homogeneous(GTK_BOX(tempbox), TRUE);
826         gtk_widget_show(tempbox);
827         gtk_box_pack_start(GTK_BOX(tempbox2), tempbox, WID_DYN);
828
829         GtkWidget *pixmap;
830         g->audio_minimize=gtk_button_new();
831         pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
832         gtk_container_add (GTK_CONTAINER (g->audio_minimize), pixmap);  
833         gtk_box_pack_end(GTK_BOX(tempbox2), g->audio_minimize, WID_FIX);
834         gtk_widget_show(pixmap);
835         gtk_widget_show(g->audio_minimize);
836
837
838         g->audio_label=gtk_label_new(vtt->name);
839         gtk_widget_set_halign(g->audio_label, GTK_ALIGN_START);
840         gtk_widget_set_margin_start(g->audio_label, 10);
841         gtk_widget_show(g->audio_label);
842         gtk_box_pack_start(GTK_BOX(tempbox), g->audio_label, WID_DYN);
843
844         nicer_filename(nice_name, vtt->filename);
845         g->file = gtk_button_new_with_label(nice_name);
846         gtk_widget_show(g->file);
847         gui_set_tooltip(g->file, "Click to Load/Edit/Reload a sample for this turntable. To load you can also drag a file and drop it over this button or the sound data display below.");
848         gtk_box_pack_start(GTK_BOX(tempbox), g->file, WID_DYN);
849
850         g->mouse_mapping=gtk_button_new_with_label("Mouse");
851         gtk_widget_show(g->mouse_mapping);
852         gui_set_tooltip(g->mouse_mapping, "Determines what parameters should be affected on mouse motion in mouse grab mode.");
853         gtk_box_pack_start(GTK_BOX(tempbox2), g->mouse_mapping, WID_FIX);
854
855 #ifdef USE_ALSA_MIDI_IN
856         g->midi_mapping=gtk_button_new_with_label("MIDI");
857         gtk_widget_show(g->midi_mapping);
858         gui_set_tooltip(g->midi_mapping, "Determines what parameters should be bound to what MIDI events.");
859         gtk_box_pack_start(GTK_BOX(tempbox2), g->midi_mapping, WID_FIX);
860         
861         if (!tX_engine::get_instance()->get_midi()->get_is_open()) {
862                 gtk_widget_set_sensitive(g->midi_mapping, FALSE);
863         }
864 #endif
865
866         tempbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
867
868         g->display=gtk_tx_new(vtt->buffer, vtt->samples_in_buffer);
869         gtk_box_pack_start(GTK_BOX(tempbox), g->display, WID_DYN);
870         gtk_widget_show(g->display);    
871         
872         g->zoom=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, 0,99.0,1.0);
873         gtk_range_set_inverted(GTK_RANGE(g->zoom), TRUE);
874         gtk_scale_set_draw_value(GTK_SCALE(g->zoom), TRUE);
875         gtk_scale_set_digits(GTK_SCALE(g->zoom), 0);
876         gtk_scale_set_value_pos(GTK_SCALE(g->zoom), GTK_POS_BOTTOM);
877         gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(g->zoom)), 0);
878         
879         gui_set_tooltip(g->zoom, "Set the zoom-level for the audio data display.");
880         gtk_box_pack_start(GTK_BOX(tempbox), g->zoom, WID_FIX);
881         gtk_widget_show(g->zoom);
882         
883         gtk_box_pack_start(GTK_BOX(g->audio_box), tempbox, WID_DYN);
884         gtk_widget_show(tempbox);
885         
886         /* Building Control Box */
887         
888         g->control_box=gtk_box_new(GTK_ORIENTATION_VERTICAL,2);
889         gtk_widget_show(g->control_box);
890
891         tempbox2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
892         gtk_widget_show(tempbox2);
893         gtk_box_pack_start(GTK_BOX(g->control_box), tempbox2, WID_FIX);
894
895         g->control_label=gtk_label_new(vtt->name);
896         gtk_widget_show(g->control_label);
897         gtk_box_pack_start(GTK_BOX(tempbox2), g->control_label, WID_DYN);
898
899         g->control_minimize=gtk_button_new();
900         pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
901         gtk_container_add (GTK_CONTAINER (g->control_minimize), pixmap);        
902         gtk_box_pack_end(GTK_BOX(tempbox2), g->control_minimize, WID_FIX);
903         gtk_widget_show(pixmap);
904         gtk_widget_show(g->control_minimize);
905
906         g->scrolled_win=gtk_scrolled_window_new (NULL, NULL);
907         gtk_container_set_border_width (GTK_CONTAINER (g->scrolled_win), 0);
908         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (g->scrolled_win),
909                                     GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
910         gtk_widget_show(g->scrolled_win);
911         gtk_box_pack_start(GTK_BOX(g->control_box), g->scrolled_win, WID_DYN);
912                                     
913         g->control_subbox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
914 #if GTK_CHECK_VERSION(3,8,0)
915         gtk_container_add(GTK_CONTAINER(g->scrolled_win), g->control_subbox);
916 #else
917         gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g->scrolled_win), g->control_subbox);
918 #endif
919         gtk_widget_show(g->control_subbox);
920                    
921
922         /* Main panel */
923         
924         tX_panel *p=new tX_panel("Main", g->control_subbox);
925         g->main_panel=p;
926                         
927         g->name = gtk_entry_new();
928         gtk_entry_set_max_length(GTK_ENTRY(g->name), 256);
929         gtk_entry_set_text(GTK_ENTRY(g->name), vtt->name);
930         gtk_entry_set_width_chars(GTK_ENTRY(g->name), 10);
931         gtk_entry_set_max_width_chars(GTK_ENTRY(g->name), 10);
932         p->add_client_widget(g->name);
933         gui_set_tooltip(g->name, "Enter the turntable's name here.");
934         //gtk_widget_set_size_request(g->name, 40, -1);
935
936         g->del=gtk_button_new_with_label("Delete");
937         gui_set_tooltip(g->del, "Click here to annihilate this turntable. All events recorded for this turntable will be erased, too.");
938         p->add_client_widget(g->del);
939         
940         g->adjust_button=gtk_button_new_with_label("Pitch Adj.");
941         gui_set_tooltip(g->adjust_button, "Activate this button to adjust this turntable's speed to the master turntable's speed.");
942         p->add_client_widget(g->adjust_button);
943
944         gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
945                                 
946         p=new tX_panel("Playback", g->control_subbox);
947         g->trigger_panel=p;
948         
949         g->trigger=gtk_button_new_with_label("Trigger!");
950         gui_set_tooltip(g->trigger, "Click here to trigger this turntable right now. If the audio engine is disabled this turntable will be triggerd as soon as the engine is turned on.");
951         p->add_client_widget(g->trigger);
952         
953         g->stop=gtk_button_new_with_label("Stop.");
954         gui_set_tooltip(g->stop, "Stop this turntable's playback.");
955         p->add_client_widget(g->stop);
956         g_signal_connect(G_OBJECT(g->trigger), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_trigger);         
957         g_signal_connect(G_OBJECT(g->stop), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_trigger);            
958         
959         g->autotrigger=gtk_check_button_new_with_label("Auto");
960         p->add_client_widget(g->autotrigger);
961         gui_set_tooltip(g->autotrigger, "If turned on, this turntable will be automagically triggered whenever the audio engine is turned on.");
962         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autotrigger), vtt->autotrigger);
963
964         g->loop=gtk_check_button_new_with_label("Loop");
965         p->add_client_widget(g->loop);
966         gui_set_tooltip(g->loop, "Enable this option to make the turntable loop the audio data.");
967         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->loop), vtt->loop);
968         g_signal_connect(G_OBJECT(g->loop), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_loop);               
969         
970         g->sync_master=gtk_check_button_new_with_label("Master");
971         p->add_client_widget(g->sync_master);
972         gui_set_tooltip(g->sync_master, "Click here to make this turntable the sync-master. All turntables marked as sync-clients will be (re-)triggered in relation to the sync-master. Note that only *one* turntable can be the sync-master.");
973         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_master), vtt->is_sync_master);
974         
975         g->sync_client=gtk_check_button_new_with_label("Client");
976         p->add_client_widget(g->sync_client);
977         gui_set_tooltip(g->sync_client, "If enabled this turntable will be (re-)triggerd in relation to the sync-master turntable.");
978         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_client), vtt->is_sync_client);
979         g_signal_connect(G_OBJECT(g->sync_client), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_sync_client); 
980         
981         g->cycles=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->sync_cycles, 0, 10.0, 1,1,0));
982         dummy=gtk_spin_button_new(g->cycles, 1.0, 0);
983         p->add_client_widget(dummy);
984         gui_set_tooltip(dummy, "Determines how often a sync-client turntable gets triggered. 0 -> this turntable will be triggered with every trigger of the sync-master table, 1 -> the table will be triggered every 2nd master trigger and so on.");
985         g_signal_connect(G_OBJECT(dummy), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_sync_cycles);  
986
987         gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
988         
989         g->fx_box=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
990         gtk_box_pack_start(GTK_BOX(g->control_subbox), g->fx_box, WID_FIX);
991         gtk_widget_show(g->fx_box);
992         
993         dummy=gtk_button_new_with_label("FX");
994         gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
995         gtk_widget_show(dummy);
996         g->fx_button=dummy;
997         gui_set_tooltip(g->fx_button, "Click here to load a LADSPA plugin. You will get a menu from which you can choose which plugin to load.");
998         gtk_box_pack_start(GTK_BOX(g->fx_box), dummy, WID_FIX);
999         
1000         /* Lowpass Panel */
1001
1002         p=new tX_panel("Lowpass", g->fx_box);
1003         g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", G_CALLBACK(vg_show_fx_menu), vtt->lp_fx);
1004         g->lp_panel=p;
1005                 
1006         g->lp_enable=gtk_check_button_new_with_label("Enable");
1007         gui_set_tooltip(g->lp_enable, "Click here to enable the built-in lowpass effect.");
1008         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->lp_enable), vtt->lp_enable);
1009         p->add_client_widget(vg_create_fx_bar(vtt, vtt->lp_fx, 0));
1010         g_signal_connect(G_OBJECT(g->lp_enable), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_lp_enable);     
1011
1012         p->add_client_widget(g->lp_enable);
1013
1014         g->lp_gain=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_gain, 0, 2, 0.1, 0.01, 0.01));
1015         g->lp_reso=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_reso, 0, 0.99, 0.1, 0.01, 0.01));
1016         g->lp_freq=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_freq, 0, 1, 0.1, 0.01, 0.01));
1017
1018         g->lp_gaind=new tX_extdial("Input Gain", g->lp_gain, &vtt->sp_lp_gain);
1019         p->add_client_widget(g->lp_gaind->get_widget());
1020         gui_set_tooltip(g->lp_gaind->get_entry(), "Adjust the input gain. with this parameter you can either amplify or damp the input-signal for the lowpass effect.");
1021
1022         g->lp_freqd=new tX_extdial("Frequency", g->lp_freq, &vtt->sp_lp_freq);
1023         p->add_client_widget(g->lp_freqd->get_widget());
1024         gui_set_tooltip(g->lp_freqd->get_entry(), "Adjust the cutoff frequency of the lowpass filter. 0 is 0 Hz, 1 is 22.1 kHz.");
1025
1026         g->lp_resod=new tX_extdial("Resonance", g->lp_reso, &vtt->sp_lp_reso);
1027         p->add_client_widget(g->lp_resod->get_widget());
1028         gui_set_tooltip(g->lp_resod->get_entry(), "Adjust the resonance of the lowpass filter. This value determines how much the signal at the cutoff frequency will be amplified.");
1029
1030         gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
1031
1032         /* Echo Panel */
1033
1034         p=new tX_panel("Echo", g->fx_box);
1035         g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event",  G_CALLBACK(vg_show_fx_menu), vtt->ec_fx);
1036         g->ec_panel=p;
1037
1038         p->add_client_widget(vg_create_fx_bar(vtt, vtt->ec_fx, 0));
1039         
1040         g->ec_enable=gtk_check_button_new_with_label("Enable");
1041         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->ec_enable), vtt->ec_enable);
1042         p->add_client_widget(g->ec_enable);
1043         gui_set_tooltip(g->ec_enable, "Enable the built-in echo effect.");
1044         g_signal_connect(G_OBJECT(g->ec_enable), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_ec_enable);     
1045
1046         g->ec_length=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_length, 0, 1, 0.1, 0.01, 0.001));
1047         g->ec_feedback=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_feedback, 0, 1, 0.1, 0.01, 0.001));
1048         g->ec_pan=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_pan, -1.0, 1, 0.1, 0.01, 0.001));
1049         g->ec_volume=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_volume, 0.0, 3.0, 0.1, 0.01, 0.001));
1050
1051         g->ec_lengthd=new tX_extdial("Duration", g->ec_length, &vtt->sp_ec_length);
1052         p->add_client_widget(g->ec_lengthd->get_widget());
1053         gui_set_tooltip(g->ec_lengthd->get_entry(), "Adjust the length of the echo buffer.");
1054
1055         g->ec_feedbackd=new tX_extdial("Feedback", g->ec_feedback, &vtt->sp_ec_feedback);
1056         p->add_client_widget(g->ec_feedbackd->get_widget());
1057         gui_set_tooltip(g->ec_feedbackd->get_entry(), "Adjust the feedback of the echo effect. Note that a value of 1 will result in a constant signal.");
1058
1059         g->ec_volumed=new tX_extdial("Volume", g->ec_volume, &vtt->sp_ec_volume);
1060         p->add_client_widget(g->ec_volumed->get_widget());
1061         gui_set_tooltip(g->ec_volumed->get_entry(), "Adjust the volume of the echo effect.");
1062
1063         g->ec_pand=new tX_extdial("Pan", g->ec_pan, &vtt->sp_ec_pan);
1064         p->add_client_widget(g->ec_pand->get_widget());
1065         gui_set_tooltip(g->ec_pand->get_entry(), "Adjust the panning of the echo effect.");
1066
1067         gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
1068         
1069         g->stereo_fx_box=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1070         gtk_box_pack_start(GTK_BOX(g->control_subbox), g->stereo_fx_box, WID_FIX);
1071         gtk_widget_show(g->stereo_fx_box);
1072         
1073         dummy=gtk_button_new_with_label("Stereo FX");
1074         gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
1075         gtk_widget_show(dummy);
1076         g->stereo_fx_button=dummy;
1077         gui_set_tooltip(g->stereo_fx_button, "Click here to load a stereo LADSPA plugin. You will get a menu from which you can choose which plugin to load.");
1078         gtk_box_pack_start(GTK_BOX(g->stereo_fx_box), dummy, WID_FIX);
1079
1080         /* Output */
1081         
1082         tempbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,2);
1083         gtk_widget_show(tempbox);
1084         gtk_box_pack_end(GTK_BOX(g->control_box), tempbox, WID_FIX);
1085         
1086         tempbox2=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
1087         gtk_widget_show(tempbox2);
1088         gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
1089         
1090         g->pitch=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->rel_pitch, -3, +3, 0.1, 0.01, 0.001));
1091         g->pan=GTK_ADJUSTMENT(gtk_adjustment_new(0, -1, 1, 0.1, 0.01, 0.001));
1092
1093         g->pitchd=new tX_extdial("Pitch", g->pitch, &vtt->sp_pitch);
1094         gui_set_tooltip(g->pitchd->get_entry(), "Adjust this turntable's pitch.");
1095
1096         gtk_box_pack_start(GTK_BOX(tempbox2), g->pitchd->get_widget(), WID_FIX);
1097
1098         g->pand=new tX_extdial("Pan", g->pan, &vtt->sp_pan);
1099         gtk_box_pack_start(GTK_BOX(tempbox2), g->pand->get_widget(), WID_FIX);
1100         gui_set_tooltip(g->pand->get_entry(), "Specifies the position of this turntable within the stereo spectrum: -1 -> left, 0-> center, 1->right.");
1101
1102         tempbox3=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,2);
1103         gtk_widget_show(tempbox3);
1104
1105         g->mute=gtk_check_button_new_with_label("M");
1106         gtk_box_pack_start(GTK_BOX(tempbox3), g->mute, WID_FIX);
1107         g_signal_connect(G_OBJECT(g->mute),"clicked", (GCallback) mute_volume, vtt);
1108         gtk_widget_show(g->mute);
1109         gui_set_tooltip(g->mute, "Mute this turntable's mixer output.");
1110
1111         g->solo=gtk_check_button_new_with_label("S");
1112         gtk_box_pack_start(GTK_BOX(tempbox3), g->solo, WID_FIX);
1113         g_signal_connect(G_OBJECT(g->solo),"clicked", (GCallback) solo_vtt, vtt);
1114         gtk_widget_show(g->solo);
1115         gui_set_tooltip(g->solo, "Allow only this and other solo-switched turntabels' signal to be routed to the mixer.");
1116
1117         gtk_box_pack_start(GTK_BOX(tempbox2), tempbox3, WID_FIX);
1118
1119         tempbox2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
1120         gtk_widget_show(tempbox2);
1121         gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
1122         
1123         g->volume=GTK_ADJUSTMENT(gtk_adjustment_new(2.0-vtt->rel_volume, 0, 2, 0.01, 0.01, 0.01));
1124         dummy=gtk_scale_new(GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT(g->volume)); 
1125         gtk_scale_set_draw_value(GTK_SCALE(dummy), FALSE);
1126         gui_set_tooltip(dummy, "Adjust this turntable's volume.");
1127         g_signal_connect(G_OBJECT(dummy), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_volume);       
1128
1129         gtk_box_pack_start(GTK_BOX(tempbox2), dummy, WID_FIX);
1130         gtk_widget_show(dummy);
1131
1132         g->flash=gtk_tx_flash_new();
1133         gtk_box_pack_start(GTK_BOX(tempbox2), g->flash, WID_FIX);
1134         gtk_widget_show(g->flash);
1135
1136         gui_connect_signals(vtt);
1137         
1138         g->audio_minimized_panel_bar_button=NULL;
1139         g->control_minimized_panel_bar_button=NULL;
1140         g->file_menu=NULL;
1141         g->mouse_mapping_menu=NULL;
1142         g->mouse_mapping_menu_x=NULL;
1143         g->mouse_mapping_menu_y=NULL;
1144         
1145         g->adjust_dialog=NULL;
1146         
1147         gui_set_name(vtt, vtt->name);   
1148 }
1149
1150 void fx_up(GtkWidget *wid, vtt_fx *effect)
1151 {
1152         vtt_class *vtt;
1153         
1154         vtt=(vtt_class*)effect->get_vtt();
1155         vtt->effect_up(effect);
1156 }
1157
1158 void fx_down(GtkWidget *wid, vtt_fx *effect)
1159 {
1160         vtt_class *vtt;
1161         
1162         vtt=(vtt_class*)effect->get_vtt();
1163         vtt->effect_down(effect);
1164 }
1165
1166 void fx_kill(GtkWidget *wid, vtt_fx_ladspa *effect)
1167 {
1168         vtt_class *vtt;
1169         
1170         vtt=(vtt_class*)effect->get_vtt();
1171         vtt->effect_remove(effect);
1172 }
1173
1174 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel)
1175 {
1176         GtkWidget *box;
1177         GtkWidget *pixmap;
1178         GtkWidget *button;
1179         
1180         box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
1181
1182         if (showdel) {
1183                 button=gtk_button_new();
1184                 pixmap=tx_pixmap_widget(FX_CLOSE);
1185                 gtk_container_add (GTK_CONTAINER (button), pixmap);     
1186                 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1187                 gtk_widget_show(pixmap);
1188                 gtk_widget_show(button);
1189                 g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_kill, (void *) effect);
1190         }
1191
1192         button=gtk_button_new();
1193         pixmap=tx_pixmap_widget(FX_DOWN);
1194         gtk_container_add (GTK_CONTAINER (button), pixmap);     
1195         gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1196         gtk_widget_show(pixmap);
1197         gtk_widget_show(button);
1198         g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_down, (void *) effect);
1199
1200         button=gtk_button_new();
1201         pixmap=tx_pixmap_widget(FX_UP);
1202         gtk_container_add (GTK_CONTAINER (button), pixmap);     
1203         gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1204         gtk_widget_show(pixmap);
1205         gtk_widget_show(button);
1206         g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_up, (void *) effect);
1207         
1208         gtk_widget_show(box);
1209         
1210         return box;
1211 }
1212
1213 int gtk_box_get_widget_pos(GtkBox *box, GtkWidget *child)
1214 {
1215         int i=0;
1216         GList *list;
1217  
1218         list = gtk_container_get_children(GTK_CONTAINER(box));
1219         while (list)
1220         {
1221                 GtkWidget *child_widget = (GtkWidget *) list->data;
1222                 if (child_widget == child)
1223                 break;
1224                 list = list->next; i++;
1225         }
1226         return i;
1227 }
1228
1229 void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt, bool stereo)
1230 {
1231         GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
1232         int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
1233         gtk_box_reorder_child(GTK_BOX(box), wid, pos-1);
1234 }
1235
1236 void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt, bool stereo)
1237 {
1238         GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
1239         int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
1240         gtk_box_reorder_child(GTK_BOX(box), wid, pos+1);
1241 }
1242
1243 static gint vg_show_fx_info(GtkWidget *wid, vtt_fx *effect)
1244 {
1245         tx_l_note(effect->get_info_string());
1246         return TRUE;
1247 }
1248
1249 void vg_toggle_drywet(GtkWidget *wid, vtt_fx *effect)
1250 {
1251         effect->toggle_drywet();
1252 }
1253
1254 static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect)
1255 {
1256         if (event->button==3) {
1257                 GtkWidget *menu=gtk_menu_new();
1258                 GtkWidget *item=gtk_menu_item_new_with_label("View Plugin Details");
1259                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1260                 gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
1261                 gtk_widget_show(item);
1262                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_show_fx_info), effect);
1263                 
1264                 switch (effect->has_drywet_feature()) {
1265                         case (NOT_DRYWET_CAPABLE):
1266                                 item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
1267                                 gtk_widget_set_sensitive(item, FALSE);
1268                                 break;
1269                         case (DRYWET_ACTIVE):
1270                                 item=gtk_menu_item_new_with_label("Remove Dry/Wet Control");
1271                                 break;
1272                         case (DRYWET_AVAILABLE):
1273                                 item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
1274                                 break;
1275                 }
1276                 
1277                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_toggle_drywet), effect);     
1278                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1279                 gtk_widget_show(item);
1280                 
1281                 item = gtk_menu_item_new();
1282                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1283                 gtk_widget_set_sensitive(item, FALSE);
1284                 gtk_widget_show(item);
1285         
1286                 item=gtk_menu_item_new_with_label("Up");
1287                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1288                 gtk_widget_show(item);
1289                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_up), effect);
1290         
1291                 item=gtk_menu_item_new_with_label("Down");
1292                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1293                 gtk_widget_show(item);
1294                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_down), effect);
1295         
1296                 item=gtk_menu_item_new_with_label("Delete");
1297                 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1298                 gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
1299                 gtk_widget_show(item);
1300                 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_kill), effect);
1301         
1302                 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
1303         
1304                 /* gtk+ is really waiting for this.. */
1305                 g_signal_emit_by_name(G_OBJECT(wid), "released", effect);
1306                 return TRUE;
1307         }
1308         return FALSE;
1309 }
1310
1311 void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin)
1312 {
1313         char buffer[1024];
1314         
1315         vtt_gui *g;
1316         g=&vtt->gui;    
1317         tX_panel *p;
1318         list <tX_seqpar_vttfx *> :: iterator sp;
1319         
1320         strcpy(buffer, plugin->getLabel());
1321         if (strlen(buffer) > 6) {
1322                 buffer[5]='.';
1323                 buffer[6]='.';
1324                 buffer[7]='.';
1325                 buffer[8]=0;
1326         }
1327
1328         p=new tX_panel(buffer, g->control_subbox);
1329         
1330         p->add_client_widget(vg_create_fx_bar(vtt, effect, 1));
1331         
1332         for (sp = effect->controls.begin(); sp != effect->controls.end(); sp++) {
1333                         p->add_client_widget((*sp)->get_widget());
1334         }
1335
1336         g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", (GCallback) vg_show_fx_menu, (void *) effect);
1337         gui_set_tooltip(p->get_labelbutton(), "Right-click to access menu.");
1338         effect->set_panel_widget(p->get_widget());
1339         effect->set_panel(p);
1340
1341         gtk_box_pack_start(GTK_BOX((effect->is_stereo() ? g->stereo_fx_box : g->fx_box)), p->get_widget(), WID_FIX);
1342 }
1343
1344 void gui_set_filename (vtt_class *vtt, char *newname)
1345 {
1346         gtk_button_set_label(GTK_BUTTON(vtt->gui.file), newname);
1347 }
1348
1349 void gui_update_display(vtt_class *vtt)
1350 {
1351         nicer_filename(global_filename_buffer, vtt->filename);
1352         gtk_button_set_label(GTK_BUTTON(vtt->gui.file), global_filename_buffer);
1353         gtk_tx_set_data(GTK_TX(vtt->gui.display), vtt->buffer, vtt->samples_in_buffer);
1354 }
1355
1356 void gui_hide_control_panel(vtt_class *vtt, bool hide) {
1357         char tooltip[2048];
1358
1359         if (hide) {
1360                 gtk_widget_hide(vtt->gui.control_box);
1361                 vtt->gui.control_minimized_panel_bar_button=tx_xpm_button_new(MIN_CONTROL, vtt->name, 0, &vtt->gui.control_minimized_panel_bar_label);
1362                 g_signal_connect(G_OBJECT(vtt->gui.control_minimized_panel_bar_button), "clicked", (GCallback) unminimize_control_panel, vtt);
1363                 gtk_widget_show(vtt->gui.control_minimized_panel_bar_button);
1364                 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" control panel.", vtt->name);
1365                 gui_set_tooltip(vtt->gui.control_minimized_panel_bar_button, tooltip);
1366                 add_to_panel_bar(vtt->gui.control_minimized_panel_bar_button);
1367         } else {
1368                 gtk_widget_show(vtt->gui.control_box);
1369                 remove_from_panel_bar(vtt->gui.control_minimized_panel_bar_button);
1370                 if (!tX_shutdown) gtk_widget_destroy(vtt->gui.control_minimized_panel_bar_button);
1371                 vtt->gui.control_minimized_panel_bar_button=NULL;
1372         }
1373 }
1374
1375 void gui_hide_audio_panel(vtt_class *vtt, bool hide) {
1376         char tooltip[2048];
1377
1378         if (hide) {
1379                 gtk_widget_hide(vtt->gui.audio_box);
1380                 vtt->gui.audio_minimized_panel_bar_button=tx_xpm_button_new(MIN_AUDIO, vtt->name, 0, &vtt->gui.audio_minimized_panel_bar_label);
1381                 g_signal_connect(G_OBJECT(vtt->gui.audio_minimized_panel_bar_button), "clicked", (GCallback) unminimize_audio_panel, vtt);              
1382                 gtk_widget_show(vtt->gui.audio_minimized_panel_bar_button);
1383                 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" audio panel.", vtt->name);
1384                 gui_set_tooltip(vtt->gui.audio_minimized_panel_bar_button, tooltip);
1385                 add_to_panel_bar(vtt->gui.audio_minimized_panel_bar_button);
1386         } else {
1387                 gtk_widget_show(vtt->gui.audio_box);
1388                 remove_from_panel_bar(vtt->gui.audio_minimized_panel_bar_button);
1389                 if (!tX_shutdown) gtk_widget_destroy(vtt->gui.audio_minimized_panel_bar_button);
1390                 vtt->gui.audio_minimized_panel_bar_button=NULL;
1391         }
1392 }
1393
1394 void delete_gui(vtt_class *vtt)
1395 {
1396         if (vtt->gui.control_minimized_panel_bar_button!=NULL) gui_hide_control_panel(vtt, false);
1397         if (vtt->gui.audio_minimized_panel_bar_button!=NULL) gui_hide_audio_panel(vtt, false);
1398
1399         delete vtt->gui.main_panel;
1400         delete vtt->gui.trigger_panel;
1401         
1402         delete vtt->gui.pitchd;
1403         delete vtt->gui.pand;
1404         
1405         delete vtt->gui.lp_gaind;
1406         delete vtt->gui.lp_resod;
1407         delete vtt->gui.lp_freqd;
1408         delete vtt->gui.lp_panel;
1409         
1410         delete vtt->gui.ec_lengthd;
1411         delete vtt->gui.ec_feedbackd;
1412         delete vtt->gui.ec_volumed;
1413         delete vtt->gui.ec_pand;
1414         delete vtt->gui.ec_panel;
1415
1416         gtk_widget_destroy(vtt->gui.control_box);
1417         gtk_widget_destroy(vtt->gui.audio_box);
1418         if (vtt->gui.file_menu) gtk_widget_destroy(vtt->gui.file_menu);
1419         if (vtt->gui.mouse_mapping_menu) gtk_widget_destroy(vtt->gui.mouse_mapping_menu);
1420         if (vtt->gui.ladspa_menu) gtk_widget_destroy(vtt->gui.ladspa_menu);
1421 }
1422
1423 void cleanup_vtt(vtt_class *vtt)
1424 {
1425         gtk_tx_cleanup_pos_display(GTK_TX(vtt->gui.display));   
1426         gtk_tx_flash_set_level(vtt->gui.flash, 0.0, 0.0);
1427         gtk_tx_flash_clear(vtt->gui.flash);
1428         vtt->cleanup_required=false;
1429 }
1430
1431 void update_all_vtts()
1432 {
1433         list <vtt_class *> :: iterator vtt;
1434         f_prec temp,temp2;
1435         
1436         for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1437         {
1438                 if ((*vtt)->is_playing) {
1439                         gtk_tx_update_pos_display(GTK_TX((*vtt)->gui.display), (*vtt)->pos_i, (*vtt)->mute);
1440                         temp=(*vtt)->max_value*(*vtt)->res_volume*vtt_class::vol_channel_adjust;
1441                         temp2=(*vtt)->max_value2*(*vtt)->res_volume*vtt_class::vol_channel_adjust;
1442 //                      tX_msg("Setting value: %f, %f -> %f; %f, %f -> %f (%f)\n",
1443 //                              (*vtt)->max_value, (*vtt)->res_volume, temp,
1444 //                              (*vtt)->max_value2, (*vtt)->res_volume, temp2,
1445 //                              vtt_class::vol_channel_adjust
1446 //                      );
1447                         gtk_tx_flash_set_level((*vtt)->gui.flash, temp, temp2);
1448                         
1449                         (*vtt)->max_value=0;
1450                         (*vtt)->max_value2=0;
1451                 }
1452                 
1453                 if ((*vtt)->needs_cleaning_up()) {
1454                         cleanup_vtt((*vtt));
1455                 }
1456         }
1457 }
1458
1459 void cleanup_all_vtts()
1460 {
1461         list <vtt_class *> :: iterator vtt;
1462         
1463         for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1464         {
1465                 if ((*vtt)->buffer) gtk_tx_cleanup_pos_display(GTK_TX((*vtt)->gui.display));
1466                 gtk_tx_flash_set_level((*vtt)->gui.flash, 0.0, 0.0);
1467                 gtk_tx_flash_clear((*vtt)->gui.flash);
1468         }
1469 }
1470
1471 void gui_clear_master_button(vtt_class *vtt)
1472 {
1473         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_master), 0);
1474 }
1475
1476 void gui_show_frame(vtt_class *vtt, int show)
1477 {
1478         gtk_tx_show_frame(GTK_TX(vtt->gui.display), show);
1479 }
1480
1481 #define vgui (*vtt)->gui
1482 #define v (*vtt)
1483
1484 void vg_enable_critical_buttons(int enable)
1485 {
1486         list <vtt_class *> :: iterator vtt;
1487         for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1488         {
1489                 gtk_widget_set_sensitive(vgui.del, enable);
1490                 gtk_widget_set_sensitive(vgui.sync_master, enable);
1491         }
1492 }
1493
1494 void vg_init_all_non_seqpars()
1495 {
1496         list <vtt_class *> :: iterator vtt;
1497         
1498         for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1499         {
1500                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.autotrigger), (*vtt)->autotrigger);
1501                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.sync_master), (*vtt)->is_sync_master);
1502         }       
1503 }
1504