@@ -129,36 +129,6 @@ private: | |||||
struct PrivateData; | struct PrivateData; | ||||
PrivateData* const pData; | PrivateData* const pData; | ||||
/* | |||||
Image fImage; | |||||
float fMinimum; | |||||
float fMaximum; | |||||
float fStep; | |||||
float fValue; | |||||
float fValueDef; | |||||
float fValueTmp; | |||||
bool fUsingDefault; | |||||
bool fUsingLog; | |||||
Orientation fOrientation; | |||||
int fRotationAngle; | |||||
bool fDragging; | |||||
int fLastX; | |||||
int fLastY; | |||||
Callback* fCallback; | |||||
bool fIsImgVertical; | |||||
uint fImgLayerWidth; | |||||
uint fImgLayerHeight; | |||||
uint fImgLayerCount; | |||||
bool fIsReady; | |||||
GLuint fTextureId; | |||||
float _logscale(float value) const; | |||||
float _invlogscale(float value) const; | |||||
*/ | |||||
DISTRHO_LEAK_DETECTOR(ImageBaseKnob) | DISTRHO_LEAK_DETECTOR(ImageBaseKnob) | ||||
}; | }; | ||||
@@ -180,6 +150,7 @@ public: | |||||
}; | }; | ||||
explicit ImageBaseSlider(Widget* parentWidget, const ImageType& image) noexcept; | explicit ImageBaseSlider(Widget* parentWidget, const ImageType& image) noexcept; | ||||
~ImageBaseSlider() override; | |||||
float getValue() const noexcept; | float getValue() const noexcept; | ||||
void setValue(float value, bool sendCallback = false) noexcept; | void setValue(float value, bool sendCallback = false) noexcept; | ||||
@@ -205,31 +176,6 @@ private: | |||||
struct PrivateData; | struct PrivateData; | ||||
PrivateData* const pData; | PrivateData* const pData; | ||||
/* | |||||
Image fImage; | |||||
float fMinimum; | |||||
float fMaximum; | |||||
float fStep; | |||||
float fValue; | |||||
float fValueDef; | |||||
float fValueTmp; | |||||
bool fUsingDefault; | |||||
bool fDragging; | |||||
bool fInverted; | |||||
bool fValueIsSet; | |||||
int fStartedX; | |||||
int fStartedY; | |||||
Callback* fCallback; | |||||
Point<int> fStartPos; | |||||
Point<int> fEndPos; | |||||
Rectangle<double> fSliderArea; | |||||
void _recheckArea() noexcept; | |||||
*/ | |||||
// these should not be used | // these should not be used | ||||
void setAbsoluteX(int) const noexcept {} | void setAbsoluteX(int) const noexcept {} | ||||
void setAbsoluteY(int) const noexcept {} | void setAbsoluteY(int) const noexcept {} | ||||
@@ -18,6 +18,7 @@ | |||||
#include "../Color.hpp" | #include "../Color.hpp" | ||||
#include "../ImageBaseWidgets.hpp" | #include "../ImageBaseWidgets.hpp" | ||||
#include "Common.hpp" | |||||
#include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
#include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
#include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
@@ -216,7 +217,6 @@ template class Triangle<uint>; | |||||
template class Triangle<short>; | template class Triangle<short>; | ||||
template class Triangle<ushort>; | template class Triangle<ushort>; | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Rectangle | // Rectangle | ||||
@@ -461,16 +461,56 @@ CairoBaseWidget<StandaloneWindow>::CairoBaseWidget(Application& app, Window& par | |||||
template class CairoBaseWidget<StandaloneWindow>; | template class CairoBaseWidget<StandaloneWindow>; | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// ImageBaseAboutWindow | |||||
#if 0 | |||||
template <> | template <> | ||||
void ImageBaseAboutWindow<CairoImage>::onDisplay() | void ImageBaseAboutWindow<CairoImage>::onDisplay() | ||||
{ | { | ||||
img.draw(getGraphicsContext()); | img.draw(getGraphicsContext()); | ||||
} | } | ||||
#endif | |||||
template class ImageBaseAboutWindow<CairoImage>; | template class ImageBaseAboutWindow<CairoImage>; | ||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseButton | |||||
template class ImageBaseButton<CairoImage>; | template class ImageBaseButton<CairoImage>; | ||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseKnob | |||||
template <> | |||||
void ImageBaseKnob<CairoImage>::PrivateData::init() | |||||
{ | |||||
notImplemented("ImageBaseKnob::PrivateData::init"); | |||||
} | |||||
template <> | |||||
void ImageBaseKnob<CairoImage>::PrivateData::cleanup() | |||||
{ | |||||
notImplemented("ImageBaseKnob::PrivateData::cleanup"); | |||||
} | |||||
template <> | |||||
void ImageBaseKnob<CairoImage>::onDisplay() | |||||
{ | |||||
notImplemented("ImageBaseKnob::onDisplay"); | |||||
} | |||||
template class ImageBaseKnob<CairoImage>; | |||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseSlider | |||||
template class ImageBaseSlider<CairoImage>; | |||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseSwitch | |||||
template class ImageBaseSwitch<CairoImage>; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | ||||
@@ -120,6 +120,64 @@ struct ButtonImpl { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
template <class ImageType> | |||||
struct ImageBaseKnob<ImageType>::PrivateData { | |||||
ImageType image; | |||||
float minimum; | |||||
float maximum; | |||||
float step; | |||||
float value; | |||||
float valueDef; | |||||
float valueTmp; | |||||
bool usingDefault; | |||||
bool usingLog; | |||||
Orientation orientation; | |||||
int rotationAngle; | |||||
bool dragging; | |||||
int lastX; | |||||
int lastY; | |||||
Callback* callback; | |||||
bool isImgVertical; | |||||
uint imgLayerWidth; | |||||
uint imgLayerHeight; | |||||
uint imgLayerCount; | |||||
bool isReady; | |||||
/*GL*/uint textureId; | |||||
explicit PrivateData(const ImageType& img, const Orientation o); | |||||
explicit PrivateData(PrivateData* const other); | |||||
void assignFrom(PrivateData* const other); | |||||
~PrivateData() | |||||
{ | |||||
cleanup(); | |||||
} | |||||
void init(); | |||||
void cleanup(); | |||||
inline float logscale(float value) const | |||||
{ | |||||
const float b = std::log(maximum/minimum)/(maximum-minimum); | |||||
const float a = maximum/std::exp(maximum*b); | |||||
return a * std::exp(b*value); | |||||
} | |||||
inline float invlogscale(float value) const | |||||
{ | |||||
const float b = std::log(maximum/minimum)/(maximum-minimum); | |||||
const float a = maximum/std::exp(maximum*b); | |||||
return std::log(value/a)/b; | |||||
} | |||||
DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
#endif // DGL_APP_PRIVATE_DATA_HPP_INCLUDED | #endif // DGL_APP_PRIVATE_DATA_HPP_INCLUDED |
@@ -18,6 +18,7 @@ | |||||
#include "../Color.hpp" | #include "../Color.hpp" | ||||
#include "../ImageWidgets.hpp" | #include "../ImageWidgets.hpp" | ||||
#include "Common.hpp" | |||||
#include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
#include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
#include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
@@ -435,17 +436,125 @@ void OpenGLImage::drawAt(const Point<int>& pos) | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// ImageBaseAboutWindow | |||||
#if 0 | |||||
template <> | template <> | ||||
void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | ||||
{ | { | ||||
const GraphicsContext& context(getGraphicsContext()); | const GraphicsContext& context(getGraphicsContext()); | ||||
img.draw(context); | img.draw(context); | ||||
} | } | ||||
#endif | |||||
template class ImageBaseAboutWindow<OpenGLImage>; | template class ImageBaseAboutWindow<OpenGLImage>; | ||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseButton | |||||
template class ImageBaseButton<OpenGLImage>; | template class ImageBaseButton<OpenGLImage>; | ||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseKnob | |||||
template <> | |||||
void ImageBaseKnob<OpenGLImage>::PrivateData::init() | |||||
{ | |||||
glGenTextures(1, &textureId); | |||||
} | |||||
template <> | |||||
void ImageBaseKnob<OpenGLImage>::PrivateData::cleanup() | |||||
{ | |||||
if (textureId != 0) | |||||
{ | |||||
glDeleteTextures(1, &textureId); | |||||
textureId = 0; | |||||
} | |||||
} | |||||
template <> | |||||
void ImageBaseKnob<OpenGLImage>::onDisplay() | |||||
{ | |||||
const GraphicsContext& context(getGraphicsContext()); | |||||
const float normValue = ((pData->usingLog ? pData->invlogscale(pData->value) : pData->value) - pData->minimum) / (pData->maximum - pData->minimum); | |||||
glEnable(GL_TEXTURE_2D); | |||||
glBindTexture(GL_TEXTURE_2D, pData->textureId); | |||||
if (! pData->isReady) | |||||
{ | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); | |||||
static const float trans[] = { 0.0f, 0.0f, 0.0f, 0.0f }; | |||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, trans); | |||||
glPixelStorei(GL_PACK_ALIGNMENT, 1); | |||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |||||
uint imageDataOffset = 0; | |||||
if (pData->rotationAngle == 0) | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(pData->imgLayerCount > 0,); | |||||
DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,); | |||||
const uint& v1(pData->isImgVertical ? pData->imgLayerWidth : pData->imgLayerHeight); | |||||
const uint& v2(pData->isImgVertical ? pData->imgLayerHeight : pData->imgLayerWidth); | |||||
const uint layerDataSize = v1 * v2 * ((pData->image.getFormat() == kImageFormatBGRA || | |||||
pData->image.getFormat() == kImageFormatRGBA) ? 4 : 3); | |||||
/* */ imageDataOffset = layerDataSize * uint(normValue * float(pData->imgLayerCount-1)); | |||||
} | |||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||||
static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0, | |||||
asOpenGLImageFormat(pData->image.getFormat()), GL_UNSIGNED_BYTE, pData->image.getRawData() + imageDataOffset); | |||||
pData->isReady = true; | |||||
} | |||||
const int w = static_cast<int>(getWidth()); | |||||
const int h = static_cast<int>(getHeight()); | |||||
if (pData->rotationAngle != 0) | |||||
{ | |||||
glPushMatrix(); | |||||
const int w2 = w/2; | |||||
const int h2 = h/2; | |||||
glTranslatef(static_cast<float>(w2), static_cast<float>(h2), 0.0f); | |||||
glRotatef(normValue*static_cast<float>(pData->rotationAngle), 0.0f, 0.0f, 1.0f); | |||||
Rectangle<int>(-w2, -h2, w, h).draw(context); | |||||
glPopMatrix(); | |||||
} | |||||
else | |||||
{ | |||||
Rectangle<int>(0, 0, w, h).draw(context); | |||||
} | |||||
glBindTexture(GL_TEXTURE_2D, 0); | |||||
glDisable(GL_TEXTURE_2D); | |||||
} | |||||
template class ImageBaseKnob<OpenGLImage>; | |||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseSlider | |||||
template class ImageBaseSlider<OpenGLImage>; | |||||
// ----------------------------------------------------------------------- | |||||
// ImageBaseSwitch | |||||
template class ImageBaseSwitch<OpenGLImage>; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | ||||