commit bb33ac67bc3713a1fe2dd85104f93e466e04b806
parent 93ce2476d997f524cd2c2e749f7e672905d126b6
Author: falkTX <falktx@falktx.com>
Date: Sun, 11 Sep 2022 15:38:55 +0100
Implement reusing nanovg context across parent/children widgets
Diffstat:
2 files changed, 111 insertions(+), 17 deletions(-)
diff --git 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<SubWidget>* parentWidget);
+
+ /**
+ Constructor for a NanoSubWidget reusing a parent top-level-widget nanovg context.
+ */
+ explicit NanoBaseWidget(NanoBaseWidget<TopLevelWidget>* 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<TopLevelWidget>;
+ friend class NanoBaseWidget<StandaloneWindow>;
+
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoBaseWidget)
};
diff --git 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);
@@ -1058,16 +1066,72 @@ bool NanoVG::loadSharedResources()
#endif
// -----------------------------------------------------------------------
+
+template <class BaseWidget>
+void NanoBaseWidget<BaseWidget>::displayChildren()
+{
+ std::list<SubWidget*> children(BaseWidget::getChildren());
+
+ for (std::list<SubWidget*>::iterator it = children.begin(); it != children.end(); ++it)
+ {
+ if (NanoSubWidget* const subwidget = dynamic_cast<NanoSubWidget*>(*it))
+ {
+ if (subwidget->fUsingParentContext && subwidget->isVisible())
+ subwidget->onDisplay();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
// NanoSubWidget
template <>
-NanoBaseWidget<SubWidget>::NanoBaseWidget(Widget* const parent, int flags)
- : SubWidget(parent),
- NanoVG(flags)
+NanoBaseWidget<SubWidget>::NanoBaseWidget(Widget* const parentWidget, int flags)
+ : SubWidget(parentWidget),
+ NanoVG(flags),
+ fUsingParentContext(false)
{
setNeedsViewportScaling();
}
+template <>
+NanoBaseWidget<SubWidget>::NanoBaseWidget(NanoSubWidget* const parentWidget)
+ : SubWidget(parentWidget),
+ NanoVG(parentWidget->getContext()),
+ fUsingParentContext(true)
+{
+ setSkipDrawing();
+}
+
+template <>
+NanoBaseWidget<SubWidget>::NanoBaseWidget(NanoTopLevelWidget* const parentWidget)
+ : SubWidget(parentWidget),
+ NanoVG(parentWidget->getContext()),
+ fUsingParentContext(true)
+{
+ setSkipDrawing();
+}
+
+template <>
+inline void NanoBaseWidget<SubWidget>::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<SubWidget>;
// -----------------------------------------------------------------------
@@ -1076,7 +1140,17 @@ template class NanoBaseWidget<SubWidget>;
template <>
NanoBaseWidget<TopLevelWidget>::NanoBaseWidget(Window& windowToMapTo, int flags)
: TopLevelWidget(windowToMapTo),
- NanoVG(flags) {}
+ NanoVG(flags),
+ fUsingParentContext(false) {}
+
+template <>
+inline void NanoBaseWidget<TopLevelWidget>::onDisplay()
+{
+ NanoVG::beginFrame(TopLevelWidget::getWidth(), TopLevelWidget::getHeight());
+ onNanoDisplay();
+ displayChildren();
+ NanoVG::endFrame();
+}
template class NanoBaseWidget<TopLevelWidget>;
@@ -1086,12 +1160,23 @@ template class NanoBaseWidget<TopLevelWidget>;
template <>
NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, int flags)
: StandaloneWindow(app),
- NanoVG(flags) {}
+ NanoVG(flags),
+ fUsingParentContext(false) {}
template <>
NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, Window& parentWindow, int flags)
: StandaloneWindow(app, parentWindow),
- NanoVG(flags) {}
+ NanoVG(flags),
+ fUsingParentContext(false) {}
+
+template <>
+inline void NanoBaseWidget<StandaloneWindow>::onDisplay()
+{
+ NanoVG::beginFrame(Window::getWidth(), Window::getHeight());
+ onNanoDisplay();
+ displayChildren();
+ NanoVG::endFrame();
+}
template class NanoBaseWidget<StandaloneWindow>;