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