diff options
author | David Robillard <d@drobilla.net> | 2009-12-31 18:27:20 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-12-31 18:27:20 +0000 |
commit | 3dded8a655b6cad1925f160cb1012b8334e00c3e (patch) | |
tree | 5d743f58c6494ea7e5ed4010f9016c7d3c3f7665 /src/gui | |
parent | c11b1bd6fe15f281c5e6b1ab2109590c17e739e9 (diff) | |
download | ingen-3dded8a655b6cad1925f160cb1012b8334e00c3e.tar.gz ingen-3dded8a655b6cad1925f160cb1012b8334e00c3e.tar.bz2 ingen-3dded8a655b6cad1925f160cb1012b8334e00c3e.zip |
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
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/Controls.cpp | 93 | ||||
-rw-r--r-- | src/gui/Controls.hpp | 26 | ||||
-rw-r--r-- | src/gui/NodeModule.cpp | 18 | ||||
-rw-r--r-- | src/gui/NodeModule.hpp | 3 | ||||
-rw-r--r-- | src/gui/PatchWindow.cpp | 64 | ||||
-rw-r--r-- | src/gui/PatchWindow.hpp | 5 | ||||
-rw-r--r-- | src/gui/Port.cpp | 71 | ||||
-rw-r--r-- | src/gui/Port.hpp | 3 | ||||
-rw-r--r-- | src/gui/WindowFactory.cpp | 3 |
9 files changed, 134 insertions, 152 deletions
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<PortModel> 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<PortModel> 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 = "<span weight=\"bold\">"; - name_label += name + "</span>"; - _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<PortModel> 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<PatchCanvas> canvas, SharedPtr<NodeMode node->signal_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<PluginModel*>(node->plugin()); + if (plugin) + plugin->signal_changed.connect(sigc::mem_fun(this, &NodeModule::plugin_changed)); } @@ -169,6 +173,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<Ingen::GUI::Port>(*p)->update_metadata(); +} + + +void NodeModule::embed_gui(bool embed) { if (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<PortModel> 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 <iostream> #include <cassert> +#include <sstream> #include <fstream> #include <boost/format.hpp> #include "raul/AtomRDF.hpp" @@ -300,38 +301,55 @@ PatchWindow::patch_port_removed(SharedPtr<PortModel> port) void -PatchWindow::object_entered(ObjectModel* model) +PatchWindow::show_status(ObjectModel* model) { - string msg = model->path().str(); - NodeModel* node = dynamic_cast<NodeModel*>(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<PortModel*>(model))) { + show_port_status(port, port->value()); + + } else if ((node = dynamic_cast<NodeModel*>(model))) { + PluginModel* plugin = dynamic_cast<PluginModel*>(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<PortModel*>(model); - if (port) { - NodeModel* parent = dynamic_cast<NodeModel*>(port->parent().get()); - if (parent) { - const PluginModel* plugin = dynamic_cast<const PluginModel*>(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<NodeModel*>(port->parent().get()); + if (parent) { + const PluginModel* plugin = dynamic_cast<const PluginModel*>(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 <gtkmm.h> #include <libglademm/xml.h> #include <libglademm.h> +#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<PortModel> port); void patch_port_removed(SharedPtr<PortModel> 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<NodeModel> parent = PtrCast<NodeModel>(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()); } @@ -91,6 +87,24 @@ Port::~Port() void +Port::update_metadata() +{ + SharedPtr<PortModel> pm = _port_model.lock(); + if (pm && pm->type().is_control()) { + boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(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() { PortMenu* menu = NULL; @@ -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<PatchModel>(model()->parent())); + if (!pw) + pw = App::instance().window_factory()->patch_window( + PtrCast<PatchModel>(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("<http://example.org/ev#BangEvent>", 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<PortModel> 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<PortModel> _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<PatchModel> patch) { + if (!patch) + return NULL; + PatchWindowMap::iterator w = _patch_windows.find(patch->path()); return (w == _patch_windows.end()) ? NULL : w->second; |