Browse Source

Add a UI feature to request a parameter value from the host

zrythm_meson
David Robillard 4 years ago
parent
commit
c11adc705f
  1. 2
      lv2/core/meta.ttl
  2. 9
      lv2/ui/lv2-ui.doap.ttl
  3. 2
      lv2/ui/manifest.ttl
  4. 90
      lv2/ui/ui.h
  5. 13
      lv2/ui/ui.ttl
  6. 1
      plugins/eg-sampler.lv2/sampler.ttl
  7. 34
      plugins/eg-sampler.lv2/sampler_ui.c
  8. 2
      wscript

2
lv2/core/meta.ttl

@ -36,7 +36,7 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R @@ -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 [

9
lv2/ui/lv2-ui.doap.ttl

@ -12,6 +12,15 @@ @@ -12,6 +12,15 @@
doap:developer <http://lv2plug.in/ns/meta#larsl> ;
doap:maintainer <http://drobilla.net/drobilla#me> ;
doap:release [
doap:revision "2.21" ;
doap:created "2020-03-17" ;
dcs:blame <http://drobilla.net/drobilla#me> ;
dcs:changeset [
dcs:item [
rdfs:label "Add ui:requestValue feature."
]
]
] , [
doap:revision "2.20" ;
doap:created "2015-07-25" ;
doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;

2
lv2/ui/manifest.ttl

@ -4,6 +4,6 @@ @@ -4,6 +4,6 @@
<http://lv2plug.in/ns/extensions/ui>
a lv2:Specification ;
lv2:minorVersion 2 ;
lv2:microVersion 20 ;
lv2:microVersion 21 ;
rdfs:seeAlso <ui.ttl> .

90
lv2/ui/ui.h

@ -30,6 +30,7 @@ @@ -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 @@ @@ -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
@ -343,6 +345,94 @@ typedef struct { @@ -343,6 +345,94 @@ typedef struct {
bool grabbed);
} 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)

13
lv2/ui/ui.ttl

@ -309,6 +309,19 @@ plugin UI. This feature corresponds to the LV2UI_Touch struct, which @@ -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 only be used 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 ;

1
plugins/eg-sampler.lv2/sampler.ttl

@ -64,6 +64,7 @@ @@ -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> ;

34
plugins/eg-sampler.lv2/sampler_ui.c

@ -47,11 +47,12 @@ @@ -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 { @@ -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. */
@ -90,6 +92,17 @@ on_file_set(GtkFileChooserButton* widget, void* handle) @@ -90,6 +92,17 @@ on_file_set(GtkFileChooserButton* widget, void* handle)
g_free(filename);
}
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)
{
@ -220,8 +233,9 @@ instantiate(const LV2UI_Descriptor* descriptor, @@ -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, @@ -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) @@ -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);
}

2
wscript

@ -9,7 +9,7 @@ from waflib.extras import autowaf as autowaf @@ -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

Loading…
Cancel
Save