diff options
author | David Robillard <d@drobilla.net> | 2006-09-11 11:10:35 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-09-11 11:10:35 +0000 |
commit | b15864870d34a1188eda93ad215734275037278e (patch) | |
tree | 224a1669a29091ea4198425d4a002e448cde8b30 /src/progs | |
parent | 22bf43352ddfc48452d776f10ad4d12161255049 (diff) | |
download | ingen-b15864870d34a1188eda93ad215734275037278e.tar.gz ingen-b15864870d34a1188eda93ad215734275037278e.tar.bz2 ingen-b15864870d34a1188eda93ad215734275037278e.zip |
Switched homebrew CountedPtr to boost::shared_ptr.
Factories for patch windows, controller.
Robustness updated in many places.
Tons of cleanups, rewrites, bugfixes, etc.
git-svn-id: http://svn.drobilla.net/lad/ingen@128 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/progs')
56 files changed, 669 insertions, 588 deletions
diff --git a/src/progs/Makefile.am b/src/progs/Makefile.am index a1a8c911..01791a1b 100644 --- a/src/progs/Makefile.am +++ b/src/progs/Makefile.am @@ -5,7 +5,7 @@ DIST_SUBDIRS = python supercollider SUBDIRS = server if BUILD_CONSOLE_CLIENTS -SUBDIRS += patch_loader demolition +SUBDIRS += patch_loader #demolition endif if BUILD_GTK_CLIENT diff --git a/src/progs/demolition/DemolitionClientInterface.cpp b/src/progs/demolition/DemolitionClientInterface.cpp index a0704028..23f5733f 100644 --- a/src/progs/demolition/DemolitionClientInterface.cpp +++ b/src/progs/demolition/DemolitionClientInterface.cpp @@ -36,7 +36,7 @@ DemolitionClientInterface::error(string msg) void -DemolitionClientInterface::new_patch_model(PatchModel* pm) +DemolitionClientInterface::new_patch_model(CountedPtr<PatchModel> pm) { m_model->add_patch(pm); } @@ -68,7 +68,7 @@ DemolitionClientInterface::patch_disabled(string path) void -DemolitionClientInterface::new_node_model(NodeModel* nm) +DemolitionClientInterface::new_node_model(CountedPtr<NodeModel> nm) { m_model->add_node(nm); } diff --git a/src/progs/demolition/DemolitionClientInterface.h b/src/progs/demolition/DemolitionClientInterface.h index 83539afc..e1093411 100644 --- a/src/progs/demolition/DemolitionClientInterface.h +++ b/src/progs/demolition/DemolitionClientInterface.h @@ -56,19 +56,19 @@ public: void new_plugin(string type, string uri, string name) {} - void new_patch_model(PatchModel* const pm); - void new_port_model(PortModel* const port_model); + void new_patch_model(CountedPtr<PatchModel> pm); + void new_port_model(CountedPtr<PortModel> port_model); void object_destroyed(string path); void patch_enabled(string path); void patch_disabled(string path); void patch_cleared(string path) { throw; } - void new_node_model(NodeModel* const nm); + void new_node_model(CountedPtr<NodeModel> nm); void object_renamed(string old_path, string new_path); - void connection_model(ConnectionModel* const cm); + void connection_model(CountedPtr<ConnectionModel> cm); void disconnection(string src_port_path, string dst_port_path); void metadata_update(string path, string key, string value) {} void control_change(string port_path, float value); - void new_plugin_model(PluginModel* const pi); + void new_plugin_model(CountedPtr<PluginModel> pi); void program_add(string path, uint32_t bank, uint32_t program, string name) {}; void program_remove(string path, uint32_t bank, uint32_t program) {}; diff --git a/src/progs/demolition/DemolitionModel.cpp b/src/progs/demolition/DemolitionModel.cpp index b91b461a..8ac10195 100644 --- a/src/progs/demolition/DemolitionModel.cpp +++ b/src/progs/demolition/DemolitionModel.cpp @@ -189,7 +189,7 @@ DemolitionModel::remove_object(const Path& path) void -DemolitionModel::add_node(NodeModel* nm) +DemolitionModel::add_node(CountedPtr<NodeModel> nm) { PatchModel* parent = patch(nm->path().parent()); if (parent == NULL) { diff --git a/src/progs/demolition/DemolitionModel.h b/src/progs/demolition/DemolitionModel.h index 67eb1005..6ae8c0ec 100644 --- a/src/progs/demolition/DemolitionModel.h +++ b/src/progs/demolition/DemolitionModel.h @@ -39,7 +39,7 @@ public: NodeModel* node(const Path& path); void add_patch(PatchModel* pm) { m_patches.push_back(pm); } - void add_node(NodeModel* nm); + void add_node(CountedPtr<NodeModel> nm); void add_port(PortModel* pm); void remove_object(const Path& path); void add_connection(ConnectionModel* cm); diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index ecf94a92..ae452f27 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -22,7 +22,6 @@ #include <libgnomecanvasmm.h> #include <time.h> #include <sys/time.h> -#include "PatchView.h" #include "OmModule.h" #include "ControlPanel.h" #include "SubpatchModule.h" @@ -44,6 +43,7 @@ #include "ConnectWindow.h" #include "Store.h" #include "Loader.h" +#include "WindowFactory.h" #ifdef HAVE_LASH #include "LashController.h" #endif @@ -66,6 +66,7 @@ App::App() _loader(NULL), _configuration(new Configuration()), _about_dialog(NULL), + _window_factory(new WindowFactory()), _enable_signal(true) { Glib::RefPtr<Gnome::Glade::Xml> glade_xml = GladeFactory::new_glade_reference(); @@ -94,7 +95,7 @@ App::instantiate() void -App::attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client) +App::attach(const CountedPtr<ModelEngineInterface>& engine, const CountedPtr<SigClientInterface>& client) { assert( ! _engine); assert( ! _client); diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 06d52ca3..25e01ff2 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -61,6 +61,7 @@ class PatchTreeWindow; class ConnectWindow; class Configuration; class Loader; +class WindowFactory; /** Singleton master class most everything is contained within. @@ -85,7 +86,8 @@ public: int num_open_patch_windows(); - void attach(CountedPtr<ModelEngineInterface>& engine, CountedPtr<SigClientInterface>& client); + void attach(const CountedPtr<ModelEngineInterface>& engine, + const CountedPtr<SigClientInterface>& client); ConnectWindow* connect_window() const { return _connect_window; } Gtk::Dialog* about_dialog() const { return _about_dialog; } @@ -95,7 +97,8 @@ public: Configuration* configuration() const { return _configuration; } Store* store() const { return _store; } Loader* loader() const { return _loader; } - + WindowFactory* window_factory() const { return _window_factory; } + const CountedPtr<ModelEngineInterface>& engine() const { return _engine; } const CountedPtr<SigClientInterface>& client() const { return _client; } @@ -121,6 +124,7 @@ protected: PatchTreeWindow* _patch_tree_window; ConfigWindow* _config_window; Gtk::Dialog* _about_dialog; + WindowFactory* _window_factory; /** Used to avoid feedback loops with (eg) process checkbutton * FIXME: Maybe this should be globally implemented at the Controller level, diff --git a/src/progs/ingenuity/BreadCrumbBox.cpp b/src/progs/ingenuity/BreadCrumbBox.cpp index d2bf7f97..aea1cdf0 100644 --- a/src/progs/ingenuity/BreadCrumbBox.cpp +++ b/src/progs/ingenuity/BreadCrumbBox.cpp @@ -28,9 +28,10 @@ BreadCrumbBox::BreadCrumbBox() } -/** Destroys current breadcrumbs and rebuilds from scratch. - * - * (Needs to be called when a patch is cleared to eliminate children crumbs) +/** Sets up the crumbs to display a @a path. + * + * If @a path is already part of the shown path, it will be selected and the + * children preserved. */ void BreadCrumbBox::build(Path path) @@ -38,8 +39,8 @@ BreadCrumbBox::build(Path path) bool old_enable_signal = _enable_signal; _enable_signal = false; - // Moving to a parent path, just switch the active button - if (path.length() < _full_path.length() && _full_path.substr(0, path.length()) == 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) ); @@ -102,5 +103,33 @@ BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) } } + +void +BreadCrumbBox::object_removed(const Path& path) +{ + for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == path) { + // Remove all crumbs after the removed one (inclusive) + for (std::list<BreadCrumb*>::iterator j = i; j != _breadcrumbs.end(); ) { + BreadCrumb* bc = *j; + j = _breadcrumbs.erase(j); + remove(*bc); + } + break; + } + } +} + + +void +BreadCrumbBox::object_renamed(const Path& old_path, const Path& new_path) +{ + for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { + if ((*i)->path() == old_path) + (*i)->set_path(new_path); + } +} + + } // namespace Ingenuity diff --git a/src/progs/ingenuity/BreadCrumbBox.h b/src/progs/ingenuity/BreadCrumbBox.h index aedfade0..35215e43 100644 --- a/src/progs/ingenuity/BreadCrumbBox.h +++ b/src/progs/ingenuity/BreadCrumbBox.h @@ -44,6 +44,9 @@ public: private: void breadcrumb_clicked(BreadCrumb* crumb); + + void object_removed(const Path& path); + void object_renamed(const Path& old_path, const Path& new_path); Path _active_path; Path _full_path; diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp index 16b2adea..df95f3c3 100644 --- a/src/progs/ingenuity/ConnectWindow.cpp +++ b/src/progs/ingenuity/ConnectWindow.cpp @@ -25,9 +25,11 @@ #include "OSCClientReceiver.h" #include "ThreadedSigClientInterface.h" #include "Store.h" +#include "ControllerFactory.h" #include "PatchController.h" #include "PatchModel.h" #include "App.h" +#include "WindowFactory.h" #ifdef MONOLITHIC_INGENUITY #include "engine/QueuedEngineInterface.h" #include "engine/Engine.h" @@ -349,10 +351,10 @@ ConnectWindow::gtk_callback() ++stage; } else if (stage == 7) { if (App::instance().store()->num_objects() > 0) { - CountedPtr<PatchModel> root = App::instance().store()->object("/"); + CountedPtr<PatchModel> root = PtrCast<PatchModel>(App::instance().store()->object("/")); assert(root); - PatchController* root_controller = new PatchController(root); - root_controller->show_patch_window(); + CountedPtr<PatchController> root_c = PtrCast<PatchController>(ControllerFactory::get_controller(root)); + App::instance().window_factory()->present(root_c); ++stage; } } else if (stage == 8) { diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp index 93a1cb5b..45218bdf 100644 --- a/src/progs/ingenuity/ControlGroups.cpp +++ b/src/progs/ingenuity/ControlGroups.cpp @@ -69,7 +69,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel : ControlGroup(panel, pm, separator), m_enabled(true), m_enable_signal(false), - m_name_label(pm->name(), 0.0, 0.0), + m_name_label(pm->path().name(), 0.0, 0.0), m_range_box(false, 0), m_range_label("<small>Range: </small>"), m_min_spinner(1.0, (pm->is_integer() ? 0 : 4)), // climb rate, digits @@ -90,7 +90,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel }*/ m_slider.property_draw_value() = false; - set_name(pm->name()); + set_name(pm->path().name()); m_name_label.property_use_markup() = true; m_range_label.property_use_markup() = true; @@ -305,10 +305,10 @@ IntegerControlGroup::IntegerControlGroup(ControlPanel* panel, CountedPtr<PortMod : ControlGroup(panel, pm, separator), m_enable_signal(false), m_alignment(0.5, 0.5, 0.0, 0.0), - m_name_label(pm->name()), + m_name_label(pm->path().name()), m_spinner(1.0, 0) { - set_name(pm->name()); + set_name(pm->path().name()); m_spinner.set_range(-99999, 99999); m_spinner.set_value(m_port_model->value()); @@ -379,9 +379,9 @@ ToggleControlGroup::ToggleControlGroup(ControlPanel* panel, CountedPtr<PortModel : ControlGroup(panel, pm, separator), m_enable_signal(false), m_alignment(0.5, 0.5, 0.0, 0.0), - m_name_label(pm->name()) + m_name_label(pm->path().name()) { - set_name(pm->name()); + set_name(pm->path().name()); set_value(m_port_model->value()); m_checkbutton.signal_toggled().connect( diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp index 57ac7824..90d17c8a 100644 --- a/src/progs/ingenuity/ControlPanel.cpp +++ b/src/progs/ingenuity/ControlPanel.cpp @@ -67,14 +67,7 @@ ControlPanel::init(NodeController* node, size_t poly) for (PortModelList::const_iterator i = node_model->ports().begin(); i != node_model->ports().end(); ++i) { - // FIXME: - if (*i) { - PortController* pc = (PortController*)((*i)->controller()); - assert(pc != NULL); - add_port(pc); - } else { - cerr << "WTF?\n"; - } + add_port(*i); } m_callback_enabled = true; @@ -95,13 +88,9 @@ ControlPanel::find_port(const Path& path) const /** Add a control to the panel for the given port. */ void -ControlPanel::add_port(PortController* port) +ControlPanel::add_port(CountedPtr<PortModel> pm) { - assert(port); - assert(port->model()); - //assert(port->control_panel() == NULL); - - const CountedPtr<PortModel> pm = port->port_model(); + assert(pm); // Already have port, don't add another if (find_port(pm->path()) != NULL) @@ -131,8 +120,6 @@ ControlPanel::add_port(PortController* port) // pm->disconnection_sig.connect(bind(sigc::mem_fun(this, &ControlPanel::disconnection), pm)) } - //port->set_control_panel(this); - Gtk::Requisition controls_size; m_control_box->size_request(controls_size); m_ideal_size.first = controls_size.width; diff --git a/src/progs/ingenuity/ControlPanel.h b/src/progs/ingenuity/ControlPanel.h index a0cc819d..025468d5 100644 --- a/src/progs/ingenuity/ControlPanel.h +++ b/src/progs/ingenuity/ControlPanel.h @@ -59,7 +59,7 @@ public: ControlGroup* find_port(const Path& path) const; - void add_port(PortController* port); + void add_port(CountedPtr<PortModel> port); void remove_port(const Path& path); //void rename_port(const Path& old_path, const Path& new_path); diff --git a/src/progs/ingenuity/ControllerFactory.cpp b/src/progs/ingenuity/ControllerFactory.cpp new file mode 100644 index 00000000..b95bef5b --- /dev/null +++ b/src/progs/ingenuity/ControllerFactory.cpp @@ -0,0 +1,72 @@ +/* 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 new file mode 100644 index 00000000..7f48c262 --- /dev/null +++ b/src/progs/ingenuity/ControllerFactory.h @@ -0,0 +1,32 @@ +/* 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/DSSIModule.cpp b/src/progs/ingenuity/DSSIModule.cpp index ebcd114c..3d91e69b 100644 --- a/src/progs/ingenuity/DSSIModule.cpp +++ b/src/progs/ingenuity/DSSIModule.cpp @@ -29,8 +29,8 @@ DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node) void DSSIModule::on_double_click(GdkEventButton* ev) { - DSSIController* const dc = static_cast<DSSIController*>(m_node); - if (!dc->attempt_to_show_gui()) + DSSIController* dc = dynamic_cast<DSSIController*>(m_node); + if (!dc || ! dc->attempt_to_show_gui()) show_control_window(); } diff --git a/src/progs/ingenuity/GtkObjectController.cpp b/src/progs/ingenuity/GtkObjectController.cpp index 798dc1f4..ccaa3ca5 100644 --- a/src/progs/ingenuity/GtkObjectController.cpp +++ b/src/progs/ingenuity/GtkObjectController.cpp @@ -28,8 +28,6 @@ GtkObjectController::GtkObjectController(CountedPtr<ObjectModel> model) GtkObjectController::~GtkObjectController() { - assert(m_model->controller() == this); - m_model->set_controller(NULL); } } // namespace Ingenuity diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp index a847e0fd..dcc08fff 100644 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ b/src/progs/ingenuity/LoadPatchWindow.cpp @@ -29,7 +29,6 @@ namespace Ingenuity { LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject), - m_patch_controller(NULL), m_replace(true) { xml->get_widget("load_patch_poly_from_current_radio", m_poly_from_current_radio); @@ -66,7 +65,7 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gno * This function MUST be called before using the window in any way! */ void -LoadPatchWindow::patch_controller(PatchController* pc) +LoadPatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; } @@ -111,7 +110,7 @@ LoadPatchWindow::ok_clicked() if (m_replace) App::instance().engine()->clear_patch(m_patch_controller->model()->path()); - PatchModel* pm = new PatchModel(m_patch_controller->model()->path(), poly); + CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path(), poly)); pm->filename(get_filename()); pm->set_metadata("filename", get_filename()); pm->set_parent(m_patch_controller->patch_model()->parent()); diff --git a/src/progs/ingenuity/LoadPatchWindow.h b/src/progs/ingenuity/LoadPatchWindow.h index 4f72c6c1..e22b1c1a 100644 --- a/src/progs/ingenuity/LoadPatchWindow.h +++ b/src/progs/ingenuity/LoadPatchWindow.h @@ -21,6 +21,8 @@ #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -42,7 +44,7 @@ class LoadPatchWindow : public Gtk::FileChooserDialog public: LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_replace() { m_replace = true; } void set_merge() { m_replace = false; } @@ -56,8 +58,8 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; - bool m_replace; + CountedPtr<PatchController> m_patch_controller; + 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 4b4290c4..2b59efef 100644 --- a/src/progs/ingenuity/LoadPluginWindow.cpp +++ b/src/progs/ingenuity/LoadPluginWindow.cpp @@ -20,7 +20,6 @@ #include <algorithm> #include <cctype> #include "PatchController.h" -#include "PatchView.h" #include "NodeModel.h" #include "App.h" #include "PatchWindow.h" @@ -28,6 +27,8 @@ #include "PatchModel.h" #include "Store.h" #include "ModelEngineInterface.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" using std::cout; using std::cerr; using std::endl; @@ -35,7 +36,6 @@ namespace Ingenuity { LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::Window(cobject), - m_patch_controller(NULL), m_has_shown(false), m_plugin_name_offset(0), m_new_module_x(0), @@ -135,7 +135,7 @@ LoadPluginWindow::name_changed() * This function MUST be called before using the window in any way! */ void -LoadPluginWindow::patch_controller(PatchController* pc) +LoadPluginWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; @@ -190,9 +190,8 @@ LoadPluginWindow::set_plugin_list(const std::map<string, CountedPtr<PluginModel> { m_plugins_liststore->clear(); - CountedPtr<PluginModel> plugin = NULL; for (std::map<string, CountedPtr<PluginModel> >::const_iterator i = m.begin(); i != m.end(); ++i) { - plugin = (*i).second; + CountedPtr<PluginModel> plugin = (*i).second; Gtk::TreeModel::iterator iter = m_plugins_liststore->append(); Gtk::TreeModel::Row row = *iter; @@ -307,12 +306,12 @@ LoadPluginWindow::add_clicked() dialog.run(); } else { - const string path = m_patch_controller->model()->base_path() + name; + const string path = m_patch_controller->model()->path().base() + name; NodeModel* nm = new NodeModel(plugin, path); nm->polyphonic(polyphonic); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } nm->x(m_new_module_x); diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h index 9d875358..1654b777 100644 --- a/src/progs/ingenuity/LoadPluginWindow.h +++ b/src/progs/ingenuity/LoadPluginWindow.h @@ -87,7 +87,7 @@ class LoadPluginWindow : public Gtk::Window public: LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_plugin_list(const std::map<string, CountedPtr<PluginModel> >& m); void set_next_module_location(double x, double y) @@ -113,7 +113,7 @@ private: void plugin_selection_changed(); string generate_module_name(int offset = 0); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; 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 832c917f..486c92b4 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.cpp +++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp @@ -33,7 +33,6 @@ namespace Ingenuity { LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::FileChooserDialog(cobject), - m_patch_controller(NULL), m_new_module_x(0), m_new_module_y(0) { @@ -74,7 +73,7 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP * This function MUST be called before using the window in any way! */ void -LoadSubpatchWindow::patch_controller(PatchController* pc) +LoadSubpatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; @@ -130,7 +129,7 @@ LoadSubpatchWindow::enable_poly_spinner() void LoadSubpatchWindow::ok_clicked() { - assert(m_patch_controller != NULL); + assert(m_patch_controller); assert(m_patch_controller->model()); const string filename = get_filename(); @@ -148,13 +147,13 @@ LoadSubpatchWindow::ok_clicked() poly = m_patch_controller->patch_model()->poly(); if (m_new_module_x == 0 && m_new_module_y == 0) { - m_patch_controller->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } - PatchModel* pm = new PatchModel(m_patch_controller->model()->base_path() + name, poly); + CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path().base() + name, poly)); pm->filename(filename); - pm->set_parent(m_patch_controller->model().get()); + pm->set_parent(m_patch_controller->model()); pm->x(m_new_module_x); pm->y(m_new_module_y); //if (name == "") diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h index c4696628..e33880e8 100644 --- a/src/progs/ingenuity/LoadSubpatchWindow.h +++ b/src/progs/ingenuity/LoadSubpatchWindow.h @@ -21,6 +21,8 @@ #include "PluginModel.h" #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -39,7 +41,7 @@ class LoadSubpatchWindow : public Gtk::FileChooserDialog public: LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } @@ -56,7 +58,7 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; 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 fed49603..0ca6f966 100644 --- a/src/progs/ingenuity/Loader.cpp +++ b/src/progs/ingenuity/Loader.cpp @@ -211,14 +211,14 @@ Loader::m_thread_function(void *) void -Loader::load_patch(PatchModel* model, bool wait, bool merge) +Loader::load_patch(CountedPtr<PatchModel> model, bool wait, bool merge) { set_event(new LoadPatchEvent(m_patch_librarian, model, wait, merge)); } void -Loader::save_patch(PatchModel* model, const string& filename, bool recursive) +Loader::save_patch(CountedPtr<PatchModel> model, const string& filename, bool recursive) { cout << "[Loader] Saving patch " << filename << endl; set_event(new SavePatchEvent(m_patch_librarian, model, filename, recursive)); diff --git a/src/progs/ingenuity/Loader.h b/src/progs/ingenuity/Loader.h index 7ff6f189..58c301af 100644 --- a/src/progs/ingenuity/Loader.h +++ b/src/progs/ingenuity/Loader.h @@ -53,15 +53,15 @@ protected: class LoadPatchEvent : public LoaderEvent { public: - LoadPatchEvent(PatchLibrarian* pl, PatchModel* model, bool wait, bool merge) + LoadPatchEvent(PatchLibrarian* pl, CountedPtr<PatchModel> model, bool wait, bool merge) : m_patch_librarian(pl), m_patch_model(model), m_wait(wait), m_merge(merge) {} virtual ~LoadPatchEvent() {} void execute(); private: - PatchLibrarian* m_patch_librarian; - PatchModel* m_patch_model; - bool m_wait; - bool m_merge; + PatchLibrarian* m_patch_librarian; + CountedPtr<PatchModel> m_patch_model; + bool m_wait; + bool m_merge; }; @@ -72,15 +72,15 @@ private: class SavePatchEvent : public LoaderEvent { public: - SavePatchEvent(PatchLibrarian* pl, PatchModel* pm, const string& filename, bool recursive) + SavePatchEvent(PatchLibrarian* pl, CountedPtr<PatchModel> pm, const string& filename, bool recursive) : m_patch_librarian(pl), m_patch_model(pm), m_filename(filename), m_recursive(recursive) {} virtual ~SavePatchEvent() {} void execute(); private: - PatchLibrarian* m_patch_librarian; - PatchModel* m_patch_model; - string m_filename; - bool m_recursive; + PatchLibrarian* m_patch_librarian; + CountedPtr<PatchModel> m_patch_model; + string m_filename; + bool m_recursive; }; /* @@ -129,8 +129,8 @@ public: void launch(); void exit() { m_thread_exit_flag = true; } - void load_patch(PatchModel* model, bool wait, bool merge); - void save_patch(PatchModel* model, const string& filename, bool recursive); + void load_patch(CountedPtr<PatchModel> model, bool wait, bool merge); + void save_patch(CountedPtr<PatchModel> model, const string& filename, bool recursive); //void load_session(const string& filename); //void save_session(const string& filename); diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am index 7cc405c1..5c4f5eed 100644 --- a/src/progs/ingenuity/Makefile.am +++ b/src/progs/ingenuity/Makefile.am @@ -43,6 +43,8 @@ ingenuity_SOURCES = \ PortController.cpp \ DSSIController.h \ DSSIController.cpp \ + ControllerFactory.h \ + ControllerFactory.cpp \ LoadPluginWindow.h \ LoadPluginWindow.cpp \ LoadPatchWindow.h \ @@ -61,6 +63,8 @@ ingenuity_SOURCES = \ PatchView.cpp \ PatchWindow.h \ PatchWindow.cpp \ + WindowFactory.h \ + WindowFactory.cpp \ OmFlowCanvas.h \ OmFlowCanvas.cpp \ ../../common/types.h \ diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp index 0b94e3d2..7f434445 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.cpp +++ b/src/progs/ingenuity/NewSubpatchWindow.cpp @@ -18,10 +18,10 @@ #include "ModelEngineInterface.h" #include "NewSubpatchWindow.h" #include "PatchController.h" -#include "PatchView.h" -#include "OmFlowCanvas.h" #include "NodeModel.h" #include "PatchModel.h" +#include "PatchView.h" +#include "OmFlowCanvas.h" namespace Ingenuity { @@ -50,7 +50,7 @@ NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr * This function MUST be called before using the window in any way! */ void -NewSubpatchWindow::patch_controller(PatchController* pc) +NewSubpatchWindow::set_patch(CountedPtr<PatchController> pc) { m_patch_controller = pc; } @@ -83,11 +83,11 @@ void NewSubpatchWindow::ok_clicked() { PatchModel* pm = new PatchModel( - m_patch_controller->model()->base_path() + m_name_entry->get_text(), + m_patch_controller->model()->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->view()->canvas()->get_new_module_location( + m_patch_controller->get_view()->canvas()->get_new_module_location( m_new_module_x, m_new_module_y); } diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h index 46fa9e1c..32560dde 100644 --- a/src/progs/ingenuity/NewSubpatchWindow.h +++ b/src/progs/ingenuity/NewSubpatchWindow.h @@ -14,13 +14,14 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef NEWSUBPATCHWINDOW_H #define NEWSUBPATCHWINDOW_H #include "PluginModel.h" #include <libglademm/xml.h> #include <gtkmm.h> +#include "util/CountedPtr.h" +#include "PatchController.h" namespace Ingenuity { @@ -39,7 +40,7 @@ class NewSubpatchWindow : public Gtk::Window public: NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void patch_controller(PatchController* pc); + void set_patch(CountedPtr<PatchController> pc); void set_next_module_location(double x, double y) { m_new_module_x = x; m_new_module_y = y; } @@ -49,7 +50,7 @@ private: void ok_clicked(); void cancel_clicked(); - PatchController* m_patch_controller; + CountedPtr<PatchController> m_patch_controller; double m_new_module_x; double m_new_module_y; diff --git a/src/progs/ingenuity/NodeController.cpp b/src/progs/ingenuity/NodeController.cpp index 1c340516..677bc8b5 100644 --- a/src/progs/ingenuity/NodeController.cpp +++ b/src/progs/ingenuity/NodeController.cpp @@ -25,6 +25,7 @@ #include "GtkObjectController.h" #include "NodeControlWindow.h" #include "OmModule.h" +#include "ControllerFactory.h" #include "PatchController.h" #include "OmFlowCanvas.h" #include "RenameWindow.h" @@ -47,17 +48,13 @@ NodeController::NodeController(CountedPtr<NodeModel> model) m_properties_window(NULL), m_bridge_port(NULL) { - assert(!model->controller()); - model->set_controller(this); - // 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()); - // FIXME: leak - PortController* const pc = new PortController(*i); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i)); assert((*i)->controller() == pc); // PortController() does this } @@ -92,6 +89,7 @@ NodeController::NodeController(CountedPtr<NodeModel> model) } model->new_port_sig.connect(sigc::mem_fun(this, &NodeController::add_port)); + model->destroyed_sig.connect(sigc::mem_fun(this, &NodeController::destroy)); } @@ -102,6 +100,13 @@ NodeController::~NodeController() void +NodeController::destroy() +{ + delete this; +} + + +void NodeController::create_module(OmFlowCanvas* canvas) { if (!m_module || m_module->canvas() != canvas) { @@ -144,7 +149,7 @@ NodeController::set_path(const Path& new_path) i != node_model()->ports().end(); ++i) { GtkObjectController* const pc = (GtkObjectController*)((*i)->controller()); assert(pc != NULL); - pc->set_path(m_model->path().base_path() + pc->model()->name()); + pc->set_path(m_model->path().base() + pc->model()->name()); } // Handle bridge port, if this node represents one @@ -160,7 +165,7 @@ NodeController::set_path(const Path& new_path) */ } - +#if 0 void NodeController::destroy() { @@ -178,7 +183,7 @@ NodeController::destroy() //if (m_module != NULL) // delete m_module; } - +#endif void NodeController::metadata_update(const string& key, const string& value) @@ -197,8 +202,8 @@ NodeController::metadata_update(const string& key, const string& value) } } - if (m_bridge_port != NULL) - m_bridge_port->metadata_update(key, value); + //if (m_bridge_port != NULL) + // m_bridge_port->metadata_update(key, value); GtkObjectController::metadata_update(key, value); } @@ -209,12 +214,11 @@ NodeController::add_port(CountedPtr<PortModel> pm) { assert(pm->parent().get() == node_model().get()); assert(pm->parent() == node_model()); - assert(node_model()->get_port(pm->name()) == pm); + assert(node_model()->get_port(pm->path().name()) == pm); //cout << "[NodeController] Adding port " << pm->path() << endl; - // FIXME: leak - PortController* pc = new PortController(pm); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(pm)); assert(pm->controller() == pc); if (m_module != NULL) { @@ -259,10 +263,10 @@ NodeController::show_rename_window() Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("rename_win"); xml->get_widget_derived("rename_win", win); - PatchController* parent = ((PatchController*)node_model()->parent()->controller()); - assert(parent != NULL); + CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller()); + assert(parent); - if (parent->window() != NULL) + if (parent->window()) win->set_transient_for(*parent->window()); win->set_object(this); @@ -298,7 +302,7 @@ NodeController::on_menu_clone() clone_name = clone_name + clone_postfix; - const string path = node_model()->parent_patch()->base_path() + clone_name; + 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); @@ -324,36 +328,33 @@ NodeController::on_menu_disconnect_all() void NodeController::show_properties_window() { - PatchController* parent = ((PatchController*)node_model()->parent()->controller()); - assert(parent != NULL); + CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller()); + assert(parent); - if (m_properties_window == NULL) { + 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 != NULL); - assert(parent != NULL); + assert(m_properties_window); + assert(parent); m_properties_window->set_node(node_model()); - if (parent->window() != NULL) + 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 != NULL); + assert(m_module); - PortController* pc = NULL; for (PortModelList::const_iterator i = node_model()->ports().begin(); i != node_model()->ports().end(); ++i) { - pc = dynamic_cast<PortController*>((*i)->controller()); - // FIXME: leak - if (pc == NULL) - pc = new PortController(*i); + CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i)); pc->create_port(m_module); } diff --git a/src/progs/ingenuity/NodeController.h b/src/progs/ingenuity/NodeController.h index 84ac09cd..c0ee6ea9 100644 --- a/src/progs/ingenuity/NodeController.h +++ b/src/progs/ingenuity/NodeController.h @@ -20,14 +20,13 @@ #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; -template <class T> class CountedPtr; - namespace Ingen { namespace Client { class MetadataModel; class PortModel; @@ -49,10 +48,7 @@ class OmFlowCanvas; class NodeController : public GtkObjectController { public: - NodeController(CountedPtr<NodeModel> model); virtual ~NodeController(); - - virtual void destroy(); virtual void metadata_update(const string& key, const string& value); @@ -68,10 +64,10 @@ public: OmModule* module() { return m_module; } - void bridge_port(PortController* port) { m_bridge_port = port; } - PortController* as_port() { return m_bridge_port; } + //void bridge_port(PortController* port) { m_bridge_port = port; } + //PortController* as_port() { return m_bridge_port; } - CountedPtr<NodeModel> node_model() { return m_model; } + 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; } @@ -89,6 +85,12 @@ public: 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(); diff --git a/src/progs/ingenuity/NodePropertiesWindow.cpp b/src/progs/ingenuity/NodePropertiesWindow.cpp index 2ee79527..a6bdfce1 100644 --- a/src/progs/ingenuity/NodePropertiesWindow.cpp +++ b/src/progs/ingenuity/NodePropertiesWindow.cpp @@ -26,7 +26,6 @@ using std::string; NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) : Gtk::Window(cobject) -, m_node_model(NULL) { glade_xml->get_widget("node_properties_path_label", m_node_path_label); glade_xml->get_widget("node_properties_polyphonic_checkbutton", m_node_polyphonic_toggle); diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp index a6e3617e..d530bca0 100644 --- a/src/progs/ingenuity/OmFlowCanvas.cpp +++ b/src/progs/ingenuity/OmFlowCanvas.cpp @@ -101,22 +101,21 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port) if (src->model()->type() == PortModel::MIDI && dst->model()->type() == PortModel::CONTROL) { - // FIXME: leaks? - PluginModel* pm = new PluginModel(PluginModel::Internal, "", "midi_control_in", ""); - NodeModel* nm = new NodeModel(pm, m_patch_controller->model()->base_path() - + src->name() + "-" + dst->name()); + 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()); - App::instance().engine()->create_node_from_model(nm); + 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()); App::instance().engine()->midi_learn(nm->path()); // Set control node range to port's user range - App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Min", + App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", atof(dst->model()->get_metadata("user-min").c_str())); - App::instance().engine()->set_port_value_queued(nm->path().base_path() + "Max", + App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", atof(dst->model()->get_metadata("user-max").c_str())); } else { App::instance().engine()->connect(src->model()->path(), @@ -195,7 +194,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_path() + generate_port_name(name); + const Path& path = m_patch_controller->path().base() + generate_port_name(name); App::instance().engine()->create_port(path, type, is_output); char temp_buf[16]; @@ -224,7 +223,7 @@ void OmFlowCanvas::menu_add_audio_input() { string name = "audio_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "AUDIO", false); } @@ -232,7 +231,7 @@ void OmFlowCanvas::menu_add_audio_output() { string name = "audio_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "AUDIO", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "AUDIO", true); } @@ -240,7 +239,7 @@ void OmFlowCanvas::menu_add_control_input() { string name = "control_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "CONTROL", false); } @@ -248,7 +247,7 @@ void OmFlowCanvas::menu_add_control_output() { string name = "control_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "CONTROL", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "CONTROL", true); } @@ -256,7 +255,7 @@ void OmFlowCanvas::menu_add_midi_input() { string name = "midi_in"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", false); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "MIDI", false); } @@ -264,7 +263,7 @@ void OmFlowCanvas::menu_add_midi_output() { string name = "midi_out"; - App::instance().engine()->create_port(m_patch_controller->path().base_path() + name, "MIDI", true); + App::instance().engine()->create_port(m_patch_controller->path().base() + name, "MIDI", true); } */ diff --git a/src/progs/ingenuity/OmModule.cpp b/src/progs/ingenuity/OmModule.cpp index e34665a7..dd6f3da5 100644 --- a/src/progs/ingenuity/OmModule.cpp +++ b/src/progs/ingenuity/OmModule.cpp @@ -31,11 +31,11 @@ namespace Ingenuity { OmModule::OmModule(OmFlowCanvas* canvas, NodeController* node) -: LibFlowCanvas::Module(canvas, node->node_model()->name(), +: LibFlowCanvas::Module(canvas, node->node_model()->path().name(), node->node_model()->x(), node->node_model()->y()), m_node(node) { - assert(m_node != NULL); + assert(m_node); /*if (node_model()->polyphonic() && node_model()->parent() != NULL && node_model()->parent_patch()->poly() > 1) { diff --git a/src/progs/ingenuity/OmModule.h b/src/progs/ingenuity/OmModule.h index 2a31a84f..a3d56187 100644 --- a/src/progs/ingenuity/OmModule.h +++ b/src/progs/ingenuity/OmModule.h @@ -21,6 +21,7 @@ #include <string> #include <libgnomecanvasmm.h> #include <flowcanvas/Module.h> +#include "util/CountedPtr.h" #include "NodeController.h" using std::string; diff --git a/src/progs/ingenuity/OmPatchPort.cpp b/src/progs/ingenuity/OmPatchPort.cpp index b900a40c..0d3acf76 100644 --- a/src/progs/ingenuity/OmPatchPort.cpp +++ b/src/progs/ingenuity/OmPatchPort.cpp @@ -29,7 +29,7 @@ using namespace Ingen::Client; namespace Ingenuity { OmPatchPort::OmPatchPort(OmPortModule* module, CountedPtr<PortModel> pm) -: Port(module, pm->name(), !pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), +: Port(module, pm->path().name(), !pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), m_port_model(pm) { assert(module); diff --git a/src/progs/ingenuity/OmPort.cpp b/src/progs/ingenuity/OmPort.cpp index 69406b97..e2a32652 100644 --- a/src/progs/ingenuity/OmPort.cpp +++ b/src/progs/ingenuity/OmPort.cpp @@ -29,7 +29,7 @@ using namespace Ingen::Client; namespace Ingenuity { OmPort::OmPort(Module* module, CountedPtr<PortModel> pm) -: Port(module, pm->name(), pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), +: Port(module, pm->path().name(), pm->is_input(), App::instance().configuration()->get_port_color(pm.get())), m_port_model(pm) { assert(module); diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp index 6ef90d32..8dee4cd2 100644 --- a/src/progs/ingenuity/PatchController.cpp +++ b/src/progs/ingenuity/PatchController.cpp @@ -44,6 +44,7 @@ #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; @@ -55,26 +56,12 @@ PatchController::PatchController(CountedPtr<PatchModel> model) : NodeController(model), m_properties_window(NULL), m_window(NULL), - m_patch_view(NULL), m_patch_model(model), m_module_x(0), m_module_y(0) { - assert(model->path().length() > 0); - assert(model->controller() == this); // NodeController() does this - assert(m_patch_model == model); - -/* FIXME if (model->path() != "/") { - PatchController* parent = Store::instance().patch(model->path().parent()); - if (parent != NULL) - parent->add_subpatch(this); - else - cerr << "[PatchController] " << path() << " ERROR: Parent not found." << endl; - }*/ - //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->removed_node_sig.connect(sigc::mem_fun(this, &PatchController::remove_node)); model->new_connection_sig.connect(sigc::mem_fun(this, &PatchController::connection)); model->removed_connection_sig.connect(sigc::mem_fun(this, &PatchController::disconnection)); } @@ -82,27 +69,23 @@ PatchController::PatchController(CountedPtr<PatchModel> model) PatchController::~PatchController() { - if (m_patch_view != NULL) { + if (m_patch_view) { claim_patch_view(); - m_patch_view->hide(); - delete m_patch_view; - m_patch_view = NULL; } - if (m_control_window != NULL) { + if (m_control_window) { m_control_window->hide(); delete m_control_window; m_control_window = NULL; } - if (m_window != NULL) { - m_window->hide(); + if (m_window) { delete m_window; m_window = NULL; } } - +#if 0 void PatchController::clear() { @@ -113,8 +96,8 @@ PatchController::clear() size_t remaining = nodes.size(); while (remaining > 0) { - NodeController* const nc = (NodeController*)(*nodes.begin()).second->controller(); - assert(nc != NULL); + CountedPtr<NodeController> nc = (*nodes.begin()).second->controller(); + assert(nc); nc->destroy(); assert(nodes.size() == remaining - 1); --remaining; @@ -123,13 +106,14 @@ PatchController::clear() patch_model()->clear(); - if (m_patch_view != NULL) { - assert(m_patch_view->canvas() != NULL); + if (m_patch_view) { + assert(m_patch_view->canvas()); m_patch_view->canvas()->destroy(); } } +#endif - +#if 0 void PatchController::destroy() { @@ -139,9 +123,8 @@ PatchController::destroy() size_t remaining = nodes.size(); while (remaining > 0) { - NodeController* const nc = (NodeController*) - (*nodes.begin()).second->controller(); - assert(nc != NULL); + CountedPtr<NodeController> nc = (*nodes.begin()).second->controller(); + assert(nc); nc->destroy(); assert(nodes.size() == remaining - 1); --remaining; @@ -158,14 +141,22 @@ PatchController::destroy() //Store::instance().remove_object(this); // Delete self from parent (this will delete model) - /*if (patch_model()->parent() != NULL) { + /*if (patch_model()->parent()) { PatchController* const parent = (PatchController*)patch_model()->parent()->controller(); - assert(parent != NULL); + assert(parent); parent->remove_node(name()); } else { //delete m_model; }*/ } +#endif + + +void +PatchController::destroy() +{ + delete this; +} void @@ -189,25 +180,25 @@ PatchController::set_path(const Path& new_path) i != patch_model()->nodes().end(); ++i) { const NodeModel* const nm = (*i).second.get(); assert(nm ); - NodeController* const nc = ((NodeController*)nm->controller()); + CountedPtr<NodeController> nc = PtrCast<NodeController>(nm->controller()); assert(nc ); - nc->set_path(new_path.base_path() + nc->node_model()->name()); + 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) { - GtkObjectController* const pc = (GtkObjectController*)((*i)->controller()); - assert(pc ); + 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_window) + m_window->patch_renamed(new_path);*/ if (m_control_window) m_control_window->set_title(new_path + " Controls"); @@ -215,11 +206,10 @@ PatchController::set_path(const Path& new_path) if (m_module) m_module->name(new_path.name()); - PatchController* parent = dynamic_cast<PatchController*>( - patch_model()->parent()->controller()); + CountedPtr<PatchController> parent = PtrCast<PatchController>(patch_model()->parent()->controller()); - if (parent && parent->window()) - parent->window()->node_renamed(old_path, new_path); + //if (parent && parent->window()) + // parent->window()->node_renamed(old_path, new_path); //remove_from_store(); GtkObjectController::set_path(new_path); @@ -249,11 +239,12 @@ PatchController::create_module(OmFlowCanvas* canvas) //cerr << "Creating patch module " << m_model->path() << endl; - assert(canvas != NULL); + assert(canvas); assert(m_module == NULL); assert(!m_patch_view || canvas != m_patch_view->canvas()); - m_module = new SubpatchModule(canvas, this); + // FIXME: weirdo using model->controller() to get shared_ptr_from_this.. + m_module = new SubpatchModule(canvas, PtrCast<PatchController>(m_model->controller())); create_all_ports(); } @@ -261,23 +252,26 @@ PatchController::create_module(OmFlowCanvas* canvas) } -void -PatchController::create_view() +CountedPtr<PatchView> +PatchController::get_view() { - assert(m_patch_view == NULL); + if (m_patch_view) + return m_patch_view; Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget_derived("patch_view_vbox", m_patch_view); - assert(m_patch_view != NULL); + 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() != NULL); + assert(m_patch_view->canvas()); // Create modules for nodes for (NodeModelMap::const_iterator i = patch_model()->nodes().begin(); i != patch_model()->nodes().end(); ++i) { - NodeModel* const nm = (*i).second.get(); + const CountedPtr<NodeModel> nm = (*i).second; string val = nm->get_metadata("module-x"); if (val != "") @@ -294,9 +288,7 @@ PatchController::create_view() nm->y(y); } - NodeController* nc = ((NodeController*)nm->controller()); - if (!nc) - nc = create_controller_for_node(nm); + CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(nm)); assert(nc); assert(nm->controller() == nc); @@ -308,7 +300,7 @@ PatchController::create_view() // 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) { - PortController* const pc = dynamic_cast<PortController*>((*i)->controller()); + CountedPtr<PortController> pc = PtrCast<PortController>((*i)->controller()); assert(pc); pc->create_module(m_patch_view->canvas()); } @@ -323,6 +315,8 @@ PatchController::create_view() // Set run checkbox if (patch_model()->enabled()) m_patch_view->enable(); + + return m_patch_view; } @@ -345,7 +339,7 @@ PatchController::show_properties_window() void PatchController::connection(CountedPtr<ConnectionModel> cm) { - if (m_patch_view != NULL) { + 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(); @@ -365,97 +359,50 @@ PatchController::connection(CountedPtr<ConnectionModel> cm) } -NodeController* -PatchController::create_controller_for_node(CountedPtr<NodeModel> node) -{ - assert(!node->controller()); - NodeController* nc = NULL; - - CountedPtr<PatchModel> patch(node); - if (patch) { - assert(patch == node); - assert(patch->parent() == m_patch_model); - nc = new PatchController(patch); - } else { - assert(node->plugin()); - if (node->plugin()->type() == PluginModel::DSSI) - nc = new DSSIController(node); - else - nc = new NodeController(node); - } - - assert(node->controller() == nc); - return nc; -} - - /** Add a child node to this patch. * * This is for plugin nodes and patches, and is responsible for creating the - * GtkObjectController for @a object (and through that the View if necessary) + * GtkObjectController for @a node (and through that the View if necessary) */ void -PatchController::add_node(CountedPtr<NodeModel> object) +PatchController::add_node(CountedPtr<NodeModel> node) { - assert(object); - assert(object->parent() == m_patch_model); - assert(patch_model()->get_node(object->name())); - - /*if (patch_model()->get_node(nm->name()) != NULL) { - cerr << "Ignoring existing\n"; - // Node already exists, ignore - //delete nm; - } else {*/ - + assert(node); + assert(node->parent().get() == m_patch_model.get()); + assert(node->parent() == m_patch_model); + assert(patch_model()->get_node(node->path().name())); - CountedPtr<NodeModel> node(object); - if (node) { - assert(node->parent() == m_patch_model); + assert(node->parent() == m_patch_model); - NodeController* nc = create_controller_for_node(node); - assert(nc); - assert(node->controller() == nc); + CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(node)); + assert(nc); + assert(node->controller() == nc); - if (m_patch_view != NULL) { - 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 (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(); -/** Removes a node from this patch. - */ -void -PatchController::remove_node(const string& name) -{ - assert(name.find("/") == string::npos); - assert(!m_patch_model->get_node(name)); + // Reset zoom + if (old_zoom != 1.0) { + m_patch_view->canvas()->set_zoom(old_zoom); + nc->module()->zoom(old_zoom); + } + } - // Update breadcrumbs if necessary - if (m_window) - m_window->node_removed(name); } - +#if 0 /** Add a port to this patch. * * Will add a port to the subpatch module and the control window, if they @@ -466,34 +413,33 @@ PatchController::add_port(CountedPtr<PortModel> pm) { assert(pm); assert(pm->parent() == m_patch_model); - assert(patch_model()->get_port(pm->name())); + assert(patch_model()->get_port(pm->path().name())); //cerr << "[PatchController] Adding port " << pm->path() << endl; - /*if (patch_model()->get_port(pm->name())) { + /*if (patch_model()->get_port(pm->path().name())) { cerr << "[PatchController] Ignoring duplicate port " << pm->path() << endl; return; }*/ //node_model()->add_port(pm); - // FIXME: leak - PortController* pc = new PortController(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 != NULL) + if (nc) nc->bridge_port(pc); */ // Create port on this patch's module (if there is one) - if (m_module != NULL) { + 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 != NULL) { + 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(); @@ -505,9 +451,9 @@ PatchController::add_port(CountedPtr<PortModel> pm) pc->module()->zoom(old_zoom); } - if (m_control_window != NULL) { - assert(m_control_window->control_panel() != NULL); - m_control_window->control_panel()->add_port(pc); + if (m_control_window) { + assert(m_control_window->control_panel()); + m_control_window->control_panel()->add_port(pm); m_control_window->resize(); } @@ -528,9 +474,9 @@ PatchController::remove_port(const Path& path, bool resize_module) //cerr << "[PatchController] Removing port " << path << endl; /* FIXME - if (m_control_panel != NULL) { + if (m_control_panel) { m_control_panel->remove_port(path); - if (m_control_window != NULL) { + if (m_control_window) { assert(m_control_window->control_panel() == m_control_panel); m_control_window->resize(); } @@ -546,7 +492,7 @@ PatchController::remove_port(const Path& path, bool resize_module) if (!has_control_inputs()) disable_controls_menuitem(); } - +#endif void PatchController::disconnection(const Path& src_port_path, const Path& dst_port_path) @@ -571,32 +517,13 @@ PatchController::disconnection(const Path& src_port_path, const Path& dst_port_p /* // Enable control slider in destination node control window PortController* p = (PortController)Store::instance().port(dst_port_path)->controller(); - assert(p != NULL); + assert(p); - if (p->control_panel() != NULL) + if (p->control_panel()) p->control_panel()->enable_port(p->path()); */ } -void -PatchController::show_patch_window() -{ - if (m_window == NULL) { - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - - xml->get_widget_derived("patch_win", m_window); - assert(m_window != NULL); - - if (m_patch_view == NULL) - create_view(); - - m_window->patch_controller(this); - } - - assert(m_window != NULL); - m_window->present(); -} - /** Become the parent of the patch view. * @@ -605,7 +532,7 @@ PatchController::show_patch_window() void PatchController::claim_patch_view() { - assert(m_patch_view != NULL); + assert(m_patch_view); m_patch_view->hide(); m_patch_view->reparent(m_patch_view_bin); @@ -625,24 +552,4 @@ PatchController::show_control_window() } -void -PatchController::enable_controls_menuitem() -{ - if (m_window != NULL) - m_window->menu_view_control_window()->property_sensitive() = true; - - NodeController::enable_controls_menuitem(); -} - - -void -PatchController::disable_controls_menuitem() -{ - if (m_window != NULL) - m_window->menu_view_control_window()->property_sensitive() = false; - - NodeController::disable_controls_menuitem(); -} - - } // namespace Ingenuity diff --git a/src/progs/ingenuity/PatchController.h b/src/progs/ingenuity/PatchController.h index a5370826..2ee01738 100644 --- a/src/progs/ingenuity/PatchController.h +++ b/src/progs/ingenuity/PatchController.h @@ -19,9 +19,9 @@ #include <string> #include <gtkmm.h> +#include "util/CountedPtr.h" #include "NodeController.h" #include "PatchModel.h" -template <class T> class CountedPtr; namespace Ingen { namespace Client { class PatchModel; @@ -60,7 +60,6 @@ class NodeController; class PatchController : public NodeController { public: - PatchController(CountedPtr<PatchModel> model); virtual ~PatchController(); /* @@ -68,16 +67,14 @@ public: virtual void remove_from_store(); */ - virtual void destroy(); - 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); + //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 clear(); void show_control_window(); void show_properties_window(); @@ -86,35 +83,31 @@ public: void claim_patch_view(); void create_module(OmFlowCanvas* canvas); - void create_view(); - PatchView* view() const { return m_patch_view; } + CountedPtr<PatchView> get_view(); PatchWindow* window() const { return m_window; } void window(PatchWindow* pw) { m_window = pw; } - inline string name() const { return m_model->name(); } - inline const Path& path() const { return m_model->path(); } - void set_path(const Path& new_path); //void enable(); //void disable(); - CountedPtr<PatchModel> patch_model() const { return m_patch_model; } + const CountedPtr<PatchModel> patch_model() const { return m_patch_model; } - void enable_controls_menuitem(); - void disable_controls_menuitem(); - private: - void add_node(CountedPtr<NodeModel> object); - void remove_node(const string& name); + friend class ControllerFactory; + PatchController(CountedPtr<PatchModel> model); - NodeController* create_controller_for_node(CountedPtr<NodeModel> node); + void destroy(); + void add_node(CountedPtr<NodeModel> object); + PatchPropertiesWindow* m_properties_window; - PatchWindow* m_window; ///< Patch Window currently showing m_patch_view - PatchView* m_patch_view; ///< View (canvas) of this patch + // 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; diff --git a/src/progs/ingenuity/PatchPropertiesWindow.cpp b/src/progs/ingenuity/PatchPropertiesWindow.cpp index ec440c15..2271cc21 100644 --- a/src/progs/ingenuity/PatchPropertiesWindow.cpp +++ b/src/progs/ingenuity/PatchPropertiesWindow.cpp @@ -24,7 +24,6 @@ using std::string; PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) : Gtk::Window(cobject) -, m_patch_model(NULL) { glade_xml->get_widget("properties_author_entry", m_author_entry); glade_xml->get_widget("properties_description_textview", m_textview); diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp index 0f8c947a..090aba18 100644 --- a/src/progs/ingenuity/PatchTreeWindow.cpp +++ b/src/progs/ingenuity/PatchTreeWindow.cpp @@ -23,6 +23,7 @@ #include "Store.h" #include "SubpatchModule.h" #include "PatchModel.h" +#include "WindowFactory.h" #include "util/Path.h" namespace Ingenuity { @@ -74,14 +75,14 @@ PatchTreeWindow::init(Store& store) void PatchTreeWindow::new_object(CountedPtr<ObjectModel> object) { - CountedPtr<PatchModel> patch = object; - if (patch && dynamic_cast<PatchController*>(patch->controller())) - add_patch(dynamic_cast<PatchController*>(patch->controller())); + CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object); + if (patch) + add_patch(PtrCast<PatchController>(patch->controller())); } void -PatchTreeWindow::add_patch(PatchController* pc) +PatchTreeWindow::add_patch(CountedPtr<PatchController> pc) { const CountedPtr<PatchModel> pm = pc->patch_model(); @@ -89,7 +90,7 @@ PatchTreeWindow::add_patch(PatchController* pc) Gtk::TreeModel::iterator iter = m_patch_treestore->append(); Gtk::TreeModel::Row row = *iter; if (pm->path() == "/") { - CountedPtr<OSCEngineSender> osc_sender = App::instance().engine(); + CountedPtr<OSCEngineSender> osc_sender = PtrCast<OSCEngineSender>(App::instance().engine()); string root_name = osc_sender ? osc_sender->engine_url() : "Internal"; // Hack off trailing '/' if it's there (ugly) //if (root_name.substr(root_name.length()-1,1) == "/") @@ -130,10 +131,8 @@ PatchTreeWindow::remove_patch(const Path& path) Gtk::TreeModel::iterator PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) { - PatchController* pc = NULL; - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - pc = (*c)[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = (*c)[m_patch_tree_columns.patch_controller_col]; if (pc->model()->path() == path) { return c; } else if ((*c)->children().size() > 0) { @@ -152,7 +151,7 @@ PatchTreeWindow::event_patch_selected() Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; } } */ @@ -166,8 +165,8 @@ PatchTreeWindow::show_patch_menu(GdkEventButton* ev) Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected(); if (active) { Gtk::TreeModel::Row row = *active; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; - if (pc != NULL) + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; + if (pc) pc->show_menu(ev); } } @@ -178,9 +177,9 @@ 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; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; - pc->show_patch_window(); + App::instance().window_factory()->present(pc); } @@ -191,10 +190,10 @@ 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; - PatchController* pc = row[m_patch_tree_columns.patch_controller_col]; + CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col]; Glib::ustring patch_path = pc->model()->path(); - assert(pc != NULL); + assert(pc); if ( ! pc->patch_model()->enabled()) { if (m_enable_signal) diff --git a/src/progs/ingenuity/PatchTreeWindow.h b/src/progs/ingenuity/PatchTreeWindow.h index a43703a7..d23c4e54 100644 --- a/src/progs/ingenuity/PatchTreeWindow.h +++ b/src/progs/ingenuity/PatchTreeWindow.h @@ -50,7 +50,7 @@ public: void patch_disabled(const Path& path); void patch_renamed(const Path& old_path, const Path& new_path); - void add_patch(PatchController* pc); + void add_patch(CountedPtr<PatchController> pc); void remove_patch(const Path& path); void show_patch_menu(GdkEventButton* ev); @@ -68,9 +68,9 @@ protected: PatchTreeModelColumns() { add(name_col); add(enabled_col); add(patch_controller_col); } - Gtk::TreeModelColumn<Glib::ustring> name_col; - Gtk::TreeModelColumn<bool> enabled_col; - Gtk::TreeModelColumn<PatchController*> patch_controller_col; + Gtk::TreeModelColumn<Glib::ustring> name_col; + Gtk::TreeModelColumn<bool> enabled_col; + Gtk::TreeModelColumn<CountedPtr<PatchController> > patch_controller_col; }; bool m_enable_signal; diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp index bce44369..90c0083e 100644 --- a/src/progs/ingenuity/PatchView.cpp +++ b/src/progs/ingenuity/PatchView.cpp @@ -52,36 +52,34 @@ PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::X xml->get_widget("patch_view_zoom_full_but", _zoom_full_but); xml->get_widget("patch_view_zoom_normal_but", _zoom_normal_but); xml->get_widget("patch_view_scrolledwindow", _canvas_scrolledwindow); - - _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); } -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ void PatchView::patch_controller(PatchController* pc) { - //m_patch = new PatchController(pm, controller); _patch = pc; - _canvas = new OmFlowCanvas(pc, 1600*2, 1200*2); _canvas_scrolledwindow->add(*_canvas); - //_canvas->show(); - //_canvas_scrolledwindow->show(); _poly_spin->set_value(pc->patch_model()->poly()); - + _destroy_but->set_sensitive(pc->path() != "/"); //_description_window->patch_model(pc->model()); + pc->patch_model()->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable)); pc->patch_model()->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable)); + + _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( + static_cast<FlowCanvas*>(_canvas), &FlowCanvas::set_zoom), 1.0)); - _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::set_zoom), 1.0)); - _zoom_full_but->signal_clicked().connect(sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::zoom_full)); + _zoom_full_but->signal_clicked().connect( + sigc::mem_fun(static_cast<FlowCanvas*>(_canvas), &FlowCanvas::zoom_full)); } @@ -108,6 +106,11 @@ PatchView::process_toggled() } } +void +PatchView::clear_clicked() +{ + App::instance().engine()->clear_patch(_patch->path()); +} void PatchView::enable() diff --git a/src/progs/ingenuity/PatchView.h b/src/progs/ingenuity/PatchView.h index 3c507b94..59e16aad 100644 --- a/src/progs/ingenuity/PatchView.h +++ b/src/progs/ingenuity/PatchView.h @@ -63,7 +63,7 @@ public: PatchController* patch_controller() const { return _patch; } Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } void show_control_window(); - void process_toggled(); + void enable(); void disable(); @@ -71,6 +71,9 @@ public: void zoom_full(); private: + void process_toggled(); + void clear_clicked(); + PatchController* _patch; OmFlowCanvas* _canvas; diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index 2dfcded0..c395c265 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -20,7 +20,6 @@ #include <fstream> #include "App.h" #include "ModelEngineInterface.h" -#include "PatchView.h" #include "OmFlowCanvas.h" #include "PatchController.h" #include "LoadPluginWindow.h" @@ -37,13 +36,15 @@ #include "Store.h" #include "ConnectWindow.h" #include "Loader.h" +#include "ControllerFactory.h" +#include "WindowFactory.h" +#include "PatchView.h" namespace Ingenuity { PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : Gtk::Window(cobject), - m_patch(NULL), m_load_plugin_window(NULL), m_new_subpatch_window(NULL), m_enable_signal(true), @@ -75,6 +76,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad 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); @@ -96,8 +98,6 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad sigc::mem_fun(this, &PatchWindow::event_save)); m_menu_save_as->signal_activate().connect( sigc::mem_fun(this, &PatchWindow::event_save_as)); - m_menu_close->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_close)); m_menu_quit->signal_activate().connect( sigc::mem_fun(this, &PatchWindow::event_quit)); m_menu_configuration->signal_activate().connect( @@ -125,7 +125,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad sigc::mem_fun<void>(App::instance().about_dialog(), &Gtk::Dialog::present)); m_breadcrumb_box = new BreadCrumbBox(); - m_breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::patch)); + m_breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::set_patch_from_path)); App::instance().add_patch_window(this); } @@ -133,38 +133,32 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad PatchWindow::~PatchWindow() { + // Prevents deletion + 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; } -/** Set the patch controller from a Path (for BreadCrumbs) +/** Set the patch controller from a Path (for use by eg. BreadCrumbBox) */ void -PatchWindow::patch(const Path& path) +PatchWindow::set_patch_from_path(const Path& path) { - CountedPtr<PatchModel> model = App::instance().store()->object(path); + CountedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path)); if (!model) return; // can't really do anything useful.. - PatchController* pc = dynamic_cast<PatchController*>(model->controller()); - - if (!pc) { - pc = new PatchController(model); - model->set_controller(pc); - } - + CountedPtr<PatchController> pc = PtrCast<PatchController>(ControllerFactory::get_controller(model)); assert(pc); - if (pc->window() != NULL && pc->window()->is_visible()) { - pc->show_patch_window(); - } else { - patch_controller(pc); - } + App::instance().window_factory()->present(pc, this); } @@ -173,20 +167,15 @@ PatchWindow::patch(const Path& path) * This function MUST be called before using the window in any way! */ void -PatchWindow::patch_controller(PatchController* pc) +PatchWindow::set_patch(CountedPtr<PatchController> pc) { if (!pc || pc == m_patch) return; m_enable_signal = false; - assert(pc); - assert(m_patch != pc); - assert(m_patch == NULL || - pc->model()->path() != m_patch->model()->path()); - - PatchController* old_pc = m_patch; - if (old_pc != NULL) { + 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); @@ -194,12 +183,8 @@ PatchWindow::patch_controller(PatchController* pc) m_patch = pc; - if (pc->view() == NULL) - pc->create_view(); - assert(pc->view()); - - PatchView* const patch_view = pc->view(); - assert(patch_view != NULL); + CountedPtr<PatchView> patch_view = pc->get_view(); + assert(patch_view); patch_view->reparent(*m_viewport); if (m_breadcrumb_box->get_parent()) @@ -217,10 +202,10 @@ PatchWindow::patch_controller(PatchController* pc) assert(m_load_patch_window != NULL); assert(m_load_subpatch_window != NULL); - m_load_patch_window->patch_controller(m_patch); - m_load_plugin_window->patch_controller(m_patch); - m_new_subpatch_window->patch_controller(m_patch); - m_load_subpatch_window->patch_controller(m_patch); + 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(); @@ -239,7 +224,6 @@ PatchWindow::patch_controller(PatchController* pc) else m_menu_destroy_patch->set_sensitive(true); - assert(old_pc == NULL || old_pc->window() != this); assert(m_patch == pc); assert(m_patch->window() == this); @@ -247,7 +231,6 @@ PatchWindow::patch_controller(PatchController* pc) } - void PatchWindow::event_show_engine() { @@ -272,58 +255,6 @@ PatchWindow::event_show_properties() } -/** Notification a node has been removed from the PatchView this window - * currently contains. - * - * This is used to update the breadcrumbs in case the Node is a patch which has - * a button present in the breadcrumbs that needs to be removed. - */ -void -PatchWindow::node_removed(const string& name) -{ - throw; // FIXME -/* - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == m_patch->model()->base_path() + name) { - for (list<BreadCrumb*>::iterator j = i; j != m_breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = m_breadcrumbs.erase(j); - m_breadcrumb_box->remove(*bc); - } - break; - } - }*/ -} - - -/** Same as @a node_removed, but for renaming. - */ -void -PatchWindow::node_renamed(const string& old_path, const string& new_path) -{ - throw; // FIXME - /* - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == old_path) - (*i)->set_path(new_path); - }*/ -} - - -/** Notification the patch this window is currently showing was renamed. - */ -void -PatchWindow::patch_renamed(const string& new_path) -{ - throw; // FIXME - /* - set_title(new_path); - for (list<BreadCrumb*>::iterator i = m_breadcrumbs.begin(); i != m_breadcrumbs.end(); ++i) { - if ((*i)->path() == m_patch->path()) - (*i)->set_path(new_path); - }*/ -} - /* void PatchWindow::event_open() @@ -344,7 +275,7 @@ PatchWindow::event_import() void PatchWindow::event_save() { - PatchModel* const model = m_patch->patch_model().get(); + CountedPtr<PatchModel> model(m_patch->patch_model().get()); if (model->filename() == "") event_save_as(); @@ -404,7 +335,7 @@ PatchWindow::event_save_as() fin.close(); if (confirm) { - App::instance().loader()->save_patch(m_patch->patch_model().get(), filename, recursive); + App::instance().loader()->save_patch(m_patch->patch_model(), filename, recursive); m_patch->patch_model()->filename(filename); } } @@ -433,20 +364,12 @@ PatchWindow::on_hide() bool -PatchWindow::on_delete_event(GdkEventAny* ev) -{ - event_close(); - return true; // destroy window -} - - -bool PatchWindow::on_key_press_event(GdkEventKey* event) { if (event->keyval == GDK_Delete) { - if (m_patch != NULL && m_patch->view() != NULL) { - assert(m_patch->view()->canvas() != NULL); - m_patch->view()->canvas()->destroy_selected(); + if (m_patch && m_patch->get_view()) { + assert(m_patch->get_view()->canvas()); + m_patch->get_view()->canvas()->destroy_selected(); } return true; } else { @@ -456,27 +379,6 @@ PatchWindow::on_key_press_event(GdkEventKey* event) void -PatchWindow::event_close() -{ - if (App::instance().num_open_patch_windows() > 1) { - hide(); - } else { - Gtk::MessageDialog d(*this, "This is the last remaining open patch " - "window. Closing this window will exit Ingenuity (the engine will " - "remain running).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - App::instance().quit(); - else - d.hide(); - } -} - - -void PatchWindow::event_quit() { Gtk::MessageDialog d(*this, "Would you like to quit just Ingenuity\nor kill the engine as well?", diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h index 07a3e92e..d538db78 100644 --- a/src/progs/ingenuity/PatchWindow.h +++ b/src/progs/ingenuity/PatchWindow.h @@ -23,9 +23,11 @@ #include <libglademm/xml.h> #include <libglademm.h> #include "util/Path.h" - +#include "util/CountedPtr.h" +#include "PatchController.h" using std::string; using std::list; + namespace Ingen { namespace Client { class PatchModel; class NodeModel; @@ -40,7 +42,6 @@ namespace Ingenuity { class PatchController; class OmFlowCanvas; -class PatchView; class LoadPluginWindow; class LoadPatchWindow; class NewSubpatchWindow; @@ -63,18 +64,13 @@ public: PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); ~PatchWindow(); - void patch(const Path& path); - void patch_controller(PatchController* pc); + void set_patch_from_path(const Path& path); + void set_patch(CountedPtr<PatchController> pc); - 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; } - - // Breadcrumb management - void node_removed(const string& name); - void node_renamed(const string& old_path, const string& new_path); - void patch_renamed(const string& new_path); + 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; } Gtk::MenuItem* menu_view_control_window() { return m_menu_view_control_window; } @@ -83,14 +79,12 @@ public: protected: void on_show(); void on_hide(); - bool on_delete_event(GdkEventAny* ev); bool on_key_press_event(GdkEventKey* event); private: void event_import(); void event_save(); void event_save_as(); - void event_close(); void event_quit(); void event_destroy(); void event_clear(); @@ -99,7 +93,8 @@ private: void event_show_controls(); void event_show_engine(); - PatchController* m_patch; + CountedPtr<PatchController> m_patch; + LoadPluginWindow* m_load_plugin_window; LoadPatchWindow* m_load_patch_window; NewSubpatchWindow* m_new_subpatch_window; diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp index 6a23169f..167cb594 100644 --- a/src/progs/ingenuity/PortController.cpp +++ b/src/progs/ingenuity/PortController.cpp @@ -34,9 +34,6 @@ PortController::PortController(CountedPtr<PortModel> model) { assert(model); assert(model->parent()); - assert(model->controller() == NULL); - - model->set_controller(this); } @@ -44,8 +41,8 @@ void PortController::destroy() { assert(m_model->parent()); - NodeController* parent = (NodeController*)m_model->parent()->controller(); - assert(parent != NULL); + CountedPtr<NodeController> parent = PtrCast<NodeController>(m_model->parent()->controller()); + assert(parent); parent->remove_port(path(), false); } @@ -73,7 +70,7 @@ PortController::create_module(OmFlowCanvas* canvas) m_module = new OmPortModule(canvas, this, x, y); - if (CountedPtr<PatchModel>(port_model()->parent())) { + if (PtrCast<PatchModel>(port_model()->parent())) { if (m_patch_port) delete m_patch_port; diff --git a/src/progs/ingenuity/PortController.h b/src/progs/ingenuity/PortController.h index 1a58491b..e28cd21d 100644 --- a/src/progs/ingenuity/PortController.h +++ b/src/progs/ingenuity/PortController.h @@ -47,7 +47,6 @@ class OmFlowCanvas; class PortController : public GtkObjectController { public: - PortController(CountedPtr<PortModel> model); virtual ~PortController() {} virtual void destroy(); @@ -63,9 +62,12 @@ public: void set_path(const Path& new_path); - CountedPtr<PortModel> port_model() const { return m_model; } + 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 diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp index dfe4b07b..7a458e31 100644 --- a/src/progs/ingenuity/RenameWindow.cpp +++ b/src/progs/ingenuity/RenameWindow.cpp @@ -70,7 +70,7 @@ RenameWindow::name_changed() 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()->base_path() + name)) { + } else if (App::instance().store()->object(m_object->model()->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) { diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp index d0492618..598cc9db 100644 --- a/src/progs/ingenuity/SubpatchModule.cpp +++ b/src/progs/ingenuity/SubpatchModule.cpp @@ -26,51 +26,46 @@ #include "OmFlowCanvas.h" #include "PatchController.h" #include "OmPort.h" +#include "WindowFactory.h" using std::cerr; using std::cout; using std::endl; namespace Ingenuity { -SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, PatchController* patch) -: OmModule(canvas, patch), +SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> patch) +: OmModule(canvas, patch.get()), m_patch(patch) { - assert(canvas != NULL); - assert(patch != NULL); + assert(canvas); + assert(patch); } void SubpatchModule::on_double_click(GdkEventButton* event) { - assert(m_patch != NULL); - - // If window is visible - if (m_patch->window() != NULL - && m_patch->window()->is_visible()) { - m_patch->show_patch_window(); // just raise it - // No window visible - } else { - if (event->state & GDK_SHIFT_MASK) - m_patch->show_patch_window(); // open a new window - else - browse_to_patch(); - } + assert(m_patch); + + CountedPtr<PatchController> parent = PtrCast<PatchController>(m_patch->model()->parent()->controller()); + + PatchWindow* const preferred + = (event->state & GDK_SHIFT_MASK) ? NULL : parent->window(); + + App::instance().window_factory()->present(m_patch, preferred); } -/** Browse to this patch in current (parent's) window. */ +/** Browse to this patch in current (parent's) window + * (unless an existing window is displaying it) + */ void SubpatchModule::browse_to_patch() { assert(m_patch->model()->parent()); - PatchController* pc = (PatchController*)m_patch->model()->parent()->controller(); - assert(pc != NULL); - assert(pc->window() != NULL); + CountedPtr<PatchController> pc = PtrCast<PatchController>(m_patch->model()->parent()->controller()); - assert(pc->window() != NULL); - pc->window()->patch_controller(m_patch); + App::instance().window_factory()->present(m_patch, pc->window()); } diff --git a/src/progs/ingenuity/SubpatchModule.h b/src/progs/ingenuity/SubpatchModule.h index c530311e..a8e6e971 100644 --- a/src/progs/ingenuity/SubpatchModule.h +++ b/src/progs/ingenuity/SubpatchModule.h @@ -21,6 +21,7 @@ #include <string> #include <libgnomecanvasmm.h> #include "OmModule.h" +#include "util/CountedPtr.h" #include "PatchController.h" using std::string; using std::list; @@ -36,7 +37,6 @@ namespace Ingenuity { class OmFlowCanvas; class NodeControlWindow; -class PatchController; /** A module to represent a subpatch @@ -46,7 +46,7 @@ class PatchController; class SubpatchModule : public OmModule { public: - SubpatchModule(OmFlowCanvas* canvas, PatchController* controller); + SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> controller); virtual ~SubpatchModule() {} void on_double_click(GdkEventButton* ev); @@ -55,10 +55,10 @@ public: void browse_to_patch(); void menu_remove(); - PatchController* patch() { return m_patch; } + CountedPtr<PatchController> patch() { return m_patch; } protected: - PatchController* m_patch; + CountedPtr<PatchController> m_patch; }; diff --git a/src/progs/ingenuity/WindowFactory.cpp b/src/progs/ingenuity/WindowFactory.cpp new file mode 100644 index 00000000..6a913663 --- /dev/null +++ b/src/progs/ingenuity/WindowFactory.cpp @@ -0,0 +1,108 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "WindowFactory.h" +#include "PatchWindow.h" +#include "GladeFactory.h" +#include "App.h" + +namespace Ingenuity { + + +/** Present a PatchWindow for a Patch. + * + * If @a preferred is not NULL, it will be set to display @a patch if the patch + * does not already have a visible window, otherwise that window will be presented and + * @a preferred left unmodified. + */ +void +WindowFactory::present(CountedPtr<PatchController> patch, PatchWindow* preferred) +{ + std::map<Path, PatchWindow*>::iterator w = _windows.find(patch->model()->path()); + + if (w != _windows.end()) { + (*w).second->present(); + } else if (preferred) { + w = _windows.find(preferred->patch_controller()->model()->path()); + assert((*w).second == preferred); + + preferred->set_patch(patch); + _windows.erase(w); + _windows[patch->model()->path()] = preferred; + preferred->present(); + + } else { + PatchWindow* win = create_new(patch); + win->present(); + } +} + + +PatchWindow* +WindowFactory::create_new(CountedPtr<PatchController> patch) +{ + // 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(); + + PatchWindow* win = NULL; + xml->get_widget_derived("patch_win", win); + assert(win); + + win->set_patch(patch); + _windows[patch->model()->path()] = win; + + win->signal_delete_event().connect(sigc::bind<0>( + sigc::mem_fun(this, &WindowFactory::remove), win)); + + cerr << "Created window - count: " << _windows.size() << endl; + + return win; +} + + +bool +WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored) +{ + if (_windows.size() <= 1) { + Gtk::MessageDialog d(*win, "This is the last remaining open patch " + "window. Closing this window will exit Ingenuity (the engine will " + "remain running).\n\nAre you sure you want to quit?", + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); + d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); + int ret = d.run(); + if (ret == Gtk::RESPONSE_CLOSE) + App::instance().quit(); + else + return false; + } + + std::map<Path, PatchWindow*>::iterator w + = _windows.find(win->patch_controller()->model()->path()); + + assert((*w).second == win); + _windows.erase(w); + + delete win; + + cerr << "Removed window " << win << "- count: " << _windows.size() << endl; + + return true; +} + +} // namespace Ingenuity diff --git a/src/progs/ingenuity/WindowFactory.h b/src/progs/ingenuity/WindowFactory.h new file mode 100644 index 00000000..add2d97b --- /dev/null +++ b/src/progs/ingenuity/WindowFactory.h @@ -0,0 +1,42 @@ +/* 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 WINDOW_FACTORY_H +#define WINDOW_FACTORY_H + +#include <map> +#include "util/CountedPtr.h" +#include "PatchController.h" + +namespace Ingenuity { + +class PatchWindow; + + +class WindowFactory { +public: + void present(CountedPtr<PatchController> patch, PatchWindow* preferred = NULL); + +private: + PatchWindow* create_new(CountedPtr<PatchController> patch); + bool remove(PatchWindow* win, GdkEventAny* ignored); + + std::map<Path, PatchWindow*> _windows; +}; + +} + +#endif // WINDOW_FACTORY_H diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade index 84540c7c..2221a805 100644 --- a/src/progs/ingenuity/ingenuity.glade +++ b/src/progs/ingenuity/ingenuity.glade @@ -1770,7 +1770,7 @@ <property name="spacing">0</property> <child> - <widget class="GtkToolbar" id="toolbar4"> + <widget class="GtkToolbar" id="patch_view_crumb_toolbar"> <property name="visible">True</property> <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> @@ -1822,7 +1822,7 @@ </child> <child> - <widget class="GtkToolbar" id="toolbar2"> + <widget class="GtkToolbar" id="patch_view_toolbar"> <property name="visible">True</property> <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> <property name="toolbar_style">GTK_TOOLBAR_ICONS</property> @@ -1942,7 +1942,8 @@ <child> <widget class="GtkToolButton" id="patch_view_clear_but"> <property name="visible">True</property> - <property name="tooltip" translatable="yes">Destroy all children nodes (twice to clear ports as well)</property> + <property name="tooltip" translatable="yes">Destroy all children nodes +(Click twice to clear ports as well)</property> <property name="label" translatable="yes"></property> <property name="use_underline">True</property> <property name="stock_id">gtk-clear</property> diff --git a/src/progs/patch_loader/patch_loader.cpp b/src/progs/patch_loader/patch_loader.cpp index 105a379c..f7464840 100644 --- a/src/progs/patch_loader/patch_loader.cpp +++ b/src/progs/patch_loader/patch_loader.cpp @@ -52,29 +52,28 @@ int main(int argc, char** argv) /* **** Mr. Spock.. Engage **** */ - OSCModelEngineInterface engine(engine_url); - PatchLibrarian librarian(&engine); + CountedPtr<OSCModelEngineInterface> engine(new OSCModelEngineInterface(engine_url)); + PatchLibrarian librarian(engine); /* Connect to engine */ - engine.attach(-1, client_port); - engine.activate(); - //engine.register_client(NULL); // FIXME + engine->attach(-1, client_port); + engine->activate(); + //engine->register_client(NULL); // FIXME - //int id = engine.get_next_request_id(); - //engine.set_wait_response_id(id); - //engine.load_plugins(id); - //engine.wait_for_response(); + //int id = engine->get_next_request_id(); + //engine->set_wait_response_id(id); + //engine->load_plugins(id); + //engine->wait_for_response(); /* FIXME: Make this work like this: - * engine.load_plugins(); - * engine.wait_for_response(); + * engine->load_plugins(); + * engine->wait_for_response(); */ // Load patches for (uint i=0; i < args_info.inputs_num; ++i) { - PatchModel* pm = new PatchModel("", 0); + CountedPtr<PatchModel> pm(new PatchModel("", 0)); pm->filename(args_info.inputs[i]); librarian.load_patch(pm, true); - delete pm; } return 0; diff --git a/src/progs/server/Makefile.am b/src/progs/server/Makefile.am index fc5b770b..e2a38742 100644 --- a/src/progs/server/Makefile.am +++ b/src/progs/server/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events -fno-exceptions +AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ @LASH_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/libs/engine -I$(top_srcdir)/src/libs/engine/events MAINTAINERCLEANFILES = Makefile.in diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp index cd79a7b4..c33014a5 100644 --- a/src/progs/server/main.cpp +++ b/src/progs/server/main.cpp @@ -137,7 +137,7 @@ main(int argc, char** argv) set_denormal_flags(); - engine = new Engine(); + engine = CountedPtr<Engine>(new Engine()); OSCEngineReceiver* receiver = new OSCEngineReceiver( engine, pre_processor_queue_size, args_info.port_arg); |