DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit c6789d1889cfdb9fef784f19ab452ff70723ffc2
parent 3a77a1144f4cb53ded4fb9194eded380bdfa9316
Author: falkTX <falktx@gmail.com>
Date:   Sun,  3 May 2015 02:25:04 +0200

Very raw, preliminar subwidgets implementation

Diffstat:
Mdgl/NanoVG.hpp | 42+++++++++++++++++++++++++++++++++++++++++-
Mdgl/Widget.hpp | 17+++++++++++++++++
Mdgl/src/NanoVG.cpp | 16+++++++++++++---
Mdgl/src/Widget.cpp | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdgl/src/Window.cpp | 4+++-
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(); } }