Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -38,7 +38,7 @@ public: | |||
Constructor. | |||
*/ | |||
// NOTE: the default value is not yet passed, so we catch where we use this | |||
Application(bool isStandalone /* = true */); | |||
Application(bool isStandalone = true); | |||
/** | |||
Destructor. | |||
@@ -17,13 +17,14 @@ | |||
#ifndef DGL_CAIRO_HPP_INCLUDED | |||
#define DGL_CAIRO_HPP_INCLUDED | |||
#include "Base.hpp" | |||
#include "SubWidget.hpp" | |||
#include "TopLevelWidget.hpp" | |||
#include <cairo/cairo.h> | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
/** | |||
Cairo Graphics context. | |||
@@ -33,7 +34,49 @@ struct CairoGraphicsContext : GraphicsContext | |||
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 | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -17,7 +17,6 @@ | |||
#ifndef DGL_STANDALONE_WINDOW_HPP_INCLUDED | |||
#define DGL_STANDALONE_WINDOW_HPP_INCLUDED | |||
#include "Application.hpp" | |||
#include "TopLevelWidget.hpp" | |||
#include "Window.hpp" | |||
@@ -25,33 +24,54 @@ START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
class StandaloneWindow : public Application, | |||
public Window | |||
class StandaloneWindow : public Window, | |||
public TopLevelWidget | |||
{ | |||
public: | |||
/** | |||
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) | |||
}; | |||
@@ -52,18 +52,10 @@ public: | |||
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. | |||
@@ -30,11 +30,11 @@ | |||
START_NAMESPACE_DGL | |||
// class Application; | |||
class Application; | |||
// class NanoWidget; | |||
// class Window; | |||
// class StandaloneWindow; | |||
// class SubWidget; | |||
class SubWidget; | |||
class TopLevelWidget; | |||
using namespace Events; | |||
@@ -46,26 +46,31 @@ using namespace Events; | |||
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. | |||
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 | |||
{ | |||
/** | |||
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: | |||
/** | |||
@@ -109,7 +114,7 @@ public: | |||
/** | |||
Get size. | |||
*/ | |||
const Size<uint>& getSize() const noexcept; | |||
const Size<uint> getSize() const noexcept; | |||
/** | |||
Set width. | |||
@@ -131,17 +136,6 @@ public: | |||
*/ | |||
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. | |||
@see setId | |||
@@ -154,9 +148,35 @@ public: | |||
*/ | |||
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: | |||
/** | |||
A function called to draw the view contents with OpenGL. | |||
A function called to draw the widget contents. | |||
*/ | |||
virtual void onDisplay() = 0; | |||
@@ -208,6 +228,7 @@ private: | |||
// friend class NanoWidget; | |||
// friend class Window; | |||
// friend class StandaloneWindow; | |||
friend class SubWidget; | |||
friend class TopLevelWidget; | |||
// #ifdef DISTRHO_DEFINES_H_INCLUDED | |||
// friend class DISTRHO_NAMESPACE::UI; | |||
@@ -22,6 +22,7 @@ | |||
START_NAMESPACE_DGL | |||
class Application; | |||
class TopLevelWidget; | |||
// ----------------------------------------------------------------------- | |||
@@ -151,6 +152,11 @@ public: | |||
const char* getTitle() const noexcept; | |||
void setTitle(const char* title); | |||
/** | |||
Get the application associated with this window. | |||
*/ | |||
Application& getApp() const noexcept; | |||
/** | |||
Get the "native" window handle. | |||
Returned value depends on the platform: | |||
@@ -161,10 +167,18 @@ public: | |||
*/ | |||
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: | |||
struct PrivateData; | |||
PrivateData* const pData; | |||
friend class Application; | |||
friend class TopLevelWidget; | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window); | |||
}; | |||
@@ -251,11 +265,6 @@ END_NAMESPACE_DGL | |||
double getScaling() const noexcept; | |||
#if 0 | |||
// should this be removed? | |||
Application& getApp() const noexcept; | |||
#endif | |||
const GraphicsContext& getGraphicsContext() const noexcept; | |||
void addIdleCallback(IdleCallback* const callback); | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* 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. | |||
*/ | |||
#include "../Geometry.hpp" | |||
#include "../Cairo.hpp" | |||
#include "WidgetPrivateData.hpp" | |||
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) | |||
* 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 | |||
* 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. | |||
*/ | |||
#include "../Geometry.hpp" | |||
#include "../OpenGL.hpp" | |||
#include "WidgetPrivateData.hpp" | |||
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 "WidgetPrivateData.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
StandaloneWindow::StandaloneWindow() | |||
: Application(true), | |||
Window((Application&)*this), | |||
fWidget(nullptr) {} | |||
StandaloneWindow::StandaloneWindow(Application& app) | |||
: Window(app), | |||
TopLevelWidget(this) {} | |||
void StandaloneWindow::exec() | |||
{ | |||
@@ -15,9 +15,15 @@ | |||
*/ | |||
#include "SubWidgetPrivateData.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
SubWidget::SubWidget(Widget* const widgetToGroupTo) | |||
: pData(new PrivateData(this, widgetToGroupTo)) {} | |||
: Widget(widgetToGroupTo), | |||
pData(new PrivateData(this, widgetToGroupTo)) {} | |||
SubWidget::~SubWidget() | |||
{ | |||
@@ -79,9 +85,14 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept | |||
pData->absolutePos = pos; | |||
onPositionChanged(ev); | |||
getTopLevelWidget().repaint(); | |||
// repaint the whole thing | |||
pData->parent->repaint(); | |||
} | |||
void SubWidget::onPositionChanged(const PositionChangedEvent&) | |||
{ | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
END_NAMESPACE_DGL |
@@ -18,31 +18,25 @@ | |||
#define DGL_SUBWIDGET_PRIVATE_DATA_HPP_INCLUDED | |||
#include "../SubWidget.hpp" | |||
#include "../WidgetPrivateData.hpp" | |||
#include <vector> | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
struct SubWidget::PrivateData { | |||
SubWidget* const self; | |||
Widget* const groupWidget; | |||
Widget* const parent; | |||
Point<int> absolutePos; | |||
PrivateData(SubWidget* const s, Widget* const g) | |||
PrivateData(SubWidget* const s, Widget* const p) | |||
: 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 | |||
@@ -15,14 +15,14 @@ | |||
*/ | |||
#include "TopLevelWidgetPrivateData.hpp" | |||
#include "pugl.hpp" | |||
// #include "pugl.hpp" | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
TopLevelWidget::TopLevelWidget(Window& windowToMapTo) | |||
: Widget(*this), | |||
: Widget(this), | |||
pData(new PrivateData(this, windowToMapTo)) {} | |||
TopLevelWidget::~TopLevelWidget() | |||
@@ -30,16 +30,14 @@ TopLevelWidget::~TopLevelWidget() | |||
delete pData; | |||
} | |||
void TopLevelWidget::onDisplayBefore() | |||
{ | |||
} | |||
void TopLevelWidget::onDisplayAfter() | |||
void TopLevelWidget::onDisplay() | |||
{ | |||
pData->display(); | |||
} | |||
void TopLevelWidget::onResize(const ResizeEvent& ev) | |||
{ | |||
pData->resize(ev.size.getWidth(), ev.size.getHeight()); | |||
Widget::onResize(ev); | |||
} | |||
@@ -15,16 +15,17 @@ | |||
*/ | |||
#include "TopLevelWidgetPrivateData.hpp" | |||
#include "../Window.hpp" | |||
// #include "pugl.hpp" | |||
#include "WidgetPrivateData.hpp" | |||
#include "WindowPrivateData.hpp" | |||
#include "pugl.hpp" | |||
START_NAMESPACE_DGL | |||
#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) \ | |||
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() | |||
{ | |||
puglFallbackOnDisplay(window.pData->view); | |||
if (widgets.size() == 0) | |||
return; | |||
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) | |||
{ | |||
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) | |||
return; | |||
/* | |||
FOR_EACH_WIDGET(it) | |||
{ | |||
Widget* const widget(*it); | |||
if (widget->pData->needsFullViewport) | |||
widget->setSize(width, height); | |||
} | |||
}*/ | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -21,8 +21,11 @@ START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// 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() | |||
{ | |||
@@ -40,7 +43,7 @@ void Widget::setVisible(bool yesNo) | |||
return; | |||
pData->visible = yesNo; | |||
pData->topLevelWidget.repaint(); | |||
repaint(); | |||
} | |||
void Widget::show() | |||
@@ -63,7 +66,7 @@ uint Widget::getHeight() const noexcept | |||
return pData->size.getHeight(); | |||
} | |||
const Size<uint>& Widget::getSize() const noexcept | |||
const Size<uint> Widget::getSize() const noexcept | |||
{ | |||
return pData->size; | |||
} | |||
@@ -80,7 +83,7 @@ void Widget::setWidth(uint width) noexcept | |||
pData->size.setWidth(width); | |||
onResize(ev); | |||
pData->topLevelWidget.repaint(); | |||
pData->repaint(); | |||
} | |||
void Widget::setHeight(uint height) noexcept | |||
@@ -95,7 +98,7 @@ void Widget::setHeight(uint height) noexcept | |||
pData->size.setHeight(height); | |||
onResize(ev); | |||
pData->topLevelWidget.repaint(); | |||
pData->repaint(); | |||
} | |||
void Widget::setSize(uint width, uint height) noexcept | |||
@@ -115,17 +118,15 @@ void Widget::setSize(const Size<uint>& size) noexcept | |||
pData->size = size; | |||
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; | |||
} | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* 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 | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -15,6 +15,7 @@ | |||
*/ | |||
#include "WidgetPrivateData.hpp" | |||
#include "../TopLevelWidget.hpp" | |||
#ifdef DGL_CAIRO | |||
# 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) | |||
* 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 | |||
* 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 | |||
#define DGL_WIDGET_PRIVATE_DATA_HPP_INCLUDED | |||
#include "../TopLevelWidget.hpp" | |||
#include "../Window.hpp" | |||
#include "../Widget.hpp" | |||
#include <vector> | |||
#include <list> | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
struct Widget::PrivateData { | |||
Widget* const self; | |||
Size<uint> size; | |||
std::vector<Widget*> subWidgets; | |||
TopLevelWidget& topLevelWidget; | |||
TopLevelWidget* const topLevelWidget; | |||
Widget* const groupWidget; | |||
uint id; | |||
bool needsScaling; | |||
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 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 | |||
@@ -27,7 +27,7 @@ START_NAMESPACE_DGL | |||
// : pData(new PrivateData(transientParentWindow.pData->fAppData, this, transientParentWindow)) {} | |||
Window::Window(Application& app) | |||
: pData(new PrivateData(app.pData, this)) {} | |||
: pData(new PrivateData(app, this)) {} | |||
Window::Window(Application& app, | |||
const uintptr_t parentWindowHandle, | |||
@@ -35,7 +35,7 @@ Window::Window(Application& app, | |||
const uint height, | |||
const double scaling, | |||
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() | |||
{ | |||
@@ -123,11 +123,21 @@ void Window::setTitle(const char* const title) | |||
puglSetWindowTitle(pData->view, title); | |||
} | |||
Application& Window::getApp() const noexcept | |||
{ | |||
return pData->app; | |||
} | |||
uintptr_t Window::getNativeWindowHandle() const noexcept | |||
{ | |||
return puglGetNativeWindow(pData->view); | |||
} | |||
void Window::onReshape(const uint width, const uint height) | |||
{ | |||
puglFallbackOnResize(pData->view); | |||
} | |||
#if 0 | |||
#if 0 | |||
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), | |||
view(puglNewView(appData->world)), | |||
topLevelWidget(nullptr), | |||
@@ -52,31 +53,37 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||
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), | |||
view(puglNewView(appData->world)), | |||
topLevelWidget(nullptr), | |||
isClosed(true), | |||
isVisible(false), | |||
isEmbed(false) | |||
isEmbed(false), | |||
scaling(1.0), | |||
autoScaling(1.0) | |||
{ | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
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 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), | |||
view(puglNewView(appData->world)), | |||
topLevelWidget(nullptr), | |||
isClosed(parentWindowHandle == 0), | |||
isVisible(parentWindowHandle != 0), | |||
isEmbed(parentWindowHandle != 0) | |||
isEmbed(parentWindowHandle != 0), | |||
scaling(scale), | |||
autoScaling(1.0) | |||
{ | |||
init(width, height, resizable); | |||
@@ -257,9 +264,7 @@ void Window::PrivateData::onPuglDisplay() | |||
#ifndef DPF_TEST_WINDOW_CPP | |||
if (topLevelWidget != nullptr) | |||
{ | |||
topLevelWidget->onDisplayBefore(); | |||
topLevelWidget->onDisplay(); | |||
topLevelWidget->onDisplayAfter(); | |||
} | |||
else | |||
#endif | |||
@@ -274,12 +279,12 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||
DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); | |||
self->onReshape(width, height); | |||
#ifndef DPF_TEST_WINDOW_CPP | |||
if (topLevelWidget != nullptr) | |||
topLevelWidget->setSize(width, height); | |||
else | |||
#endif | |||
puglFallbackOnResize(view); | |||
} | |||
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | |||
@@ -29,13 +29,13 @@ class TopLevelWidget; | |||
// ----------------------------------------------------------------------- | |||
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; | |||
/** Pugl view instance. */ | |||
@@ -57,14 +57,20 @@ struct Window::PrivateData : IdleCallback { | |||
/** Whether this Window is embed into another (usually not DGL-controlled) Window. */ | |||
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. */ | |||
PrivateData(AppData* appData, Window* self); | |||
PrivateData(Application& app, Window* self); | |||
/** 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. */ | |||
PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, | |||
PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, | |||
uint width, uint height, double scaling, bool resizable); | |||
/** 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 | |||
endif | |||
ifeq ($(HAVE_OPENGL),true) | |||
TESTS += Demo | |||
WTESTS = Window.opengl | |||
endif | |||
ifeq ($(HAVE_VULKAN),true) | |||
@@ -87,12 +88,17 @@ clean: | |||
@echo "Compiling $< (Cairo)" | |||
$(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 | |||
-@mkdir -p ../build/tests | |||
@echo "Compiling $< (OpenGL)" | |||
$(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 | |||
@echo "Compiling $< (Vulkan)" | |||
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@ | |||
@@ -108,6 +114,10 @@ clean: | |||
@echo "Linking $*" | |||
$(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 | |||
@echo "Linking $*" | |||
$(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 |