From 570e04f26fffc6430ff6894da6a6e2f39b24efb7 Mon Sep 17 00:00:00 2001 From: rncbc Date: Sat, 7 Jul 2018 19:46:42 +0100 Subject: 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 --- src/qt5_in_gtk2.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 15 deletions(-) (limited to 'src/qt5_in_gtk2.cpp') 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 + Copyright 2018 Rui Nuno Capela 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 #include +#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; } -- cgit v1.2.1