Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -38,7 +38,7 @@ public: | |||||
Constructor. | Constructor. | ||||
*/ | */ | ||||
// NOTE: the default value is not yet passed, so we catch where we use this | // NOTE: the default value is not yet passed, so we catch where we use this | ||||
Application(bool isStandalone /* = true */); | |||||
Application(bool isStandalone = true); | |||||
/** | /** | ||||
Destructor. | Destructor. | ||||
@@ -17,13 +17,14 @@ | |||||
#ifndef DGL_CAIRO_HPP_INCLUDED | #ifndef DGL_CAIRO_HPP_INCLUDED | ||||
#define DGL_CAIRO_HPP_INCLUDED | #define DGL_CAIRO_HPP_INCLUDED | ||||
#include "Base.hpp" | |||||
#include "SubWidget.hpp" | |||||
#include "TopLevelWidget.hpp" | |||||
#include <cairo/cairo.h> | #include <cairo/cairo.h> | ||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
/** | /** | ||||
Cairo Graphics context. | Cairo Graphics context. | ||||
@@ -33,7 +34,49 @@ struct CairoGraphicsContext : GraphicsContext | |||||
cairo_t* handle; | cairo_t* handle; | ||||
}; | }; | ||||
// ----------------------------------------------------------------------- | |||||
/** | |||||
Cairo SubWidget, handy class that takes graphics context during onDisplay and passes it in a new function. | |||||
*/ | |||||
class CairoSubWidget : public SubWidget | |||||
{ | |||||
public: | |||||
CairoSubWidget(Widget* widgetToGroupTo) | |||||
: SubWidget(widgetToGroupTo) {} | |||||
protected: | |||||
void onDisplay() override | |||||
{ | |||||
const CairoGraphicsContext& context((const CairoGraphicsContext&)getGraphicsContext()); | |||||
onCairoDisplay(context); | |||||
} | |||||
virtual void onCairoDisplay(const CairoGraphicsContext& context) = 0; | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoSubWidget); | |||||
}; | |||||
/** | |||||
Cairo TopLevelWidget, handy class that takes graphics context during onDisplay and passes it in a new function. | |||||
*/ | |||||
class CairoTopLevelWidget : public TopLevelWidget | |||||
{ | |||||
public: | |||||
CairoTopLevelWidget(Window& windowToMapTo) | |||||
: TopLevelWidget(windowToMapTo) {} | |||||
protected: | |||||
void onDisplay() override | |||||
{ | |||||
const CairoGraphicsContext& context((const CairoGraphicsContext&)getGraphicsContext()); | |||||
onCairoDisplay(context); | |||||
} | |||||
virtual void onCairoDisplay(const CairoGraphicsContext& context) = 0; | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoTopLevelWidget); | |||||
}; | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -17,7 +17,6 @@ | |||||
#ifndef DGL_STANDALONE_WINDOW_HPP_INCLUDED | #ifndef DGL_STANDALONE_WINDOW_HPP_INCLUDED | ||||
#define DGL_STANDALONE_WINDOW_HPP_INCLUDED | #define DGL_STANDALONE_WINDOW_HPP_INCLUDED | ||||
#include "Application.hpp" | |||||
#include "TopLevelWidget.hpp" | #include "TopLevelWidget.hpp" | ||||
#include "Window.hpp" | #include "Window.hpp" | ||||
@@ -25,33 +24,54 @@ START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
class StandaloneWindow : public Application, | |||||
public Window | |||||
class StandaloneWindow : public Window, | |||||
public TopLevelWidget | |||||
{ | { | ||||
public: | public: | ||||
/** | /** | ||||
Constructor. | Constructor. | ||||
*/ | */ | ||||
StandaloneWindow(); | |||||
StandaloneWindow(Application& app) | |||||
: Window(app), | |||||
TopLevelWidget((Window&)*this) {} | |||||
/** | /** | ||||
Show window and execute application. | |||||
Overloaded functions to ensure they apply to the Window class. | |||||
*/ | */ | ||||
void exec(); | |||||
bool isVisible() const noexcept { return Window::isVisible(); } | |||||
void setVisible(bool yesNo) { Window::setVisible(yesNo); } | |||||
void hide() { Window::hide(); } | |||||
void show() { Window::show(); } | |||||
uint getWidth() const noexcept { return Window::getWidth(); } | |||||
uint getHeight() const noexcept { return Window::getHeight(); } | |||||
const Size<uint> getSize() const noexcept { return Window::getSize(); } | |||||
private: | |||||
TopLevelWidget* fWidget; | |||||
/** | |||||
Overloaded functions to ensure size changes apply on both TopLevelWidget and Window classes. | |||||
*/ | |||||
void setWidth(uint width) | |||||
{ | |||||
TopLevelWidget::setWidth(width); | |||||
Window::setWidth(width); | |||||
} | |||||
/** @internal */ | |||||
void onReshape(uint width, uint height) override; | |||||
void setHeight(uint height) | |||||
{ | |||||
TopLevelWidget::setHeight(height); | |||||
Window::setHeight(height); | |||||
} | |||||
#if 0 | |||||
/** @internal */ | |||||
void _addWidget(TopLevelWidget* widget) override; | |||||
void setSize(uint width, uint height) | |||||
{ | |||||
TopLevelWidget::setSize(width, height); | |||||
Window::setSize(width, height); | |||||
} | |||||
/** @internal */ | |||||
void _removeWidget(TopLevelWidget* widget) override; | |||||
#endif | |||||
void setSize(const Size<uint>& size) | |||||
{ | |||||
TopLevelWidget::setSize(size); | |||||
Window::setSize(size); | |||||
} | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(StandaloneWindow) | ||||
}; | }; | ||||
@@ -52,18 +52,10 @@ public: | |||||
protected: | protected: | ||||
/** | /** | ||||
A function called before any draw operations begin (in the current event-loop cycle). | |||||
Can be used to setup any resources for needed drawing. | |||||
The default implementation simply paints the full Widget contents black. | |||||
A function called to draw the widget contents. | |||||
Reimplemented from Widget::onDisplay. | |||||
*/ | */ | ||||
virtual void onDisplayBefore(); | |||||
/** | |||||
A function called after all draw operations have ended (in the current event-loop cycle). | |||||
Can be used to clear any resources setup during onDisplayBefore(). | |||||
The default implementation does nothing. | |||||
*/ | |||||
virtual void onDisplayAfter(); | |||||
void onDisplay() override; | |||||
/** | /** | ||||
A function called when the widget is resized. | A function called when the widget is resized. | ||||
@@ -30,11 +30,11 @@ | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// class Application; | |||||
class Application; | |||||
// class NanoWidget; | // class NanoWidget; | ||||
// class Window; | // class Window; | ||||
// class StandaloneWindow; | // class StandaloneWindow; | ||||
// class SubWidget; | |||||
class SubWidget; | |||||
class TopLevelWidget; | class TopLevelWidget; | ||||
using namespace Events; | using namespace Events; | ||||
@@ -46,26 +46,31 @@ using namespace Events; | |||||
This is the base Widget class, from which all widgets are built. | This is the base Widget class, from which all widgets are built. | ||||
All widgets have a parent Window where they'll be drawn. | |||||
This parent is never changed during the widget lifetime. | |||||
All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget. | |||||
This parent is never changed during a widget's lifetime. | |||||
Widgets receive events in relative coordinates. | |||||
(0, 0) means its top-left position. | |||||
Widgets receive events in relative coordinates. (0, 0) means its top-left position. | |||||
Windows paint widgets in the order they are constructed. | |||||
Early widgets are drawn first, at the bottom, then newer ones on top. | |||||
Events are sent in the inverse order so that the top-most widget gets | |||||
The top-level widget will draw subwidgets in the order they are constructed. | |||||
Early subwidgets are drawn first, at the bottom, then newer ones on top. | |||||
Events are sent in the inverse order so that the top-most widgets get | |||||
a chance to catch the event and stop its propagation. | a chance to catch the event and stop its propagation. | ||||
All widget event callbacks do nothing by default. | |||||
All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses. | |||||
@note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead. | |||||
*/ | */ | ||||
class Widget | class Widget | ||||
{ | { | ||||
/** | /** | ||||
Constructor, reserved for DGL .. | |||||
use TopLevelWidget or SubWidget instead | |||||
Private constructor, reserved for SubWidget class. | |||||
*/ | |||||
explicit Widget(Widget* widgetToGroupTo); | |||||
/** | |||||
Private constructor, reserved for TopLevelWidget class. | |||||
*/ | */ | ||||
explicit Widget(TopLevelWidget& topLevelWidget); | |||||
explicit Widget(TopLevelWidget* topLevelWidget); | |||||
public: | public: | ||||
/** | /** | ||||
@@ -109,7 +114,7 @@ public: | |||||
/** | /** | ||||
Get size. | Get size. | ||||
*/ | */ | ||||
const Size<uint>& getSize() const noexcept; | |||||
const Size<uint> getSize() const noexcept; | |||||
/** | /** | ||||
Set width. | Set width. | ||||
@@ -131,17 +136,6 @@ public: | |||||
*/ | */ | ||||
void setSize(const Size<uint>& size) noexcept; | void setSize(const Size<uint>& size) noexcept; | ||||
/** | |||||
Get top-level widget, as passed in the constructor. | |||||
*/ | |||||
TopLevelWidget& getTopLevelWidget() const noexcept; | |||||
/** | |||||
Tell this widget's window to repaint itself. | |||||
FIXME better description, partial redraw | |||||
*/ | |||||
void repaint() noexcept; | |||||
/** | /** | ||||
Get the Id associated with this widget. | Get the Id associated with this widget. | ||||
@see setId | @see setId | ||||
@@ -154,9 +148,35 @@ public: | |||||
*/ | */ | ||||
void setId(uint id) noexcept; | void setId(uint id) noexcept; | ||||
/** | |||||
Get the application associated with this widget's window. | |||||
This is the same as calling `getTopLevelWidget()->getApp()`. | |||||
*/ | |||||
Application& getApp() const noexcept; | |||||
/** | |||||
Get the graphics context associated with this widget. | |||||
GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable, | |||||
for example GraphicsContext. | |||||
@see CairoSubWidget, CairoTopLevelWidget | |||||
*/ | |||||
const GraphicsContext& getGraphicsContext() const noexcept; | |||||
/** | |||||
Get top-level widget, as passed directly in the constructor | |||||
or going up the chain of group widgets until it finds the top-level widget. | |||||
*/ | |||||
TopLevelWidget* getTopLevelWidget() const noexcept; | |||||
/** | |||||
Tell this widget's window to repaint itself. | |||||
FIXME better description, partial redraw | |||||
*/ | |||||
void repaint() noexcept; | |||||
protected: | protected: | ||||
/** | /** | ||||
A function called to draw the view contents with OpenGL. | |||||
A function called to draw the widget contents. | |||||
*/ | */ | ||||
virtual void onDisplay() = 0; | virtual void onDisplay() = 0; | ||||
@@ -208,6 +228,7 @@ private: | |||||
// friend class NanoWidget; | // friend class NanoWidget; | ||||
// friend class Window; | // friend class Window; | ||||
// friend class StandaloneWindow; | // friend class StandaloneWindow; | ||||
friend class SubWidget; | |||||
friend class TopLevelWidget; | friend class TopLevelWidget; | ||||
// #ifdef DISTRHO_DEFINES_H_INCLUDED | // #ifdef DISTRHO_DEFINES_H_INCLUDED | ||||
// friend class DISTRHO_NAMESPACE::UI; | // friend class DISTRHO_NAMESPACE::UI; | ||||
@@ -22,6 +22,7 @@ | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
class Application; | class Application; | ||||
class TopLevelWidget; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -151,6 +152,11 @@ public: | |||||
const char* getTitle() const noexcept; | const char* getTitle() const noexcept; | ||||
void setTitle(const char* title); | void setTitle(const char* title); | ||||
/** | |||||
Get the application associated with this window. | |||||
*/ | |||||
Application& getApp() const noexcept; | |||||
/** | /** | ||||
Get the "native" window handle. | Get the "native" window handle. | ||||
Returned value depends on the platform: | Returned value depends on the platform: | ||||
@@ -161,10 +167,18 @@ public: | |||||
*/ | */ | ||||
uintptr_t getNativeWindowHandle() const noexcept; | uintptr_t getNativeWindowHandle() const noexcept; | ||||
protected: | |||||
/** | |||||
A function called when the window is resized. | |||||
If there is a top-level widget associated with this window, its size will be set right after this function. | |||||
*/ | |||||
virtual void onReshape(uint width, uint height); | |||||
private: | private: | ||||
struct PrivateData; | struct PrivateData; | ||||
PrivateData* const pData; | PrivateData* const pData; | ||||
friend class Application; | friend class Application; | ||||
friend class TopLevelWidget; | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window); | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window); | ||||
}; | }; | ||||
@@ -251,11 +265,6 @@ END_NAMESPACE_DGL | |||||
double getScaling() const noexcept; | double getScaling() const noexcept; | ||||
#if 0 | |||||
// should this be removed? | |||||
Application& getApp() const noexcept; | |||||
#endif | |||||
const GraphicsContext& getGraphicsContext() const noexcept; | const GraphicsContext& getGraphicsContext() const noexcept; | ||||
void addIdleCallback(IdleCallback* const callback); | void addIdleCallback(IdleCallback* const callback); | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -14,8 +14,8 @@ | |||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
*/ | */ | ||||
#include "../Geometry.hpp" | |||||
#include "../Cairo.hpp" | #include "../Cairo.hpp" | ||||
#include "WidgetPrivateData.hpp" | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
@@ -63,49 +63,28 @@ void Rectangle<T>::_draw(const bool outline) | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Possible template data types | |||||
template class Point<double>; | |||||
template class Point<float>; | |||||
template class Point<int>; | |||||
template class Point<uint>; | |||||
template class Point<short>; | |||||
template class Point<ushort>; | |||||
template class Size<double>; | |||||
template class Size<float>; | |||||
template class Size<int>; | |||||
template class Size<uint>; | |||||
template class Size<short>; | |||||
template class Size<ushort>; | |||||
template class Line<double>; | |||||
template class Line<float>; | |||||
template class Line<int>; | |||||
template class Line<uint>; | |||||
template class Line<short>; | |||||
template class Line<ushort>; | |||||
template class Circle<double>; | |||||
template class Circle<float>; | |||||
template class Circle<int>; | |||||
template class Circle<uint>; | |||||
template class Circle<short>; | |||||
template class Circle<ushort>; | |||||
template class Triangle<double>; | |||||
template class Triangle<float>; | |||||
template class Triangle<int>; | |||||
template class Triangle<uint>; | |||||
template class Triangle<short>; | |||||
template class Triangle<ushort>; | |||||
template class Rectangle<double>; | |||||
template class Rectangle<float>; | |||||
template class Rectangle<int>; | |||||
template class Rectangle<uint>; | |||||
template class Rectangle<short>; | |||||
template class Rectangle<ushort>; | |||||
void Widget::PrivateData::display(const uint width, | |||||
const uint height, | |||||
const double scaling, | |||||
const bool renderingSubWidget) | |||||
{ | |||||
if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) | |||||
return; | |||||
cairo_t* cr = static_cast<const CairoGraphicsContext&>(parent.getGraphicsContext()).cairo; | |||||
cairo_matrix_t matrix; | |||||
cairo_get_matrix(cr, &matrix); | |||||
cairo_translate(cr, absolutePos.getX(), absolutePos.getY()); | |||||
// TODO: scaling and cropping | |||||
// display widget | |||||
self->onDisplay(); | |||||
cairo_set_matrix(cr, &matrix); | |||||
displaySubWidgets(width, height, scaling); | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -14,8 +14,8 @@ | |||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
*/ | */ | ||||
#include "../Geometry.hpp" | |||||
#include "../OpenGL.hpp" | #include "../OpenGL.hpp" | ||||
#include "WidgetPrivateData.hpp" | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
@@ -108,49 +108,65 @@ void Rectangle<T>::_draw(const bool outline) | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Possible template data types | |||||
template class Point<double>; | |||||
template class Point<float>; | |||||
template class Point<int>; | |||||
template class Point<uint>; | |||||
template class Point<short>; | |||||
template class Point<ushort>; | |||||
template class Size<double>; | |||||
template class Size<float>; | |||||
template class Size<int>; | |||||
template class Size<uint>; | |||||
template class Size<short>; | |||||
template class Size<ushort>; | |||||
template class Line<double>; | |||||
template class Line<float>; | |||||
template class Line<int>; | |||||
template class Line<uint>; | |||||
template class Line<short>; | |||||
template class Line<ushort>; | |||||
template class Circle<double>; | |||||
template class Circle<float>; | |||||
template class Circle<int>; | |||||
template class Circle<uint>; | |||||
template class Circle<short>; | |||||
template class Circle<ushort>; | |||||
template class Triangle<double>; | |||||
template class Triangle<float>; | |||||
template class Triangle<int>; | |||||
template class Triangle<uint>; | |||||
template class Triangle<short>; | |||||
template class Triangle<ushort>; | |||||
template class Rectangle<double>; | |||||
template class Rectangle<float>; | |||||
template class Rectangle<int>; | |||||
template class Rectangle<uint>; | |||||
template class Rectangle<short>; | |||||
template class Rectangle<ushort>; | |||||
void Widget::PrivateData::display(const uint width, | |||||
const uint height, | |||||
const double scaling, | |||||
const bool renderingSubWidget) | |||||
{ | |||||
if (/*(skipDisplay && ! renderingSubWidget) ||*/ size.isInvalid() || ! 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, | |||||
-(height * scaling - height), | |||||
width * scaling, | |||||
height * scaling); | |||||
} | |||||
// else if (needsScaling) | |||||
// { | |||||
// // limit viewport to widget bounds | |||||
// glViewport(absolutePos.getX(), | |||||
// height - self->getHeight() - absolutePos.getY(), | |||||
// self->getWidth(), | |||||
// self->getHeight()); | |||||
// } | |||||
// else | |||||
// { | |||||
// // only set viewport pos | |||||
// glViewport(absolutePos.getX() * scaling, | |||||
// -std::round((height * scaling - height) + (absolutePos.getY() * scaling)), | |||||
// std::round(width * scaling), | |||||
// std::round(height * scaling)); | |||||
// | |||||
// // then cut the outer bounds | |||||
// glScissor(absolutePos.getX() * scaling, | |||||
// height - std::round((self->getHeight() + absolutePos.getY()) * scaling), | |||||
// std::round(self->getWidth() * scaling), | |||||
// std::round(self->getHeight() * scaling)); | |||||
// | |||||
// glEnable(GL_SCISSOR_TEST); | |||||
// needsDisableScissor = true; | |||||
// } | |||||
// display widget | |||||
self->onDisplay(); | |||||
// if (needsDisableScissor) | |||||
// { | |||||
// glDisable(GL_SCISSOR_TEST); | |||||
// needsDisableScissor = false; | |||||
// } | |||||
displaySubWidgets(width, height, scaling); | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -15,16 +15,15 @@ | |||||
*/ | */ | ||||
#include "../StandaloneWindow.hpp" | #include "../StandaloneWindow.hpp" | ||||
#include "WidgetPrivateData.hpp" | |||||
#include "../TopLevelWidget.hpp" | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
StandaloneWindow::StandaloneWindow() | |||||
: Application(true), | |||||
Window((Application&)*this), | |||||
fWidget(nullptr) {} | |||||
StandaloneWindow::StandaloneWindow(Application& app) | |||||
: Window(app), | |||||
TopLevelWidget(this) {} | |||||
void StandaloneWindow::exec() | void StandaloneWindow::exec() | ||||
{ | { | ||||
@@ -15,9 +15,15 @@ | |||||
*/ | */ | ||||
#include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
#include "../TopLevelWidget.hpp" | |||||
START_NAMESPACE_DGL | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
SubWidget::SubWidget(Widget* const widgetToGroupTo) | SubWidget::SubWidget(Widget* const widgetToGroupTo) | ||||
: pData(new PrivateData(this, widgetToGroupTo)) {} | |||||
: Widget(widgetToGroupTo), | |||||
pData(new PrivateData(this, widgetToGroupTo)) {} | |||||
SubWidget::~SubWidget() | SubWidget::~SubWidget() | ||||
{ | { | ||||
@@ -79,9 +85,14 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept | |||||
pData->absolutePos = pos; | pData->absolutePos = pos; | ||||
onPositionChanged(ev); | onPositionChanged(ev); | ||||
getTopLevelWidget().repaint(); | |||||
// repaint the whole thing | |||||
pData->parent->repaint(); | |||||
} | } | ||||
void SubWidget::onPositionChanged(const PositionChangedEvent&) | void SubWidget::onPositionChanged(const PositionChangedEvent&) | ||||
{ | { | ||||
} | } | ||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL |
@@ -18,31 +18,25 @@ | |||||
#define DGL_SUBWIDGET_PRIVATE_DATA_HPP_INCLUDED | #define DGL_SUBWIDGET_PRIVATE_DATA_HPP_INCLUDED | ||||
#include "../SubWidget.hpp" | #include "../SubWidget.hpp" | ||||
#include "../WidgetPrivateData.hpp" | |||||
#include <vector> | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
struct SubWidget::PrivateData { | struct SubWidget::PrivateData { | ||||
SubWidget* const self; | SubWidget* const self; | ||||
Widget* const groupWidget; | |||||
Widget* const parent; | |||||
Point<int> absolutePos; | Point<int> absolutePos; | ||||
PrivateData(SubWidget* const s, Widget* const g) | |||||
PrivateData(SubWidget* const s, Widget* const p) | |||||
: self(s), | : self(s), | ||||
groupWidget(g), | |||||
absolutePos() | |||||
{ | |||||
groupWidget->pData->subWidgets.push_back(self); | |||||
} | |||||
parent(p), | |||||
absolutePos() {} | |||||
DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | |||||
}; | }; | ||||
// ----------------------------------------------------------------------- | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
@@ -15,14 +15,14 @@ | |||||
*/ | */ | ||||
#include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
#include "pugl.hpp" | |||||
// #include "pugl.hpp" | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | ||||
: Widget(*this), | |||||
: Widget(this), | |||||
pData(new PrivateData(this, windowToMapTo)) {} | pData(new PrivateData(this, windowToMapTo)) {} | ||||
TopLevelWidget::~TopLevelWidget() | TopLevelWidget::~TopLevelWidget() | ||||
@@ -30,16 +30,14 @@ TopLevelWidget::~TopLevelWidget() | |||||
delete pData; | delete pData; | ||||
} | } | ||||
void TopLevelWidget::onDisplayBefore() | |||||
{ | |||||
} | |||||
void TopLevelWidget::onDisplayAfter() | |||||
void TopLevelWidget::onDisplay() | |||||
{ | { | ||||
pData->display(); | |||||
} | } | ||||
void TopLevelWidget::onResize(const ResizeEvent& ev) | void TopLevelWidget::onResize(const ResizeEvent& ev) | ||||
{ | { | ||||
pData->resize(ev.size.getWidth(), ev.size.getHeight()); | |||||
Widget::onResize(ev); | Widget::onResize(ev); | ||||
} | } | ||||
@@ -15,16 +15,17 @@ | |||||
*/ | */ | ||||
#include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
#include "../Window.hpp" | |||||
// #include "pugl.hpp" | |||||
#include "WidgetPrivateData.hpp" | |||||
#include "WindowPrivateData.hpp" | |||||
#include "pugl.hpp" | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
#define FOR_EACH_WIDGET(it) \ | #define FOR_EACH_WIDGET(it) \ | ||||
for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it) | |||||
for (std::list<Widget*>::iterator it = widgets.begin(); it != widgets.end(); ++it) | |||||
#define FOR_EACH_WIDGET_INV(rit) \ | #define FOR_EACH_WIDGET_INV(rit) \ | ||||
for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit) | |||||
for (std::list<Widget*>::reverse_iterator rit = widgets.rbegin(); rit != widgets.rend(); ++rit) | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -35,17 +36,20 @@ TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) | |||||
void TopLevelWidget::PrivateData::display() | void TopLevelWidget::PrivateData::display() | ||||
{ | { | ||||
puglFallbackOnDisplay(window.pData->view); | |||||
if (widgets.size() == 0) | if (widgets.size() == 0) | ||||
return; | return; | ||||
const Size<uint> size(window.getSize()); | const Size<uint> size(window.getSize()); | ||||
// const int width = rect.width; | |||||
// const int height = rect.height; | |||||
const uint width = size.getWidth(); | |||||
const uint height = size.getHeight(); | |||||
const double scaling = window.pData->autoScaling; | |||||
FOR_EACH_WIDGET(it) | FOR_EACH_WIDGET(it) | ||||
{ | { | ||||
Widget* const widget(*it); | Widget* const widget(*it); | ||||
widget->pData->display(width, height, fAutoScaling, false); | |||||
widget->pData->display(width, height, scaling, false); | |||||
} | } | ||||
} | } | ||||
@@ -53,14 +57,14 @@ void TopLevelWidget::PrivateData::resize(const uint width, const uint height) | |||||
{ | { | ||||
if (widgets.size() == 0) | if (widgets.size() == 0) | ||||
return; | return; | ||||
/* | |||||
FOR_EACH_WIDGET(it) | FOR_EACH_WIDGET(it) | ||||
{ | { | ||||
Widget* const widget(*it); | Widget* const widget(*it); | ||||
if (widget->pData->needsFullViewport) | if (widget->pData->needsFullViewport) | ||||
widget->setSize(width, height); | widget->setSize(width, height); | ||||
} | |||||
}*/ | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -21,8 +21,11 @@ START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Widget | // Widget | ||||
Widget::Widget(TopLevelWidget& tlw) | |||||
: pData(new PrivateData(this, tlw)) {} | |||||
Widget::Widget(Widget* const widgetToGroupTo) | |||||
: pData(new PrivateData(this, widgetToGroupTo)) {} | |||||
Widget::Widget(TopLevelWidget* const topLevelWidget) | |||||
: pData(new PrivateData(this, topLevelWidget)) {} | |||||
Widget::~Widget() | Widget::~Widget() | ||||
{ | { | ||||
@@ -40,7 +43,7 @@ void Widget::setVisible(bool yesNo) | |||||
return; | return; | ||||
pData->visible = yesNo; | pData->visible = yesNo; | ||||
pData->topLevelWidget.repaint(); | |||||
repaint(); | |||||
} | } | ||||
void Widget::show() | void Widget::show() | ||||
@@ -63,7 +66,7 @@ uint Widget::getHeight() const noexcept | |||||
return pData->size.getHeight(); | return pData->size.getHeight(); | ||||
} | } | ||||
const Size<uint>& Widget::getSize() const noexcept | |||||
const Size<uint> Widget::getSize() const noexcept | |||||
{ | { | ||||
return pData->size; | return pData->size; | ||||
} | } | ||||
@@ -80,7 +83,7 @@ void Widget::setWidth(uint width) noexcept | |||||
pData->size.setWidth(width); | pData->size.setWidth(width); | ||||
onResize(ev); | onResize(ev); | ||||
pData->topLevelWidget.repaint(); | |||||
pData->repaint(); | |||||
} | } | ||||
void Widget::setHeight(uint height) noexcept | void Widget::setHeight(uint height) noexcept | ||||
@@ -95,7 +98,7 @@ void Widget::setHeight(uint height) noexcept | |||||
pData->size.setHeight(height); | pData->size.setHeight(height); | ||||
onResize(ev); | onResize(ev); | ||||
pData->topLevelWidget.repaint(); | |||||
pData->repaint(); | |||||
} | } | ||||
void Widget::setSize(uint width, uint height) noexcept | void Widget::setSize(uint width, uint height) noexcept | ||||
@@ -115,17 +118,15 @@ void Widget::setSize(const Size<uint>& size) noexcept | |||||
pData->size = size; | pData->size = size; | ||||
onResize(ev); | onResize(ev); | ||||
pData->topLevelWidget.repaint(); | |||||
pData->repaint(); | |||||
} | } | ||||
#if 0 | |||||
Application& Widget::getParentApp() const noexcept | |||||
Application& Widget::getApp() const noexcept | |||||
{ | { | ||||
return pData->parent.getApp(); | |||||
return pData->topLevelWidget->getApp(); | |||||
} | } | ||||
#endif | |||||
TopLevelWidget& Widget::getTopLevelWidget() const noexcept | |||||
TopLevelWidget* Widget::getTopLevelWidget() const noexcept | |||||
{ | { | ||||
return pData->topLevelWidget; | return pData->topLevelWidget; | ||||
} | } | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -15,6 +15,7 @@ | |||||
*/ | */ | ||||
#include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
#include "../TopLevelWidget.hpp" | |||||
#ifdef DGL_CAIRO | #ifdef DGL_CAIRO | ||||
# include "../Cairo.hpp" | # include "../Cairo.hpp" | ||||
@@ -27,79 +28,67 @@ START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
void Widget::PrivateData::display(const uint width, | |||||
const uint height, | |||||
const double scaling, | |||||
const bool renderingSubWidget) | |||||
Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) | |||||
: self(s), | |||||
topLevelWidget(tlw), | |||||
groupWidget(nullptr), | |||||
id(0), | |||||
needsScaling(false), | |||||
visible(true), | |||||
size(0, 0), | |||||
subWidgets() | |||||
{ | { | ||||
if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) | |||||
return; | |||||
} | |||||
#ifdef DGL_OPENGL | |||||
bool needsDisableScissor = false; | |||||
Widget::PrivateData::PrivateData(Widget* const s, Widget* const g) | |||||
: self(s), | |||||
topLevelWidget(findTopLevelWidget(g)), | |||||
groupWidget(g), | |||||
id(0), | |||||
needsScaling(false), | |||||
visible(true), | |||||
size(0, 0), | |||||
subWidgets() | |||||
{ | |||||
groupWidget->pData->subWidgets.push_back(self); | |||||
} | |||||
// reset color | |||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||||
Widget::PrivateData::~PrivateData() | |||||
{ | |||||
if (groupWidget != nullptr) | |||||
groupWidget->pData->subWidgets.remove(self); | |||||
if (needsFullViewport || (absolutePos.isZero() && size == Size<uint>(width, height))) | |||||
{ | |||||
// full viewport size | |||||
glViewport(0, | |||||
-(height * scaling - height), | |||||
width * scaling, | |||||
height * scaling); | |||||
} | |||||
else if (needsScaling) | |||||
{ | |||||
// limit viewport to widget bounds | |||||
glViewport(absolutePos.getX(), | |||||
height - self->getHeight() - absolutePos.getY(), | |||||
self->getWidth(), | |||||
self->getHeight()); | |||||
} | |||||
else | |||||
{ | |||||
// only set viewport pos | |||||
glViewport(absolutePos.getX() * scaling, | |||||
-std::round((height * scaling - height) + (absolutePos.getY() * scaling)), | |||||
std::round(width * scaling), | |||||
std::round(height * scaling)); | |||||
subWidgets.clear(); | |||||
} | |||||
// then cut the outer bounds | |||||
glScissor(absolutePos.getX() * scaling, | |||||
height - std::round((self->getHeight() + absolutePos.getY()) * scaling), | |||||
std::round(self->getWidth() * scaling), | |||||
std::round(self->getHeight() * scaling)); | |||||
void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double scaling) | |||||
{ | |||||
for (std::list<Widget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||||
{ | |||||
Widget* const widget(*it); | |||||
DISTRHO_SAFE_ASSERT_CONTINUE(widget->pData != this); | |||||
glEnable(GL_SCISSOR_TEST); | |||||
needsDisableScissor = true; | |||||
widget->pData->display(width, height, scaling, true); | |||||
} | } | ||||
#endif | |||||
#ifdef DGL_CAIRO | |||||
cairo_t* cr = static_cast<const CairoGraphicsContext&>(parent.getGraphicsContext()).cairo; | |||||
cairo_matrix_t matrix; | |||||
cairo_get_matrix(cr, &matrix); | |||||
cairo_translate(cr, absolutePos.getX(), absolutePos.getY()); | |||||
// TODO: scaling and cropping | |||||
#endif | |||||
// display widget | |||||
self->onDisplay(); | |||||
} | |||||
#ifdef DGL_CAIRO | |||||
cairo_set_matrix(cr, &matrix); | |||||
#endif | |||||
void Widget::PrivateData::repaint() | |||||
{ | |||||
if (groupWidget != nullptr) | |||||
groupWidget->repaint(); | |||||
else if (topLevelWidget != nullptr) | |||||
topLevelWidget->repaint(); | |||||
} | |||||
#ifdef DGL_OPENGL | |||||
if (needsDisableScissor) | |||||
{ | |||||
glDisable(GL_SCISSOR_TEST); | |||||
needsDisableScissor = false; | |||||
} | |||||
#endif | |||||
// ----------------------------------------------------------------------- | |||||
displaySubWidgets(width, height, scaling); | |||||
TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) | |||||
{ | |||||
if (w->pData->topLevelWidget != nullptr) | |||||
return w->pData->topLevelWidget; | |||||
if (w->pData->groupWidget != nullptr) | |||||
return findTopLevelWidget(w->pData->groupWidget); | |||||
return nullptr; | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
@@ -17,61 +17,41 @@ | |||||
#ifndef DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | #ifndef DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | ||||
#define DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | #define DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | ||||
#include "../TopLevelWidget.hpp" | |||||
#include "../Window.hpp" | |||||
#include "../Widget.hpp" | |||||
#include <vector> | |||||
#include <list> | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
struct Widget::PrivateData { | struct Widget::PrivateData { | ||||
Widget* const self; | Widget* const self; | ||||
Size<uint> size; | |||||
std::vector<Widget*> subWidgets; | |||||
TopLevelWidget& topLevelWidget; | |||||
TopLevelWidget* const topLevelWidget; | |||||
Widget* const groupWidget; | |||||
uint id; | uint id; | ||||
bool needsScaling; | bool needsScaling; | ||||
bool visible; | bool visible; | ||||
Size<uint> size; | |||||
std::list<Widget*> subWidgets; | |||||
PrivateData(Widget* const s, TopLevelWidget& tlw) | |||||
: self(s), | |||||
size(0, 0), | |||||
subWidgets(), | |||||
topLevelWidget(tlw), | |||||
id(0), | |||||
needsScaling(false), | |||||
visible(true) | |||||
{ | |||||
// parent._addWidget(self); | |||||
} | |||||
~PrivateData() | |||||
{ | |||||
// parent._removeWidget(self); | |||||
subWidgets.clear(); | |||||
} | |||||
PrivateData(Widget* const s, TopLevelWidget* const tlw); | |||||
PrivateData(Widget* const s, Widget* const g); | |||||
~PrivateData(); | |||||
// display function is different depending on build type | |||||
// NOTE display function is different depending on build type | |||||
void display(const uint width, const uint height, const double scaling, const bool renderingSubWidget); | void display(const uint width, const uint height, const double scaling, const bool renderingSubWidget); | ||||
void displaySubWidgets(const uint width, const uint height, const double scaling) | |||||
{ | |||||
for (std::vector<Widget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||||
{ | |||||
Widget* const widget(*it); | |||||
DISTRHO_SAFE_ASSERT_CONTINUE(widget->pData != this); | |||||
void displaySubWidgets(const uint width, const uint height, const double scaling); | |||||
void repaint(); | |||||
widget->pData->display(width, height, scaling, true); | |||||
} | |||||
} | |||||
static TopLevelWidget* findTopLevelWidget(Widget* const w); | |||||
DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | |||||
}; | }; | ||||
// ----------------------------------------------------------------------- | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
@@ -27,7 +27,7 @@ START_NAMESPACE_DGL | |||||
// : pData(new PrivateData(transientParentWindow.pData->fAppData, this, transientParentWindow)) {} | // : pData(new PrivateData(transientParentWindow.pData->fAppData, this, transientParentWindow)) {} | ||||
Window::Window(Application& app) | Window::Window(Application& app) | ||||
: pData(new PrivateData(app.pData, this)) {} | |||||
: pData(new PrivateData(app, this)) {} | |||||
Window::Window(Application& app, | Window::Window(Application& app, | ||||
const uintptr_t parentWindowHandle, | const uintptr_t parentWindowHandle, | ||||
@@ -35,7 +35,7 @@ Window::Window(Application& app, | |||||
const uint height, | const uint height, | ||||
const double scaling, | const double scaling, | ||||
const bool resizable) | const bool resizable) | ||||
: pData(new PrivateData(app.pData, this, parentWindowHandle, width, height, scaling, resizable)) {} | |||||
: pData(new PrivateData(app, this, parentWindowHandle, width, height, scaling, resizable)) {} | |||||
Window::~Window() | Window::~Window() | ||||
{ | { | ||||
@@ -123,11 +123,21 @@ void Window::setTitle(const char* const title) | |||||
puglSetWindowTitle(pData->view, title); | puglSetWindowTitle(pData->view, title); | ||||
} | } | ||||
Application& Window::getApp() const noexcept | |||||
{ | |||||
return pData->app; | |||||
} | |||||
uintptr_t Window::getNativeWindowHandle() const noexcept | uintptr_t Window::getNativeWindowHandle() const noexcept | ||||
{ | { | ||||
return puglGetNativeWindow(pData->view); | return puglGetNativeWindow(pData->view); | ||||
} | } | ||||
void Window::onReshape(const uint width, const uint height) | |||||
{ | |||||
puglFallbackOnResize(pData->view); | |||||
} | |||||
#if 0 | #if 0 | ||||
#if 0 | #if 0 | ||||
void Window::exec(bool lockWait) | void Window::exec(bool lockWait) | ||||
@@ -40,8 +40,9 @@ START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s) | |||||
: appData(a), | |||||
Window::PrivateData::PrivateData(Application& a, Window* const s) | |||||
: app(a), | |||||
appData(a.pData), | |||||
self(s), | self(s), | ||||
view(puglNewView(appData->world)), | view(puglNewView(appData->world)), | ||||
topLevelWidget(nullptr), | topLevelWidget(nullptr), | ||||
@@ -52,31 +53,37 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | ||||
} | } | ||||
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow) | |||||
: appData(a), | |||||
Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transientWindow) | |||||
: app(a), | |||||
appData(a.pData), | |||||
self(s), | self(s), | ||||
view(puglNewView(appData->world)), | view(puglNewView(appData->world)), | ||||
topLevelWidget(nullptr), | topLevelWidget(nullptr), | ||||
isClosed(true), | isClosed(true), | ||||
isVisible(false), | isVisible(false), | ||||
isEmbed(false) | |||||
isEmbed(false), | |||||
scaling(1.0), | |||||
autoScaling(1.0) | |||||
{ | { | ||||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | ||||
puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | ||||
} | } | ||||
Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | |||||
Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
const uintptr_t parentWindowHandle, | const uintptr_t parentWindowHandle, | ||||
const uint width, const uint height, | const uint width, const uint height, | ||||
const double scaling, const bool resizable) | |||||
: appData(a), | |||||
const double scale, const bool resizable) | |||||
: app(a), | |||||
appData(a.pData), | |||||
self(s), | self(s), | ||||
view(puglNewView(appData->world)), | view(puglNewView(appData->world)), | ||||
topLevelWidget(nullptr), | topLevelWidget(nullptr), | ||||
isClosed(parentWindowHandle == 0), | isClosed(parentWindowHandle == 0), | ||||
isVisible(parentWindowHandle != 0), | isVisible(parentWindowHandle != 0), | ||||
isEmbed(parentWindowHandle != 0) | |||||
isEmbed(parentWindowHandle != 0), | |||||
scaling(scale), | |||||
autoScaling(1.0) | |||||
{ | { | ||||
init(width, height, resizable); | init(width, height, resizable); | ||||
@@ -257,9 +264,7 @@ void Window::PrivateData::onPuglDisplay() | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
{ | { | ||||
topLevelWidget->onDisplayBefore(); | |||||
topLevelWidget->onDisplay(); | topLevelWidget->onDisplay(); | ||||
topLevelWidget->onDisplayAfter(); | |||||
} | } | ||||
else | else | ||||
#endif | #endif | ||||
@@ -274,12 +279,12 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||||
DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); | DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); | ||||
self->onReshape(width, height); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
topLevelWidget->setSize(width, height); | topLevelWidget->setSize(width, height); | ||||
else | |||||
#endif | #endif | ||||
puglFallbackOnResize(view); | |||||
} | } | ||||
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | ||||
@@ -29,13 +29,13 @@ class TopLevelWidget; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
struct Window::PrivateData : IdleCallback { | struct Window::PrivateData : IdleCallback { | ||||
/** Handy typedef for ... */ | |||||
typedef Application::PrivateData AppData; | |||||
/* Reference to the DGL Application class this (private data) window associates with. */ | |||||
Application& app; | |||||
/** Direct access to DGL Application private data where we registers ourselves in. */ | |||||
AppData* const appData; | |||||
/** Direct access to the DGL Application private data where we registers ourselves in. */ | |||||
Application::PrivateData* const appData; | |||||
/** Pointer to the DGL Window class that this private data belongs to. */ | |||||
/** Pointer to the the DGL Window class that this private data belongs to. */ | |||||
Window* const self; | Window* const self; | ||||
/** Pugl view instance. */ | /** Pugl view instance. */ | ||||
@@ -57,14 +57,20 @@ struct Window::PrivateData : IdleCallback { | |||||
/** Whether this Window is embed into another (usually not DGL-controlled) Window. */ | /** Whether this Window is embed into another (usually not DGL-controlled) Window. */ | ||||
const bool isEmbed; | const bool isEmbed; | ||||
/** Scaling to report to widgets on request, purely informational. */ | |||||
double scaling; | |||||
/** Automatic scaling to apply on widgets, implemented internally. */ | |||||
double autoScaling; | |||||
/** Constructor for a regular, standalone window. */ | /** Constructor for a regular, standalone window. */ | ||||
PrivateData(AppData* appData, Window* self); | |||||
PrivateData(Application& app, Window* self); | |||||
/** Constructor for a regular, standalone window with a transient parent. */ | /** Constructor for a regular, standalone window with a transient parent. */ | ||||
PrivateData(AppData* appData, Window* self, Window& transientWindow); | |||||
PrivateData(Application& app, Window* self, Window& transientWindow); | |||||
/** Constructor for an embed Window, with a few extra hints from the host side. */ | /** Constructor for an embed Window, with a few extra hints from the host side. */ | ||||
PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, | |||||
PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, | |||||
uint width, uint height, double scaling, bool resizable); | uint width, uint height, double scaling, bool resizable); | ||||
/** Destructor. */ | /** Destructor. */ | ||||
@@ -0,0 +1,198 @@ | |||||
/* | |||||
* DISTRHO Plugin Framework (DPF) | |||||
* Copyright (C) 2012-2021 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_OPENGL | |||||
#error OpenGL build required for Demo | |||||
#endif | |||||
#include "tests.hpp" | |||||
// #define DPF_TEST_POINT_CPP | |||||
#include "dgl/src/pugl.cpp" | |||||
// #include "dgl/src/SubWidget.cpp" | |||||
#include "dgl/src/Application.cpp" | |||||
#include "dgl/src/ApplicationPrivateData.cpp" | |||||
#include "dgl/src/Geometry.cpp" | |||||
#include "dgl/src/OpenGL.cpp" | |||||
#include "dgl/src/SubWidget.cpp" | |||||
#include "dgl/src/TopLevelWidget.cpp" | |||||
#include "dgl/src/TopLevelWidgetPrivateData.cpp" | |||||
#include "dgl/src/Widget.cpp" | |||||
#include "dgl/src/WidgetPrivateData.cpp" | |||||
#include "dgl/src/Window.cpp" | |||||
#include "dgl/src/WindowPrivateData.cpp" | |||||
#include "dgl/StandaloneWindow.hpp" | |||||
#include "widgets/ExampleColorWidget.hpp" | |||||
START_NAMESPACE_DGL | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
// ------------------------------------------------------ | |||||
// Left side tab-like widget | |||||
class LeftSideWidget : public SubWidget | |||||
{ | |||||
public: | |||||
static const int kPageCount = 5; | |||||
class Callback | |||||
{ | |||||
public: | |||||
virtual ~Callback() {} | |||||
virtual void curPageChanged(int curPage) = 0; | |||||
}; | |||||
LeftSideWidget(Widget* parent, Callback* const cb) | |||||
: SubWidget(parent), | |||||
callback(cb), | |||||
curPage(0), | |||||
curHover(-1) | |||||
{ | |||||
// for text | |||||
// font = nvg.createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"); | |||||
// using namespace DemoArtwork; | |||||
// img1.loadFromMemory(ico1Data, ico1Width, ico1Height, GL_BGR); | |||||
// img2.loadFromMemory(ico2Data, ico2Width, ico2Height, GL_BGR); | |||||
// img3.loadFromMemory(ico3Data, ico3Width, ico2Height, GL_BGR); | |||||
// img4.loadFromMemory(ico4Data, ico4Width, ico4Height, GL_BGR); | |||||
// img5.loadFromMemory(ico5Data, ico5Width, ico5Height, GL_BGR); | |||||
} | |||||
private: | |||||
Callback* const callback; | |||||
int curPage, curHover; | |||||
// Rectangle<int> bgIcon; | |||||
// Line<int> lineSep; | |||||
// Image img1, img2, img3, img4, img5; | |||||
// for text | |||||
// NanoVG nvg; | |||||
// NanoVG::FontId font; | |||||
}; | |||||
// ------------------------------------------------------ | |||||
// Our Demo Window | |||||
class DemoWindow : public StandaloneWindow, | |||||
public LeftSideWidget::Callback | |||||
{ | |||||
static const int kSidebarWidth = 81; | |||||
ExampleColorWidget wColor; | |||||
Widget* curWidget; | |||||
public: | |||||
DemoWindow(Application& app) | |||||
: StandaloneWindow(app), | |||||
wColor(this), | |||||
curWidget(nullptr) | |||||
{ | |||||
wColor.hide(); | |||||
// wImages.hide(); | |||||
// wRects.hide(); | |||||
// wShapes.hide(); | |||||
// wText.hide(); | |||||
// //wPerf.hide(); | |||||
wColor.setAbsoluteX(kSidebarWidth); | |||||
// wImages.setAbsoluteX(kSidebarWidth); | |||||
// wRects.setAbsoluteX(kSidebarWidth); | |||||
// wShapes.setAbsoluteX(kSidebarWidth); | |||||
// wText.setAbsoluteX(kSidebarWidth); | |||||
// wLeft.setAbsolutePos(2, 2); | |||||
// wPerf.setAbsoluteY(5); | |||||
setSize(600, 500); | |||||
setTitle("DGL Demo"); | |||||
curPageChanged(0); | |||||
} | |||||
protected: | |||||
void curPageChanged(int curPage) override | |||||
{ | |||||
if (curWidget != nullptr) | |||||
{ | |||||
curWidget->hide(); | |||||
curWidget = nullptr; | |||||
} | |||||
switch (curPage) | |||||
{ | |||||
case 0: | |||||
curWidget = &wColor; | |||||
break; | |||||
// case 1: | |||||
// curWidget = &wImages; | |||||
// break; | |||||
// case 2: | |||||
// curWidget = &wRects; | |||||
// break; | |||||
// case 3: | |||||
// curWidget = &wShapes; | |||||
// break; | |||||
// case 4: | |||||
// curWidget = &wText; | |||||
// break; | |||||
} | |||||
if (curWidget != nullptr) | |||||
curWidget->show(); | |||||
} | |||||
void onReshape(uint width, uint height) override | |||||
{ | |||||
StandaloneWindow::onReshape(width, height); | |||||
if (width < kSidebarWidth) | |||||
return; | |||||
Size<uint> size(width-kSidebarWidth, height); | |||||
wColor.setSize(size); | |||||
// wImages.setSize(size); | |||||
// wRects.setSize(size); | |||||
// wShapes.setSize(size); | |||||
// wText.setSize(size); | |||||
// wLeft.setSize(kSidebarWidth-4, height-4); | |||||
// //wRezHandle.setAbsoluteX(width-wRezHandle.getWidth()); | |||||
// //wRezHandle.setAbsoluteY(height-wRezHandle.getHeight()); | |||||
// | |||||
// wPerf.setAbsoluteX(width-wPerf.getWidth()-5); | |||||
} | |||||
}; | |||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
END_NAMESPACE_DGL | |||||
int main() | |||||
{ | |||||
USE_NAMESPACE_DGL; | |||||
Application app; | |||||
DemoWindow win(app); | |||||
win.show(); | |||||
app.exec(); | |||||
return 0; | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -25,6 +25,7 @@ ifeq ($(HAVE_CAIRO),true) | |||||
WTESTS = Window.cairo | WTESTS = Window.cairo | ||||
endif | endif | ||||
ifeq ($(HAVE_OPENGL),true) | ifeq ($(HAVE_OPENGL),true) | ||||
TESTS += Demo | |||||
WTESTS = Window.opengl | WTESTS = Window.opengl | ||||
endif | endif | ||||
ifeq ($(HAVE_VULKAN),true) | ifeq ($(HAVE_VULKAN),true) | ||||
@@ -87,12 +88,17 @@ clean: | |||||
@echo "Compiling $< (Cairo)" | @echo "Compiling $< (Cairo)" | ||||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@ | $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(CAIRO_FLAGS) -DDGL_CAIRO -c -o $@ | ||||
../build/tests/Demo.cpp.o: Demo.cpp | |||||
-@mkdir -p ../build/tests | |||||
@echo "Compiling $< (OpenGL)" | |||||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ | |||||
../build/tests/%.cpp.opengl.o: %.cpp | ../build/tests/%.cpp.opengl.o: %.cpp | ||||
-@mkdir -p ../build/tests | -@mkdir -p ../build/tests | ||||
@echo "Compiling $< (OpenGL)" | @echo "Compiling $< (OpenGL)" | ||||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ | $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ | ||||
../build/tests/%.cpp.vulkan.o: Window.cpp | |||||
../build/tests/%.cpp.vulkan.o: %.cpp | |||||
-@mkdir -p ../build/tests | -@mkdir -p ../build/tests | ||||
@echo "Compiling $< (Vulkan)" | @echo "Compiling $< (Vulkan)" | ||||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@ | $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@ | ||||
@@ -108,6 +114,10 @@ clean: | |||||
@echo "Linking $*" | @echo "Linking $*" | ||||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@ | $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@ | ||||
../build/tests/Demo: ../build/tests/Demo.cpp.o | |||||
@echo "Linking Demo" | |||||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||||
../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o | ../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o | ||||
@echo "Linking $*" | @echo "Linking $*" | ||||
$(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | ||||
@@ -0,0 +1,134 @@ | |||||
/* | |||||
* 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 EXAMPLE_COLOR_WIDGET_HPP_INCLUDED | |||||
#define EXAMPLE_COLOR_WIDGET_HPP_INCLUDED | |||||
// ------------------------------------------------------ | |||||
// DGL Stuff | |||||
#include "../../dgl/SubWidget.hpp" | |||||
// #include "Window.hpp" | |||||
START_NAMESPACE_DGL | |||||
// ------------------------------------------------------ | |||||
// our widget | |||||
class ExampleColorWidget : public SubWidget, | |||||
public IdleCallback | |||||
{ | |||||
public: | |||||
ExampleColorWidget(TopLevelWidget* const topWidget) | |||||
: SubWidget(topWidget), | |||||
cur('r'), | |||||
reverse(false), | |||||
r(0), g(0), b(0) | |||||
{ | |||||
setSize(300, 300); | |||||
// groupWidget->getApp().addIdleCallback(this); | |||||
} | |||||
protected: | |||||
void idleCallback() noexcept override | |||||
{ | |||||
switch (cur) | |||||
{ | |||||
case 'r': | |||||
if (reverse) | |||||
{ | |||||
if (--r == 0) | |||||
cur = 'g'; | |||||
} | |||||
else | |||||
{ | |||||
if (++r == 100) | |||||
cur = 'g'; | |||||
} | |||||
break; | |||||
case 'g': | |||||
if (reverse) | |||||
{ | |||||
if (--g == 0) | |||||
cur = 'b'; | |||||
} | |||||
else | |||||
{ | |||||
if (++g == 100) | |||||
cur = 'b'; | |||||
} | |||||
break; | |||||
case 'b': | |||||
if (reverse) | |||||
{ | |||||
if (--b == 0) | |||||
{ | |||||
cur = 'r'; | |||||
reverse = false; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (++b == 100) | |||||
{ | |||||
cur = 'r'; | |||||
reverse = true; | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
repaint(); | |||||
} | |||||
void onDisplay() override | |||||
{ | |||||
// paint bg color (in full size) | |||||
glColor3b(r, g, b); | |||||
bgFull.draw(); | |||||
// paint inverted color (in 2/3 size) | |||||
glColor3b(100-r, 100-g, 100-b); | |||||
bgSmall.draw(); | |||||
} | |||||
void onResize(const ResizeEvent& ev) override | |||||
{ | |||||
const uint width = ev.size.getWidth(); | |||||
const uint height = ev.size.getHeight(); | |||||
// full bg | |||||
bgFull = Rectangle<uint>(0, 0, width, height); | |||||
// small bg, centered 2/3 size | |||||
bgSmall = Rectangle<uint>(width/6, height/6, width*2/3, height*2/3); | |||||
} | |||||
char cur; | |||||
bool reverse; | |||||
int r, g, b; | |||||
Rectangle<uint> bgFull, bgSmall; | |||||
}; | |||||
// ------------------------------------------------------ | |||||
END_NAMESPACE_DGL | |||||
#endif // EXAMPLE_COLOR_WIDGET_HPP_INCLUDED |