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