From fe81cb8af20ecbe721eba55d53fa62c5e2041421 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 9 Jun 2013 04:51:32 +0000 Subject: Support removing properties from the properties dialog. You can definitely blow your leg off with this one, clever ontology awareness (e.g. required properties) would be good... git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5138 a436a847-0d15-0410-975c-d299462d15a1 --- ingen/Resource.hpp | 9 +++++++++ ingen/client/ObjectModel.hpp | 2 ++ src/Resource.cpp | 5 ++++- src/client/ObjectModel.cpp | 6 ++++++ src/gui/PropertiesWindow.cpp | 37 ++++++++++++++++++++++++++++++------- src/gui/PropertiesWindow.hpp | 25 ++++++++++++++----------- 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/ingen/Resource.hpp b/ingen/Resource.hpp index 756419d8..3d6d6cd2 100644 --- a/ingen/Resource.hpp +++ b/ingen/Resource.hpp @@ -152,6 +152,15 @@ public: */ virtual void on_property(const Raul::URI& uri, const Atom& value) {} + /** Hook called whenever a property value is removed. + * + * If all values of a given key are removed, then value will be the wildcard. + * + * This can be used by derived classes to implement special behaviour for + * particular properties (e.g. ingen:value for ports). + */ + virtual void on_property_removed(const Raul::URI& uri, const Atom& value) {} + /** Get the ingen type from a set of Properties. * * If some coherent ingen type is found, true is returned and the appropriate diff --git a/ingen/client/ObjectModel.hpp b/ingen/client/ObjectModel.hpp index 66c3db7c..6c582812 100644 --- a/ingen/client/ObjectModel.hpp +++ b/ingen/client/ObjectModel.hpp @@ -62,6 +62,7 @@ public: const Atom& get_property(const Raul::URI& key) const; void on_property(const Raul::URI& uri, const Atom& value); + void on_property_removed(const Raul::URI& uri, const Atom& value); const Raul::Path& path() const { return _path; } const Raul::Symbol& symbol() const { return _symbol; } @@ -74,6 +75,7 @@ public: INGEN_SIGNAL(new_child, void, SPtr); INGEN_SIGNAL(removed_child, void, SPtr); INGEN_SIGNAL(property, void, const Raul::URI&, const Atom&); + INGEN_SIGNAL(property_removed, void, const Raul::URI&, const Atom&); INGEN_SIGNAL(destroyed, void); INGEN_SIGNAL(moved, void); diff --git a/src/Resource.cpp b/src/Resource.cpp index a8e96e5d..cd448e32 100644 --- a/src/Resource.cpp +++ b/src/Resource.cpp @@ -54,6 +54,7 @@ Resource::set_property(const Raul::URI& uri, ++next; if (i->second.context() == ctx) { _properties.erase(i); + on_property_removed(uri, i->second); } i = next; } @@ -75,10 +76,11 @@ Resource::remove_property(const Raul::URI& uri, const Atom& value) ++i) { if (i->second == value) { _properties.erase(i); - return; + break; } } } + on_property_removed(uri, value); } bool @@ -161,6 +163,7 @@ Resource::set_properties(const Properties& props) // Erase existing properties with matching keys for (const auto& p : props) { _properties.erase(p.first); + on_property_removed(p.first, _uris.wildcard); } // Set new properties diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index 4cef3188..45ac2f37 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -52,6 +52,12 @@ ObjectModel::on_property(const Raul::URI& uri, const Atom& value) _signal_property.emit(uri, value); } +void +ObjectModel::on_property_removed(const Raul::URI& uri, const Atom& value) +{ + _signal_property_removed.emit(uri, value); +} + const Atom& ObjectModel::get_property(const Raul::URI& key) const { diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index 2177de8c..50332c65 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -126,14 +126,18 @@ PropertiesWindow::add_property(const Raul::URI& uri, const Atom& value) lilv_node_free(prop); // Column 1: Value - Gtk::Alignment* align = manage(new Gtk::Alignment(0.0, 0.5, 1.0, 0.0)); - Gtk::Widget* val_widget = create_value_widget(uri, value); + Gtk::Alignment* align = manage(new Gtk::Alignment(0.0, 0.5, 1.0, 0.0)); + Gtk::CheckButton* present = manage(new Gtk::CheckButton()); + Gtk::Widget* val_widget = create_value_widget(uri, value); + present->set_active(true); if (val_widget) { align->add(*val_widget); } _table->attach(*align, 1, 2, n_rows, n_rows + 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK); - _records.insert(make_pair(uri, Record(value, align, n_rows))); + _table->attach(*present, 2, 3, n_rows, n_rows + 1, + Gtk::FILL, Gtk::SHRINK); + _records.insert(make_pair(uri, Record(value, align, n_rows, present))); } /** Set the node this window is associated with. @@ -208,6 +212,8 @@ PropertiesWindow::set_object(SPtr model) _property_connection = model->signal_property().connect( sigc::mem_fun(this, &PropertiesWindow::property_changed)); + _property_removed_connection = model->signal_property_removed().connect( + sigc::mem_fun(this, &PropertiesWindow::property_removed)); } Gtk::Widget* @@ -322,6 +328,14 @@ PropertiesWindow::property_changed(const Raul::URI& predicate, record.value = value; } +void +PropertiesWindow::property_removed(const Raul::URI& predicate, + const Atom& value) +{ + // Bleh, there doesn't seem to be an easy way to remove a Gtk::Table row... + set_object(_model); +} + void PropertiesWindow::value_edited(const Raul::URI& predicate) { @@ -446,16 +460,25 @@ PropertiesWindow::cancel_clicked() void PropertiesWindow::apply_clicked() { - Resource::Properties properties; + Resource::Properties remove; + Resource::Properties add; for (const auto& r : _records) { const Raul::URI& uri = r.first; const Record& record = r.second; - if (!_model->has_property(uri, record.value)) { - properties.insert(make_pair(uri, record.value)); + if (record.present_button->get_active()) { + if (!_model->has_property(uri, record.value)) { + add.insert(make_pair(uri, record.value)); + } + } else { + remove.insert(make_pair(uri, record.value)); } } - _app->interface()->put(_model->uri(), properties); + if (remove.empty()) { + _app->interface()->put(_model->uri(), add); + } else { + _app->interface()->delta(_model->uri(), remove, add); + } } void diff --git a/src/gui/PropertiesWindow.hpp b/src/gui/PropertiesWindow.hpp index 7725706b..025c98ae 100644 --- a/src/gui/PropertiesWindow.hpp +++ b/src/gui/PropertiesWindow.hpp @@ -23,8 +23,9 @@ #include #include #include -#include +#include #include +#include #include #include @@ -57,12 +58,13 @@ public: private: /** Record of a property (row in the table) */ struct Record { - Record(const Atom& v, Gtk::Alignment* vw, int r) - : value(v), value_widget(vw), row(r) + Record(const Atom& v, Gtk::Alignment* vw, int r, Gtk::CheckButton* cb) + : value(v), value_widget(vw), row(r), present_button(cb) {} - Atom value; - Gtk::Alignment* value_widget; - int row; + Atom value; + Gtk::Alignment* value_widget; + int row; + Gtk::CheckButton* present_button; }; struct ComboColumns : public Gtk::TreeModel::ColumnRecord { @@ -74,17 +76,17 @@ private: Gtk::TreeModelColumn uri_col; }; - void add_property(const Raul::URI& uri, - const Atom& value); + void add_property(const Raul::URI& uri, + const Atom& value); - Gtk::Widget* create_value_widget(const Raul::URI& uri, - const Atom& value); + Gtk::Widget* create_value_widget(const Raul::URI& uri, + const Atom& value); - void init(); void reset(); void on_show(); void property_changed(const Raul::URI& predicate, const Atom& value); + void property_removed(const Raul::URI& predicate, const Atom& value); void value_edited(const Raul::URI& predicate); void key_changed(); void add_clicked(); @@ -100,6 +102,7 @@ private: Glib::RefPtr _key_store; Glib::RefPtr _value_store; sigc::connection _property_connection; + sigc::connection _property_removed_connection; Gtk::VBox* _vbox; Gtk::ScrolledWindow* _scrolledwindow; Gtk::Table* _table; -- cgit v1.2.1