diff options
author | rncbc <rncbc@rncbc.org> | 2018-07-07 19:46:42 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-07-09 21:17:40 +0200 |
commit | 570e04f26fffc6430ff6894da6a6e2f39b24efb7 (patch) | |
tree | f12f16ca23e2cf524bbb616075f98ccc7f4eecda /src | |
parent | ba5d56d27534c6996bc26eb5972d3562ad660545 (diff) | |
download | suil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.tar.gz suil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.tar.bz2 suil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.zip |
Fix Qt5 in Gtk2 wrapper
- Fixes initial size and resizing in some cases
- Adds LV2_UI__resize and LV2_UI__idleInterface features
- Adds LV2_UI__updateRate option
Diffstat (limited to 'src')
-rw-r--r-- | src/qt5_in_gtk2.cpp | 109 |
1 files changed, 94 insertions, 15 deletions
diff --git a/src/qt5_in_gtk2.cpp b/src/qt5_in_gtk2.cpp index 500fdf4..a03e8a7 100644 --- a/src/qt5_in_gtk2.cpp +++ b/src/qt5_in_gtk2.cpp @@ -1,5 +1,6 @@ /* Copyright 2011-2017 David Robillard <http://drobilla.net> + Copyright 2018 Rui Nuno Capela <rncbc@rncbc.org> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -21,6 +22,9 @@ #include <QWidget> #include <QWindow> +#include "lv2/lv2plug.in/ns/ext/options/options.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" + #include "./suil_internal.h" extern "C" { @@ -31,17 +35,18 @@ extern "C" { typedef struct _SuilQtWrapper SuilQtWrapper; typedef struct _SuilQtWrapperClass SuilQtWrapperClass; -struct _SuilQtWrapper -{ - GtkSocket socket; - QApplication* app; - QWidget* qembed; - SuilWrapper* wrapper; - SuilInstance* instance; +struct _SuilQtWrapper { + GtkSocket socket; + QApplication* app; + QWidget* qembed; + SuilWrapper* wrapper; + SuilInstance* instance; + const LV2UI_Idle_Interface* idle_iface; + guint idle_id; + guint idle_ms; }; -struct _SuilQtWrapperClass -{ +struct _SuilQtWrapperClass { GtkSocketClass parent_class; }; @@ -54,6 +59,11 @@ suil_qt_wrapper_finalize(GObject* gobject) { SuilQtWrapper* const self = SUIL_QT_WRAPPER(gobject); + if (self->idle_id) { + g_source_remove(self->idle_id); + self->idle_id = 0; + } + if (self->instance->handle) { self->instance->descriptor->cleanup(self->instance->handle); self->instance->handle = NULL; @@ -63,6 +73,7 @@ suil_qt_wrapper_finalize(GObject* gobject) self->qembed = NULL; self->app = NULL; + self->idle_iface = NULL; self->wrapper->impl = NULL; G_OBJECT_CLASS(suil_qt_wrapper_parent_class)->finalize(gobject); @@ -79,9 +90,13 @@ suil_qt_wrapper_class_init(SuilQtWrapperClass* klass) static void suil_qt_wrapper_init(SuilQtWrapper* self) { - self->app = NULL; - self->qembed = NULL; - self->instance = NULL; + self->app = NULL; + self->qembed = NULL; + self->wrapper = NULL; + self->instance = NULL; + self->idle_iface = NULL; + self->idle_id = 0; + self->idle_ms = 1000 / 30; // 30 Hz default } static void @@ -97,7 +112,29 @@ suil_qt_wrapper_realize(GtkWidget* w, gpointer data) } static int -wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance) +suil_qt_wrapper_resize(LV2UI_Feature_Handle handle, int width, int height) +{ + gtk_widget_set_size_request(GTK_WIDGET(handle), width, height); + + return 0; +} + +static gboolean +suil_qt_wrapper_idle(void* data) +{ + SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(data); + + if (wrap->idle_iface) { + wrap->idle_iface->idle(wrap->instance->handle); + return TRUE; // Continue calling + } + + return FALSE; +} + +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) { SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(wrapper->impl); @@ -106,16 +143,30 @@ wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance) wrap->instance = instance; QWidget* qwidget = (QWidget*)instance->ui_widget; - QVBoxLayout* layout = new QVBoxLayout(wrap->qembed); + QVBoxLayout* layout = new QVBoxLayout(); + layout->setMargin(0); + layout->setSpacing(0); layout->addWidget(qwidget); - qwidget->setParent(wrap->qembed); + wrap->qembed->setLayout(layout); g_signal_connect_after(G_OBJECT(wrap), "realize", G_CALLBACK(suil_qt_wrapper_realize), NULL); instance->host_widget = GTK_WIDGET(wrap); + const LV2UI_Idle_Interface* idle_iface = NULL; + if (instance->descriptor->extension_data) { + idle_iface = (const LV2UI_Idle_Interface*) + instance->descriptor->extension_data(LV2_UI__idleInterface); + } + + if (idle_iface) { + wrap->idle_iface = idle_iface; + wrap->idle_id = g_timeout_add( + wrap->idle_ms, suil_qt_wrapper_idle, wrap); + } + return 0; } @@ -152,6 +203,34 @@ suil_wrapper_new(SuilHost* host, wrap->wrapper = NULL; wrapper->impl = wrap; + wrapper->resize.handle = wrap; + wrapper->resize.ui_resize = suil_qt_wrapper_resize; + + suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize); + suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL); + + // Scan for URID map and options + LV2_URID_Map* map = NULL; + LV2_Options_Option* options = NULL; + for (LV2_Feature** f = *features; *f && (!map || !options); ++f) { + if (!strcmp((*f)->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)(*f)->data; + } else if (!strcmp((*f)->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)(*f)->data; + } + } + + if (map && options) { + // Set UI update rate if given + LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate); + for (LV2_Options_Option* o = options; o->key; ++o) { + if (o->key == ui_updateRate) { + wrap->idle_ms = 1000.0f / *(const float*)o->value; + break; + } + } + } + return wrapper; } |