diff --git a/dgl/Color.hpp b/dgl/Color.hpp index 1b611805..6276b0d9 100644 --- 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 index 27a38d45..618b5fdb 100644 --- a/dgl/NanoVG.hpp +++ b/dgl/NanoVG.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 @@ -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 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 NanoSubWidget; +typedef NanoWidget NanoTopLevelWidget; +typedef NanoWidget NanoStandaloneWindow; + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp index 5e2a93c3..0f50dbe3 100644 --- a/dgl/src/NanoVG.cpp +++ b/dgl/src/NanoVG.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 @@ -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(width), static_cast(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(window.getWidth()), static_cast(window.getHeight()), 1.0f); + if (TopLevelWidget* const tlw = widget->getTopLevelWidget()) + nvgBeginFrame(fContext, static_cast(tlw->getWidth()), static_cast(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(data), static_cast(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 subWidgets; +template +struct NanoWidget::PrivateData { + NanoWidget* const self; - PrivateData(NanoWidget* const s) - : self(s), - subWidgets() {} + PrivateData(NanoWidget* const s) + : self(s) {} ~PrivateData() { - subWidgets.clear(); } }; +// SubWidget +template +NanoWidget::NanoWidget(Widget* const parent, int flags) + : BaseWidget(parent), + NanoVG(flags), + nData(new PrivateData(this)) +{ +} + +// TopLevelWidget +template +NanoWidget::NanoWidget(Window& windowToMapTo, int flags) + : BaseWidget(windowToMapTo), + NanoVG(flags), + nData(new PrivateData(this)) +{ +} + +// StandaloneWindow +template +NanoWidget::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 +NanoWidget::~NanoWidget() { delete nData; } -void NanoWidget::onDisplay() +template +void NanoWidget::onDisplay() { - NanoVG::beginFrame(getWidth(), getHeight()); + NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight()); onNanoDisplay(); + /* for (std::vector::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 index 560d4c81..9082710a 100644 --- 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 index edf2289c..89d484f5 100644 --- 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 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(app); else if (std::strcmp(argv[1], "shapes") == 0) createAndShowExampleWidgetStandaloneWindow(app); + else if (std::strcmp(argv[1], "text") == 0) + createAndShowExampleWidgetStandaloneWindow(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 index 3d3bbca1..c8d4d8e3 100644 --- a/tests/widgets/ExampleTextWidget.hpp +++ b/tests/widgets/ExampleTextWidget.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,51 +20,69 @@ // ------------------------------------------------------ // DGL Stuff -#include "NanoVG.hpp" +#include "../../dgl/NanoVG.hpp" + +START_NAMESPACE_DGL // ------------------------------------------------------ // our widget -class ExampleTextWidget : public NanoWidget +template +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 ExampleTextSubWidget; +typedef ExampleTextWidget ExampleTextTopLevelWidget; +typedef ExampleTextWidget ExampleTextStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_TEXT_WIDGET_HPP_INCLUDED