| @@ -867,38 +867,22 @@ public: | |||
| Constructor. | |||
| @see CreateFlags | |||
| */ | |||
| explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS) | |||
| : Widget(parent), | |||
| NanoVG(flags), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| fNeedsScaling = true; | |||
| } | |||
| explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS); | |||
| /** | |||
| Constructor for a subwidget. | |||
| */ | |||
| explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS) | |||
| : Widget(groupWidget, true), | |||
| NanoVG(flags), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| fNeedsScaling = true; | |||
| } | |||
| explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS); | |||
| /** | |||
| Constructor for a subwidget. | |||
| Constructor for a subwidget, reusing a NanoVG context. | |||
| */ | |||
| explicit NanoWidget(NanoWidget* groupWidget) | |||
| : Widget(groupWidget, false), | |||
| NanoVG(groupWidget), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| fNeedsScaling = true; | |||
| groupWidget->fNanoSubWidgets.push_back(this); | |||
| } | |||
| explicit NanoWidget(NanoWidget* groupWidget); | |||
| // fNanoSubWidgets.clear(); | |||
| /** | |||
| Destructor. | |||
| */ | |||
| virtual ~NanoWidget(); | |||
| protected: | |||
| /** | |||
| @@ -908,25 +892,21 @@ protected: | |||
| virtual void onNanoDisplay() = 0; | |||
| private: | |||
| std::vector<NanoWidget*> fNanoSubWidgets; | |||
| struct PrivateData; | |||
| PrivateData* const nData; | |||
| /** | |||
| Widget display function. | |||
| Implemented internally to wrap begin/endFrame() automatically. | |||
| */ | |||
| void onDisplay() override | |||
| { | |||
| beginFrame(getWidth(), getHeight()); | |||
| onNanoDisplay(); | |||
| for (std::vector<NanoWidget*>::iterator it = fNanoSubWidgets.begin(); it != fNanoSubWidgets.end(); ++it) | |||
| { | |||
| NanoWidget* const widget(*it); | |||
| widget->onNanoDisplay(); | |||
| } | |||
| void onDisplay() override; | |||
| endFrame(); | |||
| } | |||
| // these should not be used | |||
| void beginFrame(uint,uint) {} | |||
| void beginFrame(uint,uint,float) {} | |||
| void beginFrame(Widget*) {} | |||
| void cancelFrame() {} | |||
| void endFrame() {} | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget) | |||
| }; | |||
| @@ -29,47 +29,27 @@ class StandaloneWindow : public Application, | |||
| public Window | |||
| { | |||
| public: | |||
| StandaloneWindow() | |||
| : Application(), | |||
| Window((Application&)*this), | |||
| fWidget(nullptr) {} | |||
| /** | |||
| Constructor. | |||
| */ | |||
| StandaloneWindow(); | |||
| void exec() | |||
| { | |||
| Window::show(); | |||
| Application::exec(); | |||
| } | |||
| protected: | |||
| void onReshape(uint width, uint height) override | |||
| { | |||
| if (fWidget != nullptr) | |||
| fWidget->setSize(width, height); | |||
| Window::onReshape(width, height); | |||
| } | |||
| /** | |||
| Show window and execute application. | |||
| */ | |||
| void exec(); | |||
| private: | |||
| Widget* fWidget; | |||
| void _addWidget(Widget* widget) override | |||
| { | |||
| if (fWidget == nullptr) | |||
| { | |||
| fWidget = widget; | |||
| fWidget->fNeedsFullViewport = true; | |||
| } | |||
| Window::_addWidget(widget); | |||
| } | |||
| /** @internal */ | |||
| void onReshape(uint width, uint height) override; | |||
| /** @internal */ | |||
| void _addWidget(Widget* widget) override; | |||
| void _removeWidget(Widget* widget) override | |||
| { | |||
| if (fWidget == widget) | |||
| { | |||
| fWidget->fNeedsFullViewport = false; | |||
| fWidget = nullptr; | |||
| } | |||
| Window::_removeWidget(widget); | |||
| } | |||
| /** @internal */ | |||
| void _removeWidget(Widget* widget) override; | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow) | |||
| }; | |||
| @@ -363,22 +363,12 @@ protected: | |||
| virtual void onResize(const ResizeEvent&); | |||
| private: | |||
| Window& fParent; | |||
| bool fNeedsFullViewport; | |||
| bool fNeedsScaling; | |||
| bool fSkipDisplay; | |||
| bool fVisible; | |||
| uint fId; | |||
| Point<int> fAbsolutePos; | |||
| Size<uint> fSize; | |||
| std::vector<Widget*> fSubWidgets; | |||
| struct PrivateData; | |||
| PrivateData* const pData; | |||
| /** @internal */ | |||
| explicit Widget(Widget* groupWidget, bool addToSubWidgets); | |||
| /** @internal */ | |||
| void _displaySubWidgets(); | |||
| friend class ImageSlider; | |||
| friend class NanoWidget; | |||
| friend class Window; | |||
| @@ -15,8 +15,7 @@ | |||
| */ | |||
| #include "../ImageWidgets.hpp" | |||
| #include <cmath> | |||
| #include "WidgetPrivateData.hpp" | |||
| START_NAMESPACE_DGL | |||
| @@ -742,7 +741,7 @@ ImageSlider::ImageSlider(Window& parent, const Image& image) noexcept | |||
| fSliderArea(), | |||
| leakDetector_ImageSlider() | |||
| { | |||
| fNeedsFullViewport = true; | |||
| pData->needsFullViewport = true; | |||
| } | |||
| ImageSlider::ImageSlider(Widget* widget, const Image& image) noexcept | |||
| @@ -764,7 +763,7 @@ ImageSlider::ImageSlider(Widget* widget, const Image& image) noexcept | |||
| fSliderArea(), | |||
| leakDetector_ImageSlider() | |||
| { | |||
| fNeedsFullViewport = true; | |||
| pData->needsFullViewport = true; | |||
| } | |||
| float ImageSlider::getValue() const noexcept | |||
| @@ -15,7 +15,7 @@ | |||
| */ | |||
| #include "../NanoVG.hpp" | |||
| #include "../Window.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| // ----------------------------------------------------------------------- | |||
| // Ignore some warnings if debugging | |||
| @@ -859,6 +859,69 @@ int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWi | |||
| // ----------------------------------------------------------------------- | |||
| struct NanoWidget::PrivateData { | |||
| NanoWidget* const self; | |||
| std::vector<NanoWidget*> subWidgets; | |||
| PrivateData(NanoWidget* const s) | |||
| : self(s), | |||
| subWidgets() {} | |||
| ~PrivateData() | |||
| { | |||
| subWidgets.clear(); | |||
| } | |||
| }; | |||
| NanoWidget::NanoWidget(Window& parent, int flags) | |||
| : Widget(parent), | |||
| NanoVG(flags), | |||
| nData(new PrivateData(this)), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| pData->needsScaling = true; | |||
| } | |||
| NanoWidget::NanoWidget(Widget* groupWidget, int flags) | |||
| : Widget(groupWidget, true), | |||
| NanoVG(flags), | |||
| nData(new PrivateData(this)), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| pData->needsScaling = true; | |||
| } | |||
| NanoWidget::NanoWidget(NanoWidget* groupWidget) | |||
| : Widget(groupWidget, false), | |||
| NanoVG(groupWidget), | |||
| nData(new PrivateData(this)), | |||
| leakDetector_NanoWidget() | |||
| { | |||
| pData->needsScaling = true; | |||
| groupWidget->nData->subWidgets.push_back(this); | |||
| } | |||
| NanoWidget::~NanoWidget() | |||
| { | |||
| delete nData; | |||
| } | |||
| void NanoWidget::onDisplay() | |||
| { | |||
| NanoVG::beginFrame(getWidth(), getHeight()); | |||
| onNanoDisplay(); | |||
| for (std::vector<NanoWidget*>::iterator it = nData->subWidgets.begin(); it != nData->subWidgets.end(); ++it) | |||
| { | |||
| NanoWidget* const widget(*it); | |||
| widget->onNanoDisplay(); | |||
| } | |||
| NanoVG::endFrame(); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| extern "C" { | |||
| @@ -14,8 +14,7 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "../Widget.hpp" | |||
| #include "../Window.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| START_NAMESPACE_DGL | |||
| @@ -23,69 +22,44 @@ START_NAMESPACE_DGL | |||
| // Widget | |||
| Widget::Widget(Window& parent) | |||
| : fParent(parent), | |||
| fNeedsFullViewport(false), | |||
| fNeedsScaling(false), | |||
| fSkipDisplay(false), | |||
| fVisible(true), | |||
| fId(0), | |||
| fAbsolutePos(0, 0), | |||
| fSize(0, 0), | |||
| : pData(new PrivateData(this, parent, nullptr, false)), | |||
| leakDetector_Widget() | |||
| { | |||
| fParent._addWidget(this); | |||
| parent._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), | |||
| : pData(new PrivateData(this, groupWidget->getParentWindow(), groupWidget, true)), | |||
| leakDetector_Widget() | |||
| { | |||
| fParent._addWidget(this); | |||
| groupWidget->fSubWidgets.push_back(this); | |||
| pData->parent._addWidget(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), | |||
| : pData(new PrivateData(this, groupWidget->getParentWindow(), groupWidget, addToSubWidgets)), | |||
| leakDetector_Widget() | |||
| { | |||
| fParent._addWidget(this); | |||
| if (addToSubWidgets) | |||
| groupWidget->fSubWidgets.push_back(this); | |||
| pData->parent._addWidget(this); | |||
| } | |||
| Widget::~Widget() | |||
| { | |||
| fParent._removeWidget(this); | |||
| fSubWidgets.clear(); | |||
| pData->parent._removeWidget(this); | |||
| delete pData; | |||
| } | |||
| bool Widget::isVisible() const noexcept | |||
| { | |||
| return fVisible; | |||
| return pData->visible; | |||
| } | |||
| void Widget::setVisible(bool yesNo) | |||
| { | |||
| if (fVisible == yesNo) | |||
| if (pData->visible == yesNo) | |||
| return; | |||
| fVisible = yesNo; | |||
| fParent.repaint(); | |||
| pData->visible = yesNo; | |||
| pData->parent.repaint(); | |||
| } | |||
| void Widget::show() | |||
| @@ -100,47 +74,47 @@ void Widget::hide() | |||
| uint Widget::getWidth() const noexcept | |||
| { | |||
| return fSize.getWidth(); | |||
| return pData->size.getWidth(); | |||
| } | |||
| uint Widget::getHeight() const noexcept | |||
| { | |||
| return fSize.getHeight(); | |||
| return pData->size.getHeight(); | |||
| } | |||
| const Size<uint>& Widget::getSize() const noexcept | |||
| { | |||
| return fSize; | |||
| return pData->size; | |||
| } | |||
| void Widget::setWidth(uint width) noexcept | |||
| { | |||
| if (fSize.getWidth() == width) | |||
| if (pData->size.getWidth() == width) | |||
| return; | |||
| ResizeEvent ev; | |||
| ev.oldSize = fSize; | |||
| ev.size = Size<uint>(width, fSize.getHeight()); | |||
| ev.oldSize = pData->size; | |||
| ev.size = Size<uint>(width, pData->size.getHeight()); | |||
| fSize.setWidth(width); | |||
| pData->size.setWidth(width); | |||
| onResize(ev); | |||
| fParent.repaint(); | |||
| pData->parent.repaint(); | |||
| } | |||
| void Widget::setHeight(uint height) noexcept | |||
| { | |||
| if (fSize.getHeight() == height) | |||
| if (pData->size.getHeight() == height) | |||
| return; | |||
| ResizeEvent ev; | |||
| ev.oldSize = fSize; | |||
| ev.size = Size<uint>(fSize.getWidth(), height); | |||
| ev.oldSize = pData->size; | |||
| ev.size = Size<uint>(pData->size.getWidth(), height); | |||
| fSize.setHeight(height); | |||
| pData->size.setHeight(height); | |||
| onResize(ev); | |||
| fParent.repaint(); | |||
| pData->parent.repaint(); | |||
| } | |||
| void Widget::setSize(uint width, uint height) noexcept | |||
| @@ -150,50 +124,50 @@ void Widget::setSize(uint width, uint height) noexcept | |||
| void Widget::setSize(const Size<uint>& size) noexcept | |||
| { | |||
| if (fSize == size) | |||
| if (pData->size == size) | |||
| return; | |||
| ResizeEvent ev; | |||
| ev.oldSize = fSize; | |||
| ev.oldSize = pData->size; | |||
| ev.size = size; | |||
| fSize = size; | |||
| pData->size = size; | |||
| onResize(ev); | |||
| fParent.repaint(); | |||
| pData->parent.repaint(); | |||
| } | |||
| int Widget::getAbsoluteX() const noexcept | |||
| { | |||
| return fAbsolutePos.getX(); | |||
| return pData->absolutePos.getX(); | |||
| } | |||
| int Widget::getAbsoluteY() const noexcept | |||
| { | |||
| return fAbsolutePos.getY(); | |||
| return pData->absolutePos.getY(); | |||
| } | |||
| const Point<int>& Widget::getAbsolutePos() const noexcept | |||
| { | |||
| return fAbsolutePos; | |||
| return pData->absolutePos; | |||
| } | |||
| void Widget::setAbsoluteX(int x) noexcept | |||
| { | |||
| if (fAbsolutePos.getX() == x) | |||
| if (pData->absolutePos.getX() == x) | |||
| return; | |||
| fAbsolutePos.setX(x); | |||
| fParent.repaint(); | |||
| pData->absolutePos.setX(x); | |||
| pData->parent.repaint(); | |||
| } | |||
| void Widget::setAbsoluteY(int y) noexcept | |||
| { | |||
| if (fAbsolutePos.getY() == y) | |||
| if (pData->absolutePos.getY() == y) | |||
| return; | |||
| fAbsolutePos.setY(y); | |||
| fParent.repaint(); | |||
| pData->absolutePos.setY(y); | |||
| pData->parent.repaint(); | |||
| } | |||
| void Widget::setAbsolutePos(int x, int y) noexcept | |||
| @@ -203,26 +177,26 @@ void Widget::setAbsolutePos(int x, int y) noexcept | |||
| void Widget::setAbsolutePos(const Point<int>& pos) noexcept | |||
| { | |||
| if (fAbsolutePos == pos) | |||
| if (pData->absolutePos == pos) | |||
| return; | |||
| fAbsolutePos = pos; | |||
| fParent.repaint(); | |||
| pData->absolutePos = pos; | |||
| pData->parent.repaint(); | |||
| } | |||
| Application& Widget::getParentApp() const noexcept | |||
| { | |||
| return fParent.getApp(); | |||
| return pData->parent.getApp(); | |||
| } | |||
| Window& Widget::getParentWindow() const noexcept | |||
| { | |||
| return fParent; | |||
| return pData->parent; | |||
| } | |||
| bool Widget::contains(int x, int y) const noexcept | |||
| { | |||
| return (x >= 0 && y >= 0 && static_cast<uint>(x) < fSize.getWidth() && static_cast<uint>(y) < fSize.getHeight()); | |||
| return (x >= 0 && y >= 0 && static_cast<uint>(x) < pData->size.getWidth() && static_cast<uint>(y) < pData->size.getHeight()); | |||
| } | |||
| bool Widget::contains(const Point<int>& pos) const noexcept | |||
| @@ -232,17 +206,17 @@ bool Widget::contains(const Point<int>& pos) const noexcept | |||
| void Widget::repaint() noexcept | |||
| { | |||
| fParent.repaint(); | |||
| pData->parent.repaint(); | |||
| } | |||
| uint Widget::getId() const noexcept | |||
| { | |||
| return fId; | |||
| return pData->id; | |||
| } | |||
| void Widget::setId(uint id) noexcept | |||
| { | |||
| fId = id; | |||
| pData->id = id; | |||
| } | |||
| bool Widget::onKeyboard(const KeyboardEvent&) | |||
| @@ -274,44 +248,6 @@ void Widget::onResize(const ResizeEvent&) | |||
| { | |||
| } | |||
| 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 | |||
| @@ -0,0 +1,133 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| * permission notice appear in all copies. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #ifndef DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | |||
| #define DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | |||
| #include "../Widget.hpp" | |||
| #include "../Window.hpp" | |||
| #include <vector> | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| struct Widget::PrivateData { | |||
| Widget* const self; | |||
| Window& parent; | |||
| Point<int> absolutePos; | |||
| Size<uint> size; | |||
| std::vector<Widget*> subWidgets; | |||
| uint id; | |||
| bool needsFullViewport; | |||
| bool needsScaling; | |||
| bool skipDisplay; | |||
| bool visible; | |||
| PrivateData(Widget* const s, Window& p, Widget* groupWidget, bool addToSubWidgets) | |||
| : self(s), | |||
| parent(p), | |||
| absolutePos(0, 0), | |||
| size(0, 0), | |||
| id(0), | |||
| needsFullViewport(false), | |||
| needsScaling(false), | |||
| skipDisplay(false), | |||
| visible(true) | |||
| { | |||
| if (addToSubWidgets && groupWidget != nullptr) | |||
| groupWidget->pData->subWidgets.push_back(self); | |||
| } | |||
| ~PrivateData() | |||
| { | |||
| subWidgets.clear(); | |||
| } | |||
| void display(const uint width, const uint height) | |||
| { | |||
| if (skipDisplay || ! visible) | |||
| return; | |||
| bool needsDisableScissor = false; | |||
| // reset color | |||
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
| if (needsFullViewport || (absolutePos.isZero() && size == Size<uint>(width, height))) | |||
| { | |||
| // full viewport size | |||
| glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height)); | |||
| } | |||
| else if (needsScaling) | |||
| { | |||
| // limit viewport to widget bounds | |||
| glViewport(absolutePos.getX(), | |||
| height - static_cast<int>(self->getHeight()) - absolutePos.getY(), | |||
| static_cast<GLsizei>(self->getWidth()), | |||
| static_cast<GLsizei>(self->getHeight())); | |||
| } | |||
| else | |||
| { | |||
| // only set viewport pos | |||
| glViewport(absolutePos.getX(), | |||
| /*height - static_cast<int>(self->getHeight())*/ - absolutePos.getY(), | |||
| static_cast<GLsizei>(width), | |||
| static_cast<GLsizei>(height)); | |||
| // then cut the outer bounds | |||
| glScissor(absolutePos.getX(), | |||
| height - static_cast<int>(self->getHeight()) - absolutePos.getY(), | |||
| static_cast<GLsizei>(self->getWidth()), | |||
| static_cast<GLsizei>(self->getHeight())); | |||
| glEnable(GL_SCISSOR_TEST); | |||
| needsDisableScissor = true; | |||
| } | |||
| // display widget | |||
| self->onDisplay(); | |||
| if (needsDisableScissor) | |||
| { | |||
| glDisable(GL_SCISSOR_TEST); | |||
| needsDisableScissor = false; | |||
| } | |||
| displaySubWidgets(width, height); | |||
| } | |||
| void displaySubWidgets(const uint width, const uint height) | |||
| { | |||
| for (std::vector<Widget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||
| { | |||
| Widget* const widget(*it); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(widget->pData != this); | |||
| widget->pData->display(width, height); | |||
| } | |||
| } | |||
| DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| #endif // DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | |||
| @@ -40,8 +40,8 @@ extern "C" { | |||
| #endif | |||
| #include "ApplicationPrivateData.hpp" | |||
| #include "../Widget.hpp" | |||
| #include "../Window.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| #include "../StandaloneWindow.hpp" | |||
| #include "../../distrho/extra/String.hpp" | |||
| #define FOR_EACH_WIDGET(it) \ | |||
| @@ -671,62 +671,10 @@ struct Window::PrivateData { | |||
| { | |||
| fSelf->onDisplayBefore(); | |||
| bool needsDisableScissor = false; | |||
| FOR_EACH_WIDGET(it) | |||
| { | |||
| Widget* const widget(*it); | |||
| if (widget->isVisible() && ! widget->fSkipDisplay) | |||
| { | |||
| // reset color | |||
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
| if (widget->fNeedsFullViewport || (widget->fAbsolutePos.isZero() && widget->fSize == Size<uint>(fWidth, fHeight))) | |||
| { | |||
| // full viewport size | |||
| glViewport(0, | |||
| 0, | |||
| static_cast<GLsizei>(fWidth), | |||
| static_cast<GLsizei>(fHeight)); | |||
| } | |||
| else if (! widget->fNeedsScaling) | |||
| { | |||
| // only set viewport pos | |||
| glViewport(widget->getAbsoluteX(), | |||
| /*fView->height - static_cast<int>(widget->getHeight())*/ - widget->getAbsoluteY(), | |||
| static_cast<GLsizei>(fWidth), | |||
| static_cast<GLsizei>(fHeight)); | |||
| // then cut the outer bounds | |||
| glScissor(widget->getAbsoluteX(), | |||
| fView->height - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(), | |||
| static_cast<GLsizei>(widget->getWidth()), | |||
| static_cast<GLsizei>(widget->getHeight())); | |||
| glEnable(GL_SCISSOR_TEST); | |||
| needsDisableScissor = true; | |||
| } | |||
| else | |||
| { | |||
| // limit viewport to widget bounds | |||
| glViewport(widget->getAbsoluteX(), | |||
| fView->height - static_cast<int>(widget->getHeight()) - widget->getAbsoluteY(), | |||
| static_cast<GLsizei>(widget->getWidth()), | |||
| static_cast<GLsizei>(widget->getHeight())); | |||
| } | |||
| // display widget | |||
| widget->onDisplay(); | |||
| if (needsDisableScissor) | |||
| { | |||
| glDisable(GL_SCISSOR_TEST); | |||
| needsDisableScissor = false; | |||
| } | |||
| widget->_displaySubWidgets(); | |||
| } | |||
| widget->pData->display(fWidth, fHeight); | |||
| } | |||
| fSelf->onDisplayAfter(); | |||
| @@ -864,7 +812,7 @@ struct Window::PrivateData { | |||
| { | |||
| Widget* const widget(*it); | |||
| if (widget->fNeedsFullViewport) | |||
| if (widget->pData->needsFullViewport) | |||
| widget->setSize(fWidth, fHeight); | |||
| } | |||
| } | |||
| @@ -1246,6 +1194,46 @@ void Window::fileBrowserSelected(const char*) | |||
| // ----------------------------------------------------------------------- | |||
| StandaloneWindow::StandaloneWindow() | |||
| : Application(), | |||
| Window((Application&)*this), | |||
| fWidget(nullptr) {} | |||
| void StandaloneWindow::exec() | |||
| { | |||
| Window::show(); | |||
| Application::exec(); | |||
| } | |||
| void StandaloneWindow::onReshape(uint width, uint height) | |||
| { | |||
| if (fWidget != nullptr) | |||
| fWidget->setSize(width, height); | |||
| Window::onReshape(width, height); | |||
| } | |||
| void StandaloneWindow::_addWidget(Widget* widget) | |||
| { | |||
| if (fWidget == nullptr) | |||
| { | |||
| fWidget = widget; | |||
| fWidget->pData->needsFullViewport = true; | |||
| } | |||
| Window::_addWidget(widget); | |||
| } | |||
| void StandaloneWindow::_removeWidget(Widget* widget) | |||
| { | |||
| if (fWidget == widget) | |||
| { | |||
| fWidget->pData->needsFullViewport = false; | |||
| fWidget = nullptr; | |||
| } | |||
| Window::_removeWidget(widget); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| #undef DBG | |||
| @@ -225,6 +225,7 @@ puglEnterContext(PuglView* view); | |||
| void | |||
| puglLeaveContext(PuglView* view, bool flush); | |||
| #if 0 | |||
| /** Return the code point for buf, or the replacement character on error. */ | |||
| static uint32_t | |||
| puglDecodeUTF8(const uint8_t* buf) | |||
| @@ -258,6 +259,7 @@ puglDecodeUTF8(const uint8_t* buf) | |||
| } | |||
| return 0xFFFD; | |||
| } | |||
| #endif | |||
| static void | |||
| puglDefaultReshape(PuglView* view, int width, int height) | |||
| @@ -603,4 +603,7 @@ puglGetContext(PuglView* view) | |||
| } | |||
| #endif | |||
| return NULL; | |||
| // may be unused | |||
| (void)view; | |||
| } | |||