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.
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)
};



+ 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);
}

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 <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>;



Loading…
Cancel
Save