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