From e5675ebfeb93175e16762d0a078bd51d15d05f63 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 13 Sep 2006 06:11:25 +0000 Subject: Heavy-duty redesign of client library and GUI (now fully signal driven with clean Model/View separation). Smarter, centralized window creation/management (should make window unification easy (panes?)). Typed metadata system, no more fugly string conversion of floats. Supports OSC fundamental types string, int, float, blob for now (though blob isn't working over the wire yet). git-svn-id: http://svn.drobilla.net/lad/ingen@131 a436a847-0d15-0410-975c-d299462d15a1 --- src/progs/demolition/demolition.cpp | 15 +- src/progs/ingenuity/App.cpp | 5 - src/progs/ingenuity/App.h | 4 - src/progs/ingenuity/BreadCrumb.h | 33 +- src/progs/ingenuity/BreadCrumbBox.cpp | 58 ++- src/progs/ingenuity/BreadCrumbBox.h | 10 +- src/progs/ingenuity/ConfigWindow.cpp | 2 - src/progs/ingenuity/Configuration.cpp | 2 - src/progs/ingenuity/ConnectWindow.cpp | 5 +- src/progs/ingenuity/ControlGroups.cpp | 40 +- src/progs/ingenuity/ControlGroups.h | 2 +- src/progs/ingenuity/ControlPanel.cpp | 8 +- src/progs/ingenuity/ControlPanel.h | 6 +- src/progs/ingenuity/ControllerFactory.cpp | 72 ---- src/progs/ingenuity/ControllerFactory.h | 32 -- src/progs/ingenuity/DSSIController.cpp | 33 +- src/progs/ingenuity/DSSIController.h | 13 +- src/progs/ingenuity/DSSIModule.cpp | 6 +- src/progs/ingenuity/DSSIModule.h | 2 +- src/progs/ingenuity/GtkObjectController.cpp | 34 -- src/progs/ingenuity/GtkObjectController.h | 83 ---- src/progs/ingenuity/LashController.cpp | 1 - src/progs/ingenuity/LoadPatchWindow.cpp | 23 +- src/progs/ingenuity/LoadPatchWindow.h | 16 +- src/progs/ingenuity/LoadPluginWindow.cpp | 38 +- src/progs/ingenuity/LoadPluginWindow.h | 17 +- src/progs/ingenuity/LoadSubpatchWindow.cpp | 45 ++- src/progs/ingenuity/LoadSubpatchWindow.h | 17 +- src/progs/ingenuity/Loader.cpp | 1 - src/progs/ingenuity/Makefile.am | 18 +- src/progs/ingenuity/NewSubpatchWindow.cpp | 34 +- src/progs/ingenuity/NewSubpatchWindow.h | 17 +- src/progs/ingenuity/NodeControlWindow.cpp | 8 +- src/progs/ingenuity/NodeControlWindow.h | 20 +- src/progs/ingenuity/NodeController.cpp | 404 ------------------- src/progs/ingenuity/NodeController.h | 116 ------ src/progs/ingenuity/NodeMenu.cpp | 254 ++++++++++++ src/progs/ingenuity/NodeMenu.h | 75 ++++ src/progs/ingenuity/NodePropertiesWindow.h | 4 +- src/progs/ingenuity/OmFlowCanvas.cpp | 162 ++++++-- src/progs/ingenuity/OmFlowCanvas.h | 39 +- src/progs/ingenuity/OmModule.cpp | 109 +++-- src/progs/ingenuity/OmModule.h | 21 +- src/progs/ingenuity/OmPatchPort.h | 1 - src/progs/ingenuity/OmPort.h | 1 - src/progs/ingenuity/OmPortModule.cpp | 48 ++- src/progs/ingenuity/OmPortModule.h | 12 +- src/progs/ingenuity/PatchController.cpp | 548 -------------------------- src/progs/ingenuity/PatchController.h | 124 ------ src/progs/ingenuity/PatchPropertiesWindow.cpp | 26 +- src/progs/ingenuity/PatchPropertiesWindow.h | 3 +- src/progs/ingenuity/PatchTreeWindow.cpp | 37 +- src/progs/ingenuity/PatchTreeWindow.h | 7 +- src/progs/ingenuity/PatchView.cpp | 56 ++- src/progs/ingenuity/PatchView.h | 32 +- src/progs/ingenuity/PatchWindow.cpp | 139 +++---- src/progs/ingenuity/PatchWindow.h | 24 +- src/progs/ingenuity/PortController.cpp | 139 ------- src/progs/ingenuity/PortController.h | 79 ---- src/progs/ingenuity/RenameWindow.cpp | 11 +- src/progs/ingenuity/RenameWindow.h | 16 +- src/progs/ingenuity/SubpatchModule.cpp | 30 +- src/progs/ingenuity/SubpatchModule.h | 8 +- src/progs/ingenuity/WindowFactory.cpp | 232 +++++++++-- src/progs/ingenuity/WindowFactory.h | 56 ++- src/progs/ingenuity/ingenuity.glade | 2 +- 66 files changed, 1337 insertions(+), 2198 deletions(-) delete mode 100644 src/progs/ingenuity/ControllerFactory.cpp delete mode 100644 src/progs/ingenuity/ControllerFactory.h delete mode 100644 src/progs/ingenuity/GtkObjectController.cpp delete mode 100644 src/progs/ingenuity/GtkObjectController.h delete mode 100644 src/progs/ingenuity/NodeController.cpp delete mode 100644 src/progs/ingenuity/NodeController.h create mode 100644 src/progs/ingenuity/NodeMenu.cpp create mode 100644 src/progs/ingenuity/NodeMenu.h delete mode 100644 src/progs/ingenuity/PatchController.cpp delete mode 100644 src/progs/ingenuity/PatchController.h delete mode 100644 src/progs/ingenuity/PortController.cpp delete mode 100644 src/progs/ingenuity/PortController.h (limited to 'src/progs') diff --git a/src/progs/demolition/demolition.cpp b/src/progs/demolition/demolition.cpp index e5ffded0..27da5dd9 100644 --- a/src/progs/demolition/demolition.cpp +++ b/src/progs/demolition/demolition.cpp @@ -183,11 +183,8 @@ create_patch() engine->create_patch_from_model(pm); // Spread them out a bit for easier monitoring with ingenuity - char tmp_buf[8]; - snprintf(tmp_buf, 8, "%d", 1600 + rand()%800 - 400); - engine->set_metadata(pm->path(), "module-x", string(tmp_buf)); - snprintf(tmp_buf, 8, "%d", 1200 + rand()%700 - 350); - engine->set_metadata(pm->path(), "module-y", string(tmp_buf)); + engine->set_metadata(pm->path(), "module-x", 1600 + rand()%800 - 400); + engine->set_metadata(pm->path(), "module-y", 1200 + rand()%700 - 350); delete pm; } @@ -225,12 +222,10 @@ add_node() NodeModel* nm = new NodeModel(plugin, parent->path() +"/"+ random_name()); cout << "Adding node " << nm->path() << endl; engine->create_node_from_model(nm); + // Spread them out a bit for easier monitoring with ingenuity - char tmp_buf[8]; - snprintf(tmp_buf, 8, "%d", 1600 + rand()%800 - 400); - engine->set_metadata(nm->path(), "module-x", tmp_buf); - snprintf(tmp_buf, 8, "%d", 1200 + rand()%700 - 350); - engine->set_metadata(nm->path(), "module-y", tmp_buf); + engine->set_metadata(pm->path(), "module-x", 1600 + rand()%800 - 400); + engine->set_metadata(pm->path(), "module-y", 1200 + rand()%700 - 350); } } diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index ae452f27..60482d77 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -25,11 +25,6 @@ #include "OmModule.h" #include "ControlPanel.h" #include "SubpatchModule.h" -#include "OmFlowCanvas.h" -#include "GtkObjectController.h" -#include "PatchController.h" -#include "NodeController.h" -#include "PortController.h" #include "LoadPluginWindow.h" #include "PatchWindow.h" #include "MessagesWindow.h" diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 25e01ff2..d166c37b 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -45,10 +45,6 @@ using namespace Ingen::Client; namespace Ingenuity { class PatchWindow; -class GtkObjectController; -class PatchController; -class NodeController; -class PortController; class LoadPatchWindow; class MessagesWindow; class ConfigWindow; diff --git a/src/progs/ingenuity/BreadCrumb.h b/src/progs/ingenuity/BreadCrumb.h index 66e6d40a..908e0f80 100644 --- a/src/progs/ingenuity/BreadCrumb.h +++ b/src/progs/ingenuity/BreadCrumb.h @@ -17,31 +17,44 @@ #ifndef BREADCRUMB_H #define BREADCRUMB_H -// FIXME: remove -#include -using std::cerr; using std::endl; - #include #include "util/Path.h" +#include "util/CountedPtr.h" +#include "PatchView.h" namespace Ingenuity { /** Breadcrumb button in a PatchWindow. + * + * Each Breadcrumb stores a reference to a PatchView for quick switching. + * So, the amount of allocated PatchViews at a given time is equal to the + * number of visible breadcrumbs (which is the perfect cache for GUI + * responsiveness balanced with mem consumption). * * \ingroup Ingenuity */ class BreadCrumb : public Gtk::ToggleButton { public: - BreadCrumb(const Path& path) - : m_path(path) + BreadCrumb(const Path& path, CountedPtr view = CountedPtr()) + : _path(path) + , _view(view) { + assert( !view || view->patch()->path() == path); set_border_width(0); set_path(path); show_all(); } + void set_view(CountedPtr view) { + assert( !view || view->patch()->path() == _path); + _view = view; + } + + const Path& path() const { return _path; } + CountedPtr view() const { return _view; } + void set_path(const Path& path) { remove(); @@ -50,12 +63,14 @@ public: lab->set_padding(0, 0); lab->show(); add(*lab); + + if (_view && _view->patch()->path() != path) + _view.reset(); } - const Path& path() { return m_path; } - private: - Path m_path; + Path _path; + CountedPtr _view; }; } // namespace Ingenuity diff --git a/src/progs/ingenuity/BreadCrumbBox.cpp b/src/progs/ingenuity/BreadCrumbBox.cpp index aea1cdf0..8dc0b8a0 100644 --- a/src/progs/ingenuity/BreadCrumbBox.cpp +++ b/src/progs/ingenuity/BreadCrumbBox.cpp @@ -34,7 +34,7 @@ BreadCrumbBox::BreadCrumbBox() * children preserved. */ void -BreadCrumbBox::build(Path path) +BreadCrumbBox::build(Path path, CountedPtr view) { bool old_enable_signal = _enable_signal; _enable_signal = false; @@ -42,14 +42,39 @@ BreadCrumbBox::build(Path path) // Moving to a path we already contain, just switch the active button if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) { - for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - (*i)->set_active( ((*i)->path() == path) ); + for (std::list::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == path) { + (*i)->set_active(true); + (*i)->set_view(view); + } else { + (*i)->set_active(false); + } + } _active_path = path; _enable_signal = old_enable_signal; return; } + // Moving to a child of the full path, just append crumbs (preserve view cache) + if (_breadcrumbs.size() > 0 && (path.is_child_of(_full_path))) { + string postfix = path.substr(_full_path.length()); + while (postfix.length() > 0) { + const string name = postfix.substr(0, postfix.find("/")); + cerr << "NAME: " << name << endl; + _full_path = _full_path.base() + name; + BreadCrumb* but = create_crumb(_full_path, view); + pack_end(*but, false, false, 1); + _breadcrumbs.push_back(but); + if (postfix.find("/") == string::npos) + break; + else + postfix = postfix.substr(postfix.find("/")+1); + } + } + + // Getting here is bad unless absolutely necessary, since the PatchView cache is lost + // Otherwise rebuild from scratch _full_path = path; _active_path = path; @@ -60,18 +85,14 @@ BreadCrumbBox::build(Path path) _breadcrumbs.clear(); // Add root - BreadCrumb* but = manage(new BreadCrumb("/")); - but->signal_toggled().connect(sigc::bind(sigc::mem_fun( - this, &BreadCrumbBox::breadcrumb_clicked), but)); + BreadCrumb* but = create_crumb("/", view); pack_start(*but, false, false, 1); _breadcrumbs.push_front(but); but->set_active(but->path() == _active_path); // Add the others while (path != "/") { - BreadCrumb* but = manage(new BreadCrumb(path)); - but->signal_toggled().connect(sigc::bind(sigc::mem_fun( - this, &BreadCrumbBox::breadcrumb_clicked), but)); + BreadCrumb* but = create_crumb(path, view); pack_start(*but, false, false, 1); _breadcrumbs.push_front(but); but->set_active(but->path() == _active_path); @@ -84,6 +105,23 @@ BreadCrumbBox::build(Path path) } +/** Create a new crumb, assigning it a reference to @a view if their paths + * match, otherwise ignoring @a view. + */ +BreadCrumb* +BreadCrumbBox::create_crumb(const Path& path, + CountedPtr view) +{ + BreadCrumb* but = manage(new BreadCrumb(path, + (view && path == view->patch()->path()) ? view : CountedPtr())); + + but->signal_toggled().connect(sigc::bind(sigc::mem_fun( + this, &BreadCrumbBox::breadcrumb_clicked), but)); + + return but; +} + + void BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) { @@ -95,7 +133,7 @@ BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) // Tried to turn off the current active button, bad user! crumb->set_active(true); } else { - signal_patch_selected.emit(crumb->path()); + signal_patch_selected.emit(crumb->path(), crumb->view()); if (crumb->path() != _active_path) crumb->set_active(false); } diff --git a/src/progs/ingenuity/BreadCrumbBox.h b/src/progs/ingenuity/BreadCrumbBox.h index 35215e43..e38d8e49 100644 --- a/src/progs/ingenuity/BreadCrumbBox.h +++ b/src/progs/ingenuity/BreadCrumbBox.h @@ -22,10 +22,11 @@ #include #include #include "util/Path.h" +#include "util/CountedPtr.h" +#include "PatchView.h" namespace Ingenuity { -class PatchController; class BreadCrumb; @@ -38,11 +39,14 @@ class BreadCrumbBox : public Gtk::HBox public: BreadCrumbBox(); - void build(Path path); + void build(Path path, CountedPtr view); - sigc::signal signal_patch_selected; + sigc::signal > signal_patch_selected; private: + BreadCrumb* create_crumb(const Path& path, + CountedPtr view = CountedPtr()); + void breadcrumb_clicked(BreadCrumb* crumb); void object_removed(const Path& path); diff --git a/src/progs/ingenuity/ConfigWindow.cpp b/src/progs/ingenuity/ConfigWindow.cpp index 934dcc6b..a83bfbac 100644 --- a/src/progs/ingenuity/ConfigWindow.cpp +++ b/src/progs/ingenuity/ConfigWindow.cpp @@ -19,9 +19,7 @@ #include #include #include -#include "PatchController.h" #include "NodeModel.h" -#include "OmFlowCanvas.h" using std::cout; using std::cerr; using std::endl; diff --git a/src/progs/ingenuity/Configuration.cpp b/src/progs/ingenuity/Configuration.cpp index e383cf87..0c985750 100644 --- a/src/progs/ingenuity/Configuration.cpp +++ b/src/progs/ingenuity/Configuration.cpp @@ -22,9 +22,7 @@ #include #include "PortModel.h" #include "PluginModel.h" -#include "PatchController.h" #include "PatchModel.h" -#include "OmFlowCanvas.h" #include "Loader.h" #include "App.h" diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp index df95f3c3..64d611e2 100644 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ b/src/progs/ingenuity/ConnectWindow.cpp @@ -25,8 +25,6 @@ #include "OSCClientReceiver.h" #include "ThreadedSigClientInterface.h" #include "Store.h" -#include "ControllerFactory.h" -#include "PatchController.h" #include "PatchModel.h" #include "App.h" #include "WindowFactory.h" @@ -353,8 +351,7 @@ ConnectWindow::gtk_callback() if (App::instance().store()->num_objects() > 0) { CountedPtr root = PtrCast(App::instance().store()->object("/")); assert(root); - CountedPtr root_c = PtrCast(ControllerFactory::get_controller(root)); - App::instance().window_factory()->present(root_c); + App::instance().window_factory()->present_patch(root); ++stage; } } else if (stage == 8) { diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp index 45218bdf..06f49f86 100644 --- a/src/progs/ingenuity/ControlGroups.cpp +++ b/src/progs/ingenuity/ControlGroups.cpp @@ -53,13 +53,12 @@ ControlGroup::ControlGroup(ControlPanel* panel, CountedPtr pm, bool s void -ControlGroup::metadata_update(const string& key, const string& value) +ControlGroup::metadata_update(const string& key, const Atom& value) { - // FIXME: this isn't right - if (key == "user-min" || key == "min") - set_min(atof(value.c_str())); - else if (key == "user-max" || key == "max") - set_max(atof(value.c_str())); + if ( (key == "min") && value.type() == Atom::FLOAT) + set_min(value.get_float()); + else if ( (key == "max") && value.type() == Atom::FLOAT) + set_max(value.get_float()); } @@ -77,17 +76,20 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtris_integer() ? 0 : 4)), m_slider_box(false, 0), m_value_spinner(1.0, (pm->is_integer() ? 0 : 4)), - m_slider(pm->user_min(), pm->user_max(), (pm->is_integer() ? 1.0 : 0.0001)) + m_slider(0, 1, (pm->is_integer() ? 1.0 : 0.0001)) { m_slider.set_increments(1.0, 10.0); - // Compensate for crazy plugins - // FIXME - /* - if (m_port_model->user_max() <= m_port_model->user_min()) { - m_port_model->user_max(m_port_model->user_min() + 1.0); - m_slider.set_range(m_port_model->user_min(), m_port_model->user_max()); - }*/ + float min = 0.0f; + float max = 1.0f; + + const Atom& min_atom = pm->get_metadata("min"); + const Atom& max_atom = pm->get_metadata("max"); + if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) { + min = min_atom.get_float(); + max = max_atom.get_float(); + } + m_slider.property_draw_value() = false; set_name(pm->path().name()); @@ -103,12 +105,12 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtruser_min()); + m_min_spinner.set_value(min); m_min_spinner.set_increments(1.0, 10.0); m_min_spinner.set_digits(5); m_min_spinner.signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::min_changed)); m_max_spinner.set_range(-99999, 99999); - m_max_spinner.set_value(m_port_model->user_max()); + m_max_spinner.set_value(max); m_max_spinner.set_increments(1.0, 10.0); m_max_spinner.set_digits(5); m_max_spinner.signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::max_changed)); @@ -135,7 +137,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtruser_min(), m_port_model->user_max()); + m_slider.set_range(min, max); m_enable_signal = true; @@ -210,7 +212,7 @@ SliderControlGroup::min_changed() if (m_enable_signal) { char temp_buf[16]; snprintf(temp_buf, 16, "%f", min); - App::instance().engine()->set_metadata(m_port_model->path(), "user-min", temp_buf); + App::instance().engine()->set_metadata(m_port_model->path(), "min", temp_buf); } } @@ -231,7 +233,7 @@ SliderControlGroup::max_changed() if (m_enable_signal) { char temp_buf[16]; snprintf(temp_buf, 16, "%f", max); - App::instance().engine()->set_metadata(m_port_model->path(), "user-max", temp_buf); + App::instance().engine()->set_metadata(m_port_model->path(), "max", temp_buf); } } diff --git a/src/progs/ingenuity/ControlGroups.h b/src/progs/ingenuity/ControlGroups.h index a5b3d1f5..3193fa71 100644 --- a/src/progs/ingenuity/ControlGroups.h +++ b/src/progs/ingenuity/ControlGroups.h @@ -58,7 +58,7 @@ protected: virtual void set_min(float val) {} virtual void set_max(float val) {} - virtual void metadata_update(const string& key, const string& value); + virtual void metadata_update(const string& key, const Atom& value); ControlPanel* m_control_panel; CountedPtr m_port_model; diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp index 90d17c8a..94945e28 100644 --- a/src/progs/ingenuity/ControlPanel.cpp +++ b/src/progs/ingenuity/ControlPanel.cpp @@ -21,7 +21,6 @@ #include "NodeModel.h" #include "PortModel.h" #include "ControlGroups.h" -#include "PatchController.h" namespace Ingenuity { @@ -52,21 +51,18 @@ ControlPanel::~ControlPanel() void -ControlPanel::init(NodeController* node, size_t poly) +ControlPanel::init(CountedPtr node, size_t poly) { assert(node != NULL); assert(poly > 0); - const CountedPtr node_model(node->node_model()); - if (poly > 1) { m_voice_spinbutton->set_range(0, poly - 1); } else { remove(*m_voice_control_box); } - for (PortModelList::const_iterator i = node_model->ports().begin(); - i != node_model->ports().end(); ++i) { + for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) { add_port(*i); } diff --git a/src/progs/ingenuity/ControlPanel.h b/src/progs/ingenuity/ControlPanel.h index 025468d5..e1ace50a 100644 --- a/src/progs/ingenuity/ControlPanel.h +++ b/src/progs/ingenuity/ControlPanel.h @@ -27,7 +27,6 @@ #include // for pair<> #include "ControlGroups.h" #include "util/Path.h" -#include "PortController.h" using std::vector; using std::string; using std::pair; using std::cerr; using std::cout; using std::endl; @@ -40,9 +39,6 @@ using namespace Ingen::Client; namespace Ingenuity { -class NodeController; -class PortController; - /** A group of controls for a node (or patch). * @@ -55,7 +51,7 @@ public: ControlPanel(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); virtual ~ControlPanel(); - void init(NodeController* node, size_t poly); + void init(CountedPtr node, size_t poly); ControlGroup* find_port(const Path& path) const; diff --git a/src/progs/ingenuity/ControllerFactory.cpp b/src/progs/ingenuity/ControllerFactory.cpp deleted file mode 100644 index b95bef5b..00000000 --- a/src/progs/ingenuity/ControllerFactory.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 "ControllerFactory.h" -#include "NodeModel.h" -#include "PatchModel.h" -#include "PortModel.h" -#include "NodeController.h" -#include "PatchController.h" -#include "PortController.h" -#include "DSSIController.h" - -namespace Ingenuity { - - -CountedPtr -ControllerFactory::get_controller(CountedPtr model) -{ - CountedPtr patch_m = PtrCast(model); - if (patch_m && patch_m->controller()) { - assert(dynamic_cast(patch_m->controller().get())); - return PtrCast(patch_m->controller()); - } else if (patch_m) { - CountedPtr pc(new PatchController(patch_m)); - patch_m->set_controller(pc); - return pc; - } - - CountedPtr node_m = PtrCast(model); - if (node_m && node_m->controller()) { - assert(dynamic_cast(node_m->controller().get())); - return PtrCast(node_m->controller()); - } else if (node_m) { - if (node_m->plugin()->type() == PluginModel::DSSI) { - CountedPtr nc(new DSSIController(node_m)); - node_m->set_controller(nc); - return nc; - } else { - CountedPtr nc(new NodeController(node_m)); - node_m->set_controller(nc); - return nc; - } - } - - CountedPtr port_m = PtrCast(model); - if (port_m && port_m->controller()) { - assert(dynamic_cast(port_m->controller().get())); - return PtrCast(port_m->controller()); - } else if (port_m) { - CountedPtr pc(new PortController(port_m)); - port_m->set_controller(pc); - return pc; - } - - return CountedPtr(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/ControllerFactory.h b/src/progs/ingenuity/ControllerFactory.h deleted file mode 100644 index 7f48c262..00000000 --- a/src/progs/ingenuity/ControllerFactory.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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 - */ - -#ifndef CONTROLLER_FACTORY_H -#define CONTROLLER_FACTORY_H - -#include "util/CountedPtr.h" -#include "GtkObjectController.h" - -namespace Ingenuity { - -class ControllerFactory { -public: - static CountedPtr get_controller(CountedPtr model); -}; - -} - -#endif // CONTROLLER_FACTORY_H diff --git a/src/progs/ingenuity/DSSIController.cpp b/src/progs/ingenuity/DSSIController.cpp index 6bc75c70..4d5bb2f7 100644 --- a/src/progs/ingenuity/DSSIController.cpp +++ b/src/progs/ingenuity/DSSIController.cpp @@ -29,9 +29,9 @@ namespace Ingenuity { DSSIController::DSSIController(CountedPtr model) -: NodeController(model), - m_banks_dirty(true) +: m_banks_dirty(true) { +#if 0 assert(model->plugin()->type() == PluginModel::DSSI); Gtk::Menu::MenuList& items = m_menu.items(); items[0].property_sensitive() = true; // "Show Control Window" item @@ -43,21 +43,24 @@ DSSIController::DSSIController(CountedPtr model) items.push_front(Gtk::Menu_Helpers::MenuElem("Show Plugin GUI", sigc::mem_fun(this, &DSSIController::show_gui))); +#endif } void DSSIController::program_add(int bank, int program, const string& name) { - node_model()->add_program(bank, program, name); - m_banks_dirty = true; + cerr << "FIXME: DSSI add program\n"; + //node_model()->add_program(bank, program, name); + //m_banks_dirty = true; } void DSSIController::program_remove(int bank, int program) { - node_model()->remove_program(bank, program); - m_banks_dirty = true; + cerr << "FIXME: DSSI add program\n"; + //node_model()->remove_program(bank, program); + //m_banks_dirty = true; } /** Trivial wrapper of attempt_to_show_gui for libsigc @@ -120,22 +123,6 @@ DSSIController::send_program_change(int bank, int program) } -void -DSSIController::create_module(OmFlowCanvas* canvas) -{ - //cerr << "Creating DSSI module " << m_model->path() << endl; - - assert(canvas != NULL); - assert(m_module == NULL); - - m_module = new DSSIModule(canvas, this); - create_all_ports(); - - m_module->move_to(node_model()->x(), node_model()->y()); -} - - - /** Attempt to show the DSSI GUI for this plugin. * * Returns whether or not GUI was successfully loaded/shown. @@ -274,9 +261,11 @@ DSSIController::attempt_to_show_gui() void DSSIController::show_menu(GdkEventButton* event) { +#if 0 if (m_banks_dirty) update_program_menu(); NodeController::show_menu(event); +#endif } diff --git a/src/progs/ingenuity/DSSIController.h b/src/progs/ingenuity/DSSIController.h index 0ad26e76..3eaba91a 100644 --- a/src/progs/ingenuity/DSSIController.h +++ b/src/progs/ingenuity/DSSIController.h @@ -20,7 +20,6 @@ #include #include #include "util/Path.h" -#include "NodeController.h" using std::string; using namespace Ingen::Client; @@ -33,19 +32,17 @@ namespace Ingen { namespace Client { namespace Ingenuity { -class Controller; -class OmModule; class NodeControlWindow; class NodePropertiesWindow; -class PortController; -class OmFlowCanvas; -class DSSIModule; /* Controller for a DSSI node. + * + * FIXME: legacy cruft. move this code to the appropriate places and nuke + * this class. * * \ingroup Ingenuity */ -class DSSIController : public NodeController +class DSSIController { public: DSSIController(CountedPtr model); @@ -59,8 +56,6 @@ public: void send_program_change(int bank, int program); - void create_module(OmFlowCanvas* canvas); - void show_menu(GdkEventButton* event); private: diff --git a/src/progs/ingenuity/DSSIModule.cpp b/src/progs/ingenuity/DSSIModule.cpp index 3d91e69b..5d235be4 100644 --- a/src/progs/ingenuity/DSSIModule.cpp +++ b/src/progs/ingenuity/DSSIModule.cpp @@ -20,8 +20,8 @@ namespace Ingenuity { -DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node) -: OmModule(canvas, static_cast(node)) +DSSIModule::DSSIModule(OmFlowCanvas* canvas, CountedPtr node) +: OmModule(canvas, node) { } @@ -29,9 +29,11 @@ DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node) void DSSIModule::on_double_click(GdkEventButton* ev) { + /* DSSIController* dc = dynamic_cast(m_node); if (!dc || ! dc->attempt_to_show_gui()) show_control_window(); + */ } diff --git a/src/progs/ingenuity/DSSIModule.h b/src/progs/ingenuity/DSSIModule.h index 7a1b0035..6cffb891 100644 --- a/src/progs/ingenuity/DSSIModule.h +++ b/src/progs/ingenuity/DSSIModule.h @@ -30,7 +30,7 @@ class DSSIController; class DSSIModule : public OmModule { public: - DSSIModule(OmFlowCanvas* canvas, DSSIController* node); + DSSIModule(OmFlowCanvas* canvas, CountedPtr node); virtual ~DSSIModule() {} void on_double_click(GdkEventButton* ev); diff --git a/src/progs/ingenuity/GtkObjectController.cpp b/src/progs/ingenuity/GtkObjectController.cpp deleted file mode 100644 index ccaa3ca5..00000000 --- a/src/progs/ingenuity/GtkObjectController.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 "GtkObjectController.h" - -namespace Ingenuity { - - -GtkObjectController::GtkObjectController(CountedPtr model) -: m_model(model) -{ - assert(m_model); - model->metadata_update_sig.connect(sigc::mem_fun(this, &GtkObjectController::metadata_update)); -} - -GtkObjectController::~GtkObjectController() -{ -} - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/GtkObjectController.h b/src/progs/ingenuity/GtkObjectController.h deleted file mode 100644 index 6df13d02..00000000 --- a/src/progs/ingenuity/GtkObjectController.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 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 - */ - -#ifndef GTKOBJECTCONTROLLER_H -#define GTKOBJECTCONTROLLER_H - -#include -#include - -#include "ObjectModel.h" -#include "ObjectController.h" -#include "util/CountedPtr.h" - -using std::string; - -using namespace Ingen::Client; - -namespace Ingenuity { - -class Controller; - - -/** Controller for an Om object. - * - * Management of the model and view are this object's responsibility. - * The view may not be created (ie in the case of patches which have never - * been shown and all their children). - * - * \ingroup Ingenuity - */ -class GtkObjectController : public ObjectController -{ -public: - GtkObjectController(CountedPtr model); - virtual ~GtkObjectController(); - - /** Destroy object. - * - * Object must be safe to delete immediately following the return of - * this call. - */ - virtual void destroy() = 0; - -/* - virtual void add_to_store() = 0; - virtual void remove_from_store() = 0; -*/ - - /** Derived classes should override this to handle special metadata - * keys, then call this to set the model's metadata key. - */ - virtual void metadata_update(const string& key, const string& value) - { assert(m_model->get_metadata(key) != ""); } - - /** Rename object */ - virtual void set_path(const Path& new_path) - { m_model->set_path(new_path); } - - const Path& path() const { return m_model->path(); } - - CountedPtr model() const { return m_model; } - -protected: - CountedPtr m_model; ///< Model for this object -}; - - -} // namespace Ingenuity - -#endif // GTKOBJECTCONTROLLER_H diff --git a/src/progs/ingenuity/LashController.cpp b/src/progs/ingenuity/LashController.cpp index e5807da7..0fed3cf3 100644 --- a/src/progs/ingenuity/LashController.cpp +++ b/src/progs/ingenuity/LashController.cpp @@ -22,7 +22,6 @@ #include #include #include "App.h" -#include "PatchController.h" #include "PatchModel.h" using std::cerr; using std::cout; using std::endl; diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp index dcc08fff..5e740aac 100644 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ b/src/progs/ingenuity/LoadPatchWindow.cpp @@ -19,7 +19,6 @@ #include #include "App.h" #include "Configuration.h" -#include "PatchController.h" #include "PatchModel.h" #include "ModelEngineInterface.h" #include "Loader.h" @@ -60,14 +59,23 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr patch, MetadataMap data) +{ + set_patch(patch); + m_initial_data = data; + Gtk::Window::present(); +} + + /** Sets the patch controller for this window and initializes everything. * * This function MUST be called before using the window in any way! */ void -LoadPatchWindow::set_patch(CountedPtr pc) +LoadPatchWindow::set_patch(CountedPtr patch) { - m_patch_controller = pc; + m_patch = patch; } @@ -108,12 +116,13 @@ LoadPatchWindow::ok_clicked() poly = m_poly_spinbutton->get_value_as_int(); if (m_replace) - App::instance().engine()->clear_patch(m_patch_controller->model()->path()); + App::instance().engine()->clear_patch(m_patch->path()); - CountedPtr pm(new PatchModel(m_patch_controller->model()->path(), poly)); + CountedPtr pm(new PatchModel(m_patch->path(), poly)); pm->filename(get_filename()); - pm->set_metadata("filename", get_filename()); - pm->set_parent(m_patch_controller->patch_model()->parent()); + pm->set_metadata("filename", Atom(get_filename().c_str())); + // FIXME: necessary? + //pm->set_parent(m_patch->parent()); //App::instance().engine()->push_added_patch(pm); App::instance().loader()->load_patch(pm, true, true); diff --git a/src/progs/ingenuity/LoadPatchWindow.h b/src/progs/ingenuity/LoadPatchWindow.h index e22b1c1a..2c6035c8 100644 --- a/src/progs/ingenuity/LoadPatchWindow.h +++ b/src/progs/ingenuity/LoadPatchWindow.h @@ -22,12 +22,12 @@ #include #include #include "util/CountedPtr.h" -#include "PatchController.h" +#include "PatchModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; namespace Ingenuity { -class PatchController; - /** 'Load Patch' window. * @@ -44,11 +44,13 @@ class LoadPatchWindow : public Gtk::FileChooserDialog public: LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - void set_patch(CountedPtr pc); + void set_patch(CountedPtr patch); void set_replace() { m_replace = true; } void set_merge() { m_replace = false; } + void present(CountedPtr patch, MetadataMap data); + protected: void on_show(); @@ -58,8 +60,10 @@ private: void ok_clicked(); void cancel_clicked(); - CountedPtr m_patch_controller; - bool m_replace; + MetadataMap m_initial_data; + + CountedPtr m_patch; + bool m_replace; Gtk::RadioButton* m_poly_from_current_radio; Gtk::RadioButton* m_poly_from_file_radio; diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp index 2b59efef..9321b12a 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -19,11 +19,9 @@ #include #include #include -#include "PatchController.h" #include "NodeModel.h" #include "App.h" #include "PatchWindow.h" -#include "OmFlowCanvas.h" #include "PatchModel.h" #include "Store.h" #include "ModelEngineInterface.h" @@ -107,6 +105,15 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr patch, MetadataMap data) +{ + set_patch(patch); + m_initial_data = data; + Gtk::Window::present(); +} + + /** Called every time the user types into the name input box. * Used to display warning messages, and enable/disable the OK button. */ @@ -117,7 +124,7 @@ LoadPluginWindow::name_changed() if (!Path::is_valid_name(name)) { //m_message_label->set_text("Name contains invalid characters."); m_add_button->property_sensitive() = false; - } else if (m_patch_controller->patch_model()->get_node(name)) { + } else if (m_patch->get_node(name)) { //m_message_label->set_text("An object already exists with that name."); m_add_button->property_sensitive() = false; } else if (name.length() == 0) { @@ -135,11 +142,11 @@ LoadPluginWindow::name_changed() * This function MUST be called before using the window in any way! */ void -LoadPluginWindow::set_patch(CountedPtr pc) +LoadPluginWindow::set_patch(CountedPtr patch) { - m_patch_controller = pc; + m_patch = patch; - if (pc->patch_model()->poly() <= 1) + if (patch->poly() <= 1) m_polyphonic_checkbutton->property_sensitive() = false; else m_polyphonic_checkbutton->property_sensitive() = true; @@ -161,7 +168,7 @@ LoadPluginWindow::on_show() set_plugin_list(App::instance().store()->plugins()); // Center on patch window - int m_w, m_h; + /*int m_w, m_h; get_size(m_w, m_h); int parent_x, parent_y, parent_w, parent_h; @@ -169,7 +176,7 @@ LoadPluginWindow::on_show() m_patch_controller->window()->get_size(parent_w, parent_h); move(parent_x + parent_w/2 - m_w/2, parent_y + parent_h/2 - m_h/2); - + */ m_has_shown = true; } Gtk::Window::on_show(); @@ -275,7 +282,7 @@ LoadPluginWindow::generate_module_name(int offset) name += "_"; name += num_buf; } - if (!m_patch_controller->patch_model()->get_node(name)) + if (!m_patch->get_node(name)) break; else name = ""; @@ -306,17 +313,10 @@ LoadPluginWindow::add_clicked() dialog.run(); } else { - const string path = m_patch_controller->model()->path().base() + name; - NodeModel* nm = new NodeModel(plugin, path); - nm->polyphonic(polyphonic); + const string path = m_patch->path().base() + name; + NodeModel* nm = new NodeModel(plugin, path, polyphonic); + nm->add_metadata(m_initial_data); - if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_view()->canvas()->get_new_module_location( - m_new_module_x, m_new_module_y); - } - nm->x(m_new_module_x); - nm->y(m_new_module_y); - App::instance().engine()->create_node_from_model(nm); ++m_plugin_name_offset; m_node_name_entry->set_text(generate_module_name(m_plugin_name_offset)); diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h index 1654b777..0af40d05 100644 --- a/src/progs/ingenuity/LoadPluginWindow.h +++ b/src/progs/ingenuity/LoadPluginWindow.h @@ -24,12 +24,13 @@ #include #include #include "util/CountedPtr.h" - +#include "PatchModel.h" using Ingen::Client::PluginModel; +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; namespace Ingenuity { -class PatchController; // Gtkmm _really_ needs to add some helper to abstract away this stupid nonsense @@ -87,15 +88,14 @@ class LoadPluginWindow : public Gtk::Window public: LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - void set_patch(CountedPtr pc); + void set_patch(CountedPtr patch); void set_plugin_list(const std::map >& m); - void set_next_module_location(double x, double y) - { m_new_module_x = x; m_new_module_y = y; } - void add_plugin(CountedPtr plugin); bool has_shown() const { return m_has_shown; } + void present(CountedPtr patch, MetadataMap data); + protected: void on_show(); void on_hide(); @@ -113,7 +113,10 @@ private: void plugin_selection_changed(); string generate_module_name(int offset = 0); - CountedPtr m_patch_controller; + MetadataMap m_initial_data; + + CountedPtr m_patch; + bool m_has_shown; // plugin list only populated on show to speed patch window creation Glib::RefPtr m_plugins_liststore; diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp index 486c92b4..cb7a7ef6 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp @@ -19,9 +19,7 @@ #include #include #include "App.h" -#include "PatchController.h" #include "PatchView.h" -#include "OmFlowCanvas.h" #include "NodeModel.h" #include "PatchModel.h" #include "Configuration.h" @@ -68,17 +66,26 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP } +void +LoadSubpatchWindow::present(CountedPtr patch, MetadataMap data) +{ + set_patch(patch); + m_initial_data = data; + Gtk::Window::present(); +} + + /** Sets the patch controller for this window and initializes everything. * * This function MUST be called before using the window in any way! */ void -LoadSubpatchWindow::set_patch(CountedPtr pc) +LoadSubpatchWindow::set_patch(CountedPtr patch) { - m_patch_controller = pc; + m_patch = patch; char temp_buf[4]; - snprintf(temp_buf, 4, "%zd", pc->patch_model()->poly()); + snprintf(temp_buf, 4, "%zd", patch->poly()); Glib::ustring txt = "Same as parent ("; txt.append(temp_buf).append(")"); m_poly_from_parent_radio->set_label(txt); @@ -129,8 +136,7 @@ LoadSubpatchWindow::enable_poly_spinner() void LoadSubpatchWindow::ok_clicked() { - assert(m_patch_controller); - assert(m_patch_controller->model()); + assert(m_patch); const string filename = get_filename(); @@ -144,25 +150,22 @@ LoadSubpatchWindow::ok_clicked() if (m_poly_from_user_radio->get_active()) poly = m_poly_spinbutton->get_value_as_int(); else if (m_poly_from_parent_radio->get_active()) - poly = m_patch_controller->patch_model()->poly(); + poly = m_patch->poly(); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_view()->canvas()->get_new_module_location( - m_new_module_x, m_new_module_y); + throw; // FIXME + //m_patch_controller->get_view()->canvas()->get_new_module_location( + // m_new_module_x, m_new_module_y); } - CountedPtr pm(new PatchModel(m_patch_controller->model()->path().base() + name, poly)); + CountedPtr pm(new PatchModel(m_patch->path().base() + name, poly)); pm->filename(filename); - pm->set_parent(m_patch_controller->model()); - pm->x(m_new_module_x); - pm->y(m_new_module_y); - //if (name == "") - // pm->set_path(""); - char temp_buf[16]; - snprintf(temp_buf, 16, "%16f", m_new_module_x); - pm->set_metadata("module-x", temp_buf); - snprintf(temp_buf, 16, "%16f", m_new_module_y); - pm->set_metadata("module-y", temp_buf); + // FIXME: necessary? + //pm->set_parent(m_patch); + + pm->set_metadata("module-x", Atom((float)m_new_module_x)); + pm->set_metadata("module-y", Atom((float)m_new_module_y)); + App::instance().loader()->load_patch(pm, true, false); App::instance().configuration()->set_patch_folder(pm->filename().substr(0, pm->filename().find_last_of("/"))); diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h index e33880e8..ae65a9f4 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.h +++ b/src/progs/ingenuity/LoadSubpatchWindow.h @@ -14,7 +14,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef LOADSUBPATCHWINDOW_H #define LOADSUBPATCHWINDOW_H @@ -22,13 +21,12 @@ #include #include #include "util/CountedPtr.h" -#include "PatchController.h" - +#include "PatchModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; namespace Ingenuity { -class PatchController; - /** 'Add Subpatch' window. * @@ -41,10 +39,9 @@ class LoadSubpatchWindow : public Gtk::FileChooserDialog public: LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - void set_patch(CountedPtr pc); + void set_patch(CountedPtr patch); - void set_next_module_location(double x, double y) - { m_new_module_x = x; m_new_module_y = y; } + void present(CountedPtr patch, MetadataMap data); protected: void on_show(); @@ -58,7 +55,9 @@ private: void ok_clicked(); void cancel_clicked(); - CountedPtr m_patch_controller; + MetadataMap m_initial_data; + + CountedPtr m_patch; double m_new_module_x; double m_new_module_y; diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp index 0ca6f966..a0f099c2 100644 --- a/src/progs/ingenuity/Loader.cpp +++ b/src/progs/ingenuity/Loader.cpp @@ -20,7 +20,6 @@ #include #include "PatchLibrarian.h" #include "PatchModel.h" -#include "PatchController.h" using std::cout; using std::endl; namespace Ingenuity { diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am index 5c4f5eed..aaa832f3 100644 --- a/src/progs/ingenuity/Makefile.am +++ b/src/progs/ingenuity/Makefile.am @@ -22,6 +22,10 @@ ingenuity_SOURCES = \ cmdline.h \ cmdline.c \ main.cpp \ + NodeMenu.h \ + NodeMenu.cpp \ + OmFlowCanvas.h \ + OmFlowCanvas.cpp \ BreadCrumb.h \ BreadCrumbBox.h \ BreadCrumbBox.cpp \ @@ -33,18 +37,6 @@ ingenuity_SOURCES = \ Configuration.cpp \ GladeFactory.h \ GladeFactory.cpp \ - GtkObjectController.h \ - GtkObjectController.cpp \ - PatchController.h \ - PatchController.cpp \ - NodeController.h \ - NodeController.cpp \ - PortController.h \ - PortController.cpp \ - DSSIController.h \ - DSSIController.cpp \ - ControllerFactory.h \ - ControllerFactory.cpp \ LoadPluginWindow.h \ LoadPluginWindow.cpp \ LoadPatchWindow.h \ @@ -65,8 +57,6 @@ ingenuity_SOURCES = \ PatchWindow.cpp \ WindowFactory.h \ WindowFactory.cpp \ - OmFlowCanvas.h \ - OmFlowCanvas.cpp \ ../../common/types.h \ ../../common/Path.h \ OmModule.h \ diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp index 7f434445..8d673622 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ b/src/progs/ingenuity/NewSubpatchWindow.cpp @@ -17,11 +17,9 @@ #include "App.h" #include "ModelEngineInterface.h" #include "NewSubpatchWindow.h" -#include "PatchController.h" #include "NodeModel.h" #include "PatchModel.h" #include "PatchView.h" -#include "OmFlowCanvas.h" namespace Ingenuity { @@ -44,15 +42,22 @@ NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr m_ok_button->property_sensitive() = false; } +void +NewSubpatchWindow::present(CountedPtr patch, MetadataMap data) +{ + set_patch(patch); + m_initial_data = data; + Gtk::Window::present(); +} /** Sets the patch controller for this window and initializes everything. * * This function MUST be called before using the window in any way! */ void -NewSubpatchWindow::set_patch(CountedPtr pc) +NewSubpatchWindow::set_patch(CountedPtr patch) { - m_patch_controller = pc; + m_patch = patch; } @@ -66,7 +71,7 @@ NewSubpatchWindow::name_changed() if (!Path::is_valid_name(name)) { m_message_label->set_text("Name contains invalid characters."); m_ok_button->property_sensitive() = false; - } else if (m_patch_controller->patch_model()->get_node(name)) { + } else if (m_patch->get_node(name)) { m_message_label->set_text("An object already exists with that name."); m_ok_button->property_sensitive() = false; } else if (name.length() == 0) { @@ -83,22 +88,19 @@ void NewSubpatchWindow::ok_clicked() { PatchModel* pm = new PatchModel( - m_patch_controller->model()->path().base() + m_name_entry->get_text(), + m_patch->path().base() + m_name_entry->get_text(), m_poly_spinbutton->get_value_as_int()); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->get_view()->canvas()->get_new_module_location( - m_new_module_x, m_new_module_y); + throw; // FIXME + //m_patch_controller->get_view()->canvas()->get_new_module_location( + // m_new_module_x, m_new_module_y); } - pm->set_parent(m_patch_controller->patch_model()); - pm->x(m_new_module_x); - pm->y(m_new_module_y); - char temp_buf[16]; - snprintf(temp_buf, 16, "%16f", m_new_module_x); - pm->set_metadata("module-x", temp_buf); - snprintf(temp_buf, 16, "%16f", m_new_module_y); - pm->set_metadata("module-y", temp_buf); + // FIXME: necessary? + //pm->set_parent(m_patch); + pm->set_metadata("module-x", (float)m_new_module_x); + pm->set_metadata("module-y", (float)m_new_module_y); App::instance().engine()->create_patch_from_model(pm); hide(); } diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h index 32560dde..420b82c4 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.h +++ b/src/progs/ingenuity/NewSubpatchWindow.h @@ -21,13 +21,12 @@ #include #include #include "util/CountedPtr.h" -#include "PatchController.h" - +#include "PatchModel.h" +using Ingen::Client::PatchModel; +using Ingen::Client::MetadataMap; namespace Ingenuity { -class PatchController; - /** 'New Subpatch' window. * @@ -40,17 +39,17 @@ class NewSubpatchWindow : public Gtk::Window public: NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml); - void set_patch(CountedPtr pc); + void set_patch(CountedPtr patch); + + void present(CountedPtr patch, MetadataMap data); - void set_next_module_location(double x, double y) - { m_new_module_x = x; m_new_module_y = y; } - private: void name_changed(); void ok_clicked(); void cancel_clicked(); - CountedPtr m_patch_controller; + MetadataMap m_initial_data; + CountedPtr m_patch; double m_new_module_x; double m_new_module_y; diff --git a/src/progs/ingenuity/NodeControlWindow.cpp b/src/progs/ingenuity/NodeControlWindow.cpp index 3af8f834..bc362eb5 100644 --- a/src/progs/ingenuity/NodeControlWindow.cpp +++ b/src/progs/ingenuity/NodeControlWindow.cpp @@ -16,7 +16,7 @@ #include "NodeControlWindow.h" #include "GladeFactory.h" -#include "NodeController.h" +#include "NodeModel.h" #include "ControlGroups.h" #include "ControlPanel.h" #include "PatchWindow.h" @@ -29,7 +29,7 @@ namespace Ingenuity { /** Create a node control window and load a new ControlPanel for it. */ -NodeControlWindow::NodeControlWindow(NodeController* node, size_t poly) +NodeControlWindow::NodeControlWindow(CountedPtr node, size_t poly) : m_node(node), m_position_stored(false), m_x(0), m_y(0) @@ -59,11 +59,11 @@ NodeControlWindow::NodeControlWindow(NodeController* node, size_t poly) /** Create a node control window and with an existing ControlPanel. */ -NodeControlWindow::NodeControlWindow(NodeController* node, ControlPanel* panel) +NodeControlWindow::NodeControlWindow(CountedPtr node, ControlPanel* panel) : m_node(node), m_control_panel(panel) { - assert(m_node != NULL); + assert(m_node); property_resizable() = true; set_border_width(5); diff --git a/src/progs/ingenuity/NodeControlWindow.h b/src/progs/ingenuity/NodeControlWindow.h index b30223d7..91ccbc49 100644 --- a/src/progs/ingenuity/NodeControlWindow.h +++ b/src/progs/ingenuity/NodeControlWindow.h @@ -14,7 +14,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef NODECONTROLWINDOW_H #define NODECONTROLWINDOW_H @@ -23,12 +22,17 @@ #include #include #include +#include "util/CountedPtr.h" using std::string; using std::vector; +namespace Ingen { namespace Client { + class NodeModel; +} } +using Ingen::Client::NodeModel; + namespace Ingenuity { class ControlGroup; -class NodeController; class ControlPanel; @@ -39,10 +43,12 @@ class ControlPanel; class NodeControlWindow : public Gtk::Window { public: - NodeControlWindow(NodeController* node, size_t poly); - NodeControlWindow(NodeController* node, ControlPanel* panel); + NodeControlWindow(CountedPtr node, size_t poly); + NodeControlWindow(CountedPtr node, ControlPanel* panel); virtual ~NodeControlWindow(); + CountedPtr node() { return m_node; } + ControlPanel* control_panel() const { return m_control_panel; } void resize(); @@ -52,9 +58,9 @@ protected: void on_hide(); private: - NodeController* m_node; - ControlPanel* m_control_panel; - bool m_callback_enabled; + CountedPtr m_node; + ControlPanel* m_control_panel; + bool m_callback_enabled; bool m_position_stored; int m_x; diff --git a/src/progs/ingenuity/NodeController.cpp b/src/progs/ingenuity/NodeController.cpp deleted file mode 100644 index 950f70c9..00000000 --- a/src/progs/ingenuity/NodeController.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* 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 "NodeController.h" -#include -#include -#include "App.h" -#include "OmModule.h" -#include "NodeModel.h" -#include "PortModel.h" -#include "PortController.h" -#include "GtkObjectController.h" -#include "NodeControlWindow.h" -#include "OmModule.h" -#include "ControllerFactory.h" -#include "PatchController.h" -#include "OmFlowCanvas.h" -#include "RenameWindow.h" -#include "GladeFactory.h" -#include "PatchWindow.h" -#include "PatchModel.h" -#include "NodePropertiesWindow.h" -#include "Store.h" -#include "ModelEngineInterface.h" -using std::cerr; using std::endl; - -namespace Ingenuity { - - -NodeController::NodeController(CountedPtr model) -: GtkObjectController(model), - m_controls_menuitem(NULL), - m_module(NULL), - m_control_window(NULL), - m_properties_window(NULL), - m_bridge_port(NULL) -{ - // Create port controllers - for (PortModelList::const_iterator i = node_model()->ports().begin(); - i != node_model()->ports().end(); ++i) { - assert(!(*i)->controller()); - assert((*i)->parent()); - assert((*i)->parent().get() == node_model().get()); - CountedPtr pc = PtrCast(ControllerFactory::get_controller(*i)); - assert((*i)->controller() == pc); // PortController() does this - } - - // Build menu - - Gtk::Menu::MenuList& items = m_menu.items(); - - Gtk::Menu_Helpers::MenuElem controls_elem - = Gtk::Menu_Helpers::MenuElem("Controls", - sigc::mem_fun(this, &NodeController::show_control_window)); - m_controls_menuitem = controls_elem.get_child(); - items.push_back(controls_elem); - items.push_back(Gtk::Menu_Helpers::MenuElem("Properties", - sigc::mem_fun(this, &NodeController::show_properties_window))); - items.push_back(Gtk::Menu_Helpers::SeparatorElem()); - items.push_back(Gtk::Menu_Helpers::MenuElem("Rename...", - sigc::mem_fun(this, &NodeController::show_rename_window))); - items.push_back(Gtk::Menu_Helpers::MenuElem("Clone", - sigc::mem_fun(this, &NodeController::on_menu_clone))); - items.push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All", - sigc::mem_fun(this, &NodeController::on_menu_disconnect_all))); - items.push_back(Gtk::Menu_Helpers::MenuElem("Destroy", - sigc::mem_fun(this, &NodeController::on_menu_destroy))); - - m_controls_menuitem->property_sensitive() = false; - - if (node_model()->plugin() && node_model()->plugin()->type() == PluginModel::Internal - && node_model()->plugin()->plug_label() == "midi_control_in") { - Gtk::Menu::MenuList& items = m_menu.items(); - items.push_back(Gtk::Menu_Helpers::MenuElem("Learn", - sigc::mem_fun(this, &NodeController::on_menu_learn))); - } - - model->new_port_sig.connect(sigc::mem_fun(this, &NodeController::add_port)); - model->destroyed_sig.connect(sigc::mem_fun(this, &NodeController::destroy)); -} - - -NodeController::~NodeController() -{ - cerr << "~NodeController()\n"; - destroy_module(); -} - - -void -NodeController::destroy() -{ - cerr << "FIXME: NODE DESTROYED\n"; - destroy_module(); - CountedPtr model = m_model; - m_model->controller().reset(); - m_model.reset(); -} - - -void -NodeController::create_module(OmFlowCanvas* canvas) -{ - if (!m_module || m_module->canvas() != canvas) { - delete m_module; - //cerr << "Creating node module " << m_model->path() << endl; - - // If this is a DSSI plugin, DSSIController should be doing this - /*assert(node_model()->plugin()); - assert(node_model()->plugin()->type() != PluginModel::DSSI); - assert(canvas != NULL); - assert(m_module == NULL);*/ - - assert(canvas); - assert(node_model()); - m_module = new OmModule(canvas, this); - create_all_ports(); - } - - m_module->move_to(node_model()->x(), node_model()->y()); -} - - -void -NodeController::destroy_module() -{ - delete m_module; - m_module = NULL; -} - - -void -NodeController::set_path(const Path& new_path) -{ - cerr << "FIXME: rename\n"; - /* - remove_from_store(); - - // Rename ports - for (list::const_iterator i = node_model()->ports().begin(); - i != node_model()->ports().end(); ++i) { - GtkObjectController* const pc = (GtkObjectController*)((*i)->controller()); - assert(pc != NULL); - pc->set_path(m_model->path().base() + pc->model()->name()); - } - - // Handle bridge port, if this node represents one - if (m_bridge_port != NULL) - m_bridge_port->set_path(new_path); - - if (m_module != NULL) - m_module->canvas()->rename_module(node_model()->path().name(), new_path.name()); - - GtkObjectController::set_path(new_path); - - add_to_store(); - */ -} - -#if 0 -void -NodeController::destroy() -{ - PatchController* pc = ((PatchController*)m_model->parent()->controller()); - assert(pc != NULL); - - //remove_from_store(); - //pc->remove_node(m_model->path().name()); - cerr << "FIXME: remove node\n"; - - if (m_bridge_port != NULL) - m_bridge_port->destroy(); - m_bridge_port = NULL; - - //if (m_module != NULL) - // delete m_module; -} -#endif - -void -NodeController::metadata_update(const string& key, const string& value) -{ - //cout << "[NodeController] Metadata update: " << m_model->path() << endl; - - if (m_module != NULL) { - if (key == "module-x") { - float x = atof(value.c_str()); - //if (x > 0 && x < m_canvas->width()) - m_module->move_to(x, m_module->property_y().get_value()); - } else if (key == "module-y") { - float y = atof(value.c_str()); - //if (y > 0 && y < m_canvas->height()) - m_module->move_to(m_module->property_x().get_value(), y); - } - } - - //if (m_bridge_port != NULL) - // m_bridge_port->metadata_update(key, value); - - GtkObjectController::metadata_update(key, value); -} - - -void -NodeController::add_port(CountedPtr pm) -{ - assert(pm->parent().get() == node_model().get()); - assert(pm->parent() == node_model()); - assert(node_model()->get_port(pm->path().name()) == pm); - - //cout << "[NodeController] Adding port " << pm->path() << endl; - - CountedPtr pc = PtrCast(ControllerFactory::get_controller(pm)); - assert(pm->controller() == pc); - - if (m_module != NULL) { - pc->create_port(m_module); - m_module->resize(); - - // Enable "Controls" menu item on module - if (has_control_inputs()) - enable_controls_menuitem(); - } -} - - -void -NodeController::show_control_window() -{ - size_t poly = 1; - if (node_model()->polyphonic()) - poly = ((PatchModel*)node_model()->parent().get())->poly(); - - if (!m_control_window) - m_control_window = new NodeControlWindow(this, poly); - - m_control_window->present(); -} - - -void -NodeController::on_menu_destroy() -{ - App::instance().engine()->destroy(node_model()->path()); -} - - -void -NodeController::show_rename_window() -{ - assert(node_model()->parent()); - - // FIXME: will this be magically cleaned up? - RenameWindow* win = NULL; - Glib::RefPtr xml = GladeFactory::new_glade_reference("rename_win"); - xml->get_widget_derived("rename_win", win); - - CountedPtr parent = PtrCast(node_model()->parent()->controller()); - assert(parent); - - if (parent->window()) - win->set_transient_for(*parent->window()); - - win->set_object(this); - win->show(); -} - -void -NodeController::on_menu_clone() -{ - cerr << "FIXME: clone broken\n"; - /* - assert(node_model()); - //assert(m_parent != NULL); - //assert(m_parent->model() != NULL); - - string clone_name = node_model()->name(); - int i = 2; // postfix number (ie oldname_2) - - // Check if name already has a number postfix - if (clone_name.find_last_of("_") != string::npos) { - string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1); - clone_name = clone_name.substr(0, clone_name.find_last_of("_")); - if (sscanf(name_postfix.c_str(), "%d", &i)) - ++i; - } - - char clone_postfix[4]; - for ( ; i < 100; ++i) { - snprintf(clone_postfix, 4, "_%d", i); - if (node_model()->parent_patch()->get_node(clone_name + clone_postfix) == NULL) - break; - } - - clone_name = clone_name + clone_postfix; - - const string path = node_model()->parent_patch()->base() + clone_name; - NodeModel* nm = new NodeModel(node_model()->plugin(), path); - nm->polyphonic(node_model()->polyphonic()); - nm->x(node_model()->x() + 20); - nm->y(node_model()->y() + 20); - App::instance().engine()->create_node_from_model(nm); - */ -} - - -void -NodeController::on_menu_learn() -{ - App::instance().engine()->midi_learn(node_model()->path()); -} - -void -NodeController::on_menu_disconnect_all() -{ - App::instance().engine()->disconnect_all(node_model()->path()); -} - - -void -NodeController::show_properties_window() -{ - CountedPtr parent = PtrCast(node_model()->parent()->controller()); - assert(parent); - - if (m_properties_window) { - Glib::RefPtr xml = GladeFactory::new_glade_reference("node_properties_win"); - xml->get_widget_derived("node_properties_win", m_properties_window); - } - assert(m_properties_window); - assert(parent); - m_properties_window->set_node(node_model()); - if (parent->window()) - m_properties_window->set_transient_for(*parent->window()); - m_properties_window->show(); -} - - -/** Create all (visual) ports and add them to module (and resize it). - * FIXME: this doesn't belong here - */ -void -NodeController::create_all_ports() -{ - assert(m_module); - - for (PortModelList::const_iterator i = node_model()->ports().begin(); - i != node_model()->ports().end(); ++i) { - CountedPtr pc = PtrCast(ControllerFactory::get_controller(*i)); - pc->create_port(m_module); - } - - m_module->resize(); - - if (has_control_inputs()) - enable_controls_menuitem(); -} - - -bool -NodeController::has_control_inputs() -{ - for (PortModelList::const_iterator i = node_model()->ports().begin(); - i != node_model()->ports().end(); ++i) - if ((*i)->is_input() && (*i)->is_control()) - return true; - - return false; -} - - -void -NodeController::enable_controls_menuitem() -{ - m_controls_menuitem->property_sensitive() = true; -} - - -void -NodeController::disable_controls_menuitem() -{ - m_controls_menuitem->property_sensitive() = false; - - if (m_control_window != NULL) - m_control_window->hide(); -} - - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/NodeController.h b/src/progs/ingenuity/NodeController.h deleted file mode 100644 index c0ee6ea9..00000000 --- a/src/progs/ingenuity/NodeController.h +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 - */ - -#ifndef NODECONTROLLER_H -#define NODECONTROLLER_H - -#include -#include -#include "util/Path.h" -#include "util/CountedPtr.h" -#include "GtkObjectController.h" -#include "NodeModel.h" - -using std::string; -using namespace Ingen::Client; - -namespace Ingen { namespace Client { - class MetadataModel; - class PortModel; -} } - -namespace Ingenuity { - -class Controller; -class OmModule; -class NodeControlWindow; -class NodePropertiesWindow; -class PortController; -class OmFlowCanvas; - -/** Controller for a Node. - * - * \ingroup Ingenuity - */ -class NodeController : public GtkObjectController -{ -public: - virtual ~NodeController(); - - virtual void metadata_update(const string& key, const string& value); - - virtual void create_module(OmFlowCanvas* canvas); - virtual void destroy_module(); - - void set_path(const Path& new_path); - - virtual void remove_port(const Path& path, bool resize_module) {} - - virtual void program_add(int bank, int program, const string& name) {} - virtual void program_remove(int bank, int program) {} - - OmModule* module() { return m_module; } - - //void bridge_port(PortController* port) { m_bridge_port = port; } - //PortController* as_port() { return m_bridge_port; } - - CountedPtr node_model() { return PtrCast(m_model); } - - NodeControlWindow* control_window() { return m_control_window; } - void control_window(NodeControlWindow* cw) { m_control_window = cw; } - - virtual void show_control_window(); - virtual void show_properties_window(); - void show_rename_window(); - - bool has_control_inputs(); - - virtual void show_menu(GdkEventButton* event) - { m_menu.popup(event->button, event->time); } - - virtual void enable_controls_menuitem(); - virtual void disable_controls_menuitem(); - -protected: - friend class ControllerFactory; - - NodeController(CountedPtr model); - - virtual void destroy(); - - virtual void add_port(CountedPtr pm); - - void create_all_ports(); - - void on_menu_destroy(); - void on_menu_clone(); - void on_menu_learn(); - void on_menu_disconnect_all(); - - Gtk::Menu m_menu; - Glib::RefPtr m_controls_menuitem; - - OmModule* m_module; ///< View (module on a patch canvas) - - NodeControlWindow* m_control_window; - NodePropertiesWindow* m_properties_window; - PortController* m_bridge_port; -}; - - -} // namespace Ingenuity - -#endif // NODECONTROLLER_H diff --git a/src/progs/ingenuity/NodeMenu.cpp b/src/progs/ingenuity/NodeMenu.cpp new file mode 100644 index 00000000..c3ee7a5b --- /dev/null +++ b/src/progs/ingenuity/NodeMenu.cpp @@ -0,0 +1,254 @@ +/* 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 +#include +#include "NodeMenu.h" +#include "NodeModel.h" +#include "App.h" +#include "ModelEngineInterface.h" +#include "WindowFactory.h" + +using std::cerr; using std::endl; + +namespace Ingenuity { + + +NodeMenu::NodeMenu(CountedPtr node) +: _node(node) +, _controls_menuitem(NULL) +{ + App& app = App::instance(); + + Gtk::Menu_Helpers::MenuElem controls_elem = Gtk::Menu_Helpers::MenuElem("Controls", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_controls), + node)); + _controls_menuitem = controls_elem.get_child(); + items().push_back(controls_elem); + + items().push_back(Gtk::Menu_Helpers::MenuElem("Properties", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_properties), + node))); + + items().push_back(Gtk::Menu_Helpers::SeparatorElem()); + + /*items().push_back(Gtk::Menu_Helpers::MenuElem("Rename...", + sigc::bind( + sigc::mem_fun(app.window_factory(), &WindowFactory::present_rename), + node)));*/ + /*items().push_back(Gtk::Menu_Helpers::MenuElem("Clone", + sigc::bind( + sigc::mem_fun(app.engine(), &EngineInterface::clone), + node))); + sigc::mem_fun(this, &NodeMenu::on_menu_clone)));*/ + + items().push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All", + sigc::mem_fun(this, &NodeMenu::on_menu_disconnect_all))); + + items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy", + sigc::mem_fun(this, &NodeMenu::on_menu_destroy))); + + //m_controls_menuitem->property_sensitive() = false; + + if (_node->plugin() && _node->plugin()->type() == PluginModel::Internal + && _node->plugin()->plug_label() == "midi_control_in") { + items().push_back(Gtk::Menu_Helpers::MenuElem("Learn", + sigc::mem_fun(this, &NodeMenu::on_menu_learn))); + } + + //model->new_port_sig.connect(sigc::mem_fun(this, &NodeMenu::add_port)); + //model->destroyed_sig.connect(sigc::mem_fun(this, &NodeMenu::destroy)); +} + +#if 0 +NodeMenu::~NodeMenu() +{ + cerr << "~NodeMenu()\n"; +} + +void +NodeMenu::destroy() +{ + cerr << "FIXME: NODE DESTROYED\n"; + //CountedPtr model = m_model; + //m_model.reset(); +} +#endif + +void +NodeMenu::set_path(const Path& new_path) +{ + cerr << "FIXME: rename\n"; + /* + remove_from_store(); + + // Rename ports + for (list::const_iterator i = _node->ports().begin(); + i != _node->ports().end(); ++i) { + ObjectController* const pc = (*i)->controller(); + assert(pc != NULL); + pc->set_path(m_model->path().base() + pc->model()->name()); + } + + // Handle bridge port, if this node represents one + if (m_bridge_port != NULL) + m_bridge_port->set_path(new_path); + + if (m_module != NULL) + m_module->canvas()->rename_module(_node->path().name(), new_path.name()); + + ObjectController::set_path(new_path); + + add_to_store(); + */ +} + +#if 0 +void +NodeMenu::destroy() +{ + PatchController* pc = ((PatchController*)m_model->parent()->controller()); + assert(pc != NULL); + + //remove_from_store(); + //pc->remove_node(m_model->path().name()); + cerr << "FIXME: remove node\n"; + + if (m_bridge_port != NULL) + m_bridge_port->destroy(); + m_bridge_port = NULL; + + //if (m_module != NULL) + // delete m_module; +} +#endif + +#if 0 +void +NodeMenu::add_port(CountedPtr pm) +{ + assert(pm->parent().get() == _node.get()); + assert(pm->parent() == _node); + assert(_node->get_port(pm->path().name()) == pm); + + //cout << "[NodeMenu] Adding port " << pm->path() << endl; + + /* + if (m_module != NULL) { + // (formerly PortController) + pc->create_port(m_module); + m_module->resize(); + + // Enable "Controls" menu item on module + if (has_control_inputs()) + enable_controls_menuitem(); + }*/ +} +#endif + +void +NodeMenu::on_menu_destroy() +{ + App::instance().engine()->destroy(_node->path()); +} + + +void +NodeMenu::on_menu_clone() +{ + cerr << "FIXME: clone broken\n"; + /* + assert(_node); + //assert(m_parent != NULL); + //assert(m_parent->model() != NULL); + + string clone_name = _node->name(); + int i = 2; // postfix number (ie oldname_2) + + // Check if name already has a number postfix + if (clone_name.find_last_of("_") != string::npos) { + string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1); + clone_name = clone_name.substr(0, clone_name.find_last_of("_")); + if (sscanf(name_postfix.c_str(), "%d", &i)) + ++i; + } + + char clone_postfix[4]; + for ( ; i < 100; ++i) { + snprintf(clone_postfix, 4, "_%d", i); + if (_node->parent_patch()->get_node(clone_name + clone_postfix) == NULL) + break; + } + + clone_name = clone_name + clone_postfix; + + const string path = _node->parent_patch()->base() + clone_name; + NodeModel* nm = new NodeModel(_node->plugin(), path); + nm->polyphonic(_node->polyphonic()); + nm->x(_node->x() + 20); + nm->y(_node->y() + 20); + App::instance().engine()->create_node_from_model(nm); + */ +} + + +void +NodeMenu::on_menu_learn() +{ + App::instance().engine()->midi_learn(_node->path()); +} + +void +NodeMenu::on_menu_disconnect_all() +{ + App::instance().engine()->disconnect_all(_node->path()); +} + + +bool +NodeMenu::has_control_inputs() +{ + for (PortModelList::const_iterator i = _node->ports().begin(); + i != _node->ports().end(); ++i) + if ((*i)->is_input() && (*i)->is_control()) + return true; + + return false; +} + + +void +NodeMenu::enable_controls_menuitem() +{ + _controls_menuitem->property_sensitive() = true; +} + + +void +NodeMenu::disable_controls_menuitem() +{ + _controls_menuitem->property_sensitive() = false; + + //if (m_control_window != NULL) + // m_control_window->hide(); +} + + + +} // namespace Ingenuity + diff --git a/src/progs/ingenuity/NodeMenu.h b/src/progs/ingenuity/NodeMenu.h new file mode 100644 index 00000000..a80b7a69 --- /dev/null +++ b/src/progs/ingenuity/NodeMenu.h @@ -0,0 +1,75 @@ +/* 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 + */ + +#ifndef NODEMENU_H +#define NODEMENU_H + +#include +#include +#include "util/Path.h" +#include "util/CountedPtr.h" +#include "NodeModel.h" +using Ingen::Client::NodeModel; + +using std::string; + +namespace Ingenuity { + +class Controller; +class NodeControlWindow; +class NodePropertiesWindow; +class OmFlowCanvas; + +/** Controller for a Node. + * + * \ingroup Ingenuity + */ +class NodeMenu : public Gtk::Menu +{ +public: + NodeMenu(CountedPtr node); + + void set_path(const Path& new_path); + + virtual void program_add(int bank, int program, const string& name) {} + virtual void program_remove(int bank, int program) {} + + bool has_control_inputs(); + + //virtual void show_menu(GdkEventButton* event) + //{ m_menu.popup(event->button, event->time); } + +protected: + + virtual void enable_controls_menuitem(); + virtual void disable_controls_menuitem(); + + //virtual void add_port(CountedPtr pm); + + void on_menu_destroy(); + void on_menu_clone(); + void on_menu_learn(); + void on_menu_disconnect_all(); + + //Gtk::Menu m_menu; + CountedPtr _node; + Glib::RefPtr _controls_menuitem; +}; + + +} // namespace Ingenuity + +#endif // NODEMENU_H diff --git a/src/progs/ingenuity/NodePropertiesWindow.h b/src/progs/ingenuity/NodePropertiesWindow.h index 2c36dc5c..62934f0a 100644 --- a/src/progs/ingenuity/NodePropertiesWindow.h +++ b/src/progs/ingenuity/NodePropertiesWindow.h @@ -20,8 +20,7 @@ #include #include #include "util/CountedPtr.h" - -namespace Ingen { namespace Client { class NodeModel; } } +#include "NodeModel.h" using namespace Ingen::Client; namespace Ingenuity { @@ -38,6 +37,7 @@ class NodePropertiesWindow : public Gtk::Window public: NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); + void present(CountedPtr node_model) { set_node(node_model); Gtk::Window::present(); } void set_node(CountedPtr node_model); private: diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp index d530bca0..0d2e9bb0 100644 --- a/src/progs/ingenuity/OmFlowCanvas.cpp +++ b/src/progs/ingenuity/OmFlowCanvas.cpp @@ -19,7 +19,6 @@ #include #include "App.h" #include "ModelEngineInterface.h" -#include "PatchController.h" #include "PatchModel.h" #include "PatchWindow.h" #include "LoadPluginWindow.h" @@ -28,27 +27,20 @@ #include "OmPort.h" #include "NodeModel.h" #include "OmModule.h" +#include "OmPortModule.h" +#include "SubpatchModule.h" #include "GladeFactory.h" +#include "WindowFactory.h" namespace Ingenuity { -OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height) +OmFlowCanvas::OmFlowCanvas(CountedPtr patch, int width, int height) : FlowCanvas(width, height), - m_patch_controller(controller), + m_patch(patch), m_last_click_x(0), m_last_click_y(0) { - assert(controller != NULL); - - /*Gtk::Menu::MenuList& items = m_menu.items(); - items.push_back(Gtk::Menu_Helpers::MenuElem("Load Plugin...", - sigc::mem_fun(this, &OmFlowCanvas::menu_load_plugin))); - items.push_back(Gtk::Menu_Helpers::MenuElem("Load Subpatch...", - sigc::mem_fun(this, &OmFlowCanvas::menu_load_subpatch))); - items.push_back(Gtk::Menu_Helpers::MenuElem("New Subpatch...", - sigc::mem_fun(this, &OmFlowCanvas::menu_create_subpatch)));*/ - Glib::RefPtr xml = GladeFactory::new_glade_reference(); xml->get_widget("canvas_menu", m_menu); @@ -62,6 +54,8 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height) xml->get_widget("canvas_menu_load_patch", m_menu_load_patch); xml->get_widget("canvas_menu_new_patch", m_menu_new_patch); + build_canvas(); + // Add port menu items m_menu_add_audio_input->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), @@ -82,12 +76,113 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height) sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), "midi_output", "MIDI", true)); + // Connect to model signals to track state + m_patch->new_node_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::add_node)); + m_patch->removed_node_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::remove_node)); + m_patch->new_connection_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::connection)); + m_patch->removed_connection_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::disconnection)); + + // Connect widget signals to do things m_menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_plugin)); m_menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_patch)); m_menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_new_patch)); } +void +OmFlowCanvas::build_canvas() { + + // Create modules for nodes + for (NodeModelMap::const_iterator i = m_patch->nodes().begin(); + i != m_patch->nodes().end(); ++i) { + add_node((*i).second); + } + + // Create pseudo modules for ports (ports on this canvas, not on our module) + for (PortModelList::const_iterator i = m_patch->ports().begin(); + i != m_patch->ports().end(); ++i) { + cerr << "FIXME: PORT MODULE LEAK!" << endl; + new OmPortModule(this, *i); + } + + // Create connections + for (list >::const_iterator i = m_patch->connections().begin(); + i != m_patch->connections().end(); ++i) { + connection(*i); + } +} + + +void +OmFlowCanvas::add_node(CountedPtr nm) +{ + cerr << "FIXME: MODULE LEAK!" << endl; + + CountedPtr pm = PtrCast(nm); + if (pm) + new SubpatchModule(this, pm); + else + new OmModule(this, nm); +} + + +void +OmFlowCanvas::remove_node(CountedPtr nm) +{ + LibFlowCanvas::Module* module = get_module(nm->path().name()); + delete module; +} + + +void +OmFlowCanvas::connection(CountedPtr cm) +{ + // Deal with port "anonymous nodes" for this patch's own ports... + const Path& src_parent_path = cm->src_port_path().parent(); + const Path& dst_parent_path = cm->dst_port_path().parent(); + + const string& src_parent_name = + (src_parent_path == m_patch->path()) ? "" : src_parent_path.name(); + const string& dst_parent_name = + (dst_parent_path == m_patch->path()) ? "" : dst_parent_path.name(); + + Port* src_port = get_port(src_parent_name, cm->src_port_path().name()); + Port* dst_port = get_port(dst_parent_name, cm->dst_port_path().name()); + assert(src_port && dst_port); + + add_connection(src_port, dst_port); +} + + +void +OmFlowCanvas::disconnection(const Path& src_port_path, const Path& dst_port_path) +{ + const string& src_node_name = src_port_path.parent().name(); + const string& src_port_name = src_port_path.name(); + const string& dst_node_name = dst_port_path.parent().name(); + const string& dst_port_name = dst_port_path.name(); + + Port* src_port = get_port(src_node_name, src_port_name); + Port* dst_port = get_port(dst_node_name, dst_port_name); + + if (src_port && dst_port) { + remove_connection(src_port, dst_port); + } + + //patch_model()->remove_connection(src_port_path, dst_port_path); + + cerr << "FIXME: disconnection\n"; + /* + // Enable control slider in destination node control window + PortController* p = (PortController)Store::instance().port(dst_port_path)->controller(); + assert(p); + + if (p->control_panel()) + p->control_panel()->enable_port(p->path()); + */ +} + + void OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) { @@ -102,10 +197,12 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) dst->model()->type() == PortModel::CONTROL) { CountedPtr pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); - CountedPtr nm(new NodeModel(pm, m_patch_controller->model()->path().base() - + src->name() + "-" + dst->name())); - nm->x(dst->module()->property_x() - dst->module()->width() - 20); - nm->y(dst->module()->property_y()); + CountedPtr nm(new NodeModel(pm, m_patch->path().base() + + src->name() + "-" + dst->name(), false)); + nm->set_metadata("module-x", Atom((float) + (dst->module()->property_x() - dst->module()->width() - 20))); + nm->set_metadata("module-y", Atom((float) + (dst->module()->property_y()))); App::instance().engine()->create_node_from_model(nm.get()); App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); @@ -114,9 +211,9 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) // Set control node range to port's user range App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", - atof(dst->model()->get_metadata("user-min").c_str())); + dst->model()->get_metadata("user-min").get_float()); App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", - atof(dst->model()->get_metadata("user-max").c_str())); + dst->model()->get_metadata("user-max").get_float()); } else { App::instance().engine()->connect(src->model()->path(), dst->model()->path()); @@ -181,7 +278,7 @@ OmFlowCanvas::generate_port_name(const string& base) { snprintf(num_buf, 5, "%u", i); name = base + "_"; name += num_buf; - if (!m_patch_controller->patch_model()->get_port(name)) + if (!m_patch->get_port(name)) break; } @@ -194,7 +291,7 @@ OmFlowCanvas::generate_port_name(const string& base) { void OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_output) { - const Path& path = m_patch_controller->path().base() + generate_port_name(name); + const Path& path = m_patch->path().base() + generate_port_name(name); App::instance().engine()->create_port(path, type, is_output); char temp_buf[16]; @@ -267,30 +364,35 @@ OmFlowCanvas::menu_add_midi_output() } */ +MetadataMap +OmFlowCanvas::get_initial_data() +{ + MetadataMap result; + + result["module-x"] = Atom((float)m_last_click_x); + result["module-y"] = Atom((float)m_last_click_y); + + return result; +} + void OmFlowCanvas::menu_load_plugin() { - m_patch_controller->window()->load_plugin_window()->set_next_module_location( - m_last_click_x, m_last_click_y); - m_patch_controller->window()->load_plugin_window()->show(); + App::instance().window_factory()->present_load_plugin(m_patch, get_initial_data()); } void OmFlowCanvas::menu_load_patch() { - m_patch_controller->window()->load_subpatch_window()->set_next_module_location( - m_last_click_x, m_last_click_y); - m_patch_controller->window()->load_subpatch_window()->show(); + App::instance().window_factory()->present_load_subpatch(m_patch, get_initial_data()); } void OmFlowCanvas::menu_new_patch() { - m_patch_controller->window()->new_subpatch_window()->set_next_module_location( - m_last_click_x, m_last_click_y); - m_patch_controller->window()->new_subpatch_window()->show(); + App::instance().window_factory()->present_new_subpatch(m_patch, get_initial_data()); } diff --git a/src/progs/ingenuity/OmFlowCanvas.h b/src/progs/ingenuity/OmFlowCanvas.h index 7db347f7..ae5501c4 100644 --- a/src/progs/ingenuity/OmFlowCanvas.h +++ b/src/progs/ingenuity/OmFlowCanvas.h @@ -19,17 +19,24 @@ #include #include - +#include "util/CountedPtr.h" +#include "util/Path.h" +#include "ConnectionModel.h" +#include "PatchModel.h" using std::string; using namespace LibFlowCanvas; using LibFlowCanvas::Port; +using Ingen::Client::ConnectionModel; +using Ingen::Client::PatchModel; +using Ingen::Client::NodeModel; +using Ingen::Client::MetadataMap; namespace Ingenuity { class OmModule; -class PatchController; + /** Patch canvas widget. * @@ -38,16 +45,18 @@ class PatchController; class OmFlowCanvas : public LibFlowCanvas::FlowCanvas { public: - OmFlowCanvas(PatchController* controller, int width, int height); + OmFlowCanvas(CountedPtr patch, int width, int height); OmModule* find_module(const string& name) { return (OmModule*)FlowCanvas::get_module(name); } - void connect(const Port* src_port, const Port* dst_port); - void disconnect(const Port* src_port, const Port* dst_port); - + void add_node(CountedPtr nm); + void remove_node(CountedPtr nm); + void connection(CountedPtr cm); + void disconnection(const Path& src_port_path, const Path& dst_port_path); + void get_new_module_location(double& x, double& y); - bool canvas_event(GdkEvent* event); + void destroy_selected(); void show_menu(GdkEvent* event) @@ -65,10 +74,20 @@ private: void menu_load_plugin(); void menu_new_patch(); void menu_load_patch(); + + MetadataMap get_initial_data(); + + void build_canvas(); + + bool canvas_event(GdkEvent* event); + + void connect(const Port* src_port, const Port* dst_port); + void disconnect(const Port* src_port, const Port* dst_port); + + CountedPtr m_patch; - PatchController* m_patch_controller; - int m_last_click_x; - int m_last_click_y; + int m_last_click_x; + int m_last_click_y; Gtk::Menu* m_menu; Gtk::MenuItem* m_menu_add_audio_input; diff --git a/src/progs/ingenuity/OmModule.cpp b/src/progs/ingenuity/OmModule.cpp index dd6f3da5..9e06d910 100644 --- a/src/progs/ingenuity/OmModule.cpp +++ b/src/progs/ingenuity/OmModule.cpp @@ -16,6 +16,7 @@ #include "OmModule.h" #include +#include "util/Atom.h" #include "App.h" #include "ModelEngineInterface.h" #include "OmFlowCanvas.h" @@ -24,53 +25,95 @@ #include "OmPort.h" #include "GladeFactory.h" #include "RenameWindow.h" -#include "PatchController.h" #include "PatchWindow.h" +#include "WindowFactory.h" namespace Ingenuity { -OmModule::OmModule(OmFlowCanvas* canvas, NodeController* node) -: LibFlowCanvas::Module(canvas, node->node_model()->path().name(), - node->node_model()->x(), node->node_model()->y()), - m_node(node) +OmModule::OmModule(OmFlowCanvas* canvas, CountedPtr node) +: LibFlowCanvas::Module(canvas, node->path().name()), + m_node(node), + m_menu(node) { assert(m_node); - /*if (node_model()->polyphonic() && node_model()->parent() != NULL - && node_model()->parent_patch()->poly() > 1) { - border_width(2.0); - }*/ - if (node->node_model()->polyphonic()) { + if (node->polyphonic()) { border_width(2.0); } + + create_all_ports(); + + const Atom& x = node->get_metadata("module-x"); + const Atom& y = node->get_metadata("module-y"); + + if (x.type() == Atom::FLOAT && y.type() == Atom::FLOAT) { + move_to(x.get_float(), y.get_float()); + } else { + double x, y; + ((OmFlowCanvas*)m_canvas)->get_new_module_location(x, y); + } + + node->new_port_sig.connect(sigc::mem_fun(this, &OmModule::add_port)); + node->removed_port_sig.connect(sigc::mem_fun(this, &OmModule::remove_port)); + node->metadata_update_sig.connect(sigc::mem_fun(this, &OmModule::metadata_update)); +} + + +void +OmModule::create_all_ports() +{ + for (PortModelList::const_iterator i = m_node->ports().begin(); + i != m_node->ports().end(); ++i) { + add_port(*i); + } + + resize(); + + // FIXME + //if (has_control_inputs()) + // enable_controls_menuitem(); +} + + +void +OmModule::add_port(CountedPtr port) +{ + new OmPort(this, port); + resize(); +} + + +void +OmModule::remove_port(CountedPtr port) +{ + LibFlowCanvas::Port* canvas_port = get_port(port->path().name()); + delete canvas_port; } void OmModule::show_control_window() { - node()->show_control_window(); + App::instance().window_factory()->present_controls(m_node); } void OmModule::store_location() { - if (m_node->node_model()->x() == 0 || m_node->node_model()->y() == 0) - return; - - char temp_buf[16]; + const float x = static_cast(property_x()); + const float y = static_cast(property_y()); - m_node->node_model()->x(property_x()); - snprintf(temp_buf, 16, "%f", m_node->node_model()->x()); - m_node->node_model()->set_metadata("module-x", temp_buf); // just in case? - App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-x", temp_buf); + const Atom& existing_x = m_node->get_metadata("module-x"); + const Atom& existing_y = m_node->get_metadata("module-y"); - m_node->node_model()->y(property_y()); - snprintf(temp_buf, 16, "%f", m_node->node_model()->y()); - m_node->node_model()->set_metadata("module-y", temp_buf); // just in case? - App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-y", temp_buf); + if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT + || existing_x.get_float() != x || existing_y.get_float() != y) { + App::instance().engine()->set_metadata(m_node->path(), "module-x", Atom(x)); + App::instance().engine()->set_metadata(m_node->path(), "module-y", Atom(y)); + } + } @@ -78,9 +121,25 @@ void OmModule::move_to(double x, double y) { Module::move_to(x, y); - m_node->node_model()->x(x); - m_node->node_model()->y(y); //store_location(); } + +void +OmModule::on_right_click(GdkEventButton* event) +{ + m_menu.popup(event->button, event->time); +} + + +void +OmModule::metadata_update(const string& key, const Atom& value) +{ + if (key == "module-x" && value.type() == Atom::FLOAT) + move_to(value.get_float(), property_y()); + else if (key == "module-y" && value.type() == Atom::FLOAT) + move_to(property_x(), value.get_float()); +} + + } // namespace Ingenuity diff --git a/src/progs/ingenuity/OmModule.h b/src/progs/ingenuity/OmModule.h index a3d56187..243c31e7 100644 --- a/src/progs/ingenuity/OmModule.h +++ b/src/progs/ingenuity/OmModule.h @@ -14,17 +14,18 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef OMMODULE_H #define OMMODULE_H #include #include #include +#include "NodeMenu.h" #include "util/CountedPtr.h" -#include "NodeController.h" using std::string; +class Atom; + namespace Ingen { namespace Client { class PortModel; class NodeModel; @@ -34,7 +35,6 @@ using namespace Ingen::Client; namespace Ingenuity { -class PatchController; class OmFlowCanvas; class OmPort; @@ -49,7 +49,7 @@ class OmPort; class OmModule : public LibFlowCanvas::Module { public: - OmModule(OmFlowCanvas* canvas, NodeController* node); + OmModule(OmFlowCanvas* canvas, CountedPtr node); virtual ~OmModule() {} virtual OmPort* port(const string& port_name) { @@ -59,17 +59,24 @@ public: virtual void store_location(); void move_to(double x, double y); - void on_right_click(GdkEventButton* event) { m_node->show_menu(event); } + void on_right_click(GdkEventButton* event); void show_control_window(); - NodeController* node() const { return m_node; } + CountedPtr node() const { return m_node; } protected: virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } - NodeController* m_node; + void metadata_update(const string& key, const Atom& value); + + void create_all_ports(); + void add_port(CountedPtr port); + void remove_port(CountedPtr port); + + CountedPtr m_node; + NodeMenu m_menu; }; diff --git a/src/progs/ingenuity/OmPatchPort.h b/src/progs/ingenuity/OmPatchPort.h index 112fc160..e7d5765f 100644 --- a/src/progs/ingenuity/OmPatchPort.h +++ b/src/progs/ingenuity/OmPatchPort.h @@ -30,7 +30,6 @@ using std::string; using std::list; namespace Ingenuity { class FlowCanvas; -class PatchController; class PatchWindow; class OmPortModule; diff --git a/src/progs/ingenuity/OmPort.h b/src/progs/ingenuity/OmPort.h index 5ffd4e26..cedad156 100644 --- a/src/progs/ingenuity/OmPort.h +++ b/src/progs/ingenuity/OmPort.h @@ -30,7 +30,6 @@ using std::string; using std::list; namespace Ingenuity { class FlowCanvas; -class PatchController; class PatchWindow; class OmModule; diff --git a/src/progs/ingenuity/OmPortModule.cpp b/src/progs/ingenuity/OmPortModule.cpp index e5c5fca6..aaa26205 100644 --- a/src/progs/ingenuity/OmPortModule.cpp +++ b/src/progs/ingenuity/OmPortModule.cpp @@ -24,22 +24,44 @@ #include "OmPort.h" #include "GladeFactory.h" #include "RenameWindow.h" -#include "PatchController.h" #include "PatchWindow.h" +#include "OmPatchPort.h" namespace Ingenuity { -OmPortModule::OmPortModule(OmFlowCanvas* canvas, PortController* port, double x, double y) -: LibFlowCanvas::Module(canvas, "", x, y), +OmPortModule::OmPortModule(OmFlowCanvas* canvas, CountedPtr port) +: LibFlowCanvas::Module(canvas, "", 0, 0), // FIXME: coords? m_port(port) { - assert(m_port != NULL); - /*if (port_model()->polyphonic() && port_model()->parent() != NULL && port_model()->parent_patch()->poly() > 1) { border_width(2.0); }*/ + + assert(canvas); + assert(port); + + if (PtrCast(port->parent())) { + if (m_patch_port) + delete m_patch_port; + + m_patch_port = new OmPatchPort(this, port); + } + + resize(); + + const Atom& x_atom = port->get_metadata("module-x"); + const Atom& y_atom = port->get_metadata("module-y"); + + if (x_atom && y_atom && x_atom.type() == Atom::FLOAT && y_atom.type() == Atom::FLOAT) { + move_to(x_atom.get_float(), y_atom.get_float()); + } else { + double default_x; + double default_y; + canvas->get_new_module_location(default_x, default_y); + move_to(default_x, default_y); + } } @@ -48,15 +70,15 @@ OmPortModule::store_location() { char temp_buf[16]; - //m_port->port_model()->x(property_x()); + //m_port->x(property_x()); snprintf(temp_buf, 16, "%f", property_x().get_value()); - //m_port->port_model()->set_metadata("module-x", temp_buf); // just in case? - App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-x", temp_buf); + //m_port->set_metadata("module-x", temp_buf); // just in case? + App::instance().engine()->set_metadata(m_port->path(), "module-x", temp_buf); - //m_port->port_model()->y(property_y()); + //m_port->y(property_y()); snprintf(temp_buf, 16, "%f", property_y().get_value()); - //m_port->port_model()->set_metadata("module-y", temp_buf); // just in case? - App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-y", temp_buf); + //m_port->set_metadata("module-y", temp_buf); // just in case? + App::instance().engine()->set_metadata(m_port->path(), "module-y", temp_buf); } @@ -64,8 +86,8 @@ void OmPortModule::move_to(double x, double y) { Module::move_to(x, y); - //m_port->port_model()->x(x); - //m_port->port_model()->y(y); + //m_port->x(x); + //m_port->y(y); //store_location(); } diff --git a/src/progs/ingenuity/OmPortModule.h b/src/progs/ingenuity/OmPortModule.h index 85bd349b..00d20f96 100644 --- a/src/progs/ingenuity/OmPortModule.h +++ b/src/progs/ingenuity/OmPortModule.h @@ -14,14 +14,13 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef OMPORTMODULE_H #define OMPORTMODULE_H #include #include #include -#include "PortController.h" +#include "OmPatchPort.h" using std::string; namespace Ingen { namespace Client { @@ -33,8 +32,6 @@ using namespace Ingen::Client; namespace Ingenuity { -class PatchController; -class PortController; class OmFlowCanvas; class OmPort; @@ -48,7 +45,7 @@ class OmPort; class OmPortModule : public LibFlowCanvas::Module { public: - OmPortModule(OmFlowCanvas* canvas, PortController* port, double x, double y); + OmPortModule(OmFlowCanvas* canvas, CountedPtr port); virtual ~OmPortModule() {} //virtual OmPort* port(const string& port_name) { @@ -60,13 +57,14 @@ public: //void on_right_click(GdkEventButton* event) { m_port->show_menu(event); } - PortController* port() const { return m_port; } + CountedPtr port() const { return m_port; } protected: //virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } //virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } - PortController* m_port; + CountedPtr m_port; + OmPatchPort* m_patch_port; ///< Port on this 'anonymous' module }; diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp deleted file mode 100644 index f02aa773..00000000 --- a/src/progs/ingenuity/PatchController.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* 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 "config.h" -#include "PatchController.h" -#include -#include -#include "GladeFactory.h" -#include "Configuration.h" -#include "util/Path.h" -#include "ControlPanel.h" -#include "ConnectionModel.h" -#include "OmFlowCanvas.h" -#include "PatchView.h" -#include "flowcanvas/Module.h" -#include "PluginModel.h" -#include "SubpatchModule.h" -#include "DSSIModule.h" -#include "PatchWindow.h" -#include "NodeModel.h" -#include "OmModule.h" -#include "OmPortModule.h" -#include "OmPort.h" -#include "ControlModel.h" -#include "NodeControlWindow.h" -#include "NodeController.h" -#include "PortController.h" -#include "App.h" -#include "PatchTreeWindow.h" -#include "PatchPropertiesWindow.h" -#include "DSSIController.h" -#include "PatchModel.h" -#include "Store.h" -#include "ControllerFactory.h" - -using std::cerr; using std::cout; using std::endl; -using namespace Ingen::Client; - -namespace Ingenuity { - - -PatchController::PatchController(CountedPtr model) -: NodeController(model), - m_properties_window(NULL), - m_window(NULL), - m_patch_model(model), - m_module_x(0), - m_module_y(0) -{ - //model->new_port_sig.connect(sigc::mem_fun(this, &PatchController::add_port)); - model->new_node_sig.connect(sigc::mem_fun(this, &PatchController::add_node)); - model->new_connection_sig.connect(sigc::mem_fun(this, &PatchController::connection)); - model->removed_connection_sig.connect(sigc::mem_fun(this, &PatchController::disconnection)); -} - - -PatchController::~PatchController() -{ - if (m_patch_view) { - claim_patch_view(); - } - - if (m_control_window) { - m_control_window->hide(); - delete m_control_window; - m_control_window = NULL; - } - - if (m_window) { - delete m_window; - m_window = NULL; - } -} - -#if 0 -void -PatchController::clear() -{ - // Destroy model - // Destroying nodes removes models from patch model, which invalidates any - // iterator to nodes, so avoid the iterator problem by doing it this way: - const NodeModelMap& nodes = patch_model()->nodes(); - size_t remaining = nodes.size(); - - while (remaining > 0) { - CountedPtr nc = (*nodes.begin()).second->controller(); - assert(nc); - nc->destroy(); - assert(nodes.size() == remaining - 1); - --remaining; - } - assert(nodes.empty()); - - patch_model()->clear(); - - if (m_patch_view) { - assert(m_patch_view->canvas()); - m_patch_view->canvas()->destroy(); - } -} -#endif - -#if 0 -void -PatchController::destroy() -{ - // Destroying nodes removes models from patch model, which invalidates any - // iterator to nodes, so avoid the iterator problem by doing it this way: - const NodeModelMap& nodes = patch_model()->nodes(); - size_t remaining = nodes.size(); - - while (remaining > 0) { - CountedPtr nc = (*nodes.begin()).second->controller(); - assert(nc); - nc->destroy(); - assert(nodes.size() == remaining - 1); - --remaining; - } - assert(nodes.empty()); - - //App::instance().remove_patch(this); - App::instance().patch_tree()->remove_patch(path()); - - // Delete all children models - //patch_model()->clear(); - - // Remove self from object store - //Store::instance().remove_object(this); - - // Delete self from parent (this will delete model) - /*if (patch_model()->parent()) { - PatchController* const parent = (PatchController*)patch_model()->parent()->controller(); - assert(parent); - parent->remove_node(name()); - } else { - //delete m_model; - }*/ -} -#endif - - -void -PatchController::metadata_update(const string& key, const string& value) -{ - NodeController::metadata_update(key, value); - - if (key == "filename") - patch_model()->filename(value); -} - - -void -PatchController::set_path(const Path& new_path) -{ - assert(m_model); - Path old_path = path(); - - // Rename nodes - for (NodeModelMap::const_iterator i = patch_model()->nodes().begin(); - i != patch_model()->nodes().end(); ++i) { - const NodeModel* const nm = (*i).second.get(); - assert(nm); - CountedPtr nc = PtrCast(nm->controller()); - assert(nc); - nc->set_path(new_path.base() + nc->node_model()->path().name()); - } - -#ifdef DEBUG - // Be sure ports were renamed by their bridge nodes - for (PortModelList::const_iterator i = node_model()->ports().begin(); - i != node_model()->ports().end(); ++i) { - CountedPtr pc = PtrCast((*i)->controller()); - assert(pc); - assert(pc->path().parent()== new_path); - } -#endif - - App::instance().patch_tree()->patch_renamed(old_path, new_path); - - /*if (m_window) - m_window->patch_renamed(new_path);*/ - - if (m_control_window) - m_control_window->set_title(new_path + " Controls"); - - if (m_module) - m_module->name(new_path.name()); - - CountedPtr parent = PtrCast(patch_model()->parent()->controller()); - - //if (parent && parent->window()) - // parent->window()->node_renamed(old_path, new_path); - - //remove_from_store(); - GtkObjectController::set_path(new_path); - //add_to_store(); - - if (old_path.name() != new_path.name()) - parent->patch_model()->rename_node(old_path, new_path); -} - - -void -PatchController::create_module(OmFlowCanvas* canvas) -{ - // Update menu if we didn't used to have a module - if (!m_module) { - /*Gtk::Menu::MenuList& items = m_menu.items(); - m_menu.remove(items[4]); - - items.push_front(Gtk::Menu_Helpers::SeparatorElem()); - items.push_front(Gtk::Menu_Helpers::MenuElem("Browse to Patch", - sigc::mem_fun((SubpatchModule*)m_module, &SubpatchModule::browse_to_patch))); - items.push_front(Gtk::Menu_Helpers::MenuElem("Open Patch in New Window", - sigc::mem_fun(this, &PatchController::show_patch_window)));*/ - } - - if (!m_module || m_module->canvas() != canvas) { - - //cerr << "Creating patch module " << m_model->path() << endl; - - assert(canvas); - assert(m_module == NULL); - assert(!m_patch_view || canvas != m_patch_view->canvas()); - - // FIXME: weirdo using model->controller() to get shared_ptr_from_this.. - m_module = new SubpatchModule(canvas, PtrCast(m_model->controller())); - create_all_ports(); - } - - m_module->move_to(node_model()->x(), node_model()->y()); -} - - -CountedPtr -PatchController::get_view() -{ - if (m_patch_view) - return m_patch_view; - - Glib::RefPtr xml = GladeFactory::new_glade_reference(); - - PatchView* pv = NULL; - xml->get_widget_derived("patch_view_vbox", pv); - assert(pv); - m_patch_view = CountedPtr(pv); - m_patch_view->patch_controller(this); - assert(m_patch_view->canvas()); - - // Create modules for nodes - for (NodeModelMap::const_iterator i = patch_model()->nodes().begin(); - i != patch_model()->nodes().end(); ++i) { - - const CountedPtr nm = (*i).second; - - string val = nm->get_metadata("module-x"); - if (val != "") - nm->x(atof(val.c_str())); - val = nm->get_metadata("module-y"); - if (val != "") - nm->y(atof(val.c_str())); - - /* Set sane default coordinates if not set already yet */ - if (nm->x() == 0.0f && nm->y() == 0.0f) { - double x, y; - m_patch_view->canvas()->get_new_module_location(x, y); - nm->x(x); - nm->y(y); - } - - CountedPtr nc = PtrCast(ControllerFactory::get_controller(nm)); - - assert(nc); - assert(nm->controller() == nc); - - nc->create_module(m_patch_view->canvas()); - assert(nc->module()); - } - - // Create pseudo modules for ports (ports on this canvas, not on our module) - for (PortModelList::const_iterator i = patch_model()->ports().begin(); - i != patch_model()->ports().end(); ++i) { - CountedPtr pc = PtrCast((*i)->controller()); - assert(pc); - pc->create_module(m_patch_view->canvas()); - } - - - // Create connections - for (list >::const_iterator i = patch_model()->connections().begin(); - i != patch_model()->connections().end(); ++i) { - connection(*i); - } - - // Set run checkbox - if (patch_model()->enabled()) - m_patch_view->enable(); - - return m_patch_view; -} - - -void -PatchController::show_properties_window() -{ - if (!m_properties_window) { - Glib::RefPtr glade_xml = GladeFactory::new_glade_reference(); - glade_xml->get_widget_derived("patch_properties_win", m_properties_window); - m_properties_window->patch_model(patch_model()); - } - - m_properties_window->show(); - -} - - -/** Create a connection in the view (canvas). - */ -void -PatchController::connection(CountedPtr cm) -{ - if (m_patch_view) { - - // Deal with port "anonymous nodes" for this patch's own ports... - const Path& src_parent_path = cm->src_port_path().parent(); - const Path& dst_parent_path = cm->dst_port_path().parent(); - - const string& src_parent_name = - (src_parent_path == path()) ? "" : src_parent_path.name(); - const string& dst_parent_name = - (dst_parent_path == path()) ? "" : dst_parent_path.name(); - - Port* src_port = m_patch_view->canvas()->get_port(src_parent_name, cm->src_port_path().name()); - Port* dst_port = m_patch_view->canvas()->get_port(dst_parent_name, cm->dst_port_path().name()); - assert(src_port && dst_port); - - m_patch_view->canvas()->add_connection(src_port, dst_port); - } -} - - -/** Add a child node to this patch. - * - * This is for plugin nodes and patches, and is responsible for creating the - * GtkObjectController for @a node (and through that the View if necessary) - */ -void -PatchController::add_node(CountedPtr node) -{ - assert(node); - assert(node->parent().get() == m_patch_model.get()); - assert(node->parent() == m_patch_model); - assert(patch_model()->get_node(node->path().name())); - - assert(node->parent() == m_patch_model); - - CountedPtr nc = PtrCast(ControllerFactory::get_controller(node)); - assert(nc); - assert(node->controller() == nc); // lifeline reference - - if (m_patch_view) { - double x, y; - m_patch_view->canvas()->get_new_module_location(x, y); - node->x(x); - node->y(y); - - // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) - float old_zoom = m_patch_view->canvas()->get_zoom(); - if (old_zoom != 1.0) - m_patch_view->canvas()->set_zoom(1.0); - - nc->create_module(m_patch_view->canvas()); - assert(nc->module()); - nc->module()->resize(); - - // Reset zoom - if (old_zoom != 1.0) { - m_patch_view->canvas()->set_zoom(old_zoom); - nc->module()->zoom(old_zoom); - } - } - -} - -#if 0 -/** Add a port to this patch. - * - * Will add a port to the subpatch module and the control window, if they - * exist. - */ -void -PatchController::add_port(CountedPtr pm) -{ - assert(pm); - assert(pm->parent() == m_patch_model); - assert(patch_model()->get_port(pm->path().name())); - - //cerr << "[PatchController] Adding port " << pm->path() << endl; - - /*if (patch_model()->get_port(pm->path().name())) { - cerr << "[PatchController] Ignoring duplicate port " - << pm->path() << endl; - return; - }*/ - - //node_model()->add_port(pm); - CountedPtr pc = ControllerFactory::get_controller(pm); - - // Handle bridge ports/nodes (this is uglier than it should be) - /*NodeController* nc = (NodeController*)Store::instance().node(pm->path())->controller(); - if (nc) - nc->bridge_port(pc); - */ - - // Create port on this patch's module (if there is one) - if (m_module) { - pc->create_port(m_module); - m_module->resize(); - } - - // Create port's (pseudo) module on this patch's canvas (if there is one) - if (m_patch_view) { - - // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas) - float old_zoom = m_patch_view->canvas()->get_zoom(); - m_patch_view->canvas()->set_zoom(1.0); - - pc->create_module(m_patch_view->canvas()); - - // Reset zoom - pc->module()->zoom(old_zoom); - } - - if (m_control_window) { - assert(m_control_window->control_panel()); - m_control_window->control_panel()->add_port(pm); - m_control_window->resize(); - } - - // Enable "Controls" menuitem on module and patch window, if necessary - if (has_control_inputs()) - enable_controls_menuitem(); -} - - -/** Removes a port from this patch - */ -void -PatchController::remove_port(const Path& path, bool resize_module) -{ - assert(path.parent() == m_model->path()); - assert( ! patch_model()->get_port(path.name())); - - //cerr << "[PatchController] Removing port " << path << endl; - - /* FIXME - if (m_control_panel) { - m_control_panel->remove_port(path); - if (m_control_window) { - assert(m_control_window->control_panel() == m_control_panel); - m_control_window->resize(); - } - }*/ - - if (m_module) { - delete m_module->port(path.name()); - if (resize_module) - m_module->resize(); - } - - // Disable "Controls" menuitem on module and patch window, if necessary - if (!has_control_inputs()) - disable_controls_menuitem(); -} -#endif - -void -PatchController::disconnection(const Path& src_port_path, const Path& dst_port_path) -{ - const string& src_node_name = src_port_path.parent().name(); - const string& src_port_name = src_port_path.name(); - const string& dst_node_name = dst_port_path.parent().name(); - const string& dst_port_name = dst_port_path.name(); - - if (m_patch_view) { - Port* src_port = m_patch_view->canvas()->get_port(src_node_name, src_port_name); - Port* dst_port = m_patch_view->canvas()->get_port(dst_node_name, dst_port_name); - - if (src_port && dst_port) { - m_patch_view->canvas()->remove_connection(src_port, dst_port); - } - } - - //patch_model()->remove_connection(src_port_path, dst_port_path); - - cerr << "FIXME: disconnection\n"; - /* - // Enable control slider in destination node control window - PortController* p = (PortController)Store::instance().port(dst_port_path)->controller(); - assert(p); - - if (p->control_panel()) - p->control_panel()->enable_port(p->path()); - */ -} - - -/** Become the parent of the patch view. - * - * Steals the view away from whatever window is currently showing it. - */ -void -PatchController::claim_patch_view() -{ - assert(m_patch_view); - - m_patch_view->hide(); - m_patch_view->reparent(m_patch_view_bin); -} - - -void -PatchController::show_control_window() -{ - assert(patch_model()); - - if (m_control_window == NULL) - m_control_window = new NodeControlWindow(this, patch_model()->poly()); - - if (m_control_window->control_panel()->num_controls() > 0) - m_control_window->present(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchController.h b/src/progs/ingenuity/PatchController.h deleted file mode 100644 index e9c0d0b6..00000000 --- a/src/progs/ingenuity/PatchController.h +++ /dev/null @@ -1,124 +0,0 @@ -/* 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 - */ - -#ifndef PATCHCONTROLLER_H -#define PATCHCONTROLLER_H - -#include -#include -#include "util/CountedPtr.h" -#include "NodeController.h" -#include "PatchModel.h" - -namespace Ingen { namespace Client { - class PatchModel; - class NodeModel; - class PortModel; - class ControlModel; - class ConnectionModel; -} } - -using std::string; -using namespace Ingen::Client; - -namespace Ingenuity { - -class PatchWindow; -class SubpatchModule; -class Controller; -class OmFlowCanvas; -class NodeControlWindow; -class PatchPropertiesWindow; -class ControlPanel; -class PatchView; -class NodeController; - - -/** Controller for a patch. - * - * A patch is different from a port or node because there are two - * representations in the Gtk client - the window and the module in the parent - * patch (if applicable). So, this is a master class that contains both of - * those representations, and acts as the recipient of all patch related - * events (being the controller). - * - * \ingroup Ingenuity - */ -class PatchController : public NodeController -{ -public: - virtual ~PatchController(); - - /* - virtual void add_to_store(); - virtual void remove_from_store(); - */ - - virtual void metadata_update(const string& key, const string& value); - - //virtual void add_port(CountedPtr pm); - //virtual void remove_port(const Path& path, bool resize_module); - - void connection(CountedPtr cm); - void disconnection(const Path& src_port_path, const Path& dst_port_path); - //void clear(); - - void show_control_window(); - void show_properties_window(); - void show_patch_window(); - - void claim_patch_view(); - - void create_module(OmFlowCanvas* canvas); - - CountedPtr get_view(); - PatchWindow* window() const { return m_window; } - void window(PatchWindow* pw) { m_window = pw; } - - void set_path(const Path& new_path); - - //void enable(); - //void disable(); - - const CountedPtr patch_model() const { return m_patch_model; } - -private: - friend class ControllerFactory; - PatchController(CountedPtr model); - - void add_node(CountedPtr object); - - PatchPropertiesWindow* m_properties_window; - - // FIXME: remove these - PatchWindow* m_window; ///< Patch Window currently showing m_patch_view - CountedPtr m_patch_view; ///< View (canvas) of this patch - - CountedPtr m_patch_model; - - /** Invisible bin used to store patch view when not shown by a patch window */ - Gtk::Alignment m_patch_view_bin; - - // Coordinates for next added plugin (used by canvas menu) - // 0 means "not set", ie guess at the best location - int m_module_x; - int m_module_y; -}; - - -} // namespace Ingenuity - -#endif // PATCHCONTROLLER_H diff --git a/src/progs/ingenuity/PatchPropertiesWindow.cpp b/src/progs/ingenuity/PatchPropertiesWindow.cpp index 2271cc21..b6dd5e7f 100644 --- a/src/progs/ingenuity/PatchPropertiesWindow.cpp +++ b/src/progs/ingenuity/PatchPropertiesWindow.cpp @@ -41,20 +41,32 @@ PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib * the window in any way. */ void -PatchPropertiesWindow::patch_model(CountedPtr patch_model) +PatchPropertiesWindow::set_patch(CountedPtr patch_model) { property_title() = patch_model->path() + " Properties"; m_patch_model = patch_model; - m_author_entry->set_text(m_patch_model->get_metadata("author")); - m_textview->get_buffer()->set_text(m_patch_model->get_metadata("description")); + + const Atom& author_atom = m_patch_model->get_metadata("author"); + m_author_entry->set_text( + (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); + + const Atom& desc_atom = m_patch_model->get_metadata("description"); + m_textview->get_buffer()->set_text( + (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); } void PatchPropertiesWindow::cancel_clicked() { - m_author_entry->set_text(m_patch_model->get_metadata("author")); - m_textview->get_buffer()->set_text(m_patch_model->get_metadata("description")); + const Atom& author_atom = m_patch_model->get_metadata("author"); + m_author_entry->set_text( + (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); + + const Atom& desc_atom = m_patch_model->get_metadata("description"); + m_textview->get_buffer()->set_text( + (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); + hide(); } @@ -62,8 +74,8 @@ PatchPropertiesWindow::cancel_clicked() void PatchPropertiesWindow::ok_clicked() { - m_patch_model->set_metadata("author", m_author_entry->get_text()); - m_patch_model->set_metadata("description", m_textview->get_buffer()->get_text()); + m_patch_model->set_metadata("author", Atom(m_author_entry->get_text().c_str())); + m_patch_model->set_metadata("description", Atom(m_textview->get_buffer()->get_text().c_str())); hide(); } diff --git a/src/progs/ingenuity/PatchPropertiesWindow.h b/src/progs/ingenuity/PatchPropertiesWindow.h index 76f12061..4f5da674 100644 --- a/src/progs/ingenuity/PatchPropertiesWindow.h +++ b/src/progs/ingenuity/PatchPropertiesWindow.h @@ -40,7 +40,8 @@ class PatchPropertiesWindow : public Gtk::Window public: PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - void patch_model(CountedPtr patch_model); + void present(CountedPtr patch_model) { set_patch(patch_model); Gtk::Window::present(); } + void set_patch(CountedPtr patch_model); void cancel_clicked(); void ok_clicked(); diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp index 090aba18..40ce5baf 100644 --- a/src/progs/ingenuity/PatchTreeWindow.cpp +++ b/src/progs/ingenuity/PatchTreeWindow.cpp @@ -18,7 +18,6 @@ #include "ModelEngineInterface.h" #include "OSCEngineSender.h" #include "PatchTreeWindow.h" -#include "PatchController.h" #include "PatchWindow.h" #include "Store.h" #include "SubpatchModule.h" @@ -77,15 +76,13 @@ PatchTreeWindow::new_object(CountedPtr object) { CountedPtr patch = PtrCast(object); if (patch) - add_patch(PtrCast(patch->controller())); + add_patch(patch); } void -PatchTreeWindow::add_patch(CountedPtr pc) +PatchTreeWindow::add_patch(CountedPtr pm) { - const CountedPtr pm = pc->patch_model(); - if (!pm->parent()) { Gtk::TreeModel::iterator iter = m_patch_treestore->append(); Gtk::TreeModel::Row row = *iter; @@ -101,7 +98,7 @@ PatchTreeWindow::add_patch(CountedPtr pc) row[m_patch_tree_columns.name_col] = pm->path().name(); } row[m_patch_tree_columns.enabled_col] = false; - row[m_patch_tree_columns.patch_controller_col] = pc; + row[m_patch_tree_columns.patch_model_col] = pm; m_patches_treeview->expand_row(m_patch_treestore->get_path(iter), true); } else { Gtk::TreeModel::Children children = m_patch_treestore->children(); @@ -112,7 +109,7 @@ PatchTreeWindow::add_patch(CountedPtr pc) Gtk::TreeModel::Row row = *iter; row[m_patch_tree_columns.name_col] = pm->path().name(); row[m_patch_tree_columns.enabled_col] = false; - row[m_patch_tree_columns.patch_controller_col] = pc; + row[m_patch_tree_columns.patch_model_col] = pm; m_patches_treeview->expand_row(m_patch_treestore->get_path(iter), true); } } @@ -132,8 +129,8 @@ Gtk::TreeModel::iterator PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) { for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - CountedPtr pc = (*c)[m_patch_tree_columns.patch_controller_col]; - if (pc->model()->path() == path) { + CountedPtr pm = (*c)[m_patch_tree_columns.patch_model_col]; + if (pm->path() == path) { return c; } else if ((*c)->children().size() > 0) { Gtk::TreeModel::iterator ret = find_patch(c->children(), path); @@ -151,7 +148,7 @@ PatchTreeWindow::event_patch_selected() Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - CountedPtr pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr pm = row[m_patch_tree_columns.patch_model_col]; } } */ @@ -165,9 +162,10 @@ PatchTreeWindow::show_patch_menu(GdkEventButton* ev) Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - CountedPtr pc = row[m_patch_tree_columns.patch_controller_col]; - if (pc) - pc->show_menu(ev); + CountedPtr pm = row[m_patch_tree_columns.patch_model_col]; + if (pm) + cerr << "FIXME: patch menu\n"; + //pm->show_menu(ev); } } @@ -177,9 +175,10 @@ PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::Tr { Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path); Gtk::TreeModel::Row row = *active; - CountedPtr pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr pm = row[m_patch_tree_columns.patch_model_col]; - App::instance().window_factory()->present(pc); + cerr << "FIXME: tree win show\n"; + //App::instance().window_factory()->present(pc); } @@ -190,12 +189,12 @@ PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path); Gtk::TreeModel::Row row = *active; - CountedPtr pc = row[m_patch_tree_columns.patch_controller_col]; - Glib::ustring patch_path = pc->model()->path(); + CountedPtr pm = row[m_patch_tree_columns.patch_model_col]; + Glib::ustring patch_path = pm->path(); - assert(pc); + assert(pm); - if ( ! pc->patch_model()->enabled()) { + if ( ! pm->enabled()) { if (m_enable_signal) App::instance().engine()->enable_patch(patch_path); //pc->enable(); diff --git a/src/progs/ingenuity/PatchTreeWindow.h b/src/progs/ingenuity/PatchTreeWindow.h index d23c4e54..91e68bf1 100644 --- a/src/progs/ingenuity/PatchTreeWindow.h +++ b/src/progs/ingenuity/PatchTreeWindow.h @@ -29,7 +29,6 @@ using Ingen::Client::Store; namespace Ingenuity { class PatchWindow; -class PatchController; class PatchTreeView; @@ -50,7 +49,7 @@ public: void patch_disabled(const Path& path); void patch_renamed(const Path& old_path, const Path& new_path); - void add_patch(CountedPtr pc); + void add_patch(CountedPtr pm); void remove_patch(const Path& path); void show_patch_menu(GdkEventButton* ev); @@ -66,11 +65,11 @@ protected: struct PatchTreeModelColumns : public Gtk::TreeModel::ColumnRecord { PatchTreeModelColumns() - { add(name_col); add(enabled_col); add(patch_controller_col); } + { add(name_col); add(enabled_col); add(patch_model_col); } Gtk::TreeModelColumn name_col; Gtk::TreeModelColumn enabled_col; - Gtk::TreeModelColumn > patch_controller_col; + Gtk::TreeModelColumn > patch_model_col; }; bool m_enable_signal; diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp index 90c0083e..0ae82f45 100644 --- a/src/progs/ingenuity/PatchView.cpp +++ b/src/progs/ingenuity/PatchView.cpp @@ -21,7 +21,6 @@ #include "App.h" #include "ModelEngineInterface.h" #include "OmFlowCanvas.h" -#include "PatchController.h" #include "LoadPluginWindow.h" #include "PatchModel.h" #include "NewSubpatchWindow.h" @@ -29,13 +28,13 @@ #include "NodeControlWindow.h" #include "PatchPropertiesWindow.h" #include "PatchTreeWindow.h" +#include "GladeFactory.h" namespace Ingenuity { PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr& xml) : Gtk::Box(cobject), - _patch(NULL), _canvas(NULL), _breadcrumb_container(NULL), _enable_signal(true) @@ -56,23 +55,27 @@ PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr patch) { - _patch = pc; - _canvas = new OmFlowCanvas(pc, 1600*2, 1200*2); + cerr << "Creating view for " << patch->path() << endl; + + assert(_breadcrumb_container); // ensure created + + _patch = patch; + _canvas = new OmFlowCanvas(patch, 1600*2, 1200*2); _canvas_scrolledwindow->add(*_canvas); - _poly_spin->set_value(pc->patch_model()->poly()); - _destroy_but->set_sensitive(pc->path() != "/"); - //_description_window->patch_model(pc->model()); - + _poly_spin->set_value(patch->poly()); + _destroy_but->set_sensitive(patch->path() != "/"); + patch->enabled() ? enable() : disable(); + + // Connect model signals to track state + patch->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); + patch->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); - pc->patch_model()->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); - pc->patch_model()->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); - + // Connect widget signals to do things _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); - _clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked)); _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun( @@ -83,11 +86,22 @@ PatchView::patch_controller(PatchController* pc) } -void -PatchView::show_control_window() +PatchView::~PatchView() +{ + cerr << "Destroying view for " << _patch->path() << endl; +} + + +CountedPtr +PatchView::create(CountedPtr patch) + { - if (_patch != NULL) - _patch->show_control_window(); + const Glib::RefPtr& xml = GladeFactory::new_glade_reference("patch_view_box"); + PatchView* result = NULL; + xml->get_widget_derived("patch_view_box", result); + assert(result); + result->set_patch(patch); + return CountedPtr(result); } @@ -98,11 +112,11 @@ PatchView::process_toggled() return; if (_process_but->get_active()) { - App::instance().engine()->enable_patch(_patch->model()->path()); - App::instance().patch_tree()->patch_enabled(_patch->model()->path()); + App::instance().engine()->enable_patch(_patch->path()); + App::instance().patch_tree()->patch_enabled(_patch->path()); } else { - App::instance().engine()->disable_patch(_patch->model()->path()); - App::instance().patch_tree()->patch_disabled(_patch->model()->path()); + App::instance().engine()->disable_patch(_patch->path()); + App::instance().patch_tree()->patch_disabled(_patch->path()); } } diff --git a/src/progs/ingenuity/PatchView.h b/src/progs/ingenuity/PatchView.h index 59e16aad..a6484b97 100644 --- a/src/progs/ingenuity/PatchView.h +++ b/src/progs/ingenuity/PatchView.h @@ -21,12 +21,12 @@ #include #include #include +#include "util/CountedPtr.h" +#include "PatchModel.h" using std::string; namespace Ingen { namespace Client { - class PatchModel; - class NodeModel; class PortModel; class ControlModel; class MetadataModel; @@ -36,7 +36,6 @@ using namespace Ingen::Client; namespace Ingenuity { -class PatchController; class OmFlowCanvas; class LoadPluginWindow; class NewSubpatchWindow; @@ -56,28 +55,29 @@ class PatchView : public Gtk::Box { public: PatchView(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); - - void patch_controller(PatchController* pc); + ~PatchView(); + + OmFlowCanvas* canvas() const { return _canvas; } + CountedPtr patch() const { return _patch; } + Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } - OmFlowCanvas* canvas() const { return _canvas; } - PatchController* patch_controller() const { return _patch; } - Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } - void show_control_window(); + static CountedPtr create(CountedPtr patch); +private: + void set_patch(CountedPtr patch); + void process_toggled(); + void clear_clicked(); + void enable(); void disable(); void zoom_full(); -private: - void process_toggled(); - void clear_clicked(); - - PatchController* _patch; - OmFlowCanvas* _canvas; + CountedPtr _patch; + OmFlowCanvas* _canvas; - Gtk::ScrolledWindow* _canvas_scrolledwindow; + Gtk::ScrolledWindow* _canvas_scrolledwindow; Gtk::ToggleToolButton* _process_but; Gtk::SpinButton* _poly_spin; diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index c395c265..1aec1977 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -21,7 +21,6 @@ #include "App.h" #include "ModelEngineInterface.h" #include "OmFlowCanvas.h" -#include "PatchController.h" #include "LoadPluginWindow.h" #include "PatchModel.h" #include "NewSubpatchWindow.h" @@ -36,7 +35,6 @@ #include "Store.h" #include "ConnectWindow.h" #include "Loader.h" -#include "ControllerFactory.h" #include "WindowFactory.h" #include "PatchView.h" @@ -45,8 +43,6 @@ namespace Ingenuity { PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& xml) : Gtk::Window(cobject), - m_load_plugin_window(NULL), - m_new_subpatch_window(NULL), m_enable_signal(true), m_position_stored(false), m_x(0), @@ -75,17 +71,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtrget_widget("patch_view_messages_window_menuitem", m_menu_view_messages_window); xml->get_widget("patch_view_patch_tree_window_menuitem", m_menu_view_patch_tree_window); xml->get_widget("patch_help_about_menuitem", m_menu_help_about); - - // FIXME: these shouldn't be loaded here - xml->get_widget_derived("load_plugin_win", m_load_plugin_window); - xml->get_widget_derived("new_subpatch_win", m_new_subpatch_window); - xml->get_widget_derived("load_patch_win", m_load_patch_window); - xml->get_widget_derived("load_subpatch_win", m_load_subpatch_window); - - m_new_subpatch_window->set_transient_for(*this); - m_load_patch_window->set_transient_for(*this); - m_load_subpatch_window->set_transient_for(*this); - + m_menu_view_control_window->property_sensitive() = false; //m_status_bar->push(App::instance().engine()->engine_url()); //m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false); @@ -134,14 +120,10 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtrclaim_patch_view(); + //m_patch->claim_patch_view(); App::instance().remove_patch_window(this); - hide(); - - delete m_new_subpatch_window; - delete m_load_subpatch_window; delete m_breadcrumb_box; } @@ -149,84 +131,63 @@ PatchWindow::~PatchWindow() /** Set the patch controller from a Path (for use by eg. BreadCrumbBox) */ void -PatchWindow::set_patch_from_path(const Path& path) +PatchWindow::set_patch_from_path(const Path& path, CountedPtr view) { - CountedPtr model = PtrCast(App::instance().store()->object(path)); - if (!model) - return; // can't really do anything useful.. - - CountedPtr pc = PtrCast(ControllerFactory::get_controller(model)); - assert(pc); - - App::instance().window_factory()->present(pc, this); + if (view) { + assert(view->patch()->path() == path); + App::instance().window_factory()->present_patch(view->patch(), this, view); + } else { + CountedPtr model = PtrCast(App::instance().store()->object(path)); + if (model) + App::instance().window_factory()->present_patch(model, this); + } } /** Sets the patch controller for this window and initializes everything. * - * This function MUST be called before using the window in any way! + * If @a view is NULL, a new view will be created. */ void -PatchWindow::set_patch(CountedPtr pc) +PatchWindow::set_patch(CountedPtr patch, CountedPtr view) { - if (!pc || pc == m_patch) + if (!patch || patch == m_patch) return; m_enable_signal = false; - if (m_patch) { - CountedPtr old_pc = m_patch; - assert(old_pc->window() == NULL || old_pc->window() == this); - old_pc->claim_patch_view(); - old_pc->window(NULL); - } - - m_patch = pc; + m_patch = patch; - CountedPtr patch_view = pc->get_view(); - assert(patch_view); - patch_view->reparent(*m_viewport); + m_view = view ? view : PatchView::create(patch); + assert(m_view); + + m_viewport->remove(); + m_viewport->add(*m_view.get()); - if (m_breadcrumb_box->get_parent()) - m_breadcrumb_box->reparent(*patch_view->breadcrumb_container()); - else - patch_view->breadcrumb_container()->add(*m_breadcrumb_box); + m_view->breadcrumb_container()->remove(); + m_view->breadcrumb_container()->add(*m_breadcrumb_box); - m_breadcrumb_box->build(pc->model()->path()); + m_breadcrumb_box->build(patch->path(), m_view); m_breadcrumb_box->show(); - pc->window(this); - show_all(); - - assert(m_load_plugin_window != NULL); - assert(m_new_subpatch_window != NULL); - assert(m_load_patch_window != NULL); - assert(m_load_subpatch_window != NULL); - - m_load_patch_window->set_patch(m_patch); - m_load_plugin_window->set_patch(m_patch); - m_new_subpatch_window->set_patch(m_patch); - m_load_subpatch_window->set_patch(m_patch); - - m_menu_view_control_window->property_sensitive() = pc->has_control_inputs(); + show_all(); + + //m_menu_view_control_window->property_sensitive() = patch->has_control_inputs(); int width, height; get_size(width, height); - patch_view->canvas()->scroll_to( - ((int)patch_view->canvas()->width() - width)/2, - ((int)patch_view->canvas()->height() - height)/2); + m_view->canvas()->scroll_to( + ((int)m_view->canvas()->width() - width)/2, + ((int)m_view->canvas()->height() - height)/2); - set_title(m_patch->model()->path()); + set_title(m_patch->path()); //m_properties_window->patch_model(pc->patch_model()); - if (pc->model()->path() == "/") + if (patch->path() == "/") m_menu_destroy_patch->set_sensitive(false); else m_menu_destroy_patch->set_sensitive(true); - assert(m_patch == pc); - assert(m_patch->window() == this); - m_enable_signal = true; } @@ -242,45 +203,31 @@ PatchWindow::event_show_engine() void PatchWindow::event_show_controls() { - if (m_patch) - m_patch->show_control_window(); + App::instance().window_factory()->present_controls(m_patch); } void PatchWindow::event_show_properties() { - if (m_patch) - m_patch->show_properties_window(); + App::instance().window_factory()->present_properties(m_patch); } -/* -void -PatchWindow::event_open() -{ - m_load_patch_window->set_replace(); - m_load_patch_window->present(); -} -*/ - void PatchWindow::event_import() { - m_load_patch_window->set_merge(); - m_load_patch_window->present(); + App::instance().window_factory()->present_load_patch(m_patch); } void PatchWindow::event_save() { - CountedPtr model(m_patch->patch_model().get()); - - if (model->filename() == "") + if (m_patch->filename() == "") event_save_as(); else - App::instance().loader()->save_patch(model, model->filename(), false); + App::instance().loader()->save_patch(m_patch, m_patch->filename(), false); } @@ -301,7 +248,7 @@ PatchWindow::event_save_as() dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); // Set current folder to most sensible default - const string& current_filename = m_patch->patch_model()->filename(); + const string& current_filename = m_patch->filename(); if (current_filename.length() > 0) dialog.set_filename(current_filename); else if (App::instance().configuration()->patch_folder().length() > 0) @@ -335,8 +282,8 @@ PatchWindow::event_save_as() fin.close(); if (confirm) { - App::instance().loader()->save_patch(m_patch->patch_model(), filename, recursive); - m_patch->patch_model()->filename(filename); + App::instance().loader()->save_patch(m_patch, filename, recursive); + m_patch->filename(filename); } } App::instance().configuration()->set_patch_folder(dialog.get_current_folder()); @@ -367,10 +314,12 @@ bool PatchWindow::on_key_press_event(GdkEventKey* event) { if (event->keyval == GDK_Delete) { + cerr << "FIXME: delete key\n"; + /* if (m_patch && m_patch->get_view()) { assert(m_patch->get_view()->canvas()); m_patch->get_view()->canvas()->destroy_selected(); - } + }*/ return true; } else { return Gtk::Window::on_key_press_event(event); @@ -409,14 +358,14 @@ PatchWindow::event_quit() void PatchWindow::event_destroy() { - App::instance().engine()->destroy(m_patch->model()->path()); + App::instance().engine()->destroy(m_patch->path()); } void PatchWindow::event_clear() { - App::instance().engine()->clear_patch(m_patch->model()->path()); + App::instance().engine()->clear_patch(m_patch->path()); } void diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h index d538db78..2e0a388b 100644 --- a/src/progs/ingenuity/PatchWindow.h +++ b/src/progs/ingenuity/PatchWindow.h @@ -24,13 +24,15 @@ #include #include "util/Path.h" #include "util/CountedPtr.h" -#include "PatchController.h" +#include "PatchModel.h" +#include "PatchView.h" +using Ingen::Client::PatchModel; + using std::string; using std::list; namespace Ingen { namespace Client { class PatchModel; - class NodeModel; class PortModel; class ControlModel; class MetadataModel; @@ -40,7 +42,6 @@ using namespace Ingen::Client; namespace Ingenuity { -class PatchController; class OmFlowCanvas; class LoadPluginWindow; class LoadPatchWindow; @@ -64,13 +65,10 @@ public: PatchWindow(BaseObjectType* cobject, const Glib::RefPtr& glade_xml); ~PatchWindow(); - void set_patch_from_path(const Path& path); - void set_patch(CountedPtr pc); + void set_patch_from_path(const Path& path, CountedPtr view); + void set_patch(CountedPtr pc, CountedPtr view); - CountedPtr patch_controller() const { return m_patch; } - LoadPluginWindow* load_plugin_window() const { return m_load_plugin_window; } - LoadSubpatchWindow* load_subpatch_window() const { return m_load_subpatch_window; } - NewSubpatchWindow* new_subpatch_window() const { return m_new_subpatch_window; } + CountedPtr patch() const { return m_patch; } Gtk::MenuItem* menu_view_control_window() { return m_menu_view_control_window; } @@ -93,12 +91,8 @@ private: void event_show_controls(); void event_show_engine(); - CountedPtr m_patch; - - LoadPluginWindow* m_load_plugin_window; - LoadPatchWindow* m_load_patch_window; - NewSubpatchWindow* m_new_subpatch_window; - LoadSubpatchWindow* m_load_subpatch_window; + CountedPtr m_patch; + CountedPtr m_view; bool m_enable_signal; bool m_position_stored; diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp deleted file mode 100644 index 167cb594..00000000 --- a/src/progs/ingenuity/PortController.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* 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 "PortController.h" -#include "OmFlowCanvas.h" -#include "OmModule.h" -#include "PortModel.h" -#include "PatchModel.h" -#include "OmPort.h" -#include "OmPatchPort.h" -#include "Store.h" - -namespace Ingenuity { - - -PortController::PortController(CountedPtr model) -: GtkObjectController(model), - m_patch_port(NULL), - m_module(NULL), - m_port(NULL) -{ - assert(model); - assert(model->parent()); -} - - -void -PortController::destroy() -{ - assert(m_model->parent()); - CountedPtr parent = PtrCast(m_model->parent()->controller()); - assert(parent); - - parent->remove_port(path(), false); -} - - -void -PortController::create_module(OmFlowCanvas* canvas) -{ - //cerr << "Creating port module " << m_model->path() << endl; - - const string x_str = m_model->get_metadata("module-x"); - const string y_str = m_model->get_metadata("module-y"); - - double default_x; - double default_y; - canvas->get_new_module_location(default_x, default_y); - const double x = (x_str == "") ? default_x : atof(x_str.c_str()); - const double y = (y_str == "") ? default_y : atof(y_str.c_str()); - - assert(canvas); - assert(port_model()); - - if (m_module) - delete m_module; - - m_module = new OmPortModule(canvas, this, x, y); - - if (PtrCast(port_model()->parent())) { - if (m_patch_port) - delete m_patch_port; - - m_patch_port = new OmPatchPort(m_module, port_model()); - } - - m_module->resize(); - - m_module->move_to(x, y); // FIXME: redundant (?) -} - - -void -PortController::destroy_module() -{ - delete m_module; - m_module = NULL; -} - - -void -PortController::metadata_update(const string& key, const string& value) -{ - //cerr << "Metadata " << path() << ": " << key << " = " << value << endl; - - if (m_module != NULL) { - if (key == "module-x") { - float x = atof(value.c_str()); - //if (x > 0 && x < m_canvas->width()) - m_module->move_to(x, m_module->property_y().get_value()); - } else if (key == "module-y") { - float y = atof(value.c_str()); - //if (y > 0 && y < m_canvas->height()) - m_module->move_to(m_module->property_x().get_value(), y); - } - } - - GtkObjectController::metadata_update(key, value); -} - -void -PortController::set_path(const Path& new_path) -{ - // Change port name on module, if view exists - if (m_port != NULL) - m_port->set_name(new_path.name()); - - m_model->set_path(new_path); -} - - -/** Create the visible port on a canvas module. - * - * Does not resize the module, caller's responsibility to do so if necessary. - */ -void -PortController::create_port(OmModule* module) -{ - assert(module != NULL); - - new OmPort(module, port_model()); -} - - -} // namespace Ingenuity - diff --git a/src/progs/ingenuity/PortController.h b/src/progs/ingenuity/PortController.h deleted file mode 100644 index e28cd21d..00000000 --- a/src/progs/ingenuity/PortController.h +++ /dev/null @@ -1,79 +0,0 @@ -/* 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 - */ - -#ifndef PORTCONTROLLER_H -#define PORTCONTROLLER_H - -#include -#include -#include "GtkObjectController.h" -#include "OmPortModule.h" - -using std::string; -using namespace Ingen::Client; - -namespace Ingen { namespace Client { - class MetadataModel; - class PortModel; -} } - -namespace Ingenuity { - -class Controller; -class OmPort; -class OmPatchPort; -class OmModule; -class OmPortModule; -class OmFlowCanvas; - - -/** Controller for a port on a (non-patch) node. - * - * \ingroup Ingenuity - */ -class PortController : public GtkObjectController -{ -public: - virtual ~PortController() {} - - virtual void destroy(); - - virtual void create_module(OmFlowCanvas* canvas); - virtual void destroy_module(); - OmPortModule* module() { return m_module; } - - virtual void metadata_update(const string& key, const string& value); - - void create_port(OmModule* module); - void destroy_port(); - - void set_path(const Path& new_path); - - CountedPtr port_model() const { return PtrCast(m_model); } - -private: - friend class ControllerFactory; - PortController(CountedPtr model); - - OmPatchPort* m_patch_port; ///< Port on m_module - OmPortModule* m_module; ///< Port pseudo-module (for patch ports only) - OmPort* m_port; ///< Port on some other canvas module -}; - - -} // namespace Ingenuity - -#endif // PORTCONTROLLER_H diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp index 7a458e31..37d4fc39 100644 --- a/src/progs/ingenuity/RenameWindow.cpp +++ b/src/progs/ingenuity/RenameWindow.cpp @@ -18,7 +18,6 @@ #include #include #include "ObjectModel.h" -#include "GtkObjectController.h" #include "Store.h" #include "App.h" #include "ModelEngineInterface.h" @@ -47,7 +46,7 @@ RenameWindow::RenameWindow(BaseObjectType* cobject, const Glib::RefPtr object) { m_object = object; m_name_entry->set_text(object->path().name()); @@ -62,15 +61,15 @@ RenameWindow::name_changed() { assert(m_name_entry); assert(m_message_label); - assert(m_object->model()); - assert(m_object->model()->parent()); + assert(m_object); + assert(m_object->parent()); string name = m_name_entry->get_text(); if (name.find("/") != string::npos) { m_message_label->set_text("Name may not contain '/'"); m_ok_button->property_sensitive() = false; //} else if (m_object->parent()->patch_model()->get_node(name) != NULL) { - } else if (App::instance().store()->object(m_object->model()->parent()->path().base() + name)) { + } else if (App::instance().store()->object(m_object->parent()->path().base() + name)) { m_message_label->set_text("An object already exists with that name."); m_ok_button->property_sensitive() = false; } else if (name.length() == 0) { @@ -105,7 +104,7 @@ RenameWindow::ok_clicked() assert(name.length() > 0); assert(name.find("/") == string::npos); - App::instance().engine()->rename(m_object->model()->path(), name); + App::instance().engine()->rename(m_object->path(), name); hide(); } diff --git a/src/progs/ingenuity/RenameWindow.h b/src/progs/ingenuity/RenameWindow.h index af826f15..fe342100 100644 --- a/src/progs/ingenuity/RenameWindow.h +++ b/src/progs/ingenuity/RenameWindow.h @@ -19,16 +19,14 @@ #include #include - +#include "util/CountedPtr.h" +#include "ObjectModel.h" +using Ingen::Client::ObjectModel; namespace Ingenuity { -class GtkObjectController; - -/** 'New Patch' Window. - * - * Loaded by libglade as a derived object. +/** Rename window. Handles renaming of any (Ingen) object. * * \ingroup Ingenuity */ @@ -37,14 +35,16 @@ class RenameWindow : public Gtk::Window public: RenameWindow(BaseObjectType* cobject, const Glib::RefPtr& refGlade); - void set_object(GtkObjectController* object); + void present(CountedPtr object) { set_object(object); Gtk::Window::present(); } private: + void set_object(CountedPtr object); + void name_changed(); void cancel_clicked(); void ok_clicked(); - GtkObjectController* m_object; + CountedPtr m_object; Gtk::Entry* m_name_entry; Gtk::Label* m_message_label; diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp index 598cc9db..47465b09 100644 --- a/src/progs/ingenuity/SubpatchModule.cpp +++ b/src/progs/ingenuity/SubpatchModule.cpp @@ -24,7 +24,6 @@ #include "PatchModel.h" #include "PatchWindow.h" #include "OmFlowCanvas.h" -#include "PatchController.h" #include "OmPort.h" #include "WindowFactory.h" using std::cerr; using std::cout; using std::endl; @@ -32,8 +31,8 @@ using std::cerr; using std::cout; using std::endl; namespace Ingenuity { -SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr patch) -: OmModule(canvas, patch.get()), +SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr patch) +: OmModule(canvas, patch), m_patch(patch) { assert(canvas); @@ -46,12 +45,13 @@ SubpatchModule::on_double_click(GdkEventButton* event) { assert(m_patch); - CountedPtr parent = PtrCast(m_patch->model()->parent()->controller()); + CountedPtr parent = PtrCast(m_patch->parent()); - PatchWindow* const preferred - = (event->state & GDK_SHIFT_MASK) ? NULL : parent->window(); + PatchWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK)) + ? NULL + : App::instance().window_factory()->patch_window(parent) ); - App::instance().window_factory()->present(m_patch, preferred); + App::instance().window_factory()->present_patch(m_patch, preferred); } @@ -62,10 +62,15 @@ SubpatchModule::on_double_click(GdkEventButton* event) void SubpatchModule::browse_to_patch() { - assert(m_patch->model()->parent()); - CountedPtr pc = PtrCast(m_patch->model()->parent()->controller()); + assert(m_patch->parent()); - App::instance().window_factory()->present(m_patch, pc->window()); + CountedPtr parent = PtrCast(m_patch->parent()); + + PatchWindow* const preferred = ( (parent) + ? App::instance().window_factory()->patch_window(parent) + : NULL ); + + App::instance().window_factory()->present_patch(m_patch, preferred); } @@ -73,14 +78,15 @@ SubpatchModule::browse_to_patch() void SubpatchModule::show_dialog() { - m_patch->show_control_window(); + cerr << "FIXME: dialog\n"; + //m_patch->show_control_window(); } void SubpatchModule::menu_remove() { - App::instance().engine()->destroy(m_patch->model()->path()); + App::instance().engine()->destroy(m_patch->path()); } } // namespace Ingenuity diff --git a/src/progs/ingenuity/SubpatchModule.h b/src/progs/ingenuity/SubpatchModule.h index a8e6e971..0f52ae2b 100644 --- a/src/progs/ingenuity/SubpatchModule.h +++ b/src/progs/ingenuity/SubpatchModule.h @@ -22,7 +22,7 @@ #include #include "OmModule.h" #include "util/CountedPtr.h" -#include "PatchController.h" +#include "PatchModel.h" using std::string; using std::list; namespace Ingen { namespace Client { @@ -46,7 +46,7 @@ class NodeControlWindow; class SubpatchModule : public OmModule { public: - SubpatchModule(OmFlowCanvas* canvas, CountedPtr controller); + SubpatchModule(OmFlowCanvas* canvas, CountedPtr controller); virtual ~SubpatchModule() {} void on_double_click(GdkEventButton* ev); @@ -55,10 +55,10 @@ public: void browse_to_patch(); void menu_remove(); - CountedPtr patch() { return m_patch; } + CountedPtr patch() { return m_patch; } protected: - CountedPtr m_patch; + CountedPtr m_patch; }; diff --git a/src/progs/ingenuity/WindowFactory.cpp b/src/progs/ingenuity/WindowFactory.cpp index c7d79aca..3edbf568 100644 --- a/src/progs/ingenuity/WindowFactory.cpp +++ b/src/progs/ingenuity/WindowFactory.cpp @@ -15,13 +15,70 @@ */ #include "WindowFactory.h" +#include "App.h" #include "PatchWindow.h" #include "GladeFactory.h" -#include "App.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 @@ -29,54 +86,55 @@ namespace Ingenuity { * @a preferred left unmodified. */ void -WindowFactory::present(CountedPtr patch, PatchWindow* preferred) +WindowFactory::present_patch(CountedPtr patch, PatchWindow* preferred, CountedPtr view) { - std::map::iterator w = _windows.find(patch->model()->path()); + assert( !view || view->patch() == patch); + + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - if (w != _windows.end()) { + if (w != _patch_windows.end()) { (*w).second->present(); } else if (preferred) { - w = _windows.find(preferred->patch_controller()->model()->path()); + w = _patch_windows.find(preferred->patch()->path()); assert((*w).second == preferred); - preferred->set_patch(patch); - _windows.erase(w); - _windows[patch->model()->path()] = preferred; + preferred->set_patch(patch, view); + _patch_windows.erase(w); + _patch_windows[patch->path()] = preferred; preferred->present(); } else { - PatchWindow* win = create_new(patch); + PatchWindow* win = new_patch_window(patch, view); win->present(); } } PatchWindow* -WindowFactory::create_new(CountedPtr patch) +WindowFactory::new_patch_window(CountedPtr patch, CountedPtr view) { - // FIXME: can't just load "patch_win" and children because PatchWindow - // loads things it really shouldn't. - //Glib::RefPtr xml = GladeFactory::new_glade_reference("patch_win"); - Glib::RefPtr xml = GladeFactory::new_glade_reference(); + 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); - _windows[patch->model()->path()] = 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), win)); + sigc::mem_fun(this, &WindowFactory::remove_patch_window), win)); return win; } bool -WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored) +WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored) { - if (_windows.size() <= 1) { + 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?", @@ -90,15 +148,145 @@ WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored) return false; } - std::map::iterator w - = _windows.find(win->patch_controller()->model()->path()); + 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); - _windows.erase(w); + _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 diff --git a/src/progs/ingenuity/WindowFactory.h b/src/progs/ingenuity/WindowFactory.h index add2d97b..831ab646 100644 --- a/src/progs/ingenuity/WindowFactory.h +++ b/src/progs/ingenuity/WindowFactory.h @@ -18,23 +18,69 @@ #define WINDOW_FACTORY_H #include +#include #include "util/CountedPtr.h" -#include "PatchController.h" +#include "PatchView.h" +#include "PatchModel.h" +using Ingen::Client::PatchModel; namespace Ingenuity { class PatchWindow; +class NodeControlWindow; +class NodePropertiesWindow; +class PatchPropertiesWindow; +class LoadPatchWindow; +class RenameWindow; +/** Manager/Factory for all windows. + * + * This serves as a nice centralized spot for all window management issues, + * as well as an enumeration of all the windows in Ingenuity (the goal being + * to reduce that number as much as possible). + */ class WindowFactory { public: - void present(CountedPtr patch, PatchWindow* preferred = NULL); + WindowFactory(); + ~WindowFactory(); + + PatchWindow* patch_window(CountedPtr patch); + NodeControlWindow* control_window(CountedPtr node); + + void present_patch(CountedPtr patch, + PatchWindow* preferred = NULL, + CountedPtr patch = CountedPtr()); + + void present_controls(CountedPtr node); + + void present_load_plugin(CountedPtr patch, MetadataMap data = MetadataMap()); + void present_load_patch(CountedPtr patch, MetadataMap data = MetadataMap()); + void present_new_subpatch(CountedPtr patch, MetadataMap data = MetadataMap()); + void present_load_subpatch(CountedPtr patch, MetadataMap data = MetadataMap()); + void present_rename(CountedPtr object); + void present_properties(CountedPtr node); private: - PatchWindow* create_new(CountedPtr patch); - bool remove(PatchWindow* win, GdkEventAny* ignored); + typedef std::map PatchWindowMap; + typedef std::map ControlWindowMap; + + PatchWindow* new_patch_window(CountedPtr patch, CountedPtr view); + bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored); + + NodeControlWindow* new_control_window(CountedPtr node); + bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored); + + PatchWindowMap _patch_windows; + ControlWindowMap _control_windows; - std::map _windows; + LoadPluginWindow* _load_plugin_win; + LoadPatchWindow* _load_patch_win; + NewSubpatchWindow* _new_subpatch_win; + LoadSubpatchWindow* _load_subpatch_win; + NodePropertiesWindow* _node_properties_win; + PatchPropertiesWindow* _patch_properties_win; + RenameWindow* _rename_win; }; } diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade index 2221a805..7f18f954 100644 --- a/src/progs/ingenuity/ingenuity.glade +++ b/src/progs/ingenuity/ingenuity.glade @@ -1758,7 +1758,7 @@ - + True False 0 -- cgit v1.2.1