Browse Source

Hide some implementation details on private structs

pull/6/head
falkTX 6 years ago
parent
commit
c4008e3368
10 changed files with 331 additions and 257 deletions
  1. +17
    -37
      dgl/NanoVG.hpp
  2. +15
    -35
      dgl/StandaloneWindow.hpp
  3. +2
    -12
      dgl/Widget.hpp
  4. +3
    -4
      dgl/src/ImageWidgets.cpp
  5. +64
    -1
      dgl/src/NanoVG.cpp
  6. +48
    -112
      dgl/src/Widget.cpp
  7. +133
    -0
      dgl/src/WidgetPrivateData.hpp
  8. +44
    -56
      dgl/src/Window.cpp
  9. +2
    -0
      dgl/src/pugl/pugl_internal.h
  10. +3
    -0
      dgl/src/pugl/pugl_x11.c

+ 17
- 37
dgl/NanoVG.hpp View File

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


+ 15
- 35
dgl/StandaloneWindow.hpp View File

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


+ 2
- 12
dgl/Widget.hpp View File

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


+ 3
- 4
dgl/src/ImageWidgets.cpp View File

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


+ 64
- 1
dgl/src/NanoVG.cpp View File

@@ -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" {


+ 48
- 112
dgl/src/Widget.cpp View File

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

+ 133
- 0
dgl/src/WidgetPrivateData.hpp View File

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

+ 44
- 56
dgl/src/Window.cpp View File

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


+ 2
- 0
dgl/src/pugl/pugl_internal.h View File

@@ -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)


+ 3
- 0
dgl/src/pugl/pugl_x11.c View File

@@ -603,4 +603,7 @@ puglGetContext(PuglView* view)
}
#endif
return NULL;

// may be unused
(void)view;
}

Loading…
Cancel
Save