commit c6789d1889cfdb9fef784f19ab452ff70723ffc2
parent 3a77a1144f4cb53ded4fb9194eded380bdfa9316
Author: falkTX <falktx@gmail.com>
Date: Sun, 3 May 2015 02:25:04 +0200
Very raw, preliminar subwidgets implementation
Diffstat:
5 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/dgl/NanoVG.hpp b/dgl/NanoVG.hpp
@@ -296,6 +296,11 @@ public:
NanoVG(int flags = CREATE_ANTIALIAS);
/**
+ Constructor reusing a NanoVG context, used for subwidgets.
+ */
+ NanoVG(NanoWidget* groupWidget);
+
+ /**
Destructor.
*/
virtual ~NanoVG();
@@ -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();
}
diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp
@@ -19,12 +19,15 @@
#include "Geometry.hpp"
+#include <vector>
+
START_NAMESPACE_DGL
// -----------------------------------------------------------------------
// Forward class names
class App;
+class NanoWidget;
class Window;
class StandaloneWindow;
@@ -173,6 +176,11 @@ public:
explicit Widget(Window& parent);
/**
+ Constructor for a subwidget.
+ */
+ explicit Widget(Widget* groupWidget);
+
+ /**
Destructor.
*/
virtual ~Widget();
@@ -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;
diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp
@@ -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);
}
diff --git a/dgl/src/Widget.cpp b/dgl/src/Widget.cpp
@@ -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
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -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();
}
}