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