@@ -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); | |||