From acbe9a26ec3ab689e430225d15e95e73a7378aa9 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 7 Sep 2006 06:04:55 +0000 Subject: Patch port fixes. Port metadata fixes. Compatibility hacks for loading old patches. Internal node fixes, cleanups, minor refactor. Path fixes. git-svn-id: http://svn.drobilla.net/lad/ingen@118 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/client/OSCEngineInterface.cpp | 4 +- src/libs/client/OSCEngineInterface.h | 2 +- src/libs/client/PatchLibrarian.cpp | 136 +++++++++++++++++++++-------- src/libs/client/PatchLibrarian.h | 28 +++--- src/libs/engine/DSSINode.cpp | 1 + src/libs/engine/InternalNode.h | 7 +- src/libs/engine/Makefile.am | 1 + src/libs/engine/MidiControlNode.cpp | 7 +- src/libs/engine/MidiNoteNode.cpp | 7 +- src/libs/engine/MidiTriggerNode.cpp | 7 +- src/libs/engine/NodeBase.h | 14 +-- src/libs/engine/NodeFactory.cpp | 101 ++++++++------------- src/libs/engine/NodeFactory.h | 9 +- src/libs/engine/Patch.cpp | 2 +- src/libs/engine/Plugin.h | 104 ++++++++++++---------- src/libs/engine/TransportNode.cpp | 7 +- src/libs/engine/TypedConnection.cpp | 2 +- src/libs/engine/events/AddNodeEvent.cpp | 2 +- src/libs/engine/types.h | 1 - src/progs/ingenuity/LoadPluginWindow.cpp | 3 +- src/progs/ingenuity/LoadPluginWindow.h | 6 +- src/progs/ingenuity/LoadSubpatchWindow.cpp | 22 +++-- src/progs/ingenuity/LoadSubpatchWindow.h | 6 +- src/progs/ingenuity/NewSubpatchWindow.cpp | 8 +- src/progs/ingenuity/NewSubpatchWindow.h | 6 +- src/progs/ingenuity/OmFlowCanvas.cpp | 13 +++ src/progs/ingenuity/OmFlowCanvas.h | 1 + src/progs/ingenuity/PatchController.cpp | 28 ++---- src/progs/ingenuity/PatchController.h | 2 - src/progs/ingenuity/PortController.cpp | 16 +++- src/progs/ingenuity/PortController.h | 2 +- src/progs/ingenuity/ingenuity.glade | 2 +- 32 files changed, 315 insertions(+), 242 deletions(-) (limited to 'src') diff --git a/src/libs/client/OSCEngineInterface.cpp b/src/libs/client/OSCEngineInterface.cpp index 29bb965a..b747e2e4 100644 --- a/src/libs/client/OSCEngineInterface.cpp +++ b/src/libs/client/OSCEngineInterface.cpp @@ -116,14 +116,14 @@ OSCEngineInterface::create_patch(const string& path, void OSCEngineInterface::create_port(const string& path, const string& data_type, - bool direction) + bool is_output) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/create_port", "issi", next_id(), path.c_str(), data_type.c_str(), - (direction ? 1 : 0)); + (is_output ? 1 : 0)); } diff --git a/src/libs/client/OSCEngineInterface.h b/src/libs/client/OSCEngineInterface.h index 69b7dc05..4405438c 100644 --- a/src/libs/client/OSCEngineInterface.h +++ b/src/libs/client/OSCEngineInterface.h @@ -74,7 +74,7 @@ public: void create_port(const string& path, const string& data_type, - bool direction); + bool is_output); void create_node(const string& path, const string& plugin_type, diff --git a/src/libs/client/PatchLibrarian.cpp b/src/libs/client/PatchLibrarian.cpp index e12c99e0..e09ac23c 100644 --- a/src/libs/client/PatchLibrarian.cpp +++ b/src/libs/client/PatchLibrarian.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "PatchModel.h" #include "NodeModel.h" #include "ModelClientInterface.h" @@ -59,7 +60,7 @@ namespace Client { string PatchLibrarian::find_file(const string& filename, const string& additional_path) { - string search_path = additional_path + ":" + m_patch_path; + string search_path = additional_path + ":" + _patch_search_path; // Try to open the raw filename first std::ifstream is(filename.c_str(), std::ios::in); @@ -95,6 +96,20 @@ PatchLibrarian::find_file(const string& filename, const string& additional_path) } +string +PatchLibrarian::translate_load_path(const string& path) +{ + std::map::iterator t = _load_path_translations.find(path); + + if (t != _load_path_translations.end()) { + return (*t).second; + } else { + assert(Path::is_valid(path)); + return path; + } +} + + /** Save a patch from a PatchModel to a filename. * * The filename passed is the true filename the patch will be saved to (with no prefixing or anything @@ -447,10 +462,10 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if (!existing) { // Wait until the patch is created or the node creations may fail if (wait) { - //int id = m_osc_model_engine_interface->get_next_request_id(); - //m_osc_model_engine_interface->set_wait_response_id(id); - m_osc_model_engine_interface->create_patch_from_model(pm); - //bool succeeded = m_osc_model_engine_interface->wait_for_response(); + //int id = _engine->get_next_request_id(); + //_engine->set_wait_response_id(id); + _engine->create_patch_from_model(pm); + //bool succeeded = _engine->wait_for_response(); // If creating the patch failed, bail out so we don't load all these nodes // into an already existing patch @@ -459,7 +474,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) return ""; }*/ // FIXME } else { - m_osc_model_engine_interface->create_patch_from_model(pm); + _engine->create_patch_from_model(pm); } } @@ -468,7 +483,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) // This isn't so good, considering multiple clients on multiple machines, and // absolute filesystem paths obviously aren't going to be correct. But for now // this is all I can figure out to have Save/Save As work properly for subpatches - m_osc_model_engine_interface->set_metadata(pm->path(), "filename", pm->filename()); + _engine->set_metadata(pm->path(), "filename", pm->filename()); // Load nodes NodeModel* nm = NULL; @@ -478,14 +493,14 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if ((!xmlStrcmp(cur->name, (const xmlChar*)"node"))) { nm = parse_node(pm, doc, cur); if (nm != NULL) { - m_osc_model_engine_interface->create_node_from_model(nm); - m_osc_model_engine_interface->set_all_metadata(nm); + _engine->create_node_from_model(nm); + _engine->set_all_metadata(nm); for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) { // FIXME: ew snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_min()); - m_osc_model_engine_interface->set_metadata((*j)->path(), "user-min", temp_buf); + _engine->set_metadata((*j)->path(), "user-min", temp_buf); snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_max()); - m_osc_model_engine_interface->set_metadata((*j)->path(), "user-max", temp_buf); + _engine->set_metadata((*j)->path(), "user-max", temp_buf); } nm = NULL; usleep(10000); @@ -503,14 +518,14 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) cur = cur->next; } - // Load connections ConnectionModel* cm = NULL; + // Load connections cur = xmlDocGetRootElement(doc)->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar*)"connection"))) { cm = parse_connection(pm, doc, cur); if (cm != NULL) { - m_osc_model_engine_interface->connect(cm->src_port_path(), cm->dst_port_path()); + _engine->connect(cm->src_port_path(), cm->dst_port_path()); usleep(1000); } } @@ -526,7 +541,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) preset_model = parse_preset(pm, doc, cur); assert(preset_model != NULL); if (preset_model->name() == "default") - m_osc_model_engine_interface->set_preset(pm->path(), preset_model); + _engine->set_preset(pm->path(), preset_model); } cur = cur->next; } @@ -534,10 +549,12 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) xmlFreeDoc(doc); xmlCleanupParser(); - m_osc_model_engine_interface->set_all_metadata(pm); + _engine->set_all_metadata(pm); if (!existing) - m_osc_model_engine_interface->enable_patch(pm->path()); + _engine->enable_patch(pm->path()); + + _load_path_translations.clear(); string ret = pm->path(); return ret; @@ -555,14 +572,11 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod xmlChar* key; xmlNodePtr cur = node->xmlChildrenNode; - bool found_name = false; - while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - nm->set_path(parent->base_path() + (char*)key); - found_name = true; + nm->set_path(parent->base_path() + Path::nameify((char*)key)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { nm->polyphonic(!strcmp((char*)key, "true")); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { @@ -584,7 +598,7 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - path = nm->base_path() + (char*)key; + path = nm->base_path() + Path::nameify((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) { user_min = atof((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) { @@ -666,10 +680,62 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod cerr << "[PatchLibrarian] Node ignored." << endl; delete nm; return NULL; - } else { - //nm->plugin(plugin); - return nm; + + // Compatibility hacks for old patches + } else if (plugin->type() == PluginModel::Internal) { + bool is_port = false; + const string path = Path::pathify(nm->path()); + if (plugin->plug_label() == "audio_input") { + _engine->create_port(path, "AUDIO", false); + is_port = true; + } else if ( plugin->plug_label() == "audio_output") { + _engine->create_port(path, "AUDIO", true); + is_port = true; + } else if ( plugin->plug_label() == "control_input") { + _engine->create_port(path, "CONTROL", false); + is_port = true; + } else if ( plugin->plug_label() == "control_output" ) { + _engine->create_port(path, "CONTROL", true); + is_port = true; + } else if ( plugin->plug_label() == "midi_input") { + _engine->create_port(path, "MIDI", false); + is_port = true; + } else if ( plugin->plug_label() == "midi_output" ) { + _engine->create_port(path, "MIDI", true); + is_port = true; + } + + if (is_port) { + const string old_path = nm->path(); + const string new_path = Path::pathify(old_path); + + // Set up translations (for connections etc) to alias both the old + // module path and the old module/port path to the new port path + _load_path_translations[old_path] = new_path; + _load_path_translations[old_path + "/in"] = new_path; + _load_path_translations[old_path + "/out"] = new_path; + + nm->set_path(new_path); + _engine->set_all_metadata(nm); + delete nm; + return NULL; + } else { + if (plugin->uri() == "") { + if (plugin->plug_label() == "note_in") { + plugin->uri("ingen:note_node"); + } else if (plugin->plug_label() == "control_input") { + plugin->uri("ingen:control_node"); + } else if (plugin->plug_label() == "transport") { + plugin->uri("ingen:transport_node"); + } else if (plugin->plug_label() == "trigger_in") { + plugin->uri("ingen:trigger_node"); + } + } + } } + + //nm->plugin(plugin); + return nm; } @@ -749,17 +815,15 @@ PatchLibrarian::parse_connection(const PatchModel* parent, xmlDocPtr doc, const return NULL; } - // FIXME: temporary compatibility, remove any slashes from port names - // remove this soon once patches have migrated - string::size_type slash_index; - while ((slash_index = source_port.find("/")) != string::npos) - source_port[slash_index] = '-'; + // Compatibility fixes for old (fundamentally broken) patches + source_node = Path::nameify(source_node); + source_port = Path::nameify(source_port); + dest_node = Path::nameify(dest_node); + dest_port = Path::nameify(dest_port); - while ((slash_index = dest_port.find("/")) != string::npos) - dest_port[slash_index] = '-'; - - ConnectionModel* cm = new ConnectionModel(parent->base_path() + source_node +"/"+ source_port, - parent->base_path() + dest_node +"/"+ dest_port); + ConnectionModel* cm = new ConnectionModel( + translate_load_path(parent->base_path() + source_node +"/"+ source_port), + translate_load_path(parent->base_path() + dest_node +"/"+ dest_port)); return cm; } @@ -803,6 +867,10 @@ PatchLibrarian::parse_preset(const PatchModel* patch, xmlDocPtr doc, const xmlNo child = child->next; } + + // Compatibility fixes for old patch files + node_name = Path::nameify(node_name); + port_name = Path::nameify(port_name); if (port_name == "") { string msg = "Unable to parse control in patch file ( node = "; diff --git a/src/libs/client/PatchLibrarian.h b/src/libs/client/PatchLibrarian.h index 817f98ca..5c199974 100644 --- a/src/libs/client/PatchLibrarian.h +++ b/src/libs/client/PatchLibrarian.h @@ -17,6 +17,8 @@ #ifndef PATCHLIBRARIAN_H #define PATCHLIBRARIAN_H +#include +#include #include #include #include @@ -42,21 +44,16 @@ class ModelClientInterface; class PatchLibrarian { public: - // FIXME: return booleans and set an errstr that can be checked? + // FIXME: return booleans and set an errstr that can be checked or something? - PatchLibrarian(OSCModelEngineInterface* const osc_model_engine_interface/*,ModelClientInterface* const client_hooks*/) - : m_patch_path("."), m_osc_model_engine_interface(osc_model_engine_interface)//, m_client_hooks(client_hooks) + PatchLibrarian(OSCModelEngineInterface* osc_model_engine_interface) + : _patch_search_path("."), _engine(osc_model_engine_interface) { - assert(m_osc_model_engine_interface); - //assert(m_client_hooks != NULL); + assert(_engine); } -// PatchLibrarian(OSCModelEngineInterface* osc_model_engine_interface) -// : m_osc_model_engine_interface(osc_model_engine_interface), m_client_hooks(new DummyModelClientInterface()) -// {} - - void path(const string& path) { m_patch_path = path; } - const string& path() { return m_patch_path; } + void path(const string& path) { _patch_search_path = path; } + const string& path() { return _patch_search_path; } string find_file(const string& filename, const string& additional_path = ""); @@ -64,8 +61,13 @@ public: string load_patch(PatchModel* pm, bool wait = true, bool existing = false); private: - string m_patch_path; - OSCModelEngineInterface* const m_osc_model_engine_interface; + string translate_load_path(const string& path); + + string _patch_search_path; + OSCModelEngineInterface* const _engine; + + /// Translations of paths from the loading file to actual paths (for deprecated patches) + std::map _load_path_translations; NodeModel* parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); ConnectionModel* parse_connection(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); diff --git a/src/libs/engine/DSSINode.cpp b/src/libs/engine/DSSINode.cpp index c78c8d02..122c13b4 100644 --- a/src/libs/engine/DSSINode.cpp +++ b/src/libs/engine/DSSINode.cpp @@ -21,6 +21,7 @@ #include "ClientBroadcaster.h" #include "interface/ClientInterface.h" #include "InputPort.h" +#include "types.h" using namespace std; diff --git a/src/libs/engine/InternalNode.h b/src/libs/engine/InternalNode.h index 98bd473f..2cbbcff8 100644 --- a/src/libs/engine/InternalNode.h +++ b/src/libs/engine/InternalNode.h @@ -20,6 +20,7 @@ #include #include "NodeBase.h" #include "Plugin.h" +#include "types.h" namespace Ingen { @@ -37,7 +38,6 @@ public: : NodeBase(plugin, path, poly, parent, srate, buffer_size), _is_added(false) { - _plugin.lib_path("/Ingen"); } virtual ~InternalNode() {} @@ -52,14 +52,13 @@ public: //virtual void send_creation_messages(ClientInterface* client) const //{ NodeBase::send_creation_messages(client); } - virtual const Plugin* plugin() const { return &_plugin; } - protected: + Plugin* plugin() const { return const_cast(_plugin); } + // Disallow copies (undefined) InternalNode(const InternalNode&); InternalNode& operator=(const InternalNode&); - Plugin _plugin; bool _is_added; }; diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index b4b0ec45..bc2560eb 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -68,6 +68,7 @@ libingen_la_SOURCES = \ ClientRecord.h \ PluginLibrary.h \ Plugin.h \ + Plugin.cpp \ Array.h \ List.h \ Slave.h \ diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp index cd483bc7..32f14dc2 100644 --- a/src/libs/engine/MidiControlNode.cpp +++ b/src/libs/engine/MidiControlNode.cpp @@ -30,7 +30,7 @@ namespace Ingen { MidiControlNode::MidiControlNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) -: InternalNode(new Plugin(Plugin::Internal, "Ingen:ControlNode"), path, 1, parent, srate, buffer_size), +: InternalNode(new Plugin(Plugin::Internal, "ingen:control_node"), path, 1, parent, srate, buffer_size), _learning(false) { _ports = new Array(7); @@ -56,8 +56,9 @@ MidiControlNode::MidiControlNode(const string& path, size_t poly, Patch* parent, _control_port = new OutputPort(this, "Out_(CR)", 6, 1, DataType::FLOAT, 1); _ports->at(6) = _control_port; - _plugin.plug_label("midi_control_in"); - _plugin.name("Ingen Control Node (MIDI)"); + plugin()->plug_label("midi_control_in"); + assert(plugin()->uri() == "ingen:control_node"); + plugin()->name("Ingen Control Node (MIDI)"); } diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index f13b054a..5d08c495 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -34,7 +34,7 @@ namespace Ingen { MidiNoteNode::MidiNoteNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) -: InternalNode(new Plugin(Plugin::Internal, "Ingen:NoteNode"), path, poly, parent, srate, buffer_size), +: InternalNode(new Plugin(Plugin::Internal, "ingen:note_node"), path, poly, parent, srate, buffer_size), _voices(new Voice[poly]), _sustain(false) { @@ -59,8 +59,9 @@ MidiNoteNode::MidiNoteNode(const string& path, size_t poly, Patch* parent, Sampl // new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); _ports->at(4) = _trig_port; - _plugin.plug_label("note_in"); - _plugin.name("Ingen Note Node (MIDI, OSC)"); + plugin()->plug_label("note_in"); + assert(plugin()->uri() == "ingen:note_node"); + plugin()->name("Ingen Note Node (MIDI, OSC)"); } diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp index 3b21129c..c117a70c 100644 --- a/src/libs/engine/MidiTriggerNode.cpp +++ b/src/libs/engine/MidiTriggerNode.cpp @@ -26,7 +26,7 @@ namespace Ingen { MidiTriggerNode::MidiTriggerNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) -: InternalNode(new Plugin(Plugin::Internal, "Ingen:TriggerNode"), path, 1, parent, srate, buffer_size) +: InternalNode(new Plugin(Plugin::Internal, "ingen:trigger_node"), path, 1, parent, srate, buffer_size) { _ports = new Array(5); @@ -49,8 +49,9 @@ MidiTriggerNode::MidiTriggerNode(const string& path, size_t poly, Patch* parent, // new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); _ports->at(4) = _vel_port; - _plugin.plug_label("trigger_in"); - _plugin.name("Ingen Trigger Node (MIDI, OSC)"); + plugin()->plug_label("trigger_in"); + assert(plugin()->uri() == "ingen:trigger_node"); + plugin()->name("Ingen Trigger Node (MIDI, OSC)"); } diff --git a/src/libs/engine/NodeBase.h b/src/libs/engine/NodeBase.h index f0c04d80..df9c6e7c 100644 --- a/src/libs/engine/NodeBase.h +++ b/src/libs/engine/NodeBase.h @@ -17,9 +17,11 @@ #ifndef NODEBASE_H #define NODEBASE_H +#include "types.h" #include #include #include "Node.h" + using std::string; namespace Ingen { @@ -60,10 +62,12 @@ public: //void send_creation_messages(ClientInterface* client) const; - size_t num_ports() const { return _ports ? _ports->size() : 0; } - size_t poly() const { return _poly; } - bool traversed() const { return _traversed; } - void traversed(bool b) { _traversed = b; } + SampleRate sample_rate() const { return _srate; } + size_t buffer_size() const { return _buffer_size; } + size_t num_ports() const { return _ports ? _ports->size() : 0; } + size_t poly() const { return _poly; } + bool traversed() const { return _traversed; } + void traversed(bool b) { _traversed = b; } const Array& ports() const { return *_ports; } @@ -75,7 +79,7 @@ public: virtual const Plugin* plugin() const { return _plugin; } - void set_path(const Path& new_path); + virtual void set_path(const Path& new_path); /** A node's parent is always a patch, so static cast should be safe */ Patch* parent_patch() const { return (Patch*)_parent; } diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp index 57219f9f..65829d97 100644 --- a/src/libs/engine/NodeFactory.cpp +++ b/src/libs/engine/NodeFactory.cpp @@ -22,8 +22,6 @@ #include #include #include -#include "Engine.h" -#include "AudioDriver.h" #include "MidiNoteNode.h" #include "MidiTriggerNode.h" #include "MidiControlNode.h" @@ -130,7 +128,10 @@ NodeFactory::load_plugins() * Calls the load_*_plugin functions to actually do things, just a wrapper. */ Node* -NodeFactory::load_plugin(const Plugin* a_plugin, const string& name, size_t poly, Patch* parent) +NodeFactory::load_plugin(const Plugin* a_plugin, + const string& name, + size_t poly, + Patch* parent) { assert(parent != NULL); assert(poly == 1 || poly == parent->internal_poly()); @@ -141,6 +142,9 @@ NodeFactory::load_plugin(const Plugin* a_plugin, const string& name, size_t poly Node* r = NULL; Plugin* plugin = NULL; + const SampleRate srate = parent->sample_rate(); + const size_t buffer_size = parent->buffer_size(); + // FIXME FIXME FIXME: double lookup // Attempt to find the plugin in loaded DB @@ -177,21 +181,21 @@ NodeFactory::load_plugin(const Plugin* a_plugin, const string& name, size_t poly switch (a_plugin->type()) { #if HAVE_SLV2 case Plugin::LV2: - r = load_lv2_plugin(plugin->uri(), name, poly, parent); + r = load_lv2_plugin(plugin->uri(), name, poly, parent, srate, buffer_size); break; #endif #if HAVE_DSSI case Plugin::DSSI: - r = load_dssi_plugin(plugin->uri(), name, poly, parent); + r = load_dssi_plugin(plugin->uri(), name, poly, parent, srate, buffer_size); break; #endif #if HAVE_LADSPA case Plugin::LADSPA: - r = load_ladspa_plugin(plugin->uri(), name, poly, parent); + r = load_ladspa_plugin(plugin->uri(), name, poly, parent, srate, buffer_size); break; #endif case Plugin::Internal: - r = load_internal_plugin(a_plugin->uri(), name, poly, parent); + r = load_internal_plugin(a_plugin->uri(), name, poly, parent, srate, buffer_size); break; default: cerr << "[NodeFactory] WARNING: Unknown plugin type." << endl; @@ -206,59 +210,23 @@ NodeFactory::load_plugin(const Plugin* a_plugin, const string& name, size_t poly /** Loads an internal plugin. */ Node* -NodeFactory::load_internal_plugin(const string& uri, const string& name, size_t poly, Patch* parent) +NodeFactory::load_internal_plugin(const string& uri, + const string& name, + size_t poly, + Patch* parent, + SampleRate srate, + size_t buffer_size) { - return NULL; - cerr << "FIXME: Internal plugin" << endl; -#if 0 assert(parent != NULL); assert(poly == 1 || poly == parent->internal_poly()); - assert(uri.length() > 3); - assert(uri.substr(0, 3) == "om:"); - - string plug_label = uri.substr(3); - /*if (plug_label == "midi_input") { - MidiInputNode* tn = new MidiInputNode(name, 1, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return tn; - } else if (plug_label == "midi_output") { - MidiOutputNode* tn = new MidiOutputNode(name, 1, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return tn; - } else if (plug_label == "audio_input") { - AudioInputNode* in = new AudioInputNode(name, poly, parent, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return in; - } else if (plug_label == "control_input") { - ControlInputNode* in = new ControlInputNode(name, poly, parent, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return in; - } else if (plug_label == "audio_output") { - AudioOutputNode* on = new AudioOutputNode(name, poly, parent, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return on; - } else if (plug_label == "control_output") { - ControlOutputNode* on = new ControlOutputNode(name, poly, parent, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return on; - } else - */ - if (plug_label == "note_in" || plug_label == "midi_note_in") { - MidiNoteNode* mn = new MidiNoteNode(name, poly, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return mn; - } else if (plug_label == "trigger_in" || plug_label == "midi_trigger_in") { - MidiTriggerNode* mn = new MidiTriggerNode(name, 1, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return mn; - } else if (plug_label == "midi_control_in") { - MidiControlNode* mn = new MidiControlNode(name, 1, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return mn; - } else if (plug_label == "transport") { - TransportNode* tn = new TransportNode(name, 1, parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); - return tn; - } else { - cerr << "Unknown internal plugin type '" << plug_label << "'" << endl; - } + assert(uri.length() > 6); + assert(uri.substr(0, 6) == "ingen:"); + for (list::iterator i = _internal_plugins.begin(); i != _internal_plugins.end(); ++i) + if ((*i)->uri() == uri) + return (*i)->instantiate(name, poly, parent, srate, buffer_size); + return NULL; -#endif } @@ -320,7 +288,9 @@ Node* NodeFactory::load_lv2_plugin(const string& plug_uri, const string& node_name, size_t poly, - Patch* parent) + Patch* parent, + SampleRate srate, + size_t buffer_size) { // Find (internal) Plugin Plugin* plugin = NULL; @@ -333,8 +303,7 @@ NodeFactory::load_lv2_plugin(const string& plug_uri, Node* n = NULL; if (plugin) { - n = new LV2Node(plugin, node_name, poly, parent, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); + n = new LV2Node(plugin, node_name, poly, parent, srate, buffer_size); bool success = ((LV2Node*)n)->instantiate(); if (!success) { delete n; @@ -455,7 +424,7 @@ NodeFactory::load_dssi_plugins() */ Node* NodeFactory::load_dssi_plugin(const string& uri, - const string& name, size_t poly, Patch* parent) + const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) { // FIXME: awful code duplication here @@ -509,8 +478,8 @@ NodeFactory::load_dssi_plugin(const string& uri, return NULL; } - n = new DSSINode(plugin, name, poly, parent, descriptor, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); + n = new DSSINode(plugin, name, poly, parent, descriptor, srate, buffer_size); + bool success = ((DSSINode*)n)->instantiate(); if (!success) { delete n; @@ -625,7 +594,11 @@ NodeFactory::load_ladspa_plugins() */ Node* NodeFactory::load_ladspa_plugin(const string& uri, - const string& name, size_t poly, Patch* parent) + const string& name, + size_t poly, + Patch* parent, + SampleRate srate, + size_t buffer_size) { assert(uri != ""); assert(name != ""); @@ -676,8 +649,8 @@ NodeFactory::load_ladspa_plugin(const string& uri, return NULL; } - n = new LADSPANode(plugin, name, poly, parent, descriptor, - Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size()); + n = new LADSPANode(plugin, name, poly, parent, descriptor, srate, buffer_size); + bool success = ((LADSPANode*)n)->instantiate(); if (!success) { delete n; diff --git a/src/libs/engine/NodeFactory.h b/src/libs/engine/NodeFactory.h index abb30553..cf2fb0d0 100644 --- a/src/libs/engine/NodeFactory.h +++ b/src/libs/engine/NodeFactory.h @@ -19,6 +19,7 @@ #define NODEFACTORY_H #include "config.h" +#include "types.h" #include #include #include @@ -61,20 +62,20 @@ public: private: #ifdef HAVE_LADSPA void load_ladspa_plugins(); - Node* load_ladspa_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent); + Node* load_ladspa_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); #endif #ifdef HAVE_SLV2 void load_lv2_plugins(); - Node* load_lv2_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent); + Node* load_lv2_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); #endif #ifdef HAVE_DSSI void load_dssi_plugins(); - Node* load_dssi_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent); + Node* load_dssi_plugin(const string& plugin_uri, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); #endif - Node* load_internal_plugin(const string& plug_label, const string& name, size_t poly, Patch* parent); + Node* load_internal_plugin(const string& plug_label, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); list _libraries; list _internal_plugins; diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index 56006a86..c8c3dd3a 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -30,7 +30,7 @@ namespace Ingen { Patch::Patch(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size, size_t internal_poly) -: NodeBase(new Plugin(Plugin::Patch, "Ingen:Patch"), path, poly, parent, srate, buffer_size), +: NodeBase(new Plugin(Plugin::Patch, "ingen:patch"), path, poly, parent, srate, buffer_size), _internal_poly(internal_poly), _process_order(NULL), _process(false) diff --git a/src/libs/engine/Plugin.h b/src/libs/engine/Plugin.h index 295e1bbf..bdb5a748 100644 --- a/src/libs/engine/Plugin.h +++ b/src/libs/engine/Plugin.h @@ -26,13 +26,17 @@ #ifdef HAVE_SLV2 #include #endif +#include "types.h" using std::string; using std::cerr; using std::endl; +class Path; namespace Ingen { class PluginLibrary; +class Patch; +class Node; /** Representation of a plugin (of various types). @@ -47,16 +51,16 @@ public: enum Type { LV2, LADSPA, DSSI, Internal, Patch }; Plugin(Type type, const string& uri) - : m_type(type) - , m_uri(uri) + : _type(type) + , _uri(uri) {} // FIXME: remove - Plugin() : m_type(Internal), m_lib_path("/Ingen"), - m_id(0), m_library(NULL) + Plugin() : _type(Internal), _lib_path("/Ingen"), + _id(0), _library(NULL) { #ifdef HAVE_SLV2 - m_slv2_plugin = NULL; + _slv2_plugin = NULL; #endif } @@ -64,73 +68,77 @@ public: // Copying only allowed for Internal plugins. Bit of a hack, but // allows the PluginInfo to be defined in the Node class which keeps // things localized and convenient (FIXME?) - if (copy->m_type != Internal) + if (copy->_type != Internal) exit(EXIT_FAILURE); - m_type = copy->m_type; - m_lib_path = copy->m_lib_path; - m_plug_label = copy->m_plug_label; - m_name = copy->m_name; - m_library = copy->m_library; + _type = copy->_type; + _lib_path = copy->_lib_path; + _uri = copy->_uri; + _plug_label = copy->_plug_label; + _name = copy->_name; + _library = copy->_library; } - Type type() const { return m_type; } - void type(Type t) { m_type = t; } - const string& lib_path() const { return m_lib_path; } - void lib_path(const string& s) { m_lib_path = s; m_lib_name = m_lib_path.substr(m_lib_path.find_last_of("/")+1); } - string lib_name() const { return m_lib_name; } - void lib_name(const string& s) { m_lib_name = s; } - const string& plug_label() const { return m_plug_label; } - void plug_label(const string& s) { m_plug_label = s; } - const string& name() const { return m_name; } - void name(const string& s) { m_name = s; } - unsigned long id() const { return m_id; } - void id(unsigned long i) { m_id = i; } - const string uri() const { return m_uri; } - void uri(const string& s) { m_uri = s; } + Type type() const { return _type; } + void type(Type t) { _type = t; } + const string& lib_path() const { return _lib_path; } + void lib_path(const string& s) { _lib_path = s; _lib_name = _lib_path.substr(_lib_path.find_last_of("/")+1); } + string lib_name() const { return _lib_name; } + void lib_name(const string& s) { _lib_name = s; } + const string& plug_label() const { return _plug_label; } + void plug_label(const string& s) { _plug_label = s; } + const string& name() const { return _name; } + void name(const string& s) { _name = s; } + unsigned long id() const { return _id; } + void id(unsigned long i) { _id = i; } + const string uri() const { return _uri; } + void uri(const string& s) { _uri = s; } - PluginLibrary* library() const { return m_library; } - void library(PluginLibrary* const library) { m_library = library; } + PluginLibrary* library() const { return _library; } + void library(PluginLibrary* const library) { _library = library; } const char* type_string() const { - if (m_type == LADSPA) return "LADSPA"; - else if (m_type == LV2) return "LV2"; - else if (m_type == DSSI) return "DSSI"; - else if (m_type == Internal) return "Internal"; - else if (m_type == Patch) return "Patch"; + if (_type == LADSPA) return "LADSPA"; + else if (_type == LV2) return "LV2"; + else if (_type == DSSI) return "DSSI"; + else if (_type == Internal) return "Internal"; + else if (_type == Patch) return "Patch"; else return ""; } void set_type(const string& type_string) { - if (type_string == "LADSPA") m_type = LADSPA; - else if (type_string == "LV2") m_type = LV2; - else if (type_string == "DSSI") m_type = DSSI; - else if (type_string == "Internal") m_type = Internal; - else if (type_string == "Patch") m_type = Patch; + if (type_string == "LADSPA") _type = LADSPA; + else if (type_string == "LV2") _type = LV2; + else if (type_string == "DSSI") _type = DSSI; + else if (type_string == "Internal") _type = Internal; + else if (type_string == "Patch") _type = Patch; } // FIXME: ew #ifdef HAVE_SLV2 - SLV2Plugin* slv2_plugin() const { return m_slv2_plugin; } - void slv2_plugin(const SLV2Plugin* p) { m_slv2_plugin = p; } + SLV2Plugin* slv2_plugin() const { return _slv2_plugin; } + void slv2_plugin(const SLV2Plugin* p) { _slv2_plugin = p; } #endif + + Node* instantiate(const string& name, size_t poly, Ingen::Patch* parent, SampleRate srate, size_t buffer_size); + private: // Disallow copies (undefined) Plugin(const Plugin&); Plugin& operator=(const Plugin&); - Type m_type; - string m_uri; ///< LV2 only - string m_lib_path; ///< LADSPA/DSSI only - string m_lib_name; ///< LADSPA/DSSI only - string m_plug_label; ///< LADSPA/DSSI only - string m_name; ///< LADSPA/DSSI only - unsigned long m_id; ///< LADSPA/DSSI only + Type _type; + string _uri; ///< LV2 only + string _lib_path; ///< LADSPA/DSSI only + string _lib_name; ///< LADSPA/DSSI only + string _plug_label; ///< LADSPA/DSSI only + string _name; ///< LADSPA/DSSI only + unsigned long _id; ///< LADSPA/DSSI only - PluginLibrary* m_library; + PluginLibrary* _library; #ifdef HAVE_SLV2 - SLV2Plugin* m_slv2_plugin; + SLV2Plugin* _slv2_plugin; #endif }; diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp index be10dc99..49ab20b8 100644 --- a/src/libs/engine/TransportNode.cpp +++ b/src/libs/engine/TransportNode.cpp @@ -28,7 +28,7 @@ namespace Ingen { TransportNode::TransportNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) -: InternalNode(new Plugin(Plugin::Internal, "Ingen:TransportNode"), path, 1, parent, srate, buffer_size) +: InternalNode(new Plugin(Plugin::Internal, "ingen:transport_node"), path, 1, parent, srate, buffer_size) { #if 0 _num_ports = 10; @@ -74,8 +74,9 @@ TransportNode::TransportNode(const string& path, size_t poly, Patch* parent, Sam // new PortInfo("Bar Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); _ports.at(9) = bar_trig_port; #endif - _plugin.plug_label("transport"); - _plugin.name("Ingen Transport Node (BROKEN)"); + plugin()->plug_label("transport"); + assert(plugin()->uri() == "ingen:transport_node"); + plugin()->name("Ingen Transport Node (BROKEN)"); } diff --git a/src/libs/engine/TypedConnection.cpp b/src/libs/engine/TypedConnection.cpp index e294185c..daee10d9 100644 --- a/src/libs/engine/TypedConnection.cpp +++ b/src/libs/engine/TypedConnection.cpp @@ -66,7 +66,7 @@ void TypedConnection::process(SampleCount nframes) { // FIXME: nframes parameter not used - assert(nframes == m_buffer_size); + assert(m_buffer_size == 1 || m_buffer_size == nframes); /* Thought: A poly output port can be connected to multiple mono input * ports, which means this mix down would have to happen many times. diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp index 4f8d099a..a5dc7538 100644 --- a/src/libs/engine/events/AddNodeEvent.cpp +++ b/src/libs/engine/events/AddNodeEvent.cpp @@ -113,7 +113,7 @@ AddNodeEvent::post_process() } else if (m_node == NULL) { msg = "Unable to load node "; msg.append(m_path).append(" (you're missing the plugin \"").append( - m_plugin->lib_name()).append(":").append(m_plugin->plug_label()).append("\")");; + m_plugin->uri()); _responder->respond_error(msg); } else { _responder->respond_ok(); diff --git a/src/libs/engine/types.h b/src/libs/engine/types.h index c623ac42..73cc5c73 100644 --- a/src/libs/engine/types.h +++ b/src/libs/engine/types.h @@ -14,7 +14,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef TYPES_H #define TYPES_H diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 3037dd93..9d18cec4 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -20,6 +20,7 @@ #include #include #include "PatchController.h" +#include "PatchView.h" #include "NodeModel.h" #include "Controller.h" #include "App.h" @@ -287,7 +288,7 @@ LoadPluginWindow::add_clicked() nm->polyphonic(polyphonic); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_new_module_location( + m_patch_controller->view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } nm->x(m_new_module_x); diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h index 6f04d25c..00035b13 100644 --- a/src/progs/ingenuity/LoadPluginWindow.h +++ b/src/progs/ingenuity/LoadPluginWindow.h @@ -90,7 +90,7 @@ public: void patch_controller(PatchController* pc); void set_plugin_list(const std::map >& m); - void set_next_module_location(int x, int y) + void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } void add_plugin(CountedPtr plugin); @@ -125,8 +125,8 @@ private: int m_plugin_name_offset; // see comments for generate_plugin_name - int m_new_module_x; - int m_new_module_y; + double m_new_module_x; + double m_new_module_y; Gtk::TreeView* m_plugins_treeview; Gtk::CheckButton* m_polyphonic_checkbutton; diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp index dbf40c00..0ec98771 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp @@ -20,6 +20,8 @@ #include #include "App.h" #include "PatchController.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" #include "NodeModel.h" #include "Controller.h" #include "PatchModel.h" @@ -130,9 +132,11 @@ LoadSubpatchWindow::ok_clicked() assert(m_patch_controller != NULL); assert(m_patch_controller->model()); - // These values are interpreted by load_patch() as "not defined", ie load from file - string name = ""; - int poly = 0; + const string filename = get_filename(); + + // FIXME + string name = filename.substr(filename.find_last_of("/")+1); + int poly = 1; if (m_name_from_user_radio->get_active()) name = m_name_entry->get_text(); @@ -143,21 +147,21 @@ LoadSubpatchWindow::ok_clicked() poly = m_patch_controller->patch_model()->poly(); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_new_module_location( + m_patch_controller->view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } PatchModel* pm = new PatchModel(m_patch_controller->model()->base_path() + name, poly); - pm->filename(get_filename()); + pm->filename(filename); pm->set_parent(m_patch_controller->model().get()); pm->x(m_new_module_x); pm->y(m_new_module_y); - if (name == "") - pm->set_path(""); + //if (name == "") + // pm->set_path(""); char temp_buf[16]; - snprintf(temp_buf, 16, "%d", m_new_module_x); + snprintf(temp_buf, 16, "%16f", m_new_module_x); pm->set_metadata("module-x", temp_buf); - snprintf(temp_buf, 16, "%d", m_new_module_y); + snprintf(temp_buf, 16, "%16f", m_new_module_y); pm->set_metadata("module-y", temp_buf); Controller::instance().load_patch(pm); diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h index 2ec37432..c4696628 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.h +++ b/src/progs/ingenuity/LoadSubpatchWindow.h @@ -41,7 +41,7 @@ public: void patch_controller(PatchController* pc); - void set_next_module_location(int x, int y) + void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } protected: @@ -58,8 +58,8 @@ private: PatchController* m_patch_controller; - int m_new_module_x; - int m_new_module_y; + double m_new_module_x; + double m_new_module_y; Gtk::RadioButton* m_name_from_file_radio; Gtk::RadioButton* m_name_from_user_radio; diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp index 3f1e19fd..84f9bb7f 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ b/src/progs/ingenuity/NewSubpatchWindow.cpp @@ -16,6 +16,8 @@ #include "NewSubpatchWindow.h" #include "PatchController.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" #include "NodeModel.h" #include "Controller.h" #include "PatchModel.h" @@ -84,7 +86,7 @@ NewSubpatchWindow::ok_clicked() m_poly_spinbutton->get_value_as_int()); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_new_module_location( + m_patch_controller->view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } @@ -92,9 +94,9 @@ NewSubpatchWindow::ok_clicked() pm->x(m_new_module_x); pm->y(m_new_module_y); char temp_buf[16]; - snprintf(temp_buf, 16, "%d", m_new_module_x); + snprintf(temp_buf, 16, "%16f", m_new_module_x); pm->set_metadata("module-x", temp_buf); - snprintf(temp_buf, 16, "%d", m_new_module_y); + snprintf(temp_buf, 16, "%16f", m_new_module_y); pm->set_metadata("module-y", temp_buf); Controller::instance().create_patch_from_model(pm); hide(); diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h index de6c4150..46fa9e1c 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.h +++ b/src/progs/ingenuity/NewSubpatchWindow.h @@ -41,7 +41,7 @@ public: void patch_controller(PatchController* pc); - void set_next_module_location(int x, int y) + void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } private: @@ -51,8 +51,8 @@ private: PatchController* m_patch_controller; - int m_new_module_x; - int m_new_module_y; + double m_new_module_x; + double m_new_module_y; Gtk::Entry* m_name_entry; Gtk::Label* m_message_label; diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp index 94dc9b17..7d4bd3a4 100644 --- a/src/progs/ingenuity/OmFlowCanvas.cpp +++ b/src/progs/ingenuity/OmFlowCanvas.cpp @@ -203,6 +203,19 @@ OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_outp } +/** Try to guess a suitable location for a new module. + */ +void +OmFlowCanvas::get_new_module_location(double& x, double& y) +{ + int scroll_x; + int scroll_y; + get_scroll_offsets(scroll_x, scroll_y); + x = scroll_x + 20; + y = scroll_y + 20; +} + + /* void OmFlowCanvas::menu_add_audio_input() diff --git a/src/progs/ingenuity/OmFlowCanvas.h b/src/progs/ingenuity/OmFlowCanvas.h index 656cc2c2..310aa5b8 100644 --- a/src/progs/ingenuity/OmFlowCanvas.h +++ b/src/progs/ingenuity/OmFlowCanvas.h @@ -46,6 +46,7 @@ public: void connect(const Port* src_port, const Port* dst_port); void disconnect(const Port* src_port, const Port* dst_port); + void get_new_module_location(double& x, double& y); bool canvas_event(GdkEvent* event); void destroy_selected(); diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp index 79084cdc..49c7491c 100644 --- a/src/progs/ingenuity/PatchController.cpp +++ b/src/progs/ingenuity/PatchController.cpp @@ -313,8 +313,8 @@ PatchController::create_view() /* Set sane default coordinates if not set already yet */ if (nm->x() == 0.0f && nm->y() == 0.0f) { - int x, y; - get_new_module_location(x, y); + double x, y; + m_patch_view->canvas()->get_new_module_location(x, y); nm->x(x); nm->y(y); } @@ -338,7 +338,7 @@ PatchController::create_view() PortController* const pc = dynamic_cast((*i)->controller()); assert(pc); if (pc->module() == NULL) - pc->create_module(m_patch_view->canvas(), 1600, 1200); + pc->create_module(m_patch_view->canvas()); assert(pc->module() != NULL); m_patch_view->canvas()->add_module(pc->module()); pc->module()->resize(); @@ -471,8 +471,8 @@ PatchController::add_node(CountedPtr object) assert(node->controller() == nc); if (m_patch_view != NULL) { - int x, y; - get_new_module_location(x, y); + double x, y; + m_patch_view->canvas()->get_new_module_location(x, y); node->x(x); node->y(y); @@ -557,8 +557,6 @@ PatchController::add_port(CountedPtr pm) // Create port's (pseudo) module on this patch's canvas (if there is one) if (m_patch_view != NULL) { - int x, y; - get_new_module_location(x, y); // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) float old_zoom = m_patch_view->canvas()->zoom(); @@ -566,7 +564,7 @@ PatchController::add_port(CountedPtr pm) m_patch_view->canvas()->zoom(1.0); if (pc->module() == NULL) - pc->create_module(m_patch_view->canvas(), x, y); + pc->create_module(m_patch_view->canvas()); assert(pc->module() != NULL); m_patch_view->canvas()->add_module(pc->module()); pc->module()->resize(); @@ -662,20 +660,6 @@ PatchController::disconnection(const Path& src_port_path, const Path& dst_port_p */ } - -/** Try to guess a suitable location for a new module. - */ -void -PatchController::get_new_module_location(int& x, int& y) -{ - assert(m_patch_view != NULL); - assert(m_patch_view->canvas() != NULL); - m_patch_view->canvas()->get_scroll_offsets(x, y); - x += 20; - y += 20; -} - - void PatchController::show_patch_window() { diff --git a/src/progs/ingenuity/PatchController.h b/src/progs/ingenuity/PatchController.h index 54c11888..ef8a438e 100644 --- a/src/progs/ingenuity/PatchController.h +++ b/src/progs/ingenuity/PatchController.h @@ -79,8 +79,6 @@ public: void disconnection(const Path& src_port_path, const Path& dst_port_path); void clear(); - void get_new_module_location(int& x, int& y); - void show_control_window(); void show_properties_window(); void show_patch_window(); diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp index 335e673c..a26c14eb 100644 --- a/src/progs/ingenuity/PortController.cpp +++ b/src/progs/ingenuity/PortController.cpp @@ -15,6 +15,7 @@ */ #include "PortController.h" +#include "OmFlowCanvas.h" #include "OmModule.h" #include "PortModel.h" #include "ControlPanel.h" @@ -54,10 +55,19 @@ PortController::destroy() void -PortController::create_module(OmFlowCanvas* canvas, double x, double y) +PortController::create_module(OmFlowCanvas* canvas) { cerr << "Creating port module " << m_model->path() << endl; + const string x_str = m_model->get_metadata("module-x"); + const string y_str = m_model->get_metadata("module-y"); + + double default_x; + double default_y; + canvas->get_new_module_location(default_x, default_y); + const double x = (x_str == "") ? default_x : atof(x_str.c_str()); + const double y = (y_str == "") ? default_y : atof(y_str.c_str()); + assert(canvas); assert(port_model()); m_module = new OmPortModule(canvas, this, x, y); @@ -65,8 +75,8 @@ PortController::create_module(OmFlowCanvas* canvas, double x, double y) // FIXME: leak m_patch_port = new OmPatchPort(m_module, port_model()); m_module->add_port(m_patch_port, false); - - m_module->move_to(x, y); + + m_module->move_to(x, y); // FIXME: redundant (?) } diff --git a/src/progs/ingenuity/PortController.h b/src/progs/ingenuity/PortController.h index c4ff83db..53c2cd48 100644 --- a/src/progs/ingenuity/PortController.h +++ b/src/progs/ingenuity/PortController.h @@ -53,7 +53,7 @@ public: virtual void destroy(); - virtual void create_module(OmFlowCanvas* canvas, double x, double y); + virtual void create_module(OmFlowCanvas* canvas); OmPortModule* module() { return m_module; } /* virtual void add_to_store(); diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade index 67286660..178eac88 100644 --- a/src/progs/ingenuity/ingenuity.glade +++ b/src/progs/ingenuity/ingenuity.glade @@ -3607,7 +3607,7 @@ Contributors: True Load a patch as a child of this patch - Patch From _File... + _Load Patch... True -- cgit v1.2.1