From 3dded8a655b6cad1925f160cb1012b8334e00c3e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 31 Dec 2009 18:27:20 +0000 Subject: Various fixes related to port values and metadata (fix ticket #459 among other things). Fix jitterey behaviour of port controls (on module) while dragging. Update value in status bar while dragging port slider (on module). Update plugin data (e.g. port control range) if the plugin is sent to the client after nodes that are instances of it (i.e. more robust plugin state tracking via merging like with objects). Correctly save and restore port values (ticket #459). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2327 a436a847-0d15-0410-975c-d299462d15a1 --- src/gui/Controls.cpp | 93 +++++------------------------------------------ src/gui/Controls.hpp | 26 ------------- src/gui/NodeModule.cpp | 18 +++++++-- src/gui/NodeModule.hpp | 3 +- src/gui/PatchWindow.cpp | 64 ++++++++++++++++++++------------ src/gui/PatchWindow.hpp | 5 ++- src/gui/Port.cpp | 71 +++++++++++++++++++++++++++++------- src/gui/Port.hpp | 3 ++ src/gui/WindowFactory.cpp | 3 ++ 9 files changed, 134 insertions(+), 152 deletions(-) (limited to 'src/gui') diff --git a/src/gui/Controls.cpp b/src/gui/Controls.cpp index 6e8ca351..9c66b1ae 100644 --- a/src/gui/Controls.cpp +++ b/src/gui/Controls.cpp @@ -70,6 +70,7 @@ Control::init(ControlPanel* panel, SharedPtr pm) assert(_port_model); assert(panel); + _control_connection.disconnect(); _control_connection = pm->signal_value_changed.connect(sigc::mem_fun(this, &Control::set_value)); } @@ -174,13 +175,13 @@ SliderControl::clicked(GdkEventButton* ev) void SliderControl::set_value(const Atom& atom) { - float val = atom.get_float(); + if (_enabled) { + _enable_signal = false; + float val = atom.get_float(); - if (_port_model->is_integer()) - val = lrintf(val); + if (_port_model->is_integer()) + val = lrintf(val); - _enable_signal = false; - if (_enabled) { if (_slider->get_value() != val) { const Gtk::Adjustment* range = _slider->get_adjustment(); const float lower = range->get_lower(); @@ -189,10 +190,12 @@ SliderControl::set_value(const Atom& atom) set_range(min(lower, val), max(lower, val)); _slider->set_value(val); } + if (_value_spinner->get_value() != val) _value_spinner->set_value(val); + + _enable_signal = true; } - _enable_signal = true; } @@ -290,94 +293,16 @@ SliderControl::update_value_from_spinner() bool SliderControl::slider_pressed(GdkEvent* ev) { - //cerr << "Pressed: " << ev->type << endl; if (ev->type == GDK_BUTTON_PRESS) { _enabled = false; - //GtkClientInterface::instance()->set_ignore_port(_port_model->path()); } else if (ev->type == GDK_BUTTON_RELEASE) { _enabled = true; - //GtkClientInterface::instance()->clear_ignore_port(); } return false; } -// ///////////// IntegerControl ////////////// // - -#if 0 -IntegerControl::IntegerControl(ControlPanel* panel, SharedPtr pm) -: Control(panel, pm), - _enable_signal(false), - _alignment(0.5, 0.5, 0.0, 0.0), - _name_label(pm->path().name()), - _spinner(1.0, 0) -{ - set_name(pm->path().name()); - - _spinner.set_range(-99999, 99999); - _spinner.set_value(_port_model->value()); - _spinner.signal_value_changed().connect( - sigc::mem_fun(*this, &IntegerControl::update_value)); - _spinner.set_increments(1, 10); - - _alignment.add(_spinner); - pack_start(_name_label); - pack_start(_alignment); - - _enable_signal = true; - - show_all(); -} - - -void -IntegerControl::set_name(const string& name) -{ - string name_label = ""; - name_label += name + ""; - _name_label->set_markup(name_label); -} - - -void -IntegerControl::set_value(float val) -{ - //cerr << "[IntegerControl] Setting value to " << val << endl; - _enable_signal = false; - _spinner.set_value(val); - _enable_signal = true; -} - - -void -IntegerControl::enable() -{ - _spinner.property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -IntegerControl::disable() -{ - _spinner.property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -IntegerControl::update_value() -{ - if (_enable_signal) { - float value = _spinner.get_value(); - _control_panel->value_changed(_port_model, value); - //m_port_model->value(value); - } -} -#endif - - // ///////////// ToggleControl ////////////// // diff --git a/src/gui/Controls.hpp b/src/gui/Controls.hpp index 844e6738..91b737ed 100644 --- a/src/gui/Controls.hpp +++ b/src/gui/Controls.hpp @@ -104,32 +104,6 @@ private: }; -#if 0 - -/** A spinbutton for integer controls. - * - * \ingroup GUI - */ -class IntegerControl : public Control -{ -public: - IntegerControl(ControlPanel* panel, SharedPtr pm); - - void enable(); - void disable(); - -private: - void set_value(float val); - - void update_value(); - - bool _enable_signal; - Gtk::Alignment _alignment; - Gtk::SpinButton _spinner; -}; -#endif - - /** A radio button for toggle controls. * * \ingroup GUI diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 4df32263..9010221a 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -21,6 +21,7 @@ #include "interface/EngineInterface.hpp" #include "client/PatchModel.hpp" #include "client/NodeModel.hpp" +#include "client/PluginModel.hpp" #include "client/PluginUI.hpp" #include "App.hpp" #include "GladeFactory.hpp" @@ -54,6 +55,9 @@ NodeModule::NodeModule(boost::shared_ptr canvas, SharedPtrsignal_removed_port.connect(sigc::hide_return(sigc::mem_fun(this, &NodeModule::remove_port))); node->signal_property.connect(sigc::mem_fun(this, &NodeModule::set_property)); node->signal_moved.connect(sigc::mem_fun(this, &NodeModule::rename)); + PluginModel* plugin = dynamic_cast(node->plugin()); + if (plugin) + plugin->signal_changed.connect(sigc::mem_fun(this, &NodeModule::plugin_changed)); } @@ -168,6 +172,14 @@ NodeModule::value_changed(uint32_t index, const Atom& value) } +void +NodeModule::plugin_changed() +{ + for (PortVector::iterator p = ports().begin(); p != ports().end(); ++p) + PtrCast(*p)->update_metadata(); +} + + void NodeModule::embed_gui(bool embed) { @@ -217,7 +229,7 @@ NodeModule::embed_gui(bool embed) } if (embed && _embed_item) { - initialise_gui_values(); + set_control_values(); set_base_color(0x212222FF); } else { set_default_base_color(); @@ -307,7 +319,7 @@ NodeModule::popup_gui() _gui_window->set_role("plugin_ui"); _gui_window->add(*_gui_widget); _gui_widget->show_all(); - initialise_gui_values(); + set_control_values(); _gui_window->signal_unmap().connect( sigc::mem_fun(this, &NodeModule::on_gui_window_close)); @@ -334,7 +346,7 @@ NodeModule::on_gui_window_close() void -NodeModule::initialise_gui_values() +NodeModule::set_control_values() { uint32_t index=0; for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) { diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp index a1a76e71..496d8867 100644 --- a/src/gui/NodeModule.hpp +++ b/src/gui/NodeModule.hpp @@ -82,7 +82,8 @@ protected: void add_port(SharedPtr port, bool resize=true); void value_changed(uint32_t index, const Raul::Atom& value); - void initialise_gui_values(); + void plugin_changed(); + void set_control_values(); void create_menu(); diff --git a/src/gui/PatchWindow.cpp b/src/gui/PatchWindow.cpp index a2992215..2638cbbe 100644 --- a/src/gui/PatchWindow.cpp +++ b/src/gui/PatchWindow.cpp @@ -18,6 +18,7 @@ #include "PatchWindow.hpp" #include #include +#include #include #include #include "raul/AtomRDF.hpp" @@ -300,38 +301,55 @@ PatchWindow::patch_port_removed(SharedPtr port) void -PatchWindow::object_entered(ObjectModel* model) +PatchWindow::show_status(ObjectModel* model) { - string msg = model->path().str(); - NodeModel* node = dynamic_cast(model); - if (node) { - PluginModel* plugin = (PluginModel*)node->plugin(); + std::stringstream msg; + msg << model->path().chop_scheme(); + + PortModel* port = 0; + NodeModel* node = 0; + + if ((port = dynamic_cast(model))) { + show_port_status(port, port->value()); + + } else if ((node = dynamic_cast(model))) { + PluginModel* plugin = dynamic_cast(node->plugin()); if (plugin) - msg.append((boost::format(" (%1%)") % plugin->human_name()).str()); + msg << ((boost::format(" (%1%)") % plugin->human_name()).str()); + _status_bar->push(msg.str(), STATUS_CONTEXT_HOVER); } +} - PortModel* port = dynamic_cast(model); - if (port) { - NodeModel* parent = dynamic_cast(port->parent().get()); - if (parent) { - const PluginModel* plugin = dynamic_cast(parent->plugin()); - if (plugin) { - const string human_name = plugin->port_human_name(port->index()); - if (human_name != "") - msg.append((boost::format(" (%1%)") % human_name).str()); - } - } +void +PatchWindow::show_port_status(PortModel* port, const Raul::Atom& value) +{ + std::stringstream msg; + msg << port->path().chop_scheme(); - const Atom& value = port->value(); - if (value.is_valid()) { - const Redland::Node node = AtomRDF::atom_to_node( - *App::instance().world()->rdf_world, value); - msg.append(" = ").append(node.to_string()); + NodeModel* parent = dynamic_cast(port->parent().get()); + if (parent) { + const PluginModel* plugin = dynamic_cast(parent->plugin()); + if (plugin) { + const string& human_name = plugin->port_human_name(port->index()); + if (human_name != "") + msg << " (" << human_name << ")"; } } - _status_bar->push(msg, STATUS_CONTEXT_HOVER); + if (value.is_valid()) { + msg << " = " << value; + } + + _status_bar->pop(STATUS_CONTEXT_HOVER); + _status_bar->push(msg.str(), STATUS_CONTEXT_HOVER); +} + + +void +PatchWindow::object_entered(ObjectModel* model) +{ + show_status(model); } diff --git a/src/gui/PatchWindow.hpp b/src/gui/PatchWindow.hpp index 0d997ab7..82afa7ad 100644 --- a/src/gui/PatchWindow.hpp +++ b/src/gui/PatchWindow.hpp @@ -21,6 +21,7 @@ #include #include #include +#include "raul/Atom.hpp" #include "raul/SharedPtr.hpp" #include "Window.hpp" @@ -66,6 +67,8 @@ public: Gtk::MenuItem* menu_view_control_window() { return _menu_view_control_window; } + void show_port_status(PortModel* model, const Raul::Atom& value); + protected: void on_show(); void on_hide(); @@ -73,9 +76,9 @@ protected: bool on_key_release_event(GdkEventKey* event); private: - void patch_port_added(SharedPtr port); void patch_port_removed(SharedPtr port); + void show_status(ObjectModel* model); void object_entered(ObjectModel* model); void object_left(ObjectModel* model); void editable_changed(bool editable); diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index ba4e0482..91e64f3a 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -21,11 +21,13 @@ #include "flowcanvas/Module.hpp" #include "client/PatchModel.hpp" #include "client/PortModel.hpp" -#include "Configuration.hpp" #include "App.hpp" +#include "Configuration.hpp" +#include "GladeFactory.hpp" +#include "PatchWindow.hpp" #include "Port.hpp" #include "PortMenu.hpp" -#include "GladeFactory.hpp" +#include "WindowFactory.hpp" using namespace Ingen::Client; using namespace std; @@ -48,6 +50,7 @@ Port::Port( flip ? (!pm->is_input()) : pm->is_input(), App::instance().configuration()->get_port_color(pm.get())) , _port_model(pm) + , _pressed(false) , _flipped(flip) { assert(module); @@ -65,21 +68,14 @@ Port::Port( if (pm->type().is_control()) { set_toggled(pm->is_toggle()); show_control(); - - float min = 0.0f, max = 1.0f; - boost::shared_ptr parent = PtrCast(pm->parent()); - if (parent) - parent->port_value_range(pm, min, max); - - set_control_min(min); - set_control_max(max); - pm->signal_property.connect(sigc::mem_fun(this, &Port::property_changed)); pm->signal_value_changed.connect(sigc::mem_fun(this, &Port::value_changed)); } pm->signal_activity.connect(sigc::mem_fun(this, &Port::activity)); + update_metadata(); + value_changed(pm->value()); } @@ -90,6 +86,24 @@ Port::~Port() } +void +Port::update_metadata() +{ + SharedPtr pm = _port_model.lock(); + if (pm && pm->type().is_control()) { + boost::shared_ptr parent = PtrCast(pm->parent()); + if (parent) { + float min = 0.0f; + float max = 1.0f; + parent->port_value_range(pm, min, max); + set_control_min(min); + set_control_max(max); + } + } +} + + + void Port::create_menu() { @@ -112,13 +126,32 @@ Port::moved() void Port::value_changed(const Atom& value) { - if (value.type() == Atom::FLOAT) + if (_pressed) + return; + else if (value.type() == Atom::FLOAT) FlowCanvas::Port::set_control(value.get_float()); else cerr << "WARNING: Unknown port value type " << (unsigned)value.type() << endl; } +bool +Port::on_event(GdkEvent* ev) +{ + switch (ev->type) { + case GDK_BUTTON_PRESS: + _pressed = true; + break; + case GDK_BUTTON_RELEASE: + _pressed = false; + default: + break; + } + + return false; +} + + void Port::activity() { @@ -132,6 +165,14 @@ Port::set_control(float value, bool signal) if (signal) { if (model()->type() == PortType::CONTROL) { App::instance().engine()->set_port_value(model()->path(), Atom(value)); + PatchWindow* pw = App::instance().window_factory()->patch_window( + PtrCast(model()->parent())); + if (!pw) + pw = App::instance().window_factory()->patch_window( + PtrCast(model()->parent()->parent())); + if (pw) + pw->show_port_status(model().get(), value); + } else if (model()->type() == PortType::EVENTS) { App::instance().engine()->set_port_value(model()->path(), Atom("", 0, NULL)); @@ -146,9 +187,11 @@ void Port::property_changed(const URI& key, const Atom& value) { if (value.type() == Atom::FLOAT) { - if ((key.str() == "lv2:minimum")) + if (key.str() == "ingen:value") + set_control(value.get_float(), false); + else if (key.str() == "lv2:minimum") set_control_min(value.get_float()); - else if ((key.str() == "lv2:maximum")) + else if (key.str() == "lv2:maximum") set_control_max(value.get_float()); } else if (value.type() == Atom::BOOL) { if ((key.str() == "lv2:toggled")) diff --git a/src/gui/Port.hpp b/src/gui/Port.hpp index ec361a9f..2c79ec7c 100644 --- a/src/gui/Port.hpp +++ b/src/gui/Port.hpp @@ -51,6 +51,7 @@ public: SharedPtr model() const { return _port_model.lock(); } void create_menu(); + void update_metadata(); virtual void set_control(float value, bool signal); void value_changed(const Raul::Atom& value); @@ -61,11 +62,13 @@ public: private: void property_changed(const Raul::URI& key, const Raul::Atom& value); + bool on_event(GdkEvent* ev); void moved(); static ArtVpathDash* _dash; WeakPtr _port_model; + bool _pressed; bool _flipped; }; diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index b06ed449..91abccaf 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -116,6 +116,9 @@ WindowFactory::num_open_patch_windows() PatchWindow* WindowFactory::patch_window(SharedPtr patch) { + if (!patch) + return NULL; + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); return (w == _patch_windows.end()) ? NULL : w->second; -- cgit v1.2.1