summaryrefslogtreecommitdiffstats
path: root/src/progs/ingenuity
diff options
context:
space:
mode:
Diffstat (limited to 'src/progs/ingenuity')
-rw-r--r--src/progs/ingenuity/App.cpp5
-rw-r--r--src/progs/ingenuity/App.h8
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.cpp39
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.h3
-rw-r--r--src/progs/ingenuity/ConnectWindow.cpp8
-rw-r--r--src/progs/ingenuity/ControlGroups.cpp12
-rw-r--r--src/progs/ingenuity/ControlPanel.cpp19
-rw-r--r--src/progs/ingenuity/ControlPanel.h2
-rw-r--r--src/progs/ingenuity/ControllerFactory.cpp72
-rw-r--r--src/progs/ingenuity/ControllerFactory.h32
-rw-r--r--src/progs/ingenuity/DSSIModule.cpp4
-rw-r--r--src/progs/ingenuity/GtkObjectController.cpp2
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.cpp5
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.h8
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.cpp13
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.h4
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.cpp11
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.h6
-rw-r--r--src/progs/ingenuity/Loader.cpp4
-rw-r--r--src/progs/ingenuity/Loader.h24
-rw-r--r--src/progs/ingenuity/Makefile.am4
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.cpp10
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.h7
-rw-r--r--src/progs/ingenuity/NodeController.cpp59
-rw-r--r--src/progs/ingenuity/NodeController.h18
-rw-r--r--src/progs/ingenuity/NodePropertiesWindow.cpp1
-rw-r--r--src/progs/ingenuity/OmFlowCanvas.cpp27
-rw-r--r--src/progs/ingenuity/OmModule.cpp4
-rw-r--r--src/progs/ingenuity/OmModule.h1
-rw-r--r--src/progs/ingenuity/OmPatchPort.cpp2
-rw-r--r--src/progs/ingenuity/OmPort.cpp2
-rw-r--r--src/progs/ingenuity/PatchController.cpp281
-rw-r--r--src/progs/ingenuity/PatchController.h35
-rw-r--r--src/progs/ingenuity/PatchPropertiesWindow.cpp1
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.cpp29
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.h8
-rw-r--r--src/progs/ingenuity/PatchView.cpp29
-rw-r--r--src/progs/ingenuity/PatchView.h5
-rw-r--r--src/progs/ingenuity/PatchWindow.cpp154
-rw-r--r--src/progs/ingenuity/PatchWindow.h27
-rw-r--r--src/progs/ingenuity/PortController.cpp9
-rw-r--r--src/progs/ingenuity/PortController.h6
-rw-r--r--src/progs/ingenuity/RenameWindow.cpp2
-rw-r--r--src/progs/ingenuity/SubpatchModule.cpp41
-rw-r--r--src/progs/ingenuity/SubpatchModule.h8
-rw-r--r--src/progs/ingenuity/WindowFactory.cpp108
-rw-r--r--src/progs/ingenuity/WindowFactory.h42
-rw-r--r--src/progs/ingenuity/ingenuity.glade7
48 files changed, 645 insertions, 563 deletions
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>