diff --git a/source/libs/distrho/dgl/ImageButton.hpp b/source/libs/distrho/dgl/ImageButton.hpp new file mode 100644 index 000000000..48a35a749 --- /dev/null +++ b/source/libs/distrho/dgl/ImageButton.hpp @@ -0,0 +1,62 @@ +/* + * 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_BUTTON_HPP__ +#define __DGL_IMAGE_BUTTON_HPP__ + +#include "Image.hpp" +#include "Widget.hpp" + +START_NAMESPACE_DISTRHO + +// ------------------------------------------------- + +class ImageButton : public Widget +{ +public: + class Callback + { + public: + virtual ~Callback() {} + virtual void imageButtonClicked(ImageButton* imageButton, int button) = 0; + }; + + ImageButton(Window* parent, const Image& image); + ImageButton(Window* parent, const Image& imageNormal, const Image& imageHover, const Image& imageDown); + ImageButton(const ImageButton& imageButton); + + 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 fImageNormal; + Image fImageHover; + Image fImageDown; + Image* fCurImage; + int fCurButton; + + Callback* fCallback; +}; + +// ------------------------------------------------- + +END_NAMESPACE_DISTRHO + +#endif // __DGL_IMAGE_BUTTON_HPP__ diff --git a/source/libs/distrho/dgl/Widget.hpp b/source/libs/distrho/dgl/Widget.hpp index 72983802c..c40178f8d 100644 --- a/source/libs/distrho/dgl/Widget.hpp +++ b/source/libs/distrho/dgl/Widget.hpp @@ -17,7 +17,7 @@ #ifndef __DGL_WIDGET_HPP__ #define __DGL_WIDGET_HPP__ -#include "Base.hpp" +#include "Geometry.hpp" START_NAMESPACE_DISTRHO @@ -44,19 +44,47 @@ public: setVisible(false); } + int getX() const; + int getY() const; + const Point& getPos() const; + + void setX(int x); + void setY(int y); + void setPos(int x, int y); + void setPos(const Point& pos); + + void move(int x, int y); + void move(const Point& pos); + + int getWidth() const; + int getHeight() const; + const Size& getSize() const; + + void setWidth(int width); + void setHeight(int height); + void setSize(int width, int height); + void setSize(const Size& size); + + const Rectangle& getArea() const; + + Window* getParent() const; + void repaint(); + protected: virtual void onDisplay(); - virtual void onKeyboard(bool press, uint32_t key); - virtual void onMouse(int button, bool press, int x, int y); - virtual void onMotion(int x, int y); - virtual void onScroll(float dx, float dy); - virtual void onSpecial(bool press, Key key); + virtual bool onKeyboard(bool press, uint32_t key); + virtual bool onMouse(int button, bool press, int x, int y); + virtual bool onMotion(int x, int y); + virtual bool onScroll(float dx, float dy); + virtual bool onSpecial(bool press, Key key); virtual void onReshape(int width, int height); virtual void onClose(); private: Window* fParent; - bool fVisible; + bool fVisible; + Rectangle fArea; + friend class Window; }; diff --git a/source/libs/distrho/dgl/src/Image.cpp b/source/libs/distrho/dgl/src/Image.cpp index b742d73bd..24bf93c14 100644 --- a/source/libs/distrho/dgl/src/Image.cpp +++ b/source/libs/distrho/dgl/src/Image.cpp @@ -97,7 +97,7 @@ void Image::draw(const Point& pos) if (! isValid()) return; - glRasterPos2i(pos.getX(), fSize.getHeight()-pos.getY()); + glRasterPos2i(pos.getX(), fSize.getHeight()+pos.getY()); glDrawPixels(fSize.getWidth(), fSize.getHeight(), fFormat, fType, fRawData); } diff --git a/source/libs/distrho/dgl/src/ImageButton.cpp b/source/libs/distrho/dgl/src/ImageButton.cpp new file mode 100644 index 000000000..1af327536 --- /dev/null +++ b/source/libs/distrho/dgl/src/ImageButton.cpp @@ -0,0 +1,148 @@ +/* + * 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 "../ImageButton.hpp" + +#include +#include + +START_NAMESPACE_DISTRHO + +// ------------------------------------------------- + +ImageButton::ImageButton(Window* parent, const Image& image) + : Widget(parent), + fImageNormal(image), + fImageHover(image), + fImageDown(image), + fCurImage(&fImageNormal), + fCurButton(-1), + fCallback(nullptr) +{ +} + +ImageButton::ImageButton(Window* parent, const Image& imageNormal, const Image& imageHover, const Image& imageDown) + : Widget(parent), + fImageNormal(imageNormal), + fImageHover(imageHover), + fImageDown(imageDown), + fCurImage(&fImageNormal), + fCurButton(-1), + fCallback(nullptr) +{ + assert(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); + + setSize(fCurImage->getSize()); +} + +ImageButton::ImageButton(const ImageButton& imageButton) + : Widget(imageButton.getParent()), + fImageNormal(imageButton.fImageNormal), + fImageHover(imageButton.fImageHover), + fImageDown(imageButton.fImageDown), + fCurImage(&fImageNormal), + fCurButton(-1), + fCallback(nullptr) +{ + assert(fImageNormal.getSize() == fImageHover.getSize() && fImageHover.getSize() == fImageDown.getSize()); + + setSize(fCurImage->getSize()); +} + +void ImageButton::setCallback(Callback* callback) +{ + fCallback = callback; +} + +void ImageButton::onDisplay() +{ + fCurImage->draw(getPos()); +} + +bool ImageButton::onMouse(int button, bool press, int x, int y) +{ + if (fCurButton != -1 && ! press) + { + if (getArea().contains(x, y)) + { + if (fCurImage != &fImageHover) + { + fCurImage = &fImageHover; + repaint(); + } + } + else + { + if (fCurImage != &fImageNormal) + { + fCurImage = &fImageNormal; + repaint(); + } + } + + if (fCallback != nullptr) + fCallback->imageButtonClicked(this, fCurButton); + + fCurButton = -1; + + return true; + } + + if (press && getArea().contains(x, y)) + { + if (fCurImage != &fImageDown) + { + fCurImage = &fImageDown; + repaint(); + } + + fCurButton = button; + return true; + } + + return false; +} + +bool ImageButton::onMotion(int x, int y) +{ + if (fCurButton != -1) + return true; + + if (getArea().contains(x, y)) + { + if (fCurImage != &fImageHover) + { + fCurImage = &fImageHover; + repaint(); + } + + return true; + } + else + { + if (fCurImage != &fImageNormal) + { + fCurImage = &fImageNormal; + repaint(); + } + + return false; + } +} + +// ------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/source/libs/distrho/dgl/src/Widget.cpp b/source/libs/distrho/dgl/src/Widget.cpp index 346ba6e27..edf1f5b50 100644 --- a/source/libs/distrho/dgl/src/Widget.cpp +++ b/source/libs/distrho/dgl/src/Widget.cpp @@ -50,27 +50,148 @@ void Widget::setVisible(bool yesNo) fParent->repaint(); } +int Widget::getX() const +{ + return fArea.getX(); +} + +int Widget::getY() const +{ + return fArea.getY(); +} + +const Point& Widget::getPos() const +{ + return fArea.getPos(); +} + +void Widget::setX(int x) +{ + if (fArea.getX() == x) + return; + + fArea.setX(x); + repaint(); +} + +void Widget::setY(int y) +{ + if (fArea.getY() == y) + return; + + fArea.setY(y); + repaint(); +} + +void Widget::setPos(int x, int y) +{ + setPos(Point(x, y)); +} + +void Widget::setPos(const Point& pos) +{ + if (fArea.getPos() == pos) + return; + + fArea.setPos(pos); + repaint(); +} + +void Widget::move(int x, int y) +{ + fArea.move(x, y); + repaint(); +} + +void Widget::move(const Point& pos) +{ + fArea.move(pos); + repaint(); +} + +int Widget::getWidth() const +{ + return fArea.getWidth(); +} + +int Widget::getHeight() const +{ + return fArea.getHeight(); +} + +const Size& Widget::getSize() const +{ + return fArea.getSize(); +} + +void Widget::setWidth(int width) +{ + if (fArea.getWidth() == width) + return; + + fArea.setWidth(width); + fParent->repaint(); +} + +void Widget::setHeight(int height) +{ + if (fArea.getHeight() == height) + return; + + fArea.setHeight(height); + fParent->repaint(); +} + +void Widget::setSize(int width, int height) +{ + setSize(Size(width, height)); +} + +void Widget::setSize(const Size& size) +{ + if (fArea.getSize() == size) + return; + + fArea.setSize(size); + fParent->repaint(); +} + +const Rectangle& Widget::getArea() const +{ + return fArea; +} + +Window* Widget::getParent() const +{ + return fParent; +} + +void Widget::repaint() +{ + fParent->repaint(); +} + void Widget::onDisplay() { } -void Widget::onKeyboard(bool, uint32_t) +bool Widget::onKeyboard(bool, uint32_t) { } -void Widget::onMouse(int, bool, int, int) +bool Widget::onMouse(int, bool, int, int) { } -void Widget::onMotion(int, int) +bool Widget::onMotion(int, int) { } -void Widget::onScroll(float, float) +bool Widget::onScroll(float, float) { } -void Widget::onSpecial(bool, Key) +bool Widget::onSpecial(bool, Key) { } diff --git a/source/libs/distrho/dgl/src/Window.cpp b/source/libs/distrho/dgl/src/Window.cpp index bc9be1437..f0e9c192e 100644 --- a/source/libs/distrho/dgl/src/Window.cpp +++ b/source/libs/distrho/dgl/src/Window.cpp @@ -47,7 +47,10 @@ static Bool isUnmapNotify(Display*, XEvent* ev, XPointer win) #endif #define FOR_EACH_WIDGET(it) \ - for (auto it = fWidgets.begin(); it != fWidgets.end(); 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) // ------------------------------------------------- // Window Private @@ -305,11 +308,14 @@ protected: if (fChildFocus != nullptr) return fChildFocus->focus(); - FOR_EACH_WIDGET(it) + FOR_EACH_WIDGET_INV(rit) { - Widget* widget = *it; + Widget* widget = *rit; if (widget->isVisible()) - widget->onKeyboard(press, key); + { + if (widget->onKeyboard(press, key)) + break; + } } } @@ -318,11 +324,14 @@ protected: if (fChildFocus != nullptr) return fChildFocus->focus(); - FOR_EACH_WIDGET(it) + FOR_EACH_WIDGET_INV(rit) { - Widget* widget = *it; + Widget* widget = *rit; if (widget->isVisible()) - widget->onMouse(button, press, x, y); + { + if (widget->onMouse(button, press, x, y)) + break; + } } } @@ -331,11 +340,14 @@ protected: if (fChildFocus != nullptr) return; - FOR_EACH_WIDGET(it) + FOR_EACH_WIDGET_INV(rit) { - Widget* widget = *it; + Widget* widget = *rit; if (widget->isVisible()) - widget->onMotion(x, y); + { + if (widget->onMotion(x, y)) + break; + } } } @@ -344,11 +356,14 @@ protected: if (fChildFocus != nullptr) return; - FOR_EACH_WIDGET(it) + FOR_EACH_WIDGET_INV(rit) { - Widget* widget = *it; + Widget* widget = *rit; if (widget->isVisible()) - widget->onScroll(dx, dy); + { + if (widget->onScroll(dx, dy)) + break; + } } } @@ -357,11 +372,14 @@ protected: if (fChildFocus != nullptr) return; - FOR_EACH_WIDGET(it) + FOR_EACH_WIDGET_INV(rit) { - Widget* widget = *it; + Widget* widget = *rit; if (widget->isVisible()) - widget->onSpecial(press, key); + { + if (widget->onSpecial(press, key)) + break; + } } }