diff --git a/dgl/Image.hpp b/dgl/Image.hpp index 634665ff..138a9147 100644 --- a/dgl/Image.hpp +++ b/dgl/Image.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -22,103 +22,8 @@ START_NAMESPACE_DGL -// ----------------------------------------------------------------------- - -/** - OpenGL Image class. - - This is an Image class that handles raw image data in pixels. - You can init the image data on the contructor or later on by calling loadFromMemory(). - - To generate raw data useful for this class see the utils/png2rgba.py script. - Be careful when using a PNG without alpha channel, for those the format is 'GL_BGR' - instead of the default 'GL_BGRA'. - - Images are drawn on screen via 2D textures. - */ -class Image : public ImageBase -{ -public: - /** - Constructor for a null Image. - */ - Image(); - - /** - Constructor using raw image data. - @note @a rawData must remain valid for the lifetime of this Image. - */ - Image(const char* const rawData, - const uint width, - const uint height, - const GLenum format = GL_BGRA, - const GLenum type = GL_UNSIGNED_BYTE); - - /** - Constructor using raw image data. - @note @a rawData must remain valid for the lifetime of this Image. - */ - Image(const char* const rawData, - const Size& size, - const GLenum format = GL_BGRA, - const GLenum type = GL_UNSIGNED_BYTE); - - /** - Constructor using another image data. - */ - Image(const Image& image); - - /** - Destructor. - */ - ~Image() override; - - /** - Load image data from memory. - @note @a rawData must remain valid for the lifetime of this Image. - */ - void loadFromMemory(const char* const rawData, - const uint width, - const uint height, - const GLenum format = GL_BGRA, - const GLenum type = GL_UNSIGNED_BYTE) noexcept; - - /** - Load image data from memory. - @note @a rawData must remain valid for the lifetime of this Image. - */ - void loadFromMemory(const char* const rawData, - const Size& size, - const GLenum format = GL_BGRA, - const GLenum type = GL_UNSIGNED_BYTE) noexcept; - - /** - Get the image format. - */ - GLenum getFormat() const noexcept; - - /** - Get the image type. - */ - GLenum getType() const noexcept; - - /** - TODO document this. - */ - Image& operator=(const Image& image) noexcept; - -protected: - /** @internal */ - void _drawAt(const Point& pos) override; - -private: - GLenum fFormat; - GLenum fType; - GLuint fTextureId; - bool fIsReady; -}; - -// ----------------------------------------------------------------------- +// TODO mark as deprecated +typedef OpenGLImage Image; END_NAMESPACE_DGL diff --git a/dgl/ImageBase.hpp b/dgl/ImageBase.hpp index 0a7ee780..8f71aa42 100644 --- a/dgl/ImageBase.hpp +++ b/dgl/ImageBase.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -21,7 +21,7 @@ START_NAMESPACE_DGL -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- /** Base DGL Image class. @@ -68,6 +68,11 @@ public: */ bool isValid() const noexcept; + /** + Check if this image is not valid. + */ + bool isInvalid() const noexcept; + /** Get width. */ @@ -89,19 +94,19 @@ public: const char* getRawData() const noexcept; /** - Draw this image at (0, 0) point. + Draw this image at (0, 0) point using the current OpenGL context. */ - void draw(); + void draw(const GraphicsContext& context); /** - Draw this image at (x, y) point. + Draw this image at (x, y) point using the current OpenGL context. */ - void drawAt(const int x, const int y); + void drawAt(const GraphicsContext& context, const int x, const int y); /** - Draw this image at position @a pos. + Draw this image at position @a pos using the current OpenGL context. */ - void drawAt(const Point& pos); + virtual void drawAt(const GraphicsContext& context, const Point& pos) = 0; /** TODO document this. @@ -111,14 +116,11 @@ public: bool operator!=(const ImageBase& image) const noexcept; protected: - /** @internal */ - virtual void _drawAt(const Point& pos) = 0; - - const char* fRawData; - Size fSize; + const char* rawData; + Size size; }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/OpenGL.hpp b/dgl/OpenGL.hpp index 622ec89d..db1e0729 100644 --- a/dgl/OpenGL.hpp +++ b/dgl/OpenGL.hpp @@ -116,6 +116,135 @@ struct OpenGLGraphicsContext : GraphicsContext // ----------------------------------------------------------------------- +/** + OpenGL Image class. + + This is an Image class that handles raw image data in pixels. + You can init the image data on the contructor or later on by calling loadFromMemory(). + + To generate raw data useful for this class see the utils/png2rgba.py script. + Be careful when using a PNG without alpha channel, for those the format is 'GL_BGR' + instead of the default 'GL_BGRA'. + + Images are drawn on screen via 2D textures. + */ +class OpenGLImage : public ImageBase +{ +public: + /** + Constructor for a null Image. + */ + OpenGLImage(); + + /** + Constructor using raw image data. + @note @a rawData must remain valid for the lifetime of this Image. + */ + OpenGLImage(const char* const rawData, + const uint width, + const uint height, + const GLenum format = GL_BGRA, + const GLenum type = GL_UNSIGNED_BYTE); + + /** + Constructor using raw image data. + @note @a rawData must remain valid for the lifetime of this Image. + */ + OpenGLImage(const char* const rawData, + const Size& size, + const GLenum format = GL_BGRA, + const GLenum type = GL_UNSIGNED_BYTE); + + /** + Constructor using another image data. + */ + OpenGLImage(const OpenGLImage& image); + + /** + Destructor. + */ + ~OpenGLImage() override; + + /** + Load image data from memory. + @note @a rawData must remain valid for the lifetime of this Image. + */ + void loadFromMemory(const char* const rawData, + const uint width, + const uint height, + const GLenum format = GL_BGRA, + const GLenum type = GL_UNSIGNED_BYTE) noexcept; + + /** + Load image data from memory. + @note @a rawData must remain valid for the lifetime of this Image. + */ + void loadFromMemory(const char* const rawData, + const Size& size, + const GLenum format = GL_BGRA, + const GLenum type = GL_UNSIGNED_BYTE) noexcept; + + /** + TODO document this. + */ + void setup(); + + /** + TODO document this. + */ + void cleanup(); + + /** + Get the image format. + */ + GLenum getFormat() const noexcept; + + /** + Get the image type. + */ + GLenum getType() const noexcept; + + /** + Draw this image at position @a pos using the graphics context @a context. + */ + void drawAt(const GraphicsContext& context, const Point& pos) override; + + /** + TODO document this. + */ + OpenGLImage& operator=(const OpenGLImage& image) noexcept; + + /** + Draw this image at (0, 0) point using the current OpenGL context. + */ + // TODO mark as deprecated + void draw(); + + /** + Draw this image at (x, y) point using the current OpenGL context. + */ + // TODO mark as deprecated + void drawAt(const int x, const int y); + + /** + Draw this image at position @a pos using the current OpenGL context. + */ + // TODO mark as deprecated + void drawAt(const Point& pos); + +protected: + /** @internal */ +// void _drawAt(const Point& pos) override; + +private: + GLenum fFormat; + GLenum fType; + GLuint fTextureId; + bool setupCalled; +}; + +// ----------------------------------------------------------------------- + END_NAMESPACE_DGL #endif diff --git a/dgl/src/Image.cpp b/dgl/src/Image.cpp deleted file mode 100644 index 90596fec..00000000 --- a/dgl/src/Image.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho - * - * 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 "../Image.hpp" - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- - -Image::Image() - : ImageBase(), - fFormat(0), - fType(0), - fTextureId(0), - fIsReady(false) -{ - glGenTextures(1, &fTextureId); -} - -Image::Image(const Image& image) - : ImageBase(image), - fFormat(image.fFormat), - fType(image.fType), - fTextureId(0), - fIsReady(false) -{ - glGenTextures(1, &fTextureId); -} - -Image::Image(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type) - : ImageBase(rawData, width, height), - fFormat(format), - fType(type), - fTextureId(0), - fIsReady(false) -{ - glGenTextures(1, &fTextureId); -} - -Image::Image(const char* const rawData, const Size& size, const GLenum format, const GLenum type) - : ImageBase(rawData, size), - fFormat(format), - fType(type), - fTextureId(0), - fIsReady(false) -{ - glGenTextures(1, &fTextureId); -} - -Image::~Image() -{ - if (fTextureId != 0) - { -#ifndef DISTRHO_OS_MAC // FIXME - glDeleteTextures(1, &fTextureId); -#endif - fTextureId = 0; - } -} - -void Image::loadFromMemory(const char* const rawData, - const uint width, - const uint height, - const GLenum format, - const GLenum type) noexcept -{ - loadFromMemory(rawData, Size(width, height), format, type); -} - -void Image::loadFromMemory(const char* const rawData, - const Size& size, - const GLenum format, - const GLenum type) noexcept -{ - fRawData = rawData; - fSize = size; - fFormat = format; - fType = type; - fIsReady = false; -} - -GLenum Image::getFormat() const noexcept -{ - return fFormat; -} - -GLenum Image::getType() const noexcept -{ - return fType; -} - -Image& Image::operator=(const Image& image) noexcept -{ - fRawData = image.fRawData; - fSize = image.fSize; - fFormat = image.fFormat; - fType = image.fType; - fIsReady = false; - return *this; -} - -void Image::_drawAt(const Point& pos) -{ - if (fTextureId == 0 || ! isValid()) - return; - - 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); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - static_cast(fSize.getWidth()), static_cast(fSize.getHeight()), 0, - fFormat, fType, fRawData); - - fIsReady = true; - } - - Rectangle(pos, static_cast(fSize.getWidth()), static_cast(fSize.getHeight())).draw(); - - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); -} - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL diff --git a/dgl/src/ImageBase.cpp b/dgl/src/ImageBase.cpp index b5dfbb96..82151cc3 100644 --- a/dgl/src/ImageBase.cpp +++ b/dgl/src/ImageBase.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -18,82 +18,83 @@ START_NAMESPACE_DGL -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- +// protected constructors ImageBase::ImageBase() - : fRawData(nullptr), - fSize(0, 0) {} + : rawData(nullptr), + size(0, 0) {} -ImageBase::ImageBase(const char* const rawData, const uint width, const uint height) - : fRawData(rawData), - fSize(width, height) {} +ImageBase::ImageBase(const char* const rdata, const uint width, const uint height) + : rawData(rdata), + size(width, height) {} -ImageBase::ImageBase(const char* const rawData, const Size& size) - : fRawData(rawData), - fSize(size) {} +ImageBase::ImageBase(const char* const rdata, const Size& s) + : rawData(rdata), + size(s) {} ImageBase::ImageBase(const ImageBase& image) - : fRawData(image.fRawData), - fSize(image.fSize) {} + : rawData(image.rawData), + size(image.size) {} -ImageBase::~ImageBase() {} +// -------------------------------------------------------------------------------------------------------------------- +// public methods -// ----------------------------------------------------------------------- +ImageBase::~ImageBase() {} bool ImageBase::isValid() const noexcept { - return (fRawData != nullptr && fSize.isValid()); + return (rawData != nullptr && size.isValid()); +} + +bool ImageBase::isInvalid() const noexcept +{ + return (rawData == nullptr || size.isInvalid()); } uint ImageBase::getWidth() const noexcept { - return fSize.getWidth(); + return size.getWidth(); } uint ImageBase::getHeight() const noexcept { - return fSize.getHeight(); + return size.getHeight(); } const Size& ImageBase::getSize() const noexcept { - return fSize; + return size; } const char* ImageBase::getRawData() const noexcept { - return fRawData; -} - -// ----------------------------------------------------------------------- - -void ImageBase::draw() -{ - _drawAt(Point()); + return rawData; } -void ImageBase::drawAt(const int x, const int y) +void ImageBase::draw(const GraphicsContext& context) { - _drawAt(Point(x, y)); + drawAt(context, Point(0, 0)); } -void ImageBase::drawAt(const Point& pos) +void ImageBase::drawAt(const GraphicsContext& context, const int x, const int y) { - _drawAt(pos); + drawAt(context, Point(x, y)); } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- +// public operators ImageBase& ImageBase::operator=(const ImageBase& image) noexcept { - fRawData = image.fRawData; - fSize = image.fSize; + rawData = image.rawData; + size = image.size; return *this; } bool ImageBase::operator==(const ImageBase& image) const noexcept { - return (fRawData == image.fRawData && fSize == image.fSize); + return (rawData == image.rawData && size == image.size); } bool ImageBase::operator!=(const ImageBase& image) const noexcept @@ -101,6 +102,6 @@ bool ImageBase::operator!=(const ImageBase& image) const noexcept return !operator==(image); } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp index 4909dde0..dd5b39c7 100644 --- a/dgl/src/OpenGL.cpp +++ b/dgl/src/OpenGL.cpp @@ -111,6 +111,185 @@ void Rectangle::_draw(const bool outline) // ----------------------------------------------------------------------- +OpenGLImage::OpenGLImage() + : ImageBase(), + fFormat(0), + fType(0), + fTextureId(0), + setupCalled(false) {} + +OpenGLImage::OpenGLImage(const OpenGLImage& image) + : ImageBase(image), + fFormat(image.fFormat), + fType(image.fType), + fTextureId(0), + setupCalled(false) {} + +OpenGLImage::OpenGLImage(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type) + : ImageBase(rawData, width, height), + fFormat(format), + fType(type), + fTextureId(0), + setupCalled(false) {} + +OpenGLImage::OpenGLImage(const char* const rawData, const Size& size, const GLenum format, const GLenum type) + : ImageBase(rawData, size), + fFormat(format), + fType(type), + fTextureId(0), + setupCalled(false) {} + +OpenGLImage::~OpenGLImage() +{ + if (setupCalled) { + // FIXME test if this is still necessary with new pugl +#ifndef DISTRHO_OS_MAC + if (fTextureId != 0) + cleanup(); +#endif + DISTRHO_SAFE_ASSERT(fTextureId == 0); + } +} + +void OpenGLImage::loadFromMemory(const char* const rawData, + const uint width, + const uint height, + const GLenum format, + const GLenum type) noexcept +{ + loadFromMemory(rawData, Size(width, height), format, type); +} + +void OpenGLImage::loadFromMemory(const char* const rdata, + const Size& s, + const GLenum format, + const GLenum type) noexcept +{ + rawData = rdata; + size = s; + fFormat = format; + fType = type; + setupCalled = false; +} + +void OpenGLImage::setup() +{ + setupCalled = true; + DISTRHO_SAFE_ASSERT_RETURN(fTextureId == 0,); + DISTRHO_SAFE_ASSERT_RETURN(isValid(),); + + glGenTextures(1, &fTextureId); + DISTRHO_SAFE_ASSERT_RETURN(fTextureId != 0,); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fTextureId); + + 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); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + static_cast(size.getWidth()), static_cast(size.getHeight()), 0, + fFormat, fType, rawData); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); +} + +void OpenGLImage::cleanup() +{ + DISTRHO_SAFE_ASSERT_RETURN(fTextureId != 0,); + glDeleteTextures(1, &fTextureId); + fTextureId = 0; +} + +GLenum OpenGLImage::getFormat() const noexcept +{ + return fFormat; +} + +GLenum OpenGLImage::getType() const noexcept +{ + return fType; +} + +void OpenGLImage::drawAt(const GraphicsContext&, const Point& pos) +{ + drawAt(pos); +} + +OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept +{ + rawData = image.rawData; + size = image.size; + fFormat = image.fFormat; + fType = image.fType; + setupCalled = false; + return *this; +} + +void OpenGLImage::draw() +{ + drawAt(Point(0, 0)); +} + +void OpenGLImage::drawAt(const int x, const int y) +{ + drawAt(Point(x, y)); +} + +void OpenGLImage::drawAt(const Point& pos) +{ + if (isInvalid()) + return; + + if (! setupCalled) + { + // TODO check if this is valid, give warning about needing to call setup/cleanup manually + setup(); + } + + if (fTextureId == 0) + return; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fTextureId); + + glBegin(GL_QUADS); + + { + const int x = pos.getX(); + const int y = pos.getY(); + const int w = static_cast(size.getWidth()); + const int h = static_cast(size.getHeight()); + + glTexCoord2f(0.0f, 0.0f); + glVertex2d(x, y); + + glTexCoord2f(1.0f, 0.0f); + glVertex2d(x+w, y); + + glTexCoord2f(1.0f, 1.0f); + glVertex2d(x+w, y+h); + + glTexCoord2f(0.0f, 1.0f); + glVertex2d(x, y+h); + } + + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); +} + +// ----------------------------------------------------------------------- + #if 0 void Widget::PrivateData::display(const uint width, const uint height, diff --git a/tests/Demo.cpp b/tests/Demo.cpp index 99062ed2..edf2289c 100644 --- a/tests/Demo.cpp +++ b/tests/Demo.cpp @@ -25,6 +25,7 @@ #include "dgl/src/Application.cpp" #include "dgl/src/ApplicationPrivateData.cpp" #include "dgl/src/Geometry.cpp" +#include "dgl/src/ImageBase.cpp" #include "dgl/src/OpenGL.cpp" #include "dgl/src/SubWidget.cpp" #include "dgl/src/SubWidgetPrivateData.cpp" @@ -37,9 +38,13 @@ #include "dgl/StandaloneWindow.hpp" #include "widgets/ExampleColorWidget.hpp" +#include "widgets/ExampleImagesWidget.hpp" #include "widgets/ExampleRectanglesWidget.hpp" #include "widgets/ExampleShapesWidget.hpp" +#include "demo_res/DemoArtwork.cpp" +#include "images_res/CatPics.cpp" + START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- @@ -66,6 +71,7 @@ public: #if 0 // for text font = nvg.createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"); +#endif using namespace DemoArtwork; img1.loadFromMemory(ico1Data, ico1Width, ico1Height, GL_BGR); @@ -73,7 +79,6 @@ public: img3.loadFromMemory(ico3Data, ico3Width, ico2Height, GL_BGR); img4.loadFromMemory(ico4Data, ico4Width, ico4Height, GL_BGR); img5.loadFromMemory(ico5Data, ico5Width, ico5Height, GL_BGR); -#endif } protected: @@ -110,7 +115,6 @@ protected: // reset color glColor4f(1.0f, 1.0f, 1.0f, 1.0f); -#if 0 const int pad = iconSize/2 - DemoArtwork::ico1Width/2; img1.drawAt(pad, pad); @@ -119,6 +123,7 @@ protected: img4.drawAt(pad, pad + 9 + iconSize*3); img5.drawAt(pad, pad + 12 + iconSize*4); +#if 0 // draw some text nvg.beginFrame(this); @@ -215,9 +220,9 @@ private: int curPage, curHover; Rectangle bgIcon; Line lineSep; -#if 0 - Image img1, img2, img3, img4, img5; + OpenGLImage img1, img2, img3, img4, img5; +#if 0 // for text NanoVG nvg;D NanoVG::FontId font; @@ -238,20 +243,21 @@ public: DemoWindow(Application& app) : StandaloneWindow(app), wColor(this), + wImages(this), wRects(this), wShapes(this), wLeft(this, this), curWidget(nullptr) { wColor.hide(); -// wImages.hide(); + wImages.hide(); wRects.hide(); wShapes.hide(); // wText.hide(); // //wPerf.hide(); wColor.setAbsoluteX(kSidebarWidth); -// wImages.setAbsoluteX(kSidebarWidth); + wImages.setAbsoluteX(kSidebarWidth); wRects.setAbsoluteX(kSidebarWidth); wShapes.setAbsoluteX(kSidebarWidth); // wText.setAbsoluteX(kSidebarWidth); @@ -275,9 +281,9 @@ protected: case 0: curWidget = &wColor; break; -// case 1: -// curWidget = &wImages; -// break; + case 1: + curWidget = &wImages; + break; case 2: curWidget = &wRects; break; @@ -309,7 +315,7 @@ protected: Size size(width-kSidebarWidth, height); wColor.setSize(size); -// wImages.setSize(size); + wImages.setSize(size); wRects.setSize(size); wShapes.setSize(size); // wText.setSize(size); @@ -323,7 +329,7 @@ protected: private: ExampleColorSubWidget wColor; -// ExampleImagesWidget wImages; + ExampleImagesSubWidget wImages; ExampleRectanglesSubWidget wRects; ExampleShapesSubWidget wShapes; // ExampleTextWidget wText; @@ -364,6 +370,8 @@ int main(int argc, char* argv[]) /**/ if (std::strcmp(argv[1], "color") == 0) createAndShowExampleWidgetStandaloneWindow(app); + else if (std::strcmp(argv[1], "images") == 0) + createAndShowExampleWidgetStandaloneWindow(app); else if (std::strcmp(argv[1], "rectangles") == 0) createAndShowExampleWidgetStandaloneWindow(app); else if (std::strcmp(argv[1], "shapes") == 0) diff --git a/tests/widgets/ExampleImagesWidget.hpp b/tests/widgets/ExampleImagesWidget.hpp index 8c0a134a..9f33e801 100644 --- a/tests/widgets/ExampleImagesWidget.hpp +++ b/tests/widgets/ExampleImagesWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -20,22 +20,25 @@ // ------------------------------------------------------ // DGL Stuff -#include "Image.hpp" -#include "Widget.hpp" -#include "Window.hpp" +#include "../../dgl/Image.hpp" +#include "../../dgl/SubWidget.hpp" +#include "../../dgl/TopLevelWidget.hpp" + // ------------------------------------------------------ // Images #include "../images_res/CatPics.hpp" +START_NAMESPACE_DGL + // ------------------------------------------------------ // our widget -class ExampleImagesWidget : public Widget, +template +class ExampleImagesWidget : public BaseWidget, public IdleCallback { -public: static const int kImg1y = 0; static const int kImg2y = 500/2-CatPics::cat2Height/2; static const int kImg3x = 400/3-CatPics::cat3Width/3; @@ -44,160 +47,207 @@ public: static const int kImg2max = 500-CatPics::cat2Width; static const int kImg3max = 400-CatPics::cat3Height; - ExampleImagesWidget(Window& parent, const bool setParentSize = false) - : Widget(parent), - fImgTop1st(1), - fImgTop2nd(2), - fImgTop3rd(3), - fImg1x(0), - fImg2x(kImg2max), - fImg3y(kImg3max), - fImg1rev(false), - fImg2rev(true), - fImg3rev(true), - fImg1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), - fImg2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), - fImg3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) + int imgTop1st, imgTop2nd, imgTop3rd; + int img1x, img2x, img3y; + bool img1rev, img2rev, img3rev; + Image img1, img2, img3; + +public: + static constexpr const char* kExampleWidgetName = "Images"; + + // SubWidget + ExampleImagesWidget(Widget* const parent) + : BaseWidget(parent), + imgTop1st(1), + imgTop2nd(2), + imgTop3rd(3), + img1x(0), + img2x(kImg2max), + img3y(kImg3max), + img1rev(false), + img2rev(true), + img3rev(true), + img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), + img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), + img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) { - setSize(500, 400); + BaseWidget::setSize(500, 400); - parent.addIdleCallback(this); + parent->getApp().addIdleCallback(this); + } - if (setParentSize) - { - parent.setSize(500, 400); - parent.setResizable(false); - } + // TopLevelWidget + ExampleImagesWidget(Window& windowToMapTo) + : BaseWidget(windowToMapTo), + imgTop1st(1), + imgTop2nd(2), + imgTop3rd(3), + img1x(0), + img2x(kImg2max), + img3y(kImg3max), + img1rev(false), + img2rev(true), + img3rev(true), + img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), + img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), + img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) + { + BaseWidget::setSize(500, 400); + + windowToMapTo.getApp().addIdleCallback(this); } -private: + // StandaloneWindow + ExampleImagesWidget(Application& app) + : BaseWidget(app), + imgTop1st(1), + imgTop2nd(2), + imgTop3rd(3), + img1x(0), + img2x(kImg2max), + img3y(kImg3max), + img1rev(false), + img2rev(true), + img3rev(true), + img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), + img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), + img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) + { + BaseWidget::setSize(500, 400); + + app.addIdleCallback(this); + } + +protected: void idleCallback() noexcept override { - if (fImg1rev) + if (img1rev) { - fImg1x -= 2; - if (fImg1x <= -50) + img1x -= 2; + if (img1x <= -50) { - fImg1rev = false; + img1rev = false; setNewTopImg(1); } } else { - fImg1x += 2; - if (fImg1x >= kImg1max+50) + img1x += 2; + if (img1x >= kImg1max+50) { - fImg1rev = true; + img1rev = true; setNewTopImg(1); } } - if (fImg2rev) + if (img2rev) { - fImg2x -= 1; - if (fImg2x <= -50) + img2x -= 1; + if (img2x <= -50) { - fImg2rev = false; + img2rev = false; setNewTopImg(2); } } else { - fImg2x += 4; - if (fImg2x >= kImg2max+50) + img2x += 4; + if (img2x >= kImg2max+50) { - fImg2rev = true; + img2rev = true; setNewTopImg(2); } } - if (fImg3rev) + if (img3rev) { - fImg3y -= 3; - if (fImg3y <= -50) + img3y -= 3; + if (img3y <= -50) { - fImg3rev = false; + img3rev = false; setNewTopImg(3); } } else { - fImg3y += 3; - if (fImg3y >= kImg3max+50) + img3y += 3; + if (img3y >= kImg3max+50) { - fImg3rev = true; + img3rev = true; setNewTopImg(3); } } - repaint(); + BaseWidget::repaint(); } void onDisplay() override { - switch (fImgTop3rd) + switch (imgTop3rd) { case 1: - fImg1.drawAt(fImg1x, kImg1y); + img1.drawAt(img1x, kImg1y); break; case 2: - fImg2.drawAt(fImg2x, kImg2y); + img2.drawAt(img2x, kImg2y); break; case 3: - fImg3.drawAt(kImg3x, fImg3y); + img3.drawAt(kImg3x, img3y); break; }; - switch (fImgTop2nd) + switch (imgTop2nd) { case 1: - fImg1.drawAt(fImg1x, kImg1y); + img1.drawAt(img1x, kImg1y); break; case 2: - fImg2.drawAt(fImg2x, kImg2y); + img2.drawAt(img2x, kImg2y); break; case 3: - fImg3.drawAt(kImg3x, fImg3y); + img3.drawAt(kImg3x, img3y); break; }; - switch (fImgTop1st) + switch (imgTop1st) { case 1: - fImg1.drawAt(fImg1x, kImg1y); + img1.drawAt(img1x, kImg1y); break; case 2: - fImg2.drawAt(fImg2x, kImg2y); + img2.drawAt(img2x, kImg2y); break; case 3: - fImg3.drawAt(kImg3x, fImg3y); + img3.drawAt(kImg3x, img3y); break; }; } +private: void setNewTopImg(const int imgId) noexcept { - if (fImgTop1st == imgId) + if (imgTop1st == imgId) return; - if (fImgTop2nd == imgId) + if (imgTop2nd == imgId) { - fImgTop2nd = fImgTop1st; - fImgTop1st = imgId; + imgTop2nd = imgTop1st; + imgTop1st = imgId; return; } - fImgTop3rd = fImgTop2nd; - fImgTop2nd = fImgTop1st; - fImgTop1st = imgId; + imgTop3rd = imgTop2nd; + imgTop2nd = imgTop1st; + imgTop1st = imgId; } - - int fImgTop1st, fImgTop2nd, fImgTop3rd; - int fImg1x, fImg2x, fImg3y; - bool fImg1rev, fImg2rev, fImg3rev; - Image fImg1, fImg2, fImg3; }; +typedef ExampleImagesWidget ExampleImagesSubWidget; +typedef ExampleImagesWidget ExampleImagesTopLevelWidget; +typedef ExampleImagesWidget ExampleImagesStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_IMAGES_WIDGET_HPP_INCLUDED