/* * DISTRHO Plugin Framework (DPF) * Copyright (C) 2012-2022 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 "tests.hpp" #include "widgets/ExampleColorWidget.hpp" #include "widgets/ExampleImagesWidget.hpp" #include "widgets/ExampleRectanglesWidget.hpp" #include "widgets/ExampleShapesWidget.hpp" #ifdef DGL_OPENGL #include "widgets/ExampleTextWidget.hpp" #endif #include "widgets/ResizeHandle.hpp" #include "demo_res/DemoArtwork.cpp" #include "images_res/CatPics.cpp" #ifdef DGL_CAIRO #include "../dgl/Cairo.hpp" typedef DGL_NAMESPACE::CairoImage DemoImage; #endif #ifdef DGL_OPENGL #include "../dgl/OpenGL.hpp" typedef DGL_NAMESPACE::OpenGLImage DemoImage; #endif #ifdef DGL_VULKAN #include "../dgl/Vulkan.hpp" typedef DGL_NAMESPACE::VulkanImage DemoImage; #endif START_NAMESPACE_DGL // Partial specialization is not allowed in C++, so we need to define these here template<> inline ExampleImagesWidget::ExampleImagesWidget(Widget* const parentWidget) : SubWidget(parentWidget) { init(parentWidget->getApp()); } template<> inline ExampleImagesWidget::ExampleImagesWidget(Window& windowToMapTo) : TopLevelWidget(windowToMapTo) { init(windowToMapTo.getApp()); } template<> ExampleImagesWidget::ExampleImagesWidget(Application& app) : StandaloneWindow(app) { init(app); done(); } typedef ExampleImagesWidget ExampleImagesSubWidget; typedef ExampleImagesWidget ExampleImagesTopLevelWidget; typedef ExampleImagesWidget ExampleImagesStandaloneWindow; // -------------------------------------------------------------------------------------------------------------------- // Left side tab-like widget class LeftSideWidget : public SubWidget { public: #ifdef DGL_OPENGL static const int kPageCount = 5; #else static const int kPageCount = 4; #endif class Callback { public: virtual ~Callback() {} virtual void curPageChanged(int curPage) = 0; }; LeftSideWidget(Widget* parent, Callback* const cb) : SubWidget(parent), callback(cb), curPage(0), curHover(-1) { using namespace DemoArtwork; img1.loadFromMemory(ico1Data, ico1Width, ico1Height, kImageFormatBGR); img2.loadFromMemory(ico2Data, ico2Width, ico2Height, kImageFormatBGR); img3.loadFromMemory(ico3Data, ico3Width, ico2Height, kImageFormatBGR); img4.loadFromMemory(ico4Data, ico4Width, ico4Height, kImageFormatBGR); #ifdef DGL_OPENGL img5.loadFromMemory(ico5Data, ico5Width, ico5Height, kImageFormatBGR); // for text nvg.loadSharedResources(); #endif } protected: void onDisplay() override { const GraphicsContext& context(getGraphicsContext()); const double scaleFactor = getWindow().getScaleFactor(); const int iconSize = bgIcon.getWidth(); Color(0.027f, 0.027f, 0.027f).setFor(context); Rectangle(0, 0, getSize()).draw(context); bgIcon.setY(curPage * iconSize + curPage * 3 * scaleFactor); Color(0.129f, 0.129f, 0.129f).setFor(context); bgIcon.draw(context); Color(0.184f, 0.184f, 0.184f).setFor(context); bgIcon.drawOutline(context); if (curHover != curPage && curHover != -1) { Rectangle rHover(1 * scaleFactor, curHover * iconSize + curHover * 3 * scaleFactor, iconSize - 2 * scaleFactor, iconSize - 2 * scaleFactor); Color(0.071f, 0.071f, 0.071f).setFor(context); rHover.draw(context); Color(0.102f, 0.102f, 0.102f).setFor(context); rHover.drawOutline(context); } Color(0.184f, 0.184f, 0.184f).setFor(context); lineSep.draw(context); // reset color Color(1.0f, 1.0f, 1.0f, 1.0f).setFor(context, true); const int pad = iconSize/2 - DemoArtwork::ico1Width/2; img1.drawAt(context, pad, pad); img2.drawAt(context, pad, pad + 3 + iconSize); img3.drawAt(context, pad, pad + 6 + iconSize*2); img4.drawAt(context, pad, pad + 9 + iconSize*3); #ifdef DGL_OPENGL img5.drawAt(context, pad, pad + 12 + iconSize*4); // draw some text nvg.beginFrame(this); nvg.fontSize(23.0f * scaleFactor); nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP); //nvg.textLineHeight(20.0f); nvg.fillColor(220,220,220,220); nvg.textBox(10 * scaleFactor, 420 * scaleFactor, iconSize, "Haha,", nullptr); nvg.textBox(15 * scaleFactor, 440 * scaleFactor, iconSize, "Look!", nullptr); nvg.endFrame(); #endif } bool onMouse(const MouseEvent& ev) override { if (ev.button != 1 || ! ev.press) return false; if (! contains(ev.pos)) return false; const int iconSize = bgIcon.getWidth(); for (int i=0; icurPageChanged(i); repaint(); break; } } return true; } bool onMotion(const MotionEvent& ev) override { if (contains(ev.pos)) { const int iconSize = bgIcon.getWidth(); for (int i=0; i bgIcon; Line lineSep; DemoImage img1, img2, img3, img4, img5; #ifdef DGL_OPENGL // for text NanoVG nvg; #endif }; // -------------------------------------------------------------------------------------------------------------------- // Main Demo Window, having a left-side tab-like widget and main area for current widget class DemoWindow : public StandaloneWindow, public LeftSideWidget::Callback { static const int kSidebarWidth = 81; public: #ifdef DGL_CAIRO static constexpr const char* const kExampleWidgetName = "Demo - Cairo"; #endif #ifdef DGL_OPENGL static constexpr const char* const kExampleWidgetName = "Demo - OpenGL"; #endif #ifdef DGL_VULKAN static constexpr const char* const kExampleWidgetName = "Demo - Vulkan"; #endif DemoWindow(Application& app) : StandaloneWindow(app), curWidget(nullptr) { const ScopedGraphicsContext sgc(*this); const double scaleFactor = getScaleFactor(); wColor = new ExampleColorSubWidget(this); wColor->hide(); wColor->setAbsoluteX(kSidebarWidth * scaleFactor); wImages = new ExampleImagesSubWidget(this); wImages->hide(); wImages->setAbsoluteX(kSidebarWidth * scaleFactor); wRects = new ExampleRectanglesSubWidget(this); wRects->hide(); wRects->setAbsoluteX(kSidebarWidth * scaleFactor); wShapes = new ExampleShapesSubWidget(this); wShapes->hide(); wShapes->setAbsoluteX(kSidebarWidth * scaleFactor); #ifdef DGL_OPENGL wText = new ExampleTextSubWidget(this), wText->hide(); wText->setAbsoluteX(kSidebarWidth * scaleFactor); #endif wLeft = new LeftSideWidget(this, this), wLeft->setAbsolutePos(2 * scaleFactor, 2 * scaleFactor); resizer = new ResizeHandle(this); curPageChanged(0); done(); } protected: void curPageChanged(int curPage) override { if (curWidget != nullptr) curWidget->hide(); switch (curPage) { case 0: curWidget = wColor; break; case 1: curWidget = wImages; break; case 2: curWidget = wRects; break; case 3: curWidget = wShapes; break; #ifdef DGL_OPENGL case 4: curWidget = wText; break; #endif default: curWidget = nullptr; break; } if (curWidget != nullptr) curWidget->show(); } void onDisplay() override { } void onReshape(uint width, uint height) override { StandaloneWindow::onReshape(width, height); const double scaleFactor = getScaleFactor(); if (width < kSidebarWidth * scaleFactor) return; const Size size(width - kSidebarWidth * scaleFactor, height); wColor->setSize(size); wImages->setSize(size); wRects->setSize(size); wShapes->setSize(size); #ifdef DGL_OPENGL wText->setSize(size); #endif wLeft->setSize((kSidebarWidth - 4) * scaleFactor, (height - 4) * scaleFactor); } private: ScopedPointer wColor; ScopedPointer wImages; ScopedPointer wRects; ScopedPointer wShapes; #ifdef DGL_OPENGL ScopedPointer wText; #endif ScopedPointer wLeft; ScopedPointer resizer; Widget* curWidget; }; // -------------------------------------------------------------------------------------------------------------------- // Special handy function that runs a StandaloneWindow inside the function scope template void createAndShowExampleWidgetStandaloneWindow(Application& app) { ExampleWidgetStandaloneWindow swin(app); const double scaleFactor = swin.getScaleFactor(); swin.setGeometryConstraints(128 * scaleFactor, 128 * scaleFactor); swin.setResizable(true); swin.setSize(600 * scaleFactor, 500 * scaleFactor); swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); swin.show(); app.exec(); } // -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DGL int main(int argc, char* argv[]) { USE_NAMESPACE_DGL; using DGL_NAMESPACE::Window; Application app; if (argc > 1) { /**/ 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) createAndShowExampleWidgetStandaloneWindow(app); #ifdef DGL_OPENGL else if (std::strcmp(argv[1], "text") == 0) createAndShowExampleWidgetStandaloneWindow(app); #endif else d_stderr2("Invalid demo mode, must be one of: color, images, rectangles or shapes"); } else { createAndShowExampleWidgetStandaloneWindow(app); } return 0; } // --------------------------------------------------------------------------------------------------------------------