2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2011 Alexander König
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.
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.
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.
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.
28 before 11-26-2001: too many changes.
30 11-26-2001: applied Adrian's solo/mute patch - Alex
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.
39 #include "tX_vttgui.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"
49 #include "tX_ladspa.h"
50 #include "tX_ladspa_class.h"
51 #include "tX_engine.h"
52 #include "tX_glade_interface.h"
53 #include "tX_glade_support.h"
54 #include "tX_dialog.h"
64 #define WID_DYN TRUE, TRUE, 0
65 #define WID_FIX FALSE, FALSE, 0
67 static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect);
69 void nicer_filename(char *dest, char *source)
74 fn=strrchr(source, '/');
80 fn=strrchr(temp, '.');
83 if (strlen(temp) > (unsigned int) globals.filename_length) {
84 temp[globals.filename_length-3]='.';
85 temp[globals.filename_length-2]='.';
86 temp[globals.filename_length-1]='.';
87 temp[globals.filename_length]=0;
92 void name_changed(GtkWidget *wid, vtt_class *vtt)
94 vtt->set_name((char *) gtk_entry_get_text(GTK_ENTRY(wid)));
97 void volume_changed(GtkWidget *wid, vtt_class *vtt)
99 vtt->sp_volume.receive_gui_value(2.0-GTK_ADJUSTMENT(wid)->value);
102 void pan_changed(GtkWidget *wid, vtt_class *vtt)
104 vtt->sp_pan.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
107 void pitch_changed(GtkWidget *wid, vtt_class *vtt)
109 vtt->sp_pitch.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
112 #ifdef USE_FILECHOOSER
113 GtkSignalFunc chooser_prelis(GtkWidget *w)
115 GtkFileChooser *fc=GTK_FILE_CHOOSER(gtk_widget_get_toplevel(w));
116 char *filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
119 prelis_start(filename);
127 GtkSignalFunc trigger_prelis(GtkWidget *w)
129 GtkFileSelection *fs;
131 fs=GTK_FILE_SELECTION(gtk_widget_get_toplevel(w));
133 prelis_start((char *) gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
137 void cancel_load_file(GtkWidget *wid, vtt_class *vtt)
141 vtt->gui.file_dialog=NULL;
142 if (vtt->gui.fs) gtk_widget_destroy(GTK_WIDGET(vtt->gui.fs));
145 int quit_load_file(GtkWidget *wid, vtt_class *vtt)
151 char global_filename_buffer[PATH_MAX];
153 void load_part(char *newfile, vtt_class *vtt)
155 tX_audio_error ret=TX_AUDIO_SUCCESS;
157 ld_create_loaddlg(TX_LOADDLG_MODE_SINGLE, 1);
158 ld_set_filename(newfile);
160 ret = vtt->load_file(newfile);
165 case TX_AUDIO_ERR_ALLOC:
166 tx_note("Failed to load audiofile - there's not enough memory available.", true);
168 case TX_AUDIO_ERR_PIPE_READ:
169 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);
171 case TX_AUDIO_ERR_SOX:
172 tx_note("Failed to run sox - to load the given audiofile please ensure that sox is installed correctly.", true);
174 case TX_AUDIO_ERR_MPG123:
175 tx_note("Failed to run mpg123 - to load the given mp3 file please ensure that mpg123 (or mpg321) is installed correctly.", true);
177 case TX_AUDIO_ERR_WAV_NOTFOUND:
178 tx_note("Couldn't acces the audiofile - file not found.", true);
180 case TX_AUDIO_ERR_NOT_16BIT:
181 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);
183 case TX_AUDIO_ERR_NOT_MONO:
184 tx_note("The wav file is not mono - please compile terminatorX with libaudiofile support to enable loading of such files.", true);
186 case TX_AUDIO_ERR_WAV_READ:
187 tx_note("The wav file seems to be corrupt.", true);
189 case TX_AUDIO_ERR_NOT_SUPPORTED:
190 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);
192 case TX_AUDIO_ERR_MAD_OPEN:
193 tx_note("Failed to open this mp3 file - please ensure that the file exists and is readable.", true);
195 case TX_AUDIO_ERR_MAD_STAT:
196 tx_note("Failed to 'stat' this mp3 file - please ensure that the file exists and is readable.", true);
198 case TX_AUDIO_ERR_MAD_DECODE:
199 tx_note("Failed to decode the mp3 stream - file is corrupt.", true);
201 case TX_AUDIO_ERR_MAD_MMAP:
202 tx_note("Failed to map the audiofile to memory - please ensure the file is readable.", true);
204 case TX_AUDIO_ERR_MAD_MUNMAP:
205 tx_note("Failed to unmap audiofile.", true);
207 case TX_AUDIO_ERR_VORBIS_OPEN:
208 tx_note("Failed to open ogg file - please ensure the file is an ogg stream and that it is readable.", true);
210 case TX_AUDIO_ERR_VORBIS_NODATA:
211 tx_note("The vorbis codec failed to decode any data - possibly this ogg stream is corrupt.", true);
213 case TX_AUDIO_ERR_AF_OPEN:
214 tx_note("Failed to open this file with libaudiofile - please check terminatorX' INSTALL file on howto configure terminatorX for files of this format.",true);
216 case TX_AUDIO_ERR_AF_NODATA:
217 tx_note("libaudiofile failed to decode any data - possilby the audiofile is corrupt.", true);
220 tx_note("An unknown error occured - if this bug is reproducible please report it, thanks.", true);
223 nicer_filename(global_filename_buffer, newfile);
224 gtk_button_set_label(GTK_BUTTON(vtt->gui.file), global_filename_buffer);
228 #ifndef USE_FILECHOOSER
229 void do_load_file(GtkWidget *wid, vtt_class *vtt)
231 char newfile[PATH_MAX];
235 strcpy(newfile, gtk_file_selection_get_filename(GTK_FILE_SELECTION(vtt->gui.fs)));
236 gtk_widget_destroy(GTK_WIDGET(vtt->gui.fs));
237 vtt->gui.file_dialog=NULL;
239 tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
240 load_part(newfile, vtt);
241 strcpy(globals.current_path, newfile);
242 tX_cursor::reset_cursor();
246 void drop_file(GtkWidget *widget, GdkDragContext *context,
247 gint x, gint y, GtkSelectionData *selection_data,
248 guint info, guint time, vtt_class *vtt)
250 char filename[PATH_MAX];
253 strncpy(filename, (char *) selection_data->data, (size_t) selection_data->length);
254 gtk_drag_finish(context, TRUE, FALSE, time);
255 filename[selection_data->length]=0;
257 fn = strchr (filename, '\r');
263 realfn=g_filename_from_uri(filename, &host, NULL);
267 fn = strchr (filename, ':');
268 if (fn) fn++; else fn=(char *) selection_data->data;
273 if (realfn) g_free(realfn);
274 if (host) g_free(host);
277 GtkSignalFunc load_file(GtkWidget *wid, vtt_class *vtt)
279 #ifdef USE_FILECHOOSER
280 const char *extensions[]={ "mp3", "wav", "ogg", "flac", "iff", "aiff", "voc", "au", "spx", NULL };
282 sprintf(name_buf, "Select Audio File for %s", vtt->name);
284 GtkWidget * dialog = gtk_file_chooser_dialog_new (name_buf,
285 GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN,
286 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
287 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
290 GtkFileFilter *filter=gtk_file_filter_new();
291 for (int i=0; extensions[i]!=NULL; i++) {
292 char buffer[32]="*.";
294 gtk_file_filter_add_pattern(filter, strcat(buffer, extensions[i]));
295 for (unsigned int c=0; c<strlen(buffer); c++) {
296 buffer[c]=toupper(buffer[c]);
298 gtk_file_filter_add_pattern(filter, buffer);
301 gtk_file_filter_set_name(filter, "Audio Files");
302 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
304 filter=gtk_file_filter_new();
305 gtk_file_filter_add_pattern (filter, "*");
306 gtk_file_filter_set_name(filter, "All Files");
307 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
309 if (vtt->audiofile) {
310 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), vtt->filename);
311 } else if (strlen(globals.current_path)>0 ) {
312 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), globals.current_path);
315 g_signal_connect (G_OBJECT(dialog), "selection-changed", G_CALLBACK(chooser_prelis), vtt);
317 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
318 char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
319 gtk_widget_hide(dialog);
320 tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
321 load_part(filename, vtt);
322 strcpy(globals.current_path, filename);
323 tX_cursor::reset_cursor();
327 gtk_widget_destroy(dialog);
331 if (vtt->gui.file_dialog) {
332 gdk_window_raise(vtt->gui.file_dialog);
336 sprintf(buffer, "Select Audio File for %s", vtt->name);
337 vtt->gui.fs=gtk_file_selection_new(buffer);
339 if (vtt->audiofile) {
340 gtk_file_selection_set_filename(GTK_FILE_SELECTION(vtt->gui.fs), vtt->filename);
341 } else if (strlen(globals.current_path)>0 ) {
342 gtk_file_selection_set_filename(GTK_FILE_SELECTION(vtt->gui.fs),globals.current_path);
345 gtk_widget_show(GTK_WIDGET(vtt->gui.fs));
346 vtt->gui.file_dialog=vtt->gui.fs->window;
348 g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->ok_button), "clicked", G_CALLBACK(do_load_file), vtt);
349 g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->cancel_button), "clicked", G_CALLBACK (cancel_load_file), vtt);
350 g_signal_connect (G_OBJECT(vtt->gui.fs), "delete-event", G_CALLBACK(quit_load_file), vtt);
351 g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->file_list), "cursor_changed", G_CALLBACK(trigger_prelis), vtt->gui.fs);
356 void delete_vtt(GtkWidget *wid, vtt_class *vtt)
358 if (audioon) tx_note("Sorry, you'll have to stop playback first.");
364 void edit_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
366 char command[2*PATH_MAX];
368 if (vtt->samples_in_buffer == 0) {
369 tx_note("No audiofile loaded - so there's nothing to edit.", true);
370 } else if (strlen(globals.file_editor)>0) {
371 sprintf(command, "%s \"%s\" &", globals.file_editor, vtt->filename);
372 int res = system(command); /*) tx_note("Failed to run the soundfile editor."); */
374 tx_note("No soundfile editor has been configured - to do so enter the soundfile editor of your choice in the options dialog.", true);
378 void reload_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
380 char reload_buffer[PATH_MAX];
382 while (gtk_events_pending()) gtk_main_iteration();
384 if (vtt->samples_in_buffer > 0) {
385 strcpy(reload_buffer, vtt->filename);
386 load_part(reload_buffer, vtt);
388 else tx_note("No audiofile loaded - so there's nothing to reload.", true);
391 void clone_vtt(GtkWidget *wid, vtt_class *vtt)
396 void trigger_vtt(GtkWidget *wid, vtt_class *vtt)
398 vtt->sp_trigger.receive_gui_value((float) 1.0);
401 void stop_vtt(GtkWidget *wid, vtt_class *vtt)
403 vtt->sp_trigger.receive_gui_value((float) 0.0);
406 void autotrigger_toggled(GtkWidget *wid, vtt_class *vtt)
408 vtt->set_autotrigger(GTK_TOGGLE_BUTTON(wid)->active);
411 void loop_toggled(GtkWidget *wid, vtt_class *vtt)
413 vtt->sp_loop.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
416 void lp_enabled(GtkWidget *wid, vtt_class *vtt)
418 vtt->sp_lp_enable.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
421 void lp_gain_changed(GtkWidget *wid, vtt_class *vtt)
423 vtt->sp_lp_gain.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
426 void lp_reso_changed(GtkWidget *wid, vtt_class *vtt)
428 vtt->sp_lp_reso.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
431 void lp_freq_changed(GtkWidget *wid, vtt_class *vtt)
433 vtt->sp_lp_freq.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
436 void ec_enabled(GtkWidget *wid, vtt_class *vtt)
438 vtt->sp_ec_enable.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
441 #ifdef USE_ALSA_MIDI_IN
442 void midi_mapping_clicked(GtkWidget *wid, vtt_class *vtt)
444 tX_engine::get_instance()->get_midi()->configure_bindings(vtt);
448 void ec_length_changed(GtkWidget *wid, vtt_class *vtt)
450 vtt->sp_ec_length.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
453 void ec_feedback_changed(GtkWidget *wid, vtt_class *vtt)
455 vtt->sp_ec_feedback.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
458 void ec_pan_changed(GtkWidget *wid, vtt_class *vtt)
460 vtt->sp_ec_pan.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
463 void ec_volume_changed(GtkWidget *wid, vtt_class *vtt)
465 vtt->sp_ec_volume.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
468 void master_setup(GtkWidget *wid, vtt_class *vtt)
470 vtt->set_sync_master(GTK_TOGGLE_BUTTON(wid)->active);
473 void client_setup(GtkWidget *wid, vtt_class *vtt)
477 client=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_client));
478 vtt->sp_sync_client.receive_gui_value(client);
481 void client_setup_number(GtkWidget *wid, vtt_class *vtt)
485 cycles=(int) GTK_ADJUSTMENT(vtt->gui.cycles)->value;
487 vtt->sp_sync_cycles.receive_gui_value(cycles);
490 void mute_volume(GtkWidget *widget, vtt_class *vtt)
492 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
493 vtt->set_mix_mute(1);
495 vtt->set_mix_mute(0);
499 void solo_vtt(GtkWidget *widget, vtt_class *vtt)
501 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
502 vtt->set_mix_solo(1);
504 vtt->set_mix_solo(0);
508 void minimize_control_panel(GtkWidget *wid, vtt_class *vtt)
510 vtt->hide_control(true);
513 void unminimize_control_panel(GtkWidget *wid, vtt_class *vtt)
515 vtt->hide_control(false);
518 void minimize_audio_panel(GtkWidget *wid, vtt_class *vtt)
520 vtt->hide_audio(true);
523 void unminimize_audio_panel(GtkWidget *wid, vtt_class *vtt)
525 vtt->hide_audio(false);
528 void vg_xcontrol_dis(GtkWidget *wid, vtt_class *vtt)
530 vtt->set_x_input_parameter(NULL);
533 void vg_ycontrol_dis(GtkWidget *wid, vtt_class *vtt)
535 vtt->set_y_input_parameter(NULL);
538 void vg_xcontrol_set(GtkWidget *wid, tX_seqpar *sp)
540 vtt_class *vtt=(vtt_class *) sp->vtt;
541 vtt->set_x_input_parameter(sp);
544 void vg_ycontrol_set(GtkWidget *wid, tX_seqpar *sp)
546 vtt_class *vtt=(vtt_class *) sp->vtt;
547 vtt->set_y_input_parameter(sp);
550 gboolean vg_delete_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
551 vtt->gui.adjust_dialog=NULL;
555 void vg_do_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
556 int master_cycles=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "master_cycles")));
557 int cycles=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "cycles")));
558 bool create_event=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(vtt->gui.adjust_dialog, "create_event")));
560 vtt->adjust_to_master_pitch(master_cycles, cycles, create_event);
562 gtk_widget_destroy(vtt->gui.adjust_dialog);
565 void vg_cancel_pitch_adjust (GtkWidget *wid, vtt_class *vtt) {
566 gtk_widget_destroy(vtt->gui.adjust_dialog);
569 void vg_adjust_pitch_vtt(GtkWidget *wid, vtt_class *vtt) {
570 if (vtt->gui.adjust_dialog) {
571 gtk_widget_destroy(vtt->gui.adjust_dialog);
575 if (!vtt_class::sync_master) {
576 tx_note("No master turntable to adjust pitch to selected.", true);
580 if (vtt==vtt_class::sync_master) {
581 tx_note("This is the master turntable - cannot adjust a turntable to itself.", true);
585 vtt->gui.adjust_dialog=create_tx_adjust();
586 tX_set_icon(vtt->gui.adjust_dialog);
587 gtk_widget_show(vtt->gui.adjust_dialog);
589 GtkWidget *ok_button=lookup_widget(vtt->gui.adjust_dialog, "ok");
590 GtkWidget *cancel_button=lookup_widget(vtt->gui.adjust_dialog, "cancel");
592 g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(vg_do_pitch_adjust), vtt);
593 g_signal_connect(G_OBJECT(vtt->gui.adjust_dialog), "destroy", G_CALLBACK(vg_delete_pitch_adjust), vtt);
594 g_signal_connect(G_OBJECT(cancel_button), "clicked", G_CALLBACK(vg_cancel_pitch_adjust), vtt);
597 static gint vg_mouse_mapping_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt) {
598 if (vtt->gui.mouse_mapping_menu) {
599 gtk_widget_destroy(vtt->gui.mouse_mapping_menu);
600 vtt->gui.mouse_mapping_menu=NULL;
602 /* gtk+ seems to cleanup the submenus automatically */
604 vtt->gui.mouse_mapping_menu=gtk_menu_new();
608 x_item=gtk_menu_item_new_with_label("X-axis (Left <-> Right)");
609 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu), x_item);
610 gtk_widget_show(x_item);
612 y_item=gtk_menu_item_new_with_label("Y-axis (Up <-> Down)");
613 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu), y_item);
614 gtk_widget_show(y_item);
616 vtt->gui.mouse_mapping_menu_x=gtk_menu_new();
617 vtt->gui.mouse_mapping_menu_y=gtk_menu_new();
620 GtkWidget *item_to_activate=NULL;
622 /* Filling the X menu */
623 item = gtk_check_menu_item_new_with_label("Disable");
624 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_x), item);
625 gtk_widget_show(item);
626 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_xcontrol_dis), vtt);
627 if (vtt->x_par==NULL) item_to_activate=item;
629 list <tX_seqpar *> :: iterator sp;
631 for (sp=tX_seqpar::all->begin(); sp!=tX_seqpar::all->end(); sp++) {
632 if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt) {
633 item=gtk_check_menu_item_new_with_label((*sp)->get_name());
634 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_x), item);
635 gtk_widget_show(item);
636 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_xcontrol_set), (void*) (*sp));
638 if (vtt->x_par==(*sp)) item_to_activate=item;
642 if (item_to_activate) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_to_activate), TRUE);
644 /* Filling the Y menu */
645 item_to_activate=NULL;
647 item = gtk_check_menu_item_new_with_label("Disable");
648 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_y), item);
649 gtk_widget_show(item);
650 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_ycontrol_dis), vtt);
651 if (vtt->y_par==NULL) item_to_activate=item;
653 for (sp=tX_seqpar::all->begin(); sp!=tX_seqpar::all->end(); sp++) {
654 if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt) {
655 item=gtk_check_menu_item_new_with_label((*sp)->get_name());
656 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.mouse_mapping_menu_y), item);
657 gtk_widget_show(item);
658 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_ycontrol_set), (void*) (*sp));
660 if (vtt->y_par==(*sp)) item_to_activate=item;
664 if (item_to_activate) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_to_activate), TRUE);
666 gtk_menu_item_set_submenu(GTK_MENU_ITEM(x_item), vtt->gui.mouse_mapping_menu_x);
667 gtk_menu_item_set_submenu(GTK_MENU_ITEM(y_item), vtt->gui.mouse_mapping_menu_y);
668 gtk_menu_popup (GTK_MENU(vtt->gui.mouse_mapping_menu), NULL, NULL, NULL, NULL, 0, 0);
670 g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
675 static gint vg_file_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt) {
676 if (vtt->gui.file_menu==NULL) {
679 vtt->gui.file_menu=gtk_menu_new();
680 item=gtk_menu_item_new_with_label("Load audio file");
681 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
682 gtk_widget_show(item);
684 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(load_file), vtt);
686 item=gtk_menu_item_new_with_label("Edit audio file");
687 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
688 gtk_widget_show(item);
690 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_vtt_buffer), vtt);
692 item=gtk_menu_item_new_with_label("Reload current audio file");
693 gtk_menu_shell_append(GTK_MENU_SHELL(vtt->gui.file_menu), item);
694 gtk_widget_show(item);
696 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(reload_vtt_buffer), vtt);
699 gtk_menu_popup(GTK_MENU(vtt->gui.file_menu), NULL, NULL, NULL, NULL, 0,0);
700 /* gtk+ is really waiting for this.. */
701 g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
706 void vg_adjust_zoom(GtkWidget *wid, vtt_class *vtt) {
707 GtkAdjustment *adj=gtk_range_get_adjustment(GTK_RANGE(vtt->gui.zoom));
708 gtk_tx_set_zoom(GTK_TX(vtt->gui.display), adj->value/100.0);
711 static gint fx_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt)
713 vtt_gui *g=&vtt->gui;
715 LADSPA_Class::set_current_vtt(vtt);
717 if (g->ladspa_menu) gtk_object_destroy(GTK_OBJECT(g->ladspa_menu));
718 g->ladspa_menu=LADSPA_Class::get_ladspa_menu();
719 gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
721 /* gtk+ is really waiting for this.. */
722 g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
727 static gint stereo_fx_button_pressed(GtkWidget *wid, GdkEventButton *event, vtt_class *vtt)
729 vtt_gui *g=&vtt->gui;
731 LADSPA_Class::set_current_vtt(vtt);
733 if (g->ladspa_menu) gtk_object_destroy(GTK_OBJECT(g->ladspa_menu));
734 g->ladspa_menu=LADSPA_Class::get_stereo_ladspa_menu();
735 gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
737 /* gtk+ is really waiting for this.. */
738 g_signal_emit_by_name(G_OBJECT(wid), "released", vtt);
743 #define TOOLTIP_LENGTH 2048
745 void gui_set_name(vtt_class *vtt, char *newname)
748 strcpy(bold_name, "<b>");
749 strcat(bold_name, newname);
750 strcat(bold_name, "</b>");
752 gtk_label_set_markup(GTK_LABEL(vtt->gui.audio_label), bold_name);
753 gtk_label_set_markup(GTK_LABEL(vtt->gui.control_label), bold_name);
754 gtk_entry_set_text(GTK_ENTRY(vtt->gui.name), newname);
757 if (vtt->gui.audio_minimized_panel_bar_button!=NULL) {
758 gtk_label_set_text(GTK_LABEL(vtt->gui.audio_minimized_panel_bar_label), newname);
759 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" audio panel.", newname);
760 gui_set_tooltip(vtt->gui.audio_minimized_panel_bar_button, tooltip);
763 if (vtt->gui.control_minimized_panel_bar_button!=NULL) {
764 gtk_label_set_text(GTK_LABEL(vtt->gui.control_minimized_panel_bar_label), newname);
765 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" control panel.", newname);
766 gui_set_tooltip(vtt->gui.control_minimized_panel_bar_button, tooltip);
770 #define connect_entry(wid, func); g_signal_connect(G_OBJECT(g->wid), "activate", G_CALLBACK(func), (void *) vtt);
771 #define connect_adj(wid, func); g_signal_connect(G_OBJECT(g->wid), "value_changed", G_CALLBACK(func), (void *) vtt);
772 #define connect_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "clicked", G_CALLBACK(func), (void *) vtt);
773 #define connect_range(wid, func); g_signal_connect(G_OBJECT(gtk_range_get_adjustment(GTK_RANGE(g->wid))), "value_changed", G_CALLBACK(func), (void *) vtt);
774 #define connect_scale_format(wid, func); g_signal_connect(G_OBJECT(g->wid), "format-value", G_CALLBACK(func), (void *) vtt);
775 #define connect_press_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "button_press_event", G_CALLBACK(func), (void *) vtt);
776 #define connect_rel_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "released", G_CALLBACK(func), (void *) vtt);
778 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel);
782 void gui_connect_signals(vtt_class *vtt)
784 vtt_gui *g=&vtt->gui;
785 strncpy(dnd_uri, "text/uri-list", 128);
787 connect_entry(name, name_changed);
788 connect_adj(volume, volume_changed);
789 connect_adj(pitch, pitch_changed);
790 connect_adj(pan, pan_changed);
791 connect_press_button(file, vg_file_button_pressed);
793 connect_button(del, delete_vtt);
794 connect_button(trigger, trigger_vtt);
795 connect_button(stop, stop_vtt);
796 connect_button(autotrigger, autotrigger_toggled);
797 connect_button(loop, loop_toggled);
798 connect_button(sync_master, master_setup);
799 connect_button(sync_client, client_setup);
800 connect_button(adjust_button, vg_adjust_pitch_vtt);
801 connect_adj(cycles, client_setup_number);
802 connect_press_button(fx_button, fx_button_pressed);
803 connect_press_button(stereo_fx_button, stereo_fx_button_pressed);
805 connect_button(lp_enable, lp_enabled);
806 connect_adj(lp_gain, lp_gain_changed);
807 connect_adj(lp_reso, lp_reso_changed);
808 connect_adj(lp_freq, lp_freq_changed);
810 connect_button(ec_enable, ec_enabled);
811 #ifdef USE_ALSA_MIDI_IN
812 connect_button(midi_mapping, midi_mapping_clicked);
814 connect_adj(ec_length, ec_length_changed);
815 connect_adj(ec_feedback, ec_feedback_changed);
816 connect_adj(ec_pan, ec_pan_changed);
817 connect_adj(ec_volume, ec_volume_changed);
818 connect_range(zoom, vg_adjust_zoom);
819 //connect_scale_format(zoom, vg_format_zoom);
820 connect_press_button(mouse_mapping, vg_mouse_mapping_pressed);
821 connect_button(control_minimize, minimize_control_panel);
822 connect_button(audio_minimize, minimize_audio_panel);
824 static GtkTargetEntry drop_types [] = {
827 static gint n_drop_types = sizeof (drop_types) / sizeof(drop_types[0]);
829 gtk_drag_dest_set (GTK_WIDGET (g->file), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
830 drop_types, n_drop_types,
833 g_signal_connect (G_OBJECT (g->file), "drag_data_received",
834 G_CALLBACK(drop_file), (void *) vtt);
836 gtk_drag_dest_set (GTK_WIDGET (g->display), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
837 drop_types, n_drop_types,
840 g_signal_connect (G_OBJECT (g->display), "drag_data_received",
841 G_CALLBACK(drop_file), (void *) vtt);
845 void build_vtt_gui(vtt_class *vtt)
860 /* Building Audio Box */
861 g->audio_box=gtk_vbox_new(FALSE,2);
862 gtk_widget_show(g->audio_box);
864 tempbox2=gtk_hbox_new(FALSE,2);
865 gtk_widget_show(tempbox2);
866 gtk_box_pack_start(GTK_BOX(g->audio_box), tempbox2, WID_FIX);
868 tempbox=gtk_hbox_new(TRUE,2);
869 gtk_widget_show(tempbox);
870 gtk_box_pack_start(GTK_BOX(tempbox2), tempbox, WID_DYN);
873 g->audio_minimize=gtk_button_new();
874 pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
875 gtk_container_add (GTK_CONTAINER (g->audio_minimize), pixmap);
876 gtk_box_pack_end(GTK_BOX(tempbox2), g->audio_minimize, WID_FIX);
877 gtk_widget_show(pixmap);
878 gtk_widget_show(g->audio_minimize);
881 g->audio_label=gtk_label_new(vtt->name);
882 gtk_misc_set_alignment(GTK_MISC(g->audio_label), 0.025, 0.5);
883 gtk_widget_show(g->audio_label);
884 gtk_box_pack_start(GTK_BOX(tempbox), g->audio_label, WID_DYN);
886 nicer_filename(nice_name, vtt->filename);
887 g->file = gtk_button_new_with_label(nice_name);
888 gtk_widget_show(g->file);
889 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.");
890 gtk_box_pack_start(GTK_BOX(tempbox), g->file, WID_DYN);
892 g->mouse_mapping=gtk_button_new_with_label("Mouse");
893 gtk_widget_show(g->mouse_mapping);
894 gui_set_tooltip(g->mouse_mapping, "Determines what parameters should be affected on mouse motion in mouse grab mode.");
895 gtk_box_pack_start(GTK_BOX(tempbox2), g->mouse_mapping, WID_FIX);
897 #ifdef USE_ALSA_MIDI_IN
898 g->midi_mapping=gtk_button_new_with_label("MIDI");
899 gtk_widget_show(g->midi_mapping);
900 gui_set_tooltip(g->midi_mapping, "Determines what parameters should be bound to what MIDI events.");
901 gtk_box_pack_start(GTK_BOX(tempbox2), g->midi_mapping, WID_FIX);
903 if (!tX_engine::get_instance()->get_midi()->get_is_open()) {
904 gtk_widget_set_sensitive(g->midi_mapping, FALSE);
908 tempbox=gtk_hbox_new(FALSE, 2);
910 g->display=gtk_tx_new(vtt->buffer, vtt->samples_in_buffer);
911 gtk_box_pack_start(GTK_BOX(tempbox), g->display, WID_DYN);
912 gtk_widget_show(g->display);
914 g->zoom=gtk_vscale_new_with_range(0,99.0,1.0);
915 gtk_range_set_inverted(GTK_RANGE(g->zoom), TRUE);
916 gtk_scale_set_draw_value(GTK_SCALE(g->zoom), TRUE);
917 gtk_scale_set_digits(GTK_SCALE(g->zoom), 0);
918 gtk_scale_set_value_pos(GTK_SCALE(g->zoom), GTK_POS_BOTTOM);
919 gtk_adjustment_set_value(gtk_range_get_adjustment(GTK_RANGE(g->zoom)), 0);
921 gui_set_tooltip(g->zoom, "Set the zoom-level for the audio data display.");
922 gtk_box_pack_start(GTK_BOX(tempbox), g->zoom, WID_FIX);
923 gtk_widget_show(g->zoom);
925 gtk_box_pack_start(GTK_BOX(g->audio_box), tempbox, WID_DYN);
926 gtk_widget_show(tempbox);
928 /* Building Control Box */
930 g->control_box=gtk_vbox_new(FALSE,2);
931 gtk_widget_show(g->control_box);
933 tempbox2=gtk_hbox_new(FALSE, 2);
934 gtk_widget_show(tempbox2);
935 gtk_box_pack_start(GTK_BOX(g->control_box), tempbox2, WID_FIX);
937 g->control_label=gtk_label_new(vtt->name);
938 gtk_widget_show(g->control_label);
939 gtk_box_pack_start(GTK_BOX(tempbox2), g->control_label, WID_DYN);
941 g->control_minimize=gtk_button_new();
942 pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
943 gtk_container_add (GTK_CONTAINER (g->control_minimize), pixmap);
944 gtk_box_pack_end(GTK_BOX(tempbox2), g->control_minimize, WID_FIX);
945 gtk_widget_show(pixmap);
946 gtk_widget_show(g->control_minimize);
948 g->scrolled_win=gtk_scrolled_window_new (NULL, NULL);
949 gtk_container_set_border_width (GTK_CONTAINER (g->scrolled_win), 0);
950 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (g->scrolled_win),
951 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
952 gtk_widget_show(g->scrolled_win);
953 gtk_box_pack_start(GTK_BOX(g->control_box), g->scrolled_win, WID_DYN);
955 g->control_subbox=gtk_vbox_new(FALSE,0);
956 gtk_scrolled_window_add_with_viewport (
957 GTK_SCROLLED_WINDOW (g->scrolled_win), g->control_subbox);
958 gtk_widget_show(g->control_subbox);
963 tX_panel *p=new tX_panel("Main", g->control_subbox);
966 g->name = gtk_entry_new();
967 gtk_entry_set_max_length(GTK_ENTRY(g->name), 256);
968 gtk_entry_set_text(GTK_ENTRY(g->name), vtt->name);
969 p->add_client_widget(g->name);
970 gui_set_tooltip(g->name, "Enter the turntable's name here.");
971 gtk_widget_set_size_request(g->name, 40, -1);
973 g->del=gtk_button_new_with_label("Delete");
974 gui_set_tooltip(g->del, "Click here to annihilate this turntable. All events recorded for this turntable will be erased, too.");
975 p->add_client_widget(g->del);
977 g->adjust_button=gtk_button_new_with_label("Pitch Adj.");
978 gui_set_tooltip(g->adjust_button, "Activate this button to adjust this turntable's speed to the master turntable's speed.");
979 p->add_client_widget(g->adjust_button);
981 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
983 p=new tX_panel("Playback", g->control_subbox);
986 g->trigger=gtk_button_new_with_label("Trigger!");
987 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.");
988 p->add_client_widget(g->trigger);
990 g->stop=gtk_button_new_with_label("Stop.");
991 gui_set_tooltip(g->stop, "Stop this turntable's playback.");
992 p->add_client_widget(g->stop);
993 g_signal_connect(G_OBJECT(g->trigger), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_trigger);
994 g_signal_connect(G_OBJECT(g->stop), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_trigger);
996 g->autotrigger=gtk_check_button_new_with_label("Auto");
997 p->add_client_widget(g->autotrigger);
998 gui_set_tooltip(g->autotrigger, "If turned on, this turntable will be automagically triggered whenever the audio engine is turned on.");
999 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autotrigger), vtt->autotrigger);
1001 g->loop=gtk_check_button_new_with_label("Loop");
1002 p->add_client_widget(g->loop);
1003 gui_set_tooltip(g->loop, "Enable this option to make the turntable loop the audio data.");
1004 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->loop), vtt->loop);
1005 g_signal_connect(G_OBJECT(g->loop), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_loop);
1007 g->sync_master=gtk_check_button_new_with_label("Master");
1008 p->add_client_widget(g->sync_master);
1009 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.");
1010 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_master), vtt->is_sync_master);
1012 g->sync_client=gtk_check_button_new_with_label("Client");
1013 p->add_client_widget(g->sync_client);
1014 gui_set_tooltip(g->sync_client, "If enabled this turntable will be (re-)triggerd in relation to the sync-master turntable.");
1015 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_client), vtt->is_sync_client);
1016 g_signal_connect(G_OBJECT(g->sync_client), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_sync_client);
1018 g->cycles=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->sync_cycles, 0, 10.0, 1,1,0));
1019 dummy=gtk_spin_button_new(g->cycles, 1.0, 0);
1020 p->add_client_widget(dummy);
1021 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.");
1022 g_signal_connect(G_OBJECT(dummy), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_sync_cycles);
1024 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
1026 g->fx_box=gtk_vbox_new(FALSE,0);
1027 gtk_box_pack_start(GTK_BOX(g->control_subbox), g->fx_box, WID_FIX);
1028 gtk_widget_show(g->fx_box);
1030 dummy=gtk_button_new_with_label("FX");
1031 gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
1032 gtk_widget_show(dummy);
1034 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.");
1035 gtk_box_pack_start(GTK_BOX(g->fx_box), dummy, WID_FIX);
1039 p=new tX_panel("Lowpass", g->fx_box);
1040 g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", G_CALLBACK(vg_show_fx_menu), vtt->lp_fx);
1043 g->lp_enable=gtk_check_button_new_with_label("Enable");
1044 gui_set_tooltip(g->lp_enable, "Click here to enable the built-in lowpass effect.");
1045 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->lp_enable), vtt->lp_enable);
1046 p->add_client_widget(vg_create_fx_bar(vtt, vtt->lp_fx, 0));
1047 g_signal_connect(G_OBJECT(g->lp_enable), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_lp_enable);
1049 p->add_client_widget(g->lp_enable);
1051 g->lp_gain=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_gain, 0, 2, 0.1, 0.01, 0.01));
1052 g->lp_reso=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_reso, 0, 0.99, 0.1, 0.01, 0.01));
1053 g->lp_freq=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_freq, 0, 1, 0.1, 0.01, 0.01));
1055 g->lp_gaind=new tX_extdial("Input Gain", g->lp_gain, &vtt->sp_lp_gain);
1056 p->add_client_widget(g->lp_gaind->get_widget());
1057 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.");
1059 g->lp_freqd=new tX_extdial("Frequency", g->lp_freq, &vtt->sp_lp_freq);
1060 p->add_client_widget(g->lp_freqd->get_widget());
1061 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.");
1063 g->lp_resod=new tX_extdial("Resonance", g->lp_reso, &vtt->sp_lp_reso);
1064 p->add_client_widget(g->lp_resod->get_widget());
1065 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.");
1067 gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
1071 p=new tX_panel("Echo", g->fx_box);
1072 g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", G_CALLBACK(vg_show_fx_menu), vtt->ec_fx);
1075 p->add_client_widget(vg_create_fx_bar(vtt, vtt->ec_fx, 0));
1077 g->ec_enable=gtk_check_button_new_with_label("Enable");
1078 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->ec_enable), vtt->ec_enable);
1079 p->add_client_widget(g->ec_enable);
1080 gui_set_tooltip(g->ec_enable, "Enable the built-in echo effect.");
1081 g_signal_connect(G_OBJECT(g->ec_enable), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_ec_enable);
1083 g->ec_length=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_length, 0, 1, 0.1, 0.01, 0.001));
1084 g->ec_feedback=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_feedback, 0, 1, 0.1, 0.01, 0.001));
1085 g->ec_pan=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_pan, -1.0, 1, 0.1, 0.01, 0.001));
1086 g->ec_volume=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_volume, 0.0, 3.0, 0.1, 0.01, 0.001));
1088 g->ec_lengthd=new tX_extdial("Duration", g->ec_length, &vtt->sp_ec_length);
1089 p->add_client_widget(g->ec_lengthd->get_widget());
1090 gui_set_tooltip(g->ec_lengthd->get_entry(), "Adjust the length of the echo buffer.");
1092 g->ec_feedbackd=new tX_extdial("Feedback", g->ec_feedback, &vtt->sp_ec_feedback);
1093 p->add_client_widget(g->ec_feedbackd->get_widget());
1094 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.");
1096 g->ec_volumed=new tX_extdial("Volume", g->ec_volume, &vtt->sp_ec_volume);
1097 p->add_client_widget(g->ec_volumed->get_widget());
1098 gui_set_tooltip(g->ec_volumed->get_entry(), "Adjust the volume of the echo effect.");
1100 g->ec_pand=new tX_extdial("Pan", g->ec_pan, &vtt->sp_ec_pan);
1101 p->add_client_widget(g->ec_pand->get_widget());
1102 gui_set_tooltip(g->ec_pand->get_entry(), "Adjust the panning of the echo effect.");
1104 gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
1106 g->stereo_fx_box=gtk_vbox_new(FALSE, 0);
1107 gtk_box_pack_start(GTK_BOX(g->control_subbox), g->stereo_fx_box, WID_FIX);
1108 gtk_widget_show(g->stereo_fx_box);
1110 dummy=gtk_button_new_with_label("Stereo FX");
1111 gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
1112 gtk_widget_show(dummy);
1113 g->stereo_fx_button=dummy;
1114 gui_set_tooltip(g->stereo_fx_button, "Click here to load a stereo LADSPA plugin. You will get a menu from which you can choose which plugin to load.");
1115 gtk_box_pack_start(GTK_BOX(g->stereo_fx_box), dummy, WID_FIX);
1119 tempbox=gtk_hbox_new(FALSE,2);
1120 gtk_widget_show(tempbox);
1121 gtk_box_pack_end(GTK_BOX(g->control_box), tempbox, WID_FIX);
1123 tempbox2=gtk_vbox_new(FALSE,0);
1124 gtk_widget_show(tempbox2);
1125 gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
1127 g->pitch=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->rel_pitch, -3, +3, 0.1, 0.01, 0.001));
1128 g->pan=GTK_ADJUSTMENT(gtk_adjustment_new(0, -1, 1, 0.1, 0.01, 0.001));
1130 g->pitchd=new tX_extdial("Pitch", g->pitch, &vtt->sp_pitch);
1131 gui_set_tooltip(g->pitchd->get_entry(), "Adjust this turntable's pitch.");
1133 gtk_box_pack_start(GTK_BOX(tempbox2), g->pitchd->get_widget(), WID_FIX);
1135 g->pand=new tX_extdial("Pan", g->pan, &vtt->sp_pan);
1136 gtk_box_pack_start(GTK_BOX(tempbox2), g->pand->get_widget(), WID_FIX);
1137 gui_set_tooltip(g->pand->get_entry(), "Specifies the position of this turntable within the stereo spectrum: -1 -> left, 0-> center, 1->right.");
1139 tempbox3=gtk_hbox_new(FALSE,2);
1140 gtk_widget_show(tempbox3);
1142 g->mute=gtk_check_button_new_with_label("M");
1143 gtk_box_pack_start(GTK_BOX(tempbox3), g->mute, WID_FIX);
1144 g_signal_connect(G_OBJECT(g->mute),"clicked", (GtkSignalFunc) mute_volume, vtt);
1145 gtk_widget_show(g->mute);
1146 gui_set_tooltip(g->mute, "Mute this turntable's mixer output.");
1148 g->solo=gtk_check_button_new_with_label("S");
1149 gtk_box_pack_start(GTK_BOX(tempbox3), g->solo, WID_FIX);
1150 g_signal_connect(G_OBJECT(g->solo),"clicked", (GtkSignalFunc) solo_vtt, vtt);
1151 gtk_widget_show(g->solo);
1152 gui_set_tooltip(g->solo, "Allow only this and other solo-switched turntabels' signal to be routed to the mixer.");
1154 gtk_box_pack_start(GTK_BOX(tempbox2), tempbox3, WID_FIX);
1156 tempbox2=gtk_hbox_new(FALSE,0);
1157 gtk_widget_show(tempbox2);
1158 gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
1160 g->volume=GTK_ADJUSTMENT(gtk_adjustment_new(2.0-vtt->rel_volume, 0, 2, 0.01, 0.01, 0.01));
1161 dummy=gtk_vscale_new(GTK_ADJUSTMENT(g->volume));
1162 gtk_scale_set_draw_value(GTK_SCALE(dummy), False);
1163 gui_set_tooltip(dummy, "Adjust this turntable's volume.");
1164 g_signal_connect(G_OBJECT(dummy), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &vtt->sp_volume);
1166 gtk_box_pack_start(GTK_BOX(tempbox2), dummy, WID_FIX);
1167 gtk_widget_show(dummy);
1169 g->flash=gtk_tx_flash_new();
1170 gtk_box_pack_start(GTK_BOX(tempbox2), g->flash, WID_FIX);
1171 gtk_widget_show(g->flash);
1173 #ifndef USE_FILECHOOSER
1174 g->file_dialog=NULL;
1176 gui_connect_signals(vtt);
1178 g->audio_minimized_panel_bar_button=NULL;
1179 g->control_minimized_panel_bar_button=NULL;
1181 g->mouse_mapping_menu=NULL;
1182 g->mouse_mapping_menu_x=NULL;
1183 g->mouse_mapping_menu_y=NULL;
1185 g->adjust_dialog=NULL;
1187 gui_set_name(vtt, vtt->name);
1190 void fx_up(GtkWidget *wid, vtt_fx *effect)
1194 vtt=(vtt_class*)effect->get_vtt();
1195 vtt->effect_up(effect);
1198 void fx_down(GtkWidget *wid, vtt_fx *effect)
1202 vtt=(vtt_class*)effect->get_vtt();
1203 vtt->effect_down(effect);
1206 void fx_kill(GtkWidget *wid, vtt_fx_ladspa *effect)
1210 vtt=(vtt_class*)effect->get_vtt();
1211 vtt->effect_remove(effect);
1214 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel)
1220 box=gtk_hbox_new(FALSE,0);
1223 button=gtk_button_new();
1224 pixmap=tx_pixmap_widget(FX_CLOSE);
1225 gtk_container_add (GTK_CONTAINER (button), pixmap);
1226 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1227 gtk_widget_show(pixmap);
1228 gtk_widget_show(button);
1229 g_signal_connect(G_OBJECT(button), "clicked", (GtkSignalFunc) fx_kill, (void *) effect);
1232 button=gtk_button_new();
1233 pixmap=tx_pixmap_widget(FX_DOWN);
1234 gtk_container_add (GTK_CONTAINER (button), pixmap);
1235 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1236 gtk_widget_show(pixmap);
1237 gtk_widget_show(button);
1238 g_signal_connect(G_OBJECT(button), "clicked", (GtkSignalFunc) fx_down, (void *) effect);
1240 button=gtk_button_new();
1241 pixmap=tx_pixmap_widget(FX_UP);
1242 gtk_container_add (GTK_CONTAINER (button), pixmap);
1243 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
1244 gtk_widget_show(pixmap);
1245 gtk_widget_show(button);
1246 g_signal_connect(G_OBJECT(button), "clicked", (GtkSignalFunc) fx_up, (void *) effect);
1248 gtk_widget_show(box);
1253 int gtk_box_get_widget_pos(GtkBox *box, GtkWidget *child)
1258 list = box->children;
1261 GtkBoxChild *child_info;
1262 child_info = (GtkBoxChild *) list->data;
1263 if (child_info->widget == child)
1265 list = list->next; i++;
1270 void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt, bool stereo)
1272 GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
1273 int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
1274 gtk_box_reorder_child(GTK_BOX(box), wid, pos-1);
1277 void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt, bool stereo)
1279 GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
1280 int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
1281 gtk_box_reorder_child(GTK_BOX(box), wid, pos+1);
1284 static gint vg_show_fx_info(GtkWidget *wid, vtt_fx *effect)
1286 tx_l_note(effect->get_info_string());
1290 void vg_toggle_drywet(GtkWidget *wid, vtt_fx *effect)
1292 effect->toggle_drywet();
1295 static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect)
1297 if (event->button==3) {
1298 GtkWidget *menu=gtk_menu_new();
1299 GtkWidget *item=gtk_menu_item_new_with_label("View Plugin Details");
1300 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1301 gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
1302 gtk_widget_show(item);
1303 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_show_fx_info), effect);
1305 switch (effect->has_drywet_feature()) {
1306 case (NOT_DRYWET_CAPABLE):
1307 item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
1308 gtk_widget_set_sensitive(item, FALSE);
1310 case (DRYWET_ACTIVE):
1311 item=gtk_menu_item_new_with_label("Remove Dry/Wet Control");
1313 case (DRYWET_AVAILABLE):
1314 item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
1318 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_toggle_drywet), effect);
1319 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1320 gtk_widget_show(item);
1322 item = gtk_menu_item_new();
1323 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1324 gtk_widget_set_sensitive(item, FALSE);
1325 gtk_widget_show(item);
1327 item=gtk_menu_item_new_with_label("Up");
1328 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1329 gtk_widget_show(item);
1330 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_up), effect);
1332 item=gtk_menu_item_new_with_label("Down");
1333 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1334 gtk_widget_show(item);
1335 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_down), effect);
1337 item=gtk_menu_item_new_with_label("Delete");
1338 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1339 gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
1340 gtk_widget_show(item);
1341 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_kill), effect);
1343 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
1345 /* gtk+ is really waiting for this.. */
1346 g_signal_emit_by_name(G_OBJECT(wid), "released", effect);
1352 void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin)
1359 list <tX_seqpar_vttfx *> :: iterator sp;
1361 strcpy(buffer, plugin->getLabel());
1362 if (strlen(buffer) > 6) {
1369 p=new tX_panel(buffer, g->control_subbox);
1371 p->add_client_widget(vg_create_fx_bar(vtt, effect, 1));
1373 for (sp = effect->controls.begin(); sp != effect->controls.end(); sp++) {
1374 p->add_client_widget((*sp)->get_widget());
1377 g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", (GtkSignalFunc) vg_show_fx_menu, (void *) effect);
1378 gui_set_tooltip(p->get_labelbutton(), "Right-click to access menu.");
1379 effect->set_panel_widget(p->get_widget());
1380 effect->set_panel(p);
1382 gtk_box_pack_start(GTK_BOX((effect->is_stereo() ? g->stereo_fx_box : g->fx_box)), p->get_widget(), WID_FIX);
1385 void gui_set_filename (vtt_class *vtt, char *newname)
1387 gtk_button_set_label(GTK_BUTTON(vtt->gui.file), newname);
1390 void gui_update_display(vtt_class *vtt)
1392 nicer_filename(global_filename_buffer, vtt->filename);
1393 gtk_button_set_label(GTK_BUTTON(vtt->gui.file), global_filename_buffer);
1394 gtk_tx_set_data(GTK_TX(vtt->gui.display), vtt->buffer, vtt->samples_in_buffer);
1397 void gui_hide_control_panel(vtt_class *vtt, bool hide) {
1401 gtk_widget_hide(vtt->gui.control_box);
1402 vtt->gui.control_minimized_panel_bar_button=tx_xpm_button_new(MIN_CONTROL, vtt->name, 0, &vtt->gui.control_minimized_panel_bar_label);
1403 g_signal_connect(G_OBJECT(vtt->gui.control_minimized_panel_bar_button), "clicked", (GtkSignalFunc) unminimize_control_panel, vtt);
1404 gtk_widget_show(vtt->gui.control_minimized_panel_bar_button);
1405 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" control panel.", vtt->name);
1406 gui_set_tooltip(vtt->gui.control_minimized_panel_bar_button, tooltip);
1407 add_to_panel_bar(vtt->gui.control_minimized_panel_bar_button);
1409 gtk_widget_show(vtt->gui.control_box);
1410 remove_from_panel_bar(vtt->gui.control_minimized_panel_bar_button);
1411 if (!tX_shutdown) gtk_widget_destroy(vtt->gui.control_minimized_panel_bar_button);
1412 vtt->gui.control_minimized_panel_bar_button=NULL;
1416 void gui_hide_audio_panel(vtt_class *vtt, bool hide) {
1420 gtk_widget_hide(vtt->gui.audio_box);
1421 vtt->gui.audio_minimized_panel_bar_button=tx_xpm_button_new(MIN_AUDIO, vtt->name, 0, &vtt->gui.audio_minimized_panel_bar_label);
1422 g_signal_connect(G_OBJECT(vtt->gui.audio_minimized_panel_bar_button), "clicked", (GtkSignalFunc) unminimize_audio_panel, vtt);
1423 gtk_widget_show(vtt->gui.audio_minimized_panel_bar_button);
1424 snprintf(tooltip, TOOLTIP_LENGTH, "Show \"%s\" audio panel.", vtt->name);
1425 gui_set_tooltip(vtt->gui.audio_minimized_panel_bar_button, tooltip);
1426 add_to_panel_bar(vtt->gui.audio_minimized_panel_bar_button);
1428 gtk_widget_show(vtt->gui.audio_box);
1429 remove_from_panel_bar(vtt->gui.audio_minimized_panel_bar_button);
1430 if (!tX_shutdown) gtk_widget_destroy(vtt->gui.audio_minimized_panel_bar_button);
1431 vtt->gui.audio_minimized_panel_bar_button=NULL;
1435 void delete_gui(vtt_class *vtt)
1437 if (vtt->gui.control_minimized_panel_bar_button!=NULL) gui_hide_control_panel(vtt, false);
1438 if (vtt->gui.audio_minimized_panel_bar_button!=NULL) gui_hide_audio_panel(vtt, false);
1440 delete vtt->gui.main_panel;
1441 delete vtt->gui.trigger_panel;
1443 delete vtt->gui.pitchd;
1444 delete vtt->gui.pand;
1446 delete vtt->gui.lp_gaind;
1447 delete vtt->gui.lp_resod;
1448 delete vtt->gui.lp_freqd;
1449 delete vtt->gui.lp_panel;
1451 delete vtt->gui.ec_lengthd;
1452 delete vtt->gui.ec_feedbackd;
1453 delete vtt->gui.ec_volumed;
1454 delete vtt->gui.ec_pand;
1455 delete vtt->gui.ec_panel;
1457 gtk_widget_destroy(vtt->gui.control_box);
1458 gtk_widget_destroy(vtt->gui.audio_box);
1459 if (vtt->gui.file_menu) gtk_widget_destroy(vtt->gui.file_menu);
1460 if (vtt->gui.mouse_mapping_menu) gtk_widget_destroy(vtt->gui.mouse_mapping_menu);
1461 if (vtt->gui.ladspa_menu) gtk_widget_destroy(vtt->gui.ladspa_menu);
1464 void cleanup_vtt(vtt_class *vtt)
1466 gtk_tx_cleanup_pos_display(GTK_TX(vtt->gui.display));
1467 gtk_tx_flash_set_level(vtt->gui.flash, 0.0, 0.0);
1468 gtk_tx_flash_clear(vtt->gui.flash);
1469 vtt->cleanup_required=false;
1472 void update_all_vtts()
1474 list <vtt_class *> :: iterator vtt;
1477 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1479 if ((*vtt)->is_playing) {
1480 gtk_tx_update_pos_display(GTK_TX((*vtt)->gui.display), (*vtt)->pos_i, (*vtt)->mute);
1481 temp=(*vtt)->max_value*(*vtt)->res_volume*vtt_class::vol_channel_adjust;
1482 temp2=(*vtt)->max_value2*(*vtt)->res_volume*vtt_class::vol_channel_adjust;
1483 // tX_msg("Setting value: %f, %f -> %f; %f, %f -> %f (%f)\n",
1484 // (*vtt)->max_value, (*vtt)->res_volume, temp,
1485 // (*vtt)->max_value2, (*vtt)->res_volume, temp2,
1486 // vtt_class::vol_channel_adjust
1488 gtk_tx_flash_set_level((*vtt)->gui.flash, temp, temp2);
1490 (*vtt)->max_value=0;
1491 (*vtt)->max_value2=0;
1494 if ((*vtt)->needs_cleaning_up()) {
1495 cleanup_vtt((*vtt));
1500 void cleanup_all_vtts()
1502 list <vtt_class *> :: iterator vtt;
1504 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1506 if ((*vtt)->buffer) gtk_tx_cleanup_pos_display(GTK_TX((*vtt)->gui.display));
1507 gtk_tx_flash_set_level((*vtt)->gui.flash, 0.0, 0.0);
1508 gtk_tx_flash_clear((*vtt)->gui.flash);
1512 void gui_clear_master_button(vtt_class *vtt)
1514 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_master), 0);
1517 void gui_show_frame(vtt_class *vtt, int show)
1519 gtk_tx_show_frame(GTK_TX(vtt->gui.display), show);
1522 #define vgui (*vtt)->gui
1525 void vg_enable_critical_buttons(int enable)
1527 list <vtt_class *> :: iterator vtt;
1528 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1530 gtk_widget_set_sensitive(vgui.del, enable);
1531 gtk_widget_set_sensitive(vgui.sync_master, enable);
1535 void vg_init_all_non_seqpars()
1537 list <vtt_class *> :: iterator vtt;
1539 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1541 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.autotrigger), (*vtt)->autotrigger);
1542 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.sync_master), (*vtt)->is_sync_master);
1546 f_prec gui_get_audio_x_zoom(vtt_class *vtt) {
1547 return gtk_tx_get_zoom(GTK_TX(vtt->gui.display));
1550 /* Yes, this is yet another evil hack. Fix it :) */
1551 int vttgui_zoom_depth=0;
1553 extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec value) {
1554 if (vttgui_zoom_depth==0) {
1555 vttgui_zoom_depth=1;
1556 gtk_range_set_value(GTK_RANGE(vtt->gui.zoom), value*100.0);
1557 vttgui_zoom_depth=0;
1559 gtk_tx_set_zoom(GTK_TX(vtt->gui.display), value);