diff --git a/dgl/SubWidget.hpp b/dgl/SubWidget.hpp index d439771b..137bb809 100644 --- a/dgl/SubWidget.hpp +++ b/dgl/SubWidget.hpp @@ -129,7 +129,7 @@ public: /** Indicate that this subwidget will always draw at its own internal size and needs scaling to fit target size. */ - void setNeedsViewportScaling(bool needsViewportScaling = true); + void setNeedsViewportScaling(bool needsViewportScaling = true, double autoScaleFactor = 0.0); /** Indicate that this subwidget should not be drawn on screen, typically because it is managed by something else. diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp index 4d039357..df2cdf38 100644 --- a/dgl/src/OpenGL.cpp +++ b/dgl/src/OpenGL.cpp @@ -575,21 +575,33 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const bool needsDisableScissor = false; - if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size(width, height))) + if (needsViewportScaling) { - // full viewport size - glViewport(0, - -static_cast(height * autoScaleFactor - height + 0.5), - static_cast(width * autoScaleFactor + 0.5), - static_cast(height * autoScaleFactor + 0.5)); + // limit viewport to widget bounds + const int x = absolutePos.getX(); + const int w = static_cast(self->getWidth()); + const int h = static_cast(self->getHeight()); + + if (viewportScaleFactor != 0.0) + { + glViewport(x, + -static_cast(height * viewportScaleFactor - height + absolutePos.getY() + 0.5), + static_cast(width * viewportScaleFactor + 0.5), + static_cast(height * viewportScaleFactor + 0.5)); + } + else + { + const int y = static_cast(height - self->getHeight()) - absolutePos.getY(); + glViewport(x, y, w, h); + } } - else if (needsViewportScaling) + else if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size(width, height))) { - // limit viewport to widget bounds - glViewport(absolutePos.getX(), - static_cast(height - self->getHeight()) - absolutePos.getY(), - static_cast(self->getWidth()), - static_cast(self->getHeight())); + // full viewport size + glViewport(0, + -static_cast(height - height + 0.5), + static_cast(width + 0.5), + static_cast(height + 0.5)); } else { diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp index 066d5ab3..ab084648 100644 --- a/dgl/src/SubWidget.cpp +++ b/dgl/src/SubWidget.cpp @@ -123,9 +123,10 @@ void SubWidget::setNeedsFullViewportDrawing(const bool needsFullViewportForDrawi pData->needsFullViewportForDrawing = needsFullViewportForDrawing; } -void SubWidget::setNeedsViewportScaling(const bool needsViewportScaling) +void SubWidget::setNeedsViewportScaling(const bool needsViewportScaling, const double autoScaleFactor) { pData->needsViewportScaling = needsViewportScaling; + pData->viewportScaleFactor = autoScaleFactor; } void SubWidget::setSkipDrawing(const bool skipDrawing) diff --git a/dgl/src/SubWidgetPrivateData.cpp b/dgl/src/SubWidgetPrivateData.cpp index 4a1c2914..b470f7f5 100644 --- a/dgl/src/SubWidgetPrivateData.cpp +++ b/dgl/src/SubWidgetPrivateData.cpp @@ -28,7 +28,8 @@ SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const pw) absolutePos(), needsFullViewportForDrawing(false), needsViewportScaling(false), - skipDrawing(false) + skipDrawing(false), + viewportScaleFactor(0.0) { parentWidget->pData->subWidgets.push_back(self); } diff --git a/dgl/src/SubWidgetPrivateData.hpp b/dgl/src/SubWidgetPrivateData.hpp index 138d35ff..a46655b2 100644 --- a/dgl/src/SubWidgetPrivateData.hpp +++ b/dgl/src/SubWidgetPrivateData.hpp @@ -30,7 +30,8 @@ struct SubWidget::PrivateData { Point absolutePos; bool needsFullViewportForDrawing; // needed for widgets drawing out of bounds bool needsViewportScaling; // needed for NanoVG - bool skipDrawing; + bool skipDrawing; // for context reuse in NanoVG based guis + double viewportScaleFactor; // auto-scaling for NanoVG explicit PrivateData(SubWidget* const s, Widget* const pw); ~PrivateData();