diff --git a/dgl/NanoVG.hpp b/dgl/NanoVG.hpp index ebafdb99..a1fab235 100644 --- a/dgl/NanoVG.hpp +++ b/dgl/NanoVG.hpp @@ -319,10 +319,9 @@ public: /** Constructor reusing a NanoVG context, used for subwidgets. + Context will not be deleted on class destructor. */ - /* - NanoVG(NanoWidget* groupWidget); - */ + explicit NanoVG(NVGcontext* context); /** Destructor. @@ -917,7 +916,17 @@ public: Constructor for a NanoSubWidget. @see CreateFlags */ - explicit NanoBaseWidget(Widget* parentGroupWidget, int flags = CREATE_ANTIALIAS); + explicit NanoBaseWidget(Widget* parentWidget, int flags = CREATE_ANTIALIAS); + + /** + Constructor for a NanoSubWidget reusing a parent subwidget nanovg context. + */ + explicit NanoBaseWidget(NanoBaseWidget* parentWidget); + + /** + Constructor for a NanoSubWidget reusing a parent top-level-widget nanovg context. + */ + explicit NanoBaseWidget(NanoBaseWidget* parentWidget); /** Constructor for a NanoTopLevelWidget. @@ -954,13 +963,7 @@ private: Widget display function. Implemented internally to wrap begin/endFrame() automatically. */ - inline void onDisplay() override - { - // NOTE maybe should use BaseWidget::getWindow().getScaleFactor() as 3rd arg ? - NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight()); - onNanoDisplay(); - NanoVG::endFrame(); - } + void onDisplay() override; // these should not be used void beginFrame(uint,uint) {} @@ -969,6 +972,12 @@ private: void cancelFrame() {} void endFrame() {} + /** @internal */ + const bool fUsingParentContext; + void displayChildren(); + friend class NanoBaseWidget; + friend class NanoBaseWidget; + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoBaseWidget) }; diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp index f5f0b9fd..f3fd71d6 100644 --- a/dgl/src/NanoVG.cpp +++ b/dgl/src/NanoVG.cpp @@ -327,6 +327,14 @@ NanoVG::NanoVG(int flags) DISTRHO_CUSTOM_SAFE_ASSERT("Failed to create NanoVG context, expect a black screen", fContext != nullptr); } +NanoVG::NanoVG(NVGcontext* const context) + : fContext(context), + fInFrame(false), + fIsSubWidget(true) +{ + DISTRHO_CUSTOM_SAFE_ASSERT("Failed to create NanoVG context, expect a black screen", fContext != nullptr); +} + NanoVG::~NanoVG() { DISTRHO_CUSTOM_SAFE_ASSERT("Destroying NanoVG context with still active frame", ! fInFrame); @@ -1057,17 +1065,73 @@ bool NanoVG::loadSharedResources() } #endif +// ----------------------------------------------------------------------- + +template +void NanoBaseWidget::displayChildren() +{ + std::list children(BaseWidget::getChildren()); + + for (std::list::iterator it = children.begin(); it != children.end(); ++it) + { + if (NanoSubWidget* const subwidget = dynamic_cast(*it)) + { + if (subwidget->fUsingParentContext && subwidget->isVisible()) + subwidget->onDisplay(); + } + } +} + // ----------------------------------------------------------------------- // NanoSubWidget template <> -NanoBaseWidget::NanoBaseWidget(Widget* const parent, int flags) - : SubWidget(parent), - NanoVG(flags) +NanoBaseWidget::NanoBaseWidget(Widget* const parentWidget, int flags) + : SubWidget(parentWidget), + NanoVG(flags), + fUsingParentContext(false) { setNeedsViewportScaling(); } +template <> +NanoBaseWidget::NanoBaseWidget(NanoSubWidget* const parentWidget) + : SubWidget(parentWidget), + NanoVG(parentWidget->getContext()), + fUsingParentContext(true) +{ + setSkipDrawing(); +} + +template <> +NanoBaseWidget::NanoBaseWidget(NanoTopLevelWidget* const parentWidget) + : SubWidget(parentWidget), + NanoVG(parentWidget->getContext()), + fUsingParentContext(true) +{ + setSkipDrawing(); +} + +template <> +inline void NanoBaseWidget::onDisplay() +{ + if (fUsingParentContext) + { + NanoVG::save(); + translate(SubWidget::getAbsoluteX(), SubWidget::getAbsoluteY()); + onNanoDisplay(); + NanoVG::restore(); + displayChildren(); + } + else + { + NanoVG::beginFrame(SubWidget::getWidth(), SubWidget::getHeight()); + onNanoDisplay(); + displayChildren(); + NanoVG::endFrame(); + } +} + template class NanoBaseWidget; // ----------------------------------------------------------------------- @@ -1076,7 +1140,17 @@ template class NanoBaseWidget; template <> NanoBaseWidget::NanoBaseWidget(Window& windowToMapTo, int flags) : TopLevelWidget(windowToMapTo), - NanoVG(flags) {} + NanoVG(flags), + fUsingParentContext(false) {} + +template <> +inline void NanoBaseWidget::onDisplay() +{ + NanoVG::beginFrame(TopLevelWidget::getWidth(), TopLevelWidget::getHeight()); + onNanoDisplay(); + displayChildren(); + NanoVG::endFrame(); +} template class NanoBaseWidget; @@ -1086,12 +1160,23 @@ template class NanoBaseWidget; template <> NanoBaseWidget::NanoBaseWidget(Application& app, int flags) : StandaloneWindow(app), - NanoVG(flags) {} + NanoVG(flags), + fUsingParentContext(false) {} template <> NanoBaseWidget::NanoBaseWidget(Application& app, Window& parentWindow, int flags) : StandaloneWindow(app, parentWindow), - NanoVG(flags) {} + NanoVG(flags), + fUsingParentContext(false) {} + +template <> +inline void NanoBaseWidget::onDisplay() +{ + NanoVG::beginFrame(Window::getWidth(), Window::getHeight()); + onNanoDisplay(); + displayChildren(); + NanoVG::endFrame(); +} template class NanoBaseWidget;