/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. * * 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 "WindowFactory.h" #include "App.h" #include "PatchWindow.h" #include "GladeFactory.h" #include "NodePropertiesWindow.h" #include "PatchPropertiesWindow.h" #include "NodeControlWindow.h" #include "LoadPluginWindow.h" #include "LoadPatchWindow.h" #include "LoadSubpatchWindow.h" #include "RenameWindow.h" #include "NewSubpatchWindow.h" namespace Ingenuity { WindowFactory::WindowFactory() : _load_plugin_win(NULL) , _load_patch_win(NULL) , _new_subpatch_win(NULL) , _load_subpatch_win(NULL) , _node_properties_win(NULL) , _patch_properties_win(NULL) { Glib::RefPtr xml = GladeFactory::new_glade_reference(); xml->get_widget_derived("load_plugin_win", _load_plugin_win); xml->get_widget_derived("load_patch_win", _load_patch_win); xml->get_widget_derived("new_subpatch_win", _new_subpatch_win); xml->get_widget_derived("load_subpatch_win", _load_subpatch_win); xml->get_widget_derived("node_properties_win", _node_properties_win); xml->get_widget_derived("patch_properties_win", _patch_properties_win); } WindowFactory::~WindowFactory() { for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) delete i->second; for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) delete i->second; } PatchWindow* WindowFactory::patch_window(CountedPtr patch) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); return (w == _patch_windows.end()) ? NULL : w->second; } NodeControlWindow* WindowFactory::control_window(CountedPtr node) { ControlWindowMap::iterator w = _control_windows.find(node->path()); return (w == _control_windows.end()) ? NULL : w->second; } /** Present a PatchWindow for a Patch. * * If @a preferred is not NULL, it will be set to display @a patch if the patch * does not already have a visible window, otherwise that window will be presented and * @a preferred left unmodified. */ void WindowFactory::present_patch(CountedPtr patch, PatchWindow* preferred, CountedPtr view) { assert( !view || view->patch() == patch); PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) { (*w).second->present(); } else if (preferred) { w = _patch_windows.find(preferred->patch()->path()); assert((*w).second == preferred); preferred->set_patch(patch, view); _patch_windows.erase(w); _patch_windows[patch->path()] = preferred; preferred->present(); } else { PatchWindow* win = new_patch_window(patch, view); win->present(); } } PatchWindow* WindowFactory::new_patch_window(CountedPtr patch, CountedPtr view) { assert( !view || view->patch() == patch); Glib::RefPtr xml = GladeFactory::new_glade_reference("patch_win"); PatchWindow* win = NULL; xml->get_widget_derived("patch_win", win); assert(win); win->set_patch(patch, view); _patch_windows[patch->path()] = win; win->signal_delete_event().connect(sigc::bind<0>( sigc::mem_fun(this, &WindowFactory::remove_patch_window), win)); return win; } bool WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored) { if (_patch_windows.size() <= 1) { Gtk::MessageDialog d(*win, "This is the last remaining open patch " "window. Closing this window will exit Ingenuity (the engine will " "remain running).\n\nAre you sure you want to quit?", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); int ret = d.run(); if (ret == Gtk::RESPONSE_CLOSE) App::instance().quit(); else return false; } PatchWindowMap::iterator w = _patch_windows.find(win->patch()->path()); assert((*w).second == win); _patch_windows.erase(w); delete win; return true; } void WindowFactory::present_controls(CountedPtr node) { NodeControlWindow* win = control_window(node); if (win) { win->present(); } else { win = new_control_window(node); win->present(); } } NodeControlWindow* WindowFactory::new_control_window(CountedPtr node) { size_t poly = 1; if (node->polyphonic()) poly = ((PatchModel*)node->parent().get())->poly(); NodeControlWindow* win = new NodeControlWindow(node, poly); _control_windows[node->path()] = win; win->signal_delete_event().connect(sigc::bind<0>( sigc::mem_fun(this, &WindowFactory::remove_control_window), win)); return win; } bool WindowFactory::remove_control_window(NodeControlWindow* win, GdkEventAny* ignored) { ControlWindowMap::iterator w = _control_windows.find(win->node()->path()); assert((*w).second == win); _control_windows.erase(w); delete win; return true; } void WindowFactory::present_load_plugin(CountedPtr patch, MetadataMap data) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) _load_plugin_win->set_transient_for(*w->second); _load_plugin_win->present(patch, data); } void WindowFactory::present_load_patch(CountedPtr patch, MetadataMap data) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) _load_patch_win->set_transient_for(*w->second); _load_patch_win->set_merge(); // Import is the only choice _load_patch_win->present(patch, data); } void WindowFactory::present_new_subpatch(CountedPtr patch, MetadataMap data) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) _new_subpatch_win->set_transient_for(*w->second); _new_subpatch_win->present(patch, data); } void WindowFactory::present_load_subpatch(CountedPtr patch, MetadataMap data) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) _load_subpatch_win->set_transient_for(*w->second); _load_subpatch_win->present(patch, data); } void WindowFactory::present_rename(CountedPtr object) { PatchWindowMap::iterator w = _patch_windows.find(object->path()); if (w != _patch_windows.end()) _rename_win->set_transient_for(*w->second); _rename_win->present(object); } void WindowFactory::present_properties(CountedPtr node) { CountedPtr patch = PtrCast(node); if (patch) { PatchWindowMap::iterator w = _patch_windows.find(patch->path()); if (w != _patch_windows.end()) _patch_properties_win->set_transient_for(*w->second); _patch_properties_win->present(patch); } else { PatchWindowMap::iterator w = _patch_windows.find(node->parent()->path()); if (w != _patch_windows.end()) _node_properties_win->set_transient_for(*w->second); _node_properties_win->present(node); } } } // namespace Ingenuity