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