summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-01 06:46:55 +0000
committerDavid Robillard <d@drobilla.net>2012-05-01 06:46:55 +0000
commitd76ab24976e452d02e114182b3a563eeb11e8785 (patch)
tree801e459ac10f176bcce8221d2cba17bf71a14f6c
parent7477318adc8de5244fc314939c296ae74605eaa5 (diff)
downloadingen-d76ab24976e452d02e114182b3a563eeb11e8785.tar.gz
ingen-d76ab24976e452d02e114182b3a563eeb11e8785.tar.bz2
ingen-d76ab24976e452d02e114182b3a563eeb11e8785.zip
Implement menu selector for enumeration ports (sort of address #780).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4308 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ingen/client/PluginModel.hpp7
-rw-r--r--ingen/client/PortModel.hpp1
-rw-r--r--ingen/shared/URIs.hpp1
-rw-r--r--src/client/PluginModel.cpp19
-rw-r--r--src/gui/Port.cpp33
-rw-r--r--src/gui/Port.hpp3
-rw-r--r--src/shared/URIs.cpp1
7 files changed, 65 insertions, 0 deletions
diff --git a/ingen/client/PluginModel.hpp b/ingen/client/PluginModel.hpp
index e434df07..46e7b116 100644
--- a/ingen/client/PluginModel.hpp
+++ b/ingen/client/PluginModel.hpp
@@ -17,6 +17,9 @@
#ifndef INGEN_CLIENT_PLUGINMODEL_HPP
#define INGEN_CLIENT_PLUGINMODEL_HPP
+#include <list>
+#include <utility>
+
#include "lilv/lilv.h"
#include "raul/SharedPtr.hpp"
#include "raul/Symbol.hpp"
@@ -59,6 +62,10 @@ public:
std::string human_name() const;
std::string port_human_name(uint32_t index) const;
+ typedef std::pair<float, std::string> ScalePoint;
+ typedef std::list<ScalePoint> ScalePoints;
+ ScalePoints port_scale_points(uint32_t i) const;
+
static LilvWorld* lilv_world() { return _lilv_world; }
const LilvPlugin* lilv_plugin() const { return _lilv_plugin; }
diff --git a/ingen/client/PortModel.hpp b/ingen/client/PortModel.hpp
index d9fce5e4..8065692d 100644
--- a/ingen/client/PortModel.hpp
+++ b/ingen/client/PortModel.hpp
@@ -54,6 +54,7 @@ public:
bool port_property(const Raul::URI& uri) const;
bool is_logarithmic() const { return port_property(LV2_PORT_PROPS__logarithmic); }
+ bool is_enumeration() const { return port_property(LV2_CORE__enumeration); }
bool is_integer() const { return port_property(LV2_CORE__integer); }
bool is_toggle() const { return port_property(LV2_CORE__toggled); }
bool is_numeric() const {
diff --git a/ingen/shared/URIs.hpp b/ingen/shared/URIs.hpp
index c4086bb5..f59f5c38 100644
--- a/ingen/shared/URIs.hpp
+++ b/ingen/shared/URIs.hpp
@@ -98,6 +98,7 @@ public:
const Quark lv2_name;
const Quark lv2_portProperty;
const Quark lv2_sampleRate;
+ const Quark lv2_scalePoint;
const Quark lv2_symbol;
const Quark lv2_toggled;
const Quark midi_Bender;
diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp
index 9c5bd2bb..7d5aa993 100644
--- a/src/client/PluginModel.cpp
+++ b/src/client/PluginModel.cpp
@@ -185,6 +185,25 @@ PluginModel::port_human_name(uint32_t i) const
return "";
}
+PluginModel::ScalePoints
+PluginModel::port_scale_points(uint32_t i) const
+{
+ // TODO: Non-float scale points
+ ScalePoints points;
+ if (_lilv_plugin) {
+ const LilvPort* port = lilv_plugin_get_port_by_index(_lilv_plugin, i);
+ LilvScalePoints* sp = lilv_port_get_scale_points(_lilv_plugin, port);
+ LILV_FOREACH(scale_points, i, sp) {
+ const LilvScalePoint* p = lilv_scale_points_get(sp, i);
+ points.push_back(
+ std::make_pair(
+ lilv_node_as_float(lilv_scale_point_get_value(p)),
+ lilv_node_as_string(lilv_scale_point_get_label(p))));
+ }
+ }
+ return points;
+}
+
bool
PluginModel::has_ui() const
{
diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp
index 0a7536a2..e99b0285 100644
--- a/src/gui/Port.cpp
+++ b/src/gui/Port.cpp
@@ -163,6 +163,34 @@ Port::value_changed(const Atom& value)
}
}
+void
+Port::on_scale_point_activated(float f)
+{
+ _app.engine()->set_property(model()->path(),
+ _app.world()->uris()->ingen_value,
+ _app.world()->forge().make(f));
+}
+
+Gtk::Menu*
+Port::build_enum_menu()
+{
+ SharedPtr<const NodeModel> node = PtrCast<NodeModel>(model()->parent());
+ Gtk::Menu* menu = Gtk::manage(new Gtk::Menu());
+
+ PluginModel::ScalePoints points = node->plugin_model()->port_scale_points(
+ model()->index());
+ for (PluginModel::ScalePoints::iterator i = points.begin();
+ i != points.end(); ++i) {
+ menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second));
+ Gtk::MenuItem* menu_item = &(menu->items().back());
+ menu_item->signal_activate().connect(
+ sigc::bind(sigc::mem_fun(this, &Port::on_scale_point_activated),
+ i->first));
+ }
+
+ return menu;
+}
+
bool
Port::on_event(GdkEvent* ev)
{
@@ -182,6 +210,11 @@ Port::on_event(GdkEvent* ev)
break;
case GDK_BUTTON_PRESS:
if (ev->button.button == 1) {
+ if (model()->is_enumeration()) {
+ Gtk::Menu* menu = build_enum_menu();
+ menu->popup(ev->button.button, ev->button.time);
+ return true;
+ }
_pressed = true;
} else if (ev->button.button == 3) {
return show_menu(&ev->button);
diff --git a/src/gui/Port.hpp b/src/gui/Port.hpp
index f0872e39..0e5ad508 100644
--- a/src/gui/Port.hpp
+++ b/src/gui/Port.hpp
@@ -19,6 +19,7 @@
#include <cassert>
#include <string>
+#include <gtkmm/menu.h>
#include "ganv/Port.hpp"
#include "raul/SharedPtr.hpp"
#include "raul/WeakPtr.hpp"
@@ -70,12 +71,14 @@ private:
const std::string& name,
bool flip = false);
+ Gtk::Menu* build_enum_menu();
PatchBox* get_patch_box() const;
void property_changed(const Raul::URI& key, const Raul::Atom& value);
void moved();
void on_value_changed(GVariant* value);
+ void on_scale_point_activated(float f);
bool on_event(GdkEvent* ev);
App& _app;
diff --git a/src/shared/URIs.cpp b/src/shared/URIs.cpp
index b1ecda5f..db5c5bfd 100644
--- a/src/shared/URIs.cpp
+++ b/src/shared/URIs.cpp
@@ -102,6 +102,7 @@ URIs::URIs(Ingen::Forge& f, LV2URIMap* map)
, lv2_name (forge, map, LV2_CORE__name)
, lv2_portProperty (forge, map, LV2_CORE__portProperty)
, lv2_sampleRate (forge, map, LV2_CORE__sampleRate)
+ , lv2_scalePoint (forge, map, LV2_CORE__scalePoint)
, lv2_symbol (forge, map, LV2_CORE__symbol)
, lv2_toggled (forge, map, LV2_CORE__toggled)
, midi_Bender (forge, map, LV2_MIDI__Bender)