diff options
-rw-r--r-- | src/libs/client/Makefile.am | 1 | ||||
-rw-r--r-- | src/libs/client/PluginModel.cpp | 52 | ||||
-rw-r--r-- | src/libs/client/PluginModel.h | 18 | ||||
-rw-r--r-- | src/libs/client/Store.cpp | 2 | ||||
-rw-r--r-- | src/libs/client/Store.h | 12 | ||||
-rw-r--r-- | src/progs/ingenuity/LoadPluginWindow.cpp | 6 | ||||
-rw-r--r-- | src/progs/ingenuity/PatchCanvas.cpp | 74 | ||||
-rw-r--r-- | src/progs/ingenuity/PatchCanvas.h | 4 |
8 files changed, 153 insertions, 16 deletions
diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index 89dff982..b226c381 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -28,6 +28,7 @@ libingenclient_la_SOURCES = \ PatchModel.h \ PatchModel.cpp \ PluginModel.h \ + PluginModel.cpp \ Serializer.h \ Serializer.cpp \ Loader.h \ diff --git a/src/libs/client/PluginModel.cpp b/src/libs/client/PluginModel.cpp new file mode 100644 index 00000000..89dcab6d --- /dev/null +++ b/src/libs/client/PluginModel.cpp @@ -0,0 +1,52 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard <http://drobilla.net> + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <sstream> +#include <raul/Path.h> +#include "PluginModel.h" +#include "PatchModel.h" + + +namespace Ingen { +namespace Client { + +SLV2World PluginModel::_slv2_world = NULL; + + +string +PluginModel::default_node_name(SharedPtr<PatchModel> parent) +{ + string default_name = Raul::Path::nameify(_name); + string name; + + char num_buf[3]; + for (uint i=0; i < 99; ++i) { + name = default_name; + if (i != 0) { + snprintf(num_buf, 3, "%d", i+1); + name += num_buf; + } + if (!parent->get_node(name)) + break; + } + + return name; +} + + +} // namespace Client +} // namespace Ingen diff --git a/src/libs/client/PluginModel.h b/src/libs/client/PluginModel.h index f1c83377..6614a3b6 100644 --- a/src/libs/client/PluginModel.h +++ b/src/libs/client/PluginModel.h @@ -22,6 +22,7 @@ #include <string> #include <iostream> #include "raul/Path.h" +#include "raul/SharedPtr.h" #ifdef HAVE_SLV2 #include <slv2/slv2.h> #endif @@ -30,6 +31,8 @@ using std::string; using std::cerr; using std::endl; namespace Ingen { namespace Client { +class PatchModel; + /** Model for a plugin available for loading. * @@ -46,13 +49,12 @@ public: { set_type_from_uri(type_uri); #ifdef HAVE_SLV2 - static SLV2World world = NULL; static SLV2Plugins plugins = NULL; - if (!world) { - world = slv2_world_new(); - slv2_world_load_all(world); - plugins = slv2_world_get_all_plugins(world); + if (!_slv2_world) { + _slv2_world = slv2_world_new(); + slv2_world_load_all(_slv2_world); + plugins = slv2_world_get_all_plugins(_slv2_world); } _slv2_plugin = slv2_plugins_get_by_uri(plugins, uri.c_str()); @@ -101,10 +103,11 @@ public: } } - string default_node_name() { return Raul::Path::nameify(_name); } + string default_node_name(SharedPtr<PatchModel> parent); #ifdef HAVE_SLV2 - SLV2Plugin slv2_plugin() { return _slv2_plugin; } + SLV2Plugin slv2_plugin() { return _slv2_plugin; } + static SLV2World slv2_world() { return _slv2_world; } #endif private: @@ -113,6 +116,7 @@ private: string _name; #ifdef HAVE_SLV2 + static SLV2World _slv2_world; SLV2Plugin _slv2_plugin; #endif }; diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index 462b1475..fa9707d1 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -223,7 +223,7 @@ Store::add_object(SharedPtr<ObjectModel> object) { // If we already have "this" object, merge the existing one into the new // one (with precedence to the new values). - ObjectMap::iterator existing = _objects.find(object->path()); + Objects::iterator existing = _objects.find(object->path()); if (existing != _objects.end()) { existing->second->set(object); } else { diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h index 60bc88c7..2059f55f 100644 --- a/src/libs/client/Store.h +++ b/src/libs/client/Store.h @@ -59,8 +59,11 @@ public: size_t num_object() { return _objects.size(); } - const map<string, SharedPtr<PluginModel> >& plugins() const { return _plugins; } - const map<Path, SharedPtr<ObjectModel> >& objects() const { return _objects; } + typedef map<string, SharedPtr<PluginModel> > Plugins; + const Plugins& plugins() const { return _plugins; } + + typedef map<Path, SharedPtr<ObjectModel> > Objects; + const Objects& objects() const { return _objects; } sigc::signal<void, SharedPtr<ObjectModel> > new_object_sig; private: @@ -103,10 +106,9 @@ private: SharedPtr<EngineInterface> _engine; SharedPtr<SigClientInterface> _emitter; - typedef map<Path, SharedPtr<ObjectModel> > ObjectMap; - ObjectMap _objects; ///< Keyed by Ingen path - map<string, SharedPtr<PluginModel> > _plugins; ///< Keyed by URI + Objects _objects; ///< Map, keyed by Ingen path + Plugins _plugins; ///< Map, keyed by plugin URI /** Objects we've received, but depend on the existance of another unknown object. * Keyed by the path of the depended-on object (for tolerance of orderless comms) */ diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 498f5d6f..2e58c67c 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -262,7 +262,9 @@ LoadPluginWindow::generate_module_name(int offset) if (iter) { Gtk::TreeModel::Row row = *iter; SharedPtr<PluginModel> plugin = row.get_value(_plugins_columns._col_plugin_model); - char num_buf[3]; + return plugin->default_node_name(_patch); + } + /*char num_buf[3]; for (uint i=0; i < 99; ++i) { name = plugin->default_node_name(); if (name == "") @@ -277,7 +279,7 @@ LoadPluginWindow::generate_module_name(int offset) else name = ""; } - } + }*/ return name; } diff --git a/src/progs/ingenuity/PatchCanvas.cpp b/src/progs/ingenuity/PatchCanvas.cpp index 13ceaac0..af99d4d1 100644 --- a/src/progs/ingenuity/PatchCanvas.cpp +++ b/src/progs/ingenuity/PatchCanvas.cpp @@ -34,7 +34,12 @@ #include "GladeFactory.h" #include "WindowFactory.h" #include "Serializer.h" +#include "Store.h" +#include "PluginModel.h" +#include "config.h" +using Ingen::Client::Store; using Ingen::Client::Serializer; +using Ingen::Client::PluginModel; namespace Ingenuity { @@ -78,6 +83,8 @@ PatchCanvas::PatchCanvas(SharedPtr<PatchModel> patch, int width, int height) sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), "midi_output", "ingen:midi", true)); + build_plugin_menu(); + // Connect to model signals to track state _patch->new_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); _patch->removed_node_sig.connect(sigc::mem_fun(this, &PatchCanvas::remove_node)); @@ -94,6 +101,62 @@ PatchCanvas::PatchCanvas(SharedPtr<PatchModel> patch, int width, int height) void +PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu, + SLV2PluginClass plugin_class, SLV2PluginClasses classes) +{ +#ifdef HAVE_SLV2 + // Add submenus + for (unsigned i=0; i < slv2_plugin_classes_size(classes); ++i) { + SLV2PluginClass c = slv2_plugin_classes_get_at(classes, i); + const char* parent = slv2_plugin_class_get_parent_uri(c); + + if (parent && !strcmp(parent, slv2_plugin_class_get_uri(plugin_class))) { + menu->items().push_back(Gtk::Menu_Helpers::MenuElem( + slv2_plugin_class_get_label(c))); + Gtk::MenuItem* menu_item = &(menu->items().back()); + Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); + menu_item->set_submenu(*submenu); + build_plugin_class_menu(submenu, c, classes); + } + } + + + const Store::Plugins& plugins = App::instance().store()->plugins(); + + // Add plugins + for (Store::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { + SLV2Plugin p = i->second->slv2_plugin(); + if (p && slv2_plugin_get_class(p) == plugin_class) + menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second->name(), + sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), + i->second))); + } + + +#endif +} + + +void +PatchCanvas::build_plugin_menu() +{ +#ifdef HAVE_SLV2 + _menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem("Plugin", + *(manage(new Gtk::Image(Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))))); + Gtk::MenuItem* plugin_menu_item = &(_menu->items().back()); + Gtk::Menu* plugin_menu = Gtk::manage(new Gtk::Menu()); + plugin_menu_item->set_submenu(*plugin_menu); + _menu->reorder_child(*plugin_menu_item, 2); + + SLV2PluginClass lv2_plugin = slv2_world_get_plugin_class(PluginModel::slv2_world()); + SLV2PluginClasses classes = slv2_world_get_plugin_classes(PluginModel::slv2_world()); + + build_plugin_class_menu(plugin_menu, lv2_plugin, classes); +#endif +} + + +void PatchCanvas::build() { boost::shared_ptr<PatchCanvas> shared_this = @@ -118,7 +181,7 @@ PatchCanvas::build() } } - + void PatchCanvas::arrange() { @@ -397,6 +460,15 @@ PatchCanvas::menu_add_port(const string& name, const string& type, bool is_outpu } +void +PatchCanvas::load_plugin(SharedPtr<PluginModel> plugin) +{ + const Path& path = _patch->path().base() + plugin->default_node_name(_patch); + // FIXME: polyphony? + App::instance().engine()->create_node_with_data(plugin->uri(), path, false, get_initial_data()); +} + + /** Try to guess a suitable location for a new module. */ void diff --git a/src/progs/ingenuity/PatchCanvas.h b/src/progs/ingenuity/PatchCanvas.h index 64f72881..b36bd115 100644 --- a/src/progs/ingenuity/PatchCanvas.h +++ b/src/progs/ingenuity/PatchCanvas.h @@ -84,6 +84,10 @@ private: void menu_load_plugin(); void menu_new_patch(); void menu_load_patch(); + void load_plugin(SharedPtr<PluginModel> plugin); + void build_plugin_menu(); + void build_plugin_class_menu(Gtk::Menu* menu, + SLV2PluginClass plugin_class, SLV2PluginClasses classes); MetadataMap get_initial_data(); |