From b82d3403aae76d30f525fbf897d2b64d197980bc Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 26 Feb 2013 08:08:30 +0000 Subject: [PATCH] Add ImageSlider class; misc fixes --- source/libs/distrho/dgl/Geometry.hpp | 2 + source/libs/distrho/dgl/Image.hpp | 1 + source/libs/distrho/dgl/ImageSlider.hpp | 80 +++++++ source/libs/distrho/dgl/src/Geometry.cpp | 12 + source/libs/distrho/dgl/src/Image.cpp | 11 +- source/libs/distrho/dgl/src/ImageSlider.cpp | 253 ++++++++++++++++++++ source/libs/distrho/dgl/src/Widget.cpp | 5 + 7 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 source/libs/distrho/dgl/ImageSlider.hpp create mode 100644 source/libs/distrho/dgl/src/ImageSlider.cpp diff --git a/source/libs/distrho/dgl/Geometry.hpp b/source/libs/distrho/dgl/Geometry.hpp index c8b0abbee..12c6f4ca8 100644 --- a/source/libs/distrho/dgl/Geometry.hpp +++ b/source/libs/distrho/dgl/Geometry.hpp @@ -103,6 +103,8 @@ public: bool contains(T x, T y) const; bool contains(const Point& pos) const; + bool containsX(T x) const; + bool containsY(T y) const; void setX(T x); void setY(T y); diff --git a/source/libs/distrho/dgl/Image.hpp b/source/libs/distrho/dgl/Image.hpp index f81bd9012..2a68c14fd 100644 --- a/source/libs/distrho/dgl/Image.hpp +++ b/source/libs/distrho/dgl/Image.hpp @@ -43,6 +43,7 @@ public: GLenum getType() const; void draw(); + void draw(int x, int y); void draw(const Point& pos); Image& operator=(const Image& image); diff --git a/source/libs/distrho/dgl/ImageSlider.hpp b/source/libs/distrho/dgl/ImageSlider.hpp new file mode 100644 index 000000000..cf2734af1 --- /dev/null +++ b/source/libs/distrho/dgl/ImageSlider.hpp @@ -0,0 +1,80 @@ +/* + * DISTRHO Plugin Toolkit (DPT) + * Copyright (C) 2012-2013 Filipe Coelho + * + * 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_SLIDER_HPP__ +#define __DGL_IMAGE_SLIDER_HPP__ + +#include "Image.hpp" +#include "Widget.hpp" + +START_NAMESPACE_DISTRHO + +// ------------------------------------------------- + +class ImageSlider : public Widget +{ +public: + class Callback + { + public: + virtual ~Callback() {} + virtual void imageSliderDragStarted(ImageSlider* imageSlider) = 0; + virtual void imageSliderDragFinished(ImageSlider* imageSlider) = 0; + virtual void imageSliderValueChanged(ImageSlider* imageSlider, float value) = 0; + }; + + ImageSlider(Window* parent, const Image& image); + ImageSlider(const ImageSlider& imageSlider); + + float getValue() const; + + void setStartPos(const Point& startPos); + void setEndPos(const Point& endPos); + + 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; + + bool fDragging; + int fStartedX; + int fStartedY; + + Callback* fCallback; + + Point fStartPos; + Point fEndPos; + Rectangle fSliderArea; + + void _recheckArea(); +}; + +// ------------------------------------------------- + +END_NAMESPACE_DISTRHO + +#endif // __DGL_IMAGE_SLIDER_HPP__ diff --git a/source/libs/distrho/dgl/src/Geometry.cpp b/source/libs/distrho/dgl/src/Geometry.cpp index ee6740bc8..4b8927cc4 100644 --- a/source/libs/distrho/dgl/src/Geometry.cpp +++ b/source/libs/distrho/dgl/src/Geometry.cpp @@ -309,6 +309,18 @@ bool Rectangle::contains(const Point& pos) const return contains(pos.fX, pos.fY); } +template +bool Rectangle::containsX(T x) const +{ + return (x >= fPos.fX && x <= fPos.fX + fSize.fWidth); +} + +template +bool Rectangle::containsY(T y) const +{ + return (y >= fPos.fY && y <= fPos.fY + fSize.fHeight); +} + template void Rectangle::setX(T x) { diff --git a/source/libs/distrho/dgl/src/Image.cpp b/source/libs/distrho/dgl/src/Image.cpp index 24bf93c14..249ba0177 100644 --- a/source/libs/distrho/dgl/src/Image.cpp +++ b/source/libs/distrho/dgl/src/Image.cpp @@ -89,18 +89,23 @@ GLenum Image::getType() const void Image::draw() { - draw(Point(0, 0)); + draw(0, 0); } -void Image::draw(const Point& pos) +void Image::draw(int x, int y) { if (! isValid()) return; - glRasterPos2i(pos.getX(), fSize.getHeight()+pos.getY()); + glRasterPos2i(x, fSize.getHeight()+y); glDrawPixels(fSize.getWidth(), fSize.getHeight(), fFormat, fType, fRawData); } +void Image::draw(const Point& pos) +{ + draw(pos.getX(), pos.getY()); +} + Image& Image::operator=(const Image& image) { fRawData = image.fRawData; diff --git a/source/libs/distrho/dgl/src/ImageSlider.cpp b/source/libs/distrho/dgl/src/ImageSlider.cpp new file mode 100644 index 000000000..7db815896 --- /dev/null +++ b/source/libs/distrho/dgl/src/ImageSlider.cpp @@ -0,0 +1,253 @@ +/* + * DISTRHO Plugin Toolkit (DPT) + * Copyright (C) 2012-2013 Filipe Coelho + * + * 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 "../ImageSlider.hpp" + +START_NAMESPACE_DISTRHO + +// ------------------------------------------------- + +ImageSlider::ImageSlider(Window* parent, const Image& image) + : Widget(parent), + fImage(image), + fMinimum(0.0f), + fMaximum(1.0f), + fValue(0.5f), + fDragging(false), + fStartedX(0), + fStartedY(0), + fCallback(nullptr) +{ + setSize(fImage.getSize()); +} + +ImageSlider::ImageSlider(const ImageSlider& imageSlider) + : Widget(imageSlider.getParent()), + fImage(imageSlider.fImage), + fMinimum(imageSlider.fMinimum), + fMaximum(imageSlider.fMaximum), + fValue(imageSlider.fValue), + fDragging(false), + fStartedX(0), + fStartedY(0), + fCallback(nullptr) +{ + setSize(fImage.getSize()); +} + +float ImageSlider::getValue() const +{ + return fValue; +} + +void ImageSlider::setStartPos(const Point& startPos) +{ + fStartPos = startPos; + _recheckArea(); +} + +void ImageSlider::setEndPos(const Point& endPos) +{ + fEndPos = endPos; + _recheckArea(); +} + +void ImageSlider::setRange(float min, float max) +{ + if (fValue < min) + { + fValue = min; + repaint(); + + if (fCallback != nullptr) + fCallback->imageSliderValueChanged(this, fValue); + } + else if (fValue > max) + { + fValue = max; + repaint(); + + if (fCallback != nullptr) + fCallback->imageSliderValueChanged(this, fValue); + } + + fMinimum = min; + fMaximum = max; +} + +void ImageSlider::setValue(float value, bool sendCallback) +{ + if (fValue == value) + return; + + fValue = value; + repaint(); + + if (sendCallback && fCallback != nullptr) + fCallback->imageSliderValueChanged(this, fValue); +} + +void ImageSlider::setCallback(Callback* callback) +{ + 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()); +#endif + + float normValue = (fValue - fMinimum) / (fMaximum - fMinimum); + + int x, y; + + if (fStartPos.getX() == fEndPos.getX()) + { + x = fStartPos.getX(); + y = fStartPos.getY() + normValue*(fEndPos.getY()-fStartPos.getY()); + } + else if (fStartPos.getY() == fEndPos.getY()) + { + x = fStartPos.getX() + normValue*(fEndPos.getX()-fStartPos.getX()); + y = fStartPos.getY(); + } + else + return; + + fImage.draw(x, y); +} + +bool ImageSlider::onMouse(int button, bool press, int x, int y) +{ + if (button != 1) + return false; + + if (press) + { + if (! fSliderArea.contains(x, y)) + return false; + + float vper; + + if (fStartPos.getX() == fEndPos.getX()) + { + // vertical + vper = float(y - fSliderArea.getY()) / float(fSliderArea.getHeight()); + } + else if (fStartPos.getY() == fEndPos.getY()) + { + // horizontal + vper = float(x - fSliderArea.getX()) / float(fSliderArea.getWidth()); + } + else + return false; + + float value = vper * (fMaximum - fMinimum) + fMinimum; + + if (value < fMinimum) + value = fMinimum; + else if (value > fMaximum) + value = fMaximum; + + 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(int x, int y) +{ + if (! fDragging) + return false; + + bool horizontal = fStartPos.getY() == fEndPos.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 = vper * (fMaximum - fMinimum) + fMinimum; + + if (value < fMinimum) + value = fMinimum; + else if (value > fMaximum) + value = fMaximum; + + setValue(value, true); + } + else if (y < fSliderArea.getY()) + { + setValue(horizontal ? fMaximum : fMinimum, true); + } + else + { + setValue(horizontal ? fMinimum : fMaximum, true); + } + + return true; +} + +void ImageSlider::_recheckArea() +{ + if (fStartPos.getX() == fEndPos.getX()) + { + fSliderArea = Rectangle(fStartPos.getX(), + fStartPos.getY(), + fImage.getWidth(), + fEndPos.getY() + fImage.getHeight() - fStartPos.getY()); + } + else if (fStartPos.getY() == fEndPos.getY()) + { + fSliderArea = Rectangle(fStartPos.getX(), + fStartPos.getY(), + fEndPos.getX() + fImage.getWidth() - fStartPos.getX(), + fImage.getHeight()); + } +} + +// ------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/source/libs/distrho/dgl/src/Widget.cpp b/source/libs/distrho/dgl/src/Widget.cpp index edf1f5b50..929c65f17 100644 --- a/source/libs/distrho/dgl/src/Widget.cpp +++ b/source/libs/distrho/dgl/src/Widget.cpp @@ -177,22 +177,27 @@ void Widget::onDisplay() bool Widget::onKeyboard(bool, uint32_t) { + return false; } bool Widget::onMouse(int, bool, int, int) { + return false; } bool Widget::onMotion(int, int) { + return false; } bool Widget::onScroll(float, float) { + return false; } bool Widget::onSpecial(bool, Key) { + return false; } void Widget::onReshape(int width, int height)