aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lv2/core/meta.ttl2
-rw-r--r--lv2/ui/ui.h90
-rw-r--r--lv2/ui/ui.ttl13
-rw-r--r--plugins/eg-sampler.lv2/sampler.ttl1
-rw-r--r--plugins/eg-sampler.lv2/sampler_ui.c34
-rw-r--r--wscript2
6 files changed, 133 insertions, 9 deletions
diff --git a/lv2/core/meta.ttl b/lv2/core/meta.ttl
index 22aa976..836e7db 100644
--- a/lv2/core/meta.ttl
+++ b/lv2/core/meta.ttl
@@ -36,7 +36,7 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
meta:kfoltman ,
meta:paniq ;
doap:release [
- doap:revision "1.17.0" ;
+ doap:revision "1.17.2" ;
doap:created "2019-03-27" ;
dcs:blame <http://drobilla.net/drobilla#me> ;
dcs:changeset [
diff --git a/lv2/ui/ui.h b/lv2/ui/ui.h
index 8e67a36..aba3d5a 100644
--- a/lv2/ui/ui.h
+++ b/lv2/ui/ui.h
@@ -30,6 +30,7 @@
#define LV2_UI_H
#include "lv2/core/lv2.h"
+#include "lv2/urid/urid.h"
#include <stdbool.h>
#include <stdint.h>
@@ -59,6 +60,7 @@
#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification" ///< http://lv2plug.in/ns/extensions/ui#portNotification
#define LV2_UI__portSubscribe LV2_UI_PREFIX "portSubscribe" ///< http://lv2plug.in/ns/extensions/ui#portSubscribe
#define LV2_UI__protocol LV2_UI_PREFIX "protocol" ///< http://lv2plug.in/ns/extensions/ui#protocol
+#define LV2_UI__requestValue LV2_UI_PREFIX "requestValue" ///< http://lv2plug.in/ns/extensions/ui#requestValue
#define LV2_UI__floatProtocol LV2_UI_PREFIX "floatProtocol" ///< http://lv2plug.in/ns/extensions/ui#floatProtocol
#define LV2_UI__peakProtocol LV2_UI_PREFIX "peakProtocol" ///< http://lv2plug.in/ns/extensions/ui#peakProtocol
#define LV2_UI__resize LV2_UI_PREFIX "resize" ///< http://lv2plug.in/ns/extensions/ui#resize
@@ -344,6 +346,94 @@ typedef struct {
} LV2UI_Touch;
/**
+ A status code for LV2UI_Request_Value::request().
+*/
+typedef enum {
+ /**
+ Completed successfully.
+
+ The host will set the parameter later if the user choses a new value.
+ */
+ LV2UI_REQUEST_VALUE_SUCCESS,
+
+ /**
+ Parameter already being requested.
+
+ The host is already requesting a parameter from the user (for example, a
+ dialog is visible), or the UI is otherwise busy and can not make this
+ request.
+ */
+ LV2UI_REQUEST_VALUE_BUSY,
+
+ /**
+ Unknown parameter.
+
+ The host is not aware of this parameter, and is not able to set a new
+ value for it.
+ */
+ LV2UI_REQUEST_VALUE_ERR_UNKNOWN,
+
+ /**
+ Unsupported parameter.
+
+ The host knows about this parameter, but does not support requesting a
+ new value for it from the user. This is likely because the host does
+ not have UI support for choosing a value with the appropriate type.
+ */
+ LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED
+} LV2UI_Request_Value_Status;
+
+/**
+ A feature to request a new parameter value from the host.
+*/
+typedef struct {
+ /**
+ Pointer to opaque data which must be passed to request().
+ */
+ LV2UI_Feature_Handle handle;
+
+ /**
+ Request a value for a parameter from the host.
+
+ This is mainly used by UIs to request values for complex parameters that
+ don't change often, such as file paths, but it may be used to request
+ any parameter value.
+
+ This function returns immediately, and the return value indicates
+ whether the host can fulfill the request. The host may notify the
+ plugin about the new parameter value, for example when a file is
+ selected by the user, via the usual mechanism. Typically, the host will
+ send a message to the plugin that sets the new parameter value, and the
+ plugin will notify the UI via a message as usual for any other parameter
+ change.
+
+ To provide an appropriate UI, the host can determine details about the
+ parameter from the plugin data as usual. The additional parameters of
+ this function provide support for more advanced use cases, but in the
+ simple common case, the plugin will simply pass the key of the desired
+ parameter and zero for everything else.
+
+ @param handle The handle field of this struct.
+
+ @param key The URID of the parameter.
+
+ @param type The optional type of the value to request. This can be used
+ to request a specific value type for parameters that support several.
+ If non-zero, it must be the URID of an instance of rdfs:Class or
+ rdfs:Datatype.
+
+ @param features Additional features for this request, or NULL.
+
+ @return A status code which is 0 on success.
+ */
+ LV2UI_Request_Value_Status (*request)(LV2UI_Feature_Handle handle,
+ LV2_URID key,
+ LV2_URID type,
+ const LV2_Feature* const* features);
+
+} LV2UI_Request_Value;
+
+/**
UI Idle Interface (LV2_UI__idleInterface)
UIs can provide this interface to have an idle() callback called by the host
diff --git a/lv2/ui/ui.ttl b/lv2/ui/ui.ttl
index ecebbf4..387e80e 100644
--- a/lv2/ui/ui.ttl
+++ b/lv2/ui/ui.ttl
@@ -309,6 +309,19 @@ plugin UI. This feature corresponds to the LV2UI_Touch struct, which
should be passed with the URI LV2_UI__touch.</p>
""" .
+ui:requestValue
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature to request a parameter value from the user via the host. This
+allows a plugin UI to request a new parameter value using the host's UI, for
+example by showing a dialog or integrating with the host's built-in content
+browser. This should be used only for complex parameter types where the plugin
+UI is not capable of showing the expected native platform or host interface to
+choose a value, such as file path parameters. This feature corresponds to the
+LV2UI_Request_Value struct, which should be passed with the URI
+LV2_UI__requestValue.</p>
+ """ .
+
ui:idleInterface
a lv2:Feature ,
lv2:ExtensionData ;
diff --git a/plugins/eg-sampler.lv2/sampler.ttl b/plugins/eg-sampler.lv2/sampler.ttl
index 960276a..f5088f3 100644
--- a/plugins/eg-sampler.lv2/sampler.ttl
+++ b/plugins/eg-sampler.lv2/sampler.ttl
@@ -64,6 +64,7 @@
<http://lv2plug.in/plugins/eg-sampler#ui>
a ui:GtkUI ;
lv2:requiredFeature urid:map ;
+ lv2:optionalFeature ui:requestValue ;
lv2:extensionData ui:showInterface ;
ui:portNotification [
ui:plugin <http://lv2plug.in/plugins/eg-sampler> ;
diff --git a/plugins/eg-sampler.lv2/sampler_ui.c b/plugins/eg-sampler.lv2/sampler_ui.c
index 89bca2f..1cb7553 100644
--- a/plugins/eg-sampler.lv2/sampler_ui.c
+++ b/plugins/eg-sampler.lv2/sampler_ui.c
@@ -47,11 +47,12 @@
#define MIN_CANVAS_H 80
typedef struct {
- LV2_Atom_Forge forge;
- LV2_URID_Map* map;
- LV2_Log_Logger logger;
- SamplerURIs uris;
- PeaksReceiver precv;
+ LV2_Atom_Forge forge;
+ LV2_URID_Map* map;
+ LV2UI_Request_Value* request_value;
+ LV2_Log_Logger logger;
+ SamplerURIs uris;
+ PeaksReceiver precv;
LV2UI_Write_Function write;
LV2UI_Controller controller;
@@ -59,6 +60,7 @@ typedef struct {
GtkWidget* box;
GtkWidget* play_button;
GtkWidget* file_button;
+ GtkWidget* request_file_button;
GtkWidget* button_box;
GtkWidget* canvas;
GtkWidget* window; /* For optional show interface. */
@@ -91,6 +93,17 @@ on_file_set(GtkFileChooserButton* widget, void* handle)
}
static void
+on_request_file(GtkButton* widget, void* handle)
+{
+ SamplerUI* ui = (SamplerUI*)handle;
+
+ ui->request_value->request(ui->request_value->handle,
+ ui->uris.eg_sample,
+ 0,
+ NULL);
+}
+
+static void
on_play_clicked(GtkFileChooserButton* widget, void* handle)
{
SamplerUI* ui = (SamplerUI*)handle;
@@ -220,8 +233,9 @@ instantiate(const LV2UI_Descriptor* descriptor,
// Get host features
const char* missing = lv2_features_query(
features,
- LV2_LOG__log, &ui->logger.log, false,
- LV2_URID__map, &ui->map, true,
+ LV2_LOG__log, &ui->logger.log , false,
+ LV2_URID__map, &ui->map, true,
+ LV2_UI__requestValue, &ui->request_value, false,
NULL);
lv2_log_logger_set_map(&ui->logger, ui->map);
if (missing) {
@@ -242,16 +256,21 @@ instantiate(const LV2UI_Descriptor* descriptor,
ui->button_box = gtk_hbox_new(FALSE, 4);
ui->file_button = gtk_file_chooser_button_new(
"Load Sample", GTK_FILE_CHOOSER_ACTION_OPEN);
+ ui->request_file_button = gtk_button_new_with_label("Request Sample");
gtk_widget_set_size_request(ui->canvas, MIN_CANVAS_W, MIN_CANVAS_H);
gtk_container_set_border_width(GTK_CONTAINER(ui->box), 4);
gtk_box_pack_start(GTK_BOX(ui->box), ui->canvas, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(ui->box), ui->button_box, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(ui->button_box), ui->play_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ui->button_box), ui->request_file_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(ui->button_box), ui->file_button, TRUE, TRUE, 0);
g_signal_connect(ui->file_button, "file-set",
G_CALLBACK(on_file_set), ui);
+ g_signal_connect(ui->request_file_button, "clicked",
+ G_CALLBACK(on_request_file), ui);
+
g_signal_connect(ui->play_button, "clicked",
G_CALLBACK(on_play_clicked), ui);
@@ -283,6 +302,7 @@ cleanup(LV2UI_Handle handle)
gtk_widget_destroy(ui->canvas);
gtk_widget_destroy(ui->button_box);
gtk_widget_destroy(ui->file_button);
+ gtk_widget_destroy(ui->request_file_button);
free(ui);
}
diff --git a/wscript b/wscript
index 9dcfbe1..b30239a 100644
--- a/wscript
+++ b/wscript
@@ -9,7 +9,7 @@ from waflib.extras import autowaf as autowaf
# Mandatory waf variables
APPNAME = 'lv2' # Package name for waf dist
-VERSION = '1.17.0' # Package version for waf dist
+VERSION = '1.17.2' # Package version for waf dist
top = '.' # Source directory
out = 'build' # Build directory