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