DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 5b10613f6e2191a7c38cd67ec62d9517837cb039
parent c10f6b543833019372d265d0220c1cedbf62fd37
Author: falkTX <falktx@falktx.com>
Date:   Sun,  9 May 2021 17:13:12 +0100

Start working on nanovg and text, mostly works

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdgl/Color.hpp | 4++--
Mdgl/NanoVG.hpp | 29+++++++++++++++++++----------
Mdgl/src/NanoVG.cpp | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mdgl/src/WindowPrivateData.cpp | 21++++++++++++++++++---
Mtests/Demo.cpp | 33+++++++++++++++++----------------
Mtests/widgets/ExampleTextWidget.hpp | 68+++++++++++++++++++++++++++++++++++++++++++-------------------------
6 files changed, 152 insertions(+), 79 deletions(-)

diff --git a/dgl/Color.hpp b/dgl/Color.hpp @@ -19,10 +19,10 @@ #include "Base.hpp" -START_NAMESPACE_DGL - struct NVGcolor; +START_NAMESPACE_DGL + // -------------------------------------------------------------------------------------------------------------------- /** diff --git a/dgl/NanoVG.hpp b/dgl/NanoVG.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> + * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> * * 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 @@ -19,7 +19,9 @@ #include "Color.hpp" #include "OpenGL.hpp" -#include "Widget.hpp" +#include "SubWidget.hpp" +#include "TopLevelWidget.hpp" +#include "StandaloneWindow.hpp" #ifndef DGL_NO_SHARED_RESOURCES # define NANOVG_DEJAVU_SANS_TTF "__dpf_dejavusans_ttf__" @@ -853,7 +855,7 @@ public: /** Load DPF's internal shared resources for this NanoVG class. */ - virtual void loadSharedResources(); + virtual bool loadSharedResources(); #endif private: @@ -875,25 +877,28 @@ private: The drawing function onDisplay() is implemented internally but a new onNanoDisplay() needs to be overridden instead. */ -class NanoWidget : public Widget, +template <class BaseWidget> +class NanoWidget : public BaseWidget, public NanoVG { public: /** - Constructor. + Constructor for a NanoSubWidget. @see CreateFlags */ - explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS); + explicit NanoWidget(Widget* const parentGroupWidget, int flags = CREATE_ANTIALIAS); /** - Constructor for a subwidget. + Constructor for a NanoTopLevelWidget. + @see CreateFlags */ - explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS); + explicit NanoWidget(Window& windowToMapTo, int flags = CREATE_ANTIALIAS); /** - Constructor for a subwidget, reusing a NanoVG context. + Constructor for a NanoStandaloneWindow. + @see CreateFlags */ - explicit NanoWidget(NanoWidget* groupWidget); + explicit NanoWidget(Application& app, int flags = CREATE_ANTIALIAS); /** Destructor. @@ -927,6 +932,10 @@ private: DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget) }; +typedef NanoWidget<SubWidget> NanoSubWidget; +typedef NanoWidget<TopLevelWidget> NanoTopLevelWidget; +typedef NanoWidget<StandaloneWindow> NanoStandaloneWindow; + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> + * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> * * 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 @@ -257,25 +257,25 @@ NanoVG::~NanoVG() void NanoVG::beginFrame(const uint width, const uint height, const float scaleFactor) { - fInFrame = true; if (fContext == nullptr) return; DISTRHO_SAFE_ASSERT_RETURN(scaleFactor > 0.0f,); DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,); + fInFrame = true; nvgBeginFrame(fContext, static_cast<int>(width), static_cast<int>(height), scaleFactor); } void NanoVG::beginFrame(Widget* const widget) { - fInFrame = true; DISTRHO_SAFE_ASSERT_RETURN(widget != nullptr,); DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,); + fInFrame = true; if (fContext == nullptr) return; - Window& window(widget->getParentWindow()); - nvgBeginFrame(fContext, static_cast<int>(window.getWidth()), static_cast<int>(window.getHeight()), 1.0f); + if (TopLevelWidget* const tlw = widget->getTopLevelWidget()) + nvgBeginFrame(fContext, static_cast<int>(tlw->getWidth()), static_cast<int>(tlw->getHeight()), 1.0f); } void NanoVG::cancelFrame() @@ -771,26 +771,26 @@ void NanoVG::stroke() NanoVG::FontId NanoVG::createFontFromFile(const char* name, const char* filename) { - if (fContext == nullptr) return -1; DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1); DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', -1); + DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1); return nvgCreateFont(fContext, name, filename); } NanoVG::FontId NanoVG::createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData) { - if (fContext == nullptr) return -1; DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1); DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, -1); + DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1); return nvgCreateFontMem(fContext, name, const_cast<uchar*>(data), static_cast<int>(dataSize), freeData); } NanoVG::FontId NanoVG::findFont(const char* name) { - if (fContext == nullptr) return -1; DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1); + DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr, -1); return nvgFindFont(fContext, name); } @@ -912,35 +912,62 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi } #ifndef DGL_NO_SHARED_RESOURCES -void NanoVG::loadSharedResources() +bool NanoVG::loadSharedResources() { - if (fContext == nullptr) return; + if (fContext == nullptr) return false; if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) - return; + return true; using namespace dpf_resources; - nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0); + return nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, + (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0) >= 0; } #endif // ----------------------------------------------------------------------- -struct NanoWidget::PrivateData { - NanoWidget* const self; - std::vector<NanoWidget*> subWidgets; +template <class BaseWidget> +struct NanoWidget<BaseWidget>::PrivateData { + NanoWidget<BaseWidget>* const self; - PrivateData(NanoWidget* const s) - : self(s), - subWidgets() {} + PrivateData(NanoWidget<BaseWidget>* const s) + : self(s) {} ~PrivateData() { - subWidgets.clear(); } }; +// SubWidget +template <class BaseWidget> +NanoWidget<BaseWidget>::NanoWidget(Widget* const parent, int flags) + : BaseWidget(parent), + NanoVG(flags), + nData(new PrivateData(this)) +{ +} + +// TopLevelWidget +template <class BaseWidget> +NanoWidget<BaseWidget>::NanoWidget(Window& windowToMapTo, int flags) + : BaseWidget(windowToMapTo), + NanoVG(flags), + nData(new PrivateData(this)) +{ +} + +// StandaloneWindow +template <class BaseWidget> +NanoWidget<BaseWidget>::NanoWidget(Application& app, int flags) + : BaseWidget(app), + NanoVG(flags), + nData(new PrivateData(this)) +{ +} + +/* NanoWidget::NanoWidget(Window& parent, int flags) : Widget(parent), NanoVG(flags), @@ -957,7 +984,6 @@ NanoWidget::NanoWidget(Widget* groupWidget, int flags) pData->needsScaling = true; } -/* NanoWidget::NanoWidget(NanoWidget* groupWidget) : Widget(groupWidget, false), NanoVG(groupWidget), @@ -969,21 +995,25 @@ NanoWidget::NanoWidget(NanoWidget* groupWidget) } */ -NanoWidget::~NanoWidget() +template <class BaseWidget> +NanoWidget<BaseWidget>::~NanoWidget() { delete nData; } -void NanoWidget::onDisplay() +template <class BaseWidget> +void NanoWidget<BaseWidget>::onDisplay() { - NanoVG::beginFrame(getWidth(), getHeight()); + NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight()); onNanoDisplay(); + /* for (std::vector<NanoWidget*>::iterator it = nData->subWidgets.begin(); it != nData->subWidgets.end(); ++it) { NanoWidget* const widget(*it); widget->onNanoDisplay(); } + */ NanoVG::endFrame(); } diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp @@ -90,13 +90,17 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, autoScaling(1.0), pendingVisibility(kPendingVisibilityNone) { + if (isEmbed) + { + puglSetDefaultSize(view, width, height); + puglSetParentWindow(view, parentWindowHandle); + } + init(width, height, resizable); if (isEmbed) { appData->oneWindowShown(); - puglSetDefaultSize(view, width, height); - puglSetParentWindow(view, parentWindowHandle); puglShow(view); } } @@ -137,7 +141,7 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r puglSetHandle(view, this); puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); - puglSetViewHint(view, PUGL_DEPTH_BITS, 8); + puglSetViewHint(view, PUGL_DEPTH_BITS, 16); puglSetViewHint(view, PUGL_STENCIL_BITS, 8); // PUGL_SAMPLES ?? puglSetEventFunc(view, puglEventCallback); @@ -149,6 +153,10 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r rect.width = width; rect.height = height; puglSetFrame(view, rect); + + // FIXME this is bad + puglRealize(view); + puglX11GlEnter(view, NULL); } // ----------------------------------------------------------------------- @@ -182,9 +190,16 @@ void Window::PrivateData::show() isClosed = false; appData->oneWindowShown(); +#ifdef DISTRHO_OS_WINDOWS + puglWin32ShowWindowCentered(view); +#else + puglShow(view); +#endif + /* pendingVisibility = kPendingVisibilityShow; const PuglStatus status = puglRealize(view); DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close()); + */ } else { diff --git a/tests/Demo.cpp b/tests/Demo.cpp @@ -21,12 +21,16 @@ #include "tests.hpp" // #define DPF_TEST_POINT_CPP +#include "dgl/OpenGL.hpp" #include "dgl/src/pugl.cpp" #include "dgl/src/Application.cpp" #include "dgl/src/ApplicationPrivateData.cpp" +#include "dgl/src/Color.cpp" #include "dgl/src/Geometry.cpp" #include "dgl/src/ImageBase.cpp" +#include "dgl/src/NanoVG.cpp" #include "dgl/src/OpenGL.cpp" +#include "dgl/src/Resources.cpp" #include "dgl/src/SubWidget.cpp" #include "dgl/src/SubWidgetPrivateData.cpp" #include "dgl/src/TopLevelWidget.cpp" @@ -40,6 +44,7 @@ #include "widgets/ExampleColorWidget.hpp" #include "widgets/ExampleImagesWidget.hpp" #include "widgets/ExampleRectanglesWidget.hpp" +#include "widgets/ExampleTextWidget.hpp" #include "widgets/ExampleShapesWidget.hpp" #include "demo_res/DemoArtwork.cpp" @@ -68,10 +73,8 @@ public: curPage(0), curHover(-1) { -#if 0 // for text - font = nvg.createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"); -#endif + nvg.loadSharedResources(); using namespace DemoArtwork; img1.loadFromMemory(ico1Data, ico1Width, ico1Height, GL_BGR); @@ -123,7 +126,6 @@ protected: img4.drawAt(pad, pad + 9 + iconSize*3); img5.drawAt(pad, pad + 12 + iconSize*4); -#if 0 // draw some text nvg.beginFrame(this); @@ -136,7 +138,6 @@ protected: nvg.textBox(15, 440, iconSize, "Look!", nullptr); nvg.endFrame(); -#endif } bool onMouse(const MouseEvent& ev) override @@ -222,11 +223,8 @@ private: Line<int> lineSep; OpenGLImage img1, img2, img3, img4, img5; -#if 0 // for text - NanoVG nvg;D - NanoVG::FontId font; -#endif + NanoVG nvg; }; // -------------------------------------------------------------------------------------------------------------------- @@ -246,6 +244,7 @@ public: wImages(this), wRects(this), wShapes(this), + wText(this), wLeft(this, this), curWidget(nullptr) { @@ -253,14 +252,14 @@ public: wImages.hide(); wRects.hide(); wShapes.hide(); -// wText.hide(); + wText.hide(); // //wPerf.hide(); wColor.setAbsoluteX(kSidebarWidth); wImages.setAbsoluteX(kSidebarWidth); wRects.setAbsoluteX(kSidebarWidth); wShapes.setAbsoluteX(kSidebarWidth); -// wText.setAbsoluteX(kSidebarWidth); + wText.setAbsoluteX(kSidebarWidth); wLeft.setAbsolutePos(2, 2); // wPerf.setAbsoluteY(5); @@ -290,9 +289,9 @@ protected: case 3: curWidget = &wShapes; break; -// case 4: -// curWidget = &wText; -// break; + case 4: + curWidget = &wText; + break; default: curWidget = nullptr; break; @@ -318,7 +317,7 @@ protected: wImages.setSize(size); wRects.setSize(size); wShapes.setSize(size); -// wText.setSize(size); + wText.setSize(size); wLeft.setSize(kSidebarWidth-4, height-4); //wRezHandle.setAbsoluteX(width-wRezHandle.getWidth()); @@ -332,7 +331,7 @@ private: ExampleImagesSubWidget wImages; ExampleRectanglesSubWidget wRects; ExampleShapesSubWidget wShapes; -// ExampleTextWidget wText; + ExampleTextSubWidget wText; LeftSideWidget wLeft; //ResizeHandle wRezHandle; // NanoPerfWidget wPerf; @@ -376,6 +375,8 @@ int main(int argc, char* argv[]) createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); else if (std::strcmp(argv[1], "shapes") == 0) createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); + else if (std::strcmp(argv[1], "text") == 0) + createAndShowExampleWidgetStandaloneWindow<ExampleTextStandaloneWindow>(app); else d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); } diff --git a/tests/widgets/ExampleTextWidget.hpp b/tests/widgets/ExampleTextWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> + * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> * * 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,51 +20,69 @@ // ------------------------------------------------------ // DGL Stuff -#include "NanoVG.hpp" +#include "../../dgl/NanoVG.hpp" + +START_NAMESPACE_DGL // ------------------------------------------------------ // our widget -class ExampleTextWidget : public NanoWidget +template <class BaseWidget> +class ExampleTextWidget : public BaseWidget { public: - ExampleTextWidget(Window& parent) - : NanoWidget(parent), - fFont(createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf")) + static constexpr const char* kExampleWidgetName = "Text"; + + // SubWidget + explicit ExampleTextWidget(Widget* const parent) + : BaseWidget(parent) + { + NanoVG::loadSharedResources(); + BaseWidget::setSize(500, 300); + } + + // TopLevelWidget + explicit ExampleTextWidget(Window& windowToMapTo) + : BaseWidget(windowToMapTo) { - setSize(500, 300); + NanoVG::loadSharedResources(); + BaseWidget::setSize(500, 300); } - ExampleTextWidget(Widget* groupWidget) - : NanoWidget(groupWidget), - fFont(createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf")) + // StandaloneWindow + explicit ExampleTextWidget(Application& app) + : BaseWidget(app) { - setSize(500, 300); + NanoVG::loadSharedResources(); + BaseWidget::setSize(500, 300); } protected: void onNanoDisplay() override { - const int width = getWidth(); - const int height = getHeight(); + const int width = BaseWidget::getWidth(); + const int height = BaseWidget::getHeight(); - fontSize(40.0f); - textAlign(Align(ALIGN_CENTER|ALIGN_MIDDLE)); - textLineHeight(20.0f); + NanoVG::fontSize(40.0f); + NanoVG::textAlign(NanoVG::Align(NanoVG::ALIGN_CENTER|NanoVG::ALIGN_MIDDLE)); + NanoVG::textLineHeight(20.0f); - beginPath(); - fillColor(220,220,220,255); - roundedRect(10, height/4+10, width-20, height/2-20, 3); - fill(); + NanoVG::beginPath(); + NanoVG::fillColor(220,220,220,255); + NanoVG::roundedRect(10, height/4+10, width-20, height/2-20, 3); + NanoVG::fill(); - fillColor(0,200,0,220); - textBox(10, height/2, width-20, "Hello World!", nullptr); + NanoVG::fillColor(0,150,0,220); + NanoVG::textBox(10, height/2, width-20, "Hello World!", nullptr); } - -private: - FontId fFont; }; +typedef ExampleTextWidget<NanoSubWidget> ExampleTextSubWidget; +typedef ExampleTextWidget<NanoTopLevelWidget> ExampleTextTopLevelWidget; +typedef ExampleTextWidget<NanoStandaloneWindow> ExampleTextStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_TEXT_WIDGET_HPP_INCLUDED