This concludes the "DISTRHO Plugin Toolkit" code! :)tags/1.9.4
@@ -0,0 +1,83 @@ | |||
/* | |||
* DISTRHO Plugin Toolkit (DPT) | |||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* For a full copy of the license see the LGPL.txt file | |||
*/ | |||
#ifndef __DGL_IMAGE_KNOB_HPP__ | |||
#define __DGL_IMAGE_KNOB_HPP__ | |||
#include "Image.hpp" | |||
#include "Widget.hpp" | |||
START_NAMESPACE_DISTRHO | |||
// ------------------------------------------------- | |||
class ImageKnob : public Widget | |||
{ | |||
public: | |||
enum Orientation { | |||
Horizontal, | |||
Vertical | |||
}; | |||
class Callback | |||
{ | |||
public: | |||
virtual ~Callback() {} | |||
virtual void imageKnobDragStarted(ImageKnob* imageKnob) = 0; | |||
virtual void imageKnobDragFinished(ImageKnob* imageKnob) = 0; | |||
virtual void imageKnobValueChanged(ImageKnob* imageKnob, float value) = 0; | |||
}; | |||
ImageKnob(Window* parent, const Image& image, Orientation orientation = Vertical); | |||
ImageKnob(const ImageKnob& imageKnob); | |||
float getValue() const; | |||
void setOrientation(Orientation orientation); | |||
void setRange(float min, float max); | |||
void setValue(float value, bool sendCallback = false); | |||
void setCallback(Callback* callback); | |||
protected: | |||
void onDisplay(); | |||
bool onMouse(int button, bool press, int x, int y); | |||
bool onMotion(int x, int y); | |||
private: | |||
Image fImage; | |||
float fMinimum; | |||
float fMaximum; | |||
float fValue; | |||
Orientation fOrientation; | |||
bool fDragging; | |||
int fLastX; | |||
int fLastY; | |||
Callback* fCallback; | |||
bool fIsImgVertical; | |||
int fImgLayerSize; | |||
int fImgLayerCount; | |||
Rectangle<int> fKnobArea; | |||
}; | |||
// ------------------------------------------------- | |||
END_NAMESPACE_DISTRHO | |||
#endif // __DGL_IMAGE_KNOB_HPP__ |
@@ -67,6 +67,8 @@ public: | |||
const Rectangle<int>& getArea() const; | |||
int getModifiers(); | |||
Window* getParent() const; | |||
void repaint(); | |||
@@ -44,6 +44,7 @@ public: | |||
void setSize(unsigned int width, unsigned int height); | |||
void setWindowTitle(const char* title); | |||
int getModifiers(); | |||
intptr_t getWindowId(); | |||
void addWidget(Widget* widget); | |||
@@ -81,6 +81,12 @@ bool ImageButton::onMouse(int button, bool press, int x, int y) | |||
repaint(); | |||
} | |||
if (! getArea().contains(x, y)) | |||
{ | |||
fCurButton = -1; | |||
return false; | |||
} | |||
if (fCallback != nullptr) | |||
fCallback->imageButtonClicked(this, fCurButton); | |||
@@ -0,0 +1,206 @@ | |||
/* | |||
* DISTRHO Plugin Toolkit (DPT) | |||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* For a full copy of the license see the LGPL.txt file | |||
*/ | |||
#include "../ImageKnob.hpp" | |||
START_NAMESPACE_DISTRHO | |||
// ------------------------------------------------- | |||
ImageKnob::ImageKnob(Window* parent, const Image& image, Orientation orientation) | |||
: Widget(parent), | |||
fImage(image), | |||
fMinimum(0.0f), | |||
fMaximum(1.0f), | |||
fValue(0.5f), | |||
fOrientation(orientation), | |||
fDragging(false), | |||
fLastX(0), | |||
fLastY(0), | |||
fCallback(nullptr), | |||
fIsImgVertical(image.getHeight() > image.getWidth()), | |||
fImgLayerSize(fIsImgVertical ? image.getWidth() : image.getHeight()), | |||
fImgLayerCount(fIsImgVertical ? image.getHeight()/fImgLayerSize : image.getWidth()/fImgLayerSize), | |||
fKnobArea(0, 0, fImgLayerSize, fImgLayerSize) | |||
{ | |||
setSize(fImgLayerSize, fImgLayerSize); | |||
} | |||
ImageKnob::ImageKnob(const ImageKnob& imageKnob) | |||
: Widget(imageKnob.getParent()), | |||
fImage(imageKnob.fImage), | |||
fMinimum(imageKnob.fMinimum), | |||
fMaximum(imageKnob.fMaximum), | |||
fValue(imageKnob.fValue), | |||
fOrientation(imageKnob.fOrientation), | |||
fDragging(false), | |||
fLastX(0), | |||
fLastY(0), | |||
fCallback(nullptr), | |||
fIsImgVertical(imageKnob.fIsImgVertical), | |||
fImgLayerSize(imageKnob.fImgLayerSize), | |||
fImgLayerCount(imageKnob.fImgLayerCount), | |||
fKnobArea(imageKnob.fKnobArea) | |||
{ | |||
setSize(fImgLayerSize, fImgLayerSize); | |||
} | |||
float ImageKnob::getValue() const | |||
{ | |||
return fValue; | |||
} | |||
void ImageKnob::setOrientation(Orientation orientation) | |||
{ | |||
if (fOrientation == orientation) | |||
return; | |||
fOrientation = orientation; | |||
} | |||
void ImageKnob::setRange(float min, float max) | |||
{ | |||
if (fValue < min) | |||
{ | |||
fValue = min; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} | |||
else if (fValue > max) | |||
{ | |||
fValue = max; | |||
repaint(); | |||
if (fCallback != nullptr) | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} | |||
fMinimum = min; | |||
fMaximum = max; | |||
} | |||
void ImageKnob::setValue(float value, bool sendCallback) | |||
{ | |||
if (fValue == value) | |||
return; | |||
fValue = value; | |||
repaint(); | |||
if (sendCallback && fCallback != nullptr) | |||
fCallback->imageKnobValueChanged(this, fValue); | |||
} | |||
void ImageKnob::setCallback(Callback* callback) | |||
{ | |||
fCallback = callback; | |||
} | |||
void ImageKnob::onDisplay() | |||
{ | |||
float normValue = (fValue - fMinimum) / (fMaximum - fMinimum); | |||
// FIXME: assuming GL_BGRA data (* 4) | |||
int layerDataSize = fImgLayerSize * fImgLayerSize * 4; | |||
int imageDataSize = layerDataSize * fImgLayerCount; | |||
int imageDataOffset = imageDataSize - layerDataSize - (layerDataSize * int(normValue * float(fImgLayerCount-1))); | |||
glRasterPos2i(getX(), getY()+getHeight()); | |||
glDrawPixels(fImgLayerSize, fImgLayerSize, fImage.getFormat(), fImage.getType(), fImage.getRawData() + imageDataOffset); | |||
} | |||
bool ImageKnob::onMouse(int button, bool press, int x, int y) | |||
{ | |||
if (button != 1) | |||
return false; | |||
if (press) | |||
{ | |||
if (! getArea().contains(x, y)) | |||
return false; | |||
fDragging = true; | |||
fLastX = x; | |||
fLastY = y; | |||
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(int x, int y) | |||
{ | |||
if (! fDragging) | |||
return false; | |||
if (fOrientation == ImageKnob::Horizontal) | |||
{ | |||
int movX = x - fLastX; | |||
if (movX != 0) | |||
{ | |||
float d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f; | |||
float value = fValue + (float(fMaximum - fMinimum) / d * float(movX)); | |||
if (value < fMinimum) | |||
value = fMinimum; | |||
else if (value > fMaximum) | |||
value = fMaximum; | |||
setValue(value, true); | |||
} | |||
} | |||
else if (fOrientation == ImageKnob::Vertical) | |||
{ | |||
int movY = fLastY - y; | |||
if (movY != 0) | |||
{ | |||
float d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f; | |||
float value = fValue + (float(fMaximum - fMinimum) / d * float(movY)); | |||
if (value < fMinimum) | |||
value = fMinimum; | |||
else if (value > fMaximum) | |||
value = fMaximum; | |||
setValue(value, true); | |||
} | |||
} | |||
fLastX = x; | |||
fLastY = y; | |||
return true; | |||
} | |||
// ------------------------------------------------- | |||
END_NAMESPACE_DISTRHO |
@@ -43,7 +43,10 @@ ImageSlider::ImageSlider(const ImageSlider& imageSlider) | |||
fDragging(false), | |||
fStartedX(0), | |||
fStartedY(0), | |||
fCallback(nullptr) | |||
fCallback(nullptr), | |||
fStartPos(imageSlider.fStartPos), | |||
fEndPos(imageSlider.fEndPos), | |||
fSliderArea(imageSlider.fSliderArea) | |||
{ | |||
setSize(fImage.getSize()); | |||
} | |||
@@ -161,6 +161,11 @@ const Rectangle<int>& Widget::getArea() const | |||
return fArea; | |||
} | |||
int Widget::getModifiers() | |||
{ | |||
return fParent->getModifiers(); | |||
} | |||
Window* Widget::getParent() const | |||
{ | |||
return fParent; | |||
@@ -30,28 +30,14 @@ | |||
# error Unsupported platform! | |||
#endif | |||
START_NAMESPACE_DISTRHO | |||
// ------------------------------------------------- | |||
// Utils | |||
#if DISTRHO_OS_LINUX | |||
static Bool isMapNotify(Display*, XEvent* ev, XPointer win) | |||
{ | |||
return (ev->type == MapNotify && ev->xmap.window == *((::Window*)win)); | |||
} | |||
static Bool isUnmapNotify(Display*, XEvent* ev, XPointer win) | |||
{ | |||
return (ev->type == UnmapNotify && ev->xunmap.window == *((::Window*)win)); | |||
} | |||
#endif | |||
#define FOR_EACH_WIDGET(it) \ | |||
for (auto it = fWidgets.begin(); it != fWidgets.end(); ++it) | |||
#define FOR_EACH_WIDGET_INV(rit) \ | |||
for (auto rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit) | |||
START_NAMESPACE_DISTRHO | |||
// ------------------------------------------------- | |||
// Window Private | |||
@@ -259,6 +245,11 @@ public: | |||
#endif | |||
} | |||
int getModifiers() | |||
{ | |||
return puglGetModifiers(kView); | |||
} | |||
intptr_t getWindowId() | |||
{ | |||
return puglGetNativeWindow(kView); | |||
@@ -517,6 +508,11 @@ void Window::setWindowTitle(const char* title) | |||
kPrivate->setWindowTitle(title); | |||
} | |||
int Window::getModifiers() | |||
{ | |||
return kPrivate->getModifiers(); | |||
} | |||
intptr_t Window::getWindowId() | |||
{ | |||
return kPrivate->getWindowId(); | |||