Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -19,10 +19,10 @@ | |||
| #include "Base.hpp" | |||
| START_NAMESPACE_DGL | |||
| struct NVGcolor; | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| @@ -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 | |||
| @@ -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(); | |||
| } | |||
| @@ -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 | |||
| { | |||
| @@ -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"); | |||
| } | |||
| @@ -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 | |||