summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/interface/ClientInterface.h3
-rw-r--r--src/common/interface/EngineInterface.h2
-rw-r--r--src/common/util/Path.h4
-rw-r--r--src/libs/client/ModelClientInterface.cpp12
-rw-r--r--src/libs/client/ModelEngineInterface.cpp4
-rw-r--r--src/libs/client/NodeModel.cpp58
-rw-r--r--src/libs/client/NodeModel.h67
-rw-r--r--src/libs/client/OSCClientReceiver.cpp11
-rw-r--r--src/libs/client/OSCEngineSender.cpp15
-rw-r--r--src/libs/client/OSCEngineSender.h2
-rw-r--r--src/libs/client/ObjectController.h45
-rw-r--r--src/libs/client/ObjectModel.cpp32
-rw-r--r--src/libs/client/ObjectModel.h61
-rw-r--r--src/libs/client/PatchLibrarian.cpp76
-rw-r--r--src/libs/client/PatchModel.cpp32
-rw-r--r--src/libs/client/PatchModel.h24
-rw-r--r--src/libs/client/PortModel.h31
-rw-r--r--src/libs/client/SigClientInterface.h2
-rw-r--r--src/libs/client/Store.cpp16
-rw-r--r--src/libs/client/Store.h3
-rw-r--r--src/libs/client/ThreadedSigClientInterface.h5
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp2
-rw-r--r--src/libs/engine/ClientBroadcaster.h2
-rw-r--r--src/libs/engine/DSSINode.h12
-rw-r--r--src/libs/engine/GraphObject.h19
-rw-r--r--src/libs/engine/LADSPANode.cpp9
-rw-r--r--src/libs/engine/OSCClientSender.cpp10
-rw-r--r--src/libs/engine/OSCClientSender.h2
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp9
-rw-r--r--src/libs/engine/ObjectSender.cpp16
-rw-r--r--src/libs/engine/QueuedEngineInterface.cpp2
-rw-r--r--src/libs/engine/QueuedEngineInterface.h2
-rw-r--r--src/libs/engine/events/DSSIConfigureEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestMetadataEvent.cpp5
-rw-r--r--src/libs/engine/events/RequestMetadataEvent.h6
-rw-r--r--src/libs/engine/events/SetMetadataEvent.cpp2
-rw-r--r--src/libs/engine/events/SetMetadataEvent.h9
-rw-r--r--src/progs/demolition/demolition.cpp15
-rw-r--r--src/progs/ingenuity/App.cpp5
-rw-r--r--src/progs/ingenuity/App.h4
-rw-r--r--src/progs/ingenuity/BreadCrumb.h33
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.cpp58
-rw-r--r--src/progs/ingenuity/BreadCrumbBox.h10
-rw-r--r--src/progs/ingenuity/ConfigWindow.cpp2
-rw-r--r--src/progs/ingenuity/Configuration.cpp2
-rw-r--r--src/progs/ingenuity/ConnectWindow.cpp5
-rw-r--r--src/progs/ingenuity/ControlGroups.cpp40
-rw-r--r--src/progs/ingenuity/ControlGroups.h2
-rw-r--r--src/progs/ingenuity/ControlPanel.cpp8
-rw-r--r--src/progs/ingenuity/ControlPanel.h6
-rw-r--r--src/progs/ingenuity/ControllerFactory.cpp72
-rw-r--r--src/progs/ingenuity/ControllerFactory.h32
-rw-r--r--src/progs/ingenuity/DSSIController.cpp33
-rw-r--r--src/progs/ingenuity/DSSIController.h13
-rw-r--r--src/progs/ingenuity/DSSIModule.cpp6
-rw-r--r--src/progs/ingenuity/DSSIModule.h2
-rw-r--r--src/progs/ingenuity/GtkObjectController.cpp34
-rw-r--r--src/progs/ingenuity/GtkObjectController.h83
-rw-r--r--src/progs/ingenuity/LashController.cpp1
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.cpp23
-rw-r--r--src/progs/ingenuity/LoadPatchWindow.h16
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.cpp38
-rw-r--r--src/progs/ingenuity/LoadPluginWindow.h17
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.cpp45
-rw-r--r--src/progs/ingenuity/LoadSubpatchWindow.h17
-rw-r--r--src/progs/ingenuity/Loader.cpp1
-rw-r--r--src/progs/ingenuity/Makefile.am18
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.cpp34
-rw-r--r--src/progs/ingenuity/NewSubpatchWindow.h17
-rw-r--r--src/progs/ingenuity/NodeControlWindow.cpp8
-rw-r--r--src/progs/ingenuity/NodeControlWindow.h20
-rw-r--r--src/progs/ingenuity/NodeController.cpp404
-rw-r--r--src/progs/ingenuity/NodeController.h116
-rw-r--r--src/progs/ingenuity/NodeMenu.cpp254
-rw-r--r--src/progs/ingenuity/NodeMenu.h75
-rw-r--r--src/progs/ingenuity/NodePropertiesWindow.h4
-rw-r--r--src/progs/ingenuity/OmFlowCanvas.cpp162
-rw-r--r--src/progs/ingenuity/OmFlowCanvas.h39
-rw-r--r--src/progs/ingenuity/OmModule.cpp109
-rw-r--r--src/progs/ingenuity/OmModule.h21
-rw-r--r--src/progs/ingenuity/OmPatchPort.h1
-rw-r--r--src/progs/ingenuity/OmPort.h1
-rw-r--r--src/progs/ingenuity/OmPortModule.cpp48
-rw-r--r--src/progs/ingenuity/OmPortModule.h12
-rw-r--r--src/progs/ingenuity/PatchController.cpp548
-rw-r--r--src/progs/ingenuity/PatchController.h124
-rw-r--r--src/progs/ingenuity/PatchPropertiesWindow.cpp26
-rw-r--r--src/progs/ingenuity/PatchPropertiesWindow.h3
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.cpp37
-rw-r--r--src/progs/ingenuity/PatchTreeWindow.h7
-rw-r--r--src/progs/ingenuity/PatchView.cpp56
-rw-r--r--src/progs/ingenuity/PatchView.h32
-rw-r--r--src/progs/ingenuity/PatchWindow.cpp139
-rw-r--r--src/progs/ingenuity/PatchWindow.h24
-rw-r--r--src/progs/ingenuity/PortController.cpp139
-rw-r--r--src/progs/ingenuity/PortController.h79
-rw-r--r--src/progs/ingenuity/RenameWindow.cpp11
-rw-r--r--src/progs/ingenuity/RenameWindow.h16
-rw-r--r--src/progs/ingenuity/SubpatchModule.cpp30
-rw-r--r--src/progs/ingenuity/SubpatchModule.h8
-rw-r--r--src/progs/ingenuity/WindowFactory.cpp232
-rw-r--r--src/progs/ingenuity/WindowFactory.h56
-rw-r--r--src/progs/ingenuity/ingenuity.glade2
103 files changed, 1623 insertions, 2526 deletions
diff --git a/src/common/interface/ClientInterface.h b/src/common/interface/ClientInterface.h
index 3adc76f4..5d56fa8e 100644
--- a/src/common/interface/ClientInterface.h
+++ b/src/common/interface/ClientInterface.h
@@ -18,6 +18,7 @@
#define CLIENTINTERFACE_H
#include <inttypes.h>
+#include "util/Atom.h"
#include <string>
using std::string;
@@ -91,7 +92,7 @@ public:
virtual void metadata_update(string subject_path,
string predicate,
- string value) = 0;
+ Atom value) = 0;
virtual void control_change(string port_path,
float value) = 0;
diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h
index 46f6fa99..c86340c5 100644
--- a/src/common/interface/EngineInterface.h
+++ b/src/common/interface/EngineInterface.h
@@ -112,7 +112,7 @@ public:
virtual void set_metadata(const string& path,
const string& predicate,
- const string& value) = 0;
+ const Atom& value) = 0;
// Requests //
diff --git a/src/common/util/Path.h b/src/common/util/Path.h
index 6c6d54be..2fcf5774 100644
--- a/src/common/util/Path.h
+++ b/src/common/util/Path.h
@@ -76,6 +76,10 @@ public:
assert(path.find_last_of("/") != string::npos);
+ // Double slash not allowed
+ if (path.find("//") != string::npos)
+ return false;
+
// All characters must be printable ASCII
for (size_t i=0; i < path.length(); ++i)
if (path.at(i) < 32 || path.at(i) > 126)
diff --git a/src/libs/client/ModelClientInterface.cpp b/src/libs/client/ModelClientInterface.cpp
index deb37187..d29395e7 100644
--- a/src/libs/client/ModelClientInterface.cpp
+++ b/src/libs/client/ModelClientInterface.cpp
@@ -86,17 +86,17 @@ ModelClientInterface::new_patch(string path, uint32_t poly)
void
-ModelClientInterface::new_node(string plugin_type,
- string plugin_uri,
- string node_path,
- bool is_polyphonic,
- uint32_t num_ports)
+ModelClientInterface::new_node(string plugin_type,
+ string plugin_uri,
+ string node_path,
+ bool is_polyphonic,
+ uint32_t num_ports)
{
cerr << "FIXME: NEW NODE\n";
CountedPtr<PluginModel> plugin(new PluginModel(plugin_type, plugin_uri));
- CountedPtr<NodeModel> nm(new NodeModel(plugin, node_path));
+ CountedPtr<NodeModel> nm(new NodeModel(plugin, node_path, is_polyphonic));
new_node_model(nm);
}
diff --git a/src/libs/client/ModelEngineInterface.cpp b/src/libs/client/ModelEngineInterface.cpp
index ca92b1ac..7cc2ae22 100644
--- a/src/libs/client/ModelEngineInterface.cpp
+++ b/src/libs/client/ModelEngineInterface.cpp
@@ -65,8 +65,8 @@ ModelEngineInterface::create_patch_from_model(const PatchModel* pm)
void
ModelEngineInterface::set_all_metadata(const ObjectModel* m)
{
- for (map<string, string>::const_iterator i = m->metadata().begin(); i != m->metadata().end(); ++i)
- set_metadata(m->path(), (*i).first, (*i).second.c_str());
+ for (MetadataMap::const_iterator i = m->metadata().begin(); i != m->metadata().end(); ++i)
+ set_metadata(m->path(), i->first, i->second);
}
diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp
index 8d9d8697..55f70130 100644
--- a/src/libs/client/NodeModel.cpp
+++ b/src/libs/client/NodeModel.cpp
@@ -22,22 +22,18 @@ namespace Ingen {
namespace Client {
-NodeModel::NodeModel(CountedPtr<PluginModel> plugin, const Path& path)
+NodeModel::NodeModel(CountedPtr<PluginModel> plugin, const Path& path, bool polyphonic)
: ObjectModel(path),
- m_polyphonic(false),
+ m_polyphonic(polyphonic),
m_plugin_uri(plugin->uri()),
- m_plugin(plugin),
- m_x(0.0f),
- m_y(0.0f)
+ m_plugin(plugin)
{
}
-NodeModel::NodeModel(const string& plugin_uri, const Path& path)
+NodeModel::NodeModel(const string& plugin_uri, const Path& path, bool polyphonic)
: ObjectModel(path),
- m_polyphonic(false),
- m_plugin_uri(plugin_uri),
- m_x(0.0f),
- m_y(0.0f)
+ m_polyphonic(polyphonic),
+ m_plugin_uri(plugin_uri)
{
}
@@ -52,6 +48,7 @@ void
NodeModel::remove_port(CountedPtr<PortModel> port)
{
m_ports.remove(port);
+ removed_port_sig.emit(port);
}
@@ -78,12 +75,13 @@ NodeModel::clear()
void
NodeModel::set_path(const Path& p)
{
- const string old_path = m_path;
+ const string old_path = _path;
ObjectModel::set_path(p);
- for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i)
- (*i)->set_path(m_path + "/" + (*i)->path().name());
+ // FIXME: rename
+// for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i)
+// (*i)->set_path(_path + "/" + (*i)->path().name());
//if (m_parent && old_path.length() > 0)
// parent_patch()->rename_node(old_path, p);
@@ -104,7 +102,7 @@ NodeModel::add_child(CountedPtr<ObjectModel> c)
void
NodeModel::remove_child(CountedPtr<ObjectModel> c)
{
- assert(c->path().is_child_of(m_path));
+ assert(c->path().is_child_of(_path));
assert(c->parent().get() == this);
CountedPtr<PortModel> pm = PtrCast<PortModel>(c);
@@ -117,7 +115,7 @@ void
NodeModel::add_port(CountedPtr<PortModel> pm)
{
assert(pm);
- assert(pm->path().is_child_of(m_path));
+ assert(pm->path().is_child_of(_path));
assert(pm->parent().get() == this);
PortModelList::iterator existing = m_ports.end();
@@ -129,7 +127,7 @@ NodeModel::add_port(CountedPtr<PortModel> pm)
}
if (existing != m_ports.end()) {
- cerr << "Warning: port clash, assimilating old port " << m_path << endl;
+ cerr << "Warning: port clash, assimilating old port " << _path << endl;
pm->assimilate(*existing);
*existing = pm;
} else {
@@ -140,10 +138,10 @@ NodeModel::add_port(CountedPtr<PortModel> pm)
CountedPtr<PortModel>
-NodeModel::get_port(const string& port_name)
+NodeModel::get_port(const string& port_name) const
{
assert(port_name.find("/") == string::npos);
- for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i)
+ for (PortModelList::const_iterator i = m_ports.begin(); i != m_ports.end(); ++i)
if ((*i)->path().name() == port_name)
return (*i);
return CountedPtr<PortModel>();
@@ -166,29 +164,5 @@ NodeModel::remove_program(int bank, int program)
}
-void
-NodeModel::x(float a)
-{
- if (m_x != a) {
- m_x = a;
- char temp_buf[16];
- snprintf(temp_buf, 16, "%f", a);
- set_metadata("module-x", temp_buf);
- }
-}
-
-
-void
-NodeModel::y(float a)
-{
- if (m_y != a) {
- m_y = a;
- char temp_buf[16];
- snprintf(temp_buf, 16, "%f", a);
- set_metadata("module-y", temp_buf);
- }
-}
-
-
} // namespace Client
} // namespace Ingen
diff --git a/src/libs/client/NodeModel.h b/src/libs/client/NodeModel.h
index 60973d95..f9c87f6e 100644
--- a/src/libs/client/NodeModel.h
+++ b/src/libs/client/NodeModel.h
@@ -44,55 +44,50 @@ class PluginModel;
class NodeModel : public ObjectModel
{
public:
- NodeModel(const string& plugin_uri, const Path& path);
- NodeModel(CountedPtr<PluginModel> plugin, const Path& path);
+ NodeModel(const string& plugin_uri, const Path& path, bool polyphonic);
+ NodeModel(CountedPtr<PluginModel> plugin, const Path& path, bool polyphonic);
virtual ~NodeModel();
-
- void add_child(CountedPtr<ObjectModel> c);
- void remove_child(CountedPtr<ObjectModel> c);
-
- CountedPtr<PortModel> get_port(const string& port_name);
- void add_port(CountedPtr<PortModel> pm);
- void remove_port(CountedPtr<PortModel> pm);
- void remove_port(const string& port_path);
-
- virtual void clear();
-
- const map<int, map<int, string> >& get_programs() const { return m_banks; }
- void add_program(int bank, int program, const string& name);
- void remove_program(int bank, int program);
-
- string plugin_uri() { return m_plugin_uri; }
- CountedPtr<PluginModel> plugin() const { return m_plugin; }
- //void plugin(CountedPtr<PluginModel> p) { m_plugin = p; }
+ CountedPtr<PortModel> get_port(const string& port_name) const;
- virtual void set_path(const Path& p);
-
- int num_ports() const { return m_ports.size(); }
- const PortModelList& ports() const { return m_ports; }
- virtual bool polyphonic() const { return m_polyphonic; }
- void polyphonic(bool b) { m_polyphonic = b; }
- float x() const { return m_x; }
- float y() const { return m_y; }
- void x(float a);
- void y(float a);
+ const map<int, map<int, string> >& get_programs() const { return m_banks; }
+ const string& plugin_uri() const { return m_plugin_uri; }
+ CountedPtr<PluginModel> plugin() const { return m_plugin; }
+ int num_ports() const { return m_ports.size(); }
+ const PortModelList& ports() const { return m_ports; }
+ virtual bool polyphonic() const { return m_polyphonic; }
// Signals
sigc::signal<void, CountedPtr<PortModel> > new_port_sig;
+ sigc::signal<void, CountedPtr<PortModel> > removed_port_sig;
protected:
+ friend class Store;
NodeModel(const Path& path);
+ void add_child(CountedPtr<ObjectModel> c);
+ void remove_child(CountedPtr<ObjectModel> c);
+ void add_port(CountedPtr<PortModel> pm);
+ void remove_port(CountedPtr<PortModel> pm);
+ void remove_port(const string& port_path);
+ void add_program(int bank, int program, const string& name);
+ void remove_program(int bank, int program);
+
+
+ //void plugin(CountedPtr<PluginModel> p) { m_plugin = p; }
+ virtual void clear();
+
+ friend class PatchModel;
+ void set_path(const Path& p);
bool m_polyphonic;
- PortModelList m_ports; ///< List of ports (instead of map to preserve order)
- string m_plugin_uri; ///< Plugin URI (not redundant if PluginModel unknown
- CountedPtr<PluginModel> m_plugin; ///< The plugin this node is an instance of
- float m_x; ///< Just metadata, here as an optimization for GUI
- float m_y; ///< Just metadata, here as an optimization for GUI
- map<int, map<int, string> > m_banks; ///< DSSI banks
+ PortModelList m_ports; ///< List of ports (not a map to preserve order)
+ string m_plugin_uri; ///< Plugin URI (if PluginModel is unknown)
+ CountedPtr<PluginModel> m_plugin; ///< The plugin this node is an instance of
+ map<int, map<int, string> > m_banks; ///< DSSI banks
private:
+ friend class PatchLibrarian; // FIXME: remove
+
// Prevent copies (undefined)
NodeModel(const NodeModel& copy);
NodeModel& operator=(const NodeModel& copy);
diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp
index ae607af1..4c715c76 100644
--- a/src/libs/client/OSCClientReceiver.cpp
+++ b/src/libs/client/OSCClientReceiver.cpp
@@ -15,8 +15,7 @@
*/
#include "OSCClientReceiver.h"
-//#include "NodeModel.h"
-//#include "PluginModel.h"
+#include "util/LibloAtom.h"
#include <list>
#include <cassert>
#include <cstring>
@@ -154,7 +153,7 @@ OSCClientReceiver::setup_callbacks()
lo_server_thread_add_method(_st, "/om/disconnection", "ss", disconnection_cb, this);
lo_server_thread_add_method(_st, "/om/new_node", "sssii", new_node_cb, this);
lo_server_thread_add_method(_st, "/om/new_port", "ssi", new_port_cb, this);
- lo_server_thread_add_method(_st, "/om/metadata/update", "sss", metadata_update_cb, this);
+ lo_server_thread_add_method(_st, "/om/metadata/update", NULL, metadata_update_cb, this);
lo_server_thread_add_method(_st, "/om/control_change", "sf", control_change_cb, this);
lo_server_thread_add_method(_st, "/om/program_add", "siis", program_add_cb, this);
lo_server_thread_add_method(_st, "/om/program_remove", "sii", program_remove_cb, this);
@@ -337,9 +336,13 @@ OSCClientReceiver::m_new_port_cb(const char* path, const char* types, lo_arg** a
int
OSCClientReceiver::m_metadata_update_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
{
+ if (argc != 3 || types[0] != 's' || types[1] != 's')
+ return 1;
+
const char* obj_path = &argv[0]->s;
const char* key = &argv[1]->s;
- const char* value = &argv[2]->s;
+
+ Atom value = LibloAtom::lo_arg_to_atom(types[2], argv[2]);
metadata_update(obj_path, key, value);
diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp
index 10d9ab2e..447fa934 100644
--- a/src/libs/client/OSCEngineSender.cpp
+++ b/src/libs/client/OSCEngineSender.cpp
@@ -17,6 +17,7 @@
#include <iostream>
#include "OSCEngineSender.h"
#include "interface/ClientKey.h"
+#include "util/LibloAtom.h"
using std::cout; using std::cerr; using std::endl;
namespace Ingen {
@@ -374,14 +375,16 @@ OSCEngineSender::midi_learn(const string& node_path)
void
OSCEngineSender::set_metadata(const string& obj_path,
const string& predicate,
- const string& value)
+ const Atom& value)
{
+
assert(_engine_addr);
- lo_send(_engine_addr, "/om/metadata/set", "isss",
- next_id(),
- obj_path.c_str(),
- predicate.c_str(),
- value.c_str());
+ lo_message m = lo_message_new();
+ lo_message_add_int32(m, next_id());
+ lo_message_add_string(m, obj_path.c_str());
+ lo_message_add_string(m, predicate.c_str());
+ LibloAtom::lo_message_add_atom(m, value);
+ lo_send_message(_engine_addr, "/om/metadata/set", m);
}
diff --git a/src/libs/client/OSCEngineSender.h b/src/libs/client/OSCEngineSender.h
index 2603667a..f514097d 100644
--- a/src/libs/client/OSCEngineSender.h
+++ b/src/libs/client/OSCEngineSender.h
@@ -126,7 +126,7 @@ public:
void set_metadata(const string& obj_path,
const string& predicate,
- const string& value);
+ const Atom& value);
// Requests //
diff --git a/src/libs/client/ObjectController.h b/src/libs/client/ObjectController.h
deleted file mode 100644
index fca59a80..00000000
--- a/src/libs/client/ObjectController.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef OBJECTCONTROLLER_H
-#define OBJECTCONTROLLER_H
-
-namespace Ingen {
-namespace Client {
-
-
-/** A trivial base class for controllers of an ObjectModel.
- *
- * This is so ObjectModels can have pointers to app-specified controllers,
- * and the pointer relationships in models (ie PatchModel has pointers to
- * all it's NodeModel children, etc) can be used to find controllers of
- * Models, rather than having a parallel structure of pointers in the
- * app's controllers.
- *
- * \ingroup IngenClient
- */
-class ObjectController
-{
-public:
- virtual ~ObjectController() {}
-};
-
-
-} // namespace Client
-} // namespace Ingen
-
-
-#endif // OBJECTCONTROLLER_H
diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp
index 4a0eca0d..6e18e680 100644
--- a/src/libs/client/ObjectModel.cpp
+++ b/src/libs/client/ObjectModel.cpp
@@ -21,34 +21,38 @@ namespace Client {
ObjectModel::ObjectModel(const Path& path)
-: m_path(path)
+: _path(path)
{
}
+
ObjectModel::~ObjectModel()
{
- m_controller.reset();
}
-/** Get a piece of metadata for this objeect.
+/** Get a piece of metadata for this object.
*
* @return Metadata value with key @a key, empty string otherwise.
*/
-string
+const Atom&
ObjectModel::get_metadata(const string& key) const
{
- map<string,string>::const_iterator i = m_metadata.find(key);
- if (i != m_metadata.end())
+ static const Atom null_atom;
+
+ MetadataMap::const_iterator i = _metadata.find(key);
+ if (i != _metadata.end())
return i->second;
else
- return "";
+ return null_atom;
}
void
-ObjectModel::set_controller(CountedPtr<ObjectController> c)
+ObjectModel::add_metadata(const MetadataMap& data)
{
- m_controller = c;
+ for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) {
+ _metadata[i->first] = i->second;
+ }
}
@@ -60,13 +64,13 @@ ObjectModel::set_controller(CountedPtr<ObjectController> c)
void
ObjectModel::assimilate(CountedPtr<ObjectModel> model)
{
- assert(m_path == model->path());
+ assert(_path == model->path());
- for (map<string,string>::const_iterator i = model->metadata().begin();
+ for (MetadataMap::const_iterator i = model->metadata().begin();
i != model->metadata().end(); ++i) {
- map<string,string>::const_iterator i = m_metadata.find(i->first);
- if (i == m_metadata.end())
- m_metadata[i->first] = i->second;
+ MetadataMap::const_iterator i = _metadata.find(i->first);
+ if (i == _metadata.end())
+ _metadata[i->first] = i->second;
}
}
diff --git a/src/libs/client/ObjectModel.h b/src/libs/client/ObjectModel.h
index da3764d1..79d551f5 100644
--- a/src/libs/client/ObjectModel.h
+++ b/src/libs/client/ObjectModel.h
@@ -24,59 +24,66 @@
#include <algorithm>
#include <cassert>
#include <sigc++/sigc++.h>
+#include "util/Atom.h"
#include "util/Path.h"
#include "util/CountedPtr.h"
-#include "ObjectController.h"
using std::string; using std::map; using std::find;
using std::cout; using std::cerr; using std::endl;
namespace Ingen {
namespace Client {
-class ObjectController;
+typedef map<string, Atom> MetadataMap;
+
-
/** Base class for all GraphObject models (NodeModel, PatchModel, PortModel).
*
+ * There are no non-const public methods intentionally, models are not allowed
+ * to be manipulated directly by anything (but the Store) because of the
+ * asynchronous nature of engine control. To change something, use the
+ * controller (which the model probably shouldn't have a reference to but oh
+ * well, it reduces Collection Hell) and wait for the result (as a signal
+ * from this Model).
+ *
* \ingroup IngenClient
*/
class ObjectModel
{
public:
ObjectModel(const Path& path);
- ObjectModel() : m_path("/UNINITIALIZED") {} // FIXME: remove
virtual ~ObjectModel();
-
- const map<string, string>& metadata() const { return m_metadata; }
- string get_metadata(const string& key) const;
- void set_metadata(const string& key, const string& value)
- { assert(value.length() > 0); m_metadata[key] = value; metadata_update_sig.emit(key, value); }
-
- inline const Path& path() const { return m_path; }
- virtual void set_path(const Path& p) { m_path = p; }
-
- CountedPtr<ObjectModel> parent() const { return m_parent; }
- virtual void set_parent(CountedPtr<ObjectModel> p) { m_parent = p; }
-
- virtual void add_child(CountedPtr<ObjectModel> c) = 0;
- virtual void remove_child(CountedPtr<ObjectModel> c) = 0;
- CountedPtr<ObjectController> controller() const { return m_controller; }
-
- void set_controller(CountedPtr<ObjectController> c);
+ const Atom& get_metadata(const string& key) const;
+ void add_metadata(const MetadataMap& data);
+
+ const MetadataMap& metadata() const { return _metadata; }
+ inline const Path& path() const { return _path; }
+ CountedPtr<ObjectModel> parent() const { return _parent; }
void assimilate(CountedPtr<ObjectModel> model);
// Signals
- sigc::signal<void, const string&, const string&> metadata_update_sig;
- sigc::signal<void> destroyed_sig;
+ sigc::signal<void, const string&, const Atom&> metadata_update_sig;
+ sigc::signal<void> destroyed_sig;
+
+ // FIXME: make private
+ void set_metadata(const string& key, const Atom& value)
+ { _metadata[key] = value; metadata_update_sig.emit(key, value); }
+
+
protected:
- Path m_path;
- CountedPtr<ObjectModel> m_parent;
- CountedPtr<ObjectController> m_controller;
+ friend class Store;
+ friend class PatchLibrarian; // FIXME: remove
+ virtual void set_path(const Path& p) { _path = p; }
+ virtual void set_parent(CountedPtr<ObjectModel> p) { _parent = p; }
+ virtual void add_child(CountedPtr<ObjectModel> c) = 0;
+ virtual void remove_child(CountedPtr<ObjectModel> c) = 0;
+
+ Path _path;
+ CountedPtr<ObjectModel> _parent;
- map<string,string> m_metadata;
+ MetadataMap _metadata;
private:
// Prevent copies (undefined)
diff --git a/src/libs/client/PatchLibrarian.cpp b/src/libs/client/PatchLibrarian.cpp
index 07a98526..4db47b5b 100644
--- a/src/libs/client/PatchLibrarian.cpp
+++ b/src/libs/client/PatchLibrarian.cpp
@@ -136,7 +136,7 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
xmlNodePtr xml_root_node = NULL;
xmlNodePtr xml_node = NULL;
xmlNodePtr xml_child_node = NULL;
- xmlNodePtr xml_grandchild_node = NULL;
+ //xmlNodePtr xml_grandchild_node = NULL;
xml_doc = xmlNewDoc((xmlChar*)"1.0");
xml_root_node = xmlNewNode(NULL, (xmlChar*)"patch");
@@ -164,13 +164,14 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
xml_node = xmlNewChild(xml_root_node, NULL, (xmlChar*)"polyphony", (xmlChar*)temp_buf);
// Write metadata
- for (map<string, string>::const_iterator i = patch_model->metadata().begin();
+ for (MetadataMap::const_iterator i = patch_model->metadata().begin();
i != patch_model->metadata().end(); ++i) {
+ cerr << "FIXME: metadata save" << endl;
// Dirty hack, don't save coordinates in patch file
- if ((*i).first != "module-x" && (*i).first != "module-y"
- && (*i).first != "filename")
- xml_node = xmlNewChild(xml_root_node, NULL,
- (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());
+ //if (i->first != "module-x" && i->first != "module-y"
+ // && i->first != "filename")
+ // xml_node = xmlNewChild(xml_root_node, NULL,
+ // (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());
assert((*i).first != "node");
assert((*i).first != "subpatch");
@@ -215,13 +216,14 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"polyphony", (xmlChar*)temp_buf);
// Write metadata
- for (map<string, string>::const_iterator i = nm->metadata().begin();
+ for (MetadataMap::const_iterator i = nm->metadata().begin();
i != nm->metadata().end(); ++i) {
+ cerr << "FIXME: save metadata\n";
// Dirty hack, don't save metadata that would be in patch file
- if ((*i).first != "polyphony" && (*i).first != "filename"
+ /*if ((*i).first != "polyphony" && (*i).first != "filename"
&& (*i).first != "author" && (*i).first != "description")
xml_child_node = xmlNewChild(xml_node, NULL,
- (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());
+ (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());*/
}
if (recursive)
@@ -251,7 +253,9 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
(xmlChar*)(nm->plugin()->uri().c_str()));
// Write metadata
- for (map<string, string>::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) {
+ for (MetadataMap::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) {
+ cerr << "FIXME: Save metadata\n";
+ /*
// DSSI _hack_ (FIXME: fix OSC to be more like this and not smash DSSI into metadata?)
if ((*i).first.substr(0, 16) == "dssi-configure--") {
xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"dssi-configure", NULL);
@@ -269,11 +273,14 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
xml_child_node = xmlNewChild(xml_node, NULL,
(xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());
}
+ */
}
// Write port metadata, if necessary
for (PortModelList::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) {
- const PortModel* const pm = (*i).get();
+ cerr << "FIXME: save metadata\n";
+ /*
+ const PortModel* const pm = i->get();
if (pm->is_input() && pm->user_min() != pm->min_val() || pm->user_max() != pm->max_val()) {
xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"port", NULL);
xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"name",
@@ -282,7 +289,7 @@ PatchLibrarian::save_patch(CountedPtr<PatchModel> patch_model, const string& fil
xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"user-min", (xmlChar*)temp_buf);
snprintf(temp_buf, temp_buf_length, "%f", pm->user_max());
xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"user-max", (xmlChar*)temp_buf);
- }
+ }*/
}
}
}
@@ -385,8 +392,8 @@ PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing)
//cerr << "[PatchLibrarian] Loading patch " << filename << "" << endl;
- const size_t temp_buf_length = 255;
- char temp_buf[temp_buf_length];
+ //const size_t temp_buf_length = 255;
+ //char temp_buf[temp_buf_length];
bool load_name = (pm->path() == "");
bool load_poly = (poly == 0);
@@ -447,8 +454,11 @@ PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing)
// Don't know what this tag is, add it as metadata without overwriting
// (so caller can set arbitrary parameters which will be preserved)
if (key != NULL)
+ cerr << "FIXME: save metadata\n";
+ /*
if (pm->get_metadata((const char*)cur->name) == "")
pm->set_metadata((const char*)cur->name, (const char*)key);
+ */
}
xmlFree(key);
@@ -483,7 +493,7 @@ PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing)
// This isn't so good, considering multiple clients on multiple machines, and
// absolute filesystem paths obviously aren't going to be correct. But for now
// this is all I can figure out to have Save/Save As work properly for subpatches
- _engine->set_metadata(pm->path(), "filename", pm->filename());
+ _engine->set_metadata(pm->path(), "filename", Atom(pm->filename().c_str()));
// Load nodes
cur = xmlDocGetRootElement(doc)->xmlChildrenNode;
@@ -494,13 +504,15 @@ PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing)
if (nm) {
_engine->create_node_from_model(nm.get());
_engine->set_all_metadata(nm.get());
- for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) {
+ cerr << "FIXME: max min\n";
+ /*
+ //for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) {
// FIXME: ew
snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_min());
_engine->set_metadata((*j)->path(), "user-min", temp_buf);
snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_max());
_engine->set_metadata((*j)->path(), "user-max", temp_buf);
- }
+ }*/
}
}
cur = cur->next;
@@ -562,19 +574,23 @@ PatchLibrarian::load_patch(CountedPtr<PatchModel> pm, bool wait, bool existing)
CountedPtr<NodeModel>
PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr doc, const xmlNodePtr node)
{
+cerr << "FIXME: load node\n";
+#if 0
CountedPtr<PluginModel> plugin(new PluginModel());
- CountedPtr<NodeModel> nm(new NodeModel(plugin, "/UNINITIALIZED")); // FIXME: ew
xmlChar* key;
xmlNodePtr cur = node->xmlChildrenNode;
+ string path = ""'
+ bool polyphonic = false;
+
while (cur != NULL) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) {
- nm->set_path(parent->path().base() + Path::nameify((char*)key));
+ path = parent->path().base() + Path::nameify((char*)key));
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) {
- nm->polyphonic(!strcmp((char*)key, "true"));
+ polyphonic = !strcmp((char*)key, "true");
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) {
plugin->set_type((const char*)key);
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"library-name"))) {
@@ -586,7 +602,7 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"port"))) {
xmlNodePtr child = cur->xmlChildrenNode;
- string path;
+ string port_name;
float user_min = 0.0;
float user_max = 0.0;
@@ -594,7 +610,7 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) {
- path = nm->path().base() + Path::nameify((char*)key);
+ port_name = Path::nameify((char*)key);
} else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) {
user_min = atof((char*)key);
} else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) {
@@ -607,11 +623,14 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
child = child->next;
}
- // FIXME: nasty assumptions
- CountedPtr<PortModel> pm(new PortModel(path,
+ assert(path.length() > 0);
+ assert(Path::is_valid(path));
+
+ // FIXME: /nasty/ assumptions
+ CountedPtr<PortModel> pm(new PortModel(Path(path).base() + port_name,
PortModel::CONTROL, PortModel::INPUT, PortModel::NONE,
0.0, user_min, user_max));
- pm->set_parent(nm);
+ //pm->set_parent(nm);
nm->add_port(pm);
// DSSI hacks. Stored in the patch files as special elements, but sent to
@@ -637,7 +656,7 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
key = NULL; // Avoid a (possible?) double free
child = child->next;
}
- nm->set_metadata("dssi-program", bank +"/"+ program);
+ nm->set_metadata("dssi-program", Atom(bank.append("/").append(program).c_str()));
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"dssi-configure"))) {
xmlNodePtr child = cur->xmlChildrenNode;
@@ -659,7 +678,7 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
child = child->next;
}
- nm->set_metadata(string("dssi-configure--").append(dssi_key), dssi_value);
+ nm->set_metadata(string("dssi-configure--").append(dssi_key), Atom(dssi_value.c_str()));
} else { // Don't know what this tag is, add it as metadata
if (key != NULL)
@@ -729,7 +748,10 @@ PatchLibrarian::parse_node(const CountedPtr<const PatchModel> parent, xmlDocPtr
}
//nm->plugin(plugin);
+
return nm;
+#endif
+ return CountedPtr<NodeModel>();
}
diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp
index a65f1c49..21e47089 100644
--- a/src/libs/client/PatchModel.cpp
+++ b/src/libs/client/PatchModel.cpp
@@ -31,13 +31,13 @@ PatchModel::set_path(const Path& new_path)
{
// FIXME: haack
if (new_path == "") {
- m_path = "";
+ _path = "";
return;
}
NodeModel::set_path(new_path);
for (NodeModelMap::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i)
- (*i).second->set_path(m_path +"/"+ (*i).second->path().name());
+ (*i).second->set_path(_path +"/"+ (*i).second->path().name());
#ifdef DEBUG
// Be sure connection paths are updated and sane
@@ -72,7 +72,7 @@ PatchModel::add_child(CountedPtr<ObjectModel> c)
void
PatchModel::remove_child(CountedPtr<ObjectModel> c)
{
- assert(c->path().is_child_of(m_path));
+ assert(c->path().is_child_of(_path));
assert(c->parent().get() == this);
CountedPtr<PortModel> pm = PtrCast<PortModel>(c);
@@ -102,13 +102,13 @@ void
PatchModel::add_node(CountedPtr<NodeModel> nm)
{
assert(nm);
- assert(nm->path().is_child_of(m_path));
+ assert(nm->path().is_child_of(_path));
assert(nm->parent().get() == this);
NodeModelMap::iterator existing = m_nodes.find(nm->path().name());
if (existing != m_nodes.end()) {
- cerr << "Warning: node clash, assimilating old node " << m_path << endl;
+ cerr << "Warning: node clash, assimilating old node " << _path << endl;
nm->assimilate((*existing).second);
(*existing).second = nm;
} else {
@@ -121,23 +121,23 @@ PatchModel::add_node(CountedPtr<NodeModel> nm)
void
PatchModel::remove_node(CountedPtr<NodeModel> nm)
{
- assert(nm->path().is_child_of(m_path));
+ assert(nm->path().is_child_of(_path));
assert(nm->parent().get() == this);
NodeModelMap::iterator i = m_nodes.find(nm->path().name());
if (i != m_nodes.end()) {
assert(i->second == nm);
m_nodes.erase(i);
- removed_node_sig.emit(nm->path().name());
+ removed_node_sig.emit(nm);
i->second->parent().reset();
return;
}
- cerr << "[PatchModel::remove_node] " << m_path
+ cerr << "[PatchModel::remove_node] " << _path
<< ": failed to find node " << nm->path().name() << endl;
}
-
+#if 0
void
PatchModel::remove_node(const string& name)
{
@@ -151,9 +151,9 @@ PatchModel::remove_node(const string& name)
return;
}
- cerr << "[PatchModel::remove_node] " << m_path << ": failed to find node " << name << endl;
+ cerr << "[PatchModel::remove_node] " << _path << ": failed to find node " << name << endl;
}
-
+#endif
void
PatchModel::clear()
@@ -204,7 +204,7 @@ PatchModel::rename_node(const Path& old_path, const Path& new_path)
return;
}
- cerr << "[PatchModel::rename_node] " << m_path << ": failed to find node " << old_path << endl;
+ cerr << "[PatchModel::rename_node] " << _path << ": failed to find node " << old_path << endl;
}
@@ -229,8 +229,8 @@ void
PatchModel::add_connection(CountedPtr<ConnectionModel> cm)
{
assert(cm);
- //assert(cm->src_port_path().parent().parent() == m_path);
- //assert(cm->dst_port_path().parent().parent() == m_path);
+ //assert(cm->src_port_path().parent().parent() == _path);
+ //assert(cm->dst_port_path().parent().parent() == _path);
assert(cm->patch_path() == path());
//cerr << "PatchModel::add_connection: " << cm->src_port_path() << " -> " << cm->dst_port_path() << endl;
@@ -314,9 +314,9 @@ PatchModel::disable()
bool
PatchModel::polyphonic() const
{
- return (!m_parent)
+ return (!_parent)
? (m_poly > 1)
- : (m_poly > 1) && m_poly == ((PatchModel*)m_parent.get())->poly() && m_poly > 1;
+ : (m_poly > 1) && m_poly == ((PatchModel*)_parent.get())->poly() && m_poly > 1;
}
diff --git a/src/libs/client/PatchModel.h b/src/libs/client/PatchModel.h
index 6ca8ed8f..49a45503 100644
--- a/src/libs/client/PatchModel.h
+++ b/src/libs/client/PatchModel.h
@@ -39,11 +39,13 @@ namespace Client {
class PatchModel : public NodeModel
{
public:
- PatchModel(const string& patch_path, uint poly)
- : NodeModel("ingen:patch", patch_path),
+ PatchModel(const string& patch_path, size_t internal_poly)
+ : NodeModel("ingen:patch", patch_path, false ), // FIXME
m_enabled(false),
- m_poly(poly)
- {}
+ m_poly(internal_poly)
+ {
+ cerr << "FIXME: patch poly\n";
+ }
const NodeModelMap& nodes() const { return m_nodes; }
const list<CountedPtr<ConnectionModel> >& connections() const { return m_connections; }
@@ -55,7 +57,7 @@ public:
CountedPtr<NodeModel> get_node(const string& node_name);
void add_node(CountedPtr<NodeModel> nm);
- void remove_node(const string& name);
+ //void remove_node(const string& name);
void remove_node(CountedPtr<NodeModel> nm);
void rename_node(const Path& old_path, const Path& new_path);
@@ -77,12 +79,12 @@ public:
bool polyphonic() const;
// Signals
- sigc::signal<void, CountedPtr<NodeModel> > new_node_sig;
- sigc::signal<void, const string& > removed_node_sig;
- sigc::signal<void, CountedPtr<ConnectionModel> > new_connection_sig;
- sigc::signal<void, const string&, const string& > removed_connection_sig;
- sigc::signal<void> enabled_sig;
- sigc::signal<void> disabled_sig;
+ sigc::signal<void, CountedPtr<NodeModel> > new_node_sig;
+ sigc::signal<void, CountedPtr<NodeModel> > removed_node_sig;
+ sigc::signal<void, CountedPtr<ConnectionModel> > new_connection_sig;
+ sigc::signal<void, const Path&, const Path& > removed_connection_sig;
+ sigc::signal<void> enabled_sig;
+ sigc::signal<void> disabled_sig;
private:
// Prevent copies (undefined)
diff --git a/src/libs/client/PortModel.h b/src/libs/client/PortModel.h
index 1f816748..dd0a208b 100644
--- a/src/libs/client/PortModel.h
+++ b/src/libs/client/PortModel.h
@@ -35,22 +35,17 @@ namespace Client {
class PortModel : public ObjectModel
{
public:
+ // FIXME: metadataify
enum Type { CONTROL, AUDIO, MIDI };
enum Direction { INPUT, OUTPUT };
enum Hint { NONE, INTEGER, TOGGLE, LOGARITHMIC };
- PortModel(const string& path, Type type, Direction dir, Hint hint,
- float default_val, float min, float max)
+ PortModel(const string& path, Type type, Direction dir, Hint hint)
: ObjectModel(path),
m_type(type),
m_direction(dir),
m_hint(hint),
- m_default_val(default_val),
- m_min_val(min),
- //m_user_min(min),
- m_max_val(max),
- //m_user_max(max),
- m_current_val(default_val),
+ m_current_val(0.0f),
m_connections(0)
{
}
@@ -60,11 +55,6 @@ public:
m_type(type),
m_direction(dir),
m_hint(NONE),
- m_default_val(0.0f),
- m_min_val(0.0f),
- //m_user_min(0.0f),
- m_max_val(0.0f),
- //m_user_max(0.0f),
m_current_val(0.0f),
m_connections(0)
{
@@ -73,14 +63,6 @@ public:
void add_child(CountedPtr<ObjectModel> c) { throw; }
void remove_child(CountedPtr<ObjectModel> c) { throw; }
- inline float min_val() const { return m_min_val; }
- inline float user_min() const { return atof(get_metadata("min").c_str()); } // FIXME: haaack
- //inline void user_min(float f) { m_user_min = f; }
- inline float default_val() const { return m_default_val; }
- inline void default_val(float f) { m_default_val = f; }
- inline float max_val() const { return m_max_val; }
- inline float user_max() const { return atof(get_metadata("max").c_str()); }
- //inline void user_max(float f) { m_user_max = f; }
inline float value() const { return m_current_val; }
inline void value(float f) { m_current_val = f; control_change_sig.emit(f); }
inline bool connected() { return (m_connections > 0); }
@@ -96,7 +78,7 @@ public:
inline bool is_toggle() const { return (m_hint == TOGGLE); }
inline bool operator==(const PortModel& pm)
- { return (m_path == pm.m_path); }
+ { return (_path == pm._path); }
void connected_to(CountedPtr<PortModel> p) { ++m_connections; connection_sig.emit(p); }
void disconnected_from(CountedPtr<PortModel> p) { --m_connections; disconnection_sig.emit(p); }
@@ -114,11 +96,6 @@ private:
Type m_type;
Direction m_direction;
Hint m_hint;
- float m_default_val;
- float m_min_val;
- //float m_user_min;
- float m_max_val;
- //float m_user_max;
float m_current_val;
size_t m_connections;
};
diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h
index cef7d27d..a28b1a1d 100644
--- a/src/libs/client/SigClientInterface.h
+++ b/src/libs/client/SigClientInterface.h
@@ -55,7 +55,7 @@ public:
sigc::signal<void, string> object_destroyed_sig;
sigc::signal<void, string, string> connection_sig;
sigc::signal<void, string, string> disconnection_sig;
- sigc::signal<void, string, string, string> metadata_update_sig;
+ sigc::signal<void, string, string, Atom> metadata_update_sig;
sigc::signal<void, string, float> control_change_sig;
sigc::signal<void, string, uint32_t, uint32_t, string> program_add_sig;
sigc::signal<void, string, uint32_t, uint32_t> program_remove_sig;
diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp
index df0bdd95..e2637c0f 100644
--- a/src/libs/client/Store.cpp
+++ b/src/libs/client/Store.cpp
@@ -212,11 +212,11 @@ void
Store::destruction_event(const Path& path)
{
CountedPtr<ObjectModel> removed = remove_object(path);
- removed->controller().reset();
- cerr << "Store removed object " << path
- << " controller count: " << removed->controller().use_count();
+
removed.reset();
- cerr << ", model count: " << removed.use_count() << endl;
+
+ cerr << "Store removed object " << path
+ << ", count: " << removed.use_count();
}
void
@@ -244,12 +244,10 @@ Store::new_node_event(const string& plugin_type, const string& plugin_uri, const
CountedPtr<PluginModel> plug = plugin(plugin_uri);
if (!plug) {
- CountedPtr<NodeModel> n(new NodeModel(plugin_uri, node_path));
- n->polyphonic(is_polyphonic);
+ CountedPtr<NodeModel> n(new NodeModel(plugin_uri, node_path, is_polyphonic));
add_plugin_orphan(n);
} else {
- CountedPtr<NodeModel> n(new NodeModel(plug, node_path));
- n->polyphonic(is_polyphonic);
+ CountedPtr<NodeModel> n(new NodeModel(plug, node_path, is_polyphonic));
add_object(n);
}
}
@@ -292,7 +290,7 @@ Store::patch_disabled_event(const Path& path)
void
-Store::metadata_update_event(const Path& subject_path, const string& predicate, const string& value)
+Store::metadata_update_event(const Path& subject_path, const string& predicate, const Atom& value)
{
CountedPtr<ObjectModel> subject = object(subject_path);
if (subject)
diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h
index e70c5bc0..99466b1d 100644
--- a/src/libs/client/Store.h
+++ b/src/libs/client/Store.h
@@ -24,6 +24,7 @@
#include "util/CountedPtr.h"
#include <sigc++/sigc++.h>
#include "util/Path.h"
+#include "util/Atom.h"
using std::string; using std::map; using std::list;
namespace Ingen {
@@ -75,7 +76,7 @@ private:
void new_port_event(const Path& path, const string& data_type, bool is_output);
void patch_enabled_event(const Path& path);
void patch_disabled_event(const Path& path);
- void metadata_update_event(const Path& subject_path, const string& predicate, const string& value);
+ void metadata_update_event(const Path& subject_path, const string& predicate, const Atom& value);
void control_change_event(const Path& port_path, float value);
void connection_event(const Path& src_port_path, const Path& dst_port_path);
void disconnection_event(const Path& src_port_path, const Path& dst_port_path);
diff --git a/src/libs/client/ThreadedSigClientInterface.h b/src/libs/client/ThreadedSigClientInterface.h
index 5a677034..981b038d 100644
--- a/src/libs/client/ThreadedSigClientInterface.h
+++ b/src/libs/client/ThreadedSigClientInterface.h
@@ -23,6 +23,7 @@
#include "interface/ClientInterface.h"
#include "SigClientInterface.h"
#include "util/Queue.h"
+#include "util/Atom.h"
using std::string;
/** Returns nothing and takes no parameters (because they have all been bound) */
@@ -114,7 +115,7 @@ public:
void disconnection(string src_port_path, string dst_port_path)
{ push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); }
- void metadata_update(string path, string key, string value)
+ void metadata_update(string path, string key, Atom value)
{ push_sig(sigc::bind(metadata_update_slot, path, key, value)); }
void control_change(string port_path, float value)
@@ -151,7 +152,7 @@ private:
sigc::slot<void, string> object_destroyed_slot;
sigc::slot<void, string, string> object_renamed_slot;
sigc::slot<void, string, string> disconnection_slot;
- sigc::slot<void, string, string, string> metadata_update_slot;
+ sigc::slot<void, string, string, Atom> metadata_update_slot;
sigc::slot<void, string, float> control_change_slot;
sigc::slot<void, string, uint32_t, uint32_t, string> program_add_slot;
sigc::slot<void, string, uint32_t, uint32_t> program_remove_slot;
diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp
index 1b4a2bd2..7a21c38b 100644
--- a/src/libs/engine/ClientBroadcaster.cpp
+++ b/src/libs/engine/ClientBroadcaster.cpp
@@ -258,7 +258,7 @@ ClientBroadcaster::send_patch_disable(const string& patch_path)
* Like control changes, does not send update to client that set the metadata, if applicable.
*/
void
-ClientBroadcaster::send_metadata_update(const string& node_path, const string& key, const string& value)
+ClientBroadcaster::send_metadata_update(const string& node_path, const string& key, const Atom& value)
{
for (ClientList::const_iterator i = _clients.begin(); i != _clients.end(); ++i)
(*i).second->metadata_update(node_path, key, value);
diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h
index ed4bec4e..47ad75b4 100644
--- a/src/libs/engine/ClientBroadcaster.h
+++ b/src/libs/engine/ClientBroadcaster.h
@@ -82,7 +82,7 @@ public:
void send_all_objects();
void send_patch_enable(const string& patch_path);
void send_patch_disable(const string& patch_path);
- void send_metadata_update(const string& node_path, const string& key, const string& value);
+ void send_metadata_update(const string& node_path, const string& key, const Atom& value);
void send_control_change(const string& port_path, float value);
void send_program_add(const string& node_path, int bank, int program, const string& name);
void send_program_remove(const string& node_path, int bank, int program);
diff --git a/src/libs/engine/DSSINode.h b/src/libs/engine/DSSINode.h
index 3c8dc841..1ef58d58 100644
--- a/src/libs/engine/DSSINode.h
+++ b/src/libs/engine/DSSINode.h
@@ -37,7 +37,7 @@ class DSSINode : public LADSPANode
{
public:
- typedef map<int, string> Bank;
+ typedef std::map<int, string> Bank;
DSSINode(const Plugin* plugin, const string& name, size_t poly, Patch* parent, DSSI_Descriptor* descriptor, SampleRate srate, size_t buffer_size);
~DSSINode();
@@ -57,7 +57,7 @@ public:
bool update_programs(bool send_events);
void set_default_program();
- const map<int, Bank>& get_programs() const;
+ const std::map<int, Bank>& get_programs() const;
//void send_creation_messages(ClientInterface* client) const;
@@ -90,10 +90,10 @@ private:
lo_address _ui_addr;
// Current values
- int _bank;
- int _program;
- map<string, string> _configures;
- map<int, Bank> _banks;
+ int _bank;
+ int _program;
+ std::map<string, string> _configures;
+ std::map<int, Bank> _banks;
InputPort<MidiMessage>* _midi_in_port;
snd_seq_event_t* _alsa_events;
diff --git a/src/libs/engine/GraphObject.h b/src/libs/engine/GraphObject.h
index 3b0c27b1..4f72a2e6 100644
--- a/src/libs/engine/GraphObject.h
+++ b/src/libs/engine/GraphObject.h
@@ -23,8 +23,9 @@
#include <cassert>
#include "MaidObject.h"
#include "util/Path.h"
+#include "util/Atom.h"
#include "types.h"
-using std::string; using std::map;
+using std::string;
namespace Ingen {
@@ -45,6 +46,8 @@ class ObjectStore;
class GraphObject : public MaidObject
{
public:
+ typedef std::map<string, Atom> MetadataMap;
+
GraphObject(GraphObject* parent, const string& name)
: _parent(parent), _name(name)
{
@@ -67,16 +70,16 @@ public:
assert(_name.find("/") == string::npos);
}
- void set_metadata(const string& key, const string& value)
+ void set_metadata(const string& key, const Atom& value)
{ _metadata[key] = value; }
- const string& get_metadata(const string& key) {
- static const string empty_string = "";
- map<string, string>::iterator i = _metadata.find(key);
- return (i != _metadata.end()) ? (*i).second : empty_string;
+ const Atom& get_metadata(const string& key) {
+ static Atom null_atom;
+ MetadataMap::iterator i = _metadata.find(key);
+ return (i != _metadata.end()) ? (*i).second : null_atom;
}
- const map<string, string>& metadata() const { return _metadata; }
+ const MetadataMap& metadata() const { return _metadata; }
/** Patch and Node override this to recursively add their children. */
@@ -104,7 +107,7 @@ private:
GraphObject(const GraphObject&);
GraphObject& operator=(const GraphObject& copy);
- map<string, string> _metadata;
+ MetadataMap _metadata;
};
diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp
index 76550d0b..00cfd450 100644
--- a/src/libs/engine/LADSPANode.cpp
+++ b/src/libs/engine/LADSPANode.cpp
@@ -123,11 +123,10 @@ LADSPANode::instantiate()
((TypedPort<Sample>*)port)->set_value(0.0f, 0);
}
- char tmp_buf[16];
- snprintf(tmp_buf, 16, "%f", min);
- port->set_metadata("min", tmp_buf);
- snprintf(tmp_buf, 16, "%f", max);
- port->set_metadata("max", tmp_buf);
+ if (port->is_input() && port->buffer_size() == 1) {
+ port->set_metadata("min", min);
+ port->set_metadata("max", max);
+ }
}
return true;
diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp
index 068c461a..538630c0 100644
--- a/src/libs/engine/OSCClientSender.cpp
+++ b/src/libs/engine/OSCClientSender.cpp
@@ -29,7 +29,7 @@
#include "AudioDriver.h"
#include "interface/ClientInterface.h"
#include "Responder.h"
-
+#include "util/LibloAtom.h"
using std::cout; using std::cerr; using std::endl;
namespace Ingen {
@@ -421,9 +421,13 @@ OSCClientSender::disconnection(string src_port_path, string dst_port_path)
* \arg \b value (string)</p> \n \n
*/
void
-OSCClientSender::metadata_update(string path, string key, string value)
+OSCClientSender::metadata_update(string path, string key, Atom value)
{
- lo_send(_address, "/om/metadata/update", "sss", path.c_str(), key.c_str(), value.c_str());
+ lo_message m = lo_message_new();
+ lo_message_add_string(m, path.c_str());
+ lo_message_add_string(m, key.c_str());
+ LibloAtom::lo_message_add_atom(m, value);
+ lo_send_message(_address, "/om/metadata/update", m);
}
diff --git a/src/libs/engine/OSCClientSender.h b/src/libs/engine/OSCClientSender.h
index e2404c1a..260dba63 100644
--- a/src/libs/engine/OSCClientSender.h
+++ b/src/libs/engine/OSCClientSender.h
@@ -107,7 +107,7 @@ public:
virtual void metadata_update(string subject_path,
string predicate,
- string value);
+ Atom value);
virtual void control_change(string port_path,
float value);
diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp
index 2eb68d70..afed89fd 100644
--- a/src/libs/engine/OSCEngineReceiver.cpp
+++ b/src/libs/engine/OSCEngineReceiver.cpp
@@ -22,6 +22,7 @@
#include "types.h"
#include "util/Queue.h"
#include "util/CountedPtr.h"
+#include "util/LibloAtom.h"
#include "QueuedEventSource.h"
#include "interface/ClientKey.h"
#include "interface/ClientInterface.h"
@@ -106,7 +107,7 @@ OSCEngineReceiver::OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_siz
#endif
lo_server_add_method(_server, "/om/metadata/request", "isss", metadata_get_cb, this);
- lo_server_add_method(_server, "/om/metadata/set", "isss", metadata_set_cb, this);
+ lo_server_add_method(_server, "/om/metadata/set", NULL, metadata_set_cb, this);
// Queries
lo_server_add_method(_server, "/om/request/plugins", "i", request_plugins_cb, this);
@@ -758,9 +759,13 @@ OSCEngineReceiver::m_lash_restore_done_cb(const char* path, const char* types, l
int
OSCEngineReceiver::m_metadata_set_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
{
+ if (argc != 4 || types[0] != 'i' || types[1] != 's' || types[2] != 's')
+ return 1;
+
const char* node_path = &argv[1]->s;
const char* key = &argv[2]->s;
- const char* value = &argv[3]->s;
+
+ Atom value = LibloAtom::lo_arg_to_atom(types[3], argv[3]);
set_metadata(node_path, key, value);
diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp
index 063a2d1d..1e6b93c5 100644
--- a/src/libs/engine/ObjectSender.cpp
+++ b/src/libs/engine/ObjectSender.cpp
@@ -45,8 +45,8 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch)
send_port(client, port);
/*
// Send metadata
- const map<string, string>& data = port->metadata();
- for (map<string, string>::const_iterator i = data.begin(); i != data.end(); ++i)
+ const GraphObject::MetadataMap& data = port->metadata();
+ for (GraphObject::MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i)
client->metadata_update(port->path(), (*i).first, (*i).second);
// Control port, send value
@@ -64,8 +64,8 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch)
// Send metadata
- const map<string, string>& data = patch->metadata();
- for (map<string, string>::const_iterator j = data.begin(); j != data.end(); ++j)
+ const GraphObject::MetadataMap& data = patch->metadata();
+ for (GraphObject::MetadataMap::const_iterator j = data.begin(); j != data.end(); ++j)
client->metadata_update(patch->path(), (*j).first, (*j).second);
if (patch->enabled())
@@ -118,8 +118,8 @@ ObjectSender::send_node(ClientInterface* client, const Node* node)
client->bundle_end();
// Send metadata
- const map<string, string>& data = node->metadata();
- for (map<string, string>::const_iterator j = data.begin(); j != data.end(); ++j)
+ const GraphObject::MetadataMap& data = node->metadata();
+ for (GraphObject::MetadataMap::const_iterator j = data.begin(); j != data.end(); ++j)
client->metadata_update(node->path(), (*j).first, (*j).second);
}
@@ -149,8 +149,8 @@ ObjectSender::send_port(ClientInterface* client, const Port* port)
}
// Send metadata
- const map<string, string>& data = port->metadata();
- for (map<string, string>::const_iterator j = data.begin(); j != data.end(); ++j)
+ const GraphObject::MetadataMap& data = port->metadata();
+ for (GraphObject::MetadataMap::const_iterator j = data.begin(); j != data.end(); ++j)
client->metadata_update(port->path(), (*j).first, (*j).second);
}
diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp
index 35e1c99a..b0903e29 100644
--- a/src/libs/engine/QueuedEngineInterface.cpp
+++ b/src/libs/engine/QueuedEngineInterface.cpp
@@ -275,7 +275,7 @@ QueuedEngineInterface::midi_learn(const string& node_path)
void
QueuedEngineInterface::set_metadata(const string& path,
const string& predicate,
- const string& value)
+ const Atom& value)
{
push_queued(new SetMetadataEvent(*_engine.get(), _responder, now(), path, predicate, value));
}
diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h
index 1e35738f..f9aaa0b4 100644
--- a/src/libs/engine/QueuedEngineInterface.h
+++ b/src/libs/engine/QueuedEngineInterface.h
@@ -137,7 +137,7 @@ public:
virtual void set_metadata(const string& path,
const string& predicate,
- const string& value);
+ const Atom& value);
// Requests //
diff --git a/src/libs/engine/events/DSSIConfigureEvent.cpp b/src/libs/engine/events/DSSIConfigureEvent.cpp
index fb9dc727..9a26de0c 100644
--- a/src/libs/engine/events/DSSIConfigureEvent.cpp
+++ b/src/libs/engine/events/DSSIConfigureEvent.cpp
@@ -64,7 +64,7 @@ DSSIConfigureEvent::post_process()
} else {
string key = "dssi-configure--";
key += m_key;
- _engine.broadcaster()->send_metadata_update(m_node_path, key, m_val);
+ _engine.broadcaster()->send_metadata_update(m_node_path, key, Atom(m_val.c_str()));
}
}
diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp
index f6f1bdf9..aaea89c6 100644
--- a/src/libs/engine/events/RequestMetadataEvent.cpp
+++ b/src/libs/engine/events/RequestMetadataEvent.cpp
@@ -31,7 +31,6 @@ RequestMetadataEvent::RequestMetadataEvent(Engine& engine, CountedPtr<Responder>
: QueuedEvent(engine, responder, timestamp),
m_path(node_path),
m_key(key),
- m_value(""),
m_object(NULL),
m_client(CountedPtr<ClientInterface>())
{
@@ -61,8 +60,8 @@ void
RequestMetadataEvent::post_process()
{
if (m_client) {
- if (m_value == "") {
- string msg = "Unable to find object ";
+ if (!m_object) {
+ string msg = "Unable to find metadata subject ";
msg += m_path;
_responder->respond_error(msg);
} else {
diff --git a/src/libs/engine/events/RequestMetadataEvent.h b/src/libs/engine/events/RequestMetadataEvent.h
index 4f99e023..f4296ac2 100644
--- a/src/libs/engine/events/RequestMetadataEvent.h
+++ b/src/libs/engine/events/RequestMetadataEvent.h
@@ -19,7 +19,7 @@
#include <string>
#include "QueuedEvent.h"
-
+#include "util/Atom.h"
using std::string;
namespace Ingen {
@@ -45,8 +45,8 @@ public:
private:
string m_path;
string m_key;
- string m_value;
- GraphObject* m_object;
+ Atom m_value;
+ GraphObject* m_object;
CountedPtr<ClientInterface> m_client;
};
diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp
index db8e0118..c4937df5 100644
--- a/src/libs/engine/events/SetMetadataEvent.cpp
+++ b/src/libs/engine/events/SetMetadataEvent.cpp
@@ -27,7 +27,7 @@ using std::string;
namespace Ingen {
-SetMetadataEvent::SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value)
+SetMetadataEvent::SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const Atom& value)
: QueuedEvent(engine, responder, timestamp),
m_path(path),
m_key(key),
diff --git a/src/libs/engine/events/SetMetadataEvent.h b/src/libs/engine/events/SetMetadataEvent.h
index 855aeb62..b78f2502 100644
--- a/src/libs/engine/events/SetMetadataEvent.h
+++ b/src/libs/engine/events/SetMetadataEvent.h
@@ -19,6 +19,7 @@
#include <string>
#include "QueuedEvent.h"
+#include "util/Atom.h"
using std::string;
@@ -34,16 +35,16 @@ class GraphObject;
class SetMetadataEvent : public QueuedEvent
{
public:
- SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value);
+ SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const Atom& value);
void pre_process();
void execute(SampleCount nframes, FrameTime start, FrameTime end);
void post_process();
private:
- string m_path;
- string m_key;
- string m_value;
+ string m_path;
+ string m_key;
+ Atom m_value;
GraphObject* m_object;
};
diff --git a/src/progs/demolition/demolition.cpp b/src/progs/demolition/demolition.cpp
index e5ffded0..27da5dd9 100644
--- a/src/progs/demolition/demolition.cpp
+++ b/src/progs/demolition/demolition.cpp
@@ -183,11 +183,8 @@ create_patch()
engine->create_patch_from_model(pm);
// Spread them out a bit for easier monitoring with ingenuity
- char tmp_buf[8];
- snprintf(tmp_buf, 8, "%d", 1600 + rand()%800 - 400);
- engine->set_metadata(pm->path(), "module-x", string(tmp_buf));
- snprintf(tmp_buf, 8, "%d", 1200 + rand()%700 - 350);
- engine->set_metadata(pm->path(), "module-y", string(tmp_buf));
+ engine->set_metadata(pm->path(), "module-x", 1600 + rand()%800 - 400);
+ engine->set_metadata(pm->path(), "module-y", 1200 + rand()%700 - 350);
delete pm;
}
@@ -225,12 +222,10 @@ add_node()
NodeModel* nm = new NodeModel(plugin, parent->path() +"/"+ random_name());
cout << "Adding node " << nm->path() << endl;
engine->create_node_from_model(nm);
+
// Spread them out a bit for easier monitoring with ingenuity
- char tmp_buf[8];
- snprintf(tmp_buf, 8, "%d", 1600 + rand()%800 - 400);
- engine->set_metadata(nm->path(), "module-x", tmp_buf);
- snprintf(tmp_buf, 8, "%d", 1200 + rand()%700 - 350);
- engine->set_metadata(nm->path(), "module-y", tmp_buf);
+ engine->set_metadata(pm->path(), "module-x", 1600 + rand()%800 - 400);
+ engine->set_metadata(pm->path(), "module-y", 1200 + rand()%700 - 350);
}
}
diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp
index ae452f27..60482d77 100644
--- a/src/progs/ingenuity/App.cpp
+++ b/src/progs/ingenuity/App.cpp
@@ -25,11 +25,6 @@
#include "OmModule.h"
#include "ControlPanel.h"
#include "SubpatchModule.h"
-#include "OmFlowCanvas.h"
-#include "GtkObjectController.h"
-#include "PatchController.h"
-#include "NodeController.h"
-#include "PortController.h"
#include "LoadPluginWindow.h"
#include "PatchWindow.h"
#include "MessagesWindow.h"
diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h
index 25e01ff2..d166c37b 100644
--- a/src/progs/ingenuity/App.h
+++ b/src/progs/ingenuity/App.h
@@ -45,10 +45,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
class PatchWindow;
-class GtkObjectController;
-class PatchController;
-class NodeController;
-class PortController;
class LoadPatchWindow;
class MessagesWindow;
class ConfigWindow;
diff --git a/src/progs/ingenuity/BreadCrumb.h b/src/progs/ingenuity/BreadCrumb.h
index 66e6d40a..908e0f80 100644
--- a/src/progs/ingenuity/BreadCrumb.h
+++ b/src/progs/ingenuity/BreadCrumb.h
@@ -17,31 +17,44 @@
#ifndef BREADCRUMB_H
#define BREADCRUMB_H
-// FIXME: remove
-#include <iostream>
-using std::cerr; using std::endl;
-
#include <gtkmm.h>
#include "util/Path.h"
+#include "util/CountedPtr.h"
+#include "PatchView.h"
namespace Ingenuity {
/** Breadcrumb button in a PatchWindow.
*
+ * Each Breadcrumb stores a reference to a PatchView for quick switching.
+ * So, the amount of allocated PatchViews at a given time is equal to the
+ * number of visible breadcrumbs (which is the perfect cache for GUI
+ * responsiveness balanced with mem consumption).
+ *
* \ingroup Ingenuity
*/
class BreadCrumb : public Gtk::ToggleButton
{
public:
- BreadCrumb(const Path& path)
- : m_path(path)
+ BreadCrumb(const Path& path, CountedPtr<PatchView> view = CountedPtr<PatchView>())
+ : _path(path)
+ , _view(view)
{
+ assert( !view || view->patch()->path() == path);
set_border_width(0);
set_path(path);
show_all();
}
+ void set_view(CountedPtr<PatchView> view) {
+ assert( !view || view->patch()->path() == _path);
+ _view = view;
+ }
+
+ const Path& path() const { return _path; }
+ CountedPtr<PatchView> view() const { return _view; }
+
void set_path(const Path& path)
{
remove();
@@ -50,12 +63,14 @@ public:
lab->set_padding(0, 0);
lab->show();
add(*lab);
+
+ if (_view && _view->patch()->path() != path)
+ _view.reset();
}
- const Path& path() { return m_path; }
-
private:
- Path m_path;
+ Path _path;
+ CountedPtr<PatchView> _view;
};
} // namespace Ingenuity
diff --git a/src/progs/ingenuity/BreadCrumbBox.cpp b/src/progs/ingenuity/BreadCrumbBox.cpp
index aea1cdf0..8dc0b8a0 100644
--- a/src/progs/ingenuity/BreadCrumbBox.cpp
+++ b/src/progs/ingenuity/BreadCrumbBox.cpp
@@ -34,7 +34,7 @@ BreadCrumbBox::BreadCrumbBox()
* children preserved.
*/
void
-BreadCrumbBox::build(Path path)
+BreadCrumbBox::build(Path path, CountedPtr<PatchView> view)
{
bool old_enable_signal = _enable_signal;
_enable_signal = false;
@@ -42,14 +42,39 @@ BreadCrumbBox::build(Path path)
// Moving to a path we already contain, just switch the active button
if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) {
- for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i)
- (*i)->set_active( ((*i)->path() == path) );
+ for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) {
+ if ((*i)->path() == path) {
+ (*i)->set_active(true);
+ (*i)->set_view(view);
+ } else {
+ (*i)->set_active(false);
+ }
+ }
_active_path = path;
_enable_signal = old_enable_signal;
return;
}
+ // Moving to a child of the full path, just append crumbs (preserve view cache)
+ if (_breadcrumbs.size() > 0 && (path.is_child_of(_full_path))) {
+ string postfix = path.substr(_full_path.length());
+ while (postfix.length() > 0) {
+ const string name = postfix.substr(0, postfix.find("/"));
+ cerr << "NAME: " << name << endl;
+ _full_path = _full_path.base() + name;
+ BreadCrumb* but = create_crumb(_full_path, view);
+ pack_end(*but, false, false, 1);
+ _breadcrumbs.push_back(but);
+ if (postfix.find("/") == string::npos)
+ break;
+ else
+ postfix = postfix.substr(postfix.find("/")+1);
+ }
+ }
+
+ // Getting here is bad unless absolutely necessary, since the PatchView cache is lost
+
// Otherwise rebuild from scratch
_full_path = path;
_active_path = path;
@@ -60,18 +85,14 @@ BreadCrumbBox::build(Path path)
_breadcrumbs.clear();
// Add root
- BreadCrumb* but = manage(new BreadCrumb("/"));
- but->signal_toggled().connect(sigc::bind(sigc::mem_fun(
- this, &BreadCrumbBox::breadcrumb_clicked), but));
+ BreadCrumb* but = create_crumb("/", view);
pack_start(*but, false, false, 1);
_breadcrumbs.push_front(but);
but->set_active(but->path() == _active_path);
// Add the others
while (path != "/") {
- BreadCrumb* but = manage(new BreadCrumb(path));
- but->signal_toggled().connect(sigc::bind(sigc::mem_fun(
- this, &BreadCrumbBox::breadcrumb_clicked), but));
+ BreadCrumb* but = create_crumb(path, view);
pack_start(*but, false, false, 1);
_breadcrumbs.push_front(but);
but->set_active(but->path() == _active_path);
@@ -84,6 +105,23 @@ BreadCrumbBox::build(Path path)
}
+/** Create a new crumb, assigning it a reference to @a view if their paths
+ * match, otherwise ignoring @a view.
+ */
+BreadCrumb*
+BreadCrumbBox::create_crumb(const Path& path,
+ CountedPtr<PatchView> view)
+{
+ BreadCrumb* but = manage(new BreadCrumb(path,
+ (view && path == view->patch()->path()) ? view : CountedPtr<PatchView>()));
+
+ but->signal_toggled().connect(sigc::bind(sigc::mem_fun(
+ this, &BreadCrumbBox::breadcrumb_clicked), but));
+
+ return but;
+}
+
+
void
BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb)
{
@@ -95,7 +133,7 @@ BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb)
// Tried to turn off the current active button, bad user!
crumb->set_active(true);
} else {
- signal_patch_selected.emit(crumb->path());
+ signal_patch_selected.emit(crumb->path(), crumb->view());
if (crumb->path() != _active_path)
crumb->set_active(false);
}
diff --git a/src/progs/ingenuity/BreadCrumbBox.h b/src/progs/ingenuity/BreadCrumbBox.h
index 35215e43..e38d8e49 100644
--- a/src/progs/ingenuity/BreadCrumbBox.h
+++ b/src/progs/ingenuity/BreadCrumbBox.h
@@ -22,10 +22,11 @@
#include <libglademm/xml.h>
#include <libglademm.h>
#include "util/Path.h"
+#include "util/CountedPtr.h"
+#include "PatchView.h"
namespace Ingenuity {
-class PatchController;
class BreadCrumb;
@@ -38,11 +39,14 @@ class BreadCrumbBox : public Gtk::HBox
public:
BreadCrumbBox();
- void build(Path path);
+ void build(Path path, CountedPtr<PatchView> view);
- sigc::signal<void, const Path&> signal_patch_selected;
+ sigc::signal<void, const Path&, CountedPtr<PatchView> > signal_patch_selected;
private:
+ BreadCrumb* create_crumb(const Path& path,
+ CountedPtr<PatchView> view = CountedPtr<PatchView>());
+
void breadcrumb_clicked(BreadCrumb* crumb);
void object_removed(const Path& path);
diff --git a/src/progs/ingenuity/ConfigWindow.cpp b/src/progs/ingenuity/ConfigWindow.cpp
index 934dcc6b..a83bfbac 100644
--- a/src/progs/ingenuity/ConfigWindow.cpp
+++ b/src/progs/ingenuity/ConfigWindow.cpp
@@ -19,9 +19,7 @@
#include <cassert>
#include <algorithm>
#include <cctype>
-#include "PatchController.h"
#include "NodeModel.h"
-#include "OmFlowCanvas.h"
using std::cout; using std::cerr; using std::endl;
diff --git a/src/progs/ingenuity/Configuration.cpp b/src/progs/ingenuity/Configuration.cpp
index e383cf87..0c985750 100644
--- a/src/progs/ingenuity/Configuration.cpp
+++ b/src/progs/ingenuity/Configuration.cpp
@@ -22,9 +22,7 @@
#include <map>
#include "PortModel.h"
#include "PluginModel.h"
-#include "PatchController.h"
#include "PatchModel.h"
-#include "OmFlowCanvas.h"
#include "Loader.h"
#include "App.h"
diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp
index df95f3c3..64d611e2 100644
--- a/src/progs/ingenuity/ConnectWindow.cpp
+++ b/src/progs/ingenuity/ConnectWindow.cpp
@@ -25,8 +25,6 @@
#include "OSCClientReceiver.h"
#include "ThreadedSigClientInterface.h"
#include "Store.h"
-#include "ControllerFactory.h"
-#include "PatchController.h"
#include "PatchModel.h"
#include "App.h"
#include "WindowFactory.h"
@@ -353,8 +351,7 @@ ConnectWindow::gtk_callback()
if (App::instance().store()->num_objects() > 0) {
CountedPtr<PatchModel> root = PtrCast<PatchModel>(App::instance().store()->object("/"));
assert(root);
- CountedPtr<PatchController> root_c = PtrCast<PatchController>(ControllerFactory::get_controller(root));
- App::instance().window_factory()->present(root_c);
+ App::instance().window_factory()->present_patch(root);
++stage;
}
} else if (stage == 8) {
diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp
index 45218bdf..06f49f86 100644
--- a/src/progs/ingenuity/ControlGroups.cpp
+++ b/src/progs/ingenuity/ControlGroups.cpp
@@ -53,13 +53,12 @@ ControlGroup::ControlGroup(ControlPanel* panel, CountedPtr<PortModel> pm, bool s
void
-ControlGroup::metadata_update(const string& key, const string& value)
+ControlGroup::metadata_update(const string& key, const Atom& value)
{
- // FIXME: this isn't right
- if (key == "user-min" || key == "min")
- set_min(atof(value.c_str()));
- else if (key == "user-max" || key == "max")
- set_max(atof(value.c_str()));
+ if ( (key == "min") && value.type() == Atom::FLOAT)
+ set_min(value.get_float());
+ else if ( (key == "max") && value.type() == Atom::FLOAT)
+ set_max(value.get_float());
}
@@ -77,17 +76,20 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel
m_max_spinner(1.0, (pm->is_integer() ? 0 : 4)),
m_slider_box(false, 0),
m_value_spinner(1.0, (pm->is_integer() ? 0 : 4)),
- m_slider(pm->user_min(), pm->user_max(), (pm->is_integer() ? 1.0 : 0.0001))
+ m_slider(0, 1, (pm->is_integer() ? 1.0 : 0.0001))
{
m_slider.set_increments(1.0, 10.0);
- // Compensate for crazy plugins
- // FIXME
- /*
- if (m_port_model->user_max() <= m_port_model->user_min()) {
- m_port_model->user_max(m_port_model->user_min() + 1.0);
- m_slider.set_range(m_port_model->user_min(), m_port_model->user_max());
- }*/
+ float min = 0.0f;
+ float max = 1.0f;
+
+ const Atom& min_atom = pm->get_metadata("min");
+ const Atom& max_atom = pm->get_metadata("max");
+ if (min_atom.type() == Atom::FLOAT && max_atom.type() == Atom::FLOAT) {
+ min = min_atom.get_float();
+ max = max_atom.get_float();
+ }
+
m_slider.property_draw_value() = false;
set_name(pm->path().name());
@@ -103,12 +105,12 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel
m_value_spinner.signal_value_changed().connect(
sigc::mem_fun(*this, &SliderControlGroup::update_value_from_spinner));
m_min_spinner.set_range(-99999, 99999);
- m_min_spinner.set_value(m_port_model->user_min());
+ m_min_spinner.set_value(min);
m_min_spinner.set_increments(1.0, 10.0);
m_min_spinner.set_digits(5);
m_min_spinner.signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::min_changed));
m_max_spinner.set_range(-99999, 99999);
- m_max_spinner.set_value(m_port_model->user_max());
+ m_max_spinner.set_value(max);
m_max_spinner.set_increments(1.0, 10.0);
m_max_spinner.set_digits(5);
m_max_spinner.signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::max_changed));
@@ -135,7 +137,7 @@ SliderControlGroup::SliderControlGroup(ControlPanel* panel, CountedPtr<PortModel
pack_start(m_header_box, false, false, 0);
pack_start(m_slider_box, false, false, 0);
- m_slider.set_range(m_port_model->user_min(), m_port_model->user_max());
+ m_slider.set_range(min, max);
m_enable_signal = true;
@@ -210,7 +212,7 @@ SliderControlGroup::min_changed()
if (m_enable_signal) {
char temp_buf[16];
snprintf(temp_buf, 16, "%f", min);
- App::instance().engine()->set_metadata(m_port_model->path(), "user-min", temp_buf);
+ App::instance().engine()->set_metadata(m_port_model->path(), "min", temp_buf);
}
}
@@ -231,7 +233,7 @@ SliderControlGroup::max_changed()
if (m_enable_signal) {
char temp_buf[16];
snprintf(temp_buf, 16, "%f", max);
- App::instance().engine()->set_metadata(m_port_model->path(), "user-max", temp_buf);
+ App::instance().engine()->set_metadata(m_port_model->path(), "max", temp_buf);
}
}
diff --git a/src/progs/ingenuity/ControlGroups.h b/src/progs/ingenuity/ControlGroups.h
index a5b3d1f5..3193fa71 100644
--- a/src/progs/ingenuity/ControlGroups.h
+++ b/src/progs/ingenuity/ControlGroups.h
@@ -58,7 +58,7 @@ protected:
virtual void set_min(float val) {}
virtual void set_max(float val) {}
- virtual void metadata_update(const string& key, const string& value);
+ virtual void metadata_update(const string& key, const Atom& value);
ControlPanel* m_control_panel;
CountedPtr<PortModel> m_port_model;
diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp
index 90d17c8a..94945e28 100644
--- a/src/progs/ingenuity/ControlPanel.cpp
+++ b/src/progs/ingenuity/ControlPanel.cpp
@@ -21,7 +21,6 @@
#include "NodeModel.h"
#include "PortModel.h"
#include "ControlGroups.h"
-#include "PatchController.h"
namespace Ingenuity {
@@ -52,21 +51,18 @@ ControlPanel::~ControlPanel()
void
-ControlPanel::init(NodeController* node, size_t poly)
+ControlPanel::init(CountedPtr<NodeModel> node, size_t poly)
{
assert(node != NULL);
assert(poly > 0);
- const CountedPtr<NodeModel> node_model(node->node_model());
-
if (poly > 1) {
m_voice_spinbutton->set_range(0, poly - 1);
} else {
remove(*m_voice_control_box);
}
- for (PortModelList::const_iterator i = node_model->ports().begin();
- i != node_model->ports().end(); ++i) {
+ for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) {
add_port(*i);
}
diff --git a/src/progs/ingenuity/ControlPanel.h b/src/progs/ingenuity/ControlPanel.h
index 025468d5..e1ace50a 100644
--- a/src/progs/ingenuity/ControlPanel.h
+++ b/src/progs/ingenuity/ControlPanel.h
@@ -27,7 +27,6 @@
#include <utility> // for pair<>
#include "ControlGroups.h"
#include "util/Path.h"
-#include "PortController.h"
using std::vector; using std::string; using std::pair;
using std::cerr; using std::cout; using std::endl;
@@ -40,9 +39,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
-class NodeController;
-class PortController;
-
/** A group of controls for a node (or patch).
*
@@ -55,7 +51,7 @@ public:
ControlPanel(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
virtual ~ControlPanel();
- void init(NodeController* node, size_t poly);
+ void init(CountedPtr<NodeModel> node, size_t poly);
ControlGroup* find_port(const Path& path) const;
diff --git a/src/progs/ingenuity/ControllerFactory.cpp b/src/progs/ingenuity/ControllerFactory.cpp
deleted file mode 100644
index b95bef5b..00000000
--- a/src/progs/ingenuity/ControllerFactory.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "ControllerFactory.h"
-#include "NodeModel.h"
-#include "PatchModel.h"
-#include "PortModel.h"
-#include "NodeController.h"
-#include "PatchController.h"
-#include "PortController.h"
-#include "DSSIController.h"
-
-namespace Ingenuity {
-
-
-CountedPtr<GtkObjectController>
-ControllerFactory::get_controller(CountedPtr<ObjectModel> model)
-{
- CountedPtr<PatchModel> patch_m = PtrCast<PatchModel>(model);
- if (patch_m && patch_m->controller()) {
- assert(dynamic_cast<PatchController*>(patch_m->controller().get()));
- return PtrCast<GtkObjectController>(patch_m->controller());
- } else if (patch_m) {
- CountedPtr<PatchController> pc(new PatchController(patch_m));
- patch_m->set_controller(pc);
- return pc;
- }
-
- CountedPtr<NodeModel> node_m = PtrCast<NodeModel>(model);
- if (node_m && node_m->controller()) {
- assert(dynamic_cast<NodeController*>(node_m->controller().get()));
- return PtrCast<GtkObjectController>(node_m->controller());
- } else if (node_m) {
- if (node_m->plugin()->type() == PluginModel::DSSI) {
- CountedPtr<NodeController> nc(new DSSIController(node_m));
- node_m->set_controller(nc);
- return nc;
- } else {
- CountedPtr<NodeController> nc(new NodeController(node_m));
- node_m->set_controller(nc);
- return nc;
- }
- }
-
- CountedPtr<PortModel> port_m = PtrCast<PortModel>(model);
- if (port_m && port_m->controller()) {
- assert(dynamic_cast<PortController*>(port_m->controller().get()));
- return PtrCast<GtkObjectController>(port_m->controller());
- } else if (port_m) {
- CountedPtr<PortController> pc(new PortController(port_m));
- port_m->set_controller(pc);
- return pc;
- }
-
- return CountedPtr<GtkObjectController>();
-}
-
-
-} // namespace Ingenuity
diff --git a/src/progs/ingenuity/ControllerFactory.h b/src/progs/ingenuity/ControllerFactory.h
deleted file mode 100644
index 7f48c262..00000000
--- a/src/progs/ingenuity/ControllerFactory.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef CONTROLLER_FACTORY_H
-#define CONTROLLER_FACTORY_H
-
-#include "util/CountedPtr.h"
-#include "GtkObjectController.h"
-
-namespace Ingenuity {
-
-class ControllerFactory {
-public:
- static CountedPtr<GtkObjectController> get_controller(CountedPtr<ObjectModel> model);
-};
-
-}
-
-#endif // CONTROLLER_FACTORY_H
diff --git a/src/progs/ingenuity/DSSIController.cpp b/src/progs/ingenuity/DSSIController.cpp
index 6bc75c70..4d5bb2f7 100644
--- a/src/progs/ingenuity/DSSIController.cpp
+++ b/src/progs/ingenuity/DSSIController.cpp
@@ -29,9 +29,9 @@ namespace Ingenuity {
DSSIController::DSSIController(CountedPtr<NodeModel> model)
-: NodeController(model),
- m_banks_dirty(true)
+: m_banks_dirty(true)
{
+#if 0
assert(model->plugin()->type() == PluginModel::DSSI);
Gtk::Menu::MenuList& items = m_menu.items();
items[0].property_sensitive() = true; // "Show Control Window" item
@@ -43,21 +43,24 @@ DSSIController::DSSIController(CountedPtr<NodeModel> model)
items.push_front(Gtk::Menu_Helpers::MenuElem("Show Plugin GUI",
sigc::mem_fun(this, &DSSIController::show_gui)));
+#endif
}
void
DSSIController::program_add(int bank, int program, const string& name)
{
- node_model()->add_program(bank, program, name);
- m_banks_dirty = true;
+ cerr << "FIXME: DSSI add program\n";
+ //node_model()->add_program(bank, program, name);
+ //m_banks_dirty = true;
}
void
DSSIController::program_remove(int bank, int program)
{
- node_model()->remove_program(bank, program);
- m_banks_dirty = true;
+ cerr << "FIXME: DSSI add program\n";
+ //node_model()->remove_program(bank, program);
+ //m_banks_dirty = true;
}
/** Trivial wrapper of attempt_to_show_gui for libsigc
@@ -120,22 +123,6 @@ DSSIController::send_program_change(int bank, int program)
}
-void
-DSSIController::create_module(OmFlowCanvas* canvas)
-{
- //cerr << "Creating DSSI module " << m_model->path() << endl;
-
- assert(canvas != NULL);
- assert(m_module == NULL);
-
- m_module = new DSSIModule(canvas, this);
- create_all_ports();
-
- m_module->move_to(node_model()->x(), node_model()->y());
-}
-
-
-
/** Attempt to show the DSSI GUI for this plugin.
*
* Returns whether or not GUI was successfully loaded/shown.
@@ -274,9 +261,11 @@ DSSIController::attempt_to_show_gui()
void
DSSIController::show_menu(GdkEventButton* event)
{
+#if 0
if (m_banks_dirty)
update_program_menu();
NodeController::show_menu(event);
+#endif
}
diff --git a/src/progs/ingenuity/DSSIController.h b/src/progs/ingenuity/DSSIController.h
index 0ad26e76..3eaba91a 100644
--- a/src/progs/ingenuity/DSSIController.h
+++ b/src/progs/ingenuity/DSSIController.h
@@ -20,7 +20,6 @@
#include <string>
#include <gtkmm.h>
#include "util/Path.h"
-#include "NodeController.h"
using std::string;
using namespace Ingen::Client;
@@ -33,19 +32,17 @@ namespace Ingen { namespace Client {
namespace Ingenuity {
-class Controller;
-class OmModule;
class NodeControlWindow;
class NodePropertiesWindow;
-class PortController;
-class OmFlowCanvas;
-class DSSIModule;
/* Controller for a DSSI node.
*
+ * FIXME: legacy cruft. move this code to the appropriate places and nuke
+ * this class.
+ *
* \ingroup Ingenuity
*/
-class DSSIController : public NodeController
+class DSSIController
{
public:
DSSIController(CountedPtr<NodeModel> model);
@@ -59,8 +56,6 @@ public:
void send_program_change(int bank, int program);
- void create_module(OmFlowCanvas* canvas);
-
void show_menu(GdkEventButton* event);
private:
diff --git a/src/progs/ingenuity/DSSIModule.cpp b/src/progs/ingenuity/DSSIModule.cpp
index 3d91e69b..5d235be4 100644
--- a/src/progs/ingenuity/DSSIModule.cpp
+++ b/src/progs/ingenuity/DSSIModule.cpp
@@ -20,8 +20,8 @@
namespace Ingenuity {
-DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node)
-: OmModule(canvas, static_cast<NodeController*>(node))
+DSSIModule::DSSIModule(OmFlowCanvas* canvas, CountedPtr<NodeModel> node)
+: OmModule(canvas, node)
{
}
@@ -29,9 +29,11 @@ DSSIModule::DSSIModule(OmFlowCanvas* canvas, DSSIController* node)
void
DSSIModule::on_double_click(GdkEventButton* ev)
{
+ /*
DSSIController* dc = dynamic_cast<DSSIController*>(m_node);
if (!dc || ! dc->attempt_to_show_gui())
show_control_window();
+ */
}
diff --git a/src/progs/ingenuity/DSSIModule.h b/src/progs/ingenuity/DSSIModule.h
index 7a1b0035..6cffb891 100644
--- a/src/progs/ingenuity/DSSIModule.h
+++ b/src/progs/ingenuity/DSSIModule.h
@@ -30,7 +30,7 @@ class DSSIController;
class DSSIModule : public OmModule
{
public:
- DSSIModule(OmFlowCanvas* canvas, DSSIController* node);
+ DSSIModule(OmFlowCanvas* canvas, CountedPtr<NodeModel> node);
virtual ~DSSIModule() {}
void on_double_click(GdkEventButton* ev);
diff --git a/src/progs/ingenuity/GtkObjectController.cpp b/src/progs/ingenuity/GtkObjectController.cpp
deleted file mode 100644
index ccaa3ca5..00000000
--- a/src/progs/ingenuity/GtkObjectController.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "GtkObjectController.h"
-
-namespace Ingenuity {
-
-
-GtkObjectController::GtkObjectController(CountedPtr<ObjectModel> model)
-: m_model(model)
-{
- assert(m_model);
- model->metadata_update_sig.connect(sigc::mem_fun(this, &GtkObjectController::metadata_update));
-}
-
-GtkObjectController::~GtkObjectController()
-{
-}
-
-} // namespace Ingenuity
-
diff --git a/src/progs/ingenuity/GtkObjectController.h b/src/progs/ingenuity/GtkObjectController.h
deleted file mode 100644
index 6df13d02..00000000
--- a/src/progs/ingenuity/GtkObjectController.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef GTKOBJECTCONTROLLER_H
-#define GTKOBJECTCONTROLLER_H
-
-#include <string>
-#include <gtkmm.h>
-
-#include "ObjectModel.h"
-#include "ObjectController.h"
-#include "util/CountedPtr.h"
-
-using std::string;
-
-using namespace Ingen::Client;
-
-namespace Ingenuity {
-
-class Controller;
-
-
-/** Controller for an Om object.
- *
- * Management of the model and view are this object's responsibility.
- * The view may not be created (ie in the case of patches which have never
- * been shown and all their children).
- *
- * \ingroup Ingenuity
- */
-class GtkObjectController : public ObjectController
-{
-public:
- GtkObjectController(CountedPtr<ObjectModel> model);
- virtual ~GtkObjectController();
-
- /** Destroy object.
- *
- * Object must be safe to delete immediately following the return of
- * this call.
- */
- virtual void destroy() = 0;
-
-/*
- virtual void add_to_store() = 0;
- virtual void remove_from_store() = 0;
-*/
-
- /** Derived classes should override this to handle special metadata
- * keys, then call this to set the model's metadata key.
- */
- virtual void metadata_update(const string& key, const string& value)
- { assert(m_model->get_metadata(key) != ""); }
-
- /** Rename object */
- virtual void set_path(const Path& new_path)
- { m_model->set_path(new_path); }
-
- const Path& path() const { return m_model->path(); }
-
- CountedPtr<ObjectModel> model() const { return m_model; }
-
-protected:
- CountedPtr<ObjectModel> m_model; ///< Model for this object
-};
-
-
-} // namespace Ingenuity
-
-#endif // GTKOBJECTCONTROLLER_H
diff --git a/src/progs/ingenuity/LashController.cpp b/src/progs/ingenuity/LashController.cpp
index e5807da7..0fed3cf3 100644
--- a/src/progs/ingenuity/LashController.cpp
+++ b/src/progs/ingenuity/LashController.cpp
@@ -22,7 +22,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "App.h"
-#include "PatchController.h"
#include "PatchModel.h"
using std::cerr; using std::cout; using std::endl;
diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp
index dcc08fff..5e740aac 100644
--- a/src/progs/ingenuity/LoadPatchWindow.cpp
+++ b/src/progs/ingenuity/LoadPatchWindow.cpp
@@ -19,7 +19,6 @@
#include <dirent.h>
#include "App.h"
#include "Configuration.h"
-#include "PatchController.h"
#include "PatchModel.h"
#include "ModelEngineInterface.h"
#include "Loader.h"
@@ -60,14 +59,23 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gno
}
+void
+LoadPatchWindow::present(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ set_patch(patch);
+ m_initial_data = data;
+ Gtk::Window::present();
+}
+
+
/** Sets the patch controller for this window and initializes everything.
*
* This function MUST be called before using the window in any way!
*/
void
-LoadPatchWindow::set_patch(CountedPtr<PatchController> pc)
+LoadPatchWindow::set_patch(CountedPtr<PatchModel> patch)
{
- m_patch_controller = pc;
+ m_patch = patch;
}
@@ -108,12 +116,13 @@ LoadPatchWindow::ok_clicked()
poly = m_poly_spinbutton->get_value_as_int();
if (m_replace)
- App::instance().engine()->clear_patch(m_patch_controller->model()->path());
+ App::instance().engine()->clear_patch(m_patch->path());
- CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path(), poly));
+ CountedPtr<PatchModel> pm(new PatchModel(m_patch->path(), poly));
pm->filename(get_filename());
- pm->set_metadata("filename", get_filename());
- pm->set_parent(m_patch_controller->patch_model()->parent());
+ pm->set_metadata("filename", Atom(get_filename().c_str()));
+ // FIXME: necessary?
+ //pm->set_parent(m_patch->parent());
//App::instance().engine()->push_added_patch(pm);
App::instance().loader()->load_patch(pm, true, true);
diff --git a/src/progs/ingenuity/LoadPatchWindow.h b/src/progs/ingenuity/LoadPatchWindow.h
index e22b1c1a..2c6035c8 100644
--- a/src/progs/ingenuity/LoadPatchWindow.h
+++ b/src/progs/ingenuity/LoadPatchWindow.h
@@ -22,12 +22,12 @@
#include <libglademm/xml.h>
#include <gtkmm.h>
#include "util/CountedPtr.h"
-#include "PatchController.h"
+#include "PatchModel.h"
+using Ingen::Client::PatchModel;
+using Ingen::Client::MetadataMap;
namespace Ingenuity {
-class PatchController;
-
/** 'Load Patch' window.
*
@@ -44,11 +44,13 @@ class LoadPatchWindow : public Gtk::FileChooserDialog
public:
LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml);
- void set_patch(CountedPtr<PatchController> pc);
+ void set_patch(CountedPtr<PatchModel> patch);
void set_replace() { m_replace = true; }
void set_merge() { m_replace = false; }
+ void present(CountedPtr<PatchModel> patch, MetadataMap data);
+
protected:
void on_show();
@@ -58,8 +60,10 @@ private:
void ok_clicked();
void cancel_clicked();
- CountedPtr<PatchController> m_patch_controller;
- bool m_replace;
+ MetadataMap m_initial_data;
+
+ CountedPtr<PatchModel> m_patch;
+ bool m_replace;
Gtk::RadioButton* m_poly_from_current_radio;
Gtk::RadioButton* m_poly_from_file_radio;
diff --git a/src/progs/ingenuity/LoadPluginWindow.cpp b/src/progs/ingenuity/LoadPluginWindow.cpp
index 2b59efef..9321b12a 100644
--- a/src/progs/ingenuity/LoadPluginWindow.cpp
+++ b/src/progs/ingenuity/LoadPluginWindow.cpp
@@ -19,11 +19,9 @@
#include <cassert>
#include <algorithm>
#include <cctype>
-#include "PatchController.h"
#include "NodeModel.h"
#include "App.h"
#include "PatchWindow.h"
-#include "OmFlowCanvas.h"
#include "PatchModel.h"
#include "Store.h"
#include "ModelEngineInterface.h"
@@ -107,6 +105,15 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<G
}
+void
+LoadPluginWindow::present(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ set_patch(patch);
+ m_initial_data = data;
+ Gtk::Window::present();
+}
+
+
/** Called every time the user types into the name input box.
* Used to display warning messages, and enable/disable the OK button.
*/
@@ -117,7 +124,7 @@ LoadPluginWindow::name_changed()
if (!Path::is_valid_name(name)) {
//m_message_label->set_text("Name contains invalid characters.");
m_add_button->property_sensitive() = false;
- } else if (m_patch_controller->patch_model()->get_node(name)) {
+ } else if (m_patch->get_node(name)) {
//m_message_label->set_text("An object already exists with that name.");
m_add_button->property_sensitive() = false;
} else if (name.length() == 0) {
@@ -135,11 +142,11 @@ LoadPluginWindow::name_changed()
* This function MUST be called before using the window in any way!
*/
void
-LoadPluginWindow::set_patch(CountedPtr<PatchController> pc)
+LoadPluginWindow::set_patch(CountedPtr<PatchModel> patch)
{
- m_patch_controller = pc;
+ m_patch = patch;
- if (pc->patch_model()->poly() <= 1)
+ if (patch->poly() <= 1)
m_polyphonic_checkbutton->property_sensitive() = false;
else
m_polyphonic_checkbutton->property_sensitive() = true;
@@ -161,7 +168,7 @@ LoadPluginWindow::on_show()
set_plugin_list(App::instance().store()->plugins());
// Center on patch window
- int m_w, m_h;
+ /*int m_w, m_h;
get_size(m_w, m_h);
int parent_x, parent_y, parent_w, parent_h;
@@ -169,7 +176,7 @@ LoadPluginWindow::on_show()
m_patch_controller->window()->get_size(parent_w, parent_h);
move(parent_x + parent_w/2 - m_w/2, parent_y + parent_h/2 - m_h/2);
-
+ */
m_has_shown = true;
}
Gtk::Window::on_show();
@@ -275,7 +282,7 @@ LoadPluginWindow::generate_module_name(int offset)
name += "_";
name += num_buf;
}
- if (!m_patch_controller->patch_model()->get_node(name))
+ if (!m_patch->get_node(name))
break;
else
name = "";
@@ -306,17 +313,10 @@ LoadPluginWindow::add_clicked()
dialog.run();
} else {
- const string path = m_patch_controller->model()->path().base() + name;
- NodeModel* nm = new NodeModel(plugin, path);
- nm->polyphonic(polyphonic);
+ const string path = m_patch->path().base() + name;
+ NodeModel* nm = new NodeModel(plugin, path, polyphonic);
+ nm->add_metadata(m_initial_data);
- if (m_new_module_x == 0 && m_new_module_y == 0) {
- m_patch_controller->get_view()->canvas()->get_new_module_location(
- m_new_module_x, m_new_module_y);
- }
- nm->x(m_new_module_x);
- nm->y(m_new_module_y);
-
App::instance().engine()->create_node_from_model(nm);
++m_plugin_name_offset;
m_node_name_entry->set_text(generate_module_name(m_plugin_name_offset));
diff --git a/src/progs/ingenuity/LoadPluginWindow.h b/src/progs/ingenuity/LoadPluginWindow.h
index 1654b777..0af40d05 100644
--- a/src/progs/ingenuity/LoadPluginWindow.h
+++ b/src/progs/ingenuity/LoadPluginWindow.h
@@ -24,12 +24,13 @@
#include <libglademm.h>
#include <gtkmm.h>
#include "util/CountedPtr.h"
-
+#include "PatchModel.h"
using Ingen::Client::PluginModel;
+using Ingen::Client::PatchModel;
+using Ingen::Client::MetadataMap;
namespace Ingenuity {
-class PatchController;
// Gtkmm _really_ needs to add some helper to abstract away this stupid nonsense
@@ -87,15 +88,14 @@ class LoadPluginWindow : public Gtk::Window
public:
LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml);
- void set_patch(CountedPtr<PatchController> pc);
+ void set_patch(CountedPtr<PatchModel> patch);
void set_plugin_list(const std::map<string, CountedPtr<PluginModel> >& m);
- void set_next_module_location(double x, double y)
- { m_new_module_x = x; m_new_module_y = y; }
-
void add_plugin(CountedPtr<PluginModel> plugin);
bool has_shown() const { return m_has_shown; }
+ void present(CountedPtr<PatchModel> patch, MetadataMap data);
+
protected:
void on_show();
void on_hide();
@@ -113,7 +113,10 @@ private:
void plugin_selection_changed();
string generate_module_name(int offset = 0);
- CountedPtr<PatchController> m_patch_controller;
+ MetadataMap m_initial_data;
+
+ CountedPtr<PatchModel> m_patch;
+
bool m_has_shown; // plugin list only populated on show to speed patch window creation
Glib::RefPtr<Gtk::ListStore> m_plugins_liststore;
diff --git a/src/progs/ingenuity/LoadSubpatchWindow.cpp b/src/progs/ingenuity/LoadSubpatchWindow.cpp
index 486c92b4..cb7a7ef6 100644
--- a/src/progs/ingenuity/LoadSubpatchWindow.cpp
+++ b/src/progs/ingenuity/LoadSubpatchWindow.cpp
@@ -19,9 +19,7 @@
#include <dirent.h>
#include <cassert>
#include "App.h"
-#include "PatchController.h"
#include "PatchView.h"
-#include "OmFlowCanvas.h"
#include "NodeModel.h"
#include "PatchModel.h"
#include "Configuration.h"
@@ -68,17 +66,26 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP
}
+void
+LoadSubpatchWindow::present(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ set_patch(patch);
+ m_initial_data = data;
+ Gtk::Window::present();
+}
+
+
/** Sets the patch controller for this window and initializes everything.
*
* This function MUST be called before using the window in any way!
*/
void
-LoadSubpatchWindow::set_patch(CountedPtr<PatchController> pc)
+LoadSubpatchWindow::set_patch(CountedPtr<PatchModel> patch)
{
- m_patch_controller = pc;
+ m_patch = patch;
char temp_buf[4];
- snprintf(temp_buf, 4, "%zd", pc->patch_model()->poly());
+ snprintf(temp_buf, 4, "%zd", patch->poly());
Glib::ustring txt = "Same as parent (";
txt.append(temp_buf).append(")");
m_poly_from_parent_radio->set_label(txt);
@@ -129,8 +136,7 @@ LoadSubpatchWindow::enable_poly_spinner()
void
LoadSubpatchWindow::ok_clicked()
{
- assert(m_patch_controller);
- assert(m_patch_controller->model());
+ assert(m_patch);
const string filename = get_filename();
@@ -144,25 +150,22 @@ LoadSubpatchWindow::ok_clicked()
if (m_poly_from_user_radio->get_active())
poly = m_poly_spinbutton->get_value_as_int();
else if (m_poly_from_parent_radio->get_active())
- poly = m_patch_controller->patch_model()->poly();
+ poly = m_patch->poly();
if (m_new_module_x == 0 && m_new_module_y == 0) {
- m_patch_controller->get_view()->canvas()->get_new_module_location(
- m_new_module_x, m_new_module_y);
+ throw; // FIXME
+ //m_patch_controller->get_view()->canvas()->get_new_module_location(
+ // m_new_module_x, m_new_module_y);
}
- CountedPtr<PatchModel> pm(new PatchModel(m_patch_controller->model()->path().base() + name, poly));
+ CountedPtr<PatchModel> pm(new PatchModel(m_patch->path().base() + name, poly));
pm->filename(filename);
- pm->set_parent(m_patch_controller->model());
- pm->x(m_new_module_x);
- pm->y(m_new_module_y);
- //if (name == "")
- // pm->set_path("");
- char temp_buf[16];
- snprintf(temp_buf, 16, "%16f", m_new_module_x);
- pm->set_metadata("module-x", temp_buf);
- snprintf(temp_buf, 16, "%16f", m_new_module_y);
- pm->set_metadata("module-y", temp_buf);
+ // FIXME: necessary?
+ //pm->set_parent(m_patch);
+
+ pm->set_metadata("module-x", Atom((float)m_new_module_x));
+ pm->set_metadata("module-y", Atom((float)m_new_module_y));
+
App::instance().loader()->load_patch(pm, true, false);
App::instance().configuration()->set_patch_folder(pm->filename().substr(0, pm->filename().find_last_of("/")));
diff --git a/src/progs/ingenuity/LoadSubpatchWindow.h b/src/progs/ingenuity/LoadSubpatchWindow.h
index e33880e8..ae65a9f4 100644
--- a/src/progs/ingenuity/LoadSubpatchWindow.h
+++ b/src/progs/ingenuity/LoadSubpatchWindow.h
@@ -14,7 +14,6 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef LOADSUBPATCHWINDOW_H
#define LOADSUBPATCHWINDOW_H
@@ -22,13 +21,12 @@
#include <libglademm/xml.h>
#include <gtkmm.h>
#include "util/CountedPtr.h"
-#include "PatchController.h"
-
+#include "PatchModel.h"
+using Ingen::Client::PatchModel;
+using Ingen::Client::MetadataMap;
namespace Ingenuity {
-class PatchController;
-
/** 'Add Subpatch' window.
*
@@ -41,10 +39,9 @@ class LoadSubpatchWindow : public Gtk::FileChooserDialog
public:
LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml);
- void set_patch(CountedPtr<PatchController> pc);
+ void set_patch(CountedPtr<PatchModel> patch);
- void set_next_module_location(double x, double y)
- { m_new_module_x = x; m_new_module_y = y; }
+ void present(CountedPtr<PatchModel> patch, MetadataMap data);
protected:
void on_show();
@@ -58,7 +55,9 @@ private:
void ok_clicked();
void cancel_clicked();
- CountedPtr<PatchController> m_patch_controller;
+ MetadataMap m_initial_data;
+
+ CountedPtr<PatchModel> m_patch;
double m_new_module_x;
double m_new_module_y;
diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp
index 0ca6f966..a0f099c2 100644
--- a/src/progs/ingenuity/Loader.cpp
+++ b/src/progs/ingenuity/Loader.cpp
@@ -20,7 +20,6 @@
#include <string>
#include "PatchLibrarian.h"
#include "PatchModel.h"
-#include "PatchController.h"
using std::cout; using std::endl;
namespace Ingenuity {
diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am
index 5c4f5eed..aaa832f3 100644
--- a/src/progs/ingenuity/Makefile.am
+++ b/src/progs/ingenuity/Makefile.am
@@ -22,6 +22,10 @@ ingenuity_SOURCES = \
cmdline.h \
cmdline.c \
main.cpp \
+ NodeMenu.h \
+ NodeMenu.cpp \
+ OmFlowCanvas.h \
+ OmFlowCanvas.cpp \
BreadCrumb.h \
BreadCrumbBox.h \
BreadCrumbBox.cpp \
@@ -33,18 +37,6 @@ ingenuity_SOURCES = \
Configuration.cpp \
GladeFactory.h \
GladeFactory.cpp \
- GtkObjectController.h \
- GtkObjectController.cpp \
- PatchController.h \
- PatchController.cpp \
- NodeController.h \
- NodeController.cpp \
- PortController.h \
- PortController.cpp \
- DSSIController.h \
- DSSIController.cpp \
- ControllerFactory.h \
- ControllerFactory.cpp \
LoadPluginWindow.h \
LoadPluginWindow.cpp \
LoadPatchWindow.h \
@@ -65,8 +57,6 @@ ingenuity_SOURCES = \
PatchWindow.cpp \
WindowFactory.h \
WindowFactory.cpp \
- OmFlowCanvas.h \
- OmFlowCanvas.cpp \
../../common/types.h \
../../common/Path.h \
OmModule.h \
diff --git a/src/progs/ingenuity/NewSubpatchWindow.cpp b/src/progs/ingenuity/NewSubpatchWindow.cpp
index 7f434445..8d673622 100644
--- a/src/progs/ingenuity/NewSubpatchWindow.cpp
+++ b/src/progs/ingenuity/NewSubpatchWindow.cpp
@@ -17,11 +17,9 @@
#include "App.h"
#include "ModelEngineInterface.h"
#include "NewSubpatchWindow.h"
-#include "PatchController.h"
#include "NodeModel.h"
#include "PatchModel.h"
#include "PatchView.h"
-#include "OmFlowCanvas.h"
namespace Ingenuity {
@@ -44,15 +42,22 @@ NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr
m_ok_button->property_sensitive() = false;
}
+void
+NewSubpatchWindow::present(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ set_patch(patch);
+ m_initial_data = data;
+ Gtk::Window::present();
+}
/** Sets the patch controller for this window and initializes everything.
*
* This function MUST be called before using the window in any way!
*/
void
-NewSubpatchWindow::set_patch(CountedPtr<PatchController> pc)
+NewSubpatchWindow::set_patch(CountedPtr<PatchModel> patch)
{
- m_patch_controller = pc;
+ m_patch = patch;
}
@@ -66,7 +71,7 @@ NewSubpatchWindow::name_changed()
if (!Path::is_valid_name(name)) {
m_message_label->set_text("Name contains invalid characters.");
m_ok_button->property_sensitive() = false;
- } else if (m_patch_controller->patch_model()->get_node(name)) {
+ } else if (m_patch->get_node(name)) {
m_message_label->set_text("An object already exists with that name.");
m_ok_button->property_sensitive() = false;
} else if (name.length() == 0) {
@@ -83,22 +88,19 @@ void
NewSubpatchWindow::ok_clicked()
{
PatchModel* pm = new PatchModel(
- m_patch_controller->model()->path().base() + m_name_entry->get_text(),
+ m_patch->path().base() + m_name_entry->get_text(),
m_poly_spinbutton->get_value_as_int());
if (m_new_module_x == 0 && m_new_module_y == 0) {
- m_patch_controller->get_view()->canvas()->get_new_module_location(
- m_new_module_x, m_new_module_y);
+ throw; // FIXME
+ //m_patch_controller->get_view()->canvas()->get_new_module_location(
+ // m_new_module_x, m_new_module_y);
}
- pm->set_parent(m_patch_controller->patch_model());
- pm->x(m_new_module_x);
- pm->y(m_new_module_y);
- char temp_buf[16];
- snprintf(temp_buf, 16, "%16f", m_new_module_x);
- pm->set_metadata("module-x", temp_buf);
- snprintf(temp_buf, 16, "%16f", m_new_module_y);
- pm->set_metadata("module-y", temp_buf);
+ // FIXME: necessary?
+ //pm->set_parent(m_patch);
+ pm->set_metadata("module-x", (float)m_new_module_x);
+ pm->set_metadata("module-y", (float)m_new_module_y);
App::instance().engine()->create_patch_from_model(pm);
hide();
}
diff --git a/src/progs/ingenuity/NewSubpatchWindow.h b/src/progs/ingenuity/NewSubpatchWindow.h
index 32560dde..420b82c4 100644
--- a/src/progs/ingenuity/NewSubpatchWindow.h
+++ b/src/progs/ingenuity/NewSubpatchWindow.h
@@ -21,13 +21,12 @@
#include <libglademm/xml.h>
#include <gtkmm.h>
#include "util/CountedPtr.h"
-#include "PatchController.h"
-
+#include "PatchModel.h"
+using Ingen::Client::PatchModel;
+using Ingen::Client::MetadataMap;
namespace Ingenuity {
-class PatchController;
-
/** 'New Subpatch' window.
*
@@ -40,17 +39,17 @@ class NewSubpatchWindow : public Gtk::Window
public:
NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml);
- void set_patch(CountedPtr<PatchController> pc);
+ void set_patch(CountedPtr<PatchModel> patch);
+
+ void present(CountedPtr<PatchModel> patch, MetadataMap data);
- void set_next_module_location(double x, double y)
- { m_new_module_x = x; m_new_module_y = y; }
-
private:
void name_changed();
void ok_clicked();
void cancel_clicked();
- CountedPtr<PatchController> m_patch_controller;
+ MetadataMap m_initial_data;
+ CountedPtr<PatchModel> m_patch;
double m_new_module_x;
double m_new_module_y;
diff --git a/src/progs/ingenuity/NodeControlWindow.cpp b/src/progs/ingenuity/NodeControlWindow.cpp
index 3af8f834..bc362eb5 100644
--- a/src/progs/ingenuity/NodeControlWindow.cpp
+++ b/src/progs/ingenuity/NodeControlWindow.cpp
@@ -16,7 +16,7 @@
#include "NodeControlWindow.h"
#include "GladeFactory.h"
-#include "NodeController.h"
+#include "NodeModel.h"
#include "ControlGroups.h"
#include "ControlPanel.h"
#include "PatchWindow.h"
@@ -29,7 +29,7 @@ namespace Ingenuity {
/** Create a node control window and load a new ControlPanel for it.
*/
-NodeControlWindow::NodeControlWindow(NodeController* node, size_t poly)
+NodeControlWindow::NodeControlWindow(CountedPtr<NodeModel> node, size_t poly)
: m_node(node),
m_position_stored(false),
m_x(0), m_y(0)
@@ -59,11 +59,11 @@ NodeControlWindow::NodeControlWindow(NodeController* node, size_t poly)
/** Create a node control window and with an existing ControlPanel.
*/
-NodeControlWindow::NodeControlWindow(NodeController* node, ControlPanel* panel)
+NodeControlWindow::NodeControlWindow(CountedPtr<NodeModel> node, ControlPanel* panel)
: m_node(node),
m_control_panel(panel)
{
- assert(m_node != NULL);
+ assert(m_node);
property_resizable() = true;
set_border_width(5);
diff --git a/src/progs/ingenuity/NodeControlWindow.h b/src/progs/ingenuity/NodeControlWindow.h
index b30223d7..91ccbc49 100644
--- a/src/progs/ingenuity/NodeControlWindow.h
+++ b/src/progs/ingenuity/NodeControlWindow.h
@@ -14,7 +14,6 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef NODECONTROLWINDOW_H
#define NODECONTROLWINDOW_H
@@ -23,12 +22,17 @@
#include <gtkmm.h>
#include <libglademm.h>
#include <sigc++/sigc++.h>
+#include "util/CountedPtr.h"
using std::string; using std::vector;
+namespace Ingen { namespace Client {
+ class NodeModel;
+} }
+using Ingen::Client::NodeModel;
+
namespace Ingenuity {
class ControlGroup;
-class NodeController;
class ControlPanel;
@@ -39,10 +43,12 @@ class ControlPanel;
class NodeControlWindow : public Gtk::Window
{
public:
- NodeControlWindow(NodeController* node, size_t poly);
- NodeControlWindow(NodeController* node, ControlPanel* panel);
+ NodeControlWindow(CountedPtr<NodeModel> node, size_t poly);
+ NodeControlWindow(CountedPtr<NodeModel> node, ControlPanel* panel);
virtual ~NodeControlWindow();
+ CountedPtr<NodeModel> node() { return m_node; }
+
ControlPanel* control_panel() const { return m_control_panel; }
void resize();
@@ -52,9 +58,9 @@ protected:
void on_hide();
private:
- NodeController* m_node;
- ControlPanel* m_control_panel;
- bool m_callback_enabled;
+ CountedPtr<NodeModel> m_node;
+ ControlPanel* m_control_panel;
+ bool m_callback_enabled;
bool m_position_stored;
int m_x;
diff --git a/src/progs/ingenuity/NodeController.cpp b/src/progs/ingenuity/NodeController.cpp
deleted file mode 100644
index 950f70c9..00000000
--- a/src/progs/ingenuity/NodeController.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "NodeController.h"
-#include <iostream>
-#include <gtkmm.h>
-#include "App.h"
-#include "OmModule.h"
-#include "NodeModel.h"
-#include "PortModel.h"
-#include "PortController.h"
-#include "GtkObjectController.h"
-#include "NodeControlWindow.h"
-#include "OmModule.h"
-#include "ControllerFactory.h"
-#include "PatchController.h"
-#include "OmFlowCanvas.h"
-#include "RenameWindow.h"
-#include "GladeFactory.h"
-#include "PatchWindow.h"
-#include "PatchModel.h"
-#include "NodePropertiesWindow.h"
-#include "Store.h"
-#include "ModelEngineInterface.h"
-using std::cerr; using std::endl;
-
-namespace Ingenuity {
-
-
-NodeController::NodeController(CountedPtr<NodeModel> model)
-: GtkObjectController(model),
- m_controls_menuitem(NULL),
- m_module(NULL),
- m_control_window(NULL),
- m_properties_window(NULL),
- m_bridge_port(NULL)
-{
- // Create port controllers
- for (PortModelList::const_iterator i = node_model()->ports().begin();
- i != node_model()->ports().end(); ++i) {
- assert(!(*i)->controller());
- assert((*i)->parent());
- assert((*i)->parent().get() == node_model().get());
- CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i));
- assert((*i)->controller() == pc); // PortController() does this
- }
-
- // Build menu
-
- Gtk::Menu::MenuList& items = m_menu.items();
-
- Gtk::Menu_Helpers::MenuElem controls_elem
- = Gtk::Menu_Helpers::MenuElem("Controls",
- sigc::mem_fun(this, &NodeController::show_control_window));
- m_controls_menuitem = controls_elem.get_child();
- items.push_back(controls_elem);
- items.push_back(Gtk::Menu_Helpers::MenuElem("Properties",
- sigc::mem_fun(this, &NodeController::show_properties_window)));
- items.push_back(Gtk::Menu_Helpers::SeparatorElem());
- items.push_back(Gtk::Menu_Helpers::MenuElem("Rename...",
- sigc::mem_fun(this, &NodeController::show_rename_window)));
- items.push_back(Gtk::Menu_Helpers::MenuElem("Clone",
- sigc::mem_fun(this, &NodeController::on_menu_clone)));
- items.push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All",
- sigc::mem_fun(this, &NodeController::on_menu_disconnect_all)));
- items.push_back(Gtk::Menu_Helpers::MenuElem("Destroy",
- sigc::mem_fun(this, &NodeController::on_menu_destroy)));
-
- m_controls_menuitem->property_sensitive() = false;
-
- if (node_model()->plugin() && node_model()->plugin()->type() == PluginModel::Internal
- && node_model()->plugin()->plug_label() == "midi_control_in") {
- Gtk::Menu::MenuList& items = m_menu.items();
- items.push_back(Gtk::Menu_Helpers::MenuElem("Learn",
- sigc::mem_fun(this, &NodeController::on_menu_learn)));
- }
-
- model->new_port_sig.connect(sigc::mem_fun(this, &NodeController::add_port));
- model->destroyed_sig.connect(sigc::mem_fun(this, &NodeController::destroy));
-}
-
-
-NodeController::~NodeController()
-{
- cerr << "~NodeController()\n";
- destroy_module();
-}
-
-
-void
-NodeController::destroy()
-{
- cerr << "FIXME: NODE DESTROYED\n";
- destroy_module();
- CountedPtr<ObjectModel> model = m_model;
- m_model->controller().reset();
- m_model.reset();
-}
-
-
-void
-NodeController::create_module(OmFlowCanvas* canvas)
-{
- if (!m_module || m_module->canvas() != canvas) {
- delete m_module;
- //cerr << "Creating node module " << m_model->path() << endl;
-
- // If this is a DSSI plugin, DSSIController should be doing this
- /*assert(node_model()->plugin());
- assert(node_model()->plugin()->type() != PluginModel::DSSI);
- assert(canvas != NULL);
- assert(m_module == NULL);*/
-
- assert(canvas);
- assert(node_model());
- m_module = new OmModule(canvas, this);
- create_all_ports();
- }
-
- m_module->move_to(node_model()->x(), node_model()->y());
-}
-
-
-void
-NodeController::destroy_module()
-{
- delete m_module;
- m_module = NULL;
-}
-
-
-void
-NodeController::set_path(const Path& new_path)
-{
- cerr << "FIXME: rename\n";
- /*
- remove_from_store();
-
- // Rename ports
- for (list<PortModel*>::const_iterator i = node_model()->ports().begin();
- i != node_model()->ports().end(); ++i) {
- GtkObjectController* const pc = (GtkObjectController*)((*i)->controller());
- assert(pc != NULL);
- pc->set_path(m_model->path().base() + pc->model()->name());
- }
-
- // Handle bridge port, if this node represents one
- if (m_bridge_port != NULL)
- m_bridge_port->set_path(new_path);
-
- if (m_module != NULL)
- m_module->canvas()->rename_module(node_model()->path().name(), new_path.name());
-
- GtkObjectController::set_path(new_path);
-
- add_to_store();
- */
-}
-
-#if 0
-void
-NodeController::destroy()
-{
- PatchController* pc = ((PatchController*)m_model->parent()->controller());
- assert(pc != NULL);
-
- //remove_from_store();
- //pc->remove_node(m_model->path().name());
- cerr << "FIXME: remove node\n";
-
- if (m_bridge_port != NULL)
- m_bridge_port->destroy();
- m_bridge_port = NULL;
-
- //if (m_module != NULL)
- // delete m_module;
-}
-#endif
-
-void
-NodeController::metadata_update(const string& key, const string& value)
-{
- //cout << "[NodeController] Metadata update: " << m_model->path() << endl;
-
- if (m_module != NULL) {
- if (key == "module-x") {
- float x = atof(value.c_str());
- //if (x > 0 && x < m_canvas->width())
- m_module->move_to(x, m_module->property_y().get_value());
- } else if (key == "module-y") {
- float y = atof(value.c_str());
- //if (y > 0 && y < m_canvas->height())
- m_module->move_to(m_module->property_x().get_value(), y);
- }
- }
-
- //if (m_bridge_port != NULL)
- // m_bridge_port->metadata_update(key, value);
-
- GtkObjectController::metadata_update(key, value);
-}
-
-
-void
-NodeController::add_port(CountedPtr<PortModel> pm)
-{
- assert(pm->parent().get() == node_model().get());
- assert(pm->parent() == node_model());
- assert(node_model()->get_port(pm->path().name()) == pm);
-
- //cout << "[NodeController] Adding port " << pm->path() << endl;
-
- CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(pm));
- assert(pm->controller() == pc);
-
- if (m_module != NULL) {
- pc->create_port(m_module);
- m_module->resize();
-
- // Enable "Controls" menu item on module
- if (has_control_inputs())
- enable_controls_menuitem();
- }
-}
-
-
-void
-NodeController::show_control_window()
-{
- size_t poly = 1;
- if (node_model()->polyphonic())
- poly = ((PatchModel*)node_model()->parent().get())->poly();
-
- if (!m_control_window)
- m_control_window = new NodeControlWindow(this, poly);
-
- m_control_window->present();
-}
-
-
-void
-NodeController::on_menu_destroy()
-{
- App::instance().engine()->destroy(node_model()->path());
-}
-
-
-void
-NodeController::show_rename_window()
-{
- assert(node_model()->parent());
-
- // FIXME: will this be magically cleaned up?
- RenameWindow* win = NULL;
- Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("rename_win");
- xml->get_widget_derived("rename_win", win);
-
- CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller());
- assert(parent);
-
- if (parent->window())
- win->set_transient_for(*parent->window());
-
- win->set_object(this);
- win->show();
-}
-
-void
-NodeController::on_menu_clone()
-{
- cerr << "FIXME: clone broken\n";
- /*
- assert(node_model());
- //assert(m_parent != NULL);
- //assert(m_parent->model() != NULL);
-
- string clone_name = node_model()->name();
- int i = 2; // postfix number (ie oldname_2)
-
- // Check if name already has a number postfix
- if (clone_name.find_last_of("_") != string::npos) {
- string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1);
- clone_name = clone_name.substr(0, clone_name.find_last_of("_"));
- if (sscanf(name_postfix.c_str(), "%d", &i))
- ++i;
- }
-
- char clone_postfix[4];
- for ( ; i < 100; ++i) {
- snprintf(clone_postfix, 4, "_%d", i);
- if (node_model()->parent_patch()->get_node(clone_name + clone_postfix) == NULL)
- break;
- }
-
- clone_name = clone_name + clone_postfix;
-
- const string path = node_model()->parent_patch()->base() + clone_name;
- NodeModel* nm = new NodeModel(node_model()->plugin(), path);
- nm->polyphonic(node_model()->polyphonic());
- nm->x(node_model()->x() + 20);
- nm->y(node_model()->y() + 20);
- App::instance().engine()->create_node_from_model(nm);
- */
-}
-
-
-void
-NodeController::on_menu_learn()
-{
- App::instance().engine()->midi_learn(node_model()->path());
-}
-
-void
-NodeController::on_menu_disconnect_all()
-{
- App::instance().engine()->disconnect_all(node_model()->path());
-}
-
-
-void
-NodeController::show_properties_window()
-{
- CountedPtr<PatchController> parent = PtrCast<PatchController>(node_model()->parent()->controller());
- assert(parent);
-
- if (m_properties_window) {
- Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("node_properties_win");
- xml->get_widget_derived("node_properties_win", m_properties_window);
- }
- assert(m_properties_window);
- assert(parent);
- m_properties_window->set_node(node_model());
- if (parent->window())
- m_properties_window->set_transient_for(*parent->window());
- m_properties_window->show();
-}
-
-
-/** Create all (visual) ports and add them to module (and resize it).
- * FIXME: this doesn't belong here
- */
-void
-NodeController::create_all_ports()
-{
- assert(m_module);
-
- for (PortModelList::const_iterator i = node_model()->ports().begin();
- i != node_model()->ports().end(); ++i) {
- CountedPtr<PortController> pc = PtrCast<PortController>(ControllerFactory::get_controller(*i));
- pc->create_port(m_module);
- }
-
- m_module->resize();
-
- if (has_control_inputs())
- enable_controls_menuitem();
-}
-
-
-bool
-NodeController::has_control_inputs()
-{
- for (PortModelList::const_iterator i = node_model()->ports().begin();
- i != node_model()->ports().end(); ++i)
- if ((*i)->is_input() && (*i)->is_control())
- return true;
-
- return false;
-}
-
-
-void
-NodeController::enable_controls_menuitem()
-{
- m_controls_menuitem->property_sensitive() = true;
-}
-
-
-void
-NodeController::disable_controls_menuitem()
-{
- m_controls_menuitem->property_sensitive() = false;
-
- if (m_control_window != NULL)
- m_control_window->hide();
-}
-
-
-
-} // namespace Ingenuity
-
diff --git a/src/progs/ingenuity/NodeController.h b/src/progs/ingenuity/NodeController.h
deleted file mode 100644
index c0ee6ea9..00000000
--- a/src/progs/ingenuity/NodeController.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef NODECONTROLLER_H
-#define NODECONTROLLER_H
-
-#include <string>
-#include <gtkmm.h>
-#include "util/Path.h"
-#include "util/CountedPtr.h"
-#include "GtkObjectController.h"
-#include "NodeModel.h"
-
-using std::string;
-using namespace Ingen::Client;
-
-namespace Ingen { namespace Client {
- class MetadataModel;
- class PortModel;
-} }
-
-namespace Ingenuity {
-
-class Controller;
-class OmModule;
-class NodeControlWindow;
-class NodePropertiesWindow;
-class PortController;
-class OmFlowCanvas;
-
-/** Controller for a Node.
- *
- * \ingroup Ingenuity
- */
-class NodeController : public GtkObjectController
-{
-public:
- virtual ~NodeController();
-
- virtual void metadata_update(const string& key, const string& value);
-
- virtual void create_module(OmFlowCanvas* canvas);
- virtual void destroy_module();
-
- void set_path(const Path& new_path);
-
- virtual void remove_port(const Path& path, bool resize_module) {}
-
- virtual void program_add(int bank, int program, const string& name) {}
- virtual void program_remove(int bank, int program) {}
-
- OmModule* module() { return m_module; }
-
- //void bridge_port(PortController* port) { m_bridge_port = port; }
- //PortController* as_port() { return m_bridge_port; }
-
- CountedPtr<NodeModel> node_model() { return PtrCast<NodeModel>(m_model); }
-
- NodeControlWindow* control_window() { return m_control_window; }
- void control_window(NodeControlWindow* cw) { m_control_window = cw; }
-
- virtual void show_control_window();
- virtual void show_properties_window();
- void show_rename_window();
-
- bool has_control_inputs();
-
- virtual void show_menu(GdkEventButton* event)
- { m_menu.popup(event->button, event->time); }
-
- virtual void enable_controls_menuitem();
- virtual void disable_controls_menuitem();
-
-protected:
- friend class ControllerFactory;
-
- NodeController(CountedPtr<NodeModel> model);
-
- virtual void destroy();
-
- virtual void add_port(CountedPtr<PortModel> pm);
-
- void create_all_ports();
-
- void on_menu_destroy();
- void on_menu_clone();
- void on_menu_learn();
- void on_menu_disconnect_all();
-
- Gtk::Menu m_menu;
- Glib::RefPtr<Gtk::MenuItem> m_controls_menuitem;
-
- OmModule* m_module; ///< View (module on a patch canvas)
-
- NodeControlWindow* m_control_window;
- NodePropertiesWindow* m_properties_window;
- PortController* m_bridge_port;
-};
-
-
-} // namespace Ingenuity
-
-#endif // NODECONTROLLER_H
diff --git a/src/progs/ingenuity/NodeMenu.cpp b/src/progs/ingenuity/NodeMenu.cpp
new file mode 100644
index 00000000..c3ee7a5b
--- /dev/null
+++ b/src/progs/ingenuity/NodeMenu.cpp
@@ -0,0 +1,254 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <iostream>
+#include <gtkmm.h>
+#include "NodeMenu.h"
+#include "NodeModel.h"
+#include "App.h"
+#include "ModelEngineInterface.h"
+#include "WindowFactory.h"
+
+using std::cerr; using std::endl;
+
+namespace Ingenuity {
+
+
+NodeMenu::NodeMenu(CountedPtr<NodeModel> node)
+: _node(node)
+, _controls_menuitem(NULL)
+{
+ App& app = App::instance();
+
+ Gtk::Menu_Helpers::MenuElem controls_elem = Gtk::Menu_Helpers::MenuElem("Controls",
+ sigc::bind(
+ sigc::mem_fun(app.window_factory(), &WindowFactory::present_controls),
+ node));
+ _controls_menuitem = controls_elem.get_child();
+ items().push_back(controls_elem);
+
+ items().push_back(Gtk::Menu_Helpers::MenuElem("Properties",
+ sigc::bind(
+ sigc::mem_fun(app.window_factory(), &WindowFactory::present_properties),
+ node)));
+
+ items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+ /*items().push_back(Gtk::Menu_Helpers::MenuElem("Rename...",
+ sigc::bind(
+ sigc::mem_fun(app.window_factory(), &WindowFactory::present_rename),
+ node)));*/
+ /*items().push_back(Gtk::Menu_Helpers::MenuElem("Clone",
+ sigc::bind(
+ sigc::mem_fun(app.engine(), &EngineInterface::clone),
+ node)));
+ sigc::mem_fun(this, &NodeMenu::on_menu_clone)));*/
+
+ items().push_back(Gtk::Menu_Helpers::MenuElem("Disconnect All",
+ sigc::mem_fun(this, &NodeMenu::on_menu_disconnect_all)));
+
+ items().push_back(Gtk::Menu_Helpers::MenuElem("Destroy",
+ sigc::mem_fun(this, &NodeMenu::on_menu_destroy)));
+
+ //m_controls_menuitem->property_sensitive() = false;
+
+ if (_node->plugin() && _node->plugin()->type() == PluginModel::Internal
+ && _node->plugin()->plug_label() == "midi_control_in") {
+ items().push_back(Gtk::Menu_Helpers::MenuElem("Learn",
+ sigc::mem_fun(this, &NodeMenu::on_menu_learn)));
+ }
+
+ //model->new_port_sig.connect(sigc::mem_fun(this, &NodeMenu::add_port));
+ //model->destroyed_sig.connect(sigc::mem_fun(this, &NodeMenu::destroy));
+}
+
+#if 0
+NodeMenu::~NodeMenu()
+{
+ cerr << "~NodeMenu()\n";
+}
+
+void
+NodeMenu::destroy()
+{
+ cerr << "FIXME: NODE DESTROYED\n";
+ //CountedPtr<ObjectModel> model = m_model;
+ //m_model.reset();
+}
+#endif
+
+void
+NodeMenu::set_path(const Path& new_path)
+{
+ cerr << "FIXME: rename\n";
+ /*
+ remove_from_store();
+
+ // Rename ports
+ for (list<PortModel*>::const_iterator i = _node->ports().begin();
+ i != _node->ports().end(); ++i) {
+ ObjectController* const pc = (*i)->controller();
+ assert(pc != NULL);
+ pc->set_path(m_model->path().base() + pc->model()->name());
+ }
+
+ // Handle bridge port, if this node represents one
+ if (m_bridge_port != NULL)
+ m_bridge_port->set_path(new_path);
+
+ if (m_module != NULL)
+ m_module->canvas()->rename_module(_node->path().name(), new_path.name());
+
+ ObjectController::set_path(new_path);
+
+ add_to_store();
+ */
+}
+
+#if 0
+void
+NodeMenu::destroy()
+{
+ PatchController* pc = ((PatchController*)m_model->parent()->controller());
+ assert(pc != NULL);
+
+ //remove_from_store();
+ //pc->remove_node(m_model->path().name());
+ cerr << "FIXME: remove node\n";
+
+ if (m_bridge_port != NULL)
+ m_bridge_port->destroy();
+ m_bridge_port = NULL;
+
+ //if (m_module != NULL)
+ // delete m_module;
+}
+#endif
+
+#if 0
+void
+NodeMenu::add_port(CountedPtr<PortModel> pm)
+{
+ assert(pm->parent().get() == _node.get());
+ assert(pm->parent() == _node);
+ assert(_node->get_port(pm->path().name()) == pm);
+
+ //cout << "[NodeMenu] Adding port " << pm->path() << endl;
+
+ /*
+ if (m_module != NULL) {
+ // (formerly PortController)
+ pc->create_port(m_module);
+ m_module->resize();
+
+ // Enable "Controls" menu item on module
+ if (has_control_inputs())
+ enable_controls_menuitem();
+ }*/
+}
+#endif
+
+void
+NodeMenu::on_menu_destroy()
+{
+ App::instance().engine()->destroy(_node->path());
+}
+
+
+void
+NodeMenu::on_menu_clone()
+{
+ cerr << "FIXME: clone broken\n";
+ /*
+ assert(_node);
+ //assert(m_parent != NULL);
+ //assert(m_parent->model() != NULL);
+
+ string clone_name = _node->name();
+ int i = 2; // postfix number (ie oldname_2)
+
+ // Check if name already has a number postfix
+ if (clone_name.find_last_of("_") != string::npos) {
+ string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1);
+ clone_name = clone_name.substr(0, clone_name.find_last_of("_"));
+ if (sscanf(name_postfix.c_str(), "%d", &i))
+ ++i;
+ }
+
+ char clone_postfix[4];
+ for ( ; i < 100; ++i) {
+ snprintf(clone_postfix, 4, "_%d", i);
+ if (_node->parent_patch()->get_node(clone_name + clone_postfix) == NULL)
+ break;
+ }
+
+ clone_name = clone_name + clone_postfix;
+
+ const string path = _node->parent_patch()->base() + clone_name;
+ NodeModel* nm = new NodeModel(_node->plugin(), path);
+ nm->polyphonic(_node->polyphonic());
+ nm->x(_node->x() + 20);
+ nm->y(_node->y() + 20);
+ App::instance().engine()->create_node_from_model(nm);
+ */
+}
+
+
+void
+NodeMenu::on_menu_learn()
+{
+ App::instance().engine()->midi_learn(_node->path());
+}
+
+void
+NodeMenu::on_menu_disconnect_all()
+{
+ App::instance().engine()->disconnect_all(_node->path());
+}
+
+
+bool
+NodeMenu::has_control_inputs()
+{
+ for (PortModelList::const_iterator i = _node->ports().begin();
+ i != _node->ports().end(); ++i)
+ if ((*i)->is_input() && (*i)->is_control())
+ return true;
+
+ return false;
+}
+
+
+void
+NodeMenu::enable_controls_menuitem()
+{
+ _controls_menuitem->property_sensitive() = true;
+}
+
+
+void
+NodeMenu::disable_controls_menuitem()
+{
+ _controls_menuitem->property_sensitive() = false;
+
+ //if (m_control_window != NULL)
+ // m_control_window->hide();
+}
+
+
+
+} // namespace Ingenuity
+
diff --git a/src/progs/ingenuity/NodeMenu.h b/src/progs/ingenuity/NodeMenu.h
new file mode 100644
index 00000000..a80b7a69
--- /dev/null
+++ b/src/progs/ingenuity/NodeMenu.h
@@ -0,0 +1,75 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef NODEMENU_H
+#define NODEMENU_H
+
+#include <string>
+#include <gtkmm.h>
+#include "util/Path.h"
+#include "util/CountedPtr.h"
+#include "NodeModel.h"
+using Ingen::Client::NodeModel;
+
+using std::string;
+
+namespace Ingenuity {
+
+class Controller;
+class NodeControlWindow;
+class NodePropertiesWindow;
+class OmFlowCanvas;
+
+/** Controller for a Node.
+ *
+ * \ingroup Ingenuity
+ */
+class NodeMenu : public Gtk::Menu
+{
+public:
+ NodeMenu(CountedPtr<NodeModel> node);
+
+ void set_path(const Path& new_path);
+
+ virtual void program_add(int bank, int program, const string& name) {}
+ virtual void program_remove(int bank, int program) {}
+
+ bool has_control_inputs();
+
+ //virtual void show_menu(GdkEventButton* event)
+ //{ m_menu.popup(event->button, event->time); }
+
+protected:
+
+ virtual void enable_controls_menuitem();
+ virtual void disable_controls_menuitem();
+
+ //virtual void add_port(CountedPtr<PortModel> pm);
+
+ void on_menu_destroy();
+ void on_menu_clone();
+ void on_menu_learn();
+ void on_menu_disconnect_all();
+
+ //Gtk::Menu m_menu;
+ CountedPtr<NodeModel> _node;
+ Glib::RefPtr<Gtk::MenuItem> _controls_menuitem;
+};
+
+
+} // namespace Ingenuity
+
+#endif // NODEMENU_H
diff --git a/src/progs/ingenuity/NodePropertiesWindow.h b/src/progs/ingenuity/NodePropertiesWindow.h
index 2c36dc5c..62934f0a 100644
--- a/src/progs/ingenuity/NodePropertiesWindow.h
+++ b/src/progs/ingenuity/NodePropertiesWindow.h
@@ -20,8 +20,7 @@
#include <gtkmm.h>
#include <libglademm.h>
#include "util/CountedPtr.h"
-
-namespace Ingen { namespace Client { class NodeModel; } }
+#include "NodeModel.h"
using namespace Ingen::Client;
namespace Ingenuity {
@@ -38,6 +37,7 @@ class NodePropertiesWindow : public Gtk::Window
public:
NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
+ void present(CountedPtr<NodeModel> node_model) { set_node(node_model); Gtk::Window::present(); }
void set_node(CountedPtr<NodeModel> node_model);
private:
diff --git a/src/progs/ingenuity/OmFlowCanvas.cpp b/src/progs/ingenuity/OmFlowCanvas.cpp
index d530bca0..0d2e9bb0 100644
--- a/src/progs/ingenuity/OmFlowCanvas.cpp
+++ b/src/progs/ingenuity/OmFlowCanvas.cpp
@@ -19,7 +19,6 @@
#include <flowcanvas/FlowCanvas.h>
#include "App.h"
#include "ModelEngineInterface.h"
-#include "PatchController.h"
#include "PatchModel.h"
#include "PatchWindow.h"
#include "LoadPluginWindow.h"
@@ -28,27 +27,20 @@
#include "OmPort.h"
#include "NodeModel.h"
#include "OmModule.h"
+#include "OmPortModule.h"
+#include "SubpatchModule.h"
#include "GladeFactory.h"
+#include "WindowFactory.h"
namespace Ingenuity {
-OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height)
+OmFlowCanvas::OmFlowCanvas(CountedPtr<PatchModel> patch, int width, int height)
: FlowCanvas(width, height),
- m_patch_controller(controller),
+ m_patch(patch),
m_last_click_x(0),
m_last_click_y(0)
{
- assert(controller != NULL);
-
- /*Gtk::Menu::MenuList& items = m_menu.items();
- items.push_back(Gtk::Menu_Helpers::MenuElem("Load Plugin...",
- sigc::mem_fun(this, &OmFlowCanvas::menu_load_plugin)));
- items.push_back(Gtk::Menu_Helpers::MenuElem("Load Subpatch...",
- sigc::mem_fun(this, &OmFlowCanvas::menu_load_subpatch)));
- items.push_back(Gtk::Menu_Helpers::MenuElem("New Subpatch...",
- sigc::mem_fun(this, &OmFlowCanvas::menu_create_subpatch)));*/
-
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
xml->get_widget("canvas_menu", m_menu);
@@ -62,6 +54,8 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height)
xml->get_widget("canvas_menu_load_patch", m_menu_load_patch);
xml->get_widget("canvas_menu_new_patch", m_menu_new_patch);
+ build_canvas();
+
// Add port menu items
m_menu_add_audio_input->signal_activate().connect(
sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port),
@@ -82,6 +76,13 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height)
sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port),
"midi_output", "MIDI", true));
+ // Connect to model signals to track state
+ m_patch->new_node_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::add_node));
+ m_patch->removed_node_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::remove_node));
+ m_patch->new_connection_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::connection));
+ m_patch->removed_connection_sig.connect(sigc::mem_fun(this, &OmFlowCanvas::disconnection));
+
+ // Connect widget signals to do things
m_menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_plugin));
m_menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_patch));
m_menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_new_patch));
@@ -89,6 +90,100 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height)
void
+OmFlowCanvas::build_canvas() {
+
+ // Create modules for nodes
+ for (NodeModelMap::const_iterator i = m_patch->nodes().begin();
+ i != m_patch->nodes().end(); ++i) {
+ add_node((*i).second);
+ }
+
+ // Create pseudo modules for ports (ports on this canvas, not on our module)
+ for (PortModelList::const_iterator i = m_patch->ports().begin();
+ i != m_patch->ports().end(); ++i) {
+ cerr << "FIXME: PORT MODULE LEAK!" << endl;
+ new OmPortModule(this, *i);
+ }
+
+ // Create connections
+ for (list<CountedPtr<ConnectionModel> >::const_iterator i = m_patch->connections().begin();
+ i != m_patch->connections().end(); ++i) {
+ connection(*i);
+ }
+}
+
+
+void
+OmFlowCanvas::add_node(CountedPtr<NodeModel> nm)
+{
+ cerr << "FIXME: MODULE LEAK!" << endl;
+
+ CountedPtr<PatchModel> pm = PtrCast<PatchModel>(nm);
+ if (pm)
+ new SubpatchModule(this, pm);
+ else
+ new OmModule(this, nm);
+}
+
+
+void
+OmFlowCanvas::remove_node(CountedPtr<NodeModel> nm)
+{
+ LibFlowCanvas::Module* module = get_module(nm->path().name());
+ delete module;
+}
+
+
+void
+OmFlowCanvas::connection(CountedPtr<ConnectionModel> cm)
+{
+ // Deal with port "anonymous nodes" for this patch's own ports...
+ const Path& src_parent_path = cm->src_port_path().parent();
+ const Path& dst_parent_path = cm->dst_port_path().parent();
+
+ const string& src_parent_name =
+ (src_parent_path == m_patch->path()) ? "" : src_parent_path.name();
+ const string& dst_parent_name =
+ (dst_parent_path == m_patch->path()) ? "" : dst_parent_path.name();
+
+ Port* src_port = get_port(src_parent_name, cm->src_port_path().name());
+ Port* dst_port = get_port(dst_parent_name, cm->dst_port_path().name());
+ assert(src_port && dst_port);
+
+ add_connection(src_port, dst_port);
+}
+
+
+void
+OmFlowCanvas::disconnection(const Path& src_port_path, const Path& dst_port_path)
+{
+ const string& src_node_name = src_port_path.parent().name();
+ const string& src_port_name = src_port_path.name();
+ const string& dst_node_name = dst_port_path.parent().name();
+ const string& dst_port_name = dst_port_path.name();
+
+ Port* src_port = get_port(src_node_name, src_port_name);
+ Port* dst_port = get_port(dst_node_name, dst_port_name);
+
+ if (src_port && dst_port) {
+ remove_connection(src_port, dst_port);
+ }
+
+ //patch_model()->remove_connection(src_port_path, dst_port_path);
+
+ cerr << "FIXME: disconnection\n";
+ /*
+ // Enable control slider in destination node control window
+ PortController* p = (PortController)Store::instance().port(dst_port_path)->controller();
+ assert(p);
+
+ if (p->control_panel())
+ p->control_panel()->enable_port(p->path());
+ */
+}
+
+
+void
OmFlowCanvas::connect(const Port* src_port, const Port* dst_port)
{
assert(src_port != NULL);
@@ -102,10 +197,12 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port)
dst->model()->type() == PortModel::CONTROL)
{
CountedPtr<PluginModel> pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", ""));
- CountedPtr<NodeModel> nm(new NodeModel(pm, m_patch_controller->model()->path().base()
- + src->name() + "-" + dst->name()));
- nm->x(dst->module()->property_x() - dst->module()->width() - 20);
- nm->y(dst->module()->property_y());
+ CountedPtr<NodeModel> nm(new NodeModel(pm, m_patch->path().base()
+ + src->name() + "-" + dst->name(), false));
+ nm->set_metadata("module-x", Atom((float)
+ (dst->module()->property_x() - dst->module()->width() - 20)));
+ nm->set_metadata("module-y", Atom((float)
+ (dst->module()->property_y())));
App::instance().engine()->create_node_from_model(nm.get());
App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In");
App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path());
@@ -114,9 +211,9 @@ OmFlowCanvas::connect(const Port* src_port, const Port* dst_port)
// Set control node range to port's user range
App::instance().engine()->set_port_value_queued(nm->path().base() + "Min",
- atof(dst->model()->get_metadata("user-min").c_str()));
+ dst->model()->get_metadata("user-min").get_float());
App::instance().engine()->set_port_value_queued(nm->path().base() + "Max",
- atof(dst->model()->get_metadata("user-max").c_str()));
+ dst->model()->get_metadata("user-max").get_float());
} else {
App::instance().engine()->connect(src->model()->path(),
dst->model()->path());
@@ -181,7 +278,7 @@ OmFlowCanvas::generate_port_name(const string& base) {
snprintf(num_buf, 5, "%u", i);
name = base + "_";
name += num_buf;
- if (!m_patch_controller->patch_model()->get_port(name))
+ if (!m_patch->get_port(name))
break;
}
@@ -194,7 +291,7 @@ OmFlowCanvas::generate_port_name(const string& base) {
void
OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_output)
{
- const Path& path = m_patch_controller->path().base() + generate_port_name(name);
+ const Path& path = m_patch->path().base() + generate_port_name(name);
App::instance().engine()->create_port(path, type, is_output);
char temp_buf[16];
@@ -267,30 +364,35 @@ OmFlowCanvas::menu_add_midi_output()
}
*/
+MetadataMap
+OmFlowCanvas::get_initial_data()
+{
+ MetadataMap result;
+
+ result["module-x"] = Atom((float)m_last_click_x);
+ result["module-y"] = Atom((float)m_last_click_y);
+
+ return result;
+}
+
void
OmFlowCanvas::menu_load_plugin()
{
- m_patch_controller->window()->load_plugin_window()->set_next_module_location(
- m_last_click_x, m_last_click_y);
- m_patch_controller->window()->load_plugin_window()->show();
+ App::instance().window_factory()->present_load_plugin(m_patch, get_initial_data());
}
void
OmFlowCanvas::menu_load_patch()
{
- m_patch_controller->window()->load_subpatch_window()->set_next_module_location(
- m_last_click_x, m_last_click_y);
- m_patch_controller->window()->load_subpatch_window()->show();
+ App::instance().window_factory()->present_load_subpatch(m_patch, get_initial_data());
}
void
OmFlowCanvas::menu_new_patch()
{
- m_patch_controller->window()->new_subpatch_window()->set_next_module_location(
- m_last_click_x, m_last_click_y);
- m_patch_controller->window()->new_subpatch_window()->show();
+ App::instance().window_factory()->present_new_subpatch(m_patch, get_initial_data());
}
diff --git a/src/progs/ingenuity/OmFlowCanvas.h b/src/progs/ingenuity/OmFlowCanvas.h
index 7db347f7..ae5501c4 100644
--- a/src/progs/ingenuity/OmFlowCanvas.h
+++ b/src/progs/ingenuity/OmFlowCanvas.h
@@ -19,17 +19,24 @@
#include <string>
#include <flowcanvas/FlowCanvas.h>
-
+#include "util/CountedPtr.h"
+#include "util/Path.h"
+#include "ConnectionModel.h"
+#include "PatchModel.h"
using std::string;
using namespace LibFlowCanvas;
using LibFlowCanvas::Port;
+using Ingen::Client::ConnectionModel;
+using Ingen::Client::PatchModel;
+using Ingen::Client::NodeModel;
+using Ingen::Client::MetadataMap;
namespace Ingenuity {
class OmModule;
-class PatchController;
+
/** Patch canvas widget.
*
@@ -38,16 +45,18 @@ class PatchController;
class OmFlowCanvas : public LibFlowCanvas::FlowCanvas
{
public:
- OmFlowCanvas(PatchController* controller, int width, int height);
+ OmFlowCanvas(CountedPtr<PatchModel> patch, int width, int height);
OmModule* find_module(const string& name)
{ return (OmModule*)FlowCanvas::get_module(name); }
- void connect(const Port* src_port, const Port* dst_port);
- void disconnect(const Port* src_port, const Port* dst_port);
-
+ void add_node(CountedPtr<NodeModel> nm);
+ void remove_node(CountedPtr<NodeModel> nm);
+ void connection(CountedPtr<ConnectionModel> cm);
+ void disconnection(const Path& src_port_path, const Path& dst_port_path);
+
void get_new_module_location(double& x, double& y);
- bool canvas_event(GdkEvent* event);
+
void destroy_selected();
void show_menu(GdkEvent* event)
@@ -65,10 +74,20 @@ private:
void menu_load_plugin();
void menu_new_patch();
void menu_load_patch();
+
+ MetadataMap get_initial_data();
+
+ void build_canvas();
+
+ bool canvas_event(GdkEvent* event);
+
+ void connect(const Port* src_port, const Port* dst_port);
+ void disconnect(const Port* src_port, const Port* dst_port);
+
+ CountedPtr<PatchModel> m_patch;
- PatchController* m_patch_controller;
- int m_last_click_x;
- int m_last_click_y;
+ int m_last_click_x;
+ int m_last_click_y;
Gtk::Menu* m_menu;
Gtk::MenuItem* m_menu_add_audio_input;
diff --git a/src/progs/ingenuity/OmModule.cpp b/src/progs/ingenuity/OmModule.cpp
index dd6f3da5..9e06d910 100644
--- a/src/progs/ingenuity/OmModule.cpp
+++ b/src/progs/ingenuity/OmModule.cpp
@@ -16,6 +16,7 @@
#include "OmModule.h"
#include <cassert>
+#include "util/Atom.h"
#include "App.h"
#include "ModelEngineInterface.h"
#include "OmFlowCanvas.h"
@@ -24,53 +25,95 @@
#include "OmPort.h"
#include "GladeFactory.h"
#include "RenameWindow.h"
-#include "PatchController.h"
#include "PatchWindow.h"
+#include "WindowFactory.h"
namespace Ingenuity {
-OmModule::OmModule(OmFlowCanvas* canvas, NodeController* node)
-: LibFlowCanvas::Module(canvas, node->node_model()->path().name(),
- node->node_model()->x(), node->node_model()->y()),
- m_node(node)
+OmModule::OmModule(OmFlowCanvas* canvas, CountedPtr<NodeModel> node)
+: LibFlowCanvas::Module(canvas, node->path().name()),
+ m_node(node),
+ m_menu(node)
{
assert(m_node);
- /*if (node_model()->polyphonic() && node_model()->parent() != NULL
- && node_model()->parent_patch()->poly() > 1) {
- border_width(2.0);
- }*/
- if (node->node_model()->polyphonic()) {
+ if (node->polyphonic()) {
border_width(2.0);
}
+
+ create_all_ports();
+
+ const Atom& x = node->get_metadata("module-x");
+ const Atom& y = node->get_metadata("module-y");
+
+ if (x.type() == Atom::FLOAT && y.type() == Atom::FLOAT) {
+ move_to(x.get_float(), y.get_float());
+ } else {
+ double x, y;
+ ((OmFlowCanvas*)m_canvas)->get_new_module_location(x, y);
+ }
+
+ node->new_port_sig.connect(sigc::mem_fun(this, &OmModule::add_port));
+ node->removed_port_sig.connect(sigc::mem_fun(this, &OmModule::remove_port));
+ node->metadata_update_sig.connect(sigc::mem_fun(this, &OmModule::metadata_update));
+}
+
+
+void
+OmModule::create_all_ports()
+{
+ for (PortModelList::const_iterator i = m_node->ports().begin();
+ i != m_node->ports().end(); ++i) {
+ add_port(*i);
+ }
+
+ resize();
+
+ // FIXME
+ //if (has_control_inputs())
+ // enable_controls_menuitem();
+}
+
+
+void
+OmModule::add_port(CountedPtr<PortModel> port)
+{
+ new OmPort(this, port);
+ resize();
+}
+
+
+void
+OmModule::remove_port(CountedPtr<PortModel> port)
+{
+ LibFlowCanvas::Port* canvas_port = get_port(port->path().name());
+ delete canvas_port;
}
void
OmModule::show_control_window()
{
- node()->show_control_window();
+ App::instance().window_factory()->present_controls(m_node);
}
void
OmModule::store_location()
{
- if (m_node->node_model()->x() == 0 || m_node->node_model()->y() == 0)
- return;
-
- char temp_buf[16];
+ const float x = static_cast<float>(property_x());
+ const float y = static_cast<float>(property_y());
- m_node->node_model()->x(property_x());
- snprintf(temp_buf, 16, "%f", m_node->node_model()->x());
- m_node->node_model()->set_metadata("module-x", temp_buf); // just in case?
- App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-x", temp_buf);
+ const Atom& existing_x = m_node->get_metadata("module-x");
+ const Atom& existing_y = m_node->get_metadata("module-y");
- m_node->node_model()->y(property_y());
- snprintf(temp_buf, 16, "%f", m_node->node_model()->y());
- m_node->node_model()->set_metadata("module-y", temp_buf); // just in case?
- App::instance().engine()->set_metadata(m_node->node_model()->path(), "module-y", temp_buf);
+ if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT
+ || existing_x.get_float() != x || existing_y.get_float() != y) {
+ App::instance().engine()->set_metadata(m_node->path(), "module-x", Atom(x));
+ App::instance().engine()->set_metadata(m_node->path(), "module-y", Atom(y));
+ }
+
}
@@ -78,9 +121,25 @@ void
OmModule::move_to(double x, double y)
{
Module::move_to(x, y);
- m_node->node_model()->x(x);
- m_node->node_model()->y(y);
//store_location();
}
+
+void
+OmModule::on_right_click(GdkEventButton* event)
+{
+ m_menu.popup(event->button, event->time);
+}
+
+
+void
+OmModule::metadata_update(const string& key, const Atom& value)
+{
+ if (key == "module-x" && value.type() == Atom::FLOAT)
+ move_to(value.get_float(), property_y());
+ else if (key == "module-y" && value.type() == Atom::FLOAT)
+ move_to(property_x(), value.get_float());
+}
+
+
} // namespace Ingenuity
diff --git a/src/progs/ingenuity/OmModule.h b/src/progs/ingenuity/OmModule.h
index a3d56187..243c31e7 100644
--- a/src/progs/ingenuity/OmModule.h
+++ b/src/progs/ingenuity/OmModule.h
@@ -14,17 +14,18 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef OMMODULE_H
#define OMMODULE_H
#include <string>
#include <libgnomecanvasmm.h>
#include <flowcanvas/Module.h>
+#include "NodeMenu.h"
#include "util/CountedPtr.h"
-#include "NodeController.h"
using std::string;
+class Atom;
+
namespace Ingen { namespace Client {
class PortModel;
class NodeModel;
@@ -34,7 +35,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
-class PatchController;
class OmFlowCanvas;
class OmPort;
@@ -49,7 +49,7 @@ class OmPort;
class OmModule : public LibFlowCanvas::Module
{
public:
- OmModule(OmFlowCanvas* canvas, NodeController* node);
+ OmModule(OmFlowCanvas* canvas, CountedPtr<NodeModel> node);
virtual ~OmModule() {}
virtual OmPort* port(const string& port_name) {
@@ -59,17 +59,24 @@ public:
virtual void store_location();
void move_to(double x, double y);
- void on_right_click(GdkEventButton* event) { m_node->show_menu(event); }
+ void on_right_click(GdkEventButton* event);
void show_control_window();
- NodeController* node() const { return m_node; }
+ CountedPtr<NodeModel> node() const { return m_node; }
protected:
virtual void on_double_click(GdkEventButton* ev) { show_control_window(); }
virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); }
- NodeController* m_node;
+ void metadata_update(const string& key, const Atom& value);
+
+ void create_all_ports();
+ void add_port(CountedPtr<PortModel> port);
+ void remove_port(CountedPtr<PortModel> port);
+
+ CountedPtr<NodeModel> m_node;
+ NodeMenu m_menu;
};
diff --git a/src/progs/ingenuity/OmPatchPort.h b/src/progs/ingenuity/OmPatchPort.h
index 112fc160..e7d5765f 100644
--- a/src/progs/ingenuity/OmPatchPort.h
+++ b/src/progs/ingenuity/OmPatchPort.h
@@ -30,7 +30,6 @@ using std::string; using std::list;
namespace Ingenuity {
class FlowCanvas;
-class PatchController;
class PatchWindow;
class OmPortModule;
diff --git a/src/progs/ingenuity/OmPort.h b/src/progs/ingenuity/OmPort.h
index 5ffd4e26..cedad156 100644
--- a/src/progs/ingenuity/OmPort.h
+++ b/src/progs/ingenuity/OmPort.h
@@ -30,7 +30,6 @@ using std::string; using std::list;
namespace Ingenuity {
class FlowCanvas;
-class PatchController;
class PatchWindow;
class OmModule;
diff --git a/src/progs/ingenuity/OmPortModule.cpp b/src/progs/ingenuity/OmPortModule.cpp
index e5c5fca6..aaa26205 100644
--- a/src/progs/ingenuity/OmPortModule.cpp
+++ b/src/progs/ingenuity/OmPortModule.cpp
@@ -24,22 +24,44 @@
#include "OmPort.h"
#include "GladeFactory.h"
#include "RenameWindow.h"
-#include "PatchController.h"
#include "PatchWindow.h"
+#include "OmPatchPort.h"
namespace Ingenuity {
-OmPortModule::OmPortModule(OmFlowCanvas* canvas, PortController* port, double x, double y)
-: LibFlowCanvas::Module(canvas, "", x, y),
+OmPortModule::OmPortModule(OmFlowCanvas* canvas, CountedPtr<PortModel> port)
+: LibFlowCanvas::Module(canvas, "", 0, 0), // FIXME: coords?
m_port(port)
{
- assert(m_port != NULL);
-
/*if (port_model()->polyphonic() && port_model()->parent() != NULL
&& port_model()->parent_patch()->poly() > 1) {
border_width(2.0);
}*/
+
+ assert(canvas);
+ assert(port);
+
+ if (PtrCast<PatchModel>(port->parent())) {
+ if (m_patch_port)
+ delete m_patch_port;
+
+ m_patch_port = new OmPatchPort(this, port);
+ }
+
+ resize();
+
+ const Atom& x_atom = port->get_metadata("module-x");
+ const Atom& y_atom = port->get_metadata("module-y");
+
+ if (x_atom && y_atom && x_atom.type() == Atom::FLOAT && y_atom.type() == Atom::FLOAT) {
+ move_to(x_atom.get_float(), y_atom.get_float());
+ } else {
+ double default_x;
+ double default_y;
+ canvas->get_new_module_location(default_x, default_y);
+ move_to(default_x, default_y);
+ }
}
@@ -48,15 +70,15 @@ OmPortModule::store_location()
{
char temp_buf[16];
- //m_port->port_model()->x(property_x());
+ //m_port->x(property_x());
snprintf(temp_buf, 16, "%f", property_x().get_value());
- //m_port->port_model()->set_metadata("module-x", temp_buf); // just in case?
- App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-x", temp_buf);
+ //m_port->set_metadata("module-x", temp_buf); // just in case?
+ App::instance().engine()->set_metadata(m_port->path(), "module-x", temp_buf);
- //m_port->port_model()->y(property_y());
+ //m_port->y(property_y());
snprintf(temp_buf, 16, "%f", property_y().get_value());
- //m_port->port_model()->set_metadata("module-y", temp_buf); // just in case?
- App::instance().engine()->set_metadata(m_port->port_model()->path(), "module-y", temp_buf);
+ //m_port->set_metadata("module-y", temp_buf); // just in case?
+ App::instance().engine()->set_metadata(m_port->path(), "module-y", temp_buf);
}
@@ -64,8 +86,8 @@ void
OmPortModule::move_to(double x, double y)
{
Module::move_to(x, y);
- //m_port->port_model()->x(x);
- //m_port->port_model()->y(y);
+ //m_port->x(x);
+ //m_port->y(y);
//store_location();
}
diff --git a/src/progs/ingenuity/OmPortModule.h b/src/progs/ingenuity/OmPortModule.h
index 85bd349b..00d20f96 100644
--- a/src/progs/ingenuity/OmPortModule.h
+++ b/src/progs/ingenuity/OmPortModule.h
@@ -14,14 +14,13 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef OMPORTMODULE_H
#define OMPORTMODULE_H
#include <string>
#include <libgnomecanvasmm.h>
#include <flowcanvas/Module.h>
-#include "PortController.h"
+#include "OmPatchPort.h"
using std::string;
namespace Ingen { namespace Client {
@@ -33,8 +32,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
-class PatchController;
-class PortController;
class OmFlowCanvas;
class OmPort;
@@ -48,7 +45,7 @@ class OmPort;
class OmPortModule : public LibFlowCanvas::Module
{
public:
- OmPortModule(OmFlowCanvas* canvas, PortController* port, double x, double y);
+ OmPortModule(OmFlowCanvas* canvas, CountedPtr<PortModel> port);
virtual ~OmPortModule() {}
//virtual OmPort* port(const string& port_name) {
@@ -60,13 +57,14 @@ public:
//void on_right_click(GdkEventButton* event) { m_port->show_menu(event); }
- PortController* port() const { return m_port; }
+ CountedPtr<PortModel> port() const { return m_port; }
protected:
//virtual void on_double_click(GdkEventButton* ev) { show_control_window(); }
//virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); }
- PortController* m_port;
+ CountedPtr<PortModel> m_port;
+ OmPatchPort* m_patch_port; ///< Port on this 'anonymous' module
};
diff --git a/src/progs/ingenuity/PatchController.cpp b/src/progs/ingenuity/PatchController.cpp
deleted file mode 100644
index f02aa773..00000000
--- a/src/progs/ingenuity/PatchController.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "PatchController.h"
-#include <cassert>
-#include <cstdlib>
-#include "GladeFactory.h"
-#include "Configuration.h"
-#include "util/Path.h"
-#include "ControlPanel.h"
-#include "ConnectionModel.h"
-#include "OmFlowCanvas.h"
-#include "PatchView.h"
-#include "flowcanvas/Module.h"
-#include "PluginModel.h"
-#include "SubpatchModule.h"
-#include "DSSIModule.h"
-#include "PatchWindow.h"
-#include "NodeModel.h"
-#include "OmModule.h"
-#include "OmPortModule.h"
-#include "OmPort.h"
-#include "ControlModel.h"
-#include "NodeControlWindow.h"
-#include "NodeController.h"
-#include "PortController.h"
-#include "App.h"
-#include "PatchTreeWindow.h"
-#include "PatchPropertiesWindow.h"
-#include "DSSIController.h"
-#include "PatchModel.h"
-#include "Store.h"
-#include "ControllerFactory.h"
-
-using std::cerr; using std::cout; using std::endl;
-using namespace Ingen::Client;
-
-namespace Ingenuity {
-
-
-PatchController::PatchController(CountedPtr<PatchModel> model)
-: NodeController(model),
- m_properties_window(NULL),
- m_window(NULL),
- m_patch_model(model),
- m_module_x(0),
- m_module_y(0)
-{
- //model->new_port_sig.connect(sigc::mem_fun(this, &PatchController::add_port));
- model->new_node_sig.connect(sigc::mem_fun(this, &PatchController::add_node));
- model->new_connection_sig.connect(sigc::mem_fun(this, &PatchController::connection));
- model->removed_connection_sig.connect(sigc::mem_fun(this, &PatchController::disconnection));
-}
-
-
-PatchController::~PatchController()
-{
- if (m_patch_view) {
- claim_patch_view();
- }
-
- if (m_control_window) {
- m_control_window->hide();
- delete m_control_window;
- m_control_window = NULL;
- }
-
- if (m_window) {
- delete m_window;
- m_window = NULL;
- }
-}
-
-#if 0
-void
-PatchController::clear()
-{
- // Destroy model
- // Destroying nodes removes models from patch model, which invalidates any
- // iterator to nodes, so avoid the iterator problem by doing it this way:
- const NodeModelMap& nodes = patch_model()->nodes();
- size_t remaining = nodes.size();
-
- while (remaining > 0) {
- CountedPtr<NodeController> nc = (*nodes.begin()).second->controller();
- assert(nc);
- nc->destroy();
- assert(nodes.size() == remaining - 1);
- --remaining;
- }
- assert(nodes.empty());
-
- patch_model()->clear();
-
- if (m_patch_view) {
- assert(m_patch_view->canvas());
- m_patch_view->canvas()->destroy();
- }
-}
-#endif
-
-#if 0
-void
-PatchController::destroy()
-{
- // Destroying nodes removes models from patch model, which invalidates any
- // iterator to nodes, so avoid the iterator problem by doing it this way:
- const NodeModelMap& nodes = patch_model()->nodes();
- size_t remaining = nodes.size();
-
- while (remaining > 0) {
- CountedPtr<NodeController> nc = (*nodes.begin()).second->controller();
- assert(nc);
- nc->destroy();
- assert(nodes.size() == remaining - 1);
- --remaining;
- }
- assert(nodes.empty());
-
- //App::instance().remove_patch(this);
- App::instance().patch_tree()->remove_patch(path());
-
- // Delete all children models
- //patch_model()->clear();
-
- // Remove self from object store
- //Store::instance().remove_object(this);
-
- // Delete self from parent (this will delete model)
- /*if (patch_model()->parent()) {
- PatchController* const parent = (PatchController*)patch_model()->parent()->controller();
- assert(parent);
- parent->remove_node(name());
- } else {
- //delete m_model;
- }*/
-}
-#endif
-
-
-void
-PatchController::metadata_update(const string& key, const string& value)
-{
- NodeController::metadata_update(key, value);
-
- if (key == "filename")
- patch_model()->filename(value);
-}
-
-
-void
-PatchController::set_path(const Path& new_path)
-{
- assert(m_model);
- Path old_path = path();
-
- // Rename nodes
- for (NodeModelMap::const_iterator i = patch_model()->nodes().begin();
- i != patch_model()->nodes().end(); ++i) {
- const NodeModel* const nm = (*i).second.get();
- assert(nm);
- CountedPtr<NodeController> nc = PtrCast<NodeController>(nm->controller());
- assert(nc);
- nc->set_path(new_path.base() + nc->node_model()->path().name());
- }
-
-#ifdef DEBUG
- // Be sure ports were renamed by their bridge nodes
- for (PortModelList::const_iterator i = node_model()->ports().begin();
- i != node_model()->ports().end(); ++i) {
- CountedPtr<GtkObjectController> pc = PtrCast<GtkObjectController>((*i)->controller());
- assert(pc);
- assert(pc->path().parent()== new_path);
- }
-#endif
-
- App::instance().patch_tree()->patch_renamed(old_path, new_path);
-
- /*if (m_window)
- m_window->patch_renamed(new_path);*/
-
- if (m_control_window)
- m_control_window->set_title(new_path + " Controls");
-
- if (m_module)
- m_module->name(new_path.name());
-
- CountedPtr<PatchController> parent = PtrCast<PatchController>(patch_model()->parent()->controller());
-
- //if (parent && parent->window())
- // parent->window()->node_renamed(old_path, new_path);
-
- //remove_from_store();
- GtkObjectController::set_path(new_path);
- //add_to_store();
-
- if (old_path.name() != new_path.name())
- parent->patch_model()->rename_node(old_path, new_path);
-}
-
-
-void
-PatchController::create_module(OmFlowCanvas* canvas)
-{
- // Update menu if we didn't used to have a module
- if (!m_module) {
- /*Gtk::Menu::MenuList& items = m_menu.items();
- m_menu.remove(items[4]);
-
- items.push_front(Gtk::Menu_Helpers::SeparatorElem());
- items.push_front(Gtk::Menu_Helpers::MenuElem("Browse to Patch",
- sigc::mem_fun((SubpatchModule*)m_module, &SubpatchModule::browse_to_patch)));
- items.push_front(Gtk::Menu_Helpers::MenuElem("Open Patch in New Window",
- sigc::mem_fun(this, &PatchController::show_patch_window)));*/
- }
-
- if (!m_module || m_module->canvas() != canvas) {
-
- //cerr << "Creating patch module " << m_model->path() << endl;
-
- assert(canvas);
- assert(m_module == NULL);
- assert(!m_patch_view || canvas != m_patch_view->canvas());
-
- // FIXME: weirdo using model->controller() to get shared_ptr_from_this..
- m_module = new SubpatchModule(canvas, PtrCast<PatchController>(m_model->controller()));
- create_all_ports();
- }
-
- m_module->move_to(node_model()->x(), node_model()->y());
-}
-
-
-CountedPtr<PatchView>
-PatchController::get_view()
-{
- if (m_patch_view)
- return m_patch_view;
-
- Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
-
- PatchView* pv = NULL;
- xml->get_widget_derived("patch_view_vbox", pv);
- assert(pv);
- m_patch_view = CountedPtr<PatchView>(pv);
- m_patch_view->patch_controller(this);
- assert(m_patch_view->canvas());
-
- // Create modules for nodes
- for (NodeModelMap::const_iterator i = patch_model()->nodes().begin();
- i != patch_model()->nodes().end(); ++i) {
-
- const CountedPtr<NodeModel> nm = (*i).second;
-
- string val = nm->get_metadata("module-x");
- if (val != "")
- nm->x(atof(val.c_str()));
- val = nm->get_metadata("module-y");
- if (val != "")
- nm->y(atof(val.c_str()));
-
- /* Set sane default coordinates if not set already yet */
- if (nm->x() == 0.0f && nm->y() == 0.0f) {
- double x, y;
- m_patch_view->canvas()->get_new_module_location(x, y);
- nm->x(x);
- nm->y(y);
- }
-
- CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(nm));
-
- assert(nc);
- assert(nm->controller() == nc);
-
- nc->create_module(m_patch_view->canvas());
- assert(nc->module());
- }
-
- // Create pseudo modules for ports (ports on this canvas, not on our module)
- for (PortModelList::const_iterator i = patch_model()->ports().begin();
- i != patch_model()->ports().end(); ++i) {
- CountedPtr<PortController> pc = PtrCast<PortController>((*i)->controller());
- assert(pc);
- pc->create_module(m_patch_view->canvas());
- }
-
-
- // Create connections
- for (list<CountedPtr<ConnectionModel> >::const_iterator i = patch_model()->connections().begin();
- i != patch_model()->connections().end(); ++i) {
- connection(*i);
- }
-
- // Set run checkbox
- if (patch_model()->enabled())
- m_patch_view->enable();
-
- return m_patch_view;
-}
-
-
-void
-PatchController::show_properties_window()
-{
- if (!m_properties_window) {
- Glib::RefPtr<Gnome::Glade::Xml> glade_xml = GladeFactory::new_glade_reference();
- glade_xml->get_widget_derived("patch_properties_win", m_properties_window);
- m_properties_window->patch_model(patch_model());
- }
-
- m_properties_window->show();
-
-}
-
-
-/** Create a connection in the view (canvas).
- */
-void
-PatchController::connection(CountedPtr<ConnectionModel> cm)
-{
- if (m_patch_view) {
-
- // Deal with port "anonymous nodes" for this patch's own ports...
- const Path& src_parent_path = cm->src_port_path().parent();
- const Path& dst_parent_path = cm->dst_port_path().parent();
-
- const string& src_parent_name =
- (src_parent_path == path()) ? "" : src_parent_path.name();
- const string& dst_parent_name =
- (dst_parent_path == path()) ? "" : dst_parent_path.name();
-
- Port* src_port = m_patch_view->canvas()->get_port(src_parent_name, cm->src_port_path().name());
- Port* dst_port = m_patch_view->canvas()->get_port(dst_parent_name, cm->dst_port_path().name());
- assert(src_port && dst_port);
-
- m_patch_view->canvas()->add_connection(src_port, dst_port);
- }
-}
-
-
-/** Add a child node to this patch.
- *
- * This is for plugin nodes and patches, and is responsible for creating the
- * GtkObjectController for @a node (and through that the View if necessary)
- */
-void
-PatchController::add_node(CountedPtr<NodeModel> node)
-{
- assert(node);
- assert(node->parent().get() == m_patch_model.get());
- assert(node->parent() == m_patch_model);
- assert(patch_model()->get_node(node->path().name()));
-
- assert(node->parent() == m_patch_model);
-
- CountedPtr<NodeController> nc = PtrCast<NodeController>(ControllerFactory::get_controller(node));
- assert(nc);
- assert(node->controller() == nc); // lifeline reference
-
- if (m_patch_view) {
- double x, y;
- m_patch_view->canvas()->get_new_module_location(x, y);
- node->x(x);
- node->y(y);
-
- // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas)
- float old_zoom = m_patch_view->canvas()->get_zoom();
- if (old_zoom != 1.0)
- m_patch_view->canvas()->set_zoom(1.0);
-
- nc->create_module(m_patch_view->canvas());
- assert(nc->module());
- nc->module()->resize();
-
- // Reset zoom
- if (old_zoom != 1.0) {
- m_patch_view->canvas()->set_zoom(old_zoom);
- nc->module()->zoom(old_zoom);
- }
- }
-
-}
-
-#if 0
-/** Add a port to this patch.
- *
- * Will add a port to the subpatch module and the control window, if they
- * exist.
- */
-void
-PatchController::add_port(CountedPtr<PortModel> pm)
-{
- assert(pm);
- assert(pm->parent() == m_patch_model);
- assert(patch_model()->get_port(pm->path().name()));
-
- //cerr << "[PatchController] Adding port " << pm->path() << endl;
-
- /*if (patch_model()->get_port(pm->path().name())) {
- cerr << "[PatchController] Ignoring duplicate port "
- << pm->path() << endl;
- return;
- }*/
-
- //node_model()->add_port(pm);
- CountedPtr<PortController> pc = ControllerFactory::get_controller(pm);
-
- // Handle bridge ports/nodes (this is uglier than it should be)
- /*NodeController* nc = (NodeController*)Store::instance().node(pm->path())->controller();
- if (nc)
- nc->bridge_port(pc);
- */
-
- // Create port on this patch's module (if there is one)
- if (m_module) {
- pc->create_port(m_module);
- m_module->resize();
- }
-
- // Create port's (pseudo) module on this patch's canvas (if there is one)
- if (m_patch_view) {
-
- // Set zoom to 1.0 so module isn't messed up (Death to GnomeCanvas)
- float old_zoom = m_patch_view->canvas()->get_zoom();
- m_patch_view->canvas()->set_zoom(1.0);
-
- pc->create_module(m_patch_view->canvas());
-
- // Reset zoom
- pc->module()->zoom(old_zoom);
- }
-
- if (m_control_window) {
- assert(m_control_window->control_panel());
- m_control_window->control_panel()->add_port(pm);
- m_control_window->resize();
- }
-
- // Enable "Controls" menuitem on module and patch window, if necessary
- if (has_control_inputs())
- enable_controls_menuitem();
-}
-
-
-/** Removes a port from this patch
- */
-void
-PatchController::remove_port(const Path& path, bool resize_module)
-{
- assert(path.parent() == m_model->path());
- assert( ! patch_model()->get_port(path.name()));
-
- //cerr << "[PatchController] Removing port " << path << endl;
-
- /* FIXME
- if (m_control_panel) {
- m_control_panel->remove_port(path);
- if (m_control_window) {
- assert(m_control_window->control_panel() == m_control_panel);
- m_control_window->resize();
- }
- }*/
-
- if (m_module) {
- delete m_module->port(path.name());
- if (resize_module)
- m_module->resize();
- }
-
- // Disable "Controls" menuitem on module and patch window, if necessary
- if (!has_control_inputs())
- disable_controls_menuitem();
-}
-#endif
-
-void
-PatchController::disconnection(const Path& src_port_path, const Path& dst_port_path)
-{
- const string& src_node_name = src_port_path.parent().name();
- const string& src_port_name = src_port_path.name();
- const string& dst_node_name = dst_port_path.parent().name();
- const string& dst_port_name = dst_port_path.name();
-
- if (m_patch_view) {
- Port* src_port = m_patch_view->canvas()->get_port(src_node_name, src_port_name);
- Port* dst_port = m_patch_view->canvas()->get_port(dst_node_name, dst_port_name);
-
- if (src_port && dst_port) {
- m_patch_view->canvas()->remove_connection(src_port, dst_port);
- }
- }
-
- //patch_model()->remove_connection(src_port_path, dst_port_path);
-
- cerr << "FIXME: disconnection\n";
- /*
- // Enable control slider in destination node control window
- PortController* p = (PortController)Store::instance().port(dst_port_path)->controller();
- assert(p);
-
- if (p->control_panel())
- p->control_panel()->enable_port(p->path());
- */
-}
-
-
-/** Become the parent of the patch view.
- *
- * Steals the view away from whatever window is currently showing it.
- */
-void
-PatchController::claim_patch_view()
-{
- assert(m_patch_view);
-
- m_patch_view->hide();
- m_patch_view->reparent(m_patch_view_bin);
-}
-
-
-void
-PatchController::show_control_window()
-{
- assert(patch_model());
-
- if (m_control_window == NULL)
- m_control_window = new NodeControlWindow(this, patch_model()->poly());
-
- if (m_control_window->control_panel()->num_controls() > 0)
- m_control_window->present();
-}
-
-
-} // namespace Ingenuity
diff --git a/src/progs/ingenuity/PatchController.h b/src/progs/ingenuity/PatchController.h
deleted file mode 100644
index e9c0d0b6..00000000
--- a/src/progs/ingenuity/PatchController.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef PATCHCONTROLLER_H
-#define PATCHCONTROLLER_H
-
-#include <string>
-#include <gtkmm.h>
-#include "util/CountedPtr.h"
-#include "NodeController.h"
-#include "PatchModel.h"
-
-namespace Ingen { namespace Client {
- class PatchModel;
- class NodeModel;
- class PortModel;
- class ControlModel;
- class ConnectionModel;
-} }
-
-using std::string;
-using namespace Ingen::Client;
-
-namespace Ingenuity {
-
-class PatchWindow;
-class SubpatchModule;
-class Controller;
-class OmFlowCanvas;
-class NodeControlWindow;
-class PatchPropertiesWindow;
-class ControlPanel;
-class PatchView;
-class NodeController;
-
-
-/** Controller for a patch.
- *
- * A patch is different from a port or node because there are two
- * representations in the Gtk client - the window and the module in the parent
- * patch (if applicable). So, this is a master class that contains both of
- * those representations, and acts as the recipient of all patch related
- * events (being the controller).
- *
- * \ingroup Ingenuity
- */
-class PatchController : public NodeController
-{
-public:
- virtual ~PatchController();
-
- /*
- virtual void add_to_store();
- virtual void remove_from_store();
- */
-
- virtual void metadata_update(const string& key, const string& value);
-
- //virtual void add_port(CountedPtr<PortModel> pm);
- //virtual void remove_port(const Path& path, bool resize_module);
-
- void connection(CountedPtr<ConnectionModel> cm);
- void disconnection(const Path& src_port_path, const Path& dst_port_path);
- //void clear();
-
- void show_control_window();
- void show_properties_window();
- void show_patch_window();
-
- void claim_patch_view();
-
- void create_module(OmFlowCanvas* canvas);
-
- CountedPtr<PatchView> get_view();
- PatchWindow* window() const { return m_window; }
- void window(PatchWindow* pw) { m_window = pw; }
-
- void set_path(const Path& new_path);
-
- //void enable();
- //void disable();
-
- const CountedPtr<PatchModel> patch_model() const { return m_patch_model; }
-
-private:
- friend class ControllerFactory;
- PatchController(CountedPtr<PatchModel> model);
-
- void add_node(CountedPtr<NodeModel> object);
-
- PatchPropertiesWindow* m_properties_window;
-
- // FIXME: remove these
- PatchWindow* m_window; ///< Patch Window currently showing m_patch_view
- CountedPtr<PatchView> m_patch_view; ///< View (canvas) of this patch
-
- CountedPtr<PatchModel> m_patch_model;
-
- /** Invisible bin used to store patch view when not shown by a patch window */
- Gtk::Alignment m_patch_view_bin;
-
- // Coordinates for next added plugin (used by canvas menu)
- // 0 means "not set", ie guess at the best location
- int m_module_x;
- int m_module_y;
-};
-
-
-} // namespace Ingenuity
-
-#endif // PATCHCONTROLLER_H
diff --git a/src/progs/ingenuity/PatchPropertiesWindow.cpp b/src/progs/ingenuity/PatchPropertiesWindow.cpp
index 2271cc21..b6dd5e7f 100644
--- a/src/progs/ingenuity/PatchPropertiesWindow.cpp
+++ b/src/progs/ingenuity/PatchPropertiesWindow.cpp
@@ -41,20 +41,32 @@ PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib
* the window in any way.
*/
void
-PatchPropertiesWindow::patch_model(CountedPtr<PatchModel> patch_model)
+PatchPropertiesWindow::set_patch(CountedPtr<PatchModel> patch_model)
{
property_title() = patch_model->path() + " Properties";
m_patch_model = patch_model;
- m_author_entry->set_text(m_patch_model->get_metadata("author"));
- m_textview->get_buffer()->set_text(m_patch_model->get_metadata("description"));
+
+ const Atom& author_atom = m_patch_model->get_metadata("author");
+ m_author_entry->set_text(
+ (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" );
+
+ const Atom& desc_atom = m_patch_model->get_metadata("description");
+ m_textview->get_buffer()->set_text(
+ (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" );
}
void
PatchPropertiesWindow::cancel_clicked()
{
- m_author_entry->set_text(m_patch_model->get_metadata("author"));
- m_textview->get_buffer()->set_text(m_patch_model->get_metadata("description"));
+ const Atom& author_atom = m_patch_model->get_metadata("author");
+ m_author_entry->set_text(
+ (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" );
+
+ const Atom& desc_atom = m_patch_model->get_metadata("description");
+ m_textview->get_buffer()->set_text(
+ (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" );
+
hide();
}
@@ -62,8 +74,8 @@ PatchPropertiesWindow::cancel_clicked()
void
PatchPropertiesWindow::ok_clicked()
{
- m_patch_model->set_metadata("author", m_author_entry->get_text());
- m_patch_model->set_metadata("description", m_textview->get_buffer()->get_text());
+ m_patch_model->set_metadata("author", Atom(m_author_entry->get_text().c_str()));
+ m_patch_model->set_metadata("description", Atom(m_textview->get_buffer()->get_text().c_str()));
hide();
}
diff --git a/src/progs/ingenuity/PatchPropertiesWindow.h b/src/progs/ingenuity/PatchPropertiesWindow.h
index 76f12061..4f5da674 100644
--- a/src/progs/ingenuity/PatchPropertiesWindow.h
+++ b/src/progs/ingenuity/PatchPropertiesWindow.h
@@ -40,7 +40,8 @@ class PatchPropertiesWindow : public Gtk::Window
public:
PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
- void patch_model(CountedPtr<PatchModel> patch_model);
+ void present(CountedPtr<PatchModel> patch_model) { set_patch(patch_model); Gtk::Window::present(); }
+ void set_patch(CountedPtr<PatchModel> patch_model);
void cancel_clicked();
void ok_clicked();
diff --git a/src/progs/ingenuity/PatchTreeWindow.cpp b/src/progs/ingenuity/PatchTreeWindow.cpp
index 090aba18..40ce5baf 100644
--- a/src/progs/ingenuity/PatchTreeWindow.cpp
+++ b/src/progs/ingenuity/PatchTreeWindow.cpp
@@ -18,7 +18,6 @@
#include "ModelEngineInterface.h"
#include "OSCEngineSender.h"
#include "PatchTreeWindow.h"
-#include "PatchController.h"
#include "PatchWindow.h"
#include "Store.h"
#include "SubpatchModule.h"
@@ -77,15 +76,13 @@ PatchTreeWindow::new_object(CountedPtr<ObjectModel> object)
{
CountedPtr<PatchModel> patch = PtrCast<PatchModel>(object);
if (patch)
- add_patch(PtrCast<PatchController>(patch->controller()));
+ add_patch(patch);
}
void
-PatchTreeWindow::add_patch(CountedPtr<PatchController> pc)
+PatchTreeWindow::add_patch(CountedPtr<PatchModel> pm)
{
- const CountedPtr<PatchModel> pm = pc->patch_model();
-
if (!pm->parent()) {
Gtk::TreeModel::iterator iter = m_patch_treestore->append();
Gtk::TreeModel::Row row = *iter;
@@ -101,7 +98,7 @@ PatchTreeWindow::add_patch(CountedPtr<PatchController> pc)
row[m_patch_tree_columns.name_col] = pm->path().name();
}
row[m_patch_tree_columns.enabled_col] = false;
- row[m_patch_tree_columns.patch_controller_col] = pc;
+ row[m_patch_tree_columns.patch_model_col] = pm;
m_patches_treeview->expand_row(m_patch_treestore->get_path(iter), true);
} else {
Gtk::TreeModel::Children children = m_patch_treestore->children();
@@ -112,7 +109,7 @@ PatchTreeWindow::add_patch(CountedPtr<PatchController> pc)
Gtk::TreeModel::Row row = *iter;
row[m_patch_tree_columns.name_col] = pm->path().name();
row[m_patch_tree_columns.enabled_col] = false;
- row[m_patch_tree_columns.patch_controller_col] = pc;
+ row[m_patch_tree_columns.patch_model_col] = pm;
m_patches_treeview->expand_row(m_patch_treestore->get_path(iter), true);
}
}
@@ -132,8 +129,8 @@ Gtk::TreeModel::iterator
PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path)
{
for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) {
- CountedPtr<PatchController> pc = (*c)[m_patch_tree_columns.patch_controller_col];
- if (pc->model()->path() == path) {
+ CountedPtr<PatchModel> pm = (*c)[m_patch_tree_columns.patch_model_col];
+ if (pm->path() == path) {
return c;
} else if ((*c)->children().size() > 0) {
Gtk::TreeModel::iterator ret = find_patch(c->children(), path);
@@ -151,7 +148,7 @@ PatchTreeWindow::event_patch_selected()
Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected();
if (active) {
Gtk::TreeModel::Row row = *active;
- CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col];
+ CountedPtr<PatchModel> pm = row[m_patch_tree_columns.patch_model_col];
}
}
*/
@@ -165,9 +162,10 @@ PatchTreeWindow::show_patch_menu(GdkEventButton* ev)
Gtk::TreeModel::iterator active = m_patch_tree_selection->get_selected();
if (active) {
Gtk::TreeModel::Row row = *active;
- CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col];
- if (pc)
- pc->show_menu(ev);
+ CountedPtr<PatchModel> pm = row[m_patch_tree_columns.patch_model_col];
+ if (pm)
+ cerr << "FIXME: patch menu\n";
+ //pm->show_menu(ev);
}
}
@@ -177,9 +175,10 @@ PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::Tr
{
Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path);
Gtk::TreeModel::Row row = *active;
- CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col];
+ CountedPtr<PatchModel> pm = row[m_patch_tree_columns.patch_model_col];
- App::instance().window_factory()->present(pc);
+ cerr << "FIXME: tree win show\n";
+ //App::instance().window_factory()->present(pc);
}
@@ -190,12 +189,12 @@ PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str)
Gtk::TreeModel::iterator active = m_patch_treestore->get_iter(path);
Gtk::TreeModel::Row row = *active;
- CountedPtr<PatchController> pc = row[m_patch_tree_columns.patch_controller_col];
- Glib::ustring patch_path = pc->model()->path();
+ CountedPtr<PatchModel> pm = row[m_patch_tree_columns.patch_model_col];
+ Glib::ustring patch_path = pm->path();
- assert(pc);
+ assert(pm);
- if ( ! pc->patch_model()->enabled()) {
+ if ( ! pm->enabled()) {
if (m_enable_signal)
App::instance().engine()->enable_patch(patch_path);
//pc->enable();
diff --git a/src/progs/ingenuity/PatchTreeWindow.h b/src/progs/ingenuity/PatchTreeWindow.h
index d23c4e54..91e68bf1 100644
--- a/src/progs/ingenuity/PatchTreeWindow.h
+++ b/src/progs/ingenuity/PatchTreeWindow.h
@@ -29,7 +29,6 @@ using Ingen::Client::Store;
namespace Ingenuity {
class PatchWindow;
-class PatchController;
class PatchTreeView;
@@ -50,7 +49,7 @@ public:
void patch_disabled(const Path& path);
void patch_renamed(const Path& old_path, const Path& new_path);
- void add_patch(CountedPtr<PatchController> pc);
+ void add_patch(CountedPtr<PatchModel> pm);
void remove_patch(const Path& path);
void show_patch_menu(GdkEventButton* ev);
@@ -66,11 +65,11 @@ protected:
struct PatchTreeModelColumns : public Gtk::TreeModel::ColumnRecord
{
PatchTreeModelColumns()
- { add(name_col); add(enabled_col); add(patch_controller_col); }
+ { add(name_col); add(enabled_col); add(patch_model_col); }
Gtk::TreeModelColumn<Glib::ustring> name_col;
Gtk::TreeModelColumn<bool> enabled_col;
- Gtk::TreeModelColumn<CountedPtr<PatchController> > patch_controller_col;
+ Gtk::TreeModelColumn<CountedPtr<PatchModel> > patch_model_col;
};
bool m_enable_signal;
diff --git a/src/progs/ingenuity/PatchView.cpp b/src/progs/ingenuity/PatchView.cpp
index 90c0083e..0ae82f45 100644
--- a/src/progs/ingenuity/PatchView.cpp
+++ b/src/progs/ingenuity/PatchView.cpp
@@ -21,7 +21,6 @@
#include "App.h"
#include "ModelEngineInterface.h"
#include "OmFlowCanvas.h"
-#include "PatchController.h"
#include "LoadPluginWindow.h"
#include "PatchModel.h"
#include "NewSubpatchWindow.h"
@@ -29,13 +28,13 @@
#include "NodeControlWindow.h"
#include "PatchPropertiesWindow.h"
#include "PatchTreeWindow.h"
+#include "GladeFactory.h"
namespace Ingenuity {
PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml)
: Gtk::Box(cobject),
- _patch(NULL),
_canvas(NULL),
_breadcrumb_container(NULL),
_enable_signal(true)
@@ -56,23 +55,27 @@ PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::X
void
-PatchView::patch_controller(PatchController* pc)
+PatchView::set_patch(CountedPtr<PatchModel> patch)
{
- _patch = pc;
- _canvas = new OmFlowCanvas(pc, 1600*2, 1200*2);
+ cerr << "Creating view for " << patch->path() << endl;
+
+ assert(_breadcrumb_container); // ensure created
+
+ _patch = patch;
+ _canvas = new OmFlowCanvas(patch, 1600*2, 1200*2);
_canvas_scrolledwindow->add(*_canvas);
- _poly_spin->set_value(pc->patch_model()->poly());
- _destroy_but->set_sensitive(pc->path() != "/");
- //_description_window->patch_model(pc->model());
-
+ _poly_spin->set_value(patch->poly());
+ _destroy_but->set_sensitive(patch->path() != "/");
+ patch->enabled() ? enable() : disable();
+
+ // Connect model signals to track state
+ patch->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable));
+ patch->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable));
- pc->patch_model()->enabled_sig.connect(sigc::mem_fun(this, &PatchView::enable));
- pc->patch_model()->disabled_sig.connect(sigc::mem_fun(this, &PatchView::disable));
-
+ // Connect widget signals to do things
_process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled));
-
_clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked));
_zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun(
@@ -83,11 +86,22 @@ PatchView::patch_controller(PatchController* pc)
}
-void
-PatchView::show_control_window()
+PatchView::~PatchView()
+{
+ cerr << "Destroying view for " << _patch->path() << endl;
+}
+
+
+CountedPtr<PatchView>
+PatchView::create(CountedPtr<PatchModel> patch)
+
{
- if (_patch != NULL)
- _patch->show_control_window();
+ const Glib::RefPtr<Gnome::Glade::Xml>& xml = GladeFactory::new_glade_reference("patch_view_box");
+ PatchView* result = NULL;
+ xml->get_widget_derived("patch_view_box", result);
+ assert(result);
+ result->set_patch(patch);
+ return CountedPtr<PatchView>(result);
}
@@ -98,11 +112,11 @@ PatchView::process_toggled()
return;
if (_process_but->get_active()) {
- App::instance().engine()->enable_patch(_patch->model()->path());
- App::instance().patch_tree()->patch_enabled(_patch->model()->path());
+ App::instance().engine()->enable_patch(_patch->path());
+ App::instance().patch_tree()->patch_enabled(_patch->path());
} else {
- App::instance().engine()->disable_patch(_patch->model()->path());
- App::instance().patch_tree()->patch_disabled(_patch->model()->path());
+ App::instance().engine()->disable_patch(_patch->path());
+ App::instance().patch_tree()->patch_disabled(_patch->path());
}
}
diff --git a/src/progs/ingenuity/PatchView.h b/src/progs/ingenuity/PatchView.h
index 59e16aad..a6484b97 100644
--- a/src/progs/ingenuity/PatchView.h
+++ b/src/progs/ingenuity/PatchView.h
@@ -21,12 +21,12 @@
#include <gtkmm.h>
#include <libglademm/xml.h>
#include <libglademm.h>
+#include "util/CountedPtr.h"
+#include "PatchModel.h"
using std::string;
namespace Ingen { namespace Client {
- class PatchModel;
- class NodeModel;
class PortModel;
class ControlModel;
class MetadataModel;
@@ -36,7 +36,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
-class PatchController;
class OmFlowCanvas;
class LoadPluginWindow;
class NewSubpatchWindow;
@@ -56,28 +55,29 @@ class PatchView : public Gtk::Box
{
public:
PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
-
- void patch_controller(PatchController* pc);
+ ~PatchView();
+
+ OmFlowCanvas* canvas() const { return _canvas; }
+ CountedPtr<PatchModel> patch() const { return _patch; }
+ Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; }
- OmFlowCanvas* canvas() const { return _canvas; }
- PatchController* patch_controller() const { return _patch; }
- Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; }
- void show_control_window();
+ static CountedPtr<PatchView> create(CountedPtr<PatchModel> patch);
+private:
+ void set_patch(CountedPtr<PatchModel> patch);
+ void process_toggled();
+ void clear_clicked();
+
void enable();
void disable();
void zoom_full();
-private:
- void process_toggled();
- void clear_clicked();
-
- PatchController* _patch;
- OmFlowCanvas* _canvas;
+ CountedPtr<PatchModel> _patch;
+ OmFlowCanvas* _canvas;
- Gtk::ScrolledWindow* _canvas_scrolledwindow;
+ Gtk::ScrolledWindow* _canvas_scrolledwindow;
Gtk::ToggleToolButton* _process_but;
Gtk::SpinButton* _poly_spin;
diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp
index c395c265..1aec1977 100644
--- a/src/progs/ingenuity/PatchWindow.cpp
+++ b/src/progs/ingenuity/PatchWindow.cpp
@@ -21,7 +21,6 @@
#include "App.h"
#include "ModelEngineInterface.h"
#include "OmFlowCanvas.h"
-#include "PatchController.h"
#include "LoadPluginWindow.h"
#include "PatchModel.h"
#include "NewSubpatchWindow.h"
@@ -36,7 +35,6 @@
#include "Store.h"
#include "ConnectWindow.h"
#include "Loader.h"
-#include "ControllerFactory.h"
#include "WindowFactory.h"
#include "PatchView.h"
@@ -45,8 +43,6 @@ namespace Ingenuity {
PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml)
: Gtk::Window(cobject),
- m_load_plugin_window(NULL),
- m_new_subpatch_window(NULL),
m_enable_signal(true),
m_position_stored(false),
m_x(0),
@@ -75,17 +71,7 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad
xml->get_widget("patch_view_messages_window_menuitem", m_menu_view_messages_window);
xml->get_widget("patch_view_patch_tree_window_menuitem", m_menu_view_patch_tree_window);
xml->get_widget("patch_help_about_menuitem", m_menu_help_about);
-
- // FIXME: these shouldn't be loaded here
- xml->get_widget_derived("load_plugin_win", m_load_plugin_window);
- xml->get_widget_derived("new_subpatch_win", m_new_subpatch_window);
- xml->get_widget_derived("load_patch_win", m_load_patch_window);
- xml->get_widget_derived("load_subpatch_win", m_load_subpatch_window);
-
- m_new_subpatch_window->set_transient_for(*this);
- m_load_patch_window->set_transient_for(*this);
- m_load_subpatch_window->set_transient_for(*this);
-
+
m_menu_view_control_window->property_sensitive() = false;
//m_status_bar->push(App::instance().engine()->engine_url());
//m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false);
@@ -134,14 +120,10 @@ PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glad
PatchWindow::~PatchWindow()
{
// Prevents deletion
- m_patch->claim_patch_view();
+ //m_patch->claim_patch_view();
App::instance().remove_patch_window(this);
- hide();
-
- delete m_new_subpatch_window;
- delete m_load_subpatch_window;
delete m_breadcrumb_box;
}
@@ -149,84 +131,63 @@ PatchWindow::~PatchWindow()
/** Set the patch controller from a Path (for use by eg. BreadCrumbBox)
*/
void
-PatchWindow::set_patch_from_path(const Path& path)
+PatchWindow::set_patch_from_path(const Path& path, CountedPtr<PatchView> view)
{
- CountedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path));
- if (!model)
- return; // can't really do anything useful..
-
- CountedPtr<PatchController> pc = PtrCast<PatchController>(ControllerFactory::get_controller(model));
- assert(pc);
-
- App::instance().window_factory()->present(pc, this);
+ if (view) {
+ assert(view->patch()->path() == path);
+ App::instance().window_factory()->present_patch(view->patch(), this, view);
+ } else {
+ CountedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path));
+ if (model)
+ App::instance().window_factory()->present_patch(model, this);
+ }
}
/** Sets the patch controller for this window and initializes everything.
*
- * This function MUST be called before using the window in any way!
+ * If @a view is NULL, a new view will be created.
*/
void
-PatchWindow::set_patch(CountedPtr<PatchController> pc)
+PatchWindow::set_patch(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view)
{
- if (!pc || pc == m_patch)
+ if (!patch || patch == m_patch)
return;
m_enable_signal = false;
- if (m_patch) {
- CountedPtr<PatchController> old_pc = m_patch;
- assert(old_pc->window() == NULL || old_pc->window() == this);
- old_pc->claim_patch_view();
- old_pc->window(NULL);
- }
-
- m_patch = pc;
+ m_patch = patch;
- CountedPtr<PatchView> patch_view = pc->get_view();
- assert(patch_view);
- patch_view->reparent(*m_viewport);
+ m_view = view ? view : PatchView::create(patch);
+ assert(m_view);
+
+ m_viewport->remove();
+ m_viewport->add(*m_view.get());
- if (m_breadcrumb_box->get_parent())
- m_breadcrumb_box->reparent(*patch_view->breadcrumb_container());
- else
- patch_view->breadcrumb_container()->add(*m_breadcrumb_box);
+ m_view->breadcrumb_container()->remove();
+ m_view->breadcrumb_container()->add(*m_breadcrumb_box);
- m_breadcrumb_box->build(pc->model()->path());
+ m_breadcrumb_box->build(patch->path(), m_view);
m_breadcrumb_box->show();
- pc->window(this);
- show_all();
-
- assert(m_load_plugin_window != NULL);
- assert(m_new_subpatch_window != NULL);
- assert(m_load_patch_window != NULL);
- assert(m_load_subpatch_window != NULL);
-
- m_load_patch_window->set_patch(m_patch);
- m_load_plugin_window->set_patch(m_patch);
- m_new_subpatch_window->set_patch(m_patch);
- m_load_subpatch_window->set_patch(m_patch);
-
- m_menu_view_control_window->property_sensitive() = pc->has_control_inputs();
+ show_all();
+
+ //m_menu_view_control_window->property_sensitive() = patch->has_control_inputs();
int width, height;
get_size(width, height);
- patch_view->canvas()->scroll_to(
- ((int)patch_view->canvas()->width() - width)/2,
- ((int)patch_view->canvas()->height() - height)/2);
+ m_view->canvas()->scroll_to(
+ ((int)m_view->canvas()->width() - width)/2,
+ ((int)m_view->canvas()->height() - height)/2);
- set_title(m_patch->model()->path());
+ set_title(m_patch->path());
//m_properties_window->patch_model(pc->patch_model());
- if (pc->model()->path() == "/")
+ if (patch->path() == "/")
m_menu_destroy_patch->set_sensitive(false);
else
m_menu_destroy_patch->set_sensitive(true);
- assert(m_patch == pc);
- assert(m_patch->window() == this);
-
m_enable_signal = true;
}
@@ -242,45 +203,31 @@ PatchWindow::event_show_engine()
void
PatchWindow::event_show_controls()
{
- if (m_patch)
- m_patch->show_control_window();
+ App::instance().window_factory()->present_controls(m_patch);
}
void
PatchWindow::event_show_properties()
{
- if (m_patch)
- m_patch->show_properties_window();
+ App::instance().window_factory()->present_properties(m_patch);
}
-/*
-void
-PatchWindow::event_open()
-{
- m_load_patch_window->set_replace();
- m_load_patch_window->present();
-}
-*/
-
void
PatchWindow::event_import()
{
- m_load_patch_window->set_merge();
- m_load_patch_window->present();
+ App::instance().window_factory()->present_load_patch(m_patch);
}
void
PatchWindow::event_save()
{
- CountedPtr<PatchModel> model(m_patch->patch_model().get());
-
- if (model->filename() == "")
+ if (m_patch->filename() == "")
event_save_as();
else
- App::instance().loader()->save_patch(model, model->filename(), false);
+ App::instance().loader()->save_patch(m_patch, m_patch->filename(), false);
}
@@ -301,7 +248,7 @@ PatchWindow::event_save_as()
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
// Set current folder to most sensible default
- const string& current_filename = m_patch->patch_model()->filename();
+ const string& current_filename = m_patch->filename();
if (current_filename.length() > 0)
dialog.set_filename(current_filename);
else if (App::instance().configuration()->patch_folder().length() > 0)
@@ -335,8 +282,8 @@ PatchWindow::event_save_as()
fin.close();
if (confirm) {
- App::instance().loader()->save_patch(m_patch->patch_model(), filename, recursive);
- m_patch->patch_model()->filename(filename);
+ App::instance().loader()->save_patch(m_patch, filename, recursive);
+ m_patch->filename(filename);
}
}
App::instance().configuration()->set_patch_folder(dialog.get_current_folder());
@@ -367,10 +314,12 @@ bool
PatchWindow::on_key_press_event(GdkEventKey* event)
{
if (event->keyval == GDK_Delete) {
+ cerr << "FIXME: delete key\n";
+ /*
if (m_patch && m_patch->get_view()) {
assert(m_patch->get_view()->canvas());
m_patch->get_view()->canvas()->destroy_selected();
- }
+ }*/
return true;
} else {
return Gtk::Window::on_key_press_event(event);
@@ -409,14 +358,14 @@ PatchWindow::event_quit()
void
PatchWindow::event_destroy()
{
- App::instance().engine()->destroy(m_patch->model()->path());
+ App::instance().engine()->destroy(m_patch->path());
}
void
PatchWindow::event_clear()
{
- App::instance().engine()->clear_patch(m_patch->model()->path());
+ App::instance().engine()->clear_patch(m_patch->path());
}
void
diff --git a/src/progs/ingenuity/PatchWindow.h b/src/progs/ingenuity/PatchWindow.h
index d538db78..2e0a388b 100644
--- a/src/progs/ingenuity/PatchWindow.h
+++ b/src/progs/ingenuity/PatchWindow.h
@@ -24,13 +24,15 @@
#include <libglademm.h>
#include "util/Path.h"
#include "util/CountedPtr.h"
-#include "PatchController.h"
+#include "PatchModel.h"
+#include "PatchView.h"
+using Ingen::Client::PatchModel;
+
using std::string; using std::list;
namespace Ingen { namespace Client {
class PatchModel;
- class NodeModel;
class PortModel;
class ControlModel;
class MetadataModel;
@@ -40,7 +42,6 @@ using namespace Ingen::Client;
namespace Ingenuity {
-class PatchController;
class OmFlowCanvas;
class LoadPluginWindow;
class LoadPatchWindow;
@@ -64,13 +65,10 @@ public:
PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
~PatchWindow();
- void set_patch_from_path(const Path& path);
- void set_patch(CountedPtr<PatchController> pc);
+ void set_patch_from_path(const Path& path, CountedPtr<PatchView> view);
+ void set_patch(CountedPtr<PatchModel> pc, CountedPtr<PatchView> view);
- CountedPtr<PatchController> patch_controller() const { return m_patch; }
- LoadPluginWindow* load_plugin_window() const { return m_load_plugin_window; }
- LoadSubpatchWindow* load_subpatch_window() const { return m_load_subpatch_window; }
- NewSubpatchWindow* new_subpatch_window() const { return m_new_subpatch_window; }
+ CountedPtr<PatchModel> patch() const { return m_patch; }
Gtk::MenuItem* menu_view_control_window() { return m_menu_view_control_window; }
@@ -93,12 +91,8 @@ private:
void event_show_controls();
void event_show_engine();
- CountedPtr<PatchController> m_patch;
-
- LoadPluginWindow* m_load_plugin_window;
- LoadPatchWindow* m_load_patch_window;
- NewSubpatchWindow* m_new_subpatch_window;
- LoadSubpatchWindow* m_load_subpatch_window;
+ CountedPtr<PatchModel> m_patch;
+ CountedPtr<PatchView> m_view;
bool m_enable_signal;
bool m_position_stored;
diff --git a/src/progs/ingenuity/PortController.cpp b/src/progs/ingenuity/PortController.cpp
deleted file mode 100644
index 167cb594..00000000
--- a/src/progs/ingenuity/PortController.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "PortController.h"
-#include "OmFlowCanvas.h"
-#include "OmModule.h"
-#include "PortModel.h"
-#include "PatchModel.h"
-#include "OmPort.h"
-#include "OmPatchPort.h"
-#include "Store.h"
-
-namespace Ingenuity {
-
-
-PortController::PortController(CountedPtr<PortModel> model)
-: GtkObjectController(model),
- m_patch_port(NULL),
- m_module(NULL),
- m_port(NULL)
-{
- assert(model);
- assert(model->parent());
-}
-
-
-void
-PortController::destroy()
-{
- assert(m_model->parent());
- CountedPtr<NodeController> parent = PtrCast<NodeController>(m_model->parent()->controller());
- assert(parent);
-
- parent->remove_port(path(), false);
-}
-
-
-void
-PortController::create_module(OmFlowCanvas* canvas)
-{
- //cerr << "Creating port module " << m_model->path() << endl;
-
- const string x_str = m_model->get_metadata("module-x");
- const string y_str = m_model->get_metadata("module-y");
-
- double default_x;
- double default_y;
- canvas->get_new_module_location(default_x, default_y);
- const double x = (x_str == "") ? default_x : atof(x_str.c_str());
- const double y = (y_str == "") ? default_y : atof(y_str.c_str());
-
- assert(canvas);
- assert(port_model());
-
- if (m_module)
- delete m_module;
-
- m_module = new OmPortModule(canvas, this, x, y);
-
- if (PtrCast<PatchModel>(port_model()->parent())) {
- if (m_patch_port)
- delete m_patch_port;
-
- m_patch_port = new OmPatchPort(m_module, port_model());
- }
-
- m_module->resize();
-
- m_module->move_to(x, y); // FIXME: redundant (?)
-}
-
-
-void
-PortController::destroy_module()
-{
- delete m_module;
- m_module = NULL;
-}
-
-
-void
-PortController::metadata_update(const string& key, const string& value)
-{
- //cerr << "Metadata " << path() << ": " << key << " = " << value << endl;
-
- if (m_module != NULL) {
- if (key == "module-x") {
- float x = atof(value.c_str());
- //if (x > 0 && x < m_canvas->width())
- m_module->move_to(x, m_module->property_y().get_value());
- } else if (key == "module-y") {
- float y = atof(value.c_str());
- //if (y > 0 && y < m_canvas->height())
- m_module->move_to(m_module->property_x().get_value(), y);
- }
- }
-
- GtkObjectController::metadata_update(key, value);
-}
-
-void
-PortController::set_path(const Path& new_path)
-{
- // Change port name on module, if view exists
- if (m_port != NULL)
- m_port->set_name(new_path.name());
-
- m_model->set_path(new_path);
-}
-
-
-/** Create the visible port on a canvas module.
- *
- * Does not resize the module, caller's responsibility to do so if necessary.
- */
-void
-PortController::create_port(OmModule* module)
-{
- assert(module != NULL);
-
- new OmPort(module, port_model());
-}
-
-
-} // namespace Ingenuity
-
diff --git a/src/progs/ingenuity/PortController.h b/src/progs/ingenuity/PortController.h
deleted file mode 100644
index e28cd21d..00000000
--- a/src/progs/ingenuity/PortController.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef PORTCONTROLLER_H
-#define PORTCONTROLLER_H
-
-#include <string>
-#include <gtkmm.h>
-#include "GtkObjectController.h"
-#include "OmPortModule.h"
-
-using std::string;
-using namespace Ingen::Client;
-
-namespace Ingen { namespace Client {
- class MetadataModel;
- class PortModel;
-} }
-
-namespace Ingenuity {
-
-class Controller;
-class OmPort;
-class OmPatchPort;
-class OmModule;
-class OmPortModule;
-class OmFlowCanvas;
-
-
-/** Controller for a port on a (non-patch) node.
- *
- * \ingroup Ingenuity
- */
-class PortController : public GtkObjectController
-{
-public:
- virtual ~PortController() {}
-
- virtual void destroy();
-
- virtual void create_module(OmFlowCanvas* canvas);
- virtual void destroy_module();
- OmPortModule* module() { return m_module; }
-
- virtual void metadata_update(const string& key, const string& value);
-
- void create_port(OmModule* module);
- void destroy_port();
-
- void set_path(const Path& new_path);
-
- CountedPtr<PortModel> port_model() const { return PtrCast<PortModel>(m_model); }
-
-private:
- friend class ControllerFactory;
- PortController(CountedPtr<PortModel> model);
-
- OmPatchPort* m_patch_port; ///< Port on m_module
- OmPortModule* m_module; ///< Port pseudo-module (for patch ports only)
- OmPort* m_port; ///< Port on some other canvas module
-};
-
-
-} // namespace Ingenuity
-
-#endif // PORTCONTROLLER_H
diff --git a/src/progs/ingenuity/RenameWindow.cpp b/src/progs/ingenuity/RenameWindow.cpp
index 7a458e31..37d4fc39 100644
--- a/src/progs/ingenuity/RenameWindow.cpp
+++ b/src/progs/ingenuity/RenameWindow.cpp
@@ -18,7 +18,6 @@
#include <cassert>
#include <string>
#include "ObjectModel.h"
-#include "GtkObjectController.h"
#include "Store.h"
#include "App.h"
#include "ModelEngineInterface.h"
@@ -47,7 +46,7 @@ RenameWindow::RenameWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Gl
* This function MUST be called before using this object in any way.
*/
void
-RenameWindow::set_object(GtkObjectController* object)
+RenameWindow::set_object(CountedPtr<ObjectModel> object)
{
m_object = object;
m_name_entry->set_text(object->path().name());
@@ -62,15 +61,15 @@ RenameWindow::name_changed()
{
assert(m_name_entry);
assert(m_message_label);
- assert(m_object->model());
- assert(m_object->model()->parent());
+ assert(m_object);
+ assert(m_object->parent());
string name = m_name_entry->get_text();
if (name.find("/") != string::npos) {
m_message_label->set_text("Name may not contain '/'");
m_ok_button->property_sensitive() = false;
//} else if (m_object->parent()->patch_model()->get_node(name) != NULL) {
- } else if (App::instance().store()->object(m_object->model()->parent()->path().base() + name)) {
+ } else if (App::instance().store()->object(m_object->parent()->path().base() + name)) {
m_message_label->set_text("An object already exists with that name.");
m_ok_button->property_sensitive() = false;
} else if (name.length() == 0) {
@@ -105,7 +104,7 @@ RenameWindow::ok_clicked()
assert(name.length() > 0);
assert(name.find("/") == string::npos);
- App::instance().engine()->rename(m_object->model()->path(), name);
+ App::instance().engine()->rename(m_object->path(), name);
hide();
}
diff --git a/src/progs/ingenuity/RenameWindow.h b/src/progs/ingenuity/RenameWindow.h
index af826f15..fe342100 100644
--- a/src/progs/ingenuity/RenameWindow.h
+++ b/src/progs/ingenuity/RenameWindow.h
@@ -19,16 +19,14 @@
#include <gtkmm.h>
#include <libglademm.h>
-
+#include "util/CountedPtr.h"
+#include "ObjectModel.h"
+using Ingen::Client::ObjectModel;
namespace Ingenuity {
-class GtkObjectController;
-
-/** 'New Patch' Window.
- *
- * Loaded by libglade as a derived object.
+/** Rename window. Handles renaming of any (Ingen) object.
*
* \ingroup Ingenuity
*/
@@ -37,14 +35,16 @@ class RenameWindow : public Gtk::Window
public:
RenameWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
- void set_object(GtkObjectController* object);
+ void present(CountedPtr<ObjectModel> object) { set_object(object); Gtk::Window::present(); }
private:
+ void set_object(CountedPtr<ObjectModel> object);
+
void name_changed();
void cancel_clicked();
void ok_clicked();
- GtkObjectController* m_object;
+ CountedPtr<ObjectModel> m_object;
Gtk::Entry* m_name_entry;
Gtk::Label* m_message_label;
diff --git a/src/progs/ingenuity/SubpatchModule.cpp b/src/progs/ingenuity/SubpatchModule.cpp
index 598cc9db..47465b09 100644
--- a/src/progs/ingenuity/SubpatchModule.cpp
+++ b/src/progs/ingenuity/SubpatchModule.cpp
@@ -24,7 +24,6 @@
#include "PatchModel.h"
#include "PatchWindow.h"
#include "OmFlowCanvas.h"
-#include "PatchController.h"
#include "OmPort.h"
#include "WindowFactory.h"
using std::cerr; using std::cout; using std::endl;
@@ -32,8 +31,8 @@ using std::cerr; using std::cout; using std::endl;
namespace Ingenuity {
-SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> patch)
-: OmModule(canvas, patch.get()),
+SubpatchModule::SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchModel> patch)
+: OmModule(canvas, patch),
m_patch(patch)
{
assert(canvas);
@@ -46,12 +45,13 @@ SubpatchModule::on_double_click(GdkEventButton* event)
{
assert(m_patch);
- CountedPtr<PatchController> parent = PtrCast<PatchController>(m_patch->model()->parent()->controller());
+ CountedPtr<PatchModel> parent = PtrCast<PatchModel>(m_patch->parent());
- PatchWindow* const preferred
- = (event->state & GDK_SHIFT_MASK) ? NULL : parent->window();
+ PatchWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK))
+ ? NULL
+ : App::instance().window_factory()->patch_window(parent) );
- App::instance().window_factory()->present(m_patch, preferred);
+ App::instance().window_factory()->present_patch(m_patch, preferred);
}
@@ -62,10 +62,15 @@ SubpatchModule::on_double_click(GdkEventButton* event)
void
SubpatchModule::browse_to_patch()
{
- assert(m_patch->model()->parent());
- CountedPtr<PatchController> pc = PtrCast<PatchController>(m_patch->model()->parent()->controller());
+ assert(m_patch->parent());
- App::instance().window_factory()->present(m_patch, pc->window());
+ CountedPtr<PatchModel> parent = PtrCast<PatchModel>(m_patch->parent());
+
+ PatchWindow* const preferred = ( (parent)
+ ? App::instance().window_factory()->patch_window(parent)
+ : NULL );
+
+ App::instance().window_factory()->present_patch(m_patch, preferred);
}
@@ -73,14 +78,15 @@ SubpatchModule::browse_to_patch()
void
SubpatchModule::show_dialog()
{
- m_patch->show_control_window();
+ cerr << "FIXME: dialog\n";
+ //m_patch->show_control_window();
}
void
SubpatchModule::menu_remove()
{
- App::instance().engine()->destroy(m_patch->model()->path());
+ App::instance().engine()->destroy(m_patch->path());
}
} // namespace Ingenuity
diff --git a/src/progs/ingenuity/SubpatchModule.h b/src/progs/ingenuity/SubpatchModule.h
index a8e6e971..0f52ae2b 100644
--- a/src/progs/ingenuity/SubpatchModule.h
+++ b/src/progs/ingenuity/SubpatchModule.h
@@ -22,7 +22,7 @@
#include <libgnomecanvasmm.h>
#include "OmModule.h"
#include "util/CountedPtr.h"
-#include "PatchController.h"
+#include "PatchModel.h"
using std::string; using std::list;
namespace Ingen { namespace Client {
@@ -46,7 +46,7 @@ class NodeControlWindow;
class SubpatchModule : public OmModule
{
public:
- SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchController> controller);
+ SubpatchModule(OmFlowCanvas* canvas, CountedPtr<PatchModel> controller);
virtual ~SubpatchModule() {}
void on_double_click(GdkEventButton* ev);
@@ -55,10 +55,10 @@ public:
void browse_to_patch();
void menu_remove();
- CountedPtr<PatchController> patch() { return m_patch; }
+ CountedPtr<PatchModel> patch() { return m_patch; }
protected:
- CountedPtr<PatchController> m_patch;
+ CountedPtr<PatchModel> m_patch;
};
diff --git a/src/progs/ingenuity/WindowFactory.cpp b/src/progs/ingenuity/WindowFactory.cpp
index c7d79aca..3edbf568 100644
--- a/src/progs/ingenuity/WindowFactory.cpp
+++ b/src/progs/ingenuity/WindowFactory.cpp
@@ -15,13 +15,70 @@
*/
#include "WindowFactory.h"
+#include "App.h"
#include "PatchWindow.h"
#include "GladeFactory.h"
-#include "App.h"
+#include "NodePropertiesWindow.h"
+#include "PatchPropertiesWindow.h"
+#include "NodeControlWindow.h"
+#include "LoadPluginWindow.h"
+#include "LoadPatchWindow.h"
+#include "LoadSubpatchWindow.h"
+#include "RenameWindow.h"
+#include "NewSubpatchWindow.h"
namespace Ingenuity {
+WindowFactory::WindowFactory()
+: _load_plugin_win(NULL)
+, _load_patch_win(NULL)
+, _new_subpatch_win(NULL)
+, _load_subpatch_win(NULL)
+, _node_properties_win(NULL)
+, _patch_properties_win(NULL)
+{
+ Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
+
+ xml->get_widget_derived("load_plugin_win", _load_plugin_win);
+ xml->get_widget_derived("load_patch_win", _load_patch_win);
+ xml->get_widget_derived("new_subpatch_win", _new_subpatch_win);
+ xml->get_widget_derived("load_subpatch_win", _load_subpatch_win);
+ xml->get_widget_derived("node_properties_win", _node_properties_win);
+ xml->get_widget_derived("patch_properties_win", _patch_properties_win);
+
+}
+
+
+WindowFactory::~WindowFactory()
+{
+ for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i)
+ delete i->second;
+
+ for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i)
+ delete i->second;
+
+}
+
+
+PatchWindow*
+WindowFactory::patch_window(CountedPtr<PatchModel> patch)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+
+ return (w == _patch_windows.end()) ? NULL : w->second;
+}
+
+
+NodeControlWindow*
+WindowFactory::control_window(CountedPtr<NodeModel> node)
+{
+ ControlWindowMap::iterator w = _control_windows.find(node->path());
+
+ return (w == _control_windows.end()) ? NULL : w->second;
+}
+
+
/** Present a PatchWindow for a Patch.
*
* If @a preferred is not NULL, it will be set to display @a patch if the patch
@@ -29,54 +86,55 @@ namespace Ingenuity {
* @a preferred left unmodified.
*/
void
-WindowFactory::present(CountedPtr<PatchController> patch, PatchWindow* preferred)
+WindowFactory::present_patch(CountedPtr<PatchModel> patch, PatchWindow* preferred, CountedPtr<PatchView> view)
{
- std::map<Path, PatchWindow*>::iterator w = _windows.find(patch->model()->path());
+ assert( !view || view->patch() == patch);
+
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
- if (w != _windows.end()) {
+ if (w != _patch_windows.end()) {
(*w).second->present();
} else if (preferred) {
- w = _windows.find(preferred->patch_controller()->model()->path());
+ w = _patch_windows.find(preferred->patch()->path());
assert((*w).second == preferred);
- preferred->set_patch(patch);
- _windows.erase(w);
- _windows[patch->model()->path()] = preferred;
+ preferred->set_patch(patch, view);
+ _patch_windows.erase(w);
+ _patch_windows[patch->path()] = preferred;
preferred->present();
} else {
- PatchWindow* win = create_new(patch);
+ PatchWindow* win = new_patch_window(patch, view);
win->present();
}
}
PatchWindow*
-WindowFactory::create_new(CountedPtr<PatchController> patch)
+WindowFactory::new_patch_window(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view)
{
- // FIXME: can't just load "patch_win" and children because PatchWindow
- // loads things it really shouldn't.
- //Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("patch_win");
- Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference();
+ assert( !view || view->patch() == patch);
+
+ Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("patch_win");
PatchWindow* win = NULL;
xml->get_widget_derived("patch_win", win);
assert(win);
- win->set_patch(patch);
- _windows[patch->model()->path()] = win;
+ win->set_patch(patch, view);
+ _patch_windows[patch->path()] = win;
win->signal_delete_event().connect(sigc::bind<0>(
- sigc::mem_fun(this, &WindowFactory::remove), win));
+ sigc::mem_fun(this, &WindowFactory::remove_patch_window), win));
return win;
}
bool
-WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored)
+WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored)
{
- if (_windows.size() <= 1) {
+ if (_patch_windows.size() <= 1) {
Gtk::MessageDialog d(*win, "This is the last remaining open patch "
"window. Closing this window will exit Ingenuity (the engine will "
"remain running).\n\nAre you sure you want to quit?",
@@ -90,15 +148,145 @@ WindowFactory::remove(PatchWindow* win, GdkEventAny* ignored)
return false;
}
- std::map<Path, PatchWindow*>::iterator w
- = _windows.find(win->patch_controller()->model()->path());
+ PatchWindowMap::iterator w = _patch_windows.find(win->patch()->path());
+
+ assert((*w).second == win);
+ _patch_windows.erase(w);
+
+ delete win;
+
+ return true;
+}
+
+
+void
+WindowFactory::present_controls(CountedPtr<NodeModel> node)
+{
+ NodeControlWindow* win = control_window(node);
+
+ if (win) {
+ win->present();
+ } else {
+ win = new_control_window(node);
+ win->present();
+ }
+}
+
+
+NodeControlWindow*
+WindowFactory::new_control_window(CountedPtr<NodeModel> node)
+{
+ size_t poly = 1;
+ if (node->polyphonic())
+ poly = ((PatchModel*)node->parent().get())->poly();
+
+ NodeControlWindow* win = new NodeControlWindow(node, poly);
+
+ _control_windows[node->path()] = win;
+
+ win->signal_delete_event().connect(sigc::bind<0>(
+ sigc::mem_fun(this, &WindowFactory::remove_control_window), win));
+
+ return win;
+}
+
+
+bool
+WindowFactory::remove_control_window(NodeControlWindow* win, GdkEventAny* ignored)
+{
+ ControlWindowMap::iterator w = _control_windows.find(win->node()->path());
assert((*w).second == win);
- _windows.erase(w);
+ _control_windows.erase(w);
delete win;
return true;
}
+void
+WindowFactory::present_load_plugin(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+
+ if (w != _patch_windows.end())
+ _load_plugin_win->set_transient_for(*w->second);
+
+ _load_plugin_win->present(patch, data);
+}
+
+
+void
+WindowFactory::present_load_patch(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+
+ if (w != _patch_windows.end())
+ _load_patch_win->set_transient_for(*w->second);
+
+ _load_patch_win->set_merge(); // Import is the only choice
+
+ _load_patch_win->present(patch, data);
+}
+
+
+void
+WindowFactory::present_new_subpatch(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+
+ if (w != _patch_windows.end())
+ _new_subpatch_win->set_transient_for(*w->second);
+
+ _new_subpatch_win->present(patch, data);
+}
+
+
+void
+WindowFactory::present_load_subpatch(CountedPtr<PatchModel> patch, MetadataMap data)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+
+ if (w != _patch_windows.end())
+ _load_subpatch_win->set_transient_for(*w->second);
+
+ _load_subpatch_win->present(patch, data);
+}
+
+
+void
+WindowFactory::present_rename(CountedPtr<ObjectModel> object)
+{
+ PatchWindowMap::iterator w = _patch_windows.find(object->path());
+
+ if (w != _patch_windows.end())
+ _rename_win->set_transient_for(*w->second);
+
+ _rename_win->present(object);
+}
+
+
+void
+WindowFactory::present_properties(CountedPtr<NodeModel> node)
+{
+ CountedPtr<PatchModel> patch = PtrCast<PatchModel>(node);
+ if (patch) {
+
+ PatchWindowMap::iterator w = _patch_windows.find(patch->path());
+ if (w != _patch_windows.end())
+ _patch_properties_win->set_transient_for(*w->second);
+
+ _patch_properties_win->present(patch);
+
+ } else {
+
+ PatchWindowMap::iterator w = _patch_windows.find(node->parent()->path());
+ if (w != _patch_windows.end())
+ _node_properties_win->set_transient_for(*w->second);
+
+ _node_properties_win->present(node);
+ }
+}
+
+
} // namespace Ingenuity
diff --git a/src/progs/ingenuity/WindowFactory.h b/src/progs/ingenuity/WindowFactory.h
index add2d97b..831ab646 100644
--- a/src/progs/ingenuity/WindowFactory.h
+++ b/src/progs/ingenuity/WindowFactory.h
@@ -18,23 +18,69 @@
#define WINDOW_FACTORY_H
#include <map>
+#include <gtkmm.h>
#include "util/CountedPtr.h"
-#include "PatchController.h"
+#include "PatchView.h"
+#include "PatchModel.h"
+using Ingen::Client::PatchModel;
namespace Ingenuity {
class PatchWindow;
+class NodeControlWindow;
+class NodePropertiesWindow;
+class PatchPropertiesWindow;
+class LoadPatchWindow;
+class RenameWindow;
+/** Manager/Factory for all windows.
+ *
+ * This serves as a nice centralized spot for all window management issues,
+ * as well as an enumeration of all the windows in Ingenuity (the goal being
+ * to reduce that number as much as possible).
+ */
class WindowFactory {
public:
- void present(CountedPtr<PatchController> patch, PatchWindow* preferred = NULL);
+ WindowFactory();
+ ~WindowFactory();
+
+ PatchWindow* patch_window(CountedPtr<PatchModel> patch);
+ NodeControlWindow* control_window(CountedPtr<NodeModel> node);
+
+ void present_patch(CountedPtr<PatchModel> patch,
+ PatchWindow* preferred = NULL,
+ CountedPtr<PatchView> patch = CountedPtr<PatchView>());
+
+ void present_controls(CountedPtr<NodeModel> node);
+
+ void present_load_plugin(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap());
+ void present_load_patch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap());
+ void present_new_subpatch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap());
+ void present_load_subpatch(CountedPtr<PatchModel> patch, MetadataMap data = MetadataMap());
+ void present_rename(CountedPtr<ObjectModel> object);
+ void present_properties(CountedPtr<NodeModel> node);
private:
- PatchWindow* create_new(CountedPtr<PatchController> patch);
- bool remove(PatchWindow* win, GdkEventAny* ignored);
+ typedef std::map<Path, PatchWindow*> PatchWindowMap;
+ typedef std::map<Path, NodeControlWindow*> ControlWindowMap;
+
+ PatchWindow* new_patch_window(CountedPtr<PatchModel> patch, CountedPtr<PatchView> view);
+ bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored);
+
+ NodeControlWindow* new_control_window(CountedPtr<NodeModel> node);
+ bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored);
+
+ PatchWindowMap _patch_windows;
+ ControlWindowMap _control_windows;
- std::map<Path, PatchWindow*> _windows;
+ LoadPluginWindow* _load_plugin_win;
+ LoadPatchWindow* _load_patch_win;
+ NewSubpatchWindow* _new_subpatch_win;
+ LoadSubpatchWindow* _load_subpatch_win;
+ NodePropertiesWindow* _node_properties_win;
+ PatchPropertiesWindow* _patch_properties_win;
+ RenameWindow* _rename_win;
};
}
diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade
index 2221a805..7f18f954 100644
--- a/src/progs/ingenuity/ingenuity.glade
+++ b/src/progs/ingenuity/ingenuity.glade
@@ -1758,7 +1758,7 @@
</child>
<child>
- <widget class="GtkVBox" id="patch_view_vbox">
+ <widget class="GtkVBox" id="patch_view_box">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>