summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/PatchCanvas.cpp124
-rw-r--r--src/gui/PatchCanvas.hpp16
2 files changed, 89 insertions, 51 deletions
diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp
index 860b9178..f4274e4a 100644
--- a/src/gui/PatchCanvas.cpp
+++ b/src/gui/PatchCanvas.cpp
@@ -62,6 +62,7 @@ PatchCanvas::PatchCanvas(SharedPtr<PatchModel> patch, int width, int height)
, _human_names(true)
, _menu(NULL)
, _internal_menu(NULL)
+ , _classless_menu(NULL)
, _plugin_menu(NULL)
{
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
@@ -141,20 +142,17 @@ PatchCanvas::PatchCanvas(SharedPtr<PatchModel> patch, int width, int height)
void
PatchCanvas::show_menu(GdkEvent* event)
{
- if (!_internal_menu || !_plugin_menu || _refresh_menu) {
- build_internal_menu();
-#ifdef HAVE_SLV2
- build_plugin_menu();
-#endif
- _refresh_menu = false;
- }
+ if (!_internal_menu || !_classless_menu || !_plugin_menu || _refresh_menu)
+ build_menus();
+
_menu->popup(event->button.button, event->button.time);
}
void
-PatchCanvas::build_internal_menu()
+PatchCanvas::build_menus()
{
+ // Build (or clear existing) internal plugin menu
if (_internal_menu) {
_internal_menu->items().clear();
} else {
@@ -165,27 +163,45 @@ PatchCanvas::build_internal_menu()
internal_menu_item->set_submenu(*_internal_menu);
_menu->reorder_child(*internal_menu_item, 2);
}
+
+ // Build skeleton LV2 plugin class heirarchy for 'Plugin' menu
+#ifdef HAVE_SLV2
+ if (!_plugin_menu)
+ build_plugin_menu();
+
+ // Build (or clear existing) uncategorized (classless, heh) plugins menu
+ if (_classless_menu) {
+ _classless_menu->items().clear();
+ } else {
+ _plugin_menu->items().push_back(Gtk::Menu_Helpers::MenuElem("Uncategorized"));
+ Gtk::MenuItem* classless_menu_item = &(_plugin_menu->items().back());
+ _classless_menu = Gtk::manage(new Gtk::Menu());
+ classless_menu_item->set_submenu(*_classless_menu);
+ _classless_menu->hide();
+ }
+#endif
+ // Add known plugins to menu heirarchy
SharedPtr<const ClientStore::Plugins> plugins = App::instance().store()->plugins();
-
- // Add Internal plugins
for (ClientStore::Plugins::const_iterator i = plugins->begin(); i != plugins->end(); ++i) {
- SharedPtr<PluginModel> p = i->second;
- if (p->type() == Plugin::Internal) {
- _internal_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p->name(),
- sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p)));
- }
+ add_plugin(i->second);
}
}
#ifdef HAVE_SLV2
+/** Recursively build the plugin class menu heirarchy rooted at
+ * @a plugin class into @a menu
+ */
size_t
PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu,
SLV2PluginClass plugin_class, SLV2PluginClasses classes)
{
size_t num_items = 0;
+ SLV2Value class_uri = slv2_plugin_class_get_uri(plugin_class);
+ _class_menus[slv2_value_as_string(class_uri)] = menu;
+
// Add submenus
for (unsigned i=0; i < slv2_plugin_classes_size(classes); ++i) {
SLV2PluginClass c = slv2_plugin_classes_get_at(classes, i);
@@ -194,38 +210,18 @@ PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu,
if (parent && slv2_value_equals(parent, slv2_plugin_class_get_uri(plugin_class))) {
Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem(
slv2_value_as_string(slv2_plugin_class_get_label(c)));
+
+ menu->items().push_back(menu_elem);
+ Gtk::MenuItem* menu_item = &(menu->items().back());
Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu());
- size_t sub_num_items = build_plugin_class_menu(submenu, c, classes);
+ size_t num_items = build_plugin_class_menu(submenu, c, classes);
+
+ // TODO: store items in map as well and do this to hide empty classes
+ //(num_items > 0) ? submenu->show() : submenu->hide();
- if (sub_num_items > 0) {
- menu->items().push_back(menu_elem);
- Gtk::MenuItem* menu_item = &(menu->items().back());
- menu_item->set_submenu(*submenu);
- ++num_items;
- }
- }
- }
-
- SharedPtr<const ClientStore::Plugins> plugins = App::instance().store()->plugins();
-
- // Add LV2 plugins
- for (ClientStore::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) {
- Glib::RefPtr<Gdk::Pixbuf> icon
- = App::instance().icon_from_path(PluginModel::get_lv2_icon_path(p), 16);
- if (icon) {
- Gtk::Image* image = new Gtk::Image(icon);
- menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem(i->second->name(),
- *image,
- sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), i->second)));
- } else {
- menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second->name(),
- sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), i->second)));
- ++num_items;
- }
+ menu_item->set_submenu(*submenu);
+ ++num_items;
}
}
@@ -307,9 +303,37 @@ PatchCanvas::show_human_names(bool b)
void
-PatchCanvas::add_plugin(SharedPtr<PluginModel> pm)
-{
- _refresh_menu = true;
+PatchCanvas::add_plugin(SharedPtr<PluginModel> p)
+{
+ if (_internal_menu && p->type() == Plugin::Internal) {
+ _internal_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p->name(),
+ sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p)));
+ } else if (_plugin_menu && p->type() == Plugin::LV2) {
+ SLV2PluginClass pc = slv2_plugin_get_class(p->slv2_plugin());
+ SLV2Value class_uri = slv2_plugin_class_get_uri(pc);
+ ClassMenus::iterator i = _class_menus.find(slv2_value_as_string(class_uri));
+ if (i != _class_menus.end() && i->second != _plugin_menu) {
+ Gtk::Menu* menu = i->second;
+ Glib::RefPtr<Gdk::Pixbuf> icon = App::instance().icon_from_path(
+ PluginModel::get_lv2_icon_path(p->slv2_plugin()), 16);
+ if (icon) {
+ Gtk::Image* image = new Gtk::Image(icon);
+ menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem(p->human_name(),
+ *image,
+ sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p)));
+ } else {
+ menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p->human_name(),
+ sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p)));
+ menu->show();
+ }
+ } else {
+ _classless_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p->human_name(),
+ sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p)));
+ _classless_menu->show();
+ }
+ }
+
+ _refresh_menu = true; // Refresh next time on show
}
@@ -705,8 +729,12 @@ PatchCanvas::menu_add_port(const string& name, const string& type, bool is_outpu
void
-PatchCanvas::load_plugin(SharedPtr<PluginModel> plugin)
+PatchCanvas::load_plugin(WeakPtr<PluginModel> weak_plugin)
{
+ SharedPtr<PluginModel> plugin = weak_plugin.lock();
+ if (!plugin)
+ return;
+
string name = plugin->default_node_symbol();
unsigned offset = App::instance().store()->child_name_offset(_patch->path(), name);
if (offset != 0) {
diff --git a/src/gui/PatchCanvas.hpp b/src/gui/PatchCanvas.hpp
index 8885cb22..b1474495 100644
--- a/src/gui/PatchCanvas.hpp
+++ b/src/gui/PatchCanvas.hpp
@@ -97,13 +97,19 @@ private:
void menu_load_plugin();
void menu_new_patch();
void menu_load_patch();
- void load_plugin(SharedPtr<PluginModel> plugin);
+ void load_plugin(WeakPtr<PluginModel> plugin);
+
+ void build_menus();
void build_internal_menu();
+ void build_classless_menu();
+
#ifdef HAVE_SLV2
void build_plugin_menu();
- size_t build_plugin_class_menu(Gtk::Menu* menu,
- SLV2PluginClass plugin_class, SLV2PluginClasses classes);
+ size_t build_plugin_class_menu(
+ Gtk::Menu* menu,
+ SLV2PluginClass plugin_class,
+ SLV2PluginClasses classes);
#endif
GraphObject::Variables get_initial_data();
@@ -125,11 +131,15 @@ private:
int _last_click_x;
int _last_click_y;
+
+ typedef std::map<const std::string, Gtk::Menu*> ClassMenus;
+ ClassMenus _class_menus;
bool _refresh_menu;
bool _human_names;
Gtk::Menu* _menu;
Gtk::Menu* _internal_menu;
+ Gtk::Menu* _classless_menu;
Gtk::Menu* _plugin_menu;
/*Gtk::MenuItem* _menu_add_number_control;
Gtk::MenuItem* _menu_add_button_control;*/