aboutsummaryrefslogtreecommitdiffstats
path: root/src/jalv_gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jalv_gtk.c')
-rw-r--r--src/jalv_gtk.c1944
1 files changed, 1023 insertions, 921 deletions
diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c
index f909425..33b4b48 100644
--- a/src/jalv_gtk.c
+++ b/src/jalv_gtk.c
@@ -49,268 +49,347 @@ static bool updating = false;
/** Widget for a control. */
typedef struct {
- GtkSpinButton* spin;
- GtkWidget* control;
+ GtkSpinButton* spin;
+ GtkWidget* control;
} Controller;
static float
get_float(const LilvNode* node, float fallback)
{
- if (lilv_node_is_float(node) || lilv_node_is_int(node)) {
- return lilv_node_as_float(node);
- }
+ if (lilv_node_is_float(node) || lilv_node_is_int(node)) {
+ return lilv_node_as_float(node);
+ }
- return fallback;
+ return fallback;
}
static GtkWidget*
new_box(gboolean horizontal, gint spacing)
{
- #if GTK_MAJOR_VERSION == 3
- return gtk_box_new(
- horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
- spacing);
- #else
- return (horizontal
- ? gtk_hbox_new(FALSE, spacing)
- : gtk_vbox_new(FALSE, spacing));
- #endif
+#if GTK_MAJOR_VERSION == 3
+ return gtk_box_new(horizontal ? GTK_ORIENTATION_HORIZONTAL
+ : GTK_ORIENTATION_VERTICAL,
+ spacing);
+#else
+ return (horizontal ? gtk_hbox_new(FALSE, spacing)
+ : gtk_vbox_new(FALSE, spacing));
+#endif
}
static GtkWidget*
new_hscale(gdouble min, gdouble max, gdouble step)
{
- #if GTK_MAJOR_VERSION == 3
- return gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step);
- #else
- return gtk_hscale_new_with_range(min, max, step);
- #endif
+#if GTK_MAJOR_VERSION == 3
+ return gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, step);
+#else
+ return gtk_hscale_new_with_range(min, max, step);
+#endif
}
static void
size_request(GtkWidget* widget, GtkRequisition* req)
{
- #if GTK_MAJOR_VERSION == 3
- gtk_widget_get_preferred_size(widget, NULL, req);
- #else
- gtk_widget_size_request(widget, req);
- #endif
+#if GTK_MAJOR_VERSION == 3
+ gtk_widget_get_preferred_size(widget, NULL, req);
+#else
+ gtk_widget_size_request(widget, req);
+#endif
}
static void
on_window_destroy(GtkWidget* ZIX_UNUSED(widget), gpointer ZIX_UNUSED(data))
{
- gtk_main_quit();
+ gtk_main_quit();
}
int
jalv_init(int* argc, char*** argv, JalvOptions* opts)
{
- GOptionEntry entries[] = {
- { "load", 'l', 0, G_OPTION_ARG_STRING, &opts->load,
- "Load state from save directory", "DIR" },
- { "preset", 'p', 0, G_OPTION_ARG_STRING, &opts->preset,
- "Load state from preset", "URI" },
- { "dump", 'd', 0, G_OPTION_ARG_NONE, &opts->dump,
- "Dump plugin <=> UI communication", NULL },
- { "ui-uri", 'U', 0, G_OPTION_ARG_STRING, &opts->ui_uri,
- "Load the UI with the given URI", "URI" },
- { "trace", 't', 0, G_OPTION_ARG_NONE, &opts->trace,
- "Print trace messages from plugin", NULL },
- { "show-hidden", 's', 0, G_OPTION_ARG_NONE, &opts->show_hidden,
- "Show controls for ports with notOnGUI property on generic UI", NULL },
- { "no-menu", 'n', 0, G_OPTION_ARG_NONE, &opts->no_menu,
- "Do not show Jalv menu on window", NULL },
- { "generic-ui", 'g', 0, G_OPTION_ARG_NONE, &opts->generic_ui,
- "Use Jalv generic UI and not the plugin UI", NULL},
- { "buffer-size", 'b', 0, G_OPTION_ARG_INT, &opts->buffer_size,
- "Buffer size for plugin <=> UI communication", "SIZE"},
- { "update-frequency", 'r', 0, G_OPTION_ARG_DOUBLE, &opts->update_rate,
- "UI update frequency", NULL},
- { "scale-factor", 0, 0, G_OPTION_ARG_DOUBLE, &opts->scale_factor,
- "UI scale factor", NULL},
- { "control", 'c', 0, G_OPTION_ARG_STRING_ARRAY, &opts->controls,
- "Set control value (e.g. \"vol=1.4\")", NULL},
- { "print-controls", 'p', 0, G_OPTION_ARG_NONE, &opts->print_controls,
- "Print control output changes to stdout", NULL},
- { "jack-name", 'n', 0, G_OPTION_ARG_STRING, &opts->name,
- "JACK client name", NULL},
- { "exact-jack-name", 'x', 0, G_OPTION_ARG_NONE, &opts->name_exact,
- "Exact JACK client name (exit if taken)", NULL },
- { 0, 0, 0, G_OPTION_ARG_NONE, 0, 0, 0 } };
- GError* error = NULL;
- const int err = gtk_init_with_args(
- argc, argv,
- "PLUGIN_URI - Run an LV2 plugin as a Jack application",
- entries, NULL, &error);
-
- if (!err) {
- fprintf(stderr, "%s\n", error->message);
- }
-
- return !err;
+ GOptionEntry entries[] = {
+ {"load",
+ 'l',
+ 0,
+ G_OPTION_ARG_STRING,
+ &opts->load,
+ "Load state from save directory",
+ "DIR"},
+ {"preset",
+ 'p',
+ 0,
+ G_OPTION_ARG_STRING,
+ &opts->preset,
+ "Load state from preset",
+ "URI"},
+ {"dump",
+ 'd',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->dump,
+ "Dump plugin <=> UI communication",
+ NULL},
+ {"ui-uri",
+ 'U',
+ 0,
+ G_OPTION_ARG_STRING,
+ &opts->ui_uri,
+ "Load the UI with the given URI",
+ "URI"},
+ {"trace",
+ 't',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->trace,
+ "Print trace messages from plugin",
+ NULL},
+ {"show-hidden",
+ 's',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->show_hidden,
+ "Show controls for ports with notOnGUI property on generic UI",
+ NULL},
+ {"no-menu",
+ 'n',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->no_menu,
+ "Do not show Jalv menu on window",
+ NULL},
+ {"generic-ui",
+ 'g',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->generic_ui,
+ "Use Jalv generic UI and not the plugin UI",
+ NULL},
+ {"buffer-size",
+ 'b',
+ 0,
+ G_OPTION_ARG_INT,
+ &opts->buffer_size,
+ "Buffer size for plugin <=> UI communication",
+ "SIZE"},
+ {"update-frequency",
+ 'r',
+ 0,
+ G_OPTION_ARG_DOUBLE,
+ &opts->update_rate,
+ "UI update frequency",
+ NULL},
+ {"scale-factor",
+ 0,
+ 0,
+ G_OPTION_ARG_DOUBLE,
+ &opts->scale_factor,
+ "UI scale factor",
+ NULL},
+ {"control",
+ 'c',
+ 0,
+ G_OPTION_ARG_STRING_ARRAY,
+ &opts->controls,
+ "Set control value (e.g. \"vol=1.4\")",
+ NULL},
+ {"print-controls",
+ 'p',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->print_controls,
+ "Print control output changes to stdout",
+ NULL},
+ {"jack-name",
+ 'n',
+ 0,
+ G_OPTION_ARG_STRING,
+ &opts->name,
+ "JACK client name",
+ NULL},
+ {"exact-jack-name",
+ 'x',
+ 0,
+ G_OPTION_ARG_NONE,
+ &opts->name_exact,
+ "Exact JACK client name (exit if taken)",
+ NULL},
+ {0, 0, 0, G_OPTION_ARG_NONE, 0, 0, 0}};
+ GError* error = NULL;
+ const int err =
+ gtk_init_with_args(argc,
+ argv,
+ "PLUGIN_URI - Run an LV2 plugin as a Jack application",
+ entries,
+ NULL,
+ &error);
+
+ if (!err) {
+ fprintf(stderr, "%s\n", error->message);
+ }
+
+ return !err;
}
const char*
jalv_native_ui_type(void)
{
#if GTK_MAJOR_VERSION == 2
- return "http://lv2plug.in/ns/extensions/ui#GtkUI";
+ return "http://lv2plug.in/ns/extensions/ui#GtkUI";
#elif GTK_MAJOR_VERSION == 3
- return "http://lv2plug.in/ns/extensions/ui#Gtk3UI";
+ return "http://lv2plug.in/ns/extensions/ui#Gtk3UI";
#else
- return NULL;
+ return NULL;
#endif
}
static void
on_save_activate(GtkWidget* ZIX_UNUSED(widget), void* ptr)
{
- Jalv* jalv = (Jalv*)ptr;
- GtkWidget* dialog = gtk_file_chooser_dialog_new(
- "Save State",
- (GtkWindow*)jalv->window,
- GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
- "_Cancel", GTK_RESPONSE_CANCEL,
- "_Save", GTK_RESPONSE_ACCEPT,
- NULL);
-
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- char* base = g_build_filename(path, "/", NULL);
- jalv_save(jalv, base);
- g_free(path);
- g_free(base);
- }
-
- gtk_widget_destroy(dialog);
+ Jalv* jalv = (Jalv*)ptr;
+ GtkWidget* dialog =
+ gtk_file_chooser_dialog_new("Save State",
+ (GtkWindow*)jalv->window,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+ "_Cancel",
+ GTK_RESPONSE_CANCEL,
+ "_Save",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ char* base = g_build_filename(path, "/", NULL);
+ jalv_save(jalv, base);
+ g_free(path);
+ g_free(base);
+ }
+
+ gtk_widget_destroy(dialog);
}
static void
on_quit_activate(GtkWidget* ZIX_UNUSED(widget), gpointer data)
{
- GtkWidget* window = (GtkWidget*)data;
- gtk_widget_destroy(window);
+ GtkWidget* window = (GtkWidget*)data;
+ gtk_widget_destroy(window);
}
typedef struct {
- Jalv* jalv;
- LilvNode* preset;
+ Jalv* jalv;
+ LilvNode* preset;
} PresetRecord;
static char*
symbolify(const char* in)
{
- const size_t len = strlen(in);
- char* out = (char*)calloc(len + 1, 1);
- for (size_t i = 0; i < len; ++i) {
- if (g_ascii_isalnum(in[i])) {
- out[i] = in[i];
- } else {
- out[i] = '_';
- }
- }
- return out;
+ const size_t len = strlen(in);
+ char* out = (char*)calloc(len + 1, 1);
+ for (size_t i = 0; i < len; ++i) {
+ if (g_ascii_isalnum(in[i])) {
+ out[i] = in[i];
+ } else {
+ out[i] = '_';
+ }
+ }
+ return out;
}
static void
set_window_title(Jalv* jalv)
{
- LilvNode* name = lilv_plugin_get_name(jalv->plugin);
- const char* plugin = lilv_node_as_string(name);
- if (jalv->preset) {
- const char* preset_label = lilv_state_get_label(jalv->preset);
- char* title = g_strdup_printf("%s - %s", plugin, preset_label);
- gtk_window_set_title(GTK_WINDOW(jalv->window), title);
- free(title);
- } else {
- gtk_window_set_title(GTK_WINDOW(jalv->window), plugin);
- }
- lilv_node_free(name);
+ LilvNode* name = lilv_plugin_get_name(jalv->plugin);
+ const char* plugin = lilv_node_as_string(name);
+ if (jalv->preset) {
+ const char* preset_label = lilv_state_get_label(jalv->preset);
+ char* title = g_strdup_printf("%s - %s", plugin, preset_label);
+ gtk_window_set_title(GTK_WINDOW(jalv->window), title);
+ free(title);
+ } else {
+ gtk_window_set_title(GTK_WINDOW(jalv->window), plugin);
+ }
+ lilv_node_free(name);
}
static void
on_preset_activate(GtkWidget* widget, gpointer data)
{
- if (GTK_CHECK_MENU_ITEM(widget) != active_preset_item) {
- PresetRecord* record = (PresetRecord*)data;
- jalv_apply_preset(record->jalv, record->preset);
- if (active_preset_item) {
- gtk_check_menu_item_set_active(active_preset_item, FALSE);
- }
-
- active_preset_item = GTK_CHECK_MENU_ITEM(widget);
- gtk_check_menu_item_set_active(active_preset_item, TRUE);
- set_window_title(record->jalv);
- }
+ if (GTK_CHECK_MENU_ITEM(widget) != active_preset_item) {
+ PresetRecord* record = (PresetRecord*)data;
+ jalv_apply_preset(record->jalv, record->preset);
+ if (active_preset_item) {
+ gtk_check_menu_item_set_active(active_preset_item, FALSE);
+ }
+
+ active_preset_item = GTK_CHECK_MENU_ITEM(widget);
+ gtk_check_menu_item_set_active(active_preset_item, TRUE);
+ set_window_title(record->jalv);
+ }
}
static void
on_preset_destroy(gpointer data, GClosure* ZIX_UNUSED(closure))
{
- PresetRecord* record = (PresetRecord*)data;
- lilv_node_free(record->preset);
- free(record);
+ PresetRecord* record = (PresetRecord*)data;
+ lilv_node_free(record->preset);
+ free(record);
}
typedef struct {
- GtkMenuItem* item;
- char* label;
- GtkMenu* menu;
- GSequence* banks;
+ GtkMenuItem* item;
+ char* label;
+ GtkMenu* menu;
+ GSequence* banks;
} PresetMenu;
static PresetMenu*
pset_menu_new(const char* label)
{
- PresetMenu* menu = (PresetMenu*)malloc(sizeof(PresetMenu));
- menu->label = g_strdup(label);
- menu->item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(menu->label));
- menu->menu = GTK_MENU(gtk_menu_new());
- menu->banks = NULL;
- return menu;
+ PresetMenu* menu = (PresetMenu*)malloc(sizeof(PresetMenu));
+ menu->label = g_strdup(label);
+ menu->item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(menu->label));
+ menu->menu = GTK_MENU(gtk_menu_new());
+ menu->banks = NULL;
+ return menu;
}
static void
pset_menu_free(PresetMenu* menu)
{
- if (menu->banks) {
- for (GSequenceIter* i = g_sequence_get_begin_iter(menu->banks);
- !g_sequence_iter_is_end(i);
- i = g_sequence_iter_next(i)) {
- PresetMenu* bank_menu = (PresetMenu*)g_sequence_get(i);
- pset_menu_free(bank_menu);
- }
- g_sequence_free(menu->banks);
- }
-
- free(menu->label);
- free(menu);
+ if (menu->banks) {
+ for (GSequenceIter* i = g_sequence_get_begin_iter(menu->banks);
+ !g_sequence_iter_is_end(i);
+ i = g_sequence_iter_next(i)) {
+ PresetMenu* bank_menu = (PresetMenu*)g_sequence_get(i);
+ pset_menu_free(bank_menu);
+ }
+ g_sequence_free(menu->banks);
+ }
+
+ free(menu->label);
+ free(menu);
}
static gint
menu_cmp(gconstpointer a, gconstpointer b, gpointer ZIX_UNUSED(data))
{
- return strcmp(((const PresetMenu*)a)->label, ((const PresetMenu*)b)->label);
+ return strcmp(((const PresetMenu*)a)->label, ((const PresetMenu*)b)->label);
}
static PresetMenu*
get_bank_menu(Jalv* jalv, PresetMenu* menu, const LilvNode* bank)
{
- LilvNode* label = lilv_world_get(
- jalv->world, bank, jalv->nodes.rdfs_label, NULL);
-
- const char* uri = lilv_node_as_string(bank);
- const char* str = label ? lilv_node_as_string(label) : uri;
- PresetMenu key = { NULL, (char*)str, NULL, NULL };
- GSequenceIter* i = g_sequence_lookup(menu->banks, &key, menu_cmp, NULL);
- if (!i) {
- PresetMenu* bank_menu = pset_menu_new(str);
- gtk_menu_item_set_submenu(bank_menu->item, GTK_WIDGET(bank_menu->menu));
- g_sequence_insert_sorted(menu->banks, bank_menu, menu_cmp, NULL);
- return bank_menu;
- }
- return (PresetMenu*)g_sequence_get(i);
+ LilvNode* label =
+ lilv_world_get(jalv->world, bank, jalv->nodes.rdfs_label, NULL);
+
+ const char* uri = lilv_node_as_string(bank);
+ const char* str = label ? lilv_node_as_string(label) : uri;
+ PresetMenu key = {NULL, (char*)str, NULL, NULL};
+ GSequenceIter* i = g_sequence_lookup(menu->banks, &key, menu_cmp, NULL);
+ if (!i) {
+ PresetMenu* bank_menu = pset_menu_new(str);
+ gtk_menu_item_set_submenu(bank_menu->item, GTK_WIDGET(bank_menu->menu));
+ g_sequence_insert_sorted(menu->banks, bank_menu, menu_cmp, NULL);
+ return bank_menu;
+ }
+ return (PresetMenu*)g_sequence_get(i);
}
static int
@@ -319,185 +398,190 @@ add_preset_to_menu(Jalv* jalv,
const LilvNode* title,
void* data)
{
- PresetMenu* menu = (PresetMenu*)data;
- const char* label = lilv_node_as_string(title);
- GtkWidget* item = gtk_check_menu_item_new_with_label(label);
- gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), TRUE);
- if (jalv->preset &&
- lilv_node_equals(lilv_state_get_uri(jalv->preset), node)) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
- active_preset_item = GTK_CHECK_MENU_ITEM(item);
- }
-
- LilvNode* bank = lilv_world_get(
- jalv->world, node, jalv->nodes.pset_bank, NULL);
-
- if (bank) {
- PresetMenu* bank_menu = get_bank_menu(jalv, menu, bank);
- gtk_menu_shell_append(GTK_MENU_SHELL(bank_menu->menu), item);
- } else {
- gtk_menu_shell_append(GTK_MENU_SHELL(menu->menu), item);
- }
-
- PresetRecord* record = (PresetRecord*)malloc(sizeof(PresetRecord));
- record->jalv = jalv;
- record->preset = lilv_node_duplicate(node);
-
- g_signal_connect_data(G_OBJECT(item), "activate",
- G_CALLBACK(on_preset_activate),
- record, on_preset_destroy,
- (GConnectFlags)0);
-
- return 0;
+ PresetMenu* menu = (PresetMenu*)data;
+ const char* label = lilv_node_as_string(title);
+ GtkWidget* item = gtk_check_menu_item_new_with_label(label);
+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), TRUE);
+ if (jalv->preset &&
+ lilv_node_equals(lilv_state_get_uri(jalv->preset), node)) {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
+ active_preset_item = GTK_CHECK_MENU_ITEM(item);
+ }
+
+ LilvNode* bank =
+ lilv_world_get(jalv->world, node, jalv->nodes.pset_bank, NULL);
+
+ if (bank) {
+ PresetMenu* bank_menu = get_bank_menu(jalv, menu, bank);
+ gtk_menu_shell_append(GTK_MENU_SHELL(bank_menu->menu), item);
+ } else {
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu->menu), item);
+ }
+
+ PresetRecord* record = (PresetRecord*)malloc(sizeof(PresetRecord));
+ record->jalv = jalv;
+ record->preset = lilv_node_duplicate(node);
+
+ g_signal_connect_data(G_OBJECT(item),
+ "activate",
+ G_CALLBACK(on_preset_activate),
+ record,
+ on_preset_destroy,
+ (GConnectFlags)0);
+
+ return 0;
}
static void
finish_menu(PresetMenu* menu)
{
- for (GSequenceIter* i = g_sequence_get_begin_iter(menu->banks);
- !g_sequence_iter_is_end(i);
- i = g_sequence_iter_next(i)) {
- PresetMenu* bank_menu = (PresetMenu*)g_sequence_get(i);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu->menu),
- GTK_WIDGET(bank_menu->item));
- }
- g_sequence_free(menu->banks);
+ for (GSequenceIter* i = g_sequence_get_begin_iter(menu->banks);
+ !g_sequence_iter_is_end(i);
+ i = g_sequence_iter_next(i)) {
+ PresetMenu* bank_menu = (PresetMenu*)g_sequence_get(i);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu->menu),
+ GTK_WIDGET(bank_menu->item));
+ }
+ g_sequence_free(menu->banks);
}
static void
rebuild_preset_menu(Jalv* jalv, GtkContainer* pset_menu)
{
- // Clear current menu
- active_preset_item = NULL;
- for (GList* items = g_list_nth(gtk_container_get_children(pset_menu), 3);
- items;
- items = items->next) {
- gtk_container_remove(pset_menu, GTK_WIDGET(items->data));
- }
-
- // Load presets and build new menu
- PresetMenu menu = {
- NULL, NULL, GTK_MENU(pset_menu),
- g_sequence_new((GDestroyNotify)pset_menu_free)
- };
- jalv_load_presets(jalv, add_preset_to_menu, &menu);
- finish_menu(&menu);
- gtk_widget_show_all(GTK_WIDGET(pset_menu));
+ // Clear current menu
+ active_preset_item = NULL;
+ for (GList* items = g_list_nth(gtk_container_get_children(pset_menu), 3);
+ items;
+ items = items->next) {
+ gtk_container_remove(pset_menu, GTK_WIDGET(items->data));
+ }
+
+ // Load presets and build new menu
+ PresetMenu menu = {NULL,
+ NULL,
+ GTK_MENU(pset_menu),
+ g_sequence_new((GDestroyNotify)pset_menu_free)};
+ jalv_load_presets(jalv, add_preset_to_menu, &menu);
+ finish_menu(&menu);
+ gtk_widget_show_all(GTK_WIDGET(pset_menu));
}
static void
on_save_preset_activate(GtkWidget* widget, void* ptr)
{
- Jalv* jalv = (Jalv*)ptr;
-
- GtkWidget* dialog = gtk_file_chooser_dialog_new(
- "Save Preset",
- (GtkWindow*)jalv->window,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- "_Cancel", GTK_RESPONSE_REJECT,
- "_Save", GTK_RESPONSE_ACCEPT,
- NULL);
-
- char* dot_lv2 = g_build_filename(g_get_home_dir(), ".lv2", NULL);
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dot_lv2);
- free(dot_lv2);
-
- GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkBox* box = GTK_BOX(new_box(true, 8));
- GtkWidget* uri_label = gtk_label_new("URI (Optional):");
- GtkWidget* uri_entry = gtk_entry_new();
- GtkWidget* add_prefix = gtk_check_button_new_with_mnemonic(
- "_Prefix plugin name");
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(add_prefix), TRUE);
- gtk_box_pack_start(box, uri_label, FALSE, TRUE, 2);
- gtk_box_pack_start(box, uri_entry, TRUE, TRUE, 2);
- gtk_box_pack_start(GTK_BOX(content), GTK_WIDGET(box), FALSE, FALSE, 6);
- gtk_box_pack_start(GTK_BOX(content), add_prefix, FALSE, FALSE, 6);
-
- gtk_widget_show_all(GTK_WIDGET(dialog));
- gtk_entry_set_activates_default(GTK_ENTRY(uri_entry), TRUE);
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- LilvNode* plug_name = lilv_plugin_get_name(jalv->plugin);
- const char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- const char* uri = gtk_entry_get_text(GTK_ENTRY(uri_entry));
- const char* prefix = "";
- const char* sep = "";
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(add_prefix))) {
- prefix = lilv_node_as_string(plug_name);
- sep = "_";
- }
-
- char* dirname = g_path_get_dirname(path);
- char* basename = g_path_get_basename(path);
- char* sym = symbolify(basename);
- char* sprefix = symbolify(prefix);
- char* bundle = g_strjoin(NULL, sprefix, sep, sym, ".preset.lv2/", NULL);
- char* file = g_strjoin(NULL, sym, ".ttl", NULL);
- char* dir = g_build_filename(dirname, bundle, NULL);
-
- jalv_save_preset(jalv, dir, (strlen(uri) ? uri : NULL), basename, file);
-
- // Reload bundle into the world
- LilvNode* ldir = lilv_new_file_uri(jalv->world, NULL, dir);
- lilv_world_unload_bundle(jalv->world, ldir);
- lilv_world_load_bundle(jalv->world, ldir);
- lilv_node_free(ldir);
-
- // Rebuild preset menu and update window title
- rebuild_preset_menu(jalv, GTK_CONTAINER(gtk_widget_get_parent(widget)));
- set_window_title(jalv);
-
- g_free(dir);
- g_free(file);
- g_free(bundle);
- free(sprefix);
- free(sym);
- g_free(basename);
- g_free(dirname);
- lilv_node_free(plug_name);
- }
-
- gtk_widget_destroy(GTK_WIDGET(dialog));
+ Jalv* jalv = (Jalv*)ptr;
+
+ GtkWidget* dialog = gtk_file_chooser_dialog_new("Save Preset",
+ (GtkWindow*)jalv->window,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ "_Cancel",
+ GTK_RESPONSE_REJECT,
+ "_Save",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ char* dot_lv2 = g_build_filename(g_get_home_dir(), ".lv2", NULL);
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dot_lv2);
+ free(dot_lv2);
+
+ GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ GtkBox* box = GTK_BOX(new_box(true, 8));
+ GtkWidget* uri_label = gtk_label_new("URI (Optional):");
+ GtkWidget* uri_entry = gtk_entry_new();
+ GtkWidget* add_prefix =
+ gtk_check_button_new_with_mnemonic("_Prefix plugin name");
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(add_prefix), TRUE);
+ gtk_box_pack_start(box, uri_label, FALSE, TRUE, 2);
+ gtk_box_pack_start(box, uri_entry, TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(content), GTK_WIDGET(box), FALSE, FALSE, 6);
+ gtk_box_pack_start(GTK_BOX(content), add_prefix, FALSE, FALSE, 6);
+
+ gtk_widget_show_all(GTK_WIDGET(dialog));
+ gtk_entry_set_activates_default(GTK_ENTRY(uri_entry), TRUE);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ LilvNode* plug_name = lilv_plugin_get_name(jalv->plugin);
+ const char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ const char* uri = gtk_entry_get_text(GTK_ENTRY(uri_entry));
+ const char* prefix = "";
+ const char* sep = "";
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(add_prefix))) {
+ prefix = lilv_node_as_string(plug_name);
+ sep = "_";
+ }
+
+ char* dirname = g_path_get_dirname(path);
+ char* basename = g_path_get_basename(path);
+ char* sym = symbolify(basename);
+ char* sprefix = symbolify(prefix);
+ char* bundle = g_strjoin(NULL, sprefix, sep, sym, ".preset.lv2/", NULL);
+ char* file = g_strjoin(NULL, sym, ".ttl", NULL);
+ char* dir = g_build_filename(dirname, bundle, NULL);
+
+ jalv_save_preset(jalv, dir, (strlen(uri) ? uri : NULL), basename, file);
+
+ // Reload bundle into the world
+ LilvNode* ldir = lilv_new_file_uri(jalv->world, NULL, dir);
+ lilv_world_unload_bundle(jalv->world, ldir);
+ lilv_world_load_bundle(jalv->world, ldir);
+ lilv_node_free(ldir);
+
+ // Rebuild preset menu and update window title
+ rebuild_preset_menu(jalv, GTK_CONTAINER(gtk_widget_get_parent(widget)));
+ set_window_title(jalv);
+
+ g_free(dir);
+ g_free(file);
+ g_free(bundle);
+ free(sprefix);
+ free(sym);
+ g_free(basename);
+ g_free(dirname);
+ lilv_node_free(plug_name);
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
}
static void
on_delete_preset_activate(GtkWidget* widget, void* ptr)
{
- Jalv* jalv = (Jalv*)ptr;
- if (!jalv->preset) {
- return;
- }
-
- GtkWidget* dialog = gtk_dialog_new_with_buttons(
- "Delete Preset?",
- (GtkWindow*)jalv->window,
- (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
- "_Cancel", GTK_RESPONSE_REJECT,
- "_OK", GTK_RESPONSE_ACCEPT,
- NULL);
-
- char* msg = g_strdup_printf("Delete preset \"%s\" from the file system?",
- lilv_state_get_label(jalv->preset));
-
- GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget* text = gtk_label_new(msg);
- gtk_box_pack_start(GTK_BOX(content), text, TRUE, TRUE, 4);
-
- gtk_widget_show_all(dialog);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- jalv_delete_current_preset(jalv);
- rebuild_preset_menu(jalv, GTK_CONTAINER(gtk_widget_get_parent(widget)));
- }
-
- lilv_state_free(jalv->preset);
- jalv->preset = NULL;
- set_window_title(jalv);
-
- g_free(msg);
- gtk_widget_destroy(text);
- gtk_widget_destroy(dialog);
+ Jalv* jalv = (Jalv*)ptr;
+ if (!jalv->preset) {
+ return;
+ }
+
+ GtkWidget* dialog = gtk_dialog_new_with_buttons(
+ "Delete Preset?",
+ (GtkWindow*)jalv->window,
+ (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+ "_Cancel",
+ GTK_RESPONSE_REJECT,
+ "_OK",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ char* msg = g_strdup_printf("Delete preset \"%s\" from the file system?",
+ lilv_state_get_label(jalv->preset));
+
+ GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ GtkWidget* text = gtk_label_new(msg);
+ gtk_box_pack_start(GTK_BOX(content), text, TRUE, TRUE, 4);
+
+ gtk_widget_show_all(dialog);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ jalv_delete_current_preset(jalv);
+ rebuild_preset_menu(jalv, GTK_CONTAINER(gtk_widget_get_parent(widget)));
+ }
+
+ lilv_state_free(jalv->preset);
+ jalv->preset = NULL;
+ set_window_title(jalv);
+
+ g_free(msg);
+ gtk_widget_destroy(text);
+ gtk_widget_destroy(dialog);
}
static void
@@ -506,41 +590,41 @@ set_control(const ControlID* control,
LV2_URID type,
const void* body)
{
- if (!updating) {
- jalv_set_control(control, size, type, body);
- }
+ if (!updating) {
+ jalv_set_control(control, size, type, body);
+ }
}
static bool
differ_enough(float a, float b)
{
- return fabsf(a - b) >= FLT_EPSILON;
+ return fabsf(a - b) >= FLT_EPSILON;
}
static void
set_float_control(const ControlID* control, float value)
{
- if (control->value_type == control->jalv->forge.Int) {
- const int32_t ival = lrintf(value);
- set_control(control, sizeof(ival), control->jalv->forge.Int, &ival);
- } else if (control->value_type == control->jalv->forge.Long) {
- const int64_t lval = lrintf(value);
- set_control(control, sizeof(lval), control->jalv->forge.Long, &lval);
- } else if (control->value_type == control->jalv->forge.Float) {
- set_control(control, sizeof(value), control->jalv->forge.Float, &value);
- } else if (control->value_type == control->jalv->forge.Double) {
- const double dval = value;
- set_control(control, sizeof(dval), control->jalv->forge.Double, &dval);
- } else if (control->value_type == control->jalv->forge.Bool) {
- const int32_t ival = value;
- set_control(control, sizeof(ival), control->jalv->forge.Bool, &ival);
- }
-
- Controller* controller = (Controller*)control->widget;
- if (controller && controller->spin &&
- differ_enough(gtk_spin_button_get_value(controller->spin), value)) {
- gtk_spin_button_set_value(controller->spin, value);
- }
+ if (control->value_type == control->jalv->forge.Int) {
+ const int32_t ival = lrintf(value);
+ set_control(control, sizeof(ival), control->jalv->forge.Int, &ival);
+ } else if (control->value_type == control->jalv->forge.Long) {
+ const int64_t lval = lrintf(value);
+ set_control(control, sizeof(lval), control->jalv->forge.Long, &lval);
+ } else if (control->value_type == control->jalv->forge.Float) {
+ set_control(control, sizeof(value), control->jalv->forge.Float, &value);
+ } else if (control->value_type == control->jalv->forge.Double) {
+ const double dval = value;
+ set_control(control, sizeof(dval), control->jalv->forge.Double, &dval);
+ } else if (control->value_type == control->jalv->forge.Bool) {
+ const int32_t ival = value;
+ set_control(control, sizeof(ival), control->jalv->forge.Bool, &ival);
+ }
+
+ Controller* controller = (Controller*)control->widget;
+ if (controller && controller->spin &&
+ differ_enough(gtk_spin_button_get_value(controller->spin), value)) {
+ gtk_spin_button_set_value(controller->spin, value);
+ }
}
static double
@@ -549,23 +633,23 @@ get_atom_double(Jalv* jalv,
LV2_URID type,
const void* body)
{
- if (type == jalv->forge.Int || type == jalv->forge.Bool) {
- return *(const int32_t*)body;
- }
+ if (type == jalv->forge.Int || type == jalv->forge.Bool) {
+ return *(const int32_t*)body;
+ }
- if (type == jalv->forge.Long) {
- return *(const int64_t*)body;
- }
+ if (type == jalv->forge.Long) {
+ return *(const int64_t*)body;
+ }
- if (type == jalv->forge.Float) {
- return *(const float*)body;
- }
+ if (type == jalv->forge.Float) {
+ return *(const float*)body;
+ }
- if (type == jalv->forge.Double) {
- return *(const double*)body;
- }
+ if (type == jalv->forge.Double) {
+ return *(const double*)body;
+ }
- return NAN;
+ return NAN;
}
static void
@@ -575,46 +659,44 @@ control_changed(Jalv* jalv,
LV2_URID type,
const void* body)
{
- GtkWidget* widget = controller->control;
- const double fvalue = get_atom_double(jalv, size, type, body);
-
- if (!isnan(fvalue)) {
- if (GTK_IS_COMBO_BOX(widget)) {
- GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
- GValue value = { 0, { { 0 } } };
- GtkTreeIter i;
- bool valid = gtk_tree_model_get_iter_first(model, &i);
- while (valid) {
- gtk_tree_model_get_value(model, &i, 0, &value);
- const double v = g_value_get_float(&value);
- g_value_unset(&value);
- if (fabs(v - fvalue) < FLT_EPSILON) {
- gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), &i);
- return;
- }
- valid = gtk_tree_model_iter_next(model, &i);
- }
- } else if (GTK_IS_TOGGLE_BUTTON(widget)) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
- fvalue > 0.0f);
- } else if (GTK_IS_RANGE(widget)) {
- gtk_range_set_value(GTK_RANGE(widget), fvalue);
- } else {
- fprintf(stderr, "Unknown widget type for value\n");
- }
-
- if (controller->spin) {
- // Update spinner for numeric control
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(controller->spin),
- fvalue);
- }
- } else if (GTK_IS_ENTRY(widget) && type == jalv->urids.atom_String) {
- gtk_entry_set_text(GTK_ENTRY(widget), (const char*)body);
- } else if (GTK_IS_FILE_CHOOSER(widget) && type == jalv->urids.atom_Path) {
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(widget), (const char*)body);
- } else {
- fprintf(stderr, "Unknown widget type for value\n");
- }
+ GtkWidget* widget = controller->control;
+ const double fvalue = get_atom_double(jalv, size, type, body);
+
+ if (!isnan(fvalue)) {
+ if (GTK_IS_COMBO_BOX(widget)) {
+ GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
+ GValue value = {0, {{0}}};
+ GtkTreeIter i;
+ bool valid = gtk_tree_model_get_iter_first(model, &i);
+ while (valid) {
+ gtk_tree_model_get_value(model, &i, 0, &value);
+ const double v = g_value_get_float(&value);
+ g_value_unset(&value);
+ if (fabs(v - fvalue) < FLT_EPSILON) {
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), &i);
+ return;
+ }
+ valid = gtk_tree_model_iter_next(model, &i);
+ }
+ } else if (GTK_IS_TOGGLE_BUTTON(widget)) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), fvalue > 0.0f);
+ } else if (GTK_IS_RANGE(widget)) {
+ gtk_range_set_value(GTK_RANGE(widget), fvalue);
+ } else {
+ fprintf(stderr, "Unknown widget type for value\n");
+ }
+
+ if (controller->spin) {
+ // Update spinner for numeric control
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(controller->spin), fvalue);
+ }
+ } else if (GTK_IS_ENTRY(widget) && type == jalv->urids.atom_String) {
+ gtk_entry_set_text(GTK_ENTRY(widget), (const char*)body);
+ } else if (GTK_IS_FILE_CHOOSER(widget) && type == jalv->urids.atom_Path) {
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(widget), (const char*)body);
+ } else {
+ fprintf(stderr, "Unknown widget type for value\n");
+ }
}
static int
@@ -623,21 +705,23 @@ patch_set_get(Jalv* jalv,
const LV2_Atom_URID** property,
const LV2_Atom** value)
{
- lv2_atom_object_get(obj,
- jalv->urids.patch_property, (const LV2_Atom*)property,
- jalv->urids.patch_value, value,
- 0);
- if (!*property) {
- fprintf(stderr, "patch:Set message with no property\n");
- return 1;
- }
-
- if ((*property)->atom.type != jalv->forge.URID) {
- fprintf(stderr, "patch:Set property is not a URID\n");
- return 1;
- }
-
- return 0;
+ lv2_atom_object_get(obj,
+ jalv->urids.patch_property,
+ (const LV2_Atom*)property,
+ jalv->urids.patch_value,
+ value,
+ 0);
+ if (!*property) {
+ fprintf(stderr, "patch:Set message with no property\n");
+ return 1;
+ }
+
+ if ((*property)->atom.type != jalv->forge.URID) {
+ fprintf(stderr, "patch:Set property is not a URID\n");
+ return 1;
+ }
+
+ return 0;
}
static int
@@ -645,20 +729,18 @@ patch_put_get(Jalv* jalv,
const LV2_Atom_Object* obj,
const LV2_Atom_Object** body)
{
- lv2_atom_object_get(obj,
- jalv->urids.patch_body, (const LV2_Atom*)body,
- 0);
- if (!*body) {
- fprintf(stderr, "patch:Put message with no body\n");
- return 1;
- }
-
- if (!lv2_atom_forge_is_object_type(&jalv->forge, (*body)->atom.type)) {
- fprintf(stderr, "patch:Put body is not an object\n");
- return 1;
- }
-
- return 0;
+ lv2_atom_object_get(obj, jalv->urids.patch_body, (const LV2_Atom*)body, 0);
+ if (!*body) {
+ fprintf(stderr, "patch:Put message with no body\n");
+ return 1;
+ }
+
+ if (!lv2_atom_forge_is_object_type(&jalv->forge, (*body)->atom.type)) {
+ fprintf(stderr, "patch:Put body is not an object\n");
+ return 1;
+ }
+
+ return 0;
}
static LV2UI_Request_Value_Status
@@ -667,49 +749,47 @@ on_request_value(LV2UI_Feature_Handle handle,
const LV2_URID ZIX_UNUSED(type),
const LV2_Feature* const* ZIX_UNUSED(features))
{
- Jalv* jalv = (Jalv*)handle;
- ControlID* control = get_property_control(&jalv->controls, key);
+ Jalv* jalv = (Jalv*)handle;
+ ControlID* control = get_property_control(&jalv->controls, key);
- if (!control) {
- return LV2UI_REQUEST_VALUE_ERR_UNKNOWN;
- }
+ if (!control) {
+ return LV2UI_REQUEST_VALUE_ERR_UNKNOWN;
+ }
- if (control->value_type != jalv->forge.Path) {
- return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
- }
+ if (control->value_type != jalv->forge.Path) {
+ return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
+ }
- GtkWidget* dialog =
- gtk_file_chooser_dialog_new("Choose file",
- GTK_WINDOW(jalv->window),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL);
+ GtkWidget* dialog = gtk_file_chooser_dialog_new("Choose file",
+ GTK_WINDOW(jalv->window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
- char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
+ char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- set_control(control, strlen(path) + 1, jalv->forge.Path, path);
+ set_control(control, strlen(path) + 1, jalv->forge.Path, path);
- g_free(path);
- }
+ g_free(path);
+ }
- gtk_widget_destroy(dialog);
+ gtk_widget_destroy(dialog);
- return 0;
+ return 0;
}
static void
property_changed(Jalv* jalv, LV2_URID key, const LV2_Atom* value)
{
- ControlID* control = get_property_control(&jalv->controls, key);
- if (control) {
- control_changed(jalv,
- (Controller*)control->widget,
- value->size,
- value->type,
- value + 1);
- }
+ ControlID* control = get_property_control(&jalv->controls, key);
+ if (control) {
+ control_changed(
+ jalv, (Controller*)control->widget, value->size, value->type, value + 1);
+ }
}
void
@@ -719,334 +799,329 @@ jalv_ui_port_event(Jalv* jalv,
uint32_t protocol,
const void* buffer)
{
- if (jalv->ui_instance) {
- suil_instance_port_event(jalv->ui_instance, port_index,
- buffer_size, protocol, buffer);
- return;
- }
-
- if (protocol == 0 && (Controller*)jalv->ports[port_index].widget) {
- control_changed(jalv,
- (Controller*)jalv->ports[port_index].widget,
- buffer_size,
- jalv->forge.Float,
- buffer);
- return;
- }
-
- if (protocol == 0) {
- return; // No widget (probably notOnGUI)
- }
-
- if (protocol != jalv->urids.atom_eventTransfer) {
- fprintf(stderr, "Unknown port event protocol\n");
- return;
- }
-
- const LV2_Atom* atom = (const LV2_Atom*)buffer;
- if (lv2_atom_forge_is_object_type(&jalv->forge, atom->type)) {
- updating = true;
- const LV2_Atom_Object* obj = (const LV2_Atom_Object*)buffer;
- if (obj->body.otype == jalv->urids.patch_Set) {
- const LV2_Atom_URID* property = NULL;
- const LV2_Atom* value = NULL;
- if (!patch_set_get(jalv, obj, &property, &value)) {
- property_changed(jalv, property->body, value);
- }
- } else if (obj->body.otype == jalv->urids.patch_Put) {
- const LV2_Atom_Object* body = NULL;
- if (!patch_put_get(jalv, obj, &body)) {
- LV2_ATOM_OBJECT_FOREACH(body, prop) {
- property_changed(jalv, prop->key, &prop->value);
- }
- }
- } else {
- printf("Unknown object type?\n");
- }
- updating = false;
- }
+ if (jalv->ui_instance) {
+ suil_instance_port_event(
+ jalv->ui_instance, port_index, buffer_size, protocol, buffer);
+ return;
+ }
+
+ if (protocol == 0 && (Controller*)jalv->ports[port_index].widget) {
+ control_changed(jalv,
+ (Controller*)jalv->ports[port_index].widget,
+ buffer_size,
+ jalv->forge.Float,
+ buffer);
+ return;
+ }
+
+ if (protocol == 0) {
+ return; // No widget (probably notOnGUI)
+ }
+
+ if (protocol != jalv->urids.atom_eventTransfer) {
+ fprintf(stderr, "Unknown port event protocol\n");
+ return;
+ }
+
+ const LV2_Atom* atom = (const LV2_Atom*)buffer;
+ if (lv2_atom_forge_is_object_type(&jalv->forge, atom->type)) {
+ updating = true;
+ const LV2_Atom_Object* obj = (const LV2_Atom_Object*)buffer;
+ if (obj->body.otype == jalv->urids.patch_Set) {
+ const LV2_Atom_URID* property = NULL;
+ const LV2_Atom* value = NULL;
+ if (!patch_set_get(jalv, obj, &property, &value)) {
+ property_changed(jalv, property->body, value);
+ }
+ } else if (obj->body.otype == jalv->urids.patch_Put) {
+ const LV2_Atom_Object* body = NULL;
+ if (!patch_put_get(jalv, obj, &body)) {
+ LV2_ATOM_OBJECT_FOREACH(body, prop)
+ {
+ property_changed(jalv, prop->key, &prop->value);
+ }
+ }
+ } else {
+ printf("Unknown object type?\n");
+ }
+ updating = false;
+ }
}
static gboolean
scale_changed(GtkRange* range, gpointer data)
{
- set_float_control((const ControlID*)data, gtk_range_get_value(range));
- return FALSE;
+ set_float_control((const ControlID*)data, gtk_range_get_value(range));
+ return FALSE;
}
static gboolean
spin_changed(GtkSpinButton* spin, gpointer data)
{
- const ControlID* control = (const ControlID*)data;
- Controller* controller = (Controller*)control->widget;
- GtkRange* range = GTK_RANGE(controller->control);
- const double value = gtk_spin_button_get_value(spin);
- if (differ_enough(gtk_range_get_value(range), value)) {
- gtk_range_set_value(range, value);
- }
- return FALSE;
+ const ControlID* control = (const ControlID*)data;
+ Controller* controller = (Controller*)control->widget;
+ GtkRange* range = GTK_RANGE(controller->control);
+ const double value = gtk_spin_button_get_value(spin);
+ if (differ_enough(gtk_range_get_value(range), value)) {
+ gtk_range_set_value(range, value);
+ }
+ return FALSE;
}
static gboolean
log_scale_changed(GtkRange* range, gpointer data)
{
- set_float_control((const ControlID*)data, expf(gtk_range_get_value(range)));
- return FALSE;
+ set_float_control((const ControlID*)data, expf(gtk_range_get_value(range)));
+ return FALSE;
}
static gboolean
log_spin_changed(GtkSpinButton* spin, gpointer data)
{
- const ControlID* control = (const ControlID*)data;
- Controller* controller = (Controller*)control->widget;
- GtkRange* range = GTK_RANGE(controller->control);
- const double value = gtk_spin_button_get_value(spin);
- if (differ_enough(gtk_range_get_value(range), logf(value))) {
- gtk_range_set_value(range, logf(value));
- }
- return FALSE;
+ const ControlID* control = (const ControlID*)data;
+ Controller* controller = (Controller*)control->widget;
+ GtkRange* range = GTK_RANGE(controller->control);
+ const double value = gtk_spin_button_get_value(spin);
+ if (differ_enough(gtk_range_get_value(range), logf(value))) {
+ gtk_range_set_value(range, logf(value));
+ }
+ return FALSE;
}
static void
combo_changed(GtkComboBox* box, gpointer data)
{
- const ControlID* control = (const ControlID*)data;
+ const ControlID* control = (const ControlID*)data;
- GtkTreeIter iter;
- if (gtk_combo_box_get_active_iter(box, &iter)) {
- GtkTreeModel* model = gtk_combo_box_get_model(box);
- GValue value = { 0, { { 0 } } };
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter(box, &iter)) {
+ GtkTreeModel* model = gtk_combo_box_get_model(box);
+ GValue value = {0, {{0}}};
- gtk_tree_model_get_value(model, &iter, 0, &value);
- const double v = g_value_get_float(&value);
- g_value_unset(&value);
+ gtk_tree_model_get_value(model, &iter, 0, &value);
+ const double v = g_value_get_float(&value);
+ g_value_unset(&value);
- set_float_control(control, v);
- }
+ set_float_control(control, v);
+ }
}
static gboolean
toggle_changed(GtkToggleButton* button, gpointer data)
{
- set_float_control((const ControlID*)data,
- gtk_toggle_button_get_active(button) ? 1.0f : 0.0f);
- return FALSE;
+ set_float_control((const ControlID*)data,
+ gtk_toggle_button_get_active(button) ? 1.0f : 0.0f);
+ return FALSE;
}
static void
string_changed(GtkEntry* widget, gpointer data)
{
- ControlID* control = (ControlID*)data;
- const char* string = gtk_entry_get_text(widget);
+ ControlID* control = (ControlID*)data;
+ const char* string = gtk_entry_get_text(widget);
- set_control(control, strlen(string) + 1, control->jalv->forge.String, string);
+ set_control(control, strlen(string) + 1, control->jalv->forge.String, string);
}
static void
-file_changed(GtkFileChooserButton* widget,
- gpointer data)
+file_changed(GtkFileChooserButton* widget, gpointer data)
{
- ControlID* control = (ControlID*)data;
- Jalv* jalv = control->jalv;
- const char* filename = gtk_file_chooser_get_filename(
- GTK_FILE_CHOOSER(widget));
+ ControlID* control = (ControlID*)data;
+ Jalv* jalv = control->jalv;
+ const char* filename =
+ gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
- set_control(control, strlen(filename) + 1, jalv->forge.Path, filename);
+ set_control(control, strlen(filename) + 1, jalv->forge.Path, filename);
}
static Controller*
new_controller(GtkSpinButton* spin, GtkWidget* control)
{
- Controller* controller = (Controller*)malloc(sizeof(Controller));
- controller->spin = spin;
- controller->control = control;
- return controller;
+ Controller* controller = (Controller*)malloc(sizeof(Controller));
+ controller->spin = spin;
+ controller->control = control;
+ return controller;
}
static Controller*
make_combo(ControlID* record, float value)
{
- GtkListStore* list_store = gtk_list_store_new(
- 2, G_TYPE_FLOAT, G_TYPE_STRING);
- int active = -1;
- for (size_t i = 0; i < record->n_points; ++i) {
- const ScalePoint* point = &record->points[i];
- GtkTreeIter iter;
- gtk_list_store_append(list_store, &iter);
- gtk_list_store_set(list_store, &iter,
- 0, point->value,
- 1, point->label,
- -1);
- if (fabsf(value - point->value) < FLT_EPSILON) {
- active = i;
- }
- }
-
- GtkWidget* combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list_store));
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
- g_object_unref(list_store);
-
- gtk_widget_set_sensitive(combo, record->is_writable);
-
- GtkCellRenderer* cell = gtk_cell_renderer_text_new();
- gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE);
- gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell, "text", 1, NULL);
-
- if (record->is_writable) {
- g_signal_connect(G_OBJECT(combo), "changed",
- G_CALLBACK(combo_changed), record);
- }
-
- return new_controller(NULL, combo);
+ GtkListStore* list_store = gtk_list_store_new(2, G_TYPE_FLOAT, G_TYPE_STRING);
+ int active = -1;
+ for (size_t i = 0; i < record->n_points; ++i) {
+ const ScalePoint* point = &record->points[i];
+ GtkTreeIter iter;
+ gtk_list_store_append(list_store, &iter);
+ gtk_list_store_set(list_store, &iter, 0, point->value, 1, point->label, -1);
+ if (fabsf(value - point->value) < FLT_EPSILON) {
+ active = i;
+ }
+ }
+
+ GtkWidget* combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list_store));
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
+ g_object_unref(list_store);
+
+ gtk_widget_set_sensitive(combo, record->is_writable);
+
+ GtkCellRenderer* cell = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell, "text", 1, NULL);
+
+ if (record->is_writable) {
+ g_signal_connect(
+ G_OBJECT(combo), "changed", G_CALLBACK(combo_changed), record);
+ }
+
+ return new_controller(NULL, combo);
}
static Controller*
make_log_slider(ControlID* record, float value)
{
- const float min = get_float(record->min, 0.0f);
- const float max = get_float(record->max, 1.0f);
- const float lmin = logf(min);
- const float lmax = logf(max);
- const float ldft = logf(value);
- GtkWidget* scale = new_hscale(lmin, lmax, 0.001);
- GtkWidget* spin = gtk_spin_button_new_with_range(min, max, 0.000001);
-
- gtk_widget_set_sensitive(scale, record->is_writable);
- gtk_widget_set_sensitive(spin, record->is_writable);
-
- gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
- gtk_range_set_value(GTK_RANGE(scale), ldft);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
-
- if (record->is_writable) {
- g_signal_connect(G_OBJECT(scale), "value-changed",
- G_CALLBACK(log_scale_changed), record);
- g_signal_connect(G_OBJECT(spin), "value-changed",
- G_CALLBACK(log_spin_changed), record);
- }
-
- return new_controller(GTK_SPIN_BUTTON(spin), scale);
+ const float min = get_float(record->min, 0.0f);
+ const float max = get_float(record->max, 1.0f);
+ const float lmin = logf(min);
+ const float lmax = logf(max);
+ const float ldft = logf(value);
+ GtkWidget* scale = new_hscale(lmin, lmax, 0.001);
+ GtkWidget* spin = gtk_spin_button_new_with_range(min, max, 0.000001);
+
+ gtk_widget_set_sensitive(scale, record->is_writable);
+ gtk_widget_set_sensitive(spin, record->is_writable);
+
+ gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
+ gtk_range_set_value(GTK_RANGE(scale), ldft);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
+
+ if (record->is_writable) {
+ g_signal_connect(
+ G_OBJECT(scale), "value-changed", G_CALLBACK(log_scale_changed), record);
+ g_signal_connect(
+ G_OBJECT(spin), "value-changed", G_CALLBACK(log_spin_changed), record);
+ }
+
+ return new_controller(GTK_SPIN_BUTTON(spin), scale);
}
static Controller*
make_slider(ControlID* record, float value)
{
- const float min = get_float(record->min, 0.0f);
- const float max = get_float(record->max, 1.0f);
- const double step = record->is_integer ? 1.0 : ((max - min) / 100.0);
- GtkWidget* scale = new_hscale(min, max, step);
- GtkWidget* spin = gtk_spin_button_new_with_range(min, max, step);
-
- gtk_widget_set_sensitive(scale, record->is_writable);
- gtk_widget_set_sensitive(spin, record->is_writable);
-
- if (record->is_integer) {
- gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 0);
- } else {
- gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 7);
- }
-
- gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
- gtk_range_set_value(GTK_RANGE(scale), value);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
- if (record->points) {
- for (size_t i = 0; i < record->n_points; ++i) {
- const ScalePoint* point = &record->points[i];
-
- gchar* str = g_markup_printf_escaped(
- "<span font_size=\"small\">%s</span>", point->label);
- gtk_scale_add_mark(
- GTK_SCALE(scale), point->value, GTK_POS_TOP, str);
- }
- }
-
- if (record->is_writable) {
- g_signal_connect(G_OBJECT(scale), "value-changed",
- G_CALLBACK(scale_changed), record);
- g_signal_connect(G_OBJECT(spin), "value-changed",
- G_CALLBACK(spin_changed), record);
- }
-
- return new_controller(GTK_SPIN_BUTTON(spin), scale);
+ const float min = get_float(record->min, 0.0f);
+ const float max = get_float(record->max, 1.0f);
+ const double step = record->is_integer ? 1.0 : ((max - min) / 100.0);
+ GtkWidget* scale = new_hscale(min, max, step);
+ GtkWidget* spin = gtk_spin_button_new_with_range(min, max, step);
+
+ gtk_widget_set_sensitive(scale, record->is_writable);
+ gtk_widget_set_sensitive(spin, record->is_writable);
+
+ if (record->is_integer) {
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 0);
+ } else {
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 7);
+ }
+
+ gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
+ gtk_range_set_value(GTK_RANGE(scale), value);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
+ if (record->points) {
+ for (size_t i = 0; i < record->n_points; ++i) {
+ const ScalePoint* point = &record->points[i];
+
+ gchar* str = g_markup_printf_escaped(
+ "<span font_size=\"small\">%s</span>", point->label);
+ gtk_scale_add_mark(GTK_SCALE(scale), point->value, GTK_POS_TOP, str);
+ }
+ }
+
+ if (record->is_writable) {
+ g_signal_connect(
+ G_OBJECT(scale), "value-changed", G_CALLBACK(scale_changed), record);
+ g_signal_connect(
+ G_OBJECT(spin), "value-changed", G_CALLBACK(spin_changed), record);
+ }
+
+ return new_controller(GTK_SPIN_BUTTON(spin), scale);
}
static Controller*
make_toggle(ControlID* record, float value)
{
- GtkWidget* check = gtk_check_button_new();
+ GtkWidget* check = gtk_check_button_new();
- gtk_widget_set_sensitive(check, record->is_writable);
+ gtk_widget_set_sensitive(check, record->is_writable);
- if (value) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
- }
+ if (value) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+ }
- if (record->is_writable) {
- g_signal_connect(G_OBJECT(check), "toggled",
- G_CALLBACK(toggle_changed), record);
- }
+ if (record->is_writable) {
+ g_signal_connect(
+ G_OBJECT(check), "toggled", G_CALLBACK(toggle_changed), record);
+ }
- return new_controller(NULL, check);
+ return new_controller(NULL, check);
}
static Controller*
make_entry(ControlID* control)
{
- GtkWidget* entry = gtk_entry_new();
+ GtkWidget* entry = gtk_entry_new();
- gtk_widget_set_sensitive(entry, control->is_writable);
- if (control->is_writable) {
- g_signal_connect(G_OBJECT(entry), "activate",
- G_CALLBACK(string_changed), control);
- }
+ gtk_widget_set_sensitive(entry, control->is_writable);
+ if (control->is_writable) {
+ g_signal_connect(
+ G_OBJECT(entry), "activate", G_CALLBACK(string_changed), control);
+ }
- return new_controller(NULL, entry);
+ return new_controller(NULL, entry);
}
static Controller*
make_file_chooser(ControlID* record)
{
- GtkWidget* button = gtk_file_chooser_button_new(
- "Open File", GTK_FILE_CHOOSER_ACTION_OPEN);
+ GtkWidget* button =
+ gtk_file_chooser_button_new("Open File", GTK_FILE_CHOOSER_ACTION_OPEN);
- gtk_widget_set_sensitive(button, record->is_writable);
+ gtk_widget_set_sensitive(button, record->is_writable);
- if (record->is_writable) {
- g_signal_connect(G_OBJECT(button), "file-set",
- G_CALLBACK(file_changed), record);
- }
+ if (record->is_writable) {
+ g_signal_connect(
+ G_OBJECT(button), "file-set", G_CALLBACK(file_changed), record);
+ }
- return new_controller(NULL, button);
+ return new_controller(NULL, button);
}
static Controller*
make_controller(ControlID* control, float value)
{
- Controller* controller = NULL;
-
- if (control->is_toggle) {
- controller = make_toggle(control, value);
- } else if (control->is_enumeration) {
- controller = make_combo(control, value);
- } else if (control->is_logarithmic) {
- controller = make_log_slider(control, value);
- } else {
- controller = make_slider(control, value);
- }
-
- return controller;
+ Controller* controller = NULL;
+
+ if (control->is_toggle) {
+ controller = make_toggle(control, value);
+ } else if (control->is_enumeration) {
+ controller = make_combo(control, value);
+ } else if (control->is_logarithmic) {
+ controller = make_log_slider(control, value);
+ } else {
+ controller = make_slider(control, value);
+ }
+
+ return controller;
}
static GtkWidget*
new_label(const char* text, bool title, float xalign, float yalign)
{
- GtkWidget* label = gtk_label_new(NULL);
- const char* fmt = title ? "<span font_weight=\"bold\">%s</span>" : "%s:";
- gchar* str = g_markup_printf_escaped(fmt, text);
- gtk_label_set_markup(GTK_LABEL(label), str);
- g_free(str);
- gtk_misc_set_alignment(GTK_MISC(label), xalign, yalign);
- return label;
+ GtkWidget* label = gtk_label_new(NULL);
+ const char* fmt = title ? "<span font_weight=\"bold\">%s</span>" : "%s:";
+ gchar* str = g_markup_printf_escaped(fmt, text);
+ gtk_label_set_markup(GTK_LABEL(label), str);
+ g_free(str);
+ gtk_misc_set_alignment(GTK_MISC(label), xalign, yalign);
+ return label;
}
static void
@@ -1055,191 +1130,220 @@ add_control_row(GtkWidget* table,
const char* name,
Controller* controller)
{
- GtkWidget* label = new_label(name, false, 1.0, 0.5);
- gtk_table_attach(GTK_TABLE(table),
- label,
- 0, 1, row, row + 1,
- GTK_FILL, (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), 8, 1);
- int control_left_attach = 1;
- if (controller->spin) {
- control_left_attach = 2;
- gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(controller->spin),
- 1, 2, row, row + 1,
- GTK_FILL, GTK_FILL, 2, 1);
- }
- gtk_table_attach(GTK_TABLE(table), controller->control,
- control_left_attach, 3, row, row + 1,
- (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), GTK_FILL, 2, 1);
+ GtkWidget* label = new_label(name, false, 1.0, 0.5);
+ gtk_table_attach(GTK_TABLE(table),
+ label,
+ 0,
+ 1,
+ row,
+ row + 1,
+ GTK_FILL,
+ (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
+ 8,
+ 1);
+ int control_left_attach = 1;
+ if (controller->spin) {
+ control_left_attach = 2;
+ gtk_table_attach(GTK_TABLE(table),
+ GTK_WIDGET(controller->spin),
+ 1,
+ 2,
+ row,
+ row + 1,
+ GTK_FILL,
+ GTK_FILL,
+ 2,
+ 1);
+ }
+ gtk_table_attach(GTK_TABLE(table),
+ controller->control,
+ control_left_attach,
+ 3,
+ row,
+ row + 1,
+ (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
+ GTK_FILL,
+ 2,
+ 1);
}
static int
control_group_cmp(const void* p1, const void* p2, void* ZIX_UNUSED(data))
{
- const ControlID* control1 = *(const ControlID*const*)p1;
- const ControlID* control2 = *(const ControlID*const*)p2;
+ const ControlID* control1 = *(const ControlID* const*)p1;
+ const ControlID* control2 = *(const ControlID* const*)p2;
- const int cmp = (control1->group && control2->group)
- ? strcmp(lilv_node_as_string(control1->group),
- lilv_node_as_string(control2->group))
- : ((intptr_t)control1->group - (intptr_t)control2->group);
+ const int cmp = (control1->group && control2->group)
+ ? strcmp(lilv_node_as_string(control1->group),
+ lilv_node_as_string(control2->group))
+ : ((intptr_t)control1->group - (intptr_t)control2->group);
- return cmp;
+ return cmp;
}
static GtkWidget*
build_control_widget(Jalv* jalv, GtkWidget* window)
{
- GtkWidget* port_table = gtk_table_new(jalv->num_ports, 3, false);
-
- /* Make an array of controls sorted by group */
- GArray* controls = g_array_new(FALSE, TRUE, sizeof(ControlID*));
- for (unsigned i = 0; i < jalv->controls.n_controls; ++i) {
- g_array_append_vals(controls, &jalv->controls.controls[i], 1);
- }
- g_array_sort_with_data(controls, control_group_cmp, jalv);
-
- /* Add controls in group order */
- LilvNode* last_group = NULL;
- int n_rows = 0;
- for (size_t i = 0; i < controls->len; ++i) {
- ControlID* record = g_array_index(controls, ControlID*, i);
- Controller* controller = NULL;
- LilvNode* group = record->group;
-
- /* Check group and add new heading if necessary */
- if (group && !lilv_node_equals(group, last_group)) {
- LilvNode* group_name = lilv_world_get(
- jalv->world, group, jalv->nodes.lv2_name, NULL);
- GtkWidget* group_label = new_label(
- lilv_node_as_string(group_name), true, 0.0f, 1.0f);
- gtk_table_attach(GTK_TABLE(port_table), group_label,
- 0, 2, n_rows, n_rows + 1,
- GTK_FILL, GTK_FILL, 0, 6);
- ++n_rows;
- }
- last_group = group;
-
- /* Make control widget */
- if (record->value_type == jalv->forge.String) {
- controller = make_entry(record);
- } else if (record->value_type == jalv->forge.Path) {
- controller = make_file_chooser(record);
- } else {
- const float val = get_float(record->def, 0.0f);
- controller = make_controller(record, val);
- }
-
- record->widget = controller;
- if (record->type == PORT) {
- jalv->ports[record->index].widget = controller;
- }
- if (controller) {
- /* Add row to table for this controller */
- add_control_row(
- port_table, n_rows++,
- (record->label
- ? lilv_node_as_string(record->label)
- : lilv_node_as_uri(record->node)),
- controller);
-
- /* Set tooltip text from comment, if available */
- LilvNode* comment = lilv_world_get(
- jalv->world, record->node, jalv->nodes.rdfs_comment, NULL);
- if (comment) {
- gtk_widget_set_tooltip_text(controller->control,
- lilv_node_as_string(comment));
- }
- lilv_node_free(comment);
- }
- }
-
- if (n_rows > 0) {
- gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
- GtkWidget* alignment = gtk_alignment_new(0.5, 0.0, 1.0, 0.0);
- gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 8, 8);
- gtk_container_add(GTK_CONTAINER(alignment), port_table);
- return alignment;
- }
-
- gtk_widget_destroy(port_table);
- GtkWidget* button = gtk_button_new_with_label("Close");
- g_signal_connect_swapped(button, "clicked",
- G_CALLBACK(gtk_widget_destroy), window);
- gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- return button;
+ GtkWidget* port_table = gtk_table_new(jalv->num_ports, 3, false);
+
+ /* Make an array of controls sorted by group */
+ GArray* controls = g_array_new(FALSE, TRUE, sizeof(ControlID*));
+ for (unsigned i = 0; i < jalv->controls.n_controls; ++i) {
+ g_array_append_vals(controls, &jalv->controls.controls[i], 1);
+ }
+ g_array_sort_with_data(controls, control_group_cmp, jalv);
+
+ /* Add controls in group order */
+ LilvNode* last_group = NULL;
+ int n_rows = 0;
+ for (size_t i = 0; i < controls->len; ++i) {
+ ControlID* record = g_array_index(controls, ControlID*, i);
+ Controller* controller = NULL;
+ LilvNode* group = record->group;
+
+ /* Check group and add new heading if necessary */
+ if (group && !lilv_node_equals(group, last_group)) {
+ LilvNode* group_name =
+ lilv_world_get(jalv->world, group, jalv->nodes.lv2_name, NULL);
+ GtkWidget* group_label =
+ new_label(lilv_node_as_string(group_name), true, 0.0f, 1.0f);
+ gtk_table_attach(GTK_TABLE(port_table),
+ group_label,
+ 0,
+ 2,
+ n_rows,
+ n_rows + 1,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 6);
+ ++n_rows;
+ }
+ last_group = group;
+
+ /* Make control widget */
+ if (record->value_type == jalv->forge.String) {
+ controller = make_entry(record);
+ } else if (record->value_type == jalv->forge.Path) {
+ controller = make_file_chooser(record);
+ } else {
+ const float val = get_float(record->def, 0.0f);
+ controller = make_controller(record, val);
+ }
+
+ record->widget = controller;
+ if (record->type == PORT) {
+ jalv->ports[record->index].widget = controller;
+ }
+ if (controller) {
+ /* Add row to table for this controller */
+ add_control_row(port_table,
+ n_rows++,
+ (record->label ? lilv_node_as_string(record->label)
+ : lilv_node_as_uri(record->node)),
+ controller);
+
+ /* Set tooltip text from comment, if available */
+ LilvNode* comment = lilv_world_get(
+ jalv->world, record->node, jalv->nodes.rdfs_comment, NULL);
+ if (comment) {
+ gtk_widget_set_tooltip_text(controller->control,
+ lilv_node_as_string(comment));
+ }
+ lilv_node_free(comment);
+ }
+ }
+
+ if (n_rows > 0) {
+ gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
+ GtkWidget* alignment = gtk_alignment_new(0.5, 0.0, 1.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 8, 8);
+ gtk_container_add(GTK_CONTAINER(alignment), port_table);
+ return alignment;
+ }
+
+ gtk_widget_destroy(port_table);
+ GtkWidget* button = gtk_button_new_with_label("Close");
+ g_signal_connect_swapped(
+ button, "clicked", G_CALLBACK(gtk_widget_destroy), window);
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ return button;
}
static void
build_menu(Jalv* jalv, GtkWidget* window, GtkWidget* vbox)
{
- GtkWidget* menu_bar = gtk_menu_bar_new();
- GtkWidget* file = gtk_menu_item_new_with_mnemonic("_File");
- GtkWidget* file_menu = gtk_menu_new();
-
- GtkAccelGroup* ag = gtk_accel_group_new();
- gtk_window_add_accel_group(GTK_WINDOW(window), ag);
-
- GtkWidget* save = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, ag);
- GtkWidget* quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, ag);
-
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), file_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save);
- gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file);
-
- GtkWidget* pset_item = gtk_menu_item_new_with_mnemonic("_Presets");
- GtkWidget* pset_menu = gtk_menu_new();
- GtkWidget* save_preset = gtk_menu_item_new_with_mnemonic(
- "_Save Preset...");
- GtkWidget* delete_preset = gtk_menu_item_new_with_mnemonic(
- "_Delete Current Preset...");
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(pset_item), pset_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu), save_preset);
- gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu), delete_preset);
- gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu),
- gtk_separator_menu_item_new());
- gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), pset_item);
-
- PresetMenu menu = {
- NULL, NULL, GTK_MENU(pset_menu),
- g_sequence_new((GDestroyNotify)pset_menu_free)
- };
- jalv_load_presets(jalv, add_preset_to_menu, &menu);
- finish_menu(&menu);
-
- g_signal_connect(G_OBJECT(quit), "activate",
- G_CALLBACK(on_quit_activate), window);
-
- g_signal_connect(G_OBJECT(save), "activate",
- G_CALLBACK(on_save_activate), jalv);
-
- g_signal_connect(G_OBJECT(save_preset), "activate",
- G_CALLBACK(on_save_preset_activate), jalv);
-
- g_signal_connect(G_OBJECT(delete_preset), "activate",
- G_CALLBACK(on_delete_preset_activate), jalv);
-
- gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 0);
+ GtkWidget* menu_bar = gtk_menu_bar_new();
+ GtkWidget* file = gtk_menu_item_new_with_mnemonic("_File");
+ GtkWidget* file_menu = gtk_menu_new();
+
+ GtkAccelGroup* ag = gtk_accel_group_new();
+ gtk_window_add_accel_group(GTK_WINDOW(window), ag);
+
+ GtkWidget* save = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, ag);
+ GtkWidget* quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, ag);
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), file_menu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save);
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file);
+
+ GtkWidget* pset_item = gtk_menu_item_new_with_mnemonic("_Presets");
+ GtkWidget* pset_menu = gtk_menu_new();
+ GtkWidget* save_preset = gtk_menu_item_new_with_mnemonic("_Save Preset...");
+ GtkWidget* delete_preset =
+ gtk_menu_item_new_with_mnemonic("_Delete Current Preset...");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(pset_item), pset_menu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu), save_preset);
+ gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu), delete_preset);
+ gtk_menu_shell_append(GTK_MENU_SHELL(pset_menu),
+ gtk_separator_menu_item_new());
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), pset_item);
+
+ PresetMenu menu = {NULL,
+ NULL,
+ GTK_MENU(pset_menu),
+ g_sequence_new((GDestroyNotify)pset_menu_free)};
+ jalv_load_presets(jalv, add_preset_to_menu, &menu);
+ finish_menu(&menu);
+
+ g_signal_connect(
+ G_OBJECT(quit), "activate", G_CALLBACK(on_quit_activate), window);
+
+ g_signal_connect(
+ G_OBJECT(save), "activate", G_CALLBACK(on_save_activate), jalv);
+
+ g_signal_connect(G_OBJECT(save_preset),
+ "activate",
+ G_CALLBACK(on_save_preset_activate),
+ jalv);
+
+ g_signal_connect(G_OBJECT(delete_preset),
+ "activate",
+ G_CALLBACK(on_delete_preset_activate),
+ jalv);
+
+ gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 0);
}
bool
jalv_discover_ui(Jalv* ZIX_UNUSED(jalv))
{
- return TRUE;
+ return TRUE;
}
float
jalv_ui_refresh_rate(Jalv* ZIX_UNUSED(jalv))
{
#if GTK_MAJOR_VERSION == 2
- return 30.0f;
+ return 30.0f;
#else
- GdkDisplay* const display = gdk_display_get_default();
- GdkMonitor* const monitor = gdk_display_get_primary_monitor(display);
+ GdkDisplay* const display = gdk_display_get_default();
+ GdkMonitor* const monitor = gdk_display_get_primary_monitor(display);
- const float rate = (float)gdk_monitor_get_refresh_rate(monitor);
+ const float rate = (float)gdk_monitor_get_refresh_rate(monitor);
- return rate < 30.0f ? 30.0f : rate;
+ return rate < 30.0f ? 30.0f : rate;
#endif
}
@@ -1247,94 +1351,92 @@ float
jalv_ui_scale_factor(Jalv* ZIX_UNUSED(jalv))
{
#if GTK_MAJOR_VERSION == 2
- return 1.0f;
+ return 1.0f;
#else
- GdkDisplay* const display = gdk_display_get_default();
- GdkMonitor* const monitor = gdk_display_get_primary_monitor(display);
+ GdkDisplay* const display = gdk_display_get_default();
+ GdkMonitor* const monitor = gdk_display_get_primary_monitor(display);
- return (float)gdk_monitor_get_scale_factor(monitor);
+ return (float)gdk_monitor_get_scale_factor(monitor);
#endif
}
int
jalv_open_ui(Jalv* jalv)
{
- GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- jalv->window = window;
-
- g_signal_connect(window, "destroy",
- G_CALLBACK(on_window_destroy), jalv);
-
- set_window_title(jalv);
-
- GtkWidget* vbox = new_box(false, 0);
- gtk_window_set_role(GTK_WINDOW(window), "plugin_ui");
- gtk_container_add(GTK_CONTAINER(window), vbox);
-
- if (!jalv->opts.no_menu) {
- build_menu(jalv, window, vbox);
- }
-
- /* Create/show alignment to contain UI (whether custom or generic) */
- GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
- gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
- gtk_widget_show(alignment);
-
- /* Attempt to instantiate custom UI if necessary */
- if (jalv->ui && !jalv->opts.generic_ui) {
- jalv_ui_instantiate(jalv, jalv_native_ui_type(), alignment);
- }
-
- jalv->features.request_value.request = on_request_value;
-
- if (jalv->ui_instance) {
- GtkWidget* widget = (GtkWidget*)suil_instance_get_widget(
- jalv->ui_instance);
-
- gtk_container_add(GTK_CONTAINER(alignment), widget);
- gtk_window_set_resizable(GTK_WINDOW(window), jalv_ui_is_resizable(jalv));
- gtk_widget_show_all(vbox);
- gtk_widget_grab_focus(widget);
- } else {
- GtkWidget* controls = build_control_widget(jalv, window);
- GtkWidget* scroll_win = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_add_with_viewport(
- GTK_SCROLLED_WINDOW(scroll_win), controls);
- gtk_scrolled_window_set_policy(
- GTK_SCROLLED_WINDOW(scroll_win),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(alignment), scroll_win);
- gtk_widget_show_all(vbox);
-
- GtkRequisition controls_size = {0, 0};
- GtkRequisition box_size = {0, 0};
- size_request(GTK_WIDGET(controls), &controls_size);
- size_request(GTK_WIDGET(vbox), &box_size);
-
- gtk_window_set_default_size(
- GTK_WINDOW(window),
- MAX(MAX(box_size.width, controls_size.width) + 24, 640),
- box_size.height + controls_size.height);
- }
-
- jalv_init_ui(jalv);
-
- g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_update, jalv);
-
- gtk_window_present(GTK_WINDOW(window));
-
- gtk_main();
- suil_instance_free(jalv->ui_instance);
- jalv->ui_instance = NULL;
- zix_sem_post(&jalv->done);
- return 0;
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ jalv->window = window;
+
+ g_signal_connect(window, "destroy", G_CALLBACK(on_window_destroy), jalv);
+
+ set_window_title(jalv);
+
+ GtkWidget* vbox = new_box(false, 0);
+ gtk_window_set_role(GTK_WINDOW(window), "plugin_ui");
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ if (!jalv->opts.no_menu) {
+ build_menu(jalv, window, vbox);
+ }
+
+ /* Create/show alignment to contain UI (whether custom or generic) */
+ GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
+ gtk_widget_show(alignment);
+
+ /* Attempt to instantiate custom UI if necessary */
+ if (jalv->ui && !jalv->opts.generic_ui) {
+ jalv_ui_instantiate(jalv, jalv_native_ui_type(), alignment);
+ }
+
+ jalv->features.request_value.request = on_request_value;
+
+ if (jalv->ui_instance) {
+ GtkWidget* widget = (GtkWidget*)suil_instance_get_widget(jalv->ui_instance);
+
+ gtk_container_add(GTK_CONTAINER(alignment), widget);
+ gtk_window_set_resizable(GTK_WINDOW(window), jalv_ui_is_resizable(jalv));
+ gtk_widget_show_all(vbox);
+ gtk_widget_grab_focus(widget);
+ } else {
+ GtkWidget* controls = build_control_widget(jalv, window);
+ GtkWidget* scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_win),
+ controls);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(alignment), scroll_win);
+ gtk_widget_show_all(vbox);
+
+ GtkRequisition controls_size = {0, 0};
+ GtkRequisition box_size = {0, 0};
+ size_request(GTK_WIDGET(controls), &controls_size);
+ size_request(GTK_WIDGET(vbox), &box_size);
+
+ gtk_window_set_default_size(
+ GTK_WINDOW(window),
+ MAX(MAX(box_size.width, controls_size.width) + 24, 640),
+ box_size.height + controls_size.height);
+ }
+
+ jalv_init_ui(jalv);
+
+ g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_update, jalv);
+
+ gtk_window_present(GTK_WINDOW(window));
+
+ gtk_main();
+ suil_instance_free(jalv->ui_instance);
+ jalv->ui_instance = NULL;
+ zix_sem_post(&jalv->done);
+ return 0;
}
int
jalv_close_ui(Jalv* ZIX_UNUSED(jalv))
{
- gtk_main_quit();
- return 0;
+ gtk_main_quit();
+ return 0;
}
LV2_RESTORE_WARNINGS