Browse Source

Implement reusing nanovg context across parent/children widgets

pull/321/merge
falkTX 2 years ago
parent
commit
bb33ac67bc
2 changed files with 111 additions and 17 deletions
  1. +20
    -11
      dgl/NanoVG.hpp
  2. +91
    -6
      dgl/src/NanoVG.cpp

+ 20
- 11
dgl/NanoVG.hpp View File

@@ -319,10 +319,9 @@ public:


/** /**
Constructor reusing a NanoVG context, used for subwidgets. Constructor reusing a NanoVG context, used for subwidgets.
Context will not be deleted on class destructor.
*/ */
/*
NanoVG(NanoWidget* groupWidget);
*/
explicit NanoVG(NVGcontext* context);


/** /**
Destructor. Destructor.
@@ -917,7 +916,17 @@ public:
Constructor for a NanoSubWidget. Constructor for a NanoSubWidget.
@see CreateFlags @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. Constructor for a NanoTopLevelWidget.
@@ -954,13 +963,7 @@ private:
Widget display function. Widget display function.
Implemented internally to wrap begin/endFrame() automatically. 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 // these should not be used
void beginFrame(uint,uint) {} void beginFrame(uint,uint) {}
@@ -969,6 +972,12 @@ private:
void cancelFrame() {} void cancelFrame() {}
void endFrame() {} void endFrame() {}


/** @internal */
const bool fUsingParentContext;
void displayChildren();
friend class NanoBaseWidget<TopLevelWidget>;
friend class NanoBaseWidget<StandaloneWindow>;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoBaseWidget) DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoBaseWidget)
}; };




+ 91
- 6
dgl/src/NanoVG.cpp View File

@@ -327,6 +327,14 @@ NanoVG::NanoVG(int flags)
DISTRHO_CUSTOM_SAFE_ASSERT("Failed to create NanoVG context, expect a black screen", fContext != nullptr); 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() NanoVG::~NanoVG()
{ {
DISTRHO_CUSTOM_SAFE_ASSERT("Destroying NanoVG context with still active frame", ! fInFrame); DISTRHO_CUSTOM_SAFE_ASSERT("Destroying NanoVG context with still active frame", ! fInFrame);
@@ -1057,17 +1065,73 @@ bool NanoVG::loadSharedResources()
} }
#endif #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 // NanoSubWidget


template <> 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(); 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>; template class NanoBaseWidget<SubWidget>;


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -1076,7 +1140,17 @@ template class NanoBaseWidget<SubWidget>;
template <> template <>
NanoBaseWidget<TopLevelWidget>::NanoBaseWidget(Window& windowToMapTo, int flags) NanoBaseWidget<TopLevelWidget>::NanoBaseWidget(Window& windowToMapTo, int flags)
: TopLevelWidget(windowToMapTo), : 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>; template class NanoBaseWidget<TopLevelWidget>;


@@ -1086,12 +1160,23 @@ template class NanoBaseWidget<TopLevelWidget>;
template <> template <>
NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, int flags) NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, int flags)
: StandaloneWindow(app), : StandaloneWindow(app),
NanoVG(flags) {}
NanoVG(flags),
fUsingParentContext(false) {}


template <> template <>
NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, Window& parentWindow, int flags) NanoBaseWidget<StandaloneWindow>::NanoBaseWidget(Application& app, Window& parentWindow, int flags)
: StandaloneWindow(app, parentWindow), : 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>; template class NanoBaseWidget<StandaloneWindow>;




Loading…
Cancel
Save