summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-04-21 07:18:40 +0000
committerDavid Robillard <d@drobilla.net>2007-04-21 07:18:40 +0000
commitbd315305771e98eba1d81672a47ce4fe7bcc95cc (patch)
treed8bdf2a4737fe53bf2c37a4bd6fa262b79b0c348
parent7b2eaa5d9a71ce17dc1407f27bbe325c26cfc128 (diff)
downloadingen-bd315305771e98eba1d81672a47ce4fe7bcc95cc.tar.gz
ingen-bd315305771e98eba1d81672a47ce4fe7bcc95cc.tar.bz2
ingen-bd315305771e98eba1d81672a47ce4fe7bcc95cc.zip
Loading plugins via class-based menu heirarchy in patch context menu.
git-svn-id: http://svn.drobilla.net/lad/ingen@468 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/client/Makefile.am1
-rw-r--r--src/libs/client/PluginModel.cpp52
-rw-r--r--src/libs/client/PluginModel.h18
-rw-r--r--src/libs/client/Store.cpp2
-rw-r--r--src/libs/client/Store.h12
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.cpp6
-rw-r--r--src/progs/ingenuity/PatchCanvas.cpp74
-rw-r--r--src/progs/ingenuity/PatchCanvas.h4
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();