| @@ -129,36 +129,6 @@ private: | |||
| struct PrivateData; | |||
| 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) | |||
| }; | |||
| @@ -180,6 +150,7 @@ public: | |||
| }; | |||
| explicit ImageBaseSlider(Widget* parentWidget, const ImageType& image) noexcept; | |||
| ~ImageBaseSlider() override; | |||
| float getValue() const noexcept; | |||
| void setValue(float value, bool sendCallback = false) noexcept; | |||
| @@ -205,31 +176,6 @@ private: | |||
| struct PrivateData; | |||
| 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 | |||
| void setAbsoluteX(int) const noexcept {} | |||
| void setAbsoluteY(int) const noexcept {} | |||
| @@ -18,6 +18,7 @@ | |||
| #include "../Color.hpp" | |||
| #include "../ImageBaseWidgets.hpp" | |||
| #include "Common.hpp" | |||
| #include "SubWidgetPrivateData.hpp" | |||
| #include "TopLevelWidgetPrivateData.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| @@ -216,7 +217,6 @@ template class Triangle<uint>; | |||
| template class Triangle<short>; | |||
| template class Triangle<ushort>; | |||
| // ----------------------------------------------------------------------- | |||
| // Rectangle | |||
| @@ -461,16 +461,56 @@ CairoBaseWidget<StandaloneWindow>::CairoBaseWidget(Application& app, Window& par | |||
| template class CairoBaseWidget<StandaloneWindow>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseAboutWindow | |||
| #if 0 | |||
| template <> | |||
| void ImageBaseAboutWindow<CairoImage>::onDisplay() | |||
| { | |||
| img.draw(getGraphicsContext()); | |||
| } | |||
| #endif | |||
| template class ImageBaseAboutWindow<CairoImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseButton | |||
| 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) | |||
| @@ -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 | |||
| #endif // DGL_APP_PRIVATE_DATA_HPP_INCLUDED | |||
| @@ -18,6 +18,7 @@ | |||
| #include "../Color.hpp" | |||
| #include "../ImageWidgets.hpp" | |||
| #include "Common.hpp" | |||
| #include "SubWidgetPrivateData.hpp" | |||
| #include "TopLevelWidgetPrivateData.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| @@ -435,17 +436,125 @@ void OpenGLImage::drawAt(const Point<int>& pos) | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseAboutWindow | |||
| #if 0 | |||
| template <> | |||
| void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| img.draw(context); | |||
| } | |||
| #endif | |||
| template class ImageBaseAboutWindow<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseButton | |||
| 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) | |||