@@ -43,7 +43,6 @@ protected: | |||
private: | |||
Image fImgBackground; | |||
//DISTRHO_DECLARE_NON_COPY_CLASS(ImageAboutWindow) | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ImageAboutWindow) | |||
}; | |||
@@ -19,11 +19,7 @@ OBJS = \ | |||
src/Color.cpp.o \ | |||
src/Geometry.cpp.o \ | |||
src/Image.cpp.o \ | |||
src/ImageAboutWindow.cpp.o \ | |||
src/ImageButton.cpp.o \ | |||
src/ImageKnob.cpp.o \ | |||
src/ImageSlider.cpp.o \ | |||
src/ImageSwitch.cpp.o \ | |||
src/ImageWidgets.cpp.o \ | |||
src/NanoVG.cpp.o \ | |||
src/Widget.cpp.o | |||
@@ -1,89 +0,0 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#include "../ImageWidgets.hpp" | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image) | |||
: Window(parent.getApp(), parent), | |||
Widget((Window&)*this), | |||
fImgBackground(image)/*, | |||
leakDetector_ImageAboutWindow()*/ | |||
{ | |||
Window::setResizable(false); | |||
Window::setSize(static_cast<uint>(image.getWidth()), static_cast<uint>(image.getHeight())); | |||
Window::setTitle("About"); | |||
} | |||
ImageAboutWindow::ImageAboutWindow(Widget* widget, const Image& image) | |||
: Window(widget->getParentApp(), widget->getParentWindow()), | |||
Widget((Window&)*this), | |||
fImgBackground(image)/*, | |||
leakDetector_ImageAboutWindow()*/ | |||
{ | |||
Window::setResizable(false); | |||
Window::setSize(static_cast<uint>(image.getWidth()), static_cast<uint>(image.getHeight())); | |||
Window::setTitle("About"); | |||
} | |||
void ImageAboutWindow::setImage(const Image& image) | |||
{ | |||
if (fImgBackground == image) | |||
return; | |||
fImgBackground = image; | |||
Window::setSize(static_cast<uint>(image.getWidth()), static_cast<uint>(image.getHeight())); | |||
} | |||
void ImageAboutWindow::onDisplay() | |||
{ | |||
fImgBackground.draw(); | |||
} | |||
bool ImageAboutWindow::onKeyboard(const KeyboardEvent& ev) | |||
{ | |||
if (ev.press && ev.key == CHAR_ESCAPE) | |||
{ | |||
Window::close(); | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool ImageAboutWindow::onMouse(const MouseEvent& ev) | |||
{ | |||
if (ev.press) | |||
{ | |||
Window::close(); | |||
return true; | |||
} | |||
return false; | |||
} | |||
void ImageAboutWindow::onReshape(uint width, uint height) | |||
{ | |||
Widget::setSize(width, height); | |||
Window::onReshape(width, height); | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -1,190 +0,0 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#include "../ImageWidgets.hpp" | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
ImageButton::ImageButton(Window& parent, const Image& image) noexcept | |||
: Widget(parent), | |||
fImageNormal(image), | |||
fImageHover(image), | |||
fImageDown(image), | |||
fCurImage(&fImageNormal), | |||
fCurButton(-1), | |||
fCallback(nullptr), | |||
leakDetector_ImageButton() {} | |||
ImageButton::ImageButton(Window& parent, const Image& imageNormal, const Image& imageHover, const Image& imageDown) noexcept | |||
: Widget(parent), | |||
fImageNormal(imageNormal), | |||
fImageHover(imageHover), | |||
fImageDown(imageDown), | |||
fCurImage(&fImageNormal), | |||
fCurButton(-1), | |||
fCallback(nullptr), | |||
leakDetector_ImageButton() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); | |||
setSize(fCurImage->getSize()); | |||
} | |||
ImageButton::ImageButton(Widget* widget, const Image& image) noexcept | |||
: Widget(widget->getParentWindow()), | |||
fImageNormal(image), | |||
fImageHover(image), | |||
fImageDown(image), | |||
fCurImage(&fImageNormal), | |||
fCurButton(-1), | |||
fCallback(nullptr), | |||
leakDetector_ImageButton() {} | |||
ImageButton::ImageButton(Widget* widget, const Image& imageNormal, const Image& imageHover, const Image& imageDown) noexcept | |||
: Widget(widget->getParentWindow()), | |||
fImageNormal(imageNormal), | |||
fImageHover(imageHover), | |||
fImageDown(imageDown), | |||
fCurImage(&fImageNormal), | |||
fCurButton(-1), | |||
fCallback(nullptr), | |||
leakDetector_ImageButton() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); | |||
setSize(fCurImage->getSize()); | |||
} | |||
ImageButton::ImageButton(const ImageButton& imageButton) noexcept | |||
: Widget(imageButton.getParentWindow()), | |||
fImageNormal(imageButton.fImageNormal), | |||
fImageHover(imageButton.fImageHover), | |||
fImageDown(imageButton.fImageDown), | |||
fCurImage(&fImageNormal), | |||
fCurButton(-1), | |||
fCallback(imageButton.fCallback), | |||
leakDetector_ImageButton() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); | |||
setSize(fCurImage->getSize()); | |||
} | |||
ImageButton& ImageButton::operator=(const ImageButton& imageButton) noexcept | |||
{ | |||
fImageNormal = imageButton.fImageNormal; | |||
fImageHover = imageButton.fImageHover; | |||
fImageDown = imageButton.fImageDown; | |||
fCurImage = &fImageNormal; | |||
fCurButton = -1; | |||
fCallback = imageButton.fCallback; | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); | |||
setSize(fCurImage->getSize()); | |||
return *this; | |||
} | |||
void ImageButton::setCallback(Callback* callback) noexcept | |||
{ | |||
fCallback = callback; | |||
} | |||
void ImageButton::onDisplay() | |||
{ | |||
fCurImage->draw(); | |||
} | |||
bool ImageButton::onMouse(const MouseEvent& ev) | |||
{ | |||
if (fCurButton != -1 && ! ev.press) | |||
{ | |||
if (fCurImage != &fImageNormal) | |||
{ | |||
fCurImage = &fImageNormal; | |||
repaint(); | |||
} | |||
if (! contains(ev.pos)) | |||
{ | |||
fCurButton = -1; | |||
return false; | |||
} | |||
if (fCallback != nullptr) | |||
fCallback->imageButtonClicked(this, fCurButton); | |||
#if 0 | |||
if (contains(ev.pos)) | |||
{ | |||
fCurImage = &fImageHover; | |||
repaint(); | |||
} | |||
#endif | |||
fCurButton = -1; | |||
return true; | |||
} | |||
if (ev.press && contains(ev.pos)) | |||
{ | |||
if (fCurImage != &fImageDown) | |||
{ | |||
fCurImage = &fImageDown; | |||
repaint(); | |||
} | |||
fCurButton = ev.button; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool ImageButton::onMotion(const MotionEvent& ev) | |||
{ | |||
if (fCurButton != -1) | |||
return true; | |||
if (contains(ev.pos)) | |||
{ | |||
if (fCurImage != &fImageHover) | |||
{ | |||
fCurImage = &fImageHover; | |||
repaint(); | |||
} | |||
return true; | |||
} | |||
else | |||
{ | |||
if (fCurImage != &fImageNormal) | |||
{ | |||
fCurImage = &fImageNormal; | |||
repaint(); | |||
} | |||
return false; | |||
} | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -1,480 +0,0 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#include "../ImageWidgets.hpp" | |||
#include <cmath> | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
ImageKnob::ImageKnob(Window& parent, const Image& image, Orientation orientation) noexcept | |||
: Widget(parent), | |||
fImage(image), | |||
fMinimum(0.0f), | |||
fMaximum(1.0f), | |||
fStep(0.0f), | |||
fValue(0.5f), | |||
fValueDef(fValue), | |||
fValueTmp(fValue), | |||
fUsingDefault(false), | |||
fUsingLog(false), | |||
fOrientation(orientation), | |||
fRotationAngle(0), | |||
fDragging(false), | |||
fLastX(0), | |||
fLastY(0), | |||
fCallback(nullptr), | |||
fIsImgVertical(image.getHeight() > image.getWidth()), | |||
fImgLayerWidth(fIsImgVertical ? image.getWidth() : image.getHeight()), | |||
fImgLayerHeight(fImgLayerWidth), | |||
fImgLayerCount(fIsImgVertical ? image.getHeight()/fImgLayerHeight : image.getWidth()/fImgLayerWidth), | |||
fIsReady(false), | |||
fTextureId(0), | |||
leakDetector_ImageKnob() | |||
{ | |||
glGenTextures(1, &fTextureId); | |||
setSize(fImgLayerWidth, fImgLayerHeight); | |||
} | |||
ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation) noexcept | |||
: Widget(widget->getParentWindow()), | |||
fImage(image), | |||
fMinimum(0.0f), | |||
fMaximum(1.0f), | |||
fStep(0.0f), | |||
fValue(0.5f), | |||
fValueDef(fValue), | |||
fValueTmp(fValue), | |||
fUsingDefault(false), | |||
fUsingLog(false), | |||
fOrientation(orientation), | |||
fRotationAngle(0), | |||
fDragging(false), | |||
fLastX(0), | |||
fLastY(0), | |||
fCallback(nullptr), | |||
fIsImgVertical(image.getHeight() > image.getWidth()), | |||
fImgLayerWidth(fIsImgVertical ? image.getWidth() : image.getHeight()), | |||
fImgLayerHeight(fImgLayerWidth), | |||
fImgLayerCount(fIsImgVertical ? image.getHeight()/fImgLayerHeight : image.getWidth()/fImgLayerWidth), | |||
fIsReady(false), | |||
fTextureId(0), | |||
leakDetector_ImageKnob() | |||
{ | |||
glGenTextures(1, &fTextureId); | |||
setSize(fImgLayerWidth, fImgLayerHeight); | |||
} | |||
ImageKnob::ImageKnob(const ImageKnob& imageKnob) | |||
: Widget(imageKnob.getParentWindow()), | |||
fImage(imageKnob.fImage), | |||
fMinimum(imageKnob.fMinimum), | |||
fMaximum(imageKnob.fMaximum), | |||
fStep(imageKnob.fStep), | |||
fValue(imageKnob.fValue), | |||
fValueDef(imageKnob.fValueDef), | |||
fValueTmp(fValue), | |||
fUsingDefault(imageKnob.fUsingDefault), | |||
fUsingLog(imageKnob.fUsingLog), | |||
fOrientation(imageKnob.fOrientation), | |||
fRotationAngle(imageKnob.fRotationAngle), | |||
fDragging(false), | |||
fLastX(0), | |||
fLastY(0), | |||
fCallback(imageKnob.fCallback), | |||
fIsImgVertical(imageKnob.fIsImgVertical), | |||
fImgLayerWidth(imageKnob.fImgLayerWidth), | |||
fImgLayerHeight(imageKnob.fImgLayerHeight), | |||
fImgLayerCount(imageKnob.fImgLayerCount), | |||
fIsReady(false), | |||
fTextureId(0), | |||
leakDetector_ImageKnob() | |||
{ | |||
glGenTextures(1, &fTextureId); | |||
setSize(fImgLayerWidth, fImgLayerHeight); | |||
} | |||
ImageKnob& ImageKnob::operator=(const ImageKnob& imageKnob) | |||
{ | |||
fImage = imageKnob.fImage; | |||
fMinimum = imageKnob.fMinimum; | |||
fMaximum = imageKnob.fMaximum; | |||
fStep = imageKnob.fStep; | |||
fValue = imageKnob.fValue; | |||
fValueDef = imageKnob.fValueDef; | |||
fValueTmp = fValue; | |||
fUsingDefault = imageKnob.fUsingDefault; | |||
fUsingLog = imageKnob.fUsingLog; | |||
fOrientation = imageKnob.fOrientation; | |||
fRotationAngle = imageKnob.fRotationAngle; | |||
fDragging = false; | |||
fLastX = 0; | |||
fLastY = 0; | |||
fCallback = imageKnob.fCallback; | |||
fIsImgVertical = imageKnob.fIsImgVertical; | |||
fImgLayerWidth = imageKnob.fImgLayerWidth; | |||
fImgLayerHeight = imageKnob.fImgLayerHeight; | |||
fImgLayerCount = imageKnob.fImgLayerCount; | |||
fIsReady = false; | |||
if (fTextureId != 0) | |||
{ | |||
glDeleteTextures(1, &fTextureId); | |||
fTextureId = 0; | |||
} | |||
glGenTextures(1, &fTextureId); | |||
setSize(fImgLayerWidth, fImgLayerHeight); | |||
return *this; | |||
} | |||
ImageKnob::~ImageKnob() | |||
{ | |||
if (fTextureId != 0) | |||
{ | |||
glDeleteTextures(1, &fTextureId); | |||
fTextureId = 0; | |||
} | |||
} | |||
float ImageKnob::getValue() const noexcept | |||
{ | |||
return fValue; | |||
} | |||
// NOTE: value is assumed to be scaled if using log | |||
void ImageKnob::setDefault(float value) noexcept | |||
{ | |||
fValueDef = value; | |||
fUsingDefault = true; | |||
} | |||
void ImageKnob::setRange(float min, float max) noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(max > min,); | |||
if (fValue < min) | |||
{ | |||
fValue = min; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageKnob::setRange < min"); | |||
} | |||
} | |||
else if (fValue > max) | |||
{ | |||
fValue = max; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageKnob::setRange > max"); | |||
} | |||
} | |||
fMinimum = min; | |||
fMaximum = max; | |||
} | |||
void ImageKnob::setStep(float step) noexcept | |||
{ | |||
fStep = step; | |||
} | |||
// NOTE: value is assumed to be scaled if using log | |||
void ImageKnob::setValue(float value, bool sendCallback) noexcept | |||
{ | |||
if (d_isEqual(fValue, value)) | |||
return; | |||
fValue = value; | |||
if (d_isZero(fStep)) | |||
fValueTmp = value; | |||
if (fRotationAngle == 0) | |||
fIsReady = false; | |||
repaint(); | |||
if (sendCallback && fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageKnob::setValue"); | |||
} | |||
} | |||
void ImageKnob::setUsingLogScale(bool yesNo) noexcept | |||
{ | |||
fUsingLog = yesNo; | |||
} | |||
void ImageKnob::setCallback(Callback* callback) noexcept | |||
{ | |||
fCallback = callback; | |||
} | |||
void ImageKnob::setOrientation(Orientation orientation) noexcept | |||
{ | |||
if (fOrientation == orientation) | |||
return; | |||
fOrientation = orientation; | |||
} | |||
void ImageKnob::setRotationAngle(int angle) | |||
{ | |||
if (fRotationAngle == angle) | |||
return; | |||
fRotationAngle = angle; | |||
fIsReady = false; | |||
} | |||
void ImageKnob::setImageLayerCount(uint count) noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(count > 1,); | |||
fImgLayerCount = count; | |||
if (fIsImgVertical) | |||
fImgLayerHeight = fImage.getHeight()/count; | |||
else | |||
fImgLayerWidth = fImage.getWidth()/count; | |||
setSize(fImgLayerWidth, fImgLayerHeight); | |||
} | |||
void ImageKnob::onDisplay() | |||
{ | |||
const float normValue = ((fUsingLog ? _invlogscale(fValue) : fValue) - fMinimum) / (fMaximum - fMinimum); | |||
glEnable(GL_TEXTURE_2D); | |||
glBindTexture(GL_TEXTURE_2D, fTextureId); | |||
if (! fIsReady) | |||
{ | |||
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 (fRotationAngle == 0) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(fImgLayerCount > 0,); | |||
DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,); | |||
const uint& v1(fIsImgVertical ? fImgLayerWidth : fImgLayerHeight); | |||
const uint& v2(fIsImgVertical ? fImgLayerHeight : fImgLayerWidth); | |||
const uint layerDataSize = v1 * v2 * ((fImage.getFormat() == GL_BGRA || fImage.getFormat() == GL_RGBA) ? 4 : 3); | |||
/* */ imageDataOffset = layerDataSize * uint(normValue * float(fImgLayerCount-1)); | |||
} | |||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0, | |||
fImage.getFormat(), fImage.getType(), fImage.getRawData() + imageDataOffset); | |||
fIsReady = true; | |||
} | |||
const int w = static_cast<int>(getWidth()); | |||
const int h = static_cast<int>(getHeight()); | |||
if (fRotationAngle != 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>(fRotationAngle), 0.0f, 0.0f, 1.0f); | |||
Rectangle<int>(-w2, -h2, w, h).draw(); | |||
glPopMatrix(); | |||
} | |||
else | |||
{ | |||
Rectangle<int>(0, 0, w, h).draw(); | |||
} | |||
glBindTexture(GL_TEXTURE_2D, 0); | |||
glDisable(GL_TEXTURE_2D); | |||
} | |||
bool ImageKnob::onMouse(const MouseEvent& ev) | |||
{ | |||
if (ev.button != 1) | |||
return false; | |||
if (ev.press) | |||
{ | |||
if (! contains(ev.pos)) | |||
return false; | |||
if ((ev.mod & MODIFIER_SHIFT) != 0 && fUsingDefault) | |||
{ | |||
setValue(fValueDef, true); | |||
fValueTmp = fValue; | |||
return true; | |||
} | |||
fDragging = true; | |||
fLastX = ev.pos.getX(); | |||
fLastY = ev.pos.getY(); | |||
if (fCallback != nullptr) | |||
fCallback->imageKnobDragStarted(this); | |||
return true; | |||
} | |||
else if (fDragging) | |||
{ | |||
if (fCallback != nullptr) | |||
fCallback->imageKnobDragFinished(this); | |||
fDragging = false; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool ImageKnob::onMotion(const MotionEvent& ev) | |||
{ | |||
if (! fDragging) | |||
return false; | |||
bool doVal = false; | |||
float d, value = 0.0f; | |||
if (fOrientation == ImageKnob::Horizontal) | |||
{ | |||
if (const int movX = ev.pos.getX() - fLastX) | |||
{ | |||
d = (ev.mod & MODIFIER_CTRL) ? 2000.0f : 200.0f; | |||
value = (fUsingLog ? _invlogscale(fValueTmp) : fValueTmp) + (float(fMaximum - fMinimum) / d * float(movX)); | |||
doVal = true; | |||
} | |||
} | |||
else if (fOrientation == ImageKnob::Vertical) | |||
{ | |||
if (const int movY = fLastY - ev.pos.getY()) | |||
{ | |||
d = (ev.mod & MODIFIER_CTRL) ? 2000.0f : 200.0f; | |||
value = (fUsingLog ? _invlogscale(fValueTmp) : fValueTmp) + (float(fMaximum - fMinimum) / d * float(movY)); | |||
doVal = true; | |||
} | |||
} | |||
if (! doVal) | |||
return false; | |||
if (fUsingLog) | |||
value = _logscale(value); | |||
if (value < fMinimum) | |||
{ | |||
fValueTmp = value = fMinimum; | |||
} | |||
else if (value > fMaximum) | |||
{ | |||
fValueTmp = value = fMaximum; | |||
} | |||
else if (d_isNotZero(fStep)) | |||
{ | |||
fValueTmp = value; | |||
const float rest = std::fmod(value, fStep); | |||
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f); | |||
} | |||
setValue(value, true); | |||
fLastX = ev.pos.getX(); | |||
fLastY = ev.pos.getY(); | |||
return true; | |||
} | |||
bool ImageKnob::onScroll(const ScrollEvent& ev) | |||
{ | |||
if (! contains(ev.pos)) | |||
return false; | |||
const float d = (ev.mod & MODIFIER_CTRL) ? 2000.0f : 200.0f; | |||
float value = (fUsingLog ? _invlogscale(fValueTmp) : fValueTmp) + (float(fMaximum - fMinimum) / d * 10.f * ev.delta.getY()); | |||
if (fUsingLog) | |||
value = _logscale(value); | |||
if (value < fMinimum) | |||
{ | |||
fValueTmp = value = fMinimum; | |||
} | |||
else if (value > fMaximum) | |||
{ | |||
fValueTmp = value = fMaximum; | |||
} | |||
else if (d_isNotZero(fStep)) | |||
{ | |||
fValueTmp = value; | |||
const float rest = std::fmod(value, fStep); | |||
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f); | |||
} | |||
setValue(value, true); | |||
return true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
float ImageKnob::_logscale(float value) const | |||
{ | |||
const float b = std::log(fMaximum/fMinimum)/(fMaximum-fMinimum); | |||
const float a = fMaximum/std::exp(fMaximum*b); | |||
return a * std::exp(b*value); | |||
} | |||
float ImageKnob::_invlogscale(float value) const | |||
{ | |||
const float b = std::log(fMaximum/fMinimum)/(fMaximum-fMinimum); | |||
const float a = fMaximum/std::exp(fMaximum*b); | |||
return std::log(value/a)/b; | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -1,399 +0,0 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#include "../ImageWidgets.hpp" | |||
#include <cmath> | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
ImageSlider::ImageSlider(Window& parent, const Image& image) noexcept | |||
: Widget(parent), | |||
fImage(image), | |||
fMinimum(0.0f), | |||
fMaximum(1.0f), | |||
fStep(0.0f), | |||
fValue(0.5f), | |||
fValueTmp(fValue), | |||
fDragging(false), | |||
fInverted(false), | |||
fStartedX(0), | |||
fStartedY(0), | |||
fCallback(nullptr), | |||
fStartPos(), | |||
fEndPos(), | |||
fSliderArea(), | |||
leakDetector_ImageSlider() | |||
{ | |||
fNeedsFullViewport = true; | |||
} | |||
ImageSlider::ImageSlider(Widget* widget, const Image& image) noexcept | |||
: Widget(widget->getParentWindow()), | |||
fImage(image), | |||
fMinimum(0.0f), | |||
fMaximum(1.0f), | |||
fStep(0.0f), | |||
fValue(0.5f), | |||
fValueTmp(fValue), | |||
fDragging(false), | |||
fInverted(false), | |||
fStartedX(0), | |||
fStartedY(0), | |||
fCallback(nullptr), | |||
fStartPos(), | |||
fEndPos(), | |||
fSliderArea(), | |||
leakDetector_ImageSlider() | |||
{ | |||
fNeedsFullViewport = true; | |||
} | |||
ImageSlider::ImageSlider(const ImageSlider& imageSlider) noexcept | |||
: Widget(imageSlider.getParentWindow()), | |||
fImage(imageSlider.fImage), | |||
fMinimum(imageSlider.fMinimum), | |||
fMaximum(imageSlider.fMaximum), | |||
fStep(imageSlider.fStep), | |||
fValue(imageSlider.fValue), | |||
fValueTmp(fValue), | |||
fDragging(false), | |||
fInverted(imageSlider.fInverted), | |||
fStartedX(0), | |||
fStartedY(0), | |||
fCallback(imageSlider.fCallback), | |||
fStartPos(imageSlider.fStartPos), | |||
fEndPos(imageSlider.fEndPos), | |||
fSliderArea(imageSlider.fSliderArea), | |||
leakDetector_ImageSlider() | |||
{ | |||
fNeedsFullViewport = true; | |||
} | |||
ImageSlider& ImageSlider::operator=(const ImageSlider& imageSlider) noexcept | |||
{ | |||
fImage = imageSlider.fImage; | |||
fMinimum = imageSlider.fMinimum; | |||
fMaximum = imageSlider.fMaximum; | |||
fStep = imageSlider.fStep; | |||
fValue = imageSlider.fValue; | |||
fValueTmp = fValue; | |||
fDragging = false; | |||
fInverted = imageSlider.fInverted; | |||
fStartedX = 0; | |||
fStartedY = 0; | |||
fCallback = imageSlider.fCallback; | |||
fStartPos = imageSlider.fStartPos; | |||
fEndPos = imageSlider.fEndPos; | |||
fSliderArea = imageSlider.fSliderArea; | |||
return *this; | |||
} | |||
float ImageSlider::getValue() const noexcept | |||
{ | |||
return fValue; | |||
} | |||
void ImageSlider::setStartPos(const Point<int>& startPos) noexcept | |||
{ | |||
fStartPos = startPos; | |||
_recheckArea(); | |||
} | |||
void ImageSlider::setStartPos(int x, int y) noexcept | |||
{ | |||
setStartPos(Point<int>(x, y)); | |||
} | |||
void ImageSlider::setEndPos(const Point<int>& endPos) noexcept | |||
{ | |||
fEndPos = endPos; | |||
_recheckArea(); | |||
} | |||
void ImageSlider::setEndPos(int x, int y) noexcept | |||
{ | |||
setEndPos(Point<int>(x, y)); | |||
} | |||
void ImageSlider::setInverted(bool inverted) noexcept | |||
{ | |||
if (fInverted == inverted) | |||
return; | |||
fInverted = inverted; | |||
repaint(); | |||
} | |||
void ImageSlider::setRange(float min, float max) noexcept | |||
{ | |||
if (fValue < min) | |||
{ | |||
fValue = min; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageSliderValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageSlider::setRange < min"); | |||
} | |||
} | |||
else if (fValue > max) | |||
{ | |||
fValue = max; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageSliderValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageSlider::setRange > max"); | |||
} | |||
} | |||
fMinimum = min; | |||
fMaximum = max; | |||
} | |||
void ImageSlider::setStep(float step) noexcept | |||
{ | |||
fStep = step; | |||
} | |||
void ImageSlider::setValue(float value, bool sendCallback) noexcept | |||
{ | |||
if (d_isEqual(fValue, value)) | |||
return; | |||
fValue = value; | |||
if (d_isZero(fStep)) | |||
fValueTmp = value; | |||
repaint(); | |||
if (sendCallback && fCallback != nullptr) | |||
{ | |||
try { | |||
fCallback->imageSliderValueChanged(this, fValue); | |||
} DISTRHO_SAFE_EXCEPTION("ImageSlider::setValue"); | |||
} | |||
} | |||
void ImageSlider::setCallback(Callback* callback) noexcept | |||
{ | |||
fCallback = callback; | |||
} | |||
void ImageSlider::onDisplay() | |||
{ | |||
#if 0 // DEBUG, paints slider area | |||
glColor3f(0.4f, 0.5f, 0.1f); | |||
glRecti(fSliderArea.getX(), fSliderArea.getY(), fSliderArea.getX()+fSliderArea.getWidth(), fSliderArea.getY()+fSliderArea.getHeight()); | |||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
#endif | |||
const float normValue = (fValue - fMinimum) / (fMaximum - fMinimum); | |||
int x, y; | |||
if (fStartPos.getY() == fEndPos.getY()) | |||
{ | |||
// horizontal | |||
if (fInverted) | |||
x = fEndPos.getX() - static_cast<int>(normValue*static_cast<float>(fEndPos.getX()-fStartPos.getX())); | |||
else | |||
x = fStartPos.getX() + static_cast<int>(normValue*static_cast<float>(fEndPos.getX()-fStartPos.getX())); | |||
y = fStartPos.getY(); | |||
} | |||
else | |||
{ | |||
// vertical | |||
x = fStartPos.getX(); | |||
if (fInverted) | |||
y = fEndPos.getY() - static_cast<int>(normValue*static_cast<float>(fEndPos.getY()-fStartPos.getY())); | |||
else | |||
y = fStartPos.getY() + static_cast<int>(normValue*static_cast<float>(fEndPos.getY()-fStartPos.getY())); | |||
} | |||
fImage.drawAt(x, y); | |||
} | |||
bool ImageSlider::onMouse(const MouseEvent& ev) | |||
{ | |||
if (ev.button != 1) | |||
return false; | |||
if (ev.press) | |||
{ | |||
if (! fSliderArea.contains(ev.pos)) | |||
return false; | |||
float vper; | |||
const int x = ev.pos.getX(); | |||
const int y = ev.pos.getY(); | |||
if (fStartPos.getY() == fEndPos.getY()) | |||
{ | |||
// horizontal | |||
vper = float(x - fSliderArea.getX()) / float(fSliderArea.getWidth()); | |||
} | |||
else | |||
{ | |||
// vertical | |||
vper = float(y - fSliderArea.getY()) / float(fSliderArea.getHeight()); | |||
} | |||
float value; | |||
if (fInverted) | |||
value = fMaximum - vper * (fMaximum - fMinimum); | |||
else | |||
value = fMinimum + vper * (fMaximum - fMinimum); | |||
if (value < fMinimum) | |||
{ | |||
fValueTmp = value = fMinimum; | |||
} | |||
else if (value > fMaximum) | |||
{ | |||
fValueTmp = value = fMaximum; | |||
} | |||
else if (d_isNotZero(fStep)) | |||
{ | |||
fValueTmp = value; | |||
const float rest = std::fmod(value, fStep); | |||
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f); | |||
} | |||
fDragging = true; | |||
fStartedX = x; | |||
fStartedY = y; | |||
if (fCallback != nullptr) | |||
fCallback->imageSliderDragStarted(this); | |||
setValue(value, true); | |||
return true; | |||
} | |||
else if (fDragging) | |||
{ | |||
if (fCallback != nullptr) | |||
fCallback->imageSliderDragFinished(this); | |||
fDragging = false; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool ImageSlider::onMotion(const MotionEvent& ev) | |||
{ | |||
if (! fDragging) | |||
return false; | |||
const bool horizontal = fStartPos.getY() == fEndPos.getY(); | |||
const int x = ev.pos.getX(); | |||
const int y = ev.pos.getY(); | |||
if ((horizontal && fSliderArea.containsX(x)) || (fSliderArea.containsY(y) && ! horizontal)) | |||
{ | |||
float vper; | |||
if (horizontal) | |||
{ | |||
// horizontal | |||
vper = float(x - fSliderArea.getX()) / float(fSliderArea.getWidth()); | |||
} | |||
else | |||
{ | |||
// vertical | |||
vper = float(y - fSliderArea.getY()) / float(fSliderArea.getHeight()); | |||
} | |||
float value; | |||
if (fInverted) | |||
value = fMaximum - vper * (fMaximum - fMinimum); | |||
else | |||
value = fMinimum + vper * (fMaximum - fMinimum); | |||
if (value < fMinimum) | |||
{ | |||
fValueTmp = value = fMinimum; | |||
} | |||
else if (value > fMaximum) | |||
{ | |||
fValueTmp = value = fMaximum; | |||
} | |||
else if (d_isNotZero(fStep)) | |||
{ | |||
fValueTmp = value; | |||
const float rest = std::fmod(value, fStep); | |||
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f); | |||
} | |||
setValue(value, true); | |||
} | |||
else if (horizontal) | |||
{ | |||
if (x < fSliderArea.getX()) | |||
setValue(fInverted ? fMaximum : fMinimum, true); | |||
else | |||
setValue(fInverted ? fMinimum : fMaximum, true); | |||
} | |||
else | |||
{ | |||
if (y < fSliderArea.getY()) | |||
setValue(fInverted ? fMaximum : fMinimum, true); | |||
else | |||
setValue(fInverted ? fMinimum : fMaximum, true); | |||
} | |||
return true; | |||
} | |||
void ImageSlider::_recheckArea() noexcept | |||
{ | |||
if (fStartPos.getY() == fEndPos.getY()) | |||
{ | |||
// horizontal | |||
fSliderArea = Rectangle<int>(fStartPos.getX(), | |||
fStartPos.getY(), | |||
fEndPos.getX() + static_cast<int>(fImage.getWidth()) - fStartPos.getX(), | |||
static_cast<int>(fImage.getHeight())); | |||
} | |||
else | |||
{ | |||
// vertical | |||
fSliderArea = Rectangle<int>(fStartPos.getX(), | |||
fStartPos.getY(), | |||
static_cast<int>(fImage.getWidth()), | |||
fEndPos.getY() + static_cast<int>(fImage.getHeight()) - fStartPos.getY()); | |||
} | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -1,122 +0,0 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#include "../ImageWidgets.hpp" | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
ImageSwitch::ImageSwitch(Window& parent, const Image& imageNormal, const Image& imageDown) noexcept | |||
: Widget(parent), | |||
fImageNormal(imageNormal), | |||
fImageDown(imageDown), | |||
fIsDown(false), | |||
fCallback(nullptr), | |||
leakDetector_ImageSwitch() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageDown.getSize()); | |||
setSize(fImageNormal.getSize()); | |||
} | |||
ImageSwitch::ImageSwitch(Widget* widget, const Image& imageNormal, const Image& imageDown) noexcept | |||
: Widget(widget->getParentWindow()), | |||
fImageNormal(imageNormal), | |||
fImageDown(imageDown), | |||
fIsDown(false), | |||
fCallback(nullptr), | |||
leakDetector_ImageSwitch() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageDown.getSize()); | |||
setSize(fImageNormal.getSize()); | |||
} | |||
ImageSwitch::ImageSwitch(const ImageSwitch& imageSwitch) noexcept | |||
: Widget(imageSwitch.getParentWindow()), | |||
fImageNormal(imageSwitch.fImageNormal), | |||
fImageDown(imageSwitch.fImageDown), | |||
fIsDown(imageSwitch.fIsDown), | |||
fCallback(imageSwitch.fCallback), | |||
leakDetector_ImageSwitch() | |||
{ | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageDown.getSize()); | |||
setSize(fImageNormal.getSize()); | |||
} | |||
ImageSwitch& ImageSwitch::operator=(const ImageSwitch& imageSwitch) noexcept | |||
{ | |||
fImageNormal = imageSwitch.fImageNormal; | |||
fImageDown = imageSwitch.fImageDown; | |||
fIsDown = imageSwitch.fIsDown; | |||
fCallback = imageSwitch.fCallback; | |||
DISTRHO_SAFE_ASSERT(fImageNormal.getSize() == fImageDown.getSize()); | |||
setSize(fImageNormal.getSize()); | |||
return *this; | |||
} | |||
bool ImageSwitch::isDown() const noexcept | |||
{ | |||
return fIsDown; | |||
} | |||
void ImageSwitch::setDown(bool down) noexcept | |||
{ | |||
if (fIsDown == down) | |||
return; | |||
fIsDown = down; | |||
repaint(); | |||
} | |||
void ImageSwitch::setCallback(Callback* callback) noexcept | |||
{ | |||
fCallback = callback; | |||
} | |||
void ImageSwitch::onDisplay() | |||
{ | |||
if (fIsDown) | |||
fImageDown.draw(); | |||
else | |||
fImageNormal.draw(); | |||
} | |||
bool ImageSwitch::onMouse(const MouseEvent& ev) | |||
{ | |||
if (ev.press && contains(ev.pos)) | |||
{ | |||
fIsDown = !fIsDown; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
fCallback->imageSwitchClicked(this, fIsDown); | |||
return true; | |||
} | |||
return false; | |||
} | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |