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