| @@ -81,6 +81,18 @@ public: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Host state */ | |||
| /** | |||
| Get the color used for UI background (i.e. window color) in RGBA format. | |||
| Returns 0 by default, in case of error or lack of host support. | |||
| */ | |||
| uint getBackgroundColor() const noexcept; | |||
| /** | |||
| Get the color used for UI foreground (i.e. text color) in RGBA format. | |||
| Returns 0xffffffff by default, in case of error or lack of host support. | |||
| */ | |||
| uint getForegroundColor() const noexcept; | |||
| /** | |||
| Get the current sample rate used in plugin processing. | |||
| @see sampleRateChanged(double) | |||
| @@ -92,7 +104,7 @@ public: | |||
| Touch/pressed-down event. | |||
| Lets the host know the user is tweaking a parameter. | |||
| Required in some hosts to record automation. | |||
| Required in some hosts to record automation. | |||
| */ | |||
| void editParameter(uint32_t index, bool started); | |||
| @@ -108,8 +108,9 @@ public: | |||
| nullptr, // send note | |||
| setSizeCallback, | |||
| nullptr, // file request | |||
| getDesktopScaleFactor(), | |||
| fPlugin.getInstancePointer()), | |||
| nullptr, // bundle | |||
| fPlugin.getInstancePointer(), | |||
| getDesktopScaleFactor()), | |||
| #endif | |||
| fClient(client) | |||
| { | |||
| @@ -178,8 +178,9 @@ public: | |||
| sendNoteCallback, | |||
| setSizeCallback, | |||
| nullptr, // TODO file request | |||
| scaleFactor, | |||
| plugin->getInstancePointer()), | |||
| nullptr, | |||
| plugin->getInstancePointer(), | |||
| scaleFactor), | |||
| fShouldCaptureVstKeys(false) | |||
| { | |||
| // FIXME only needed for windows? | |||
| @@ -593,8 +594,8 @@ public: | |||
| d_lastUiSampleRate = fPlugin.getSampleRate(); | |||
| UIExporter tmpUI(nullptr, 0, | |||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |||
| fLastScaleFactor, fPlugin.getInstancePointer()); | |||
| nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, | |||
| fPlugin.getInstancePointer(), fLastScaleFactor); | |||
| fVstRect.right = tmpUI.getWidth(); | |||
| fVstRect.bottom = tmpUI.getHeight(); | |||
| tmpUI.quit(); | |||
| @@ -81,6 +81,16 @@ void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRa | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Host state */ | |||
| uint UI::getBackgroundColor() const noexcept | |||
| { | |||
| return pData->bgColor; | |||
| } | |||
| uint UI::getForegroundColor() const noexcept | |||
| { | |||
| return pData->fgColor; | |||
| } | |||
| double UI::getSampleRate() const noexcept | |||
| { | |||
| return pData->sampleRate; | |||
| @@ -71,6 +71,8 @@ struct UI::PrivateData { | |||
| bool resizeInProgress; | |||
| uint minWidth; | |||
| uint minHeight; | |||
| uint bgColor; | |||
| uint fgColor; | |||
| // Callbacks | |||
| void* callbacksPtr; | |||
| @@ -91,6 +93,8 @@ struct UI::PrivateData { | |||
| resizeInProgress(false), | |||
| minWidth(0), | |||
| minHeight(0), | |||
| bgColor(0), | |||
| fgColor(0), | |||
| callbacksPtr(nullptr), | |||
| editParamCallbackFunc(nullptr), | |||
| setParamCallbackFunc(nullptr), | |||
| @@ -272,9 +276,11 @@ public: | |||
| const sendNoteFunc sendNoteCall, | |||
| const setSizeFunc setSizeCall, | |||
| const fileRequestFunc fileRequestCall, | |||
| const float scaleFactor = 1.0f, | |||
| const char* const bundlePath = nullptr, | |||
| void* const dspPtr = nullptr, | |||
| const char* const bundlePath = nullptr) | |||
| const float scaleFactor = 1.0f, | |||
| const uint32_t bgColor = 0, | |||
| const uint32_t fgColor = 0xffffffff) | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| : fUI(createUiWrapper(dspPtr, winId, scaleFactor, bundlePath)), | |||
| #else | |||
| @@ -288,6 +294,9 @@ public: | |||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); | |||
| fData->bgColor = bgColor; | |||
| fData->fgColor = fgColor; | |||
| fData->callbacksPtr = callbacksPtr; | |||
| fData->editParamCallbackFunc = editParamCall; | |||
| fData->setParamCallbackFunc = setParamCall; | |||
| @@ -356,6 +365,20 @@ public: | |||
| } | |||
| #endif | |||
| uint getBackgroundColor() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0); | |||
| return fData->bgColor; | |||
| } | |||
| uint getForegroundColor() const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0xffffffff); | |||
| return fData->fgColor; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| uint32_t getParameterOffset() const noexcept | |||
| @@ -70,9 +70,11 @@ public: | |||
| const LV2_Feature* const* const features, | |||
| const LV2UI_Controller controller, | |||
| const LV2UI_Write_Function writeFunc, | |||
| const float scaleFactor, | |||
| LV2UI_Widget* const widget, | |||
| void* const dspPtr) | |||
| void* const dspPtr, | |||
| const float scaleFactor, | |||
| const uint32_t bgColor, | |||
| const uint32_t fgColor) | |||
| : fUI(this, winId, | |||
| editParameterCallback, | |||
| setParameterCallback, | |||
| @@ -80,7 +82,11 @@ public: | |||
| sendNoteCallback, | |||
| setSizeCallback, | |||
| fileRequestCallback, | |||
| scaleFactor, dspPtr, bundlePath), | |||
| bundlePath, | |||
| dspPtr, | |||
| scaleFactor, | |||
| bgColor, | |||
| fgColor), | |||
| fUridMap(uridMap), | |||
| fUiRequestValue(getLv2Feature<LV2UI_Request_Value>(features, LV2_UI__requestValue)), | |||
| fUiResize(getLv2Feature<LV2UI_Resize>(features, LV2_UI__resize)), | |||
| @@ -515,13 +521,18 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| } | |||
| #endif | |||
| const intptr_t winId = (intptr_t)parentId; | |||
| float scaleFactor = 1.0f; | |||
| const intptr_t winId((intptr_t)parentId); | |||
| uint32_t bgColor = 0; | |||
| uint32_t fgColor = 0xffffffff; | |||
| if (options != nullptr) | |||
| { | |||
| const LV2_URID uridAtomInt = uridMap->map(uridMap->handle, LV2_ATOM__Int); | |||
| const LV2_URID uridAtomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float); | |||
| const LV2_URID uridSampleRate = uridMap->map(uridMap->handle, LV2_PARAMETERS__sampleRate); | |||
| const LV2_URID uridBgColor = uridMap->map(uridMap->handle, LV2_UI__backgroundColor); | |||
| const LV2_URID uridFgColor = uridMap->map(uridMap->handle, LV2_UI__foregroundColor); | |||
| const LV2_URID uridScaleFactor = uridMap->map(uridMap->handle, LV2_UI__scaleFactor); | |||
| for (int i=0; options[i].key != 0; ++i) | |||
| @@ -540,6 +551,20 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| else | |||
| d_stderr("Host provides UI scale factor but has wrong value type"); | |||
| } | |||
| else if (options[i].key == uridBgColor) | |||
| { | |||
| if (options[i].type == uridAtomInt) | |||
| bgColor = (uint32_t)*(const int32_t*)options[i].value; | |||
| else | |||
| d_stderr("Host provides UI background color but has wrong value type"); | |||
| } | |||
| else if (options[i].key == uridFgColor) | |||
| { | |||
| if (options[i].type == uridAtomInt) | |||
| fgColor = (uint32_t)*(const int32_t*)options[i].value; | |||
| else | |||
| d_stderr("Host provides UI foreground color but has wrong value type"); | |||
| } | |||
| } | |||
| } | |||
| @@ -550,7 +575,8 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, | |||
| } | |||
| return new UiLv2(bundlePath, winId, options, uridMap, features, | |||
| controller, writeFunction, scaleFactor, widget, instance); | |||
| controller, writeFunction, widget, instance, | |||
| scaleFactor, bgColor, fgColor); | |||
| } | |||
| #define uiPtr ((UiLv2*)ui) | |||
| @@ -105,9 +105,32 @@ protected: | |||
| const uint width = getWidth(); | |||
| const uint height = getHeight(); | |||
| const uint minwh = std::min(width, height); | |||
| const uint bgColor = getBackgroundColor(); | |||
| Rectangle<int> r; | |||
| // if host doesn't respect aspect-ratio but supports ui background, draw out-of-bounds color from it | |||
| if (width != height && bgColor != 0) | |||
| { | |||
| const GLubyte red = (bgColor >> 24) & 0xff; | |||
| const GLubyte green = (bgColor >> 16) & 0xff; | |||
| const GLubyte blue = (bgColor >> 8) & 0xff; | |||
| glColor3ub(red, green, blue); | |||
| if (width > height) | |||
| { | |||
| r.setPos(height, 0); | |||
| r.setSize(width-height, height); | |||
| } | |||
| else | |||
| { | |||
| r.setPos(0, width); | |||
| r.setSize(width, height-width); | |||
| } | |||
| r.draw(); | |||
| } | |||
| r.setWidth(minwh/3 - 6); | |||
| r.setHeight(minwh/3 - 6); | |||