Browse Source

Very raw, preliminar subwidgets implementation

pull/6/head
falkTX 6 years ago
parent
commit
c6789d1889
5 changed files with 146 additions and 5 deletions
  1. +41
    -1
      dgl/NanoVG.hpp
  2. +17
    -0
      dgl/Widget.hpp
  3. +13
    -3
      dgl/src/NanoVG.cpp
  4. +72
    -0
      dgl/src/Widget.cpp
  5. +3
    -1
      dgl/src/Window.cpp

+ 41
- 1
dgl/NanoVG.hpp View File

@@ -295,6 +295,11 @@ public:
*/
NanoVG(int flags = CREATE_ANTIALIAS);

/**
Constructor reusing a NanoVG context, used for subwidgets.
*/
NanoVG(NanoWidget* groupWidget);

/**
Destructor.
*/
@@ -838,6 +843,7 @@ public:
private:
NVGcontext* const fContext;
bool fInFrame;
bool fIsSubWidget;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoVG)
};
@@ -860,7 +866,7 @@ public:
Constructor.
@see CreateFlags
*/
NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS)
explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS)
: Widget(parent),
NanoVG(flags),
leakDetector_NanoWidget()
@@ -868,6 +874,31 @@ public:
setNeedsScaling(true);
}

/**
Constructor for a subwidget.
*/
explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS)
: Widget(groupWidget, true),
NanoVG(flags),
leakDetector_NanoWidget()
{
setNeedsScaling(true);
}

/**
Constructor for a subwidget.
*/
explicit NanoWidget(NanoWidget* groupWidget)
: Widget(groupWidget, false),
NanoVG(groupWidget),
leakDetector_NanoWidget()
{
setNeedsScaling(true);
groupWidget->fNanoSubWidgets.push_back(this);
}

// fNanoSubWidgets.clear();

protected:
/**
New virtual onDisplay function.
@@ -876,6 +907,8 @@ protected:
virtual void onNanoDisplay() = 0;

private:
std::vector<NanoWidget*> fNanoSubWidgets;

/**
Widget display function.
Implemented internally to wrap begin/endFrame() automatically.
@@ -884,6 +917,13 @@ private:
{
beginFrame(getWidth(), getHeight());
onNanoDisplay();

for (std::vector<NanoWidget*>::iterator it = fNanoSubWidgets.begin(); it != fNanoSubWidgets.end(); ++it)
{
NanoWidget* const widget(*it);
widget->onNanoDisplay();
}

endFrame();
}



+ 17
- 0
dgl/Widget.hpp View File

@@ -19,12 +19,15 @@

#include "Geometry.hpp"

#include <vector>

START_NAMESPACE_DGL

// -----------------------------------------------------------------------
// Forward class names

class App;
class NanoWidget;
class Window;
class StandaloneWindow;

@@ -172,6 +175,11 @@ public:
*/
explicit Widget(Window& parent);

/**
Constructor for a subwidget.
*/
explicit Widget(Widget* groupWidget);

/**
Destructor.
*/
@@ -369,11 +377,20 @@ private:
Window& fParent;
bool fNeedsFullViewport;
bool fNeedsScaling;
bool fSkipDisplay;
bool fVisible;
uint fId;
Point<int> fAbsolutePos;
Size<uint> fSize;
std::vector<Widget*> fSubWidgets;

/** @internal */
explicit Widget(Widget* groupWidget, bool addToSubWidgets);

/** @internal */
void _displaySubWidgets();

friend class NanoWidget;
friend class Window;
friend class StandaloneWindow;



+ 13
- 3
dgl/src/NanoVG.cpp View File

@@ -43,8 +43,9 @@
// -----------------------------------------------------------------------
// Include NanoVG OpenGL implementation

//#define STB_IMAGE_STATIC 1
#define NANOVG_GL2_IMPLEMENTATION 1
//#define STB_IMAGE_STATIC
#define BLENDISH_IMPLEMENTATION
#define NANOVG_GL2_IMPLEMENTATION
#include "nanovg/nanovg_gl.h"
#include "oui-blendish/blendish.h"

@@ -188,16 +189,25 @@ void NanoImage::_updateSize()
NanoVG::NanoVG(int flags)
: fContext(nvgCreateGL(flags)),
fInFrame(false),
fIsSubWidget(false),
leakDetector_NanoVG()
{
DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,);
}

NanoVG::NanoVG(NanoWidget* groupWidget)
: fContext(groupWidget->fContext),
fInFrame(false),
fIsSubWidget(true),
leakDetector_NanoVG()
{
}

NanoVG::~NanoVG()
{
DISTRHO_SAFE_ASSERT(! fInFrame);

if (fContext != nullptr)
if (fContext != nullptr && ! fIsSubWidget)
nvgDeleteGL(fContext);
}



+ 72
- 0
dgl/src/Widget.cpp View File

@@ -26,6 +26,7 @@ Widget::Widget(Window& parent)
: fParent(parent),
fNeedsFullViewport(false),
fNeedsScaling(false),
fSkipDisplay(false),
fVisible(true),
fId(0),
fAbsolutePos(0, 0),
@@ -35,9 +36,42 @@ Widget::Widget(Window& parent)
fParent._addWidget(this);
}

Widget::Widget(Widget* groupWidget)
: fParent(groupWidget->getParentWindow()),
fNeedsFullViewport(false),
fNeedsScaling(false),
fSkipDisplay(true),
fVisible(true),
fId(0),
fAbsolutePos(0, 0),
fSize(0, 0),
leakDetector_Widget()
{
fParent._addWidget(this);
groupWidget->fSubWidgets.push_back(this);
}

Widget::Widget(Widget* groupWidget, bool addToSubWidgets)
: fParent(groupWidget->getParentWindow()),
fNeedsFullViewport(false),
fNeedsScaling(false),
fSkipDisplay(true),
fVisible(true),
fId(0),
fAbsolutePos(0, 0),
fSize(0, 0),
leakDetector_Widget()
{
fParent._addWidget(this);

if (addToSubWidgets)
groupWidget->fSubWidgets.push_back(this);
}

Widget::~Widget()
{
fParent._removeWidget(this);
fSubWidgets.clear();
}

bool Widget::isVisible() const noexcept
@@ -250,6 +284,44 @@ void Widget::setNeedsScaling(bool yesNo) noexcept
fNeedsScaling = yesNo;
}

void Widget::_displaySubWidgets()
{
for (std::vector<Widget*>::iterator it = fSubWidgets.begin(); it != fSubWidgets.end(); ++it)
{
Widget* const widget(*it);

if (widget->fNeedsScaling)
{
// limit viewport to widget bounds
glViewport(widget->getAbsoluteX(),
fParent.getHeight() - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(),
static_cast<GLsizei>(widget->getWidth()),
static_cast<GLsizei>(widget->getHeight()));
}
else
{
// only set viewport pos
glViewport(widget->getAbsoluteX(),
/*fParent.getHeight() - static_cast<int>(widget->getHeight())*/ - widget->getAbsoluteY(),
static_cast<GLsizei>(fParent.getWidth()),
static_cast<GLsizei>(fParent.getHeight()));

// then cut the outer bounds
glScissor(widget->getAbsoluteX(),
fParent.getHeight() - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(),
static_cast<GLsizei>(widget->getWidth()),
static_cast<GLsizei>(widget->getHeight()));

glEnable(GL_SCISSOR_TEST);
}

widget->onDisplay();

if (! fNeedsScaling)
glDisable(GL_SCISSOR_TEST);
}
}

// -----------------------------------------------------------------------

END_NAMESPACE_DGL

+ 3
- 1
dgl/src/Window.cpp View File

@@ -659,7 +659,7 @@ struct Window::PrivateData {
{
Widget* const widget(*it);

if (widget->isVisible())
if (widget->isVisible() && ! widget->fSkipDisplay)
{
// reset color
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
@@ -706,6 +706,8 @@ struct Window::PrivateData {
glDisable(GL_SCISSOR_TEST);
needsDisableScissor = false;
}

widget->_displaySubWidgets();
}
}



Loading…
Cancel
Save