Rework vttgui, old up/down buttons are gone, hello drag'n'drop!
authorAlexander Koenig <alex@lisas.de>
Mon, 24 Feb 2020 20:24:57 +0000 (21:24 +0100)
committerAlexander Koenig <alex@lisas.de>
Mon, 24 Feb 2020 20:24:57 +0000 (21:24 +0100)
12 files changed:
configure.ac
src/tX_mastergui.cc
src/tX_panel.cc
src/tX_panel.h
src/tX_pbutton.cc
src/tX_pbutton.h
src/tX_seqpar.h
src/tX_vtt.cc
src/tX_vtt.h
src/tX_vttfx.cc
src/tX_vttgui.cc
src/tX_vttgui.h

index bbcd45f17fba71d24a639a338f59f7fecf49fcf1..f9dc35182478898a96e812d40daf1b19fd1d1d93 100644 (file)
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT([terminatorX], [4.0.1], [https://terminatorX.org/bugs/], [terminatorX], [https://terminatorX.org])
+AC_INIT([terminatorX], [4.0.99], [https://terminatorX.org/bugs/], [terminatorX], [https://terminatorX.org])
 
 AC_CONFIG_SRCDIR([src/tX_global.h])
 AM_INIT_AUTOMAKE
index 581c87d4b9b67a07aea6662119e4b3c978bfdef3..7a5a258cd75a42d7326918ffccd0faccb2ea21a7 100644 (file)
@@ -1413,7 +1413,7 @@ void create_mastergui(int x, int y)
        gui_set_tooltip(dummy, "Enable recording of *events* into the sequencer. All touched controls will be recorded. Existing events for the song-time recording will be overwritten for touched controls.");
        gtk_widget_show(dummy);
 
-       gtk_box_pack_start(GTK_BOX(control_box), posLabel, WID_FIX);
+       gtk_box_pack_start(GTK_BOX(control_box), posLabel, WID_FIX_BREATHE);
        gtk_widget_show(posLabel);
        
        dummy=gtk_entry_new();
index 643e4798140fd53c2e7fe13dddd6bac021f6dc92..939675128d6524f020a9044a545cf4b086458214 100644 (file)
 /*
     terminatorX - realtime audio scratching software
     Copyright (C) 1999-2016  Alexander König
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
+
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
+
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */
-    
+
 #include "tX_panel.h"
+#include "tX_vttfx.h"
+#include "tX_vtt.h"
 #include "tX_pbutton.h"
+#include "tX_mastergui.h"
 #include <string.h>
 #include <stdio.h>
 
 #define WID_DYN TRUE, TRUE, 0
 #define WID_FIX FALSE, FALSE, 0
 
-void tX_panel :: minimize(GtkWidget *w, tX_panel *p)
-{
+static const GtkTargetEntry entries[] = { { "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 } };
+
+static vtt_fx *dragged_effect = NULL;
+static GtkWidget *dragged_list_box = NULL;
+
+void panel_begin_drag(GtkWidget* widget, GdkDragContext *context, gpointer data) {
+       dragged_effect = (vtt_fx *) data;
+
+       GtkWidget *row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
+       dragged_list_box = gtk_widget_get_ancestor(row, GTK_TYPE_LIST_BOX);
+       GtkAllocation allocation;
+       gtk_widget_get_allocation(row, &allocation);
+       cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
+       cairo_t *cr = cairo_create(surface);
+
+       gtk_style_context_add_class(gtk_widget_get_style_context(row), "dragging");
+       gtk_widget_draw(row, cr);
+       gtk_style_context_remove_class (gtk_widget_get_style_context(row), "dragging");
+
+       int x, y;
+       gtk_widget_translate_coordinates(widget, row, 0, 0, &x, &y);
+       cairo_surface_set_device_offset(surface, -x, -y);
+       gtk_drag_set_icon_surface(context, surface);
+
+       cairo_destroy(cr);
+       cairo_surface_destroy(surface);
+}
+
+void panel_get_drag_data(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, gpointer data) {
+       gtk_selection_data_set(selection_data, gdk_atom_intern_static_string("GTK_LIST_BOX_ROW"), 32, (const guchar *) &widget, sizeof(gpointer));
+}
+
+void panel_receive_drag_data(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint32 time, gpointer data) {
+       int pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(widget));
+       GtkWidget* list_box = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX);
+       GtkWidget* row = GTK_WIDGET((gpointer)* (gpointer*) gtk_selection_data_get_data(selection_data));
+       GtkWidget* source = gtk_widget_get_ancestor(row, GTK_TYPE_LIST_BOX_ROW);
+
+       if (list_box == dragged_list_box) {
+               if (source != widget) {
+                       g_object_ref (source);
+                       gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent (source)), source);
+                       gtk_list_box_insert(GTK_LIST_BOX(gtk_widget_get_parent (widget)), source, pos);
+                       if (dragged_effect) {
+                               vtt_class *vtt=(vtt_class*) dragged_effect->get_vtt();
+                               vtt->effect_move(dragged_effect, pos);
+                       }
+                       g_object_unref (source);
+               }
+       } else {
+               tx_note("Effects can be reordered within the\nsame <b>FX</b> or <b>Stereo FX</b> queue only.");
+       }
+       dragged_effect = NULL;
+       dragged_list_box = NULL;
+}
+
+void tX_panel :: minimize(GtkWidget *w, tX_panel *p) {
        if (!p->client_hidden) {
-               gtk_widget_hide(p->pixmap_min);
-               gtk_widget_show(p->pixmap_max);
+               gtk_widget_hide(p->minimize_button);
+               gtk_widget_show(p->maximize_button);
                gtk_widget_hide(p->clientframe);
                p->client_hidden=1;
        } else {
-               gtk_widget_hide(p->pixmap_max);
-               gtk_widget_show(p->pixmap_min);
+               gtk_widget_hide(p->maximize_button);
+               gtk_widget_show(p->minimize_button);
                gtk_widget_show(p->clientframe);
                p->client_hidden=0;
        }
-               
-       gboolean expand;
-       gboolean fill;
-       guint padding;
-       GtkPackType pack_type;
-               
-       if (p->container) {
-               gtk_box_query_child_packing(GTK_BOX(p->container), p->mainbox,
-               &expand, &fill, &padding, &pack_type);
-               gtk_box_set_child_packing(GTK_BOX(p->container), p->mainbox,
-               expand, fill, padding, pack_type);
-               gtk_container_check_resize(GTK_CONTAINER(p->container));                            
+
+       if (p->controlbox) {
+               gtk_widget_queue_draw(p->controlbox);
        }
 }
 
 void tX_panel_make_label_bold(GtkWidget *widget) {
-       char label[128];
-       sprintf(label, "<b>%s</b>", gtk_label_get_text(GTK_LABEL(widget)));
+       char label[4096];
+       snprintf(label, sizeof(label), "<b>%s</b>", gtk_label_get_text(GTK_LABEL(widget)));
        gtk_label_set_markup(GTK_LABEL (widget), label);
 }
 
-tX_panel :: tX_panel (const char *name, GtkWidget *par)
-{
+void tX_panel_make_tooltip(GtkWidget *widget, vtt_fx* effect) {
+       char label[4096];
+       snprintf(label, sizeof(label), "%s\n\nDrag this handle to reorder effects queue.", effect->get_info_string());
+       gtk_widget_set_tooltip_text(widget, label);
+}
+
+tX_panel :: tX_panel (const char *name, GtkWidget* controlbox, GCallback close_callback, vtt_fx *effect) {
        client_hidden=0;
-       
-       container=par;
-       minbutton=gtk_button_new();
-       pixmap_min=tx_pixmap_widget(MINIMIZE);
-       pixmap_max=tx_pixmap_widget(MAXIMIZE);
+       this->controlbox = controlbox;
+       add_drywet_button = NULL;
+       remove_drywet_button = NULL;
+
+       list_box_row = gtk_list_box_row_new();
+
+       drag_handle = gtk_event_box_new();
+
        labelbutton=gtk_label_new(name);
        gtk_widget_set_halign(labelbutton, GTK_ALIGN_START);
        tX_panel_make_label_bold(labelbutton);
-       button_box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
-              
-       gtk_box_pack_start(GTK_BOX(button_box), pixmap_min, WID_FIX);
-       gtk_box_pack_start(GTK_BOX(button_box), pixmap_max, WID_FIX);
-       gtk_box_pack_start(GTK_BOX(button_box), labelbutton, WID_DYN);
-
-       gtk_container_set_border_width(GTK_CONTAINER(button_box), 2);
-       
-       gtk_container_add (GTK_CONTAINER (minbutton), button_box);
+       gtk_container_add(GTK_CONTAINER(drag_handle), labelbutton);
+
+       topbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+       g_object_set(topbox, "margin-start", 10, "margin-end", 0,  "border-width", 0, NULL);
+       gtk_container_add_with_properties(GTK_CONTAINER (topbox), drag_handle, "expand", TRUE, NULL);
+
+       minimize_button=create_top_button(MINIMIZE);
+       gtk_container_add(GTK_CONTAINER(topbox), minimize_button);
+       maximize_button=create_top_button(MAXIMIZE);
+       gtk_container_add(GTK_CONTAINER(topbox), maximize_button);
+
+       if (close_callback) {
+               close_button = create_top_button(FX_CLOSE);
+               gtk_widget_set_name(close_button, "close");
+               g_object_set(close_button, "border-width", 0, NULL);
+               gtk_container_add(GTK_CONTAINER(topbox), close_button);
+       } else {
+               close_button = NULL;
+       }
+
+       gtk_container_set_border_width(GTK_CONTAINER(topbox), 0);
+
        mainbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-       
-       topbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-       clientbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+       gtk_container_add(GTK_CONTAINER(list_box_row), mainbox);
+
+       clientbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
        clientframe=gtk_frame_new((char *) NULL);
        gtk_container_set_border_width( GTK_CONTAINER(clientframe), 0);
        gtk_container_add(GTK_CONTAINER(clientframe), clientbox);
-       
+
        gtk_box_pack_start(GTK_BOX(mainbox), topbox, WID_FIX);
        gtk_box_pack_start(GTK_BOX(mainbox), clientframe, WID_FIX);
-       
-       gtk_box_pack_start(GTK_BOX(topbox), minbutton, WID_DYN);
-       
-       gtk_widget_show(pixmap_min);
-       gtk_widget_show(button_box);
+
        gtk_widget_show(labelbutton);
-       gtk_widget_show(minbutton);
+       gtk_widget_show(minimize_button);
        gtk_widget_show(topbox);
        gtk_widget_show(clientbox);
-       gtk_widget_show(clientframe);   
+       gtk_widget_show(clientframe);
        gtk_widget_show(mainbox);
-       
-       g_signal_connect(G_OBJECT(minbutton), "clicked", (GCallback) tX_panel::minimize, (void *) this);
+       gtk_widget_show(list_box_row);
+       gtk_widget_show(drag_handle);
+
+       if (close_callback) {
+               gtk_widget_show(close_button);
+               g_signal_connect(G_OBJECT(close_button), "clicked", (GCallback) close_callback, (gpointer) effect);
+       }
+
+       if (effect) {
+               tX_panel_make_tooltip(drag_handle, effect);
+
+               if (effect->has_drywet_feature() != NOT_DRYWET_CAPABLE) {
+                       add_drywet_button = create_top_button(ADD_DRYWET);
+                       remove_drywet_button = create_top_button(REMOVE_DRYWET);
+               }
+
+               gtk_drag_source_set(drag_handle, GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
+               g_signal_connect(drag_handle, "drag-begin", G_CALLBACK(panel_begin_drag), effect);
+               g_signal_connect(drag_handle, "drag-data-get", G_CALLBACK(panel_get_drag_data), NULL);
+
+               gtk_drag_dest_set(list_box_row, GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);
+               g_signal_connect(list_box_row, "drag-data-received", G_CALLBACK(panel_receive_drag_data), (gpointer) effect);
+       }
+
+       g_signal_connect(G_OBJECT(minimize_button), "clicked", (GCallback) tX_panel::minimize, (void *) this);
+       g_signal_connect(G_OBJECT(maximize_button), "clicked", (GCallback) tX_panel::minimize, (void *) this);
+
 }
 
 void tX_panel :: add_client_widget(GtkWidget *w)
@@ -114,7 +204,6 @@ void tX_panel :: add_client_widget(GtkWidget *w)
 
 tX_panel :: ~tX_panel()
 {
-       gtk_widget_destroy(minbutton);
        gtk_widget_destroy(clientbox);
        gtk_widget_destroy(clientframe);
        gtk_widget_destroy(topbox);
index ee783d015bc2dcb6af36706f42d47efdd111ca28..67fa0d108e15d8938a26d723b7dbd805618fda8f 100644 (file)
@@ -1,51 +1,61 @@
 /*
     terminatorX - realtime audio scratching software
     Copyright (C) 1999-2016  Alexander König
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
+
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
+
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-*/    
+*/
 
 #ifndef _h_tX_panel_
 #define _h_tX_panel_
 
 #include <gtk/gtk.h>
 
+class vtt_fx;
+
 class tX_panel
 {
-       GtkWidget *container;
+       GtkWidget *list_box_row;
+       GtkWidget *drag_handle;
        GtkWidget *mainbox;
-       GtkWidget *pixmap_min;
-       GtkWidget *pixmap_max;
        GtkWidget *topbox;
        GtkWidget *clientbox;
        GtkWidget *clientframe;
        GtkWidget *labelbutton;
-       GtkWidget *minbutton;
+       GtkWidget *minimize_button;
+       GtkWidget *maximize_button;
+       GtkWidget *close_button;
        GtkWidget *button_box;
+       GtkWidget *controlbox;
+       GtkWidget *add_drywet_button;
+       GtkWidget *remove_drywet_button;
        int client_hidden;
-               
+
        public:
-       tX_panel(const char *name, GtkWidget *par);
+       tX_panel(const char *name, GtkWidget *controlbox, GCallback close_callback = NULL, vtt_fx* effect = NULL);
        ~tX_panel();
-       
+
        GtkWidget *get_widget() {return mainbox;};
-       GtkWidget *get_labelbutton() {return minbutton;}
+       GtkWidget *get_list_box_row() {return list_box_row;};
+       GtkWidget *get_labelbutton() {return labelbutton;}
+       GtkWidget *get_add_drywet_button() { return add_drywet_button; }
+       GtkWidget *get_remove_drywet_button() { return remove_drywet_button; }
+
        void add_client_widget(GtkWidget *w);
        int is_hidden() { return client_hidden; }
-       void hide(int i) { client_hidden=i; tX_panel::minimize(NULL, this); } 
-       
+       void hide(int i) { client_hidden=i; tX_panel::minimize(NULL, this); }
+
        static void minimize(GtkWidget *w, tX_panel *p);
 };
 
index d8c2b0597394eab59df1db5580886aab4f1a7ba6..2356da06e784bc7deae0ca7901bfb931b5323e09 100644 (file)
@@ -35,28 +35,35 @@ const char* tx_icons[ALL_ICONS];
 
 int tx_icon_size=20;
 
-void tx_icons_init(int size) 
-{
+static const char tx_css[] = "#close:hover { background-color: #FF5555; color: #FFFFFF; }";
+
+void tx_icons_init(int size) {
        tx_icon_size=size;
 
        tx_icons[AUDIOENGINE] = "audio-speakers-symbolic";
        tx_icons[POWER] = "system-shutdown-symbolic";
-       tx_icons[GRAB] = "input-mouse-symbolic";        
+       tx_icons[GRAB] = "input-mouse-symbolic";
 
        tx_icons[SEQUENCER] = "emblem-music-symbolic";
-       
+
        tx_icons[PLAY] = "media-playback-start-symbolic";
        tx_icons[STOP] = "media-playback-stop-symbolic";
        tx_icons[RECORD] = "media-record-symbolic";
        tx_icons[MIN_AUDIO] = "audio-x-generic-symbolic";
        tx_icons[MIN_CONTROL] = "multimedia-volume-control-symbolic";
-       
-       tx_icons[MINIMIZE] = "go-top-symbolic";
-       tx_icons[MAXIMIZE] = "go-bottom-symbolic";
+
+       tx_icons[MINIMIZE] = "window-minimize-symbolic";
+       tx_icons[MAXIMIZE] = "view-more-symbolic";
        tx_icons[FX_UP] = "go-up-symbolic";
        tx_icons[FX_DOWN] = "go-down-symbolic";
        tx_icons[FX_CLOSE] = "window-close-symbolic";
-       tx_icons[MINIMIZE_PANEL] = "window-minimize-symbolic";
+       tx_icons[ADD_ITEM] = "list-add-symbolic";
+       tx_icons[ADD_DRYWET] = "list-add-symbolic";
+       tx_icons[REMOVE_DRYWET] = "list-remove-symbolic";
+
+       GtkCssProvider *provider = gtk_css_provider_new();
+       gtk_css_provider_load_from_data(provider, tx_css, -1, NULL);
+       gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 }
 
 GtkWidget *tx_pixmap_widget(tX_icon id)
@@ -69,7 +76,7 @@ GtkWidget *tx_xpm_label_box(tX_icon id, const gchar *label_text, GtkWidget **lab
        GtkWidget *box1;
        GtkWidget *label;
        GtkWidget *pixmapwid;
-       
+
        switch (globals.button_type) {
                case BUTTON_TYPE_TEXT:
                        label = gtk_label_new(label_text);
@@ -90,23 +97,31 @@ GtkWidget *tx_xpm_label_box(tX_icon id, const gchar *label_text, GtkWidget **lab
                        gtk_widget_show(pixmapwid);
                        label = gtk_label_new (label_text);
                        gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
-                       gtk_widget_show(label); 
+                       gtk_widget_show(label);
                        if (labelwidget!=NULL)  *labelwidget=label;
                        return box1;
-       }    
+       }
 }
 
 extern GtkWidget *tx_xpm_button_new(tX_icon id, const char *label, int toggle, GtkWidget **labelwidget)
 {
        GtkWidget *box;
        GtkWidget *button;
-       
+
        if (toggle) button=gtk_toggle_button_new();
        else button=gtk_button_new();
-       
+
        box=tx_xpm_label_box(id, label, labelwidget);
        gtk_widget_show(box);
-       gtk_container_add (GTK_CONTAINER (button), box);                
-       
+       gtk_container_add (GTK_CONTAINER (button), box);
+
        return(button);
 }
+
+GtkWidget* create_top_button(int icon_id) {
+        GtkWidget* button = gtk_button_new_from_icon_name(tx_icons[icon_id], GTK_ICON_SIZE_SMALL_TOOLBAR);
+        gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+        gtk_widget_set_margin_end(button, 0);
+        gtk_container_set_border_width(GTK_CONTAINER(button),0);
+        return button;
+}
index ef9421f44a0e1a42d88bccafb9d2890cddbedd22..401d6869e5e281773c0a296091a9f11485d00dc0 100644 (file)
@@ -38,12 +38,16 @@ typedef enum {
        FX_UP,
        FX_DOWN,
        FX_CLOSE,
-       MINIMIZE_PANEL,
+       ADD_ITEM,
+       ADD_DRYWET,
+       REMOVE_DRYWET,
        ALL_ICONS
 } tX_icon;
 
+extern const char* tx_icons[];
 extern GtkWidget *tx_pixmap_widget(tX_icon id);
 extern void tx_icons_init(int size);
+extern GtkWidget* create_top_button(int icon_id);
 extern GtkWidget *tx_xpm_label_box(tX_icon id, const gchar *label_text, GtkWidget **labelwidget=(GtkWidget **) NULL);
 extern GtkWidget *tx_xpm_button_new(tX_icon id, const char *label, int toggle, GtkWidget **labelwidget=(GtkWidget **) NULL);
 #endif
index e85d8820d46406d5f0f4a8ff13dd0d41f1b9b127..39e8f258d0777bc03981a214dfa0a541bc35026d 100644 (file)
@@ -423,6 +423,7 @@ class tX_seqpar_vttfx : public tX_seqpar_update
        tX_seqpar_vttfx();
        virtual ~tX_seqpar_vttfx();
        void set_name(const char *, const char *);
+       const char *get_label_name() { return label_name; }
        GtkWidget *get_widget() { return widget; } 
        
        virtual float get_value();
index d2462b6e5ac5a77df60c5465bb7f55b97af1410e..b2558ed06f971c99793789f71482e2f04d1eb484 100644 (file)
@@ -1,29 +1,29 @@
 /*
     terminatorX - realtime audio scratching software
     Copyright (C) 1999-2016  Alexander König
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
+
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
+
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
     File: tX_vtt.cc
+
     Description: This implements the new virtual turntable class. It replaces
                 the old turntable.c from terminatorX 3.2 and earlier. The lowpass
                 filter is based on some sample code by Paul Kellett
                 <paul.kellett@maxim.abel.co.uk>
-                
-    08 Dec 1999 - Switched to the new audiofile class           
-*/    
+
+    08 Dec 1999 - Switched to the new audiofile class
+*/
 
 #include "tX_vtt.h"
 #include "tX_global.h"
@@ -89,10 +89,10 @@ int vtt_class::mix_buffer_size=0;
 #define GAIN_AUTO_ADJUST 0.8
 
 vtt_class :: vtt_class (int do_create_gui)
-{      
+{
        vtt_amount++;
        cleanup_required=false;
-       
+
        sprintf (name, "Turntable %i", vtt_amount);
        strcpy(filename, "NONE");
        buffer=NULL;
@@ -174,8 +174,10 @@ vtt_class :: vtt_class (int do_create_gui)
        if (do_create_gui)
        {       
                build_vtt_gui(this);
-               lp_fx->set_panel_widget(gui.lp_panel->get_widget());    
+               lp_fx->set_panel_widget(gui.lp_panel->get_widget());
+               lp_fx->set_panel(gui.lp_panel);
                ec_fx->set_panel_widget(gui.ec_panel->get_widget());
+               ec_fx->set_panel(gui.ec_panel);
        }
        else have_gui=0;
                
@@ -1604,12 +1606,41 @@ void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
        if (fn) new_tt->load_file(fn);
 }
 
-extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt, bool stereo);
-extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt, bool stereo);
+extern void vg_move_fx_panel_up(tX_panel *panel, vtt_class *vtt, bool stereo);
+extern void vg_move_fx_panel_down(tX_panel *panel, vtt_class *vtt, bool stereo);
 
 //#define debug_fx_stack(); for (i=list->begin(); i != list->end(); i++) puts((*i)->get_info_string());
 #define debug_fx_stack();
 
+void vtt_class :: effect_move(vtt_fx *effect, int pos) {
+       list <vtt_fx *> :: iterator i;
+       list <vtt_fx *> :: iterator previous;
+       list <vtt_fx *> *list;
+       int ctr = 0;
+
+       if (effect->is_stereo()) {
+               list=(std::list <vtt_fx *> *) &stereo_fx_list;
+       } else {
+               list=&fx_list;
+       }
+
+       if (pos == 0) {
+           list->remove(effect);
+           list->push_front(effect);
+       } else if (pos == list->size() - 1) {
+           list->remove(effect);
+           list->push_back(effect);
+       } else {
+               list->remove(effect);
+               for (previous = i = list->begin(), ctr = 0; ctr <= pos; i++, ctr++) {
+                   previous = i;
+               }
+               list->insert(previous, effect);
+       }
+    debug_fx_stack();
+}
+
+
 void vtt_class :: effect_up(vtt_fx *effect)
 {
        list <vtt_fx *> :: iterator i;
@@ -1641,7 +1672,7 @@ void vtt_class :: effect_up(vtt_fx *effect)
                list->insert(previous, effect);
                pthread_mutex_unlock(&render_lock);
 
-               vg_move_fx_panel_up(effect->get_panel_widget(), this, effect->is_stereo());
+               vg_move_fx_panel_up(effect->get_panel(), this, effect->is_stereo());
        }
        
        debug_fx_stack();
@@ -1677,7 +1708,7 @@ void vtt_class :: effect_down(vtt_fx *effect)
                list->remove(effect);
                
                list->insert(i, effect);
-               vg_move_fx_panel_down(effect->get_panel_widget(), this, effect->is_stereo());
+               vg_move_fx_panel_down(effect->get_panel(), this, effect->is_stereo());
                pthread_mutex_unlock(&render_lock);
        }
        
index f8179d2e06f1e36801bf6d866aef62e027c1ee7d..9d97843814d2ae7661fde4ab7f42da9ac346e2f5 100644 (file)
@@ -311,8 +311,11 @@ class vtt_class
        void render_lp();
        void render_ec();
        
+       vtt_fx *get_lp_effect() { return lp_fx; }
+       vtt_fx *get_ec_effect() { return ec_fx; }
        void effect_up(vtt_fx *effect);
        void effect_down(vtt_fx *effect);
+       void effect_move(vtt_fx *effect, int pos);
        void effect_remove(vtt_fx_ladspa *effect);
        
        void hide_audio(bool);
index bb168dabf0960ed70e503acc293050cc193226ba..0145241b839aca204a65eebad93762ad8d455892 100644 (file)
@@ -30,6 +30,7 @@
 #include <string.h>
 
 float ladspa_dummy_output_port;
+extern void vg_toggle_drywet(GtkWidget *wid, vtt_fx *effect);
 
 void vtt_fx :: reconnect_buffer()
 {
@@ -319,7 +320,13 @@ void vtt_fx_ladspa :: load(xmlDocPtr doc, xmlNodePtr node) {
                        restore_int("ladspa_id", dummy);
                        restore_bool("panel_hidden", hidden);
                        restore_bool("has_drywet", drywet);
-                       if (drywet) add_drywet();
+                       if (drywet) {
+                              if (panel) {
+                                       vg_toggle_drywet(panel_widget, this);
+                               } else {
+                                       add_drywet();
+                               }
+                       }
                        
                        if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "param")==0)) {
                                val=0;
@@ -354,7 +361,6 @@ void vtt_fx_ladspa :: toggle_drywet() {
 
 void vtt_fx_ladspa :: add_drywet() {
        char buffer[1024];
-       
        sp_wet=new tX_seqpar_vttfx_float();
        sp_wet->set_mapping_parameters(1.0, 0, 0.01, 1);
        sprintf(buffer, "%s: Dry/Wet", plugin->getLabel());
index be3c205fb397ff06f1f90c3b8692a9a5ef3b9058..ef241fb52628c906f551017f50469fe586f41278 100644 (file)
@@ -54,8 +54,6 @@
 #define WID_DYN TRUE, TRUE, 0
 #define WID_FIX FALSE, FALSE, 0
 
-static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect);
-
 void nicer_filename(char *dest, char *source)
 {
                char *fn;
@@ -259,18 +257,18 @@ GCallback load_file(GtkWidget *wid, vtt_class *vtt)
        }
        
        g_signal_connect (G_OBJECT(dialog), "selection-changed", G_CALLBACK(chooser_prelis), vtt);      
-       
+
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
-       char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+       char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
                gtk_widget_hide(dialog);
                tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
                load_part(filename, vtt);
                strcpy(globals.current_path, filename);
-               tX_cursor::reset_cursor();              
-       }       
-       
+               tX_cursor::reset_cursor();
+       }
+
        prelis_stop();
-       gtk_widget_destroy(dialog);     
+       gtk_widget_destroy(dialog);
 
        return NULL;
 }
@@ -279,18 +277,18 @@ void delete_vtt(GtkWidget *wid, vtt_class *vtt)
 {
        if (audioon) tx_note("Sorry, you'll have to stop playback first.");
        else delete(vtt);
-               
+
        mg_update_status();
 }
 
 void edit_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
 {
-       char command[2*PATH_MAX];
+       char command[2*PATH_MAX+32];
 
        if (vtt->samples_in_buffer == 0) {
                tx_note("No audiofile loaded - so there's nothing to edit.", true);
        } else if (strlen(globals.file_editor)>0) {
-               sprintf(command, "%s \"%s\" &", globals.file_editor, vtt->filename);
+               snprintf(command, sizeof(command), "%s \"%s\" &", globals.file_editor, vtt->filename);
                if (system(command) < 0) {
                        tx_note("Error running the soundfile editor.");
                }
@@ -302,9 +300,9 @@ void edit_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
 void reload_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
 {
        char reload_buffer[PATH_MAX];
-       
+
        while (gtk_events_pending()) gtk_main_iteration();
-       
+
        if (vtt->samples_in_buffer > 0) {
                strcpy(reload_buffer, vtt->filename);
                load_part(reload_buffer, vtt);
@@ -728,8 +726,6 @@ void gui_scroll_callback(GtkWidget *tx, GdkEventScroll *eventScroll, gpointer us
 #define connect_press_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "button_press_event", G_CALLBACK(func), (void *) vtt);
 #define connect_rel_button(wid, func); g_signal_connect(G_OBJECT(g->wid), "released", G_CALLBACK(func), (void *) vtt);
 
-GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel);
-
 gchar dnd_uri[128];
 
 void gui_connect_signals(vtt_class *vtt)
@@ -827,14 +823,10 @@ void build_vtt_gui(vtt_class *vtt)
        gtk_box_pack_start(GTK_BOX(tempbox2), tempbox, WID_DYN);
 
        GtkWidget *pixmap;
-       g->audio_minimize=gtk_button_new();
-       pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
-       gtk_container_add (GTK_CONTAINER (g->audio_minimize), pixmap);  
+       g->audio_minimize=create_top_button(MINIMIZE);
        gtk_box_pack_end(GTK_BOX(tempbox2), g->audio_minimize, WID_FIX);
-       gtk_widget_show(pixmap);
        gtk_widget_show(g->audio_minimize);
 
-
        g->audio_label=gtk_label_new(vtt->name);
        gtk_widget_set_halign(g->audio_label, GTK_ALIGN_START);
        gtk_widget_set_margin_start(g->audio_label, 10);
@@ -896,11 +888,8 @@ void build_vtt_gui(vtt_class *vtt)
        gtk_widget_show(g->control_label);
        gtk_box_pack_start(GTK_BOX(tempbox2), g->control_label, WID_DYN);
 
-       g->control_minimize=gtk_button_new();
-       pixmap=tx_pixmap_widget(MINIMIZE_PANEL);
-       gtk_container_add (GTK_CONTAINER (g->control_minimize), pixmap);        
+       g->control_minimize=create_top_button(MINIMIZE);
        gtk_box_pack_end(GTK_BOX(tempbox2), g->control_minimize, WID_FIX);
-       gtk_widget_show(pixmap);
        gtk_widget_show(g->control_minimize);
 
        g->scrolled_win=gtk_scrolled_window_new (NULL, NULL);
@@ -917,7 +906,11 @@ void build_vtt_gui(vtt_class *vtt)
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(g->scrolled_win), g->control_subbox);
 #endif
        gtk_widget_show(g->control_subbox);
-                  
+
+       g->static_box = gtk_list_box_new();
+       gtk_list_box_set_selection_mode (GTK_LIST_BOX (g->static_box), GTK_SELECTION_NONE);
+       gtk_widget_show(g->static_box);
+       gtk_container_add(GTK_CONTAINER(g->control_subbox), g->static_box);
 
        /* Main panel */
        
@@ -941,16 +934,16 @@ void build_vtt_gui(vtt_class *vtt)
        gui_set_tooltip(g->adjust_button, "Activate this button to adjust this turntable's speed to the master turntable's speed.");
        p->add_client_widget(g->adjust_button);
 
-       gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
+       gtk_list_box_insert(GTK_LIST_BOX(g->static_box), p->get_list_box_row(), -1);
                                
        p=new tX_panel("Playback", g->control_subbox);
        g->trigger_panel=p;
        
-       g->trigger=gtk_button_new_with_label("Trigger!");
+       g->trigger=gtk_button_new_with_label("Trigger");
        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.");
        p->add_client_widget(g->trigger);
        
-       g->stop=gtk_button_new_with_label("Stop.");
+       g->stop=gtk_button_new_with_label("Stop");
        gui_set_tooltip(g->stop, "Stop this turntable's playback.");
        p->add_client_widget(g->stop);
        g_signal_connect(G_OBJECT(g->trigger), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_trigger);         
@@ -984,29 +977,31 @@ void build_vtt_gui(vtt_class *vtt)
        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.");
        g_signal_connect(G_OBJECT(dummy), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_sync_cycles);  
 
-       gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
+       gtk_list_box_insert(GTK_LIST_BOX(g->static_box), p->get_list_box_row(), -1);
        
-       g->fx_box=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
-       gtk_box_pack_start(GTK_BOX(g->control_subbox), g->fx_box, WID_FIX);
-       gtk_widget_show(g->fx_box);
-       
-       dummy=gtk_button_new_with_label("FX");
-       gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
+       dummy=gtk_header_bar_new();
+       gtk_header_bar_set_title(GTK_HEADER_BAR(dummy), "FX");
+       gtk_header_bar_set_has_subtitle(GTK_HEADER_BAR(dummy), FALSE);
        gtk_widget_show(dummy);
-       g->fx_button=dummy;
+       g->fx_button=create_top_button(ADD_ITEM);
+       gtk_header_bar_pack_end(GTK_HEADER_BAR(dummy), g->fx_button);
+       gtk_widget_show(g->fx_button);
        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.");
-       gtk_box_pack_start(GTK_BOX(g->fx_box), dummy, WID_FIX);
+       gtk_box_pack_start(GTK_BOX(g->control_subbox), dummy, WID_FIX);
        
+       g->fx_box = gtk_list_box_new();
+       gtk_list_box_set_selection_mode (GTK_LIST_BOX (g->fx_box), GTK_SELECTION_NONE);
+       gtk_box_pack_start(GTK_BOX(g->control_subbox), g->fx_box, WID_FIX);
+       gtk_widget_show(g->fx_box);
+
        /* Lowpass Panel */
 
-       p=new tX_panel("Lowpass", g->fx_box);
-       g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", G_CALLBACK(vg_show_fx_menu), vtt->lp_fx);
+       p=new tX_panel("Lowpass", g->control_subbox, NULL, vtt->get_lp_effect());
        g->lp_panel=p;
                
        g->lp_enable=gtk_check_button_new_with_label("Enable");
        gui_set_tooltip(g->lp_enable, "Click here to enable the built-in lowpass effect.");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->lp_enable), vtt->lp_enable);
-       p->add_client_widget(vg_create_fx_bar(vtt, vtt->lp_fx, 0));
        g_signal_connect(G_OBJECT(g->lp_enable), "button_press_event", (GCallback) tX_seqpar::tX_seqpar_press, &vtt->sp_lp_enable);     
 
        p->add_client_widget(g->lp_enable);
@@ -1027,16 +1022,13 @@ void build_vtt_gui(vtt_class *vtt)
        p->add_client_widget(g->lp_resod->get_widget());
        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.");
 
-       gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
+       gtk_list_box_insert(GTK_LIST_BOX(g->fx_box), p->get_list_box_row(), -1);
 
        /* Echo Panel */
 
-       p=new tX_panel("Echo", g->fx_box);
-       g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event",  G_CALLBACK(vg_show_fx_menu), vtt->ec_fx);
+       p=new tX_panel("Echo", g->control_subbox, NULL, vtt->get_ec_effect());
        g->ec_panel=p;
 
-       p->add_client_widget(vg_create_fx_bar(vtt, vtt->ec_fx, 0));
-       
        g->ec_enable=gtk_check_button_new_with_label("Enable");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->ec_enable), vtt->ec_enable);
        p->add_client_widget(g->ec_enable);
@@ -1064,18 +1056,21 @@ void build_vtt_gui(vtt_class *vtt)
        p->add_client_widget(g->ec_pand->get_widget());
        gui_set_tooltip(g->ec_pand->get_entry(), "Adjust the panning of the echo effect.");
 
-       gtk_box_pack_start(GTK_BOX(g->fx_box), p->get_widget(), WID_FIX);
-       
-       g->stereo_fx_box=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+       gtk_list_box_insert(GTK_LIST_BOX(g->fx_box), p->get_list_box_row(), -1);
+
+       dummy=gtk_header_bar_new();
+       gtk_header_bar_set_title(GTK_HEADER_BAR(dummy), "Stereo FX");
+       gtk_header_bar_set_has_subtitle(GTK_HEADER_BAR(dummy), FALSE);
+       gtk_widget_show(dummy);
+       g->stereo_fx_button=create_top_button(ADD_ITEM);
+       gtk_header_bar_pack_end(GTK_HEADER_BAR(dummy), g->stereo_fx_button);
+       gtk_widget_show(g->stereo_fx_button);
+       gtk_box_pack_start(GTK_BOX(g->control_subbox), dummy, WID_FIX);
+
+       g->stereo_fx_box = gtk_list_box_new();
+       gtk_list_box_set_selection_mode (GTK_LIST_BOX (g->stereo_fx_box), GTK_SELECTION_NONE);
        gtk_box_pack_start(GTK_BOX(g->control_subbox), g->stereo_fx_box, WID_FIX);
        gtk_widget_show(g->stereo_fx_box);
-       
-       dummy=gtk_button_new_with_label("Stereo FX");
-       gtk_container_foreach(GTK_CONTAINER(dummy), (GtkCallback) tX_panel_make_label_bold, NULL);
-       gtk_widget_show(dummy);
-       g->stereo_fx_button=dummy;
-       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.");
-       gtk_box_pack_start(GTK_BOX(g->stereo_fx_box), dummy, WID_FIX);
 
        /* Output */
        
@@ -1171,45 +1166,6 @@ void fx_kill(GtkWidget *wid, vtt_fx_ladspa *effect)
        vtt->effect_remove(effect);
 }
 
-GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel)
-{
-       GtkWidget *box;
-       GtkWidget *pixmap;
-       GtkWidget *button;
-       
-       box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
-
-       if (showdel) {
-               button=gtk_button_new();
-               pixmap=tx_pixmap_widget(FX_CLOSE);
-               gtk_container_add (GTK_CONTAINER (button), pixmap);     
-               gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
-               gtk_widget_show(pixmap);
-               gtk_widget_show(button);
-               g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_kill, (void *) effect);
-       }
-
-       button=gtk_button_new();
-       pixmap=tx_pixmap_widget(FX_DOWN);
-       gtk_container_add (GTK_CONTAINER (button), pixmap);     
-       gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
-       gtk_widget_show(pixmap);
-       gtk_widget_show(button);
-       g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_down, (void *) effect);
-
-       button=gtk_button_new();
-       pixmap=tx_pixmap_widget(FX_UP);
-       gtk_container_add (GTK_CONTAINER (button), pixmap);     
-       gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
-       gtk_widget_show(pixmap);
-       gtk_widget_show(button);
-       g_signal_connect(G_OBJECT(button), "clicked", (GCallback) fx_up, (void *) effect);
-       
-       gtk_widget_show(box);
-       
-       return box;
-}
-
 int gtk_box_get_widget_pos(GtkBox *box, GtkWidget *child)
 {
        int i=0;
@@ -1226,86 +1182,42 @@ int gtk_box_get_widget_pos(GtkBox *box, GtkWidget *child)
        return i;
 }
 
-void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt, bool stereo)
+void vg_move_fx_panel_up(tX_panel *panel, vtt_class *vtt, bool stereo)
 {
-       GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
-       int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
-       gtk_box_reorder_child(GTK_BOX(box), wid, pos-1);
-}
+       GtkWidget *list_box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
+       GtkWidget *row=panel->get_list_box_row();
 
-void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt, bool stereo)
-{
-       GtkWidget *box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
-       int pos=gtk_box_get_widget_pos(GTK_BOX(box), wid);
-       gtk_box_reorder_child(GTK_BOX(box), wid, pos+1);
+       int pos=gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row));
+       g_object_ref(row);
+       gtk_container_remove(GTK_CONTAINER(list_box), row);
+       gtk_list_box_insert(GTK_LIST_BOX(list_box), row, pos-1);
+       g_object_unref(row);
 }
 
-static gint vg_show_fx_info(GtkWidget *wid, vtt_fx *effect)
+void vg_move_fx_panel_down(tX_panel *panel, vtt_class *vtt, bool stereo)
 {
-       tx_l_note(effect->get_info_string());
-       return TRUE;
+       GtkWidget *list_box=(stereo ? vtt->gui.stereo_fx_box : vtt->gui.fx_box);
+       GtkWidget *row=panel->get_list_box_row();
+
+       int pos=gtk_list_box_row_get_index(GTK_LIST_BOX_ROW(row));
+       g_object_ref(row);
+       gtk_container_remove(GTK_CONTAINER(list_box), row);
+       gtk_list_box_insert(GTK_LIST_BOX(list_box), row, pos+1);
+       g_object_unref(row);
 }
 
 void vg_toggle_drywet(GtkWidget *wid, vtt_fx *effect)
 {
+       tX_panel *panel = effect->get_panel();
        effect->toggle_drywet();
-}
 
-static gint vg_show_fx_menu(GtkWidget *wid, GdkEventButton *event, vtt_fx *effect)
-{
-       if (event->button==3) {
-               GtkWidget *menu=gtk_menu_new();
-               GtkWidget *item=gtk_menu_item_new_with_label("View Plugin Details");
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
-               gtk_widget_show(item);
-               g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_show_fx_info), effect);
-               
-               switch (effect->has_drywet_feature()) {
-                       case (NOT_DRYWET_CAPABLE):
-                               item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
-                               gtk_widget_set_sensitive(item, FALSE);
-                               break;
-                       case (DRYWET_ACTIVE):
-                               item=gtk_menu_item_new_with_label("Remove Dry/Wet Control");
-                               break;
-                       case (DRYWET_AVAILABLE):
-                               item=gtk_menu_item_new_with_label("Add Dry/Wet Control");
-                               break;
-               }
-               
-               g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(vg_toggle_drywet), effect);     
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_show(item);
-               
-               item = gtk_menu_item_new();
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_set_sensitive(item, FALSE);
-               gtk_widget_show(item);
-       
-               item=gtk_menu_item_new_with_label("Up");
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_show(item);
-               g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_up), effect);
-       
-               item=gtk_menu_item_new_with_label("Down");
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_show(item);
-               g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_down), effect);
-       
-               item=gtk_menu_item_new_with_label("Delete");
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               gtk_widget_set_sensitive(item, (effect->has_drywet_feature()!=NOT_DRYWET_CAPABLE));
-               gtk_widget_show(item);
-               g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(fx_kill), effect);
-       
-               gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
-       
-               /* gtk+ is really waiting for this.. */
-               g_signal_emit_by_name(G_OBJECT(wid), "released", effect);
-               return TRUE;
+       if (effect->has_drywet_feature() == DRYWET_ACTIVE) {
+               gtk_widget_hide(panel->get_add_drywet_button());
+               gtk_widget_show(panel->get_remove_drywet_button());
+       } else {
+               gtk_widget_show(panel->get_add_drywet_button());
+               gtk_widget_hide(panel->get_remove_drywet_button());
        }
-       return FALSE;
 }
 
 void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin)
@@ -1317,28 +1229,46 @@ void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plug
        tX_panel *p;
        list <tX_seqpar_vttfx *> :: iterator sp;
        
-       strcpy(buffer, plugin->getLabel());
-       if (strlen(buffer) > 6) {
-               buffer[5]='.';
-               buffer[6]='.';
+       strcpy(buffer, plugin->getName());
+       if (strlen(buffer) > 8) {
                buffer[7]='.';
-               buffer[8]=0;
+               buffer[8]='.';
+               buffer[9]='.';
+               buffer[10]=0;
        }
 
-       p=new tX_panel(buffer, g->control_subbox);
-       
-       p->add_client_widget(vg_create_fx_bar(vtt, effect, 1));
+       p=new tX_panel(buffer, g->control_subbox, G_CALLBACK(fx_kill), effect);
        
        for (sp = effect->controls.begin(); sp != effect->controls.end(); sp++) {
+               if ((strcmp((*sp)->get_label_name(), "Enable") == 0) && ((effect->has_drywet_feature() != NOT_DRYWET_CAPABLE))) {
+                       GtkWidget *box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
+                       gtk_container_add_with_properties(GTK_CONTAINER(box), (*sp)->get_widget(), "expand", TRUE, NULL);
+                       gtk_widget_show((*sp)->get_widget());
+                       
+                       g_signal_connect(G_OBJECT(p->get_add_drywet_button()), "clicked", G_CALLBACK(vg_toggle_drywet), effect);
+                       gtk_widget_set_tooltip_text(p->get_add_drywet_button(), "Click to add Dry/Wet controls for this effect.");      
+                       gtk_container_add(GTK_CONTAINER(box), p->get_add_drywet_button());
+                       if (effect->has_drywet_feature() == DRYWET_AVAILABLE) {
+                               gtk_widget_show(p->get_add_drywet_button());
+                       }
+                       
+                       g_signal_connect(G_OBJECT(p->get_remove_drywet_button()), "clicked", G_CALLBACK(vg_toggle_drywet), effect);     
+                       gtk_widget_set_tooltip_text(p->get_remove_drywet_button(), "Click to remove Dry/Wet controls for this effect.");        
+                       gtk_container_add(GTK_CONTAINER(box), p->get_remove_drywet_button());
+                       if (effect->has_drywet_feature() == DRYWET_ACTIVE) {
+                               gtk_widget_show(p->get_remove_drywet_button());
+                       }
+
+                       p->add_client_widget(box);
+               } else {
                        p->add_client_widget((*sp)->get_widget());
+               }
        }
 
-       g_signal_connect(G_OBJECT(p->get_labelbutton()), "button_press_event", (GCallback) vg_show_fx_menu, (void *) effect);
-       gui_set_tooltip(p->get_labelbutton(), "Right-click to access menu.");
        effect->set_panel_widget(p->get_widget());
        effect->set_panel(p);
 
-       gtk_box_pack_start(GTK_BOX((effect->is_stereo() ? g->stereo_fx_box : g->fx_box)), p->get_widget(), WID_FIX);
+       gtk_list_box_insert(GTK_LIST_BOX(effect->is_stereo() ? g->stereo_fx_box : g->fx_box), p->get_list_box_row(), -1);
 }
 
 void gui_set_filename (vtt_class *vtt, char *newname)
index 1ae65c900440675b6cdbd8213ae92898f442532b..b9557d01152e6f65a455cb41cdb36b733f5fe492 100644 (file)
@@ -42,6 +42,7 @@ struct vtt_gui
        GtkWidget *control_minimize;
        GtkWidget *scrolled_win;
        GtkWidget *control_subbox;
+       GtkWidget *static_box;
        GtkWidget *fx_box;
        GtkWidget *stereo_fx_box;
        GtkWidget *ladspa_menu;