""")
audiounit_files=Split("""
-au_pluginui.cc
+au_pluginui.mm
""")
gtkosx_files=Split("""
export_range_markers_dialog.cc
gain_automation_time_axis.cc
gain_meter.cc
+generic_pluginui.cc
ghostregion.cc
gtk-custom-hruler.c
gtk-custom-ruler.c
io_selector.cc
keyboard.cc
keyeditor.cc
-ladspa_pluginui.cc
level_meter.cc
location_ui.cc
main.cc
if gtkardour['GTKOSX']:
extra_sources += gtkosx_files
gtkardour.Append (CCFLAGS="-DTOP_MENUBAR -DGTKOSX")
+ gtkardour.Append (LINKFLAGS=" -framework AppKit -framework CoreAudioKit")
+
else:
extra_sources += x11_files
#include <gtkmm/accelmap.h>
#include <pbd/error.h>
+#include <pbd/basename.h>
#include <pbd/compose.h>
#include <pbd/misc.h>
#include <pbd/pathscanner.h>
int response = Gtk::RESPONSE_NONE;
+ Glib::ustring dir = Glib::path_get_dirname (string (predetermined_path));
+ Glib::ustring name = basename_nosuffix (string (predetermined_path));
+
new_session_dialog->set_modal(true);
- new_session_dialog->set_name (predetermined_path);
+
+ if (name.length()) {
+ new_session_dialog->set_session_name (name);
+ }
+ if (dir.length()) {
+ new_session_dialog->set_session_folder (dir);
+ }
new_session_dialog->reset_recent();
new_session_dialog->set_position (WIN_POS_CENTER);
new_session_dialog->set_current_page (0);
+ cerr << "NSD with " << predetermined_path << endl;
+
do {
new_session_dialog->set_have_engine (have_engine);
+++ /dev/null
-/*
- Copyright (C) 2006 Paul Davis
- Written by Taybin Rutkin
-
- 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <ardour/audio_unit.h>
-#include <ardour/insert.h>
-
-#include <gtkmm2ext/doi.h>
-
-#include "au_pluginui.h"
-#include "gui_thread.h"
-
-#include <appleutility/CAAudioUnit.h>
-#include <appleutility/CAComponent.h>
-
-#include <AudioUnit/AudioUnit.h>
-
-#include "i18n.h"
-
-using namespace ARDOUR;
-using namespace PBD;
-
-AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
-{
- if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) {
- error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg;
- throw failed_constructor ();
- }
-
- info << "AUPluginUI created" << endmsg;
-}
-
-AUPluginUI::~AUPluginUI ()
-{
- // nothing to do here - plugin destructor destroys the GUI
-}
-
-/*
- Copyright (C) 2006 Paul Davis
+#ifndef __gtk2_ardour_auplugin_ui_h__
+#define __gtk2_ardour_auplugin_ui_h__
- 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <AppKit/AppKit.h>
+#include <Carbon/Carbon.h>
+#include <AudioUnit/AudioUnit.h>
-*/
+/* fix up stupid apple macros */
-#ifndef __au_plugin_ui_h__
-#define __au_plugin_ui_h__
+#undef check
+#undef require
+#undef verify
-#include <boost/shared_ptr.hpp>
-
-#include <Carbon/Carbon.h>
-#include <AudioUnit/AudioUnit.h>
+#include <gtkmm/box.h>
+#include "plugin_ui.h"
namespace ARDOUR {
class AUPlugin;
class Redirect;
}
-class AUPluginUI
+class AUPluginUI : public PlugUIBase, public Gtk::VBox
{
public:
AUPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>);
~AUPluginUI ();
+ gint get_preferred_height () { return prefheight; }
+ gint get_preferred_width () { return prefwidth; }
+ bool start_updating(GdkEventAny*);
+ bool stop_updating(GdkEventAny*);
+
+ void on_realize ();
+ void on_show ();
+
+ OSStatus carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event);
+
private:
boost::shared_ptr<ARDOUR::AUPlugin> au;
+ int prefheight;
+ int prefwidth;
+
+ /* Cocoa */
+
+ NSWindow* cocoa_window;
+ NSScrollView* scroll_view;
+
+ /* Carbon */
+
+ NSWindow* cocoa_parent;
+ ComponentDescription carbon_descriptor;
+ AudioUnitCarbonView editView;
+ WindowRef carbon_window;
+ EventHandlerRef carbon_event_handler;
+ bool carbon_parented;
+ bool cocoa_parented;
+
+ void test_view_support (bool&, bool&);
+ bool test_cocoa_view_support ();
+ bool test_carbon_view_support ();
+ int create_carbon_view (bool generic);
+ int create_cocoa_view ();
+
+ int parent_carbon_window ();
+ int parent_cocoa_window ();
+ NSWindow* get_nswindow();
+
+ bool plugin_class_valid (Class pluginClass);
};
-#endif // __au_plugin_ui_h__
+#endif /* __gtk2_ardour_auplugin_ui_h__ */
--- /dev/null
+#include <pbd/error.h>
+#include <ardour/audio_unit.h>
+#include <ardour/insert.h>
+
+#include <gdk/gdkquartz.h>
+
+#include "au_pluginui.h"
+#include "gui_thread.h"
+
+#include <appleutility/CAAudioUnit.h>
+#include <appleutility/CAComponent.h>
+
+#import <AudioUnit/AUCocoaUIView.h>
+#import <CoreAudioKit/AUGenericView.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace Gtk;
+using namespace sigc;
+using namespace std;
+using namespace PBD;
+
+static const float kOffsetForAUView_X = 220;
+static const float kOffsetForAUView_Y = 90;
+
+AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
+ : PlugUIBase (insert)
+{
+ if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) {
+ error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg;
+ throw failed_constructor ();
+ }
+
+ bool has_carbon;
+ bool has_cocoa;
+
+ carbon_parented = false;
+ cocoa_parented = false;
+ cocoa_parent = 0;
+ cocoa_window = 0;
+
+ test_view_support (has_carbon, has_cocoa);
+
+ cerr << "plugin has carbon ? " << has_carbon << " cocoa ? " << has_cocoa << endl;
+
+ if (has_cocoa) {
+ create_cocoa_view ();
+ } else {
+ create_carbon_view (has_carbon);
+ }
+}
+
+
+AUPluginUI::~AUPluginUI ()
+{
+ if (carbon_parented) {
+ NSWindow* win = get_nswindow();
+ RemoveEventHandler(carbon_event_handler);
+ [win removeChildWindow:cocoa_parent];
+ }
+}
+
+void
+AUPluginUI::test_view_support (bool& has_carbon, bool& has_cocoa)
+{
+ has_carbon = test_carbon_view_support();
+ has_cocoa = test_cocoa_view_support();
+}
+
+bool
+AUPluginUI::test_carbon_view_support ()
+{
+ bool ret = true; // there is always the generic GUI
+
+ carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType;
+ carbon_descriptor.componentSubType = 'gnrc';
+ carbon_descriptor.componentManufacturer = 'appl';
+ carbon_descriptor.componentFlags = 0;
+ carbon_descriptor.componentFlagsMask = 0;
+
+ OSStatus err;
+
+ // ask the AU for its first editor component
+ UInt32 propertySize;
+ err = AudioUnitGetPropertyInfo(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, &propertySize, NULL);
+ if (!err) {
+ int nEditors = propertySize / sizeof(ComponentDescription);
+ ComponentDescription *editors = new ComponentDescription[nEditors];
+ err = AudioUnitGetProperty(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, editors, &propertySize);
+ if (!err) {
+ // just pick the first one for now
+ carbon_descriptor = editors[0];
+ ret = true;
+ }
+ delete[] editors;
+ }
+
+ return ret;
+}
+
+bool
+AUPluginUI::test_cocoa_view_support ()
+{
+ UInt32 dataSize = 0;
+ Boolean isWritable = 0;
+ OSStatus err = AudioUnitGetPropertyInfo(*au->get_au(),
+ kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
+ 0, &dataSize, &isWritable);
+
+ return dataSize > 0 && err == noErr;
+}
+
+bool
+AUPluginUI::plugin_class_valid (Class pluginClass)
+{
+ if([pluginClass conformsToProtocol: @protocol(AUCocoaUIBase)]) {
+ if([pluginClass instancesRespondToSelector: @selector(interfaceVersion)] &&
+ [pluginClass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int
+AUPluginUI::create_cocoa_view ()
+{
+ NSView *AUView = nil;
+ BOOL wasAbleToLoadCustomView = NO;
+ AudioUnitCocoaViewInfo* cocoaViewInfo = NULL;
+ UInt32 numberOfClasses = 0;
+ UInt32 dataSize;
+ Boolean isWritable;
+ NSString* factoryClassName = 0;
+ NSURL* CocoaViewBundlePath;
+
+ OSStatus result = AudioUnitGetPropertyInfo (*au->get_au(),
+ kAudioUnitProperty_CocoaUI,
+ kAudioUnitScope_Global,
+ 0,
+ &dataSize,
+ &isWritable );
+
+
+ if (result != noErr) {
+ return -1;
+ }
+
+ numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
+
+ // Does view have custom Cocoa UI?
+
+ if ((result == noErr) && (numberOfClasses > 0) ) {
+ cocoaViewInfo = (AudioUnitCocoaViewInfo *)malloc(dataSize);
+ if(AudioUnitGetProperty(*au->get_au(),
+ kAudioUnitProperty_CocoaUI,
+ kAudioUnitScope_Global,
+ 0,
+ cocoaViewInfo,
+ &dataSize) == noErr) {
+
+ CocoaViewBundlePath = (NSURL *)cocoaViewInfo->mCocoaAUViewBundleLocation;
+
+ // we only take the first view in this example.
+ factoryClassName = (NSString *)cocoaViewInfo->mCocoaAUViewClass[0];
+
+ } else {
+
+ if (cocoaViewInfo != NULL) {
+ free (cocoaViewInfo);
+ cocoaViewInfo = NULL;
+ }
+ }
+ }
+
+ cocoa_window = [NSWindow alloc];
+
+ NSRect frameRect = [[cocoa_window contentView] frame];
+ scroll_view = [[[NSScrollView alloc] initWithFrame:frameRect] autorelease];
+ [scroll_view setDrawsBackground:NO];
+ [scroll_view setHasHorizontalScroller:YES];
+ [scroll_view setHasVerticalScroller:YES];
+
+ [cocoa_window setContentView:scroll_view];
+
+ // [A] Show custom UI if view has it
+
+ if (CocoaViewBundlePath && factoryClassName) {
+ NSBundle *viewBundle = [NSBundle bundleWithPath:[CocoaViewBundlePath path]];
+ if (viewBundle == nil) {
+ error << _("AUPluginUI: error loading AU view's bundle") << endmsg;
+ return -1;
+ } else {
+ Class factoryClass = [viewBundle classNamed:factoryClassName];
+ if (!factoryClass) {
+ error << _("AUPluginUI: error getting AU view's factory class from bundle") << endmsg;
+ return -1;
+ }
+
+ // make sure 'factoryClass' implements the AUCocoaUIBase protocol
+ if (!plugin_class_valid (factoryClass)) {
+ error << _("AUPluginUI: U view's factory class does not properly implement the AUCocoaUIBase protocol") << endmsg;
+ return -1;
+ }
+ // make a factory
+ id factoryInstance = [[[factoryClass alloc] init] autorelease];
+ if (factoryInstance == nil) {
+ error << _("AUPluginUI: Could not create an instance of the AU view factory") << endmsg;
+ return -1;
+ }
+
+ // make a view
+ AUView = [factoryInstance uiViewForAudioUnit:*au->get_au()
+ withSize:[[scroll_view contentView] bounds].size];
+
+ // cleanup
+ [CocoaViewBundlePath release];
+ if (cocoaViewInfo) {
+ UInt32 i;
+ for (i = 0; i < numberOfClasses; i++)
+ CFRelease(cocoaViewInfo->mCocoaAUViewClass[i]);
+
+ free (cocoaViewInfo);
+ }
+ wasAbleToLoadCustomView = YES;
+ }
+ }
+
+ if (!wasAbleToLoadCustomView) {
+ // [B] Otherwise show generic Cocoa view
+ AUView = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()];
+ [(AUGenericView *)AUView setShowsExpertParameters:YES];
+ }
+
+ // Display view
+ NSRect viewFrame = [AUView frame];
+ NSSize frameSize = [NSScrollView frameSizeForContentSize:viewFrame.size
+ hasHorizontalScroller:[scroll_view hasHorizontalScroller]
+ hasVerticalScroller:[scroll_view hasVerticalScroller]
+ borderType:[scroll_view borderType]];
+
+
+ NSRect newFrame;
+ newFrame.origin = [scroll_view frame].origin;
+ newFrame.size = frameSize;
+
+ NSRect currentFrame = [scroll_view frame];
+ [scroll_view setFrame:newFrame];
+ [scroll_view setDocumentView:AUView];
+
+ NSSize oldContentSize = [[cocoa_window contentView] frame].size;
+ NSSize newContentSize = oldContentSize;
+ newContentSize.width += (newFrame.size.width - currentFrame.size.width);
+ newContentSize.height += (newFrame.size.height - currentFrame.size.height);
+
+ [cocoa_window setContentSize:newContentSize];
+
+ return 0;
+}
+
+int
+AUPluginUI::create_carbon_view (bool generic)
+{
+ OSStatus err;
+ ControlRef root_control;
+
+ Component editComponent = FindNextComponent(NULL, &carbon_descriptor);
+
+ OpenAComponent(editComponent, &editView);
+ if (!editView) {
+ error << _("AU Carbon view: cannot open AU Component") << endmsg;
+ return -1;
+ }
+
+ Rect r = { 100, 100, 100, 100 };
+ WindowAttributes attr = WindowAttributes (kWindowStandardHandlerAttribute |
+ kWindowCompositingAttribute|
+ kWindowNoShadowAttribute|
+ kWindowNoTitleBarAttribute);
+
+ if ((err = CreateNewWindow(kFloatingWindowClass, attr, &r, &carbon_window)) != noErr) {
+ error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
+ return -1;
+ }
+
+ if ((err = GetRootControl(carbon_window, &root_control)) != noErr) {
+ error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg;
+ return -1;
+ }
+
+ ControlRef viewPane;
+ Float32Point location = { 0.0, 0.0 };
+ Float32Point size = { 0.0, 0.0 } ;
+
+ if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) {
+ error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg;
+ return -1;
+ }
+
+ // resize window
+
+ Rect bounds;
+ GetControlBounds(viewPane, &bounds);
+ size.x = bounds.right-bounds.left;
+ size.y = bounds.bottom-bounds.top;
+ SizeWindow(carbon_window, (short) (size.x + 0.5), (short) (size.y + 0.5), true);
+
+ prefwidth = (int) (size.x + 0.5);
+ prefheight = (int) (size.y + 0.5);
+
+#if 0
+ mViewPaneResizer->WantEventTypes (GetControlEventTarget(mAUViewPane), GetEventTypeCount(resizeEvent), resizeEvent);
+#endif
+ return 0;
+}
+
+NSWindow*
+AUPluginUI::get_nswindow ()
+{
+ Gtk::Container* toplevel = get_toplevel();
+
+ if (!toplevel || !toplevel->is_toplevel()) {
+ error << _("AUPluginUI: no top level window!") << endmsg;
+ return 0;
+ }
+
+ NSWindow* true_parent = gdk_quartz_window_get_nswindow (toplevel->get_window()->gobj());
+
+ if (!true_parent) {
+ error << _("AUPluginUI: no top level window!") << endmsg;
+ return 0;
+ }
+
+ return true_parent;
+}
+
+
+OSStatus
+_carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
+{
+ return ((AUPluginUI*)userData)->carbon_event (nextHandlerRef, event);
+}
+
+OSStatus
+AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event)
+{
+ UInt32 eventKind = GetEventKind(event);
+ ClickActivationResult howToHandleClick;
+
+ cerr << "Carbon event for " << au->name();
+
+ switch (eventKind) {
+ case kEventWindowHandleDeactivate:
+ // don't allow window to get deactivated while app is active
+ // (do this only if you are a floating window that doesn't hide)
+ cerr << " deactivate!";
+ ActivateWindow(carbon_window, TRUE);
+ break;
+
+ case kEventWindowGetClickActivation:
+ cerr << " click activate!";
+ howToHandleClick = kActivateAndHandleClick;
+ SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult,
+ sizeof(ClickActivationResult), &howToHandleClick);
+ break;
+ }
+
+ cerr << "\n";
+
+ return noErr;
+}
+
+int
+AUPluginUI::parent_carbon_window ()
+{
+ NSWindow* win = get_nswindow ();
+ int x, y;
+
+ if (!win) {
+ return -1;
+ }
+
+ Gtk::Container* toplevel = get_toplevel();
+
+ if (!toplevel || !toplevel->is_toplevel()) {
+ error << _("AUPluginUI: no top level window!") << endmsg;
+ return -1;
+ }
+
+ toplevel->get_window()->get_root_origin (x, y);
+
+ /* compute how tall the title bar is, because we have to offset the position of the carbon window
+ by that much.
+ */
+
+ NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]];
+ NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]];
+
+ int titlebar_height = wm_frame.size.height - content_frame.size.height;
+
+ MoveWindow (carbon_window, x, y + titlebar_height, false);
+ ShowWindow (carbon_window);
+
+ // create the cocoa window for the carbon one and make it visible
+ cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
+
+ EventTypeSpec windowEventTypes[] = {
+ {kEventClassWindow, kEventWindowGetClickActivation },
+ {kEventClassWindow, kEventWindowHandleDeactivate }
+ };
+
+ EventHandlerUPP ehUPP = NewEventHandlerUPP(_carbon_event);
+ OSStatus result = InstallWindowEventHandler (carbon_window, ehUPP,
+ sizeof(windowEventTypes) / sizeof(EventTypeSpec),
+ windowEventTypes, this, &carbon_event_handler);
+ if (result != noErr) {
+ return -1;
+ }
+
+ [win addChildWindow:cocoa_parent ordered:NSWindowAbove];
+ [win setLevel:NSFloatingWindowLevel];
+
+ carbon_parented = true;
+
+ return 0;
+}
+
+int
+AUPluginUI::parent_cocoa_window ()
+{
+ NSWindow* win = get_nswindow ();
+
+ if (!win) {
+ return -1;
+ }
+
+ [win addChildWindow:cocoa_window ordered:NSWindowAbove];
+ [win setLevel:NSFloatingWindowLevel];
+
+ cocoa_parented = true;
+
+ return 0;
+}
+
+void
+AUPluginUI::on_realize ()
+{
+ VBox::on_realize ();
+
+ if (cocoa_window) {
+
+ if (parent_cocoa_window ()) {
+ }
+
+ } else if (carbon_window) {
+
+ if (parent_carbon_window ()) {
+ // ShowWindow (carbon_window);
+ }
+ }
+}
+
+void
+AUPluginUI::on_show ()
+{
+ cerr << "AU plugin window shown\n";
+
+ VBox::on_show ();
+
+ if (cocoa_window) {
+ // [cocoa_window setIsVisible:YES];
+ } else if (carbon_window) {
+ // [cocoa_parent setIsVisible:YES];
+ }
+}
+
+bool
+AUPluginUI::start_updating (GdkEventAny* any)
+{
+ return false;
+}
+
+bool
+AUPluginUI::stop_updating (GdkEventAny* any)
+{
+ return false;
+}
+
+PlugUIBase*
+create_au_gui (boost::shared_ptr<PluginInsert> plugin_insert, VBox** box)
+{
+ AUPluginUI* aup = new AUPluginUI (plugin_insert);
+ (*box) = aup;
+ return aup;
+}
#include "actions.h"
#include "sync-menu.h"
+sigc::signal<void,bool> ApplicationActivationChanged;
+static EventHandlerRef application_event_handler_ref;
+
/* Called for clicks on the dock icon. Can be used to unminimize or
* create a new window for example.
*/
return noErr;
}
+static OSStatus
+application_event_handler (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
+{
+ UInt32 eventKind = GetEventKind (event);
+
+ switch (eventKind) {
+ case kEventAppActivated:
+ ApplicationActivationChanged (true); // EMIT SIGNAL
+ return eventNotHandledErr;
+
+ case kEventAppDeactivated:
+ ApplicationActivationChanged (false); // EMIT SIGNAL
+ return eventNotHandledErr;
+
+ default:
+ // pass-thru all kEventClassApplication events we're not interested in.
+ break;
+ }
+ return eventNotHandledErr;
+}
+
void
ARDOUR_UI::platform_specific ()
{
if (widget) {
ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0);
}
+
+ EventTypeSpec applicationEventTypes[] = {
+ {kEventClassApplication, kEventAppActivated },
+ {kEventClassApplication, kEventAppDeactivated }
+ };
+
+ EventHandlerUPP ehUPP = NewEventHandlerUPP (application_event_handler);
+
+ InstallApplicationEventHandler (ehUPP, sizeof(applicationEventTypes) / sizeof(EventTypeSpec),
+ applicationEventTypes, 0, &application_event_handler_ref);
}
+
Track* t;
boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<Region> new_region;
+ bool in_command = false;
for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
- if (!arv)
+
+ if (!arv) {
continue;
+ }
boost::shared_ptr<AudioRegion> region (arv->audio_region());
TimeAxisView* tv = &(arv->get_time_axis_view());
if (!fx->results.empty()) {
new_region = fx->results.front();
+ if (!in_command) {
+ begin_reversible_command (dialog.pitching ? _("pitch shift") : _("time stretch"));
+ in_command = true;
+ }
+
XMLNode &before = playlist->get_state();
playlist->replace_region (region, new_region, region->position());
XMLNode &after = playlist->get_state();
delete fx;
}
+ if (in_command) {
+ commit_reversible_command ();
+ }
+
dialog.status = 0;
dialog.request.done = true;
}
--- /dev/null
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <climits>
+#include <cerrno>
+#include <cmath>
+#include <string>
+
+#include <pbd/stl_delete.h>
+#include <pbd/xml++.h>
+#include <pbd/failed_constructor.h>
+
+#include <gtkmm2ext/click_box.h>
+#include <gtkmm2ext/fastmeter.h>
+#include <gtkmm2ext/barcontroller.h>
+#include <gtkmm2ext/utils.h>
+#include <gtkmm2ext/doi.h>
+#include <gtkmm2ext/slider_controller.h>
+
+#include <midi++/manager.h>
+
+#include <ardour/plugin.h>
+#include <ardour/insert.h>
+#include <ardour/ladspa_plugin.h>
+
+#include <lrdf.h>
+
+#include "ardour_ui.h"
+#include "prompter.h"
+#include "plugin_ui.h"
+#include "utils.h"
+#include "gui_thread.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Gtkmm2ext;
+using namespace Gtk;
+using namespace sigc;
+
+GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrollable)
+ : PlugUIBase (pi),
+ button_table (initial_button_rows, initial_button_cols),
+ output_table (initial_output_rows, initial_output_cols),
+ hAdjustment(0.0, 0.0, 0.0),
+ vAdjustment(0.0, 0.0, 0.0),
+ scroller_view(hAdjustment, vAdjustment),
+ automation_menu (0),
+ is_scrollable(scrollable)
+{
+ set_name ("PluginEditor");
+ set_border_width (10);
+ set_homogeneous (false);
+
+ settings_box.set_homogeneous (false);
+
+ HBox* constraint_hbox = manage (new HBox);
+ HBox* smaller_hbox = manage (new HBox);
+ Label* combo_label = manage (new Label (_("<span size=\"large\">Presets</span>")));
+ combo_label->set_use_markup (true);
+
+ smaller_hbox->pack_start (*combo_label, false, false, 10);
+ smaller_hbox->pack_start (combo, false, false);
+ smaller_hbox->pack_start (save_button, false, false);
+
+ constraint_hbox->set_spacing (5);
+ constraint_hbox->pack_start (*smaller_hbox, true, false);
+ constraint_hbox->pack_end (bypass_button, false, false);
+
+ settings_box.pack_end (*constraint_hbox, false, false);
+
+ pack_start (settings_box, false, false);
+
+ if ( is_scrollable ) {
+ scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ scroller.set_name ("PluginEditor");
+ scroller_view.set_name("PluginEditor");
+ scroller_view.add (hpacker);
+ scroller.add (scroller_view);
+
+ pack_start (scroller, true, true);
+
+ }
+ else {
+ pack_start (hpacker, false, false);
+ }
+
+ insert->active_changed.connect (mem_fun(*this, &GenericPluginUI::redirect_active_changed));
+ bypass_button.set_active (!insert->active());
+
+ build ();
+}
+
+GenericPluginUI::~GenericPluginUI ()
+{
+ if (output_controls.size() > 0) {
+ screen_update_connection.disconnect();
+ }
+}
+
+void
+GenericPluginUI::build ()
+
+{
+ guint32 i = 0;
+ guint32 x = 0;
+ Frame* frame;
+ Frame* bt_frame;
+ VBox* box;
+ int output_row, output_col;
+ int button_row, button_col;
+ int output_rows, output_cols;
+ int button_rows, button_cols;
+ guint32 n_ins=0, n_outs = 0;
+
+ prefheight = 30;
+ hpacker.set_spacing (10);
+
+ output_rows = initial_output_rows;
+ output_cols = initial_output_cols;
+ button_rows = initial_button_rows;
+ button_cols = initial_button_cols;
+ output_row = 0;
+ button_row = 0;
+ output_col = 0;
+ button_col = 0;
+
+ button_table.set_homogeneous (false);
+ button_table.set_row_spacings (2);
+ button_table.set_col_spacings (2);
+ output_table.set_homogeneous (true);
+ output_table.set_row_spacings (2);
+ output_table.set_col_spacings (2);
+ button_table.set_border_width (5);
+ output_table.set_border_width (5);
+
+ hpacker.set_border_width (10);
+
+ bt_frame = manage (new Frame);
+ bt_frame->set_name ("BaseFrame");
+ bt_frame->add (button_table);
+ hpacker.pack_start(*bt_frame, true, true);
+
+ box = manage (new VBox);
+ box->set_border_width (5);
+ box->set_spacing (1);
+
+ frame = manage (new Frame);
+ frame->set_name ("BaseFrame");
+ frame->set_label (_("Controls"));
+ frame->add (*box);
+ hpacker.pack_start(*frame, true, true);
+
+ /* find all ports. build control elements for all appropriate control ports */
+
+ for (i = 0; i < plugin->parameter_count(); ++i) {
+
+ if (plugin->parameter_is_control (i)) {
+
+ /* Don't show latency control ports */
+
+ if (plugin->describe_parameter (i) == X_("latency")) {
+ continue;
+ }
+
+ ControlUI* cui;
+
+ /* if we are scrollable, just use one long column */
+
+ if (!is_scrollable) {
+ if (x++ > 7){
+ frame = manage (new Frame);
+ frame->set_name ("BaseFrame");
+ box = manage (new VBox);
+
+ box->set_border_width (5);
+ box->set_spacing (1);
+
+ frame->add (*box);
+ hpacker.pack_start(*frame,true,true);
+
+ x = 1;
+ }
+ }
+
+ if ((cui = build_control_ui (i, plugin->get_nth_control (i))) == 0) {
+ error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
+ continue;
+ }
+
+ if (cui->control || cui->clickbox || cui->combo) {
+
+ box->pack_start (*cui, false, false);
+
+ } else if (cui->button) {
+
+ if (button_row == button_rows) {
+ button_row = 0;
+ if (++button_col == button_cols) {
+ button_cols += 2;
+ button_table.resize (button_rows, button_cols);
+ }
+ }
+
+ button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1,
+ FILL|EXPAND, FILL);
+ button_row++;
+
+ } else if (cui->display) {
+
+ output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1,
+ FILL|EXPAND, FILL);
+
+ // TODO: The meters should be divided into multiple rows
+
+ if (++output_col == output_cols) {
+ output_cols ++;
+ output_table.resize (output_rows, output_cols);
+ }
+
+ /* old code, which divides meters into
+ * columns first, rows later. New code divides into one row
+
+ if (output_row == output_rows) {
+ output_row = 0;
+ if (++output_col == output_cols) {
+ output_cols += 2;
+ output_table.resize (output_rows, output_cols);
+ }
+ }
+
+ output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1,
+ FILL|EXPAND, FILL);
+
+ output_row++;
+ */
+ }
+
+ /* HACK: ideally the preferred height would be queried from
+ the complete hpacker, but I can't seem to get that
+ information in time, so this is an estimation
+ */
+
+ prefheight += 30;
+
+ }
+ }
+
+ n_ins = plugin->get_info()->n_inputs;
+ n_outs = plugin->get_info()->n_outputs;
+
+ if (box->children().empty()) {
+ hpacker.remove (*frame);
+ }
+
+ if (button_table.children().empty()) {
+ hpacker.remove (*bt_frame);
+ }
+
+ if (!output_table.children().empty()) {
+ frame = manage (new Frame);
+ frame->set_name ("BaseFrame");
+ frame->add (output_table);
+ hpacker.pack_end (*frame, true, true);
+ }
+
+ output_update ();
+
+ output_table.show_all ();
+ button_table.show_all ();
+}
+
+GenericPluginUI::ControlUI::ControlUI ()
+ : automate_button (X_("")) // force creation of a label
+{
+ automate_button.set_name ("PluginAutomateButton");
+ ARDOUR_UI::instance()->tooltips().set_tip (automate_button, _("Automation control"));
+
+ /* XXX translators: use a string here that will be at least as long
+ as the longest automation label (see ::automation_state_changed()
+ below). be sure to include a descender.
+ */
+
+ set_size_request_to_display_given_text (*automate_button.get_child(), _("Mgnual"), 5, 5);
+
+ ignore_change = 0;
+ display = 0;
+ button = 0;
+ control = 0;
+ clickbox = 0;
+ adjustment = 0;
+ meterinfo = 0;
+}
+
+GenericPluginUI::ControlUI::~ControlUI()
+{
+ if (adjustment) {
+ delete adjustment;
+ }
+
+ if (meterinfo) {
+ delete meterinfo->meter;
+ delete meterinfo;
+ }
+}
+
+void
+GenericPluginUI::automation_state_changed (ControlUI* cui)
+{
+ /* update button label */
+
+ switch (insert->get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) {
+ case Off:
+ cui->automate_button.set_label (_("Manual"));
+ break;
+ case Play:
+ cui->automate_button.set_label (_("Play"));
+ break;
+ case Write:
+ cui->automate_button.set_label (_("Write"));
+ break;
+ case Touch:
+ cui->automate_button.set_label (_("Touch"));
+ break;
+ default:
+ cui->automate_button.set_label (_("???"));
+ break;
+ }
+}
+
+
+static void integer_printer (char buf[32], Adjustment &adj, void *arg)
+{
+ snprintf (buf, 32, "%.0f", adj.get_value());
+}
+
+void
+GenericPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
+{
+ plugin->print_parameter (param, buf, len);
+}
+
+GenericPluginUI::ControlUI*
+GenericPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontrol)
+
+{
+ ControlUI* control_ui;
+ Plugin::ParameterDescriptor desc;
+
+ plugin->get_parameter_descriptor (port_index, desc);
+
+ control_ui = manage (new ControlUI ());
+ control_ui->adjustment = 0;
+ control_ui->combo = 0;
+ control_ui->combo_map = 0;
+ control_ui->port_index = port_index;
+ control_ui->update_pending = false;
+ control_ui->label.set_text (desc.label);
+ control_ui->label.set_alignment (0.0, 0.5);
+ control_ui->label.set_name ("PluginParameterLabel");
+
+ control_ui->set_spacing (5);
+
+ Gtk::Requisition req (control_ui->automate_button.size_request());
+
+ if (plugin->parameter_is_input (port_index)) {
+
+ boost::shared_ptr<LadspaPlugin> lp;
+
+ if ((lp = boost::dynamic_pointer_cast<LadspaPlugin>(plugin)) != 0) {
+
+ // all LADPSA plugins have a numeric unique ID
+ uint32_t id = atol (lp->unique_id().c_str());
+
+ lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index);
+
+ if (defaults && defaults->count > 0) {
+
+ control_ui->combo = new Gtk::ComboBoxText;
+ //control_ui->combo->set_value_in_list(true, false);
+ set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
+ control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
+ plugin->ParameterChanged.connect (bind (mem_fun (*this, &GenericPluginUI::parameter_changed), control_ui));
+ control_ui->pack_start(control_ui->label, true, true);
+ control_ui->pack_start(*control_ui->combo, false, true);
+
+ update_control_display(control_ui);
+
+ lrdf_free_setting_values(defaults);
+ return control_ui;
+ }
+ }
+
+ if (desc.toggled) {
+
+ /* Build a button */
+
+ control_ui->button = manage (new ToggleButton ());
+ control_ui->button->set_name ("PluginEditorButton");
+ control_ui->button->set_size_request (20, 20);
+
+ control_ui->pack_start (control_ui->label, true, true);
+ control_ui->pack_start (*control_ui->button, false, true);
+ control_ui->pack_start (control_ui->automate_button, false, false);
+
+ control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui));
+
+ if(plugin->get_parameter (port_index) == 1){
+ control_ui->button->set_active(true);
+ }
+
+ return control_ui;
+ }
+
+ control_ui->adjustment = new Adjustment (0, 0, 0, 0, 0);
+
+ /* XXX this code is not right yet, because it doesn't handle
+ the absence of bounds in any sensible fashion.
+ */
+
+ control_ui->adjustment->set_lower (desc.lower);
+ control_ui->adjustment->set_upper (desc.upper);
+
+ control_ui->logarithmic = desc.logarithmic;
+ if (control_ui->logarithmic) {
+ if (control_ui->adjustment->get_lower() == 0.0) {
+ control_ui->adjustment->set_lower (control_ui->adjustment->get_upper()/10000);
+ }
+ control_ui->adjustment->set_upper (log(control_ui->adjustment->get_upper()));
+ control_ui->adjustment->set_lower (log(control_ui->adjustment->get_lower()));
+ }
+
+ float delta = desc.upper - desc.lower;
+
+ control_ui->adjustment->set_page_size (delta/100.0);
+ control_ui->adjustment->set_step_increment (desc.step);
+ control_ui->adjustment->set_page_increment (desc.largestep);
+
+ if (desc.integer_step) {
+ control_ui->clickbox = new ClickBox (control_ui->adjustment, "PluginUIClickBox");
+ Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2);
+ control_ui->clickbox->set_print_func (integer_printer, 0);
+ } else {
+ sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &GenericPluginUI::print_parameter), (uint32_t) port_index);
+
+ control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot);
+ control_ui->control->set_size_request (200, req.height);
+ control_ui->control->set_name (X_("PluginSlider"));
+ control_ui->control->set_style (BarController::LeftToRight);
+ control_ui->control->set_use_parent (true);
+
+ control_ui->control->StartGesture.connect (bind (mem_fun(*this, &GenericPluginUI::start_touch), control_ui));
+ control_ui->control->StopGesture.connect (bind (mem_fun(*this, &GenericPluginUI::stop_touch), control_ui));
+
+ }
+
+ if (control_ui->logarithmic) {
+ control_ui->adjustment->set_value(log(plugin->get_parameter(port_index)));
+ } else{
+ control_ui->adjustment->set_value(plugin->get_parameter(port_index));
+ }
+
+ /* XXX memory leak: SliderController not destroyed by ControlUI
+ destructor, and manage() reports object hierarchy
+ ambiguity.
+ */
+
+ control_ui->pack_start (control_ui->label, true, true);
+ if (desc.integer_step) {
+ control_ui->pack_start (*control_ui->clickbox, false, false);
+ } else {
+ control_ui->pack_start (*control_ui->control, false, false);
+ }
+
+ control_ui->pack_start (control_ui->automate_button, false, false);
+ control_ui->adjustment->signal_value_changed().connect (bind (mem_fun(*this, &GenericPluginUI::control_adjustment_changed), control_ui));
+ control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
+
+ automation_state_changed (control_ui);
+
+ plugin->ParameterChanged.connect (bind (mem_fun(*this, &GenericPluginUI::parameter_changed), control_ui));
+ insert->automation_list (port_index).automation_state_changed.connect
+ (bind (mem_fun(*this, &GenericPluginUI::automation_state_changed), control_ui));
+
+ } else if (plugin->parameter_is_output (port_index)) {
+
+ control_ui->display = manage (new EventBox);
+ control_ui->display->set_name ("ParameterValueDisplay");
+
+ control_ui->display_label = manage (new Label);
+
+ control_ui->display_label->set_name ("ParameterValueDisplay");
+
+ control_ui->display->add (*control_ui->display_label);
+ Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->display, "-99,99", 2, 2);
+
+ control_ui->display->show_all ();
+
+ /* set up a meter */
+ /* TODO: only make a meter if the port is Hinted for it */
+
+ MeterInfo * info = new MeterInfo(port_index);
+ control_ui->meterinfo = info;
+
+ info->meter = new FastMeter (5, 100, FastMeter::Vertical);
+
+ info->min_unbound = desc.min_unbound;
+ info->max_unbound = desc.max_unbound;
+
+ info->min = desc.lower;
+ info->max = desc.upper;
+
+ control_ui->vbox = manage (new VBox);
+ control_ui->hbox = manage (new HBox);
+
+ control_ui->label.set_angle(90);
+ control_ui->hbox->pack_start (control_ui->label, false, false);
+ control_ui->hbox->pack_start (*info->meter, false, false);
+
+ control_ui->vbox->pack_start (*control_ui->hbox, false, false);
+
+ control_ui->vbox->pack_start (*control_ui->display, false, false);
+
+ control_ui->pack_start (*control_ui->vbox);
+
+ control_ui->meterinfo->meter->show_all();
+ control_ui->meterinfo->packed = true;
+
+ output_controls.push_back (control_ui);
+ }
+
+ plugin->ParameterChanged.connect (bind (mem_fun(*this, &GenericPluginUI::parameter_changed), control_ui));
+ return control_ui;
+}
+
+void
+GenericPluginUI::start_touch (GenericPluginUI::ControlUI* cui)
+{
+ insert->automation_list (cui->port_index).start_touch ();
+}
+
+void
+GenericPluginUI::stop_touch (GenericPluginUI::ControlUI* cui)
+{
+ insert->automation_list (cui->port_index).stop_touch ();
+}
+
+void
+GenericPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
+{
+ using namespace Menu_Helpers;
+
+ if (automation_menu == 0) {
+ automation_menu = manage (new Menu);
+ automation_menu->set_name ("ArdourContextMenu");
+ }
+
+ MenuList& items (automation_menu->items());
+
+ items.clear ();
+ items.push_back (MenuElem (_("Manual"),
+ bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Off, cui)));
+ items.push_back (MenuElem (_("Play"),
+ bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Play, cui)));
+ items.push_back (MenuElem (_("Write"),
+ bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Write, cui)));
+ items.push_back (MenuElem (_("Touch"),
+ bind (mem_fun(*this, &GenericPluginUI::set_automation_state), (AutoState) Touch, cui)));
+
+ automation_menu->popup (1, gtk_get_current_event_time());
+}
+
+void
+GenericPluginUI::set_automation_state (AutoState state, ControlUI* cui)
+{
+ insert->set_port_automation_state (cui->port_index, state);
+}
+
+void
+GenericPluginUI::control_adjustment_changed (ControlUI* cui)
+{
+ if (cui->ignore_change) {
+ return;
+ }
+
+ double value = cui->adjustment->get_value();
+
+ if (cui->logarithmic) {
+ value = exp(value);
+ }
+
+ insert->set_parameter (cui->port_index, (float) value);
+}
+
+void
+GenericPluginUI::parameter_changed (uint32_t abs_port_id, float val, ControlUI* cui)
+{
+ if (cui->port_index == abs_port_id) {
+ if (!cui->update_pending) {
+ cui->update_pending = true;
+ Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &GenericPluginUI::update_control_display), cui));
+ }
+ }
+}
+
+void
+GenericPluginUI::update_control_display (ControlUI* cui)
+{
+ /* XXX how do we handle logarithmic stuff here ? */
+
+ cui->update_pending = false;
+
+ float val = plugin->get_parameter (cui->port_index);
+
+ cui->ignore_change++;
+ if (cui->combo) {
+ std::map<string,float>::iterator it;
+ for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) {
+ if (it->second == val) {
+ cui->combo->set_active_text(it->first);
+ break;
+ }
+ }
+ } else if (cui->adjustment == 0) {
+
+ if (val > 0.5) {
+ cui->button->set_active (true);
+ } else {
+ cui->button->set_active (false);
+ }
+
+ } else {
+ if (cui->logarithmic) {
+ val = log(val);
+ }
+ if (val != cui->adjustment->get_value()) {
+ cui->adjustment->set_value (val);
+ }
+ }
+ cui->ignore_change--;
+}
+
+void
+GenericPluginUI::control_port_toggled (ControlUI* cui)
+{
+ if (!cui->ignore_change) {
+ insert->set_parameter (cui->port_index, cui->button->get_active());
+ }
+}
+
+void
+GenericPluginUI::control_combo_changed (ControlUI* cui)
+{
+ if (!cui->ignore_change) {
+ string value = cui->combo->get_active_text();
+ std::map<string,float> mapping = *cui->combo_map;
+ insert->set_parameter (cui->port_index, mapping[value]);
+ }
+
+}
+
+void
+GenericPluginUI::redirect_active_changed (Redirect* r, void* src)
+{
+ ENSURE_GUI_THREAD(bind (mem_fun(*this, &GenericPluginUI::redirect_active_changed), r, src));
+
+ bypass_button.set_active (!r->active());
+}
+
+bool
+GenericPluginUI::start_updating (GdkEventAny* ignored)
+{
+ if (output_controls.size() > 0 ) {
+ screen_update_connection.disconnect();
+ screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect
+ (mem_fun(*this, &GenericPluginUI::output_update));
+ }
+ return false;
+}
+
+bool
+GenericPluginUI::stop_updating (GdkEventAny* ignored)
+{
+ if (output_controls.size() > 0 ) {
+ screen_update_connection.disconnect();
+ }
+ return false;
+}
+
+void
+GenericPluginUI::output_update ()
+{
+ for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) {
+ float val = plugin->get_parameter ((*i)->port_index);
+ char buf[32];
+ snprintf (buf, sizeof(buf), "%.2f", val);
+ (*i)->display_label->set_text (buf);
+
+ /* autoscaling for the meter */
+ if ((*i)->meterinfo && (*i)->meterinfo->packed) {
+
+ if (val < (*i)->meterinfo->min) {
+ if ((*i)->meterinfo->min_unbound)
+ (*i)->meterinfo->min = val;
+ else
+ val = (*i)->meterinfo->min;
+ }
+
+ if (val > (*i)->meterinfo->max) {
+ if ((*i)->meterinfo->max_unbound)
+ (*i)->meterinfo->max = val;
+ else
+ val = (*i)->meterinfo->max;
+ }
+
+ if ((*i)->meterinfo->max > (*i)->meterinfo->min ) {
+ float lval = (val - (*i)->meterinfo->min) / ((*i)->meterinfo->max - (*i)->meterinfo->min) ;
+ (*i)->meterinfo->meter->set (lval );
+ }
+ }
+ }
+}
+
+vector<string>
+GenericPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
+{
+ vector<string> enums;
+ boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin);
+
+ if (!lp) {
+ return enums;
+ }
+
+ // all LADPSA plugins have a numeric unique ID
+ uint32_t id = atol (lp->unique_id().c_str());
+
+ cui->combo_map = new std::map<string, float>;
+ lrdf_defaults* defaults = lrdf_get_scale_values(id, port_index);
+ if (defaults) {
+ for (uint32_t i = 0; i < defaults->count; ++i) {
+ enums.push_back(defaults->items[i].label);
+ pair<string, float> newpair;
+ newpair.first = defaults->items[i].label;
+ newpair.second = defaults->items[i].value;
+ cui->combo_map->insert(newpair);
+ }
+
+ lrdf_free_setting_values(defaults);
+ }
+
+ return enums;
+}
if (find (state.begin(), state.end(), keyval) == state.end()) {
state.push_back (keyval);
sort (state.begin(), state.end());
- }
+ }
} else if (event->type == GDK_KEY_RELEASE) {
+++ /dev/null
-/*
- Copyright (C) 2000 Paul Davis
-
- 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <climits>
-#include <cerrno>
-#include <cmath>
-#include <string>
-
-#include <pbd/stl_delete.h>
-#include <pbd/xml++.h>
-#include <pbd/failed_constructor.h>
-
-#include <gtkmm2ext/click_box.h>
-#include <gtkmm2ext/fastmeter.h>
-#include <gtkmm2ext/barcontroller.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/doi.h>
-#include <gtkmm2ext/slider_controller.h>
-
-#include <midi++/manager.h>
-
-#include <ardour/plugin.h>
-#include <ardour/insert.h>
-#include <ardour/ladspa_plugin.h>
-
-#include <lrdf.h>
-
-#include "ardour_ui.h"
-#include "prompter.h"
-#include "plugin_ui.h"
-#include "utils.h"
-#include "gui_thread.h"
-
-#include "i18n.h"
-
-using namespace std;
-using namespace ARDOUR;
-using namespace PBD;
-using namespace Gtkmm2ext;
-using namespace Gtk;
-using namespace sigc;
-
-LadspaPluginUI::LadspaPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrollable)
- : PlugUIBase (pi),
- button_table (initial_button_rows, initial_button_cols),
- output_table (initial_output_rows, initial_output_cols),
- hAdjustment(0.0, 0.0, 0.0),
- vAdjustment(0.0, 0.0, 0.0),
- scroller_view(hAdjustment, vAdjustment),
- automation_menu (0),
- is_scrollable(scrollable)
-{
- set_name ("PluginEditor");
- set_border_width (10);
- set_homogeneous (false);
-
- settings_box.set_homogeneous (false);
-
- HBox* constraint_hbox = manage (new HBox);
- HBox* smaller_hbox = manage (new HBox);
- Label* combo_label = manage (new Label (_("<span size=\"large\">Presets</span>")));
- combo_label->set_use_markup (true);
-
- smaller_hbox->pack_start (*combo_label, false, false, 10);
- smaller_hbox->pack_start (combo, false, false);
- smaller_hbox->pack_start (save_button, false, false);
-
- constraint_hbox->set_spacing (5);
- constraint_hbox->pack_start (*smaller_hbox, true, false);
- constraint_hbox->pack_end (bypass_button, false, false);
-
- settings_box.pack_end (*constraint_hbox, false, false);
-
- pack_start (settings_box, false, false);
-
- if ( is_scrollable ) {
- scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- scroller.set_name ("PluginEditor");
- scroller_view.set_name("PluginEditor");
- scroller_view.add (hpacker);
- scroller.add (scroller_view);
-
- pack_start (scroller, true, true);
-
- }
- else {
- pack_start (hpacker, false, false);
- }
-
- insert->active_changed.connect (mem_fun(*this, &LadspaPluginUI::redirect_active_changed));
- bypass_button.set_active (!insert->active());
-
- build ();
-}
-
-LadspaPluginUI::~LadspaPluginUI ()
-{
- if (output_controls.size() > 0) {
- screen_update_connection.disconnect();
- }
-}
-
-void
-LadspaPluginUI::build ()
-
-{
- guint32 i = 0;
- guint32 x = 0;
- Frame* frame;
- Frame* bt_frame;
- VBox* box;
- int output_row, output_col;
- int button_row, button_col;
- int output_rows, output_cols;
- int button_rows, button_cols;
- guint32 n_ins=0, n_outs = 0;
-
- prefheight = 30;
- hpacker.set_spacing (10);
-
- output_rows = initial_output_rows;
- output_cols = initial_output_cols;
- button_rows = initial_button_rows;
- button_cols = initial_button_cols;
- output_row = 0;
- button_row = 0;
- output_col = 0;
- button_col = 0;
-
- button_table.set_homogeneous (false);
- button_table.set_row_spacings (2);
- button_table.set_col_spacings (2);
- output_table.set_homogeneous (true);
- output_table.set_row_spacings (2);
- output_table.set_col_spacings (2);
- button_table.set_border_width (5);
- output_table.set_border_width (5);
-
- hpacker.set_border_width (10);
-
- bt_frame = manage (new Frame);
- bt_frame->set_name ("BaseFrame");
- bt_frame->add (button_table);
- hpacker.pack_start(*bt_frame, true, true);
-
- box = manage (new VBox);
- box->set_border_width (5);
- box->set_spacing (1);
-
- frame = manage (new Frame);
- frame->set_name ("BaseFrame");
- frame->set_label (_("Controls"));
- frame->add (*box);
- hpacker.pack_start(*frame, true, true);
-
- /* find all ports. build control elements for all appropriate control ports */
-
- for (i = 0; i < plugin->parameter_count(); ++i) {
-
- if (plugin->parameter_is_control (i)) {
-
- /* Don't show latency control ports */
-
- if (plugin->describe_parameter (i) == X_("latency")) {
- continue;
- }
-
- ControlUI* cui;
-
- /* if we are scrollable, just use one long column */
-
- if (!is_scrollable) {
- if (x++ > 7){
- frame = manage (new Frame);
- frame->set_name ("BaseFrame");
- box = manage (new VBox);
-
- box->set_border_width (5);
- box->set_spacing (1);
-
- frame->add (*box);
- hpacker.pack_start(*frame,true,true);
-
- x = 1;
- }
- }
-
- if ((cui = build_control_ui (i, plugin->get_nth_control (i))) == 0) {
- error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
- continue;
- }
-
- if (cui->control || cui->clickbox || cui->combo) {
-
- box->pack_start (*cui, false, false);
-
- } else if (cui->button) {
-
- if (button_row == button_rows) {
- button_row = 0;
- if (++button_col == button_cols) {
- button_cols += 2;
- button_table.resize (button_rows, button_cols);
- }
- }
-
- button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1,
- FILL|EXPAND, FILL);
- button_row++;
-
- } else if (cui->display) {
-
- output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1,
- FILL|EXPAND, FILL);
-
- // TODO: The meters should be divided into multiple rows
-
- if (++output_col == output_cols) {
- output_cols ++;
- output_table.resize (output_rows, output_cols);
- }
-
- /* old code, which divides meters into
- * columns first, rows later. New code divides into one row
-
- if (output_row == output_rows) {
- output_row = 0;
- if (++output_col == output_cols) {
- output_cols += 2;
- output_table.resize (output_rows, output_cols);
- }
- }
-
- output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1,
- FILL|EXPAND, FILL);
-
- output_row++;
- */
- }
-
- /* HACK: ideally the preferred height would be queried from
- the complete hpacker, but I can't seem to get that
- information in time, so this is an estimation
- */
-
- prefheight += 30;
-
- }
- }
-
- n_ins = plugin->get_info()->n_inputs;
- n_outs = plugin->get_info()->n_outputs;
-
- if (box->children().empty()) {
- hpacker.remove (*frame);
- }
-
- if (button_table.children().empty()) {
- hpacker.remove (*bt_frame);
- }
-
- if (!output_table.children().empty()) {
- frame = manage (new Frame);
- frame->set_name ("BaseFrame");
- frame->add (output_table);
- hpacker.pack_end (*frame, true, true);
- }
-
- output_update ();
-
- output_table.show_all ();
- button_table.show_all ();
-}
-
-LadspaPluginUI::ControlUI::ControlUI ()
- : automate_button (X_("")) // force creation of a label
-{
- automate_button.set_name ("PluginAutomateButton");
- ARDOUR_UI::instance()->tooltips().set_tip (automate_button, _("Automation control"));
-
- /* XXX translators: use a string here that will be at least as long
- as the longest automation label (see ::automation_state_changed()
- below). be sure to include a descender.
- */
-
- set_size_request_to_display_given_text (*automate_button.get_child(), _("Mgnual"), 5, 5);
-
- ignore_change = 0;
- display = 0;
- button = 0;
- control = 0;
- clickbox = 0;
- adjustment = 0;
- meterinfo = 0;
-}
-
-LadspaPluginUI::ControlUI::~ControlUI()
-{
- if (adjustment) {
- delete adjustment;
- }
-
- if (meterinfo) {
- delete meterinfo->meter;
- delete meterinfo;
- }
-}
-
-void
-LadspaPluginUI::automation_state_changed (ControlUI* cui)
-{
- /* update button label */
-
- switch (insert->get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) {
- case Off:
- cui->automate_button.set_label (_("Manual"));
- break;
- case Play:
- cui->automate_button.set_label (_("Play"));
- break;
- case Write:
- cui->automate_button.set_label (_("Write"));
- break;
- case Touch:
- cui->automate_button.set_label (_("Touch"));
- break;
- default:
- cui->automate_button.set_label (_("???"));
- break;
- }
-}
-
-
-static void integer_printer (char buf[32], Adjustment &adj, void *arg)
-{
- snprintf (buf, 32, "%.0f", adj.get_value());
-}
-
-void
-LadspaPluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
-{
- plugin->print_parameter (param, buf, len);
-}
-
-LadspaPluginUI::ControlUI*
-LadspaPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontrol)
-
-{
- ControlUI* control_ui;
- Plugin::ParameterDescriptor desc;
-
- plugin->get_parameter_descriptor (port_index, desc);
-
- control_ui = manage (new ControlUI ());
- control_ui->adjustment = 0;
- control_ui->combo = 0;
- control_ui->combo_map = 0;
- control_ui->port_index = port_index;
- control_ui->update_pending = false;
- control_ui->label.set_text (desc.label);
- control_ui->label.set_alignment (0.0, 0.5);
- control_ui->label.set_name ("PluginParameterLabel");
-
- control_ui->set_spacing (5);
-
- Gtk::Requisition req (control_ui->automate_button.size_request());
-
- if (plugin->parameter_is_input (port_index)) {
-
- boost::shared_ptr<LadspaPlugin> lp;
-
- if ((lp = boost::dynamic_pointer_cast<LadspaPlugin>(plugin)) != 0) {
-
- lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index);
-
- if (defaults && defaults->count > 0) {
-
- control_ui->combo = new Gtk::ComboBoxText;
- //control_ui->combo->set_value_in_list(true, false);
- set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
- control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_combo_changed), control_ui));
- plugin->ParameterChanged.connect (bind (mem_fun (*this, &LadspaPluginUI::parameter_changed), control_ui));
- control_ui->pack_start(control_ui->label, true, true);
- control_ui->pack_start(*control_ui->combo, false, true);
-
- update_control_display(control_ui);
-
- lrdf_free_setting_values(defaults);
- return control_ui;
- }
- }
-
- if (desc.toggled) {
-
- /* Build a button */
-
- control_ui->button = manage (new ToggleButton ());
- control_ui->button->set_name ("PluginEditorButton");
- control_ui->button->set_size_request (20, 20);
-
- control_ui->pack_start (control_ui->label, true, true);
- control_ui->pack_start (*control_ui->button, false, true);
- control_ui->pack_start (control_ui->automate_button, false, false);
-
- control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::control_port_toggled), control_ui));
-
- if(plugin->get_parameter (port_index) == 1){
- control_ui->button->set_active(true);
- }
-
- return control_ui;
- }
-
- control_ui->adjustment = new Adjustment (0, 0, 0, 0, 0);
-
- /* XXX this code is not right yet, because it doesn't handle
- the absence of bounds in any sensible fashion.
- */
-
- control_ui->adjustment->set_lower (desc.lower);
- control_ui->adjustment->set_upper (desc.upper);
-
- control_ui->logarithmic = desc.logarithmic;
- if (control_ui->logarithmic) {
- if (control_ui->adjustment->get_lower() == 0.0) {
- control_ui->adjustment->set_lower (control_ui->adjustment->get_upper()/10000);
- }
- control_ui->adjustment->set_upper (log(control_ui->adjustment->get_upper()));
- control_ui->adjustment->set_lower (log(control_ui->adjustment->get_lower()));
- }
-
- float delta = desc.upper - desc.lower;
-
- control_ui->adjustment->set_page_size (delta/100.0);
- control_ui->adjustment->set_step_increment (desc.step);
- control_ui->adjustment->set_page_increment (desc.largestep);
-
- if (desc.integer_step) {
- control_ui->clickbox = new ClickBox (control_ui->adjustment, "PluginUIClickBox");
- Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->clickbox, "g9999999", 2, 2);
- control_ui->clickbox->set_print_func (integer_printer, 0);
- } else {
- sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &LadspaPluginUI::print_parameter), (uint32_t) port_index);
-
- control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot);
- control_ui->control->set_size_request (200, req.height);
- control_ui->control->set_name (X_("PluginSlider"));
- control_ui->control->set_style (BarController::LeftToRight);
- control_ui->control->set_use_parent (true);
-
- control_ui->control->StartGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::start_touch), control_ui));
- control_ui->control->StopGesture.connect (bind (mem_fun(*this, &LadspaPluginUI::stop_touch), control_ui));
-
- }
-
- if (control_ui->logarithmic) {
- control_ui->adjustment->set_value(log(plugin->get_parameter(port_index)));
- } else{
- control_ui->adjustment->set_value(plugin->get_parameter(port_index));
- }
-
- /* XXX memory leak: SliderController not destroyed by ControlUI
- destructor, and manage() reports object hierarchy
- ambiguity.
- */
-
- control_ui->pack_start (control_ui->label, true, true);
- if (desc.integer_step) {
- control_ui->pack_start (*control_ui->clickbox, false, false);
- } else {
- control_ui->pack_start (*control_ui->control, false, false);
- }
-
- control_ui->pack_start (control_ui->automate_button, false, false);
- control_ui->adjustment->signal_value_changed().connect (bind (mem_fun(*this, &LadspaPluginUI::control_adjustment_changed), control_ui));
- control_ui->automate_button.signal_clicked().connect (bind (mem_fun(*this, &LadspaPluginUI::astate_clicked), control_ui, (uint32_t) port_index));
-
- automation_state_changed (control_ui);
-
- plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
- insert->automation_list (port_index).automation_state_changed.connect
- (bind (mem_fun(*this, &LadspaPluginUI::automation_state_changed), control_ui));
-
- } else if (plugin->parameter_is_output (port_index)) {
-
- control_ui->display = manage (new EventBox);
- control_ui->display->set_name ("ParameterValueDisplay");
-
- control_ui->display_label = manage (new Label);
-
- control_ui->display_label->set_name ("ParameterValueDisplay");
-
- control_ui->display->add (*control_ui->display_label);
- Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->display, "-99,99", 2, 2);
-
- control_ui->display->show_all ();
-
- /* set up a meter */
- /* TODO: only make a meter if the port is Hinted for it */
-
- MeterInfo * info = new MeterInfo(port_index);
- control_ui->meterinfo = info;
-
- info->meter = new FastMeter (5, 5, FastMeter::Vertical);
-
- info->min_unbound = desc.min_unbound;
- info->max_unbound = desc.max_unbound;
-
- info->min = desc.lower;
- info->max = desc.upper;
-
- control_ui->vbox = manage (new VBox);
- control_ui->hbox = manage (new HBox);
-
- control_ui->label.set_angle(90);
- control_ui->hbox->pack_start (control_ui->label, false, false);
- control_ui->hbox->pack_start (*info->meter, false, false);
-
- control_ui->vbox->pack_start (*control_ui->hbox, false, false);
-
- control_ui->vbox->pack_start (*control_ui->display, false, false);
-
- control_ui->pack_start (*control_ui->vbox);
-
- control_ui->meterinfo->meter->show_all();
- control_ui->meterinfo->packed = true;
-
- output_controls.push_back (control_ui);
- }
-
- plugin->ParameterChanged.connect (bind (mem_fun(*this, &LadspaPluginUI::parameter_changed), control_ui));
- return control_ui;
-}
-
-void
-LadspaPluginUI::start_touch (LadspaPluginUI::ControlUI* cui)
-{
- insert->automation_list (cui->port_index).start_touch ();
-}
-
-void
-LadspaPluginUI::stop_touch (LadspaPluginUI::ControlUI* cui)
-{
- insert->automation_list (cui->port_index).stop_touch ();
-}
-
-void
-LadspaPluginUI::astate_clicked (ControlUI* cui, uint32_t port)
-{
- using namespace Menu_Helpers;
-
- if (automation_menu == 0) {
- automation_menu = manage (new Menu);
- automation_menu->set_name ("ArdourContextMenu");
- }
-
- MenuList& items (automation_menu->items());
-
- items.clear ();
- items.push_back (MenuElem (_("Manual"),
- bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Off, cui)));
- items.push_back (MenuElem (_("Play"),
- bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Play, cui)));
- items.push_back (MenuElem (_("Write"),
- bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Write, cui)));
- items.push_back (MenuElem (_("Touch"),
- bind (mem_fun(*this, &LadspaPluginUI::set_automation_state), (AutoState) Touch, cui)));
-
- automation_menu->popup (1, gtk_get_current_event_time());
-}
-
-void
-LadspaPluginUI::set_automation_state (AutoState state, ControlUI* cui)
-{
- insert->set_port_automation_state (cui->port_index, state);
-}
-
-void
-LadspaPluginUI::control_adjustment_changed (ControlUI* cui)
-{
- if (cui->ignore_change) {
- return;
- }
-
- double value = cui->adjustment->get_value();
-
- if (cui->logarithmic) {
- value = exp(value);
- }
-
- insert->set_parameter (cui->port_index, (float) value);
-}
-
-void
-LadspaPluginUI::parameter_changed (uint32_t abs_port_id, float val, ControlUI* cui)
-{
- if (cui->port_index == abs_port_id) {
- if (!cui->update_pending) {
- cui->update_pending = true;
- Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &LadspaPluginUI::update_control_display), cui));
- }
- }
-}
-
-void
-LadspaPluginUI::update_control_display (ControlUI* cui)
-{
- /* XXX how do we handle logarithmic stuff here ? */
-
- cui->update_pending = false;
-
- float val = plugin->get_parameter (cui->port_index);
-
- cui->ignore_change++;
- if (cui->combo) {
- std::map<string,float>::iterator it;
- for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) {
- if (it->second == val) {
- cui->combo->set_active_text(it->first);
- break;
- }
- }
- } else if (cui->adjustment == 0) {
-
- if (val > 0.5) {
- cui->button->set_active (true);
- } else {
- cui->button->set_active (false);
- }
-
- } else {
- if (cui->logarithmic) {
- val = log(val);
- }
- if (val != cui->adjustment->get_value()) {
- cui->adjustment->set_value (val);
- }
- }
- cui->ignore_change--;
-}
-
-void
-LadspaPluginUI::control_port_toggled (ControlUI* cui)
-{
- if (!cui->ignore_change) {
- insert->set_parameter (cui->port_index, cui->button->get_active());
- }
-}
-
-void
-LadspaPluginUI::control_combo_changed (ControlUI* cui)
-{
- if (!cui->ignore_change) {
- string value = cui->combo->get_active_text();
- std::map<string,float> mapping = *cui->combo_map;
- insert->set_parameter (cui->port_index, mapping[value]);
- }
-
-}
-
-void
-LadspaPluginUI::redirect_active_changed (Redirect* r, void* src)
-{
- ENSURE_GUI_THREAD(bind (mem_fun(*this, &LadspaPluginUI::redirect_active_changed), r, src));
-
- bypass_button.set_active (!r->active());
-}
-
-bool
-LadspaPluginUI::start_updating (GdkEventAny* ignored)
-{
- if (output_controls.size() > 0 ) {
- screen_update_connection.disconnect();
- screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect
- (mem_fun(*this, &LadspaPluginUI::output_update));
- }
- return false;
-}
-
-bool
-LadspaPluginUI::stop_updating (GdkEventAny* ignored)
-{
- if (output_controls.size() > 0 ) {
- screen_update_connection.disconnect();
- }
- return false;
-}
-
-void
-LadspaPluginUI::output_update ()
-{
- for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) {
- float val = plugin->get_parameter ((*i)->port_index);
- char buf[32];
- snprintf (buf, sizeof(buf), "%.2f", val);
- (*i)->display_label->set_text (buf);
-
- /* autoscaling for the meter */
- if ((*i)->meterinfo && (*i)->meterinfo->packed) {
-
- if (val < (*i)->meterinfo->min) {
- if ((*i)->meterinfo->min_unbound)
- (*i)->meterinfo->min = val;
- else
- val = (*i)->meterinfo->min;
- }
-
- if (val > (*i)->meterinfo->max) {
- if ((*i)->meterinfo->max_unbound)
- (*i)->meterinfo->max = val;
- else
- val = (*i)->meterinfo->max;
- }
-
- if ((*i)->meterinfo->max > (*i)->meterinfo->min ) {
- float lval = (val - (*i)->meterinfo->min) / ((*i)->meterinfo->max - (*i)->meterinfo->min) ;
- (*i)->meterinfo->meter->set (lval );
- }
- }
- }
-}
-
-vector<string>
-LadspaPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
-{
- vector<string> enums;
- boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin);
-
- cui->combo_map = new std::map<string, float>;
- lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index);
- if (defaults) {
- for (uint32_t i = 0; i < defaults->count; ++i) {
- enums.push_back(defaults->items[i].label);
- pair<string, float> newpair;
- newpair.first = defaults->items[i].label;
- newpair.second = defaults->items[i].value;
- cui->combo_map->insert(newpair);
- }
-
- lrdf_free_setting_values(defaults);
- }
-
- return enums;
-}
}
void
-NewSessionDialog::set_session_name(const Glib::ustring& name)
+NewSessionDialog::set_session_name (const Glib::ustring& name)
{
- m_name->set_text(name);
+ m_name->set_text (name);
}
void
NewSessionDialog::set_session_folder(const Glib::ustring& dir)
{
- // XXX DO SOMETHING
+ m_folder->set_current_folder (dir);
}
std::string
manager = mgr;
session = 0;
- current_selection = ARDOUR::LADSPA;
-
- lmodel = Gtk::ListStore::create(lcols);
- ladspa_display.set_model (lmodel);
- ladspa_display.append_column (_("Available LADSPA Plugins"), lcols.name);
- ladspa_display.append_column (_("Type"), lcols.type);
- ladspa_display.append_column (_("# Inputs"),lcols.ins);
- ladspa_display.append_column (_("# Outputs"), lcols.outs);
- ladspa_display.set_headers_visible (true);
- ladspa_display.set_headers_clickable (true);
- ladspa_display.set_reorderable (false);
- lscroller.set_border_width(10);
- lscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- lscroller.add(ladspa_display);
+ plugin_model = Gtk::ListStore::create (plugin_columns);
+ plugin_display.set_model (plugin_model);
+ plugin_display.append_column (_("Available Plugins"), plugin_columns.name);
+ plugin_display.append_column (_("Type"), plugin_columns.type_name);
+ plugin_display.append_column (_("Category"), plugin_columns.category);
+ plugin_display.append_column (_("Creator"), plugin_columns.creator);
+ plugin_display.append_column (_("# Inputs"),plugin_columns.ins);
+ plugin_display.append_column (_("# Outputs"), plugin_columns.outs);
+ plugin_display.set_headers_visible (true);
+ plugin_display.set_headers_clickable (true);
+ plugin_display.set_reorderable (false);
+ scroller.set_border_width(10);
+ scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ scroller.add(plugin_display);
amodel = Gtk::ListStore::create(acols);
added_list.set_model (amodel);
added_list.set_reorderable (false);
for (int i = 0; i <=3; i++) {
- Gtk::TreeView::Column* column = ladspa_display.get_column(i);
+ Gtk::TreeView::Column* column = plugin_display.get_column(i);
column->set_sort_column(i);
}
-#ifdef VST_SUPPORT
- vmodel = ListStore::create(vcols);
- vst_display.set_model (vmodel);
- vst_display.append_column (_("Available plugins"), vcols.name);
- vst_display.append_column (_("# Inputs"), vcols.ins);
- vst_display.append_column (_("# Outputs"), vcols.outs);
- vst_display.set_headers_visible (true);
- vst_display.set_headers_clickable (true);
- vst_display.set_reorderable (false);
- vscroller.set_border_width(10);
- vscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- vscroller.add(vst_display);
-
- for (int i = 0; i <=2; i++) {
- Gtk::TreeView::Column* column = vst_display.get_column(i);
- column->set_sort_column(i);
- }
-#endif
-
-#ifdef HAVE_AUDIOUNIT
- aumodel = ListStore::create(aucols);
- au_display.set_model (aumodel);
- au_display.append_column (_("Available plugins"), aucols.name);
- au_display.append_column (_("# Inputs"), aucols.ins);
- au_display.append_column (_("# Outputs"), aucols.outs);
- au_display.set_headers_visible (true);
- au_display.set_headers_clickable (true);
- au_display.set_reorderable (false);
- auscroller.set_border_width(10);
- auscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- auscroller.add(au_display);
-
- for (int i = 0; i <=2; i++) {
- Gtk::TreeView::Column* column = au_display.get_column(i);
- column->set_sort_column(i);
- }
-#endif
-
ascroller.set_border_width(10);
ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
ascroller.add(added_list);
Gtk::Table* table = manage(new Gtk::Table(7, 11));
table->set_size_request(750, 500);
- table->attach(notebook, 0, 7, 0, 5);
+ table->attach(scroller, 0, 7, 0, 5);
HBox* filter_box = manage (new HBox);
table->attach(ascroller, 0, 7, 8, 10);
add_button (Stock::CANCEL, RESPONSE_CANCEL);
- add_button (Stock::CONNECT, RESPONSE_APPLY);
+ add_button (_("Insert Plugin(s)"), RESPONSE_APPLY);
set_default_response (RESPONSE_APPLY);
set_response_sensitive (RESPONSE_APPLY, false);
get_vbox()->pack_start (*table);
-
- // Notebook tab order must be the same in here as in set_correct_focus()
- using namespace Notebook_Helpers;
- notebook.pages().push_back (TabElem (lscroller, _("LADSPA")));
-
-#ifdef VST_SUPPORT
- if (Config->get_use_vst()) {
- notebook.pages().push_back (TabElem (vscroller, _("VST")));
- }
-#endif
-
-#ifdef HAVE_AUDIOUNIT
- notebook.pages().push_back (TabElem (auscroller, _("AudioUnit")));
-#endif
-
table->set_name("PluginSelectorTable");
- ladspa_display.set_name("PluginSelectorDisplay");
- //ladspa_display.set_name("PluginSelectorList");
+ plugin_display.set_name("PluginSelectorDisplay");
+ //plugin_display.set_name("PluginSelectorList");
added_list.set_name("PluginSelectorList");
- ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
- ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed));
- ladspa_display.grab_focus();
+ plugin_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
+ plugin_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::display_selection_changed));
+ plugin_display.grab_focus();
-#ifdef VST_SUPPORT
- if (Config->get_use_vst()) {
- vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
- vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed));
- }
-#endif
-
-#ifdef HAVE_AUDIOUNIT
- au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
- au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed));
-#endif
-
btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked));
btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked));
btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked));
added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed));
- ladspa_refiller ();
-
-#ifdef VST_SUPPORT
- vst_refiller ();
-#endif
-
-#ifdef HAVE_AUDIOUNIT
- au_refiller ();
-#endif
-
- signal_show().connect (mem_fun (*this, &PluginSelector::set_correct_focus));
-}
-
-/**
- * Makes sure keyboard focus is always in the plugin list
- * of the selected notebook tab.
- **/
-void
-PluginSelector::set_correct_focus()
-{
- int cp = notebook.get_current_page();
-
- if (cp == 0) {
- ladspa_display.grab_focus();
- return;
- }
-
-#ifdef VST_SUPPORT
- if (Config->get_use_vst()) {
- cp--;
-
- if (cp == 0) {
- vst_display.grab_focus();
- return;
- }
- }
-#endif
-
-#ifdef HAVE_AUDIOUNIT
- cp--;
-
- if (cp == 0) {
- au_display.grab_focus();
- return;
- }
-#endif
+ refill ();
}
void
}
bool
-PluginSelector::show_this_plugin (PluginInfoPtr& info, const std::string& filterstr)
+PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string& filterstr)
{
std::string compstr;
std::string mode = filter_mode.get_active_text ();
}
void
-PluginSelector::ladspa_refiller ()
+PluginSelector::refill ()
{
- guint row;
- PluginInfoList &plugs = manager->ladspa_plugin_info ();
- PluginInfoList::iterator i;
- char ibuf[16], obuf[16];
-
- lmodel->clear();
-
std::string filterstr;
- setup_filter_string (filterstr);
- for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
+ plugin_model->clear ();
- if (show_this_plugin (*i, filterstr)) {
-
- snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
- snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);
- TreeModel::Row newrow = *(lmodel->append());
- newrow[lcols.name] = (*i)->name.c_str();
- newrow[lcols.type] = (*i)->category.c_str();
- newrow[lcols.ins] = ibuf;
- newrow[lcols.outs] = obuf;
- newrow[lcols.plugin] = *i;
- }
- }
+ setup_filter_string (filterstr);
- lmodel->set_sort_column (0, SORT_ASCENDING);
+ ladspa_refiller (filterstr);
+ vst_refiller (filterstr);
+ au_refiller (filterstr);
}
-#ifdef VST_SUPPORT
-
void
-PluginSelector::vst_refiller ()
+PluginSelector::refiller (const PluginInfoList& plugs, const::std::string& filterstr, const char* type)
{
- guint row;
- PluginInfoList &plugs = manager->vst_plugin_info ();
- PluginInfoList::iterator i;
- char ibuf[16], obuf[16];
- vmodel->clear();
-
- std::string filterstr;
- setup_filter_string (filterstr);
-
- for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
+ char buf[16];
+
+ for (PluginInfoList::const_iterator i = plugs.begin(); i != plugs.end(); ++i) {
if (show_this_plugin (*i, filterstr)) {
- snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
- snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);
-
- TreeModel::Row newrow = *(vmodel->append());
- newrow[vcols.name] = (*i)->name.c_str();
- newrow[vcols.ins] = ibuf;
- newrow[vcols.outs] = obuf;
- newrow[vcols.plugin] = *i;
- }
- }
- vmodel->set_sort_column (0, SORT_ASCENDING);
-}
-void
-PluginSelector::vst_display_selection_changed()
-{
- if (vst_display.get_selection()->count_selected_rows() != 0) {
- btn_add->set_sensitive (true);
- } else {
- btn_add->set_sensitive (false);
- }
+ TreeModel::Row newrow = *(plugin_model->append());
+ newrow[plugin_columns.name] = (*i)->name;
+ newrow[plugin_columns.type_name] = type;
+ newrow[plugin_columns.category] = (*i)->category;
- current_selection = ARDOUR::VST;
-}
-#endif //VST_SUPPORT
+ string creator = (*i)->creator;
+ string::size_type pos = 0;
-#ifdef HAVE_AUDIOUNIT
+ /* stupid LADSPA creator strings */
-void
-PluginSelector::au_refiller ()
-{
- guint row;
- PluginInfoList plugs (AUPluginInfo::discover ());
- PluginInfoList::iterator i;
- char ibuf[16], obuf[16];
- aumodel->clear();
-
- std::string filterstr;
- setup_filter_string (filterstr);
-
- for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
+ while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos;
+ creator = creator.substr (0, pos);
- if (show_this_plugin (*i, filterstr)) {
+ newrow[plugin_columns.creator] = creator;
+
+ if ((*i)->n_inputs < 0) {
+ newrow[plugin_columns.ins] = "various";
+ } else {
+ snprintf (buf, sizeof(buf), "%d", (*i)->n_inputs);
+ newrow[plugin_columns.ins] = buf;
+ }
+ if ((*i)->n_outputs < 0) {
+ newrow[plugin_columns.outs] = "various";
+ } else {
+ snprintf (buf, sizeof(buf), "%d", (*i)->n_outputs);
+ newrow[plugin_columns.outs] = buf;
+ }
- snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
- snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);
-
- TreeModel::Row newrow = *(aumodel->append());
- newrow[aucols.name] = (*i)->name.c_str();
- newrow[aucols.ins] = ibuf;
- newrow[aucols.outs] = obuf;
- newrow[aucols.plugin] = *i;
+ newrow[plugin_columns.plugin] = *i;
}
- }
+ }
+}
- aumodel->set_sort_column (0, SORT_ASCENDING);
+void
+PluginSelector::ladspa_refiller (const std::string& filterstr)
+{
+ refiller (manager->ladspa_plugin_info(), filterstr, "LADSPA");
}
void
-PluginSelector::au_display_selection_changed()
+PluginSelector::vst_refiller (const std::string& filterstr)
{
- if (au_display.get_selection()->count_selected_rows() != 0) {
- btn_add->set_sensitive (true);
- } else {
- btn_add->set_sensitive (false);
- }
-
- current_selection = ARDOUR::AudioUnit;
+#ifdef VST_SUPPORT
+ refiller (manager->vst_plugin_info(), filterstr, "VST");
+#endif
}
-#endif //HAVE_AUDIOUNIT
+void
+PluginSelector::au_refiller (const std::string& filterstr)
+{
+#ifdef HAVE_AUDIOUNITS
+ refiller (manager->au_plugin_info(), filterstr, "AU");
+#endif
+}
void
PluginSelector::use_plugin (PluginInfoPtr pi)
std::string name;
PluginInfoPtr pi;
TreeModel::Row newrow = *(amodel->append());
-
TreeModel::Row row;
- switch (current_selection) {
- case ARDOUR::LADSPA:
- row = *(ladspa_display.get_selection()->get_selected());
- name = row[lcols.name];
- pi = row[lcols.plugin];
- break;
- case ARDOUR::VST:
-#ifdef VST_SUPPORT
- row = *(vst_display.get_selection()->get_selected());
- name = row[vcols.name];
- pi = row[vcols.plugin];
-#endif
- break;
- case ARDOUR::AudioUnit:
-#ifdef HAVE_AUDIOUNIT
- row = *(au_display.get_selection()->get_selected());
- name = row[aucols.name];
- pi = row[aucols.plugin];
-#endif
- break;
- default:
- error << "Programming error. Unknown plugin selected." << endmsg;
- return;
- }
+ row = *(plugin_display.get_selection()->get_selected());
+ name = row[plugin_columns.name];
+ pi = row[plugin_columns.plugin];
newrow[acols.text] = name;
newrow[acols.plugin] = pi;
}
void
-PluginSelector::refill()
+PluginSelector::display_selection_changed()
{
- ladspa_refiller ();
-#ifdef VST_SUPPORT
- vst_refiller ();
-#endif
-#ifdef HAVE_AUDIOUNIT
- au_refiller ();
-#endif
-}
-
-void
-PluginSelector::ladspa_display_selection_changed()
-{
- if (ladspa_display.get_selection()->count_selected_rows() != 0) {
+ if (plugin_display.get_selection()->count_selected_rows() != 0) {
btn_add->set_sensitive (true);
} else {
btn_add->set_sensitive (false);
}
-
- current_selection = ARDOUR::LADSPA;
}
void
private:
ARDOUR::Session* session;
- Gtk::Notebook notebook;
- Gtk::ScrolledWindow lscroller; // ladspa
- Gtk::ScrolledWindow vscroller; // vst
- Gtk::ScrolledWindow auscroller; // AudioUnit
+ Gtk::ScrolledWindow scroller; // Available plugins
Gtk::ScrolledWindow ascroller; // Added plugins
Gtk::ComboBoxText filter_mode;
void filter_entry_changed ();
void filter_mode_changed ();
- ARDOUR::PluginType current_selection;
-
- // page 1
- struct LadspaColumns : public Gtk::TreeModel::ColumnRecord {
- LadspaColumns () {
+ struct PluginColumns : public Gtk::TreeModel::ColumnRecord {
+ PluginColumns () {
add (name);
- add (type);
+ add (type_name);
+ add (category);
+ add (creator);
add (ins);
add (outs);
add (plugin);
}
- Gtk::TreeModelColumn<std::string> name;
- Gtk::TreeModelColumn<std::string> type;
+ Gtk::TreeModelColumn<std::string> name;
+ Gtk::TreeModelColumn<std::string> type_name;
+ Gtk::TreeModelColumn<std::string> category;
+ Gtk::TreeModelColumn<std::string> creator;
Gtk::TreeModelColumn<std::string> ins;
Gtk::TreeModelColumn<std::string> outs;
- Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
+ Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
};
- LadspaColumns lcols;
- Glib::RefPtr<Gtk::ListStore> lmodel;
- Glib::RefPtr<Gtk::TreeSelection> lselection;
- Gtk::TreeView ladspa_display;
+ PluginColumns plugin_columns;
+ Glib::RefPtr<Gtk::ListStore> plugin_model;
+ Gtk::TreeView plugin_display;
Gtk::Button* btn_add;
Gtk::Button* btn_remove;
};
AddedColumns acols;
Glib::RefPtr<Gtk::ListStore> amodel;
- Glib::RefPtr<Gtk::TreeSelection> aselection;
Gtk::TreeView added_list;
-#ifdef VST_SUPPORT
- // page 2
- struct VstColumns : public Gtk::TreeModel::ColumnRecord {
- VstColumns () {
- add (name);
- add (ins);
- add (outs);
- add (plugin);
- }
- Gtk::TreeModelColumn<std::string> name;
- Gtk::TreeModelColumn<std::string> ins;
- Gtk::TreeModelColumn<std::string> outs;
- Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
- };
- VstColumns vcols;
- Glib::RefPtr<Gtk::ListStore> vmodel;
- Glib::RefPtr<Gtk::TreeSelection> vselection;
- Gtk::TreeView vst_display;
- void vst_refiller ();
- void vst_display_selection_changed();
-#endif // VST_SUPPORT
-
-#ifdef HAVE_AUDIOUNIT
- // page 3
- struct AUColumns : public Gtk::TreeModel::ColumnRecord {
- AUColumns () {
- add (name);
- add (ins);
- add (outs);
- add (plugin);
- }
- Gtk::TreeModelColumn<std::string> name;
- Gtk::TreeModelColumn<std::string> ins;
- Gtk::TreeModelColumn<std::string> outs;
- Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
- };
- AUColumns aucols;
- Glib::RefPtr<Gtk::ListStore> aumodel;
- Glib::RefPtr<Gtk::TreeSelection> auselection;
- Gtk::TreeView au_display;
- void au_refiller ();
- void au_display_selection_changed();
-#endif //HAVE_AUDIOUNIT
+ void refill ();
+ void refiller (const ARDOUR::PluginInfoList& plugs, const::std::string& filterstr, const char* type);
+ void ladspa_refiller (const std::string&);
+ void vst_refiller (const std::string&);
+ void au_refiller (const std::string&);
ARDOUR::PluginManager *manager;
- static void _ladspa_refiller (void *);
-
- void ladspa_refiller ();
void row_clicked(GdkEventButton *);
void btn_add_clicked();
void btn_remove_clicked();
void btn_update_clicked();
void added_list_selection_changed();
- void ladspa_display_selection_changed();
+ void display_selection_changed();
void btn_apply_clicked();
void use_plugin (ARDOUR::PluginInfoPtr);
void cleanup ();
- void refill ();
- bool show_this_plugin (ARDOUR::PluginInfoPtr&, const std::string&);
+ bool show_this_plugin (const ARDOUR::PluginInfoPtr&, const std::string&);
void setup_filter_string (std::string&);
-
- void set_correct_focus();
};
#endif // __ardour_plugin_selector_h__
#ifdef VST_SUPPORT
#include <ardour/vst_plugin.h>
#endif
+#ifndef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
#include <lrdf.h>
PluginUIWindow::PluginUIWindow (boost::shared_ptr<PluginInsert> insert, bool scrollable)
: ArdourDialog ("plugin ui")
{
- if (insert->plugin()->has_editor()) {
-
-#ifdef VST_SUPPORT
-
- boost::shared_ptr<VSTPlugin> vp;
+ bool have_gui = false;
+ non_gtk_gui = false;
- if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (insert->plugin())) != 0) {
-
-
- VSTPluginUI* vpu = new VSTPluginUI (insert, vp);
-
- _pluginui = vpu;
- get_vbox()->add (*vpu);
- vpu->package (*this);
+ if (insert->plugin()->has_editor()) {
+ switch (insert->type()) {
+ case ARDOUR::VST:
+ have_gui = create_vst_editor (insert);
+ break;
+
+ case ARDOUR::AudioUnit:
+ have_gui = create_audiounit_editor (insert);
+ break;
- } else {
-#endif
+ case ARDOUR::LADSPA:
+ error << _("Eh? LADSPA plugins don't have editors!") << endmsg;
+ break;
+
+ default:
error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)")
<< endmsg;
throw failed_constructor ();
-#ifdef VST_SUPPORT
}
-#endif
- } else {
+ }
- LadspaPluginUI* pu = new LadspaPluginUI (insert, scrollable);
+ if (!have_gui) {
+
+ GenericPluginUI* pu = new GenericPluginUI (insert, scrollable);
_pluginui = pu;
get_vbox()->add (*pu);
set_wmclass (X_("ardour_plugin_editor"), "Ardour");
- signal_map_event().connect (mem_fun (*pu, &LadspaPluginUI::start_updating));
- signal_unmap_event().connect (mem_fun (*pu, &LadspaPluginUI::stop_updating));
+ signal_map_event().connect (mem_fun (*pu, &GenericPluginUI::start_updating));
+ signal_unmap_event().connect (mem_fun (*pu, &GenericPluginUI::stop_updating));
}
set_position (Gtk::WIN_POS_MOUSE);
signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)));
insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
+ gint h = _pluginui->get_preferred_height ();
+ gint w = _pluginui->get_preferred_width ();
+
if (scrollable) {
- gint h = _pluginui->get_preferred_height ();
if (h > 600) h = 600;
- set_default_size (450, h);
+ if (w > 600) w = 600;
+
+ if (w < 0) {
+ w = 450;
+ }
}
+ set_default_size (w, h);
}
PluginUIWindow::~PluginUIWindow ()
{
}
+bool
+PluginUIWindow::create_vst_editor(boost::shared_ptr<PluginInsert> insert)
+{
+#ifndef VST_SUPPORT
+ return false;
+#else
+ VSTPluginUI* vpu = new VSTPluginUI (insert, vp);
+
+ _pluginui = vpu;
+ get_vbox()->add (*vpu);
+ vpu->package (*this);
+
+ non_gtk_gui = true;
+ return true;
+#endif
+}
+
+bool
+PluginUIWindow::create_audiounit_editor (boost::shared_ptr<PluginInsert> insert)
+{
+#if !defined(HAVE_AUDIOUNITS) || !defined(GTKOSX)
+ return false;
+#else
+ VBox* box;
+ _pluginui = create_au_gui (insert, &box);
+ get_vbox()->add (*box);
+ non_gtk_gui = true;
+
+ extern sigc::signal<void,bool> ApplicationActivationChanged;
+ ApplicationActivationChanged.connect (mem_fun (*this, &PluginUIWindow::app_activated));
+
+ return true;
+#endif
+}
+
+void
+PluginUIWindow::app_activated (bool yn)
+{
+#if defined(HAVE_AUDIOUNITS) && defined(GTKOSX)
+ if (yn) {
+ ARDOUR_UI::instance()->the_editor().ensure_float (*this);
+ show ();
+ } else {
+ hide ();
+ }
+#endif
+}
+
bool
PluginUIWindow::on_key_press_event (GdkEventKey* event)
{
+ if (non_gtk_gui) {
+ return false;
+ }
+
if (!key_press_focus_accelerator_handler (*this, event)) {
return PublicEditor::instance().on_key_press_event(event);
} else {
virtual ~PlugUIBase() {}
virtual gint get_preferred_height () = 0;
+ virtual gint get_preferred_width () = 0;
virtual bool start_updating(GdkEventAny*) = 0;
virtual bool stop_updating(GdkEventAny*) = 0;
void bypass_toggled();
};
-class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
+class GenericPluginUI : public PlugUIBase, public Gtk::VBox
{
public:
- LadspaPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false);
- ~LadspaPluginUI ();
+ GenericPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false);
+ ~GenericPluginUI ();
gint get_preferred_height () { return prefheight; }
-
+ gint get_preferred_width () { return -1; }
+
bool start_updating(GdkEventAny*);
bool stop_updating(GdkEventAny*);
private:
PlugUIBase* _pluginui;
+ bool non_gtk_gui;
+ void app_activated (bool);
void plugin_going_away ();
+
+ bool create_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
+ bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
};
#ifdef VST_SUPPORT
~VSTPluginUI ();
gint get_preferred_height ();
+ gint get_preferred_width ();
bool start_updating(GdkEventAny*) {return false;}
bool stop_updating(GdkEventAny*) {return false;}
};
#endif // VST_SUPPORT
+#ifdef HAVE_AUDIOUNITS
+/* this function has to be in a .mm file */
+extern PlugUIBase* create_au_gui (boost::shared_ptr<ARDOUR::PluginInsert>, Gtk::VBox**);
+#endif
+
#endif /* __ardour_plugin_ui_h__ */
#include "i18n.h"
-#ifdef HAVE_AUDIOUNIT
-#include "au_pluginui.h"
+#ifdef HAVE_AUDIOUNITS
+class AUPluginUI;
#endif
using namespace sigc;
} else {
/* it's an insert */
+
+ cerr << "the plugin insert, that is\n";
boost::shared_ptr<PluginInsert> plugin_insert;
boost::shared_ptr<PortInsert> port_insert;
if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
- ARDOUR::PluginType type = plugin_insert->type();
-
- if (type == ARDOUR::LADSPA || type == ARDOUR::VST) {
- PluginUIWindow *plugin_ui;
+ PluginUIWindow *plugin_ui;
- if (plugin_insert->get_gui() == 0) {
-
- plugin_ui = new PluginUIWindow (plugin_insert);
-
- if (_owner_is_mixer) {
- ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui);
- } else {
- ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui);
- }
-
- WindowTitle title(Glib::get_application_name());
- title += generate_redirect_title (plugin_insert);
- plugin_ui->set_title (title.get_string());
-
- plugin_insert->set_gui (plugin_ui);
-
- // change window title when route name is changed
- _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
-
+ if (plugin_insert->get_gui() == 0) {
- } else {
- plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
- }
-
- if (plugin_ui->is_visible()) {
- plugin_ui->get_window()->raise ();
- } else {
- plugin_ui->show_all ();
- plugin_ui->present ();
- }
-#ifdef HAVE_AUDIOUNIT
- } else if (type == ARDOUR::AudioUnit) {
- AUPluginUI* plugin_ui;
- if (plugin_insert->get_gui() == 0) {
- plugin_ui = new AUPluginUI (plugin_insert);
- } else {
- plugin_ui = reinterpret_cast<AUPluginUI*> (plugin_insert->get_gui());
- }
+ plugin_ui = new PluginUIWindow (plugin_insert);
- if (plugin_ui->is_visible()) {
- plugin_ui->get_window()->raise ();
+ if (_owner_is_mixer) {
+ ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui);
} else {
- plugin_ui->show_all ();
- plugin_ui->present ();
+ ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui);
}
-#endif
+
+ WindowTitle title(Glib::get_application_name());
+ title += generate_redirect_title (plugin_insert);
+ plugin_ui->set_title (title.get_string());
+
+ plugin_insert->set_gui (plugin_ui);
+
+ // change window title when route name is changed
+ _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
+
+
} else {
- warning << "Unsupported plugin sent to RedirectBox::edit_redirect()" << endmsg;
- return;
+ plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
}
+
+ if (plugin_ui->is_visible()) {
+ plugin_ui->get_window()->raise ();
+ } else {
+ plugin_ui->show_all ();
+ plugin_ui->present ();
+ }
+
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
if (!_session.engine().connected()) {
RouteParams_UI::cleanup_pre_view (bool stopupdate)
{
if (_active_pre_view) {
- LadspaPluginUI * plugui = 0;
+ GenericPluginUI * plugui = 0;
- if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_pre_view)) != 0) {
+ if (stopupdate && (plugui = dynamic_cast<GenericPluginUI*>(_active_pre_view)) != 0) {
plugui->stop_updating (0);
}
RouteParams_UI::cleanup_post_view (bool stopupdate)
{
if (_active_post_view) {
- LadspaPluginUI * plugui = 0;
+ GenericPluginUI * plugui = 0;
- if (stopupdate && (plugui = dynamic_cast<LadspaPluginUI*>(_active_post_view)) != 0) {
+ if (stopupdate && (plugui = dynamic_cast<GenericPluginUI*>(_active_post_view)) != 0) {
plugui->stop_updating (0);
}
_post_plugin_conn.disconnect();
if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
- LadspaPluginUI *plugin_ui = new LadspaPluginUI (plugin_insert, true);
+ GenericPluginUI *plugin_ui = new GenericPluginUI (plugin_insert, true);
if (place == PreFader) {
cleanup_pre_view();
} else {
/* click: solo this route */
-
+
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
}
}
return vst->fst()->height;
}
+int
+VSTPluginUI::get_preferred_width ()
+{
+ return vst->fst()->width;
+}
+
int
VSTPluginUI::package (Gtk::Window& win)
{