summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-06-12 21:46:22 +0000
committerDavid Robillard <d@drobilla.net>2012-06-12 21:46:22 +0000
commit071e36b69b5bcc203f70179580c8bed924b7305b (patch)
tree6af0c15841b20ae8ca5d020a7423d80a7c432fc3
parent9923f2bc2a0731c111dbf614223ed81dee3e91f5 (diff)
downloadingen-071e36b69b5bcc203f70179580c8bed924b7305b.tar.gz
ingen-071e36b69b5bcc203f70179580c8bed924b7305b.tar.bz2
ingen-071e36b69b5bcc203f70179580c8bed924b7305b.zip
Add "expose" (to parent) operation for ports.
Partially implments #39. Export all the way to root has a few issues, I am considering this functionality good enough for now. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4496 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ingen/client/NodeModel.hpp1
-rw-r--r--src/client/NodeModel.cpp13
-rw-r--r--src/gui/NodeModule.cpp9
-rw-r--r--src/gui/PortMenu.cpp76
-rw-r--r--src/gui/PortMenu.hpp8
-rw-r--r--src/gui/ingen_gui.ui8
-rw-r--r--src/serialisation/Serialiser.cpp25
7 files changed, 98 insertions, 42 deletions
diff --git a/ingen/client/NodeModel.hpp b/ingen/client/NodeModel.hpp
index f56e4a54..cc41070c 100644
--- a/ingen/client/NodeModel.hpp
+++ b/ingen/client/NodeModel.hpp
@@ -70,6 +70,7 @@ public:
void port_value_range(SharedPtr<const PortModel> port,
float& min, float& max, uint32_t srate=1) const;
+ std::string label() const;
std::string port_label(SharedPtr<const PortModel> port) const;
// Signals
diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp
index ad3ce273..a92d5aae 100644
--- a/src/client/NodeModel.cpp
+++ b/src/client/NodeModel.cpp
@@ -219,6 +219,19 @@ NodeModel::port_value_range(SharedPtr<const PortModel> port,
}
std::string
+NodeModel::label() const
+{
+ const Raul::Atom& name_property = get_property(_uris.lv2_name);
+ if (name_property.type() == _uris.forge.String) {
+ return name_property.get_string();
+ } else if (plugin_model()) {
+ return plugin_model()->human_name();
+ } else {
+ return symbol().c_str();
+ }
+}
+
+std::string
NodeModel::port_label(SharedPtr<const PortModel> port) const
{
const Raul::Atom& name = port->get_property(LV2_CORE__name);
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index e6bbee67..5ee75584 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -139,14 +139,9 @@ NodeModule::show_human_names(bool b)
{
const URIs& uris = app().uris();
- if (b && node()->plugin()) {
- const Raul::Atom& name_property = node()->get_property(uris.lv2_name);
- if (name_property.type() == uris.forge.String)
- set_label(name_property.get_string());
- else
- set_label(node()->plugin_model()->human_name().c_str());
+ if (b) {
+ set_label(node()->label().c_str());
} else {
- b = false;
set_label(node()->symbol().c_str());
}
diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp
index 0e3e215c..2785db77 100644
--- a/src/gui/PortMenu.cpp
+++ b/src/gui/PortMenu.cpp
@@ -35,21 +35,22 @@ namespace GUI {
PortMenu::PortMenu(BaseObjectType* cobject,
const Glib::RefPtr<Gtk::Builder>& xml)
: ObjectMenu(cobject, xml)
- , _patch_port(NULL)
+ , _is_patch_port(false)
{
xml->get_widget("object_menu", _port_menu);
xml->get_widget("port_set_min_menuitem", _set_min_menuitem);
xml->get_widget("port_set_max_menuitem", _set_max_menuitem);
xml->get_widget("port_reset_range_menuitem", _reset_range_menuitem);
+ xml->get_widget("port_expose_menuitem", _expose_menuitem);
}
void
-PortMenu::init(App& app, SharedPtr<const PortModel> port, bool patch_port)
+PortMenu::init(App& app, SharedPtr<const PortModel> port, bool is_patch_port)
{
const URIs& uris = app.uris();
ObjectMenu::init(app, port);
- _patch_port = patch_port;
+ _is_patch_port = is_patch_port;
_set_min_menuitem->signal_activate().connect(
sigc::mem_fun(this, &PortMenu::on_menu_set_min));
@@ -60,38 +61,36 @@ PortMenu::init(App& app, SharedPtr<const PortModel> port, bool patch_port)
_reset_range_menuitem->signal_activate().connect(
sigc::mem_fun(this, &PortMenu::on_menu_reset_range));
- if (!PtrCast<PatchModel>(port->parent())) {
+ _expose_menuitem->signal_activate().connect(
+ sigc::mem_fun(this, &PortMenu::on_menu_expose));
+
+ const bool is_control = app.can_control(port.get()) && port->is_numeric();
+ const bool is_on_patch = PtrCast<PatchModel>(port->parent());
+
+ if (!_is_patch_port) {
_polyphonic_menuitem->set_sensitive(false);
_rename_menuitem->set_sensitive(false);
_destroy_menuitem->set_sensitive(false);
}
- if (port->is_a(uris.atom_AtomPort))
+ if (port->is_a(uris.atom_AtomPort)) {
_polyphonic_menuitem->hide();
-
- const bool is_control = app.can_control(port.get())
- && port->is_numeric();
-
- _reset_range_menuitem->set_visible(true);
- _set_max_menuitem->set_visible(true);
- _set_min_menuitem->set_visible(true);
-
- _reset_range_menuitem->set_sensitive(is_control);
- _set_max_menuitem->set_sensitive(is_control);
- _set_min_menuitem->set_sensitive(is_control);
-
- if (is_control) {
- _learn_menuitem->show();
- _unlearn_menuitem->show();
}
+ _reset_range_menuitem->set_visible(is_control && !is_on_patch);
+ _set_max_menuitem->set_visible(is_control);
+ _set_min_menuitem->set_visible(is_control);
+ _expose_menuitem->set_visible(!is_on_patch);
+ _learn_menuitem->set_visible(is_control);
+ _unlearn_menuitem->set_visible(is_control);
+
_enable_signal = true;
}
void
PortMenu::on_menu_disconnect()
{
- if (_patch_port) {
+ if (_is_patch_port) {
_app->interface()->disconnect_all(
_object->parent()->path(), _object->path());
} else {
@@ -141,6 +140,41 @@ PortMenu::on_menu_reset_range()
_app->forge().make(max));
}
+void
+PortMenu::on_menu_expose()
+{
+ const URIs& uris = _app->uris();
+ SharedPtr<const PortModel> port = PtrCast<const PortModel>(_object);
+ SharedPtr<const NodeModel> node = PtrCast<const NodeModel>(_object->parent());
+
+ std::string label = node->label() + " " + node->port_label(port);
+ Raul::Path path = node->path().str() + "_" + _object->symbol().c_str();
+ Raul::Atom symbol = _app->forge().alloc(path.symbol());
+ Raul::Atom name = _app->forge().alloc(label.c_str());
+
+ Shared::ResourceImpl r(*_object.get());
+ r.remove_property(uris.lv2_index, uris.wildcard);
+ r.set_property(uris.lv2_symbol, symbol);
+ r.set_property(uris.lv2_name, name);
+
+ // TODO: Pretty kludgey coordinates
+ const float node_x = node->get_property(uris.ingen_canvasX).get_float();
+ const float node_y = node->get_property(uris.ingen_canvasY).get_float();
+ r.set_property(uris.ingen_canvasX,
+ _app->forge().make(node_x + ((label.length() * 16.0f)
+ * (port->is_input() ? -1 : 1))));
+ r.set_property(uris.ingen_canvasY,
+ _app->forge().make(node_y + port->index() * 32.0f));
+
+ _app->interface()->put(path, r.properties());
+
+ if (port->is_input()) {
+ _app->interface()->connect(path, _object->path());
+ } else {
+ _app->interface()->connect(_object->path(), path);
+ }
+}
+
} // namespace GUI
} // namespace Ingen
diff --git a/src/gui/PortMenu.hpp b/src/gui/PortMenu.hpp
index fc89703f..cc33efb0 100644
--- a/src/gui/PortMenu.hpp
+++ b/src/gui/PortMenu.hpp
@@ -43,20 +43,22 @@ public:
void init(App& app,
SharedPtr<const Client::PortModel> port,
- bool patch_port = false);
+ bool is_patch_port = false);
private:
void on_menu_disconnect();
void on_menu_set_min();
void on_menu_set_max();
void on_menu_reset_range();
-
- bool _patch_port;
+ void on_menu_expose();
Gtk::Menu* _port_menu;
Gtk::MenuItem* _set_min_menuitem;
Gtk::MenuItem* _set_max_menuitem;
Gtk::MenuItem* _reset_range_menuitem;
+ Gtk::MenuItem* _expose_menuitem;
+
+ bool _is_patch_port;
};
} // namespace GUI
diff --git a/src/gui/ingen_gui.ui b/src/gui/ingen_gui.ui
index 8a043c30..40db0323 100644
--- a/src/gui/ingen_gui.ui
+++ b/src/gui/ingen_gui.ui
@@ -1507,6 +1507,14 @@ Contributors:
<property name="label" translatable="yes">Reset Range</property>
</object>
</child>
+ <child>
+ <object class="GtkMenuItem" id="port_expose_menuitem">
+ <property name="can_focus">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_Expose</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
</object>
<object class="GtkWindow" id="patch_tree_win">
<property name="width_request">320</property>
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 4d715f7a..1d22ce75 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -77,9 +77,8 @@ struct Serialiser::Impl {
Resource::Graph context,
const Sord::Node& id);
- void serialise_properties(const GraphObject* o,
- Resource::Graph context,
- Sord::Node id);
+ void serialise_properties(Sord::Node id,
+ const Resource::Properties& props);
void write_bundle(SharedPtr<const Patch> patch,
const std::string& uri);
@@ -371,7 +370,8 @@ Serialiser::Impl::serialise_patch(SharedPtr<const Patch> patch,
Sord::URI(world, uris.doap_name.str()),
Sord::Literal(world, symbol));
- serialise_properties(patch.get(), Resource::INTERNAL, patch_id);
+ const GraphObject::Properties props = patch->properties(Resource::INTERNAL);
+ serialise_properties(patch_id, props);
for (Store::const_iterator n = _world.store()->children_begin(patch);
n != _world.store()->children_end(patch); ++n) {
@@ -458,7 +458,8 @@ Serialiser::Impl::serialise_node(SharedPtr<const Node> node,
Sord::Curie(_model->world(), "lv2:symbol"),
Sord::Literal(_model->world(), node->path().symbol()));
- serialise_properties(node.get(), Resource::EXTERNAL, node_id);
+ const GraphObject::Properties props = node->properties(Resource::EXTERNAL);
+ serialise_properties(node_id, props);
for (uint32_t i = 0; i < node->num_ports(); ++i) {
Port* const p = node->port(i);
@@ -491,7 +492,12 @@ Serialiser::Impl::serialise_port(const Port* port,
Sord::Curie(world, "lv2:symbol"),
Sord::Literal(world, port->path().symbol()));
- serialise_properties(port, context, port_id);
+ GraphObject::Properties props = port->properties(context);
+ if (context == Resource::INTERNAL) {
+ props.insert(make_pair(_world.uris().lv2_default, port->value()));
+ }
+
+ serialise_properties(port_id, props);
}
void
@@ -541,12 +547,9 @@ skip_property(const Sord::Node& predicate)
}
void
-Serialiser::Impl::serialise_properties(const GraphObject* o,
- Ingen::Resource::Graph context,
- Sord::Node id)
+Serialiser::Impl::serialise_properties(Sord::Node id,
+ const GraphObject::Properties& props)
{
- const GraphObject::Properties props = o->properties(context);
-
LV2_URID_Map* map = &_world.uri_map().urid_map_feature()->urid_map;
LV2_URID_Unmap* unmap = &_world.uri_map().urid_unmap_feature()->urid_unmap;
Sratom* sratom = sratom_new(map);