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