DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit ab5f3d3b011096ee8966493828bcc609377d905b
parent ffe1a84634db0bec6031789f0d64ac6cf2534221
Author: falkTX <falktx@falktx.com>
Date:   Fri,  7 May 2021 02:03:04 +0100

More code restructure; Add back onClose and repaint

Diffstat:
Mdgl/SubWidget.hpp | 1+
Mdgl/TopLevelWidget.hpp | 13-------------
Mdgl/Widget.hpp | 8++++----
Mdgl/Window.hpp | 14++++++++++----
Mdgl/src/ApplicationPrivateData.hpp | 4++--
Mdgl/src/Cairo.cpp | 6+++---
Mdgl/src/OpenGL.cpp | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mdgl/src/SubWidget.cpp | 1-
Adgl/src/SubWidgetPrivateData.cpp | 39+++++++++++++++++++++++++++++++++++++++
Mdgl/src/SubWidgetPrivateData.hpp | 9+++++----
Mdgl/src/TopLevelWidget.cpp | 12------------
Mdgl/src/TopLevelWidgetPrivateData.cpp | 48++++++++++++++++++++++--------------------------
Mdgl/src/TopLevelWidgetPrivateData.hpp | 6+++---
Mdgl/src/Widget.cpp | 6+++---
Mdgl/src/WidgetPrivateData.cpp | 44+++++++++++++++++---------------------------
Mdgl/src/WidgetPrivateData.hpp | 14++++++++------
Mdgl/src/Window.cpp | 41+++++++++++++++++++++--------------------
Mdgl/src/WindowPrivateData.cpp | 49++++++++++++++++++++++++++-----------------------
Mdgl/src/WindowPrivateData.hpp | 9+++++----
Mdgl/src/pugl.cpp | 4++--
Mdgl/src/pugl.hpp | 4++--
Mtests/Demo.cpp | 202++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mtests/widgets/ExampleColorWidget.hpp | 2+-
23 files changed, 452 insertions(+), 219 deletions(-)

diff --git a/dgl/SubWidget.hpp b/dgl/SubWidget.hpp @@ -105,6 +105,7 @@ protected: private: struct PrivateData; PrivateData* const pData; + friend class Widget; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SubWidget) }; diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp @@ -50,19 +50,6 @@ public: */ virtual ~TopLevelWidget(); -protected: - /** - A function called to draw the widget contents. - Reimplemented from Widget::onDisplay. - */ - void onDisplay() override; - - /** - A function called when the widget is resized. - Reimplemented from Widget::onResize. - */ - void onResize(const ResizeEvent&) override; - private: struct PrivateData; PrivateData* const pData; diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp @@ -63,14 +63,14 @@ using namespace Events; class Widget { /** - Private constructor, reserved for SubWidget class. + Private constructor, reserved for TopLevelWidget class. */ - explicit Widget(Widget* widgetToGroupTo); + explicit Widget(TopLevelWidget* topLevelWidget); /** - Private constructor, reserved for TopLevelWidget class. + Private constructor, reserved for SubWidget class. */ - explicit Widget(TopLevelWidget* topLevelWidget); + explicit Widget(Widget* widgetToGroupTo); public: /** diff --git a/dgl/Window.hpp b/dgl/Window.hpp @@ -167,6 +167,9 @@ public: */ uintptr_t getNativeWindowHandle() const noexcept; + void repaint() noexcept; + void repaint(const Rectangle<uint>& rect) noexcept; + protected: /** A function called when the window is resized. @@ -174,6 +177,13 @@ protected: */ virtual void onReshape(uint width, uint height); + /** + A function called when the window is attempted to be closed. + Returning true closes the window, which is the default behaviour. + Override this method and return false to prevent the window from being closed by the user. + */ + virtual bool onClose(); + private: struct PrivateData; PrivateData* const pData; @@ -247,8 +257,6 @@ END_NAMESPACE_DGL void exec(bool lockWait = false); void focus(); - void repaint() noexcept; - void repaint(const Rectangle<uint>& rect) noexcept; #ifndef DGL_FILE_BROWSER_DISABLED bool openFileBrowser(const FileBrowserOptions& options); @@ -272,8 +280,6 @@ END_NAMESPACE_DGL protected: - virtual void onClose(); - #ifndef DGL_FILE_BROWSER_DISABLED virtual void fileBrowserSelected(const char* filename); #endif diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp @@ -53,7 +53,7 @@ struct Application::PrivateData { std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks; /** Constructor and destructor */ - PrivateData(const bool standalone); + explicit PrivateData(bool standalone); ~PrivateData(); /** Flag one window as shown, which increments @a visibleWindows. @@ -67,7 +67,7 @@ struct Application::PrivateData { void oneWindowClosed() noexcept; /** Run Pugl world update for @a timeoutInMs, and then each idle callback in order of registration. */ - void idle(const uint timeoutInMs); + void idle(uint timeoutInMs); /** Set flag indicating application is quitting, and close all windows in reverse order of registration. For standalone mode only. */ diff --git a/dgl/src/Cairo.cpp b/dgl/src/Cairo.cpp @@ -66,7 +66,7 @@ void Rectangle<T>::_draw(const bool outline) void Widget::PrivateData::display(const uint width, const uint height, - const double scaling, + const double autoScaling, const bool renderingSubWidget) { if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) @@ -76,14 +76,14 @@ void Widget::PrivateData::display(const uint width, cairo_matrix_t matrix; cairo_get_matrix(cr, &matrix); cairo_translate(cr, absolutePos.getX(), absolutePos.getY()); - // TODO: scaling and cropping + // TODO: autoScaling and cropping // display widget self->onDisplay(); cairo_set_matrix(cr, &matrix); - displaySubWidgets(width, height, scaling); + displaySubWidgets(width, height, autoScaling); } // ----------------------------------------------------------------------- diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp @@ -15,6 +15,7 @@ */ #include "../OpenGL.hpp" +#include "SubWidgetPrivateData.hpp" #include "WidgetPrivateData.hpp" #include "WindowPrivateData.hpp" @@ -110,63 +111,123 @@ void Rectangle<T>::_draw(const bool outline) // ----------------------------------------------------------------------- +#if 0 void Widget::PrivateData::display(const uint width, const uint height, - const double scaling, + const double autoScaling, const bool renderingSubWidget) { + printf("Widget::PrivateData::display INIT\n"); + if (/*(skipDisplay && ! renderingSubWidget) ||*/ size.isInvalid() || ! visible) return; -// bool needsDisableScissor = false; + bool needsDisableScissor = false; // reset color glColor4f(1.0f, 1.0f, 1.0f, 1.0f); -// if (needsFullViewport || (absolutePos.isZero() && size == Size<uint>(width, height))) +#if 0 + if (/*needsFullViewport ||*/ (absolutePos.isZero() && size == Size<uint>(width, height))) +#endif + { + // full viewport size + glViewport(0, + -(height * autoScaling - height), + width * autoScaling, + height * autoScaling); + } +#if 0 + 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() * autoScaling, + -std::round((height * autoScaling - height) + (absolutePos.getY() * autoScaling)), + std::round(width * autoScaling), + std::round(height * autoScaling)); + + // then cut the outer bounds + glScissor(absolutePos.getX() * autoScaling, + height - std::round((self->getHeight() + absolutePos.getY()) * autoScaling), + std::round(self->getWidth() * autoScaling), + std::round(self->getHeight() * autoScaling)); + + glEnable(GL_SCISSOR_TEST); + needsDisableScissor = true; + } +#endif + + // display widget + self->onDisplay(); + + if (needsDisableScissor) + { + glDisable(GL_SCISSOR_TEST); + needsDisableScissor = false; + } + + displaySubWidgets(width, height, autoScaling); +} +#endif + +void SubWidget::PrivateData::display(uint width, uint height, double autoScaling) +{ + bool needsDisableScissor = false; + + if (absolutePos.isZero() && self->getSize() == Size<uint>(width, height)) { // full viewport size glViewport(0, - -(height * scaling - height), - width * scaling, - height * scaling); + -(height * autoScaling - height), + width * autoScaling, + height * autoScaling); + } + /* + 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() * autoScaling, + -std::round((height * autoScaling - height) + (absolutePos.getY() * autoScaling)), + std::round(width * autoScaling), + std::round(height * autoScaling)); + + // then cut the outer bounds + glScissor(absolutePos.getX() * autoScaling, + height - std::round((self->getHeight() + absolutePos.getY()) * autoScaling), + std::round(self->getWidth() * autoScaling), + std::round(self->getHeight() * autoScaling)); + + glEnable(GL_SCISSOR_TEST); + needsDisableScissor = true; } -// 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; -// } + if (needsDisableScissor) + { + glDisable(GL_SCISSOR_TEST); + needsDisableScissor = false; + } - displaySubWidgets(width, height, scaling); +// displaySubWidgets(width, height, autoScaling); } // ----------------------------------------------------------------------- diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp @@ -15,7 +15,6 @@ */ #include "SubWidgetPrivateData.hpp" -#include "../TopLevelWidget.hpp" START_NAMESPACE_DGL diff --git a/dgl/src/SubWidgetPrivateData.cpp b/dgl/src/SubWidgetPrivateData.cpp @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#include "SubWidgetPrivateData.hpp" +#include "WidgetPrivateData.hpp" + +START_NAMESPACE_DGL + +// -------------------------------------------------------------------------------------------------------------------- + +SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const p) + : self(s), + parent(p), + absolutePos() +{ + parent->pData->subWidgets.push_back(self); +} + +SubWidget::PrivateData::~PrivateData() +{ + parent->pData->subWidgets.remove(self); +} + +// -------------------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DGL diff --git a/dgl/src/SubWidgetPrivateData.hpp b/dgl/src/SubWidgetPrivateData.hpp @@ -28,10 +28,11 @@ struct SubWidget::PrivateData { Widget* const parent; Point<int> absolutePos; - PrivateData(SubWidget* const s, Widget* const p) - : self(s), - parent(p), - absolutePos() {} + explicit PrivateData(SubWidget* const s, Widget* const p); + ~PrivateData(); + + // NOTE display function is different depending on build type, must call displaySubWidgets at the end + void display(uint width, uint height, double autoScaling); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) }; diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp @@ -15,7 +15,6 @@ */ #include "TopLevelWidgetPrivateData.hpp" -// #include "pugl.hpp" START_NAMESPACE_DGL @@ -30,17 +29,6 @@ TopLevelWidget::~TopLevelWidget() delete pData; } -void TopLevelWidget::onDisplay() -{ - pData->display(); -} - -void TopLevelWidget::onResize(const ResizeEvent& ev) -{ - pData->resize(ev.size.getWidth(), ev.size.getHeight()); - Widget::onResize(ev); -} - // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp @@ -31,40 +31,36 @@ START_NAMESPACE_DGL TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) : self(s), - window(w), - widgets() {} + selfw(s), + window(w) +{ + window.pData->topLevelWidget = self; +} -void TopLevelWidget::PrivateData::display() +TopLevelWidget::PrivateData::~PrivateData() { - puglFallbackOnDisplay(window.pData->view); + // FIXME? + window.pData->topLevelWidget = nullptr; +} - if (widgets.size() == 0) - return; +void TopLevelWidget::PrivateData::display() +{ + printf("TopLevelWidget::PrivateData::display INIT\n"); const Size<uint> size(window.getSize()); - const uint width = size.getWidth(); - const uint height = size.getHeight(); - const double scaling = window.pData->autoScaling; + const uint width = size.getWidth(); + const uint height = size.getHeight(); + const double autoScaling = window.pData->autoScaling; + printf("TopLevelWidget::PrivateData::display %i %i\n", width, height); - FOR_EACH_WIDGET(it) - { - Widget* const widget(*it); - widget->pData->display(width, height, scaling, false); - } -} + // full viewport size + glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); -void TopLevelWidget::PrivateData::resize(const uint width, const uint height) -{ - if (widgets.size() == 0) - return; -/* - FOR_EACH_WIDGET(it) - { - Widget* const widget(*it); + // main widget drawing + self->onDisplay(); - if (widget->pData->needsFullViewport) - widget->setSize(width, height); - }*/ + // now draw subwidgets if there are any + selfw->pData->displaySubWidgets(width, height, autoScaling); } // ----------------------------------------------------------------------- diff --git a/dgl/src/TopLevelWidgetPrivateData.hpp b/dgl/src/TopLevelWidgetPrivateData.hpp @@ -27,12 +27,12 @@ START_NAMESPACE_DGL struct TopLevelWidget::PrivateData { TopLevelWidget* const self; + Widget* const selfw; Window& window; - std::list<Widget*> widgets; - PrivateData(TopLevelWidget* const s, Window& w); + explicit PrivateData(TopLevelWidget* const s, Window& w); + ~PrivateData(); void display(); - void resize(uint width, uint height); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) }; diff --git a/dgl/src/Widget.cpp b/dgl/src/Widget.cpp @@ -21,12 +21,12 @@ START_NAMESPACE_DGL // ----------------------------------------------------------------------- // Widget -Widget::Widget(Widget* const widgetToGroupTo) - : pData(new PrivateData(this, widgetToGroupTo)) {} - Widget::Widget(TopLevelWidget* const topLevelWidget) : pData(new PrivateData(this, topLevelWidget)) {} +Widget::Widget(Widget* const widgetToGroupTo) + : pData(new PrivateData(this, widgetToGroupTo)) {} + Widget::~Widget() { delete pData; diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp @@ -17,13 +17,6 @@ #include "WidgetPrivateData.hpp" #include "../TopLevelWidget.hpp" -#ifdef DGL_CAIRO -# include "../Cairo.hpp" -#endif -#ifdef DGL_OPENGL -# include "../OpenGL.hpp" -#endif - START_NAMESPACE_DGL // ----------------------------------------------------------------------- @@ -36,9 +29,7 @@ Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) needsScaling(false), visible(true), size(0, 0), - subWidgets() -{ -} + subWidgets() {} Widget::PrivateData::PrivateData(Widget* const s, Widget* const g) : self(s), @@ -48,44 +39,43 @@ Widget::PrivateData::PrivateData(Widget* const s, Widget* const g) needsScaling(false), visible(true), size(0, 0), - subWidgets() -{ - parentGroupWidget->pData->subWidgets.push_back(self); -} + subWidgets() {} Widget::PrivateData::~PrivateData() { - if (parentGroupWidget != nullptr) - parentGroupWidget->pData->subWidgets.remove(self); - subWidgets.clear(); } 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) + printf("Widget::PrivateData::displaySubWidgets INIT | %lu\n", subWidgets.size()); + + if (subWidgets.size() == 0) + return; + + for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) { - Widget* const widget(*it); - DISTRHO_SAFE_ASSERT_CONTINUE(widget->pData != this); + SubWidget* const subwidget(*it); + printf("Widget::PrivateData::displaySubWidgets %i %i -> %p\n", width, height, subwidget); - widget->pData->display(width, height, scaling, true); + subwidget->pData->display(width, height, scaling); } } void Widget::PrivateData::repaint() { - if (parentGroupWidget != nullptr) - parentGroupWidget->repaint(); - else if (topLevelWidget != nullptr) - topLevelWidget->repaint(); +// if (parentGroupWidget != nullptr) +// parentGroupWidget->repaint(); +// else if (topLevelWidget != nullptr) +// topLevelWidget->repaint(); } // ----------------------------------------------------------------------- TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) { - if (TopLevelWidget* const tlw = dynamic_cast<TopLevelWidget*>(w)) - return tlw; +// if (TopLevelWidget* const tlw = dynamic_cast<TopLevelWidget*>(w)) +// return tlw; if (w->pData->topLevelWidget != nullptr) return w->pData->topLevelWidget; if (w->pData->parentGroupWidget != nullptr) diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp @@ -33,16 +33,18 @@ struct Widget::PrivateData { bool needsScaling; bool visible; Size<uint> size; - std::list<Widget*> subWidgets; + std::list<SubWidget*> subWidgets; - PrivateData(Widget* const s, TopLevelWidget* const tlw); - PrivateData(Widget* const s, Widget* const pgw); + // called via TopLevelWidget + explicit PrivateData(Widget* const s, TopLevelWidget* const tlw); + // called via SubWidget + explicit PrivateData(Widget* const s, Widget* const pgw); ~PrivateData(); - // NOTE display function is different depending on build type - void display(const uint width, const uint height, const double scaling, const bool renderingSubWidget); + // NOTE display function is different depending on build type, must call displaySubWidgets at the end +// void display(uint width, uint height, double autoScaling, bool renderingSubWidget); - void displaySubWidgets(const uint width, const uint height, const double scaling); + void displaySubWidgets(uint width, uint height, double autoScaling); void repaint(); diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp @@ -133,11 +133,32 @@ uintptr_t Window::getNativeWindowHandle() const noexcept return puglGetNativeWindow(pData->view); } +void Window::repaint() noexcept +{ + puglPostRedisplay(pData->view); +} + +void Window::repaint(const Rectangle<uint>& rect) noexcept +{ + const PuglRect prect = { + static_cast<double>(rect.getX()), + static_cast<double>(rect.getY()), + static_cast<double>(rect.getWidth()), + static_cast<double>(rect.getHeight()), + }; + puglPostRedisplayRect(pData->view, prect); +} + void Window::onReshape(const uint width, const uint height) { puglFallbackOnResize(pData->view); } +bool Window::onClose() +{ + return true; +} + #if 0 #if 0 void Window::exec(bool lockWait) @@ -154,22 +175,6 @@ void Window::focus() puglGrabFocus(pData->fView); } -void Window::repaint() noexcept -{ - puglPostRedisplay(pData->fView); -} - -void Window::repaint(const Rectangle<uint>& rect) noexcept -{ - const PuglRect prect = { - static_cast<double>(rect.getX()), - static_cast<double>(rect.getY()), - static_cast<double>(rect.getWidth()), - static_cast<double>(rect.getHeight()), - }; - puglPostRedisplayRect(pData->fView, prect); -} - bool Window::isResizable() const noexcept { return puglGetViewHint(pData->fView, PUGL_RESIZABLE) == PUGL_TRUE; @@ -267,10 +272,6 @@ void Window::removeIdleCallback(IdleCallback* const callback) // ----------------------------------------------------------------------- -void Window::onClose() -{ -} - #ifndef DGL_FILE_BROWSER_DISABLED void Window::fileBrowserSelected(const char*) { diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp @@ -15,7 +15,7 @@ */ #include "WindowPrivateData.hpp" -#include "../TopLevelWidget.hpp" +#include "TopLevelWidgetPrivateData.hpp" #include "pugl.hpp" @@ -255,22 +255,19 @@ void Window::PrivateData::idleCallback() // // if (fModal.enabled && fModal.parent != nullptr) // fModal.parent->windowSpecificIdle(); +// self->repaint(); } // ----------------------------------------------------------------------- void Window::PrivateData::onPuglDisplay() { + puglOnDisplayPrepare(view); + #ifndef DPF_TEST_WINDOW_CPP if (topLevelWidget != nullptr) - { - topLevelWidget->onDisplay(); - } - else + topLevelWidget->pData->display(); #endif - { - puglFallbackOnDisplay(view); - } } void Window::PrivateData::onPuglReshape(const int width, const int height) @@ -287,6 +284,22 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) #endif } +void Window::PrivateData::onPuglClose() +{ + DGL_DBG("PUGL: onClose\n"); + +// if (fModal.enabled) +// exec_fini(); + + if (! self->onClose()) + return; + +// if (fModal.childFocus != nullptr) +// fModal.childFocus->fSelf->onClose(); + + close(); +} + static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) @@ -310,6 +323,11 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu pData->onPuglDisplay(); break; + ///< View will be closed, a #PuglEventClose + case PUGL_CLOSE: + pData->onPuglClose(); + break; + // TODO default: break; @@ -517,21 +535,6 @@ void Window::PrivateData::removeWidget(Widget* const widget) // ----------------------------------------------------------------------- -void Window::PrivateData::onPuglClose() -{ - DGL_DBG("PUGL: onClose\n"); - -// if (fModal.enabled) -// exec_fini(); - - fSelf->onClose(); - - if (fModal.childFocus != nullptr) - fModal.childFocus->fSelf->onClose(); - - close(); -} - void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev) { DGL_DBGp("PUGL: onMouse : %i %i %i %i\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp @@ -64,14 +64,14 @@ struct Window::PrivateData : IdleCallback { double autoScaling; /** Constructor for a regular, standalone window. */ - PrivateData(Application& app, Window* self); + explicit PrivateData(Application& app, Window* self); /** Constructor for a regular, standalone window with a transient parent. */ - PrivateData(Application& app, Window* self, Window& transientWindow); + explicit PrivateData(Application& app, Window* self, Window& transientWindow); /** Constructor for an embed Window, with a few extra hints from the host side. */ - PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, - uint width, uint height, double scaling, bool resizable); + explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, + uint width, uint height, double scaling, bool resizable); /** Destructor. */ ~PrivateData() override; @@ -98,6 +98,7 @@ struct Window::PrivateData : IdleCallback { // pugl events void onPuglDisplay(); void onPuglReshape(int width, int height); + void onPuglClose(); // Pugl event handling entry point static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp @@ -170,9 +170,9 @@ void puglSetMatchingBackendForCurrentBuild(PuglView* view) } // -------------------------------------------------------------------------------------------------------------------- -// DGL specific, build-specific fallback drawing +// DGL specific, build-specific drawing prepare -void puglFallbackOnDisplay(PuglView*) +void puglOnDisplayPrepare(PuglView*) { #ifdef DGL_OPENGL glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp @@ -45,9 +45,9 @@ puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height); PUGL_API void puglSetMatchingBackendForCurrentBuild(PuglView* view); -// DGL specific, build-specific fallback drawing +// DGL specific, build-specific drawing prepare PUGL_API void -puglFallbackOnDisplay(PuglView* view); +puglOnDisplayPrepare(PuglView* view); // DGL specific, build-specific fallback resize PUGL_API void diff --git a/tests/Demo.cpp b/tests/Demo.cpp @@ -22,12 +22,12 @@ // #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/SubWidgetPrivateData.cpp" #include "dgl/src/TopLevelWidget.cpp" #include "dgl/src/TopLevelWidgetPrivateData.cpp" #include "dgl/src/Widget.cpp" @@ -63,27 +63,166 @@ public: curPage(0), curHover(-1) { +#if 0 // 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); + 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); +#endif + } + +protected: + void onDisplay() override + { + const int iconSize = bgIcon.getWidth(); + printf("LEFT SIDE WIDGET onDisplay %i\n", iconSize); + + glColor3f(0.027f, 0.027f, 0.027f); + Rectangle<uint>(0, 0, getSize()).draw(); + + bgIcon.setY(curPage*iconSize + curPage*3); + + glColor3f(0.129f, 0.129f, 0.129f); + bgIcon.draw(); + + glColor3f(0.184f, 0.184f, 0.184f); + bgIcon.drawOutline(); + + if (curHover != curPage && curHover != -1) + { + Rectangle<int> rHover(1, curHover*iconSize + curHover*3, iconSize-2, iconSize-2); + + glColor3f(0.071f, 0.071f, 0.071f); + rHover.draw(); + + glColor3f(0.102f, 0.102f, 0.102f); + rHover.drawOutline(); + } + + glLineWidth(2.0f); + glColor3f(0.184f, 0.184f, 0.184f); + lineSep.draw(); + + // reset color + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + +#if 0 + const int pad = iconSize/2 - DemoArtwork::ico1Width/2; + + img1.drawAt(pad, pad); + img2.drawAt(pad, pad + 3 + iconSize); + img3.drawAt(pad, pad + 6 + iconSize*2); + img4.drawAt(pad, pad + 9 + iconSize*3); + img5.drawAt(pad, pad + 12 + iconSize*4); + + // draw some text + nvg.beginFrame(this); + + nvg.fontSize(23.0f); + nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP); + //nvg.textLineHeight(20.0f); + + nvg.fillColor(220,220,220,220); + nvg.textBox(10, 420, iconSize, "Haha,", nullptr); + nvg.textBox(15, 440, iconSize, "Look!", nullptr); + + nvg.endFrame(); +#endif + } + + bool onMouse(const MouseEvent& ev) override + { + if (ev.button != 1 || ! ev.press) + return false; + if (! contains(ev.pos)) + return false; + + const int iconSize = bgIcon.getWidth(); + + for (int i=0; i<kPageCount; ++i) + { + bgIcon.setY(i*iconSize + i*3); + + if (bgIcon.contains(ev.pos)) + { + curPage = i; + callback->curPageChanged(i); + repaint(); + break; + } + } + + return true; + } + + bool onMotion(const MotionEvent& ev) override + { + if (contains(ev.pos)) + { + const int iconSize = bgIcon.getWidth(); + + for (int i=0; i<kPageCount; ++i) + { + bgIcon.setY(i*iconSize + i*3); + + if (bgIcon.contains(ev.pos)) + { + if (curHover == i) + return true; + + curHover = i; + repaint(); + return true; + } + } + + if (curHover == -1) + return true; + + curHover = -1; + repaint(); + return true; + } + else + { + if (curHover == -1) + return false; + + curHover = -1; + repaint(); + return true; + } + } + + void onResize(const ResizeEvent& ev) override + { + const int width = ev.size.getWidth(); + const int height = ev.size.getHeight(); + + bgIcon.setWidth(width-4); + bgIcon.setHeight(width-4); + + lineSep.setStartPos(width, 0); + lineSep.setEndPos(width, height); } private: Callback* const callback; int curPage, curHover; -// Rectangle<int> bgIcon; -// Line<int> lineSep; -// Image img1, img2, img3, img4, img5; + Rectangle<double> bgIcon; + Line<int> lineSep; +#if 0 + Image img1, img2, img3, img4, img5; // for text -// NanoVG nvg; -// NanoVG::FontId font; + NanoVG nvg;D + NanoVG::FontId font; +#endif }; // ------------------------------------------------------ @@ -94,13 +233,11 @@ class DemoWindow : public StandaloneWindow, { static const int kSidebarWidth = 81; - ExampleColorWidget wColor; - Widget* curWidget; - public: DemoWindow(Application& app) : StandaloneWindow(app), wColor(this), + wLeft(this, this), curWidget(nullptr) { wColor.hide(); @@ -115,7 +252,7 @@ public: // wRects.setAbsoluteX(kSidebarWidth); // wShapes.setAbsoluteX(kSidebarWidth); // wText.setAbsoluteX(kSidebarWidth); -// wLeft.setAbsolutePos(2, 2); + wLeft.setAbsolutePos(2, 2); // wPerf.setAbsoluteY(5); setSize(600, 500); @@ -156,6 +293,15 @@ protected: curWidget->show(); } + void onDisplay() override + { + static int counter = 0; + printf("print %i\n", ++counter); + + glColor3f(0.471f, 0.971f, 0.171f); + Rectangle<uint>(0, 0, getSize()).draw(); + } + void onReshape(uint width, uint height) override { StandaloneWindow::onReshape(width, height); @@ -170,12 +316,24 @@ protected: // wShapes.setSize(size); // wText.setSize(size); -// wLeft.setSize(kSidebarWidth-4, height-4); -// //wRezHandle.setAbsoluteX(width-wRezHandle.getWidth()); -// //wRezHandle.setAbsoluteY(height-wRezHandle.getHeight()); -// + wLeft.setSize(kSidebarWidth-4, height-4); + //wRezHandle.setAbsoluteX(width-wRezHandle.getWidth()); + //wRezHandle.setAbsoluteY(height-wRezHandle.getHeight()); + // wPerf.setAbsoluteX(width-wPerf.getWidth()-5); } + +private: + ExampleColorWidget wColor; +// ExampleImagesWidget wImages; +// ExampleRectanglesWidget wRects; +// ExampleShapesWidget wShapes; +// ExampleTextWidget wText; + LeftSideWidget wLeft; + //ResizeHandle wRezHandle; +// NanoPerfWidget wPerf; + + Widget* curWidget; }; // -------------------------------------------------------------------------------------------------------------------- diff --git a/tests/widgets/ExampleColorWidget.hpp b/tests/widgets/ExampleColorWidget.hpp @@ -41,7 +41,7 @@ public: : SubWidget(topWidget), cur('r'), reverse(false), - r(0), g(0), b(0) + r(0), g(99), b(32) { setSize(300, 300);