diff options
Diffstat (limited to 'src/progs')
66 files changed, 1337 insertions, 2198 deletions
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 <iostream> -using std::cerr; using std::endl; - #include <gtkmm.h> #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<PatchView> view = CountedPtr<PatchView>()) + : _path(path) + , _view(view) { + assert( !view || view->patch()->path() == path); set_border_width(0); set_path(path); show_all(); } + void set_view(CountedPtr<PatchView> view) { + assert( !view || view->patch()->path() == _path); + _view = view; + } + + const Path& path() const { return _path; } + CountedPtr<PatchView> 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<PatchView> _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<PatchView> 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<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - (*i)->set_active( ((*i)->path() == path) ); + for (std::list<BreadCrumb*>::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<PatchView> view) +{ + BreadCrumb* but = manage(new BreadCrumb(path, + (view && path == view->patch()->path()) ? view : CountedPtr<PatchView>())); + + 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 <libglademm/xml.h> #include <libglademm.h> #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<PatchView> view); - sigc::signal<void, const Path&> signal_patch_selected; + sigc::signal<void, const Path&, CountedPtr<PatchView> > signal_patch_selected; private: + BreadCrumb* create_crumb(const Path& path, + CountedPtr<PatchView> view = CountedPtr<PatchView>()); + 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 <cassert> #include <algorithm> #include <cctype> -#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 <map> #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<PatchModel> root = PtrCast<PatchModel>(App::instance().store()->object("/")); assert(root); - CountedPtr<PatchController> root_c = PtrCast<PatchController>(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<PortModel> 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, CountedPtr<PortModel m_max_spinner(1.0, (pm->is_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, CountedPtr<PortModel m_value_spinner.signal_value_changed().connect( sigc::mem_fun(*this, &SliderControlGroup::update_value_from_spinner)); m_min_spinner.set_range(-99999, 99999); - m_min_spinner.set_value(m_port_model->user_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, CountedPtr<PortModel pack_start(m_header_box, false, false, 0); pack_start(m_slider_box, false, false, 0); - m_slider.set_range(m_port_model->user_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<PortModel> 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<NodeModel> node, size_t poly) { assert(node != NULL); assert(poly > 0); - const CountedPtr<NodeModel> 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 <utility> // 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<Gnome::Glade::Xml>& glade_xml); virtual ~ControlPanel(); - void init(NodeController* node, size_t poly); + void init(CountedPtr<NodeModel> 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<GtkObjectController> -ControllerFactory::get_controller(CountedPtr<ObjectModel> model) -{ - CountedPtr<PatchModel> patch_m = PtrCast<PatchModel>(model); - if (patch_m && patch_m->controller()) { - assert(dynamic_cast<PatchController*>(patch_m->controller().get())); - return PtrCast<GtkObjectController>(patch_m->controller()); - } else if (patch_m) { - CountedPtr<PatchController> pc(new PatchController(patch_m)); - patch_m->set_controller(pc); - return pc; - } - - CountedPtr<NodeModel> node_m = PtrCast<NodeModel>(model); - if (node_m && node_m->controller()) { - assert(dynamic_cast<NodeController*>(node_m->controller().get())); - return PtrCast<GtkObjectController>(node_m->controller()); - } else if (node_m) { - if (node_m->plugin()->type() == PluginModel::DSSI) { - CountedPtr<NodeController> nc(new DSSIController(node_m)); - node_m->set_controller(nc); - return nc; - } else { - CountedPtr<NodeController> nc(new NodeController(node_m)); - node_m->set_controller(nc); - return nc; - } - } - - CountedPtr<PortModel> port_m = PtrCast<PortModel>(model); - if (port_m && port_m->controller()) { - assert(dynamic_cast<PortController*>(port_m->controller().get())); - return PtrCast<GtkObjectController>(port_m->controller()); - } else if (port_m) { - CountedPtr<PortController> pc(new PortController(port_m)); - port_m->set_controller(pc); - return pc; - } - - return CountedPtr<GtkObjectController>(); -} - - -} // 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<GtkObjectController> get_controller(CountedPtr<ObjectModel> 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<NodeModel> 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<NodeModel> 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 <string> #include <gtkmm.h> #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<NodeModel> 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<NodeController*>(node)) +DSSIModule::DSSIModule(OmFlowCanvas* canvas, CountedPtr<NodeModel> 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<DSSIController*>(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<NodeModel> 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<ObjectModel> 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 <string> -#include <gtkmm.h> - -#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<ObjectModel> 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<ObjectModel> model() const { return m_model; } - -protected: - CountedPtr<ObjectModel> 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 <sys/stat.h> #include <sys/types.h> #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 <dirent.h> #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<Gno } +void +LoadPatchWindow::present(CountedPtr<PatchModel> 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<PatchController> pc) +LoadPatchWindow::set_patch(CountedPtr<PatchModel> 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<PatchModel> pm(new PatchModel(m_patch_controller->model()->path(), poly)); + CountedPtr<PatchModel> 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 <libglademm/xml.h> #include <gtkmm.h> #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<Gnome::Glade::Xml>& xml); - void set_patch(CountedPtr<PatchController> pc); + void set_patch(CountedPtr<PatchModel> patch); void set_replace() { m_replace = true; } void set_merge() { m_replace = false; } + void present(CountedPtr<PatchModel> patch, MetadataMap data); + protected: void on_show(); @@ -58,8 +60,10 @@ private: void ok_clicked(); void cancel_clicked(); - CountedPtr<PatchController> m_patch_controller; - bool m_replace; + MetadataMap m_initial_data; + + CountedPtr<PatchModel> 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 <cassert> #include <algorithm> #include <cctype> -#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<G } +void +LoadPluginWindow::present(CountedPtr<PatchModel> 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<PatchController> pc) +LoadPluginWindow::set_patch(CountedPtr<PatchModel> 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 <libglademm.h> #include <gtkmm.h> #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<Gnome::Glade::Xml>& xml); - void set_patch(CountedPtr<PatchController> pc); + void set_patch(CountedPtr<PatchModel> patch); void set_plugin_list(const std::map<string, CountedPtr<PluginModel> >& m); - void set_next_module_location(double x, double y) - { m_new_module_x = x; m_new_module_y = y; } - void add_plugin(CountedPtr<PluginModel> plugin); bool has_shown() const { return m_has_shown; } + void present(CountedPtr<PatchModel> 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<PatchController> m_patch_controller; + MetadataMap m_initial_data; + + CountedPtr<PatchModel> m_patch; + bool m_has_shown; // plugin list only populated on show to speed patch window creation Glib::RefPtr<Gtk::ListStore> 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 <dirent.h> #include <cassert> #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<PatchModel> 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<PatchController> pc) +LoadSubpatchWindow::set_patch(CountedPtr<PatchModel> 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<PatchModel> pm(new PatchModel(m_patch_controller->model()->path().base() + name, poly)); + CountedPtr<PatchModel> 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 <libglademm/xml.h> #include <gtkmm.h> #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<Gnome::Glade::Xml>& xml); - void set_patch(CountedPtr<PatchController> pc); + void set_patch(CountedPtr<PatchModel> patch); - void set_next_module_location(double x, double y) - { m_new_module_x = x; m_new_module_y = y; } + void present(CountedPtr<PatchModel> patch, MetadataMap data); protected: void on_show(); @@ -58,7 +55,9 @@ private: void ok_clicked(); void cancel_clicked(); - CountedPtr<PatchController> m_patch_controller; + MetadataMap m_initial_data; + + CountedPtr<PatchModel> 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 <string> #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<PatchModel> 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<PatchController> pc) +NewSubpatchWindow::set_patch(CountedPtr<PatchModel> 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 <libglademm/xml.h> #include <gtkmm.h> #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<Gnome::Glade::Xml>& xml); - void set_patch(CountedPtr<PatchController> pc); + void set_patch(CountedPtr<PatchModel> patch); + + void present(CountedPtr<PatchModel> 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<PatchController> m_patch_controller; + MetadataMap m_initial_data; + CountedPtr<PatchModel> 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<NodeModel> 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<NodeModel> 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 <gtkmm.h> #include <libglademm.h> #include <sigc++/sigc++.h> +#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<NodeModel> node, size_t poly); + NodeControlWindow(CountedPtr<NodeModel> node, ControlPanel* panel); virtual ~NodeControlWindow(); + CountedPtr<NodeModel> 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<NodeModel> 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 <iostream> -#include <gtkmm.h> -#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<NodeModel> 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<PortController> pc = PtrCast<PortController>(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<ObjectModel> 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<PortModel*>::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<PortModel> 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<PortController> pc = PtrCast<PortController>(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<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("rename_win"); - xml->get_widget_derived("rename_win", win); - - CountedPtr<PatchController> parent = PtrCast<PatchController>(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<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller()); - assert(parent); - - if (m_properties_window) { - Glib::RefPtr<Gnome::Glade::Xml> 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<PortController> pc = PtrCast<PortController>(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 <string> -#include <gtkmm.h> -#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<NodeModel> node_model() { return PtrCast<NodeModel>(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<NodeModel> model); - - virtual void destroy(); - - virtual void add_port(CountedPtr<PortModel> 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<Gtk::MenuItem> 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 <iostream> +#include <gtkmm.h> +#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<NodeModel> 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<ObjectModel> 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<PortModel*>::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<PortModel> 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 <string> +#include <gtkmm.h> +#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<NodeModel> 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<PortModel> pm); + + void on_menu_destroy(); + void on_menu_clone(); + void on_menu_learn(); + void on_menu_disconnect_all(); + + //Gtk::Menu m_menu; + CountedPtr<NodeModel> _node; + Glib::RefPtr<Gtk::MenuItem> _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 <gtkmm.h> #include <libglademm.h> #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<Gnome::Glade::Xml>& refGlade); + void present(CountedPtr<NodeModel> node_model) { set_node(node_model); Gtk::Window::present(); } void set_node(CountedPtr<NodeModel> 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 <flowcanvas/FlowCanvas.h> #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<PatchModel> 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<Gnome::Glade::Xml> 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,6 +76,13 @@ 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)); @@ -89,6 +90,100 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height) 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<CountedPtr<ConnectionModel> >::const_iterator i = m_patch->connections().begin(); + i != m_patch->connections().end(); ++i) { + connection(*i); + } +} + + +void +OmFlowCanvas::add_node(CountedPtr<NodeModel> nm) +{ + cerr << "FIXME: MODULE LEAK!" << endl; + + CountedPtr<PatchModel> pm = PtrCast<PatchModel>(nm); + if (pm) + new SubpatchModule(this, pm); + else + new OmModule(this, nm); +} + + +void +OmFlowCanvas::remove_node(CountedPtr<NodeModel> nm) +{ + LibFlowCanvas::Module* module = get_module(nm->path().name()); + delete module; +} + + +void +OmFlowCanvas::connection(CountedPtr<ConnectionModel> 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) { assert(src_port != NULL); @@ -102,10 +197,12 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) dst->model()->type() == PortModel::CONTROL) { CountedPtr<PluginModel> pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); - CountedPtr<NodeModel> 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<NodeModel> 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 <string> #include <flowcanvas/FlowCanvas.h> - +#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<PatchModel> 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<NodeModel> nm); + void remove_node(CountedPtr<NodeModel> nm); + void connection(CountedPtr<ConnectionModel> 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<PatchModel> 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 <cassert> +#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<NodeModel> 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<PortModel> port) +{ + new OmPort(this, port); + resize(); +} + + +void +OmModule::remove_port(CountedPtr<PortModel> 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<float>(property_x()); + const float y = static_cast<float>(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 <string> #include <libgnomecanvasmm.h> #include <flowcanvas/Module.h> +#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<NodeModel> 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<NodeModel> 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<PortModel> port); + void remove_port(CountedPtr<PortModel> port); + + CountedPtr<NodeModel> 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<PortModel> 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<PatchModel>(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 <string> #include <libgnomecanvasmm.h> #include <flowcanvas/Module.h> -#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<PortModel> 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<PortModel> 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<PortModel> 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 <cassert> -#include <cstdlib> -#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<PatchModel> 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<NodeController> 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<NodeController> 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<NodeController> nc = PtrCast<NodeController>(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<GtkObjectController> pc = PtrCast<GtkObjectController>((*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<PatchController> parent = PtrCast<PatchController>(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<PatchController>(m_model->controller())); - create_all_ports(); - } - - m_module->move_to(node_model()->x(), node_model()->y()); -} - - -CountedPtr<PatchView> -PatchController::get_view() -{ - if (m_patch_view) - return m_patch_view; - - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - - PatchView* pv = NULL; - xml->get_widget_derived("patch_view_vbox", pv); - assert(pv); - m_patch_view = CountedPtr<PatchView>(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<NodeModel> 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<NodeController> nc = PtrCast<NodeController>(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<PortController> pc = PtrCast<PortController>((*i)->controller()); - assert(pc); - pc->create_module(m_patch_view->canvas()); - } - - - // Create connections - for (list<CountedPtr<ConnectionModel> >::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<Gnome::Glade::Xml> 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<ConnectionModel> 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<NodeModel> 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<NodeController> nc = PtrCast<NodeController>(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<PortModel> 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<PortController> 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 <string> -#include <gtkmm.h> -#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<PortModel> pm); - //virtual void remove_port(const Path& path, bool resize_module); - - void connection(CountedPtr<ConnectionModel> 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<PatchView> 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<PatchModel> patch_model() const { return m_patch_model; } - -private: - friend class ControllerFactory; - PatchController(CountedPtr<PatchModel> model); - - void add_node(CountedPtr<NodeModel> object); - - PatchPropertiesWindow* m_properties_window; - - // FIXME: remove these - PatchWindow* m_window; ///< Patch Window currently showing m_patch_view - CountedPtr<PatchView> m_patch_view; ///< View (canvas) of this patch - - CountedPtr<PatchModel> 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<PatchModel> patch_model) +PatchPropertiesWindow::set_patch(CountedPtr<PatchModel> 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<Gnome::Glade::Xml>& refGlade); - void patch_model(CountedPtr<PatchModel> patch_model); + void present(CountedPtr<PatchModel> patch_model) { set_patch(patch_model); Gtk::Window::present(); } + void set_patch(CountedPtr<PatchModel> 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<ObjectModel> object) { CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object); if (patch) - add_patch(PtrCast<PatchController>(patch->controller())); + add_patch(patch); } void -PatchTreeWindow::add_patch(CountedPtr<PatchController> pc) +PatchTreeWindow::add_patch(CountedPtr<PatchModel> pm) { - const CountedPtr<PatchModel> 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<PatchController> 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<PatchController> 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<PatchController> pc = (*c)[m_patch_tree_columns.patch_controller_col]; - if (pc->model()->path() == path) { + CountedPtr<PatchModel> 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<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchModel> 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<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; - if (pc) - pc->show_menu(ev); + CountedPtr<PatchModel> 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<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchModel> 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<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; - Glib::ustring patch_path = pc->model()->path(); + CountedPtr<PatchModel> 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<PatchController> pc); + void add_patch(CountedPtr<PatchModel> 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<Glib::ustring> name_col; Gtk::TreeModelColumn<bool> enabled_col; - Gtk::TreeModelColumn<CountedPtr<PatchController> > patch_controller_col; + Gtk::TreeModelColumn<CountedPtr<PatchModel> > 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<Gnome::Glade::Xml>& 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<Gnome::Glade::X void -PatchView::patch_controller(PatchController* pc) +PatchView::set_patch(CountedPtr<PatchModel> 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> +PatchView::create(CountedPtr<PatchModel> patch) + { - if (_patch != NULL) - _patch->show_control_window(); + const Glib::RefPtr<Gnome::Glade::Xml>& 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<PatchView>(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 <gtkmm.h> #include <libglademm/xml.h> #include <libglademm.h> +#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<Gnome::Glade::Xml>& glade_xml); - - void patch_controller(PatchController* pc); + ~PatchView(); + + OmFlowCanvas* canvas() const { return _canvas; } + CountedPtr<PatchModel> 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<PatchView> create(CountedPtr<PatchModel> patch); +private: + void set_patch(CountedPtr<PatchModel> 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<PatchModel> _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<Gnome::Glade::Xml>& 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::RefPtr<Gnome::Glad xml->get_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::RefPtr<Gnome::Glad PatchWindow::~PatchWindow() { // Prevents deletion - m_patch->claim_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<PatchView> view) { - CountedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path)); - if (!model) - return; // can't really do anything useful.. - - CountedPtr<PatchController> pc = PtrCast<PatchController>(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<PatchModel> model = PtrCast<PatchModel>(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<PatchController> pc) +PatchWindow::set_patch(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view) { - if (!pc || pc == m_patch) + if (!patch || patch == m_patch) return; m_enable_signal = false; - if (m_patch) { - CountedPtr<PatchController> 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<PatchView> 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<PatchModel> 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 <libglademm.h> #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<Gnome::Glade::Xml>& glade_xml); ~PatchWindow(); - void set_patch_from_path(const Path& path); - void set_patch(CountedPtr<PatchController> pc); + void set_patch_from_path(const Path& path, CountedPtr<PatchView> view); + void set_patch(CountedPtr<PatchModel> pc, CountedPtr<PatchView> view); - CountedPtr<PatchController> 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<PatchModel> 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<PatchController> m_patch; - - LoadPluginWindow* m_load_plugin_window; - LoadPatchWindow* m_load_patch_window; - NewSubpatchWindow* m_new_subpatch_window; - LoadSubpatchWindow* m_load_subpatch_window; + CountedPtr<PatchModel> m_patch; + CountedPtr<PatchView> 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<PortModel> 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<NodeController> parent = PtrCast<NodeController>(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<PatchModel>(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 <string> -#include <gtkmm.h> -#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<PortModel> port_model() const { return PtrCast<PortModel>(m_model); } - -private: - friend class ControllerFactory; - PortController(CountedPtr<PortModel> 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 <cassert> #include <string> #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<Gnome::Gl * This function MUST be called before using this object in any way. */ void -RenameWindow::set_object(GtkObjectController* object) +RenameWindow::set_object(CountedPtr<ObjectModel> 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 <gtkmm.h> #include <libglademm.h> - +#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<Gnome::Glade::Xml>& refGlade); - void set_object(GtkObjectController* object); + void present(CountedPtr<ObjectModel> object) { set_object(object); Gtk::Window::present(); } private: + void set_object(CountedPtr<ObjectModel> object); + void name_changed(); void cancel_clicked(); void ok_clicked(); - GtkObjectController* m_object; + CountedPtr<ObjectModel> 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<PatchController> patch) -: OmModule(canvas, patch.get()), +SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchModel> patch) +: OmModule(canvas, patch), m_patch(patch) { assert(canvas); @@ -46,12 +45,13 @@ SubpatchModule::on_double_click(GdkEventButton* event) { assert(m_patch); - CountedPtr<PatchController> parent = PtrCast<PatchController>(m_patch->model()->parent()->controller()); + CountedPtr<PatchModel> parent = PtrCast<PatchModel>(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<PatchController> pc = PtrCast<PatchController>(m_patch->model()->parent()->controller()); + assert(m_patch->parent()); - App::instance().window_factory()->present(m_patch, pc->window()); + CountedPtr<PatchModel> parent = PtrCast<PatchModel>(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 <libgnomecanvasmm.h> #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<PatchController> controller); + SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchModel> controller); virtual ~SubpatchModule() {} void on_double_click(GdkEventButton* ev); @@ -55,10 +55,10 @@ public: void browse_to_patch(); void menu_remove(); - CountedPtr<PatchController> patch() { return m_patch; } + CountedPtr<PatchModel> patch() { return m_patch; } protected: - CountedPtr<PatchController> m_patch; + CountedPtr<PatchModel> 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<Gnome::Glade::Xml> 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<PatchModel> patch) +{ + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); + + return (w == _patch_windows.end()) ? NULL : w->second; +} + + +NodeControlWindow* +WindowFactory::control_window(CountedPtr<NodeModel> 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<PatchController> patch, PatchWindow* preferred) +WindowFactory::present_patch(CountedPtr<PatchModel> patch, PatchWindow* preferred, CountedPtr<PatchView> view) { - std::map<Path, PatchWindow*>::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<PatchController> patch) +WindowFactory::new_patch_window(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view) { - // FIXME: can't just load "patch_win" and children because PatchWindow - // loads things it really shouldn't. - //Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("patch_win"); - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); + assert( !view || view->patch() == patch); + + Glib::RefPtr<Gnome::Glade::Xml> 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<Path, PatchWindow*>::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<NodeModel> node) +{ + NodeControlWindow* win = control_window(node); + + if (win) { + win->present(); + } else { + win = new_control_window(node); + win->present(); + } +} + + +NodeControlWindow* +WindowFactory::new_control_window(CountedPtr<NodeModel> 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<PatchModel> 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<PatchModel> 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<PatchModel> 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<PatchModel> 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<ObjectModel> 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<NodeModel> node) +{ + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(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 <map> +#include <gtkmm.h> #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<PatchController> patch, PatchWindow* preferred = NULL); + WindowFactory(); + ~WindowFactory(); + + PatchWindow* patch_window(CountedPtr<PatchModel> patch); + NodeControlWindow* control_window(CountedPtr<NodeModel> node); + + void present_patch(CountedPtr<PatchModel> patch, + PatchWindow* preferred = NULL, + CountedPtr<PatchView> patch = CountedPtr<PatchView>()); + + void present_controls(CountedPtr<NodeModel> node); + + void present_load_plugin(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap()); + void present_load_patch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap()); + void present_new_subpatch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap()); + void present_load_subpatch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap()); + void present_rename(CountedPtr<ObjectModel> object); + void present_properties(CountedPtr<NodeModel> node); private: - PatchWindow* create_new(CountedPtr<PatchController> patch); - bool remove(PatchWindow* win, GdkEventAny* ignored); + typedef std::map<Path, PatchWindow*> PatchWindowMap; + typedef std::map<Path, NodeControlWindow*> ControlWindowMap; + + PatchWindow* new_patch_window(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view); + bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored); + + NodeControlWindow* new_control_window(CountedPtr<NodeModel> node); + bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored); + + PatchWindowMap _patch_windows; + ControlWindowMap _control_windows; - std::map<Path, PatchWindow*> _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 @@ </child> <child> - <widget class="GtkVBox" id="patch_view_vbox"> + <widget class="GtkVBox" id="patch_view_box"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> |