diff options
-rw-r--r-- | src/libs/gui/App.cpp | 39 | ||||
-rw-r--r-- | src/libs/gui/App.hpp | 21 | ||||
-rw-r--r-- | src/libs/gui/LoadPluginWindow.cpp | 2 | ||||
-rw-r--r-- | src/libs/gui/PatchCanvas.cpp | 18 |
4 files changed, 62 insertions, 18 deletions
diff --git a/src/libs/gui/App.cpp b/src/libs/gui/App.cpp index 997ae791..78f9e6e8 100644 --- a/src/libs/gui/App.cpp +++ b/src/libs/gui/App.cpp @@ -356,24 +356,49 @@ App::quit() Glib::RefPtr<Gdk::Pixbuf> -App::icon_from_path(const string& path) +App::icon_from_path(const string& path, int size) { - map<string, Glib::RefPtr<Gdk::Pixbuf> >::iterator iter = _icons.find(path); + /* If weak references to Glib::Objects are needed somewhere else it will + probably be a good idea to create a proper WeakPtr class instead of + using raw pointers, but for a single use this will do. */ - if (iter != _icons.end()) - return iter->second; + IconMap::iterator iter = _icons.find(make_pair(path, size)); + + if (iter != _icons.end()) { + // we need to reference manually since the RefPtr constructor doesn't do it + iter->second->reference(); + return Glib::RefPtr<Gdk::Pixbuf>(iter->second); + } Glib::RefPtr<Gdk::Pixbuf> buf; try { - buf = Gdk::Pixbuf::create_from_file(path, 20, 20); - _icons.insert(make_pair(path, buf)); + buf = Gdk::Pixbuf::create_from_file(path, size, size); + _icons.insert(make_pair(make_pair(path, size), buf.operator->())); + buf->add_destroy_notify_callback(new pair<string, int>(path, size), + &App::icon_destroyed); + cerr << "Loaded icon " << path << " with size " << size << endl; } catch (...) { - buf = Glib::RefPtr<Gdk::Pixbuf>(0); + cerr << "Caught exception, failed to load icon " << path << endl; } return buf; } +void* +App::icon_destroyed(void* data) +{ + pair<string, int>* p = static_cast<pair<string, int>*>(data); + cerr << "Destroyed icon " << p->first << " with size " << p->second << endl; + IconMap::iterator iter = instance()._icons.find(*p); + if (iter != instance()._icons.end()) + instance()._icons.erase(iter); + + delete p; // allocated in App::icon_from_path + + return NULL; +} + + } // namespace GUI } // namespace Ingen diff --git a/src/libs/gui/App.hpp b/src/libs/gui/App.hpp index a54db98f..9e700ceb 100644 --- a/src/libs/gui/App.hpp +++ b/src/libs/gui/App.hpp @@ -100,7 +100,7 @@ public: Configuration* configuration() const { return _configuration; } WindowFactory* window_factory() const { return _window_factory; } - Glib::RefPtr<Gdk::Pixbuf> icon_from_path(const string& path); + Glib::RefPtr<Gdk::Pixbuf> icon_from_path(const string& path, int size); const SharedPtr<EngineInterface>& engine() const { return _engine; } const SharedPtr<SigClientInterface>& client() const { return _client; } @@ -120,10 +120,25 @@ public: Ingen::Shared::World* world() { return _world; } protected: + + /** This is needed for the icon map. */ + template <typename A, typename B> + struct LexicalCompare { + bool operator()(const pair<A, B>& p1, const pair<A, B>& p2) { + return (p1.first < p2.first) || + ((p1.first == p2.first) && (p1.second < p2.second)); + } + }; + + typedef map<pair<string, int>, Gdk::Pixbuf*, LexicalCompare<string, int> > IconMap; + IconMap _icons; + App(Ingen::Shared::World* world); bool animate(); + static void* icon_destroyed(void* data); + static App* _instance; SharedPtr<Glib::Module> _serialisation_module; @@ -141,9 +156,7 @@ protected: PatchTreeWindow* _patch_tree_window; Gtk::AboutDialog* _about_dialog; WindowFactory* _window_factory; - - map<string, Glib::RefPtr<Gdk::Pixbuf> > _icons; - + Ingen::Shared::World* _world; /// <Port, whether it has been seen in gtk callback yet> diff --git a/src/libs/gui/LoadPluginWindow.cpp b/src/libs/gui/LoadPluginWindow.cpp index 5abbcb72..5c357827 100644 --- a/src/libs/gui/LoadPluginWindow.cpp +++ b/src/libs/gui/LoadPluginWindow.cpp @@ -219,7 +219,7 @@ LoadPluginWindow::set_plugins(const Raul::Table<string, SharedPtr<PluginModel> > Gtk::TreeModel::iterator iter = _plugins_liststore->append(); Gtk::TreeModel::Row row = *iter; - row[_plugins_columns._col_icon] = App::instance().icon_from_path(plugin->icon_path()); + row[_plugins_columns._col_icon] = App::instance().icon_from_path(plugin->icon_path(), 20); row[_plugins_columns._col_name] = plugin->name(); //row[_plugins_columns._col_label] = plugin->plug_label(); if (!strcmp(plugin->type_uri(), "ingen:Internal")) diff --git a/src/libs/gui/PatchCanvas.cpp b/src/libs/gui/PatchCanvas.cpp index 0b136014..657617dd 100644 --- a/src/libs/gui/PatchCanvas.cpp +++ b/src/libs/gui/PatchCanvas.cpp @@ -159,15 +159,16 @@ PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu, 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)); + 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))); + *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))); + sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), i->second))); ++num_items; } } @@ -245,9 +246,14 @@ PatchCanvas::add_node(SharedPtr<NodeModel> nm) SharedPtr<NodeModule> module; if (pm) module = SubpatchModule::create(shared_this, pm); - else + else { module = NodeModule::create(shared_this, nm); - + const PluginModel* plugm = + dynamic_cast<const PluginModel*>(nm->plugin()); + if (plugm) + module->set_icon(App::instance().icon_from_path(plugm->icon_path(), 100)); + } + add_item(module); module->show(); _views.insert(std::make_pair(nm, module)); |