summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client/ClientStore.cpp13
-rw-r--r--src/gui/Port.cpp15
-rw-r--r--src/gui/Port.hpp1
-rw-r--r--src/gui/PortMenu.cpp24
-rw-r--r--src/gui/PortPropertiesWindow.cpp166
-rw-r--r--src/gui/PortPropertiesWindow.hpp69
-rw-r--r--src/gui/wscript1
-rw-r--r--src/serialisation/Parser.cpp47
-rw-r--r--src/serialisation/Serialiser.cpp21
-rw-r--r--src/server/DuplexPort.cpp12
-rw-r--r--src/server/InputPort.cpp6
-rw-r--r--src/server/LV2Block.cpp2
-rw-r--r--src/server/PortImpl.cpp9
-rw-r--r--src/server/events/Delta.cpp12
14 files changed, 96 insertions, 302 deletions
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index 02f5f4f0..f5c99e38 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -289,16 +289,17 @@ ClientStore::put(const Raul::URI& uri,
PortModel::Direction pdir = (is_output)
? PortModel::Direction::OUTPUT
: PortModel::Direction::INPUT;
- const Iterator i = properties.find(_uris.lv2_index);
+ uint32_t index = 0;
+ const Iterator i = properties.find(_uris.lv2_index);
if (i != properties.end() && i->second.type() == _uris.forge.Int) {
- const uint32_t index = i->second.get<int32_t>();
- SPtr<PortModel> p(
- new PortModel(uris(), path, index, pdir));
- p->set_properties(properties);
- add_object(p);
+ index = i->second.get<int32_t>();
} else {
_log.error(fmt("Port %1% has no index\n") % path);
}
+
+ SPtr<PortModel> p(new PortModel(uris(), path, index, pdir));
+ p->set_properties(properties);
+ add_object(p);
} else {
_log.warn(fmt("Ignoring object %1% with unknown type\n")
% path.c_str());
diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp
index 2bdf2e43..0d82d0cd 100644
--- a/src/gui/Port.cpp
+++ b/src/gui/Port.cpp
@@ -89,6 +89,8 @@ Port::Port(App& app,
show_control();
pm->signal_property().connect(
sigc::mem_fun(this, &Port::property_changed));
+ pm->signal_property_removed().connect(
+ sigc::mem_fun(this, &Port::property_removed));
pm->signal_value_changed().connect(
sigc::mem_fun(this, &Port::value_changed));
}
@@ -121,7 +123,7 @@ void
Port::update_metadata()
{
SPtr<const PortModel> pm = _port_model.lock();
- if (_app.can_control(pm.get()) && pm->is_numeric()) {
+ if (pm && _app.can_control(pm.get()) && pm->is_numeric()) {
SPtr<const BlockModel> parent = dynamic_ptr_cast<const BlockModel>(pm->parent());
if (parent) {
float min = 0.0f;
@@ -435,13 +437,22 @@ Port::property_changed(const Raul::URI& key, const Atom& value)
}
}
+void
+Port::property_removed(const Raul::URI& key, const Atom& value)
+{
+ const URIs& uris = _app.uris();
+ if (key == uris.lv2_minimum || key == uris.lv2_maximum) {
+ update_metadata();
+ }
+}
+
bool
Port::on_selected(gboolean b)
{
if (b) {
SPtr<const PortModel> pm = _port_model.lock();
if (pm) {
- SPtr<const BlockModel> block = dynamic_ptr_cast<BlockModel>(pm->parent());
+ SPtr<const BlockModel> block = dynamic_ptr_cast<const BlockModel>(pm->parent());
GraphWindow* win = _app.window_factory()->parent_graph_window(block);
if (win && win->documentation_is_visible() && block->plugin_model()) {
bool html = false;
diff --git a/src/gui/Port.hpp b/src/gui/Port.hpp
index a8d16095..216b8356 100644
--- a/src/gui/Port.hpp
+++ b/src/gui/Port.hpp
@@ -78,6 +78,7 @@ private:
GraphBox* get_graph_box() const;
void property_changed(const Raul::URI& key, const Atom& value);
+ void property_removed(const Raul::URI& key, const Atom& value);
void moved();
void on_value_changed(double value);
diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp
index 9c428dd8..138ee397 100644
--- a/src/gui/PortMenu.cpp
+++ b/src/gui/PortMenu.cpp
@@ -121,22 +121,14 @@ PortMenu::on_menu_set_max()
void
PortMenu::on_menu_reset_range()
{
- const URIs& uris = _app->uris();
- SPtr<const PortModel> model = dynamic_ptr_cast<const PortModel>(_object);
- SPtr<const BlockModel> parent = dynamic_ptr_cast<const BlockModel>(_object->parent());
-
- float min, max;
- parent->default_port_value_range(model, min, max);
-
- if (!std::isnan(min))
- _app->interface()->set_property(_object->uri(),
- uris.lv2_minimum,
- _app->forge().make(min));
-
- if (!std::isnan(max))
- _app->interface()->set_property(_object->uri(),
- uris.lv2_maximum,
- _app->forge().make(max));
+ const URIs& uris = _app->uris();
+ SPtr<const PortModel> model = dynamic_ptr_cast<const PortModel>(_object);
+
+ // Remove lv2:minimum and lv2:maximum properties
+ Resource::Properties remove;
+ remove.insert({uris.lv2_minimum, Resource::Property(uris.patch_wildcard)});
+ remove.insert({uris.lv2_maximum, Resource::Property(uris.patch_wildcard)});
+ _app->interface()->delta(_object->uri(), remove, Resource::Properties());
}
void
diff --git a/src/gui/PortPropertiesWindow.cpp b/src/gui/PortPropertiesWindow.cpp
deleted file mode 100644
index e4aec41d..00000000
--- a/src/gui/PortPropertiesWindow.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2012 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or 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 Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cassert>
-#include <list>
-
-#include "ingen/Interface.hpp"
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/client/PluginModel.hpp"
-
-#include "App.hpp"
-#include "PortPropertiesWindow.hpp"
-
-using namespace std;
-
-namespace Ingen {
-using namespace Client;
-namespace GUI {
-
-PortPropertiesWindow::PortPropertiesWindow(BaseObjectType* cobject,
- const Glib::RefPtr<Gtk::Builder>& xml)
- : Window(cobject)
- , _initial_min(0.0f)
- , _initial_max(1.0f)
-{
- xml->get_widget("port_properties_min_spinner", _min_spinner);
- xml->get_widget("port_properties_max_spinner", _max_spinner);
- xml->get_widget("port_properties_cancel_button", _cancel_button);
- xml->get_widget("port_properties_ok_button", _ok_button);
-
- _cancel_button->signal_clicked().connect(sigc::mem_fun(this,
- &PortPropertiesWindow::cancel));
-
- _ok_button->signal_clicked().connect(sigc::mem_fun(this,
- &PortPropertiesWindow::ok));
-}
-
-/** Set the port this window is associated with.
- * This function MUST be called before using this object in any way.
- */
-void
-PortPropertiesWindow::present(SPtr<const PortModel> pm)
-{
- assert(pm);
-
- for (auto& c : _connections)
- c.disconnect();
-
- _connections.clear();
-
- _port_model = pm;
-
- set_title(pm->path() + " Properties - Ingen");
-
- float min = 0.0f, max = 1.0f;
- SPtr<BlockModel> parent = dynamic_ptr_cast<BlockModel>(_port_model->parent());
- if (parent)
- parent->port_value_range(_port_model, min, max,
- _app->sample_rate());
-
- _initial_min = min;
- _initial_max = max;
-
- _min_spinner->set_value(min);
- _connections.push_back(
- _min_spinner->signal_value_changed().connect(
- sigc::mem_fun(*this, &PortPropertiesWindow::min_changed)));
-
- _max_spinner->set_value(max);
- _connections.push_back(
- _max_spinner->signal_value_changed().connect(
- sigc::mem_fun(*this, &PortPropertiesWindow::max_changed)));
-
- _connections.push_back(
- pm->signal_property().connect(
- sigc::mem_fun(this, &PortPropertiesWindow::property_changed)));
-
- Gtk::Window::present();
-}
-
-void
-PortPropertiesWindow::property_changed(const Raul::URI& key,
- const Atom& value)
-{
- const URIs& uris = _app->uris();
- if (value.type() == uris.forge.Float) {
- if (key == uris.lv2_minimum)
- _min_spinner->set_value(value.get<float>());
- else if (key == uris.lv2_maximum)
- _max_spinner->set_value(value.get<float>());
- }
-}
-
-void
-PortPropertiesWindow::min_changed()
-{
- const float val = _port_model->value().get<float>();
- float min = _min_spinner->get_value();
- float max = _max_spinner->get_value();
-
- if (min > val) {
- _min_spinner->set_value(val);
- return; // avoid recursion
- }
-
- if (max <= min) {
- max = min + 1.0;
- _max_spinner->set_value(max);
- }
-}
-
-void
-PortPropertiesWindow::max_changed()
-{
- const float val = _port_model->value().get<float>();
- float min = _min_spinner->get_value();
- float max = _max_spinner->get_value();
-
- if (max < val) {
- _max_spinner->set_value(val);
- return; // avoid recursion
- }
-
- if (min >= max) {
- min = max - 1.0;
- _min_spinner->set_value(min);
- }
-}
-
-void
-PortPropertiesWindow::cancel()
-{
- hide();
-}
-
-void
-PortPropertiesWindow::ok()
-{
- const URIs& uris = _app->uris();
- Resource::Properties props;
- props.insert(
- make_pair(uris.lv2_minimum,
- _app->forge().make(float(_min_spinner->get_value()))));
- props.insert(
- make_pair(uris.lv2_maximum,
- _app->forge().make(float(_max_spinner->get_value()))));
- _app->interface()->put(_port_model->uri(), props);
- hide();
-}
-
-} // namespace GUI
-} // namespace Ingen
-
diff --git a/src/gui/PortPropertiesWindow.hpp b/src/gui/PortPropertiesWindow.hpp
deleted file mode 100644
index 684a2dfb..00000000
--- a/src/gui/PortPropertiesWindow.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2012 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or 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 Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_GUI_PORTPROPERTIESWINDOW_HPP
-#define INGEN_GUI_PORTPROPERTIESWINDOW_HPP
-
-#include <list>
-
-#include <gtkmm/builder.h>
-#include <gtkmm/spinbutton.h>
-
-#include "ingen/client/PortModel.hpp"
-#include "ingen/types.hpp"
-
-#include "Window.hpp"
-
-namespace Ingen {
-namespace GUI {
-
-/** Port properties window.
- *
- * Loaded from XML as a derived object.
- *
- * \ingroup GUI
- */
-class PortPropertiesWindow : public Window
-{
-public:
- PortPropertiesWindow(BaseObjectType* cobject,
- const Glib::RefPtr<Gtk::Builder>& xml);
-
- void present(SPtr<const Client::PortModel> port_model);
-
-private:
- void property_changed(const Raul::URI& key, const Atom& value);
- void min_changed();
- void max_changed();
-
- void ok();
- void cancel();
-
- float _initial_min;
- float _initial_max;
-
- SPtr<const Client::PortModel> _port_model;
- Gtk::SpinButton* _min_spinner;
- Gtk::SpinButton* _max_spinner;
- Gtk::Button* _cancel_button;
- Gtk::Button* _ok_button;
- std::list<sigc::connection> _connections;
-};
-
-} // namespace GUI
-} // namespace Ingen
-
-#endif // INGEN_GUI_PORTPROPERTIESWINDOW_HPP
diff --git a/src/gui/wscript b/src/gui/wscript
index 62731abe..153c4d15 100644
--- a/src/gui/wscript
+++ b/src/gui/wscript
@@ -47,7 +47,6 @@ def build(bld):
PluginMenu.cpp
Port.cpp
PortMenu.cpp
- PortPropertiesWindow.cpp
PropertiesWindow.cpp
RDFS.cpp
RenameWindow.cpp
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index 3d8ba96d..d49ac9a6 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -140,31 +140,47 @@ get_port(Ingen::World* world,
Sord::Model& model,
const Sord::Node& subject,
const Raul::Path& parent,
- uint32_t& index)
+ uint32_t* index)
{
const URIs& uris = world->uris();
// Get all properties
Resource::Properties props = get_properties(world, model, subject);
- // Get index
- Resource::Properties::const_iterator i = props.find(uris.lv2_index);
- if (i == props.end()
- || i->second.type() != world->forge().Int
- || i->second.get<int32_t>() < 0) {
- world->log().warn(fmt("Port %1% has no valid index\n") % subject);
- return boost::optional<PortRecord>();
+ // Get index if requested (for Graphs)
+ if (index) {
+ Resource::Properties::const_iterator i = props.find(uris.lv2_index);
+ if (i == props.end()
+ || i->second.type() != world->forge().Int
+ || i->second.get<int32_t>() < 0) {
+ world->log().error(fmt("Port %1% has no valid index\n") % subject);
+ return boost::optional<PortRecord>();
+ }
+ *index = i->second.get<int32_t>();
}
- index = i->second.get<int32_t>();
// Get symbol
Resource::Properties::const_iterator s = props.find(uris.lv2_symbol);
- if (s == props.end()) {
- world->log().warn(fmt("Port %1% has no symbol\n") % subject);
+ std::string sym;
+ if (s != props.end()) {
+ sym = s->second.ptr<char>();
+ } else {
+ const std::string subject_str = subject.to_string();
+ const size_t last_slash = subject_str.find_last_of("/");
+
+ sym = ((last_slash == string::npos)
+ ? subject_str
+ : subject_str.substr(last_slash + 1));
+ }
+
+ if (!Raul::Symbol::is_valid(sym)) {
+ world->log().error(fmt("Port %1% has invalid symbol `%2%'\n")
+ % subject % sym);
return boost::optional<PortRecord>();
}
- const Raul::Symbol port_sym(s->second.ptr<char>());
- const Raul::Path port_path = parent.child(port_sym);
+
+ const Raul::Symbol port_sym(sym);
+ const Raul::Path port_path(parent.child(port_sym));
return make_pair(port_path, props);
}
@@ -341,9 +357,8 @@ parse_graph(Ingen::World* world,
Sord::Node port = p.get_object();
// Get all properties
- uint32_t index = 0;
boost::optional<PortRecord> port_record = get_port(
- world, model, port, block_path, index);
+ world, model, port, block_path, NULL);
if (!port_record) {
world->log().error(fmt("Invalid port %1%\n") % port);
return boost::optional<Raul::Path>();
@@ -364,7 +379,7 @@ parse_graph(Ingen::World* world,
// Get all properties
uint32_t index = 0;
boost::optional<PortRecord> port_record = get_port(
- world, model, port, graph_path, index);
+ world, model, port, graph_path, &index);
if (!port_record) {
world->log().error(fmt("Invalid port %1%\n") % port);
return boost::optional<Raul::Path>();
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 425ac00f..dd1be2b4 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -433,9 +433,6 @@ Serialiser::Impl::serialise_block(SPtr<const Node> block,
_model->add_statement(block_id,
Sord::URI(_model->world(), uris.ingen_prototype),
class_id);
- _model->add_statement(block_id,
- Sord::URI(_model->world(), uris.lv2_symbol),
- Sord::Literal(_model->world(), block->path().symbol()));
const Node::Properties props = block->properties(Resource::Graph::EXTERNAL);
serialise_properties(block_id, props);
@@ -455,14 +452,20 @@ Serialiser::Impl::serialise_port(const Node* port,
Resource::Graph context,
const Sord::Node& port_id)
{
- URIs& uris = _world.uris();
- Sord::World& world = _model->world();
+ URIs& uris = _world.uris();
+ Sord::World& world = _model->world();
+ Node::Properties props = port->properties(context);
- _model->add_statement(port_id,
- Sord::URI(world, uris.lv2_symbol),
- Sord::Literal(world, port->path().symbol()));
+ if (context == Resource::Graph::INTERNAL) {
+ // Always write lv2:symbol for Graph ports (required for lv2:Plugin)
+ _model->add_statement(port_id,
+ Sord::URI(world, uris.lv2_symbol),
+ Sord::Literal(world, port->path().symbol()));
+ } else {
+ // Never write lv2:index for plugin instances (not persistent/stable)
+ props.erase(uris.lv2_index);
+ }
- Node::Properties props = port->properties(context);
if (context == Resource::Graph::INTERNAL &&
port->has_property(uris.rdf_type, uris.lv2_ControlPort) &&
port->has_property(uris.rdf_type, uris.lv2_InputPort))
diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp
index 438d315c..256d45b1 100644
--- a/src/server/DuplexPort.cpp
+++ b/src/server/DuplexPort.cpp
@@ -42,8 +42,16 @@ DuplexPort::DuplexPort(BufferFactory& bufs,
, OutputPort(bufs, parent, symbol, index, poly, type, buffer_type, value, buffer_size)
, _is_output(is_output)
{
- set_property(bufs.uris().ingen_polyphonic,
- bufs.forge().make(polyphonic));
+ if (polyphonic) {
+ set_property(bufs.uris().ingen_polyphonic, bufs.forge().make(true));
+ }
+
+ // Set default control range
+ if (!is_output && (type == PortType::CONTROL || type == PortType::CV)) {
+ set_property(bufs.uris().lv2_minimum, bufs.forge().make(0.0f));
+ set_property(bufs.uris().lv2_maximum, bufs.forge().make(1.0f));
+ }
+
}
DuplexPort::~DuplexPort()
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index f1be3b8f..cdf70575 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -53,12 +53,6 @@ InputPort::InputPort(BufferFactory& bufs,
if (parent->graph_type() != Node::GraphType::GRAPH) {
add_property(uris.rdf_type, uris.lv2_InputPort);
}
-
- // Set default control range
- if (type == PortType::CONTROL || type == PortType::CV) {
- set_property(uris.lv2_minimum, bufs.forge().make(0.0f));
- set_property(uris.lv2_maximum, bufs.forge().make(1.0f));
- }
}
bool
diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp
index 0525a2db..5e97bfe5 100644
--- a/src/server/LV2Block.cpp
+++ b/src/server/LV2Block.cpp
@@ -366,11 +366,9 @@ LV2Block::instantiate(BufferFactory& bufs)
|| port_type == PortType::CV)) {
port->set_value(val);
if (!isnan(min_values[j])) {
- port->set_property(uris.lv2_minimum, forge.make(min_values[j]));
port->set_minimum(forge.make(min_values[j]));
}
if (!isnan(max_values[j])) {
- port->set_property(uris.lv2_maximum, forge.make(max_values[j]));
port->set_maximum(forge.make(max_values[j]));
}
}
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index e4b3ad4d..aed67ec3 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -82,15 +82,14 @@ PortImpl::PortImpl(BufferFactory& bufs,
set_type(type, buffer_type);
- add_property(uris.rdf_type, bufs.forge().alloc_uri(type.uri()));
set_property(uris.lv2_index, bufs.forge().make((int32_t)index));
if ((type == PortType::CONTROL || type == PortType::CV) && value.is_valid()) {
set_property(uris.ingen_value, value);
}
- if (type == PortType::ATOM) {
- add_property(uris.atom_bufferType,
- bufs.forge().make_urid(buffer_type));
- }
+ // if (type == PortType::ATOM) {
+ // set_property(uris.atom_bufferType,
+ // bufs.forge().make_urid(buffer_type));
+ // }
}
PortImpl::~PortImpl()
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 072d0ba3..0c134ede 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -148,9 +148,10 @@ Delta::pre_process()
NodeImpl* obj = dynamic_cast<NodeImpl*>(_object);
+ // Remove any properties removed in delta
for (const auto& r : _remove) {
- const Raul::URI& key = r.first;
- const Atom& value = r.second;
+ const Raul::URI& key = r.first;
+ const Atom& value = r.second;
if (key == uris.midi_binding && value == uris.patch_wildcard) {
PortImpl* port = dynamic_cast<PortImpl*>(_object);
if (port)
@@ -161,6 +162,13 @@ Delta::pre_process()
}
}
+ // Remove all added properties if this is a put
+ if (_create && _object) {
+ for (const auto& p : _properties) {
+ _object->remove_property(p.first, p.second);
+ }
+ }
+
for (const auto& p : _properties) {
const Raul::URI& key = p.first;
const Resource::Property& value = p.second;