@@ -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; | |||
} |