From 467f9199fcb73e54d94998f9d0cfb8230a39bff4 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 8 May 2021 22:47:38 +0100 Subject: [PATCH] Add SubWidget area calls, rename some vars, cleanup repaint Signed-off-by: falkTX --- dgl/Geometry.hpp | 2 + dgl/StandaloneWindow.hpp | 1 + dgl/SubWidget.hpp | 20 +++- dgl/TopLevelWidget.hpp | 8 ++ dgl/Widget.hpp | 6 +- dgl/src/Geometry.cpp | 6 ++ dgl/src/SubWidget.cpp | 30 +++++- dgl/src/SubWidgetPrivateData.cpp | 8 +- dgl/src/SubWidgetPrivateData.hpp | 4 +- dgl/src/TopLevelWidget.cpp | 15 +++ dgl/src/Widget.cpp | 13 ++- dgl/src/WidgetPrivateData.cpp | 20 ++-- dgl/src/WidgetPrivateData.hpp | 6 +- dgl/src/Window.cpp | 2 +- dgl/src/WindowPrivateData.cpp | 53 ++++++++--- dgl/src/WindowPrivateData.hpp | 8 ++ tests/Demo.cpp | 108 ++++++++++++++++------ tests/Makefile | 9 ++ tests/tests.hpp | 8 +- tests/widgets/ExampleColorWidget.hpp | 35 ++++++- tests/widgets/ExampleRectanglesWidget.hpp | 80 +++++++++------- tests/widgets/ExampleShapesWidget.hpp | 48 ++++++---- 22 files changed, 355 insertions(+), 135 deletions(-) diff --git a/dgl/Geometry.hpp b/dgl/Geometry.hpp index e922d683..9b90ae7c 100644 --- a/dgl/Geometry.hpp +++ b/dgl/Geometry.hpp @@ -210,6 +210,8 @@ public: */ bool isInvalid() const noexcept; + Size toInt() const noexcept; + Size operator+(const Size& size) noexcept; Size operator-(const Size& size) noexcept; Size& operator=(const Size& size) noexcept; diff --git a/dgl/StandaloneWindow.hpp b/dgl/StandaloneWindow.hpp index a788dfb0..85bfd4b7 100644 --- a/dgl/StandaloneWindow.hpp +++ b/dgl/StandaloneWindow.hpp @@ -45,6 +45,7 @@ public: uint getWidth() const noexcept { return Window::getWidth(); } uint getHeight() const noexcept { return Window::getHeight(); } const Size getSize() const noexcept { return Window::getSize(); } + void repaint() noexcept { Window::repaint(); } /** Overloaded functions to ensure size changes apply on both TopLevelWidget and Window classes. diff --git a/dgl/SubWidget.hpp b/dgl/SubWidget.hpp index 631be76a..6cbe49af 100644 --- a/dgl/SubWidget.hpp +++ b/dgl/SubWidget.hpp @@ -42,7 +42,7 @@ public: /** Constructor. */ - explicit SubWidget(Widget* widgetToGroupTo); + explicit SubWidget(Widget* parentWidget); /** Destructor. @@ -76,6 +76,19 @@ public: */ Point getAbsolutePos() const noexcept; + /** + Get absolute area of this subwidget. + This is the same as `Rectangle(getAbsolutePos(), getSize());` + @see getConstrainedAbsoluteArea() + */ + Rectangle getAbsoluteArea() const noexcept; + + /** + Get absolute area of this subwidget, with special consideration for not allowing negative values. + @see getAbsoluteArea() + */ + Rectangle getConstrainedAbsoluteArea() const noexcept; + /** Set absolute X. */ @@ -96,6 +109,11 @@ public: */ void setAbsolutePos(const Point& pos) noexcept; + /** + Request repaint of this subwidget's area to the window this widget belongs to. + */ + void repaint() noexcept override; + protected: /** A function called when the subwidget's absolute position is changed. diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp index 214d2888..f3c02a10 100644 --- a/dgl/TopLevelWidget.hpp +++ b/dgl/TopLevelWidget.hpp @@ -50,6 +50,14 @@ public: */ virtual ~TopLevelWidget(); + /** + Get the application associated with this top-level widget's window. + */ + Application& getApp() const noexcept; + + void repaint() noexcept; + void repaint(const Rectangle& rect) noexcept; + private: struct PrivateData; PrivateData* const pData; diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp index b1a590f7..3f268edd 100644 --- a/dgl/Widget.hpp +++ b/dgl/Widget.hpp @@ -169,10 +169,10 @@ public: TopLevelWidget* getTopLevelWidget() const noexcept; /** - Tell this widget's window to repaint itself. - FIXME better description, partial redraw + Request repaint of this widget's area to the window this widget belongs to. + On the raw Widget class this function does nothing. */ - void repaint() noexcept; + virtual void repaint() noexcept; protected: /** diff --git a/dgl/src/Geometry.cpp b/dgl/src/Geometry.cpp index 01af9620..1df6e9b7 100644 --- a/dgl/src/Geometry.cpp +++ b/dgl/src/Geometry.cpp @@ -246,6 +246,12 @@ bool Size::isInvalid() const noexcept return fWidth <= 0 || fHeight <= 0; } +template +Size Size::toInt() const noexcept +{ + return Size(fWidth, fHeight); +} + template Size Size::operator+(const Size& size) noexcept { diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp index b3704f6a..05c5476a 100644 --- a/dgl/src/SubWidget.cpp +++ b/dgl/src/SubWidget.cpp @@ -15,14 +15,15 @@ */ #include "SubWidgetPrivateData.hpp" +#include "../TopLevelWidget.hpp" START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- -SubWidget::SubWidget(Widget* const widgetToGroupTo) - : Widget(widgetToGroupTo), - pData(new PrivateData(this, widgetToGroupTo)) {} +SubWidget::SubWidget(Widget* const parentWidget) + : Widget(parentWidget), + pData(new PrivateData(this, parentWidget)) {} SubWidget::~SubWidget() { @@ -56,6 +57,18 @@ Point SubWidget::getAbsolutePos() const noexcept return pData->absolutePos; } +Rectangle SubWidget::getAbsoluteArea() const noexcept +{ + return Rectangle(getAbsolutePos(), getSize().toInt()); +} + +Rectangle SubWidget::getConstrainedAbsoluteArea() const noexcept +{ + return Rectangle(std::max(0, getAbsoluteX()), + std::max(0, getAbsoluteY()), + getSize()); +} + void SubWidget::setAbsoluteX(int x) noexcept { setAbsolutePos(Point(x, getAbsoluteY())); @@ -83,8 +96,15 @@ void SubWidget::setAbsolutePos(const Point& pos) noexcept pData->absolutePos = pos; onPositionChanged(ev); - // repaint the whole thing - pData->parent->repaint(); + // repaint the bounds of parent + pData->parentWidget->repaint(); +} + + +void SubWidget::repaint() noexcept +{ + if (TopLevelWidget* const topw = getTopLevelWidget()) + topw->repaint(getConstrainedAbsoluteArea()); } void SubWidget::onPositionChanged(const PositionChangedEvent&) diff --git a/dgl/src/SubWidgetPrivateData.cpp b/dgl/src/SubWidgetPrivateData.cpp index 17d1c3e0..98133fa9 100644 --- a/dgl/src/SubWidgetPrivateData.cpp +++ b/dgl/src/SubWidgetPrivateData.cpp @@ -21,17 +21,17 @@ START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- -SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const p) +SubWidget::PrivateData::PrivateData(SubWidget* const s, Widget* const pw) : self(s), - parent(p), + parentWidget(pw), absolutePos() { - parent->pData->subWidgets.push_back(self); + parentWidget->pData->subWidgets.push_back(self); } SubWidget::PrivateData::~PrivateData() { - parent->pData->subWidgets.remove(self); + parentWidget->pData->subWidgets.remove(self); } // -------------------------------------------------------------------------------------------------------------------- diff --git a/dgl/src/SubWidgetPrivateData.hpp b/dgl/src/SubWidgetPrivateData.hpp index 3f1a348b..699bcac0 100644 --- a/dgl/src/SubWidgetPrivateData.hpp +++ b/dgl/src/SubWidgetPrivateData.hpp @@ -25,10 +25,10 @@ START_NAMESPACE_DGL struct SubWidget::PrivateData { SubWidget* const self; - Widget* const parent; + Widget* const parentWidget; Point absolutePos; - explicit PrivateData(SubWidget* const s, Widget* const p); + explicit PrivateData(SubWidget* const s, Widget* const pw); ~PrivateData(); // NOTE display function is different depending on build type, must call displaySubWidgets at the end diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp index 8dda54a3..aa3bede9 100644 --- a/dgl/src/TopLevelWidget.cpp +++ b/dgl/src/TopLevelWidget.cpp @@ -29,6 +29,21 @@ TopLevelWidget::~TopLevelWidget() delete pData; } +Application& TopLevelWidget::getApp() const noexcept +{ + return pData->window.getApp(); +} + +void TopLevelWidget::repaint() noexcept +{ + pData->window.repaint(); +} + +void TopLevelWidget::repaint(const Rectangle& rect) noexcept +{ + pData->window.repaint(rect); +} + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/Widget.cpp b/dgl/src/Widget.cpp index a0cfc5c6..707a31c4 100644 --- a/dgl/src/Widget.cpp +++ b/dgl/src/Widget.cpp @@ -15,6 +15,7 @@ */ #include "WidgetPrivateData.hpp" +#include "../TopLevelWidget.hpp" START_NAMESPACE_DGL @@ -24,8 +25,8 @@ START_NAMESPACE_DGL Widget::Widget(TopLevelWidget* const topLevelWidget) : pData(new PrivateData(this, topLevelWidget)) {} -Widget::Widget(Widget* const widgetToGroupTo) - : pData(new PrivateData(this, widgetToGroupTo)) {} +Widget::Widget(Widget* const parentWidget) + : pData(new PrivateData(this, parentWidget)) {} Widget::~Widget() { @@ -83,7 +84,7 @@ void Widget::setWidth(uint width) noexcept pData->size.setWidth(width); onResize(ev); - pData->repaint(); + repaint(); } void Widget::setHeight(uint height) noexcept @@ -98,7 +99,7 @@ void Widget::setHeight(uint height) noexcept pData->size.setHeight(height); onResize(ev); - pData->repaint(); + repaint(); } void Widget::setSize(uint width, uint height) noexcept @@ -118,7 +119,7 @@ void Widget::setSize(const Size& size) noexcept pData->size = size; onResize(ev); - pData->repaint(); + repaint(); } Application& Widget::getApp() const noexcept @@ -133,8 +134,6 @@ TopLevelWidget* Widget::getTopLevelWidget() const noexcept void Widget::repaint() noexcept { - // FIXME partial repaint - // pData->topLevelWidget.repaint(); } uint Widget::getId() const noexcept diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp index 3cab134e..3a16c1e4 100644 --- a/dgl/src/WidgetPrivateData.cpp +++ b/dgl/src/WidgetPrivateData.cpp @@ -24,17 +24,17 @@ START_NAMESPACE_DGL Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) : self(s), topLevelWidget(tlw), - parentGroupWidget(nullptr), + parentWidget(nullptr), id(0), needsScaling(false), visible(true), size(0, 0), subWidgets() {} -Widget::PrivateData::PrivateData(Widget* const s, Widget* const g) +Widget::PrivateData::PrivateData(Widget* const s, Widget* const pw) : self(s), - topLevelWidget(findTopLevelWidget(g)), - parentGroupWidget(g), + topLevelWidget(findTopLevelWidget(pw)), + parentWidget(pw), id(0), needsScaling(false), visible(true), @@ -62,14 +62,6 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, } } -void Widget::PrivateData::repaint() -{ -// if (parentGroupWidget != nullptr) -// parentGroupWidget->repaint(); -// else if (topLevelWidget != nullptr) -// topLevelWidget->repaint(); -} - // ----------------------------------------------------------------------- TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) @@ -78,8 +70,8 @@ TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) // return tlw; if (w->pData->topLevelWidget != nullptr) return w->pData->topLevelWidget; - if (w->pData->parentGroupWidget != nullptr) - return findTopLevelWidget(w->pData->parentGroupWidget); + if (w->pData->parentWidget != nullptr) + return findTopLevelWidget(w->pData->parentWidget); return nullptr; } diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp index 9061548d..5d58721a 100644 --- a/dgl/src/WidgetPrivateData.hpp +++ b/dgl/src/WidgetPrivateData.hpp @@ -28,7 +28,7 @@ START_NAMESPACE_DGL struct Widget::PrivateData { Widget* const self; TopLevelWidget* const topLevelWidget; - Widget* const parentGroupWidget; + Widget* const parentWidget; uint id; bool needsScaling; bool visible; @@ -38,7 +38,7 @@ struct Widget::PrivateData { // called via TopLevelWidget explicit PrivateData(Widget* const s, TopLevelWidget* const tlw); // called via SubWidget - explicit PrivateData(Widget* const s, Widget* const pgw); + explicit PrivateData(Widget* const s, Widget* const pw); ~PrivateData(); // NOTE display function is different depending on build type, must call displaySubWidgets at the end @@ -46,8 +46,6 @@ struct Widget::PrivateData { void displaySubWidgets(uint width, uint height, double autoScaling); - void repaint(); - static TopLevelWidget* findTopLevelWidget(Widget* const w); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index 22a181d0..b45b2c1a 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -149,7 +149,7 @@ void Window::repaint(const Rectangle& rect) noexcept puglPostRedisplayRect(pData->view, prect); } -void Window::onReshape(const uint width, const uint height) +void Window::onReshape(uint, uint) { puglFallbackOnResize(pData->view); } diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 0f4f8a93..bb7bce36 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -48,7 +48,10 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) topLevelWidget(nullptr), isClosed(true), isVisible(false), - isEmbed(false) + isEmbed(false), + scaling(1.0), + autoScaling(1.0), + pendingVisibility(kPendingVisibilityNone) { init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); } @@ -63,7 +66,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transi isVisible(false), isEmbed(false), scaling(1.0), - autoScaling(1.0) + autoScaling(1.0), + pendingVisibility(kPendingVisibilityNone) { init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); @@ -83,7 +87,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), scaling(scale), - autoScaling(1.0) + autoScaling(1.0), + pendingVisibility(kPendingVisibilityNone) { init(width, height, resizable); @@ -132,6 +137,9 @@ void Window::PrivateData::init(const uint width, const uint height, const bool r puglSetHandle(view, this); puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); + puglSetViewHint(view, PUGL_DEPTH_BITS, 8); + puglSetViewHint(view, PUGL_STENCIL_BITS, 8); + // PUGL_SAMPLES ?? puglSetEventFunc(view, puglEventCallback); // #ifndef DGL_FILE_BROWSER_DISABLED // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); @@ -174,14 +182,9 @@ void Window::PrivateData::show() isClosed = false; appData->oneWindowShown(); + pendingVisibility = kPendingVisibilityShow; const PuglStatus status = puglRealize(view); DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close()); - -#ifdef DISTRHO_OS_WINDOWS - puglWin32ShowWindowCentered(view); -#else - puglShow(view); -#endif } else { @@ -197,14 +200,17 @@ void Window::PrivateData::show() void Window::PrivateData::hide() { - if (! isVisible) + if (isEmbed) { - DGL_DBG("Window hide matches current visible state, ignoring request\n"); + DGL_DBG("Window hide cannot be called when embedded\n"); return; } - if (isEmbed) + + pendingVisibility = kPendingVisibilityHide; + + if (! isVisible) { - DGL_DBG("Window hide cannot be called when embedded\n"); + DGL_DBG("Window hide matches current visible state, ignoring request\n"); return; } @@ -262,6 +268,8 @@ void Window::PrivateData::idleCallback() void Window::PrivateData::onPuglDisplay() { + DGL_DBGp("PUGL: onPuglDisplay : %p\n", topLevelWidget); + puglOnDisplayPrepare(view); #ifndef DPF_TEST_WINDOW_CPP @@ -284,6 +292,21 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) #endif } +void Window::PrivateData::onPuglCreate() +{ + DGL_DBGp("PUGL: onPuglCreate %i\n", pendingVisibility); + + if (pendingVisibility != kPendingVisibilityShow) + return; + + pendingVisibility = kPendingVisibilityNone; +#ifdef DISTRHO_OS_WINDOWS + puglWin32ShowWindowCentered(view); +#else + puglShow(view); +#endif +} + void Window::PrivateData::onPuglClose() { DGL_DBG("PUGL: onClose\n"); @@ -328,6 +351,10 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu pData->onPuglClose(); break; + case PUGL_CREATE: + pData->onPuglCreate(); + break; + // TODO default: break; diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index e11c69fd..76a405b4 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -63,6 +63,13 @@ struct Window::PrivateData : IdleCallback { /** Automatic scaling to apply on widgets, implemented internally. */ double autoScaling; + /** Pending state of visility, used for the action to be triggered during Pugl create events. */ + enum PendingVisibility { + kPendingVisibilityNone, + kPendingVisibilityShow, + kPendingVisibilityHide + } pendingVisibility; + /** Constructor for a regular, standalone window. */ explicit PrivateData(Application& app, Window* self); @@ -98,6 +105,7 @@ struct Window::PrivateData : IdleCallback { // pugl events void onPuglDisplay(); void onPuglReshape(int width, int height); + void onPuglCreate(); void onPuglClose(); // Pugl event handling entry point diff --git a/tests/Demo.cpp b/tests/Demo.cpp index 74cdf622..0241e03e 100644 --- a/tests/Demo.cpp +++ b/tests/Demo.cpp @@ -37,12 +37,12 @@ #include "dgl/StandaloneWindow.hpp" #include "widgets/ExampleColorWidget.hpp" +#include "widgets/ExampleRectanglesWidget.hpp" +#include "widgets/ExampleShapesWidget.hpp" START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- - -// ------------------------------------------------------ // Left side tab-like widget class LeftSideWidget : public SubWidget @@ -225,8 +225,8 @@ private: #endif }; -// ------------------------------------------------------ -// Our Demo Window +// -------------------------------------------------------------------------------------------------------------------- +// Main Demo Window, having a left-side tab-like widget and main area for current widget class DemoWindow : public StandaloneWindow, public LeftSideWidget::Callback @@ -234,23 +234,27 @@ class DemoWindow : public StandaloneWindow, static const int kSidebarWidth = 81; public: + static constexpr const char* const kExampleWidgetName = "Demo"; + DemoWindow(Application& app) : StandaloneWindow(app), wColor(this), + wRects(this), + wShapes(this), wLeft(this, this), curWidget(nullptr) { wColor.hide(); // wImages.hide(); -// wRects.hide(); -// wShapes.hide(); + wRects.hide(); + wShapes.hide(); // wText.hide(); // //wPerf.hide(); wColor.setAbsoluteX(kSidebarWidth); // wImages.setAbsoluteX(kSidebarWidth); -// wRects.setAbsoluteX(kSidebarWidth); -// wShapes.setAbsoluteX(kSidebarWidth); + wRects.setAbsoluteX(kSidebarWidth); + wShapes.setAbsoluteX(kSidebarWidth); // wText.setAbsoluteX(kSidebarWidth); wLeft.setAbsolutePos(2, 2); // wPerf.setAbsoluteY(5); @@ -265,10 +269,7 @@ protected: void curPageChanged(int curPage) override { if (curWidget != nullptr) - { curWidget->hide(); - curWidget = nullptr; - } switch (curPage) { @@ -278,15 +279,18 @@ protected: // case 1: // curWidget = &wImages; // break; -// case 2: -// curWidget = &wRects; -// break; -// case 3: -// curWidget = &wShapes; -// break; + case 2: + curWidget = &wRects; + break; + case 3: + curWidget = &wShapes; + break; // case 4: // curWidget = &wText; // break; + default: + curWidget = nullptr; + break; } if (curWidget != nullptr) @@ -312,8 +316,8 @@ protected: Size size(width-kSidebarWidth, height); wColor.setSize(size); // wImages.setSize(size); -// wRects.setSize(size); -// wShapes.setSize(size); + wRects.setSize(size); + wShapes.setSize(size); // wText.setSize(size); wLeft.setSize(kSidebarWidth-4, height-4); @@ -324,10 +328,10 @@ protected: } private: - ExampleColorWidget wColor; + ExampleColorSubWidget wColor; // ExampleImagesWidget wImages; -// ExampleRectanglesWidget wRects; -// ExampleShapesWidget wShapes; + ExampleRectanglesSubWidget wRects; + ExampleShapesSubWidget wShapes; // ExampleTextWidget wText; LeftSideWidget wLeft; //ResizeHandle wRezHandle; @@ -336,19 +340,71 @@ private: Widget* curWidget; }; +// -------------------------------------------------------------------------------------------------------------------- +// Testing StandaloneWindow, for custom local widget drawing code + +class TestingWidgetStandaloneWindow : public StandaloneWindow +{ +public: + static constexpr const char* kExampleWidgetName = "Testing"; + + TestingWidgetStandaloneWindow(Application& app) + : StandaloneWindow(app) + { + } + +protected: + void onDisplay() override + { + glColor3f(0.5f, 0.3f, 0.9f); + Rectangle(0, 0, 500, 500).draw(); + // getWidth(), getHeight() + } +}; + +// -------------------------------------------------------------------------------------------------------------------- +// Special handy function that runs a StandaloneWindow inside the function scope + +template +void createAndShowExampleWidgetStandaloneWindow(Application& app) +{ + ExampleWidgetStandaloneWindow swin(app); + swin.setSize(600, 500); + swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); + swin.show(); + app.exec(); +} + // -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DGL -int main() +int main(int argc, char* argv[]) { USE_NAMESPACE_DGL; + using DGL_NAMESPACE::Window; Application app; - DemoWindow win(app); - win.show(); - app.exec(); + if (argc > 1) + { + // TODO images, text + + /**/ if (std::strcmp(argv[1], "color") == 0) + createAndShowExampleWidgetStandaloneWindow(app); + else if (std::strcmp(argv[1], "rectangles") == 0) + createAndShowExampleWidgetStandaloneWindow(app); + else if (std::strcmp(argv[1], "shapes") == 0) + createAndShowExampleWidgetStandaloneWindow(app); + else if (std::strcmp(argv[1], "testing") == 0) + createAndShowExampleWidgetStandaloneWindow(app); + else + d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); + } + else + { + createAndShowExampleWidgetStandaloneWindow(app); + } return 0; } diff --git a/tests/Makefile b/tests/Makefile index 93c6e6c5..71ab42e7 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -93,6 +93,11 @@ clean: @echo "Compiling $< (OpenGL)" $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_OPENGL -c -o $@ +../build/tests/Testing.cpp.o: Testing.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)" @@ -118,6 +123,10 @@ clean: @echo "Linking Demo" $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ +../build/tests/Testing: ../build/tests/Testing.cpp.o + @echo "Linking Testing" + $(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 $@ diff --git a/tests/tests.hpp b/tests/tests.hpp index 37bdd6f1..466141f7 100644 --- a/tests/tests.hpp +++ b/tests/tests.hpp @@ -31,11 +31,13 @@ START_NAMESPACE_DGL class ApplicationQuitter : public Thread { Application& app; + const int numSecondsToWait; public: - ApplicationQuitter(Application& a) + ApplicationQuitter(Application& a, const int s = 2) : Thread("ApplicationQuitter"), - app(a) + app(a), + numSecondsToWait(s) { startThread(); } @@ -43,7 +45,7 @@ public: private: void run() override { - d_sleep(2); + d_sleep(numSecondsToWait); app.quit(); } }; diff --git a/tests/widgets/ExampleColorWidget.hpp b/tests/widgets/ExampleColorWidget.hpp index ab4f22e8..07432212 100644 --- a/tests/widgets/ExampleColorWidget.hpp +++ b/tests/widgets/ExampleColorWidget.hpp @@ -21,13 +21,15 @@ // DGL Stuff #include "../../dgl/SubWidget.hpp" +#include "../../dgl/TopLevelWidget.hpp" START_NAMESPACE_DGL // ------------------------------------------------------ // our widget -class ExampleColorWidget : public SubWidget, +template +class ExampleColorWidget : public BaseWidget, public IdleCallback { char cur; @@ -37,13 +39,32 @@ class ExampleColorWidget : public SubWidget, Rectangle bgFull, bgSmall; public: - ExampleColorWidget(TopLevelWidget* const topWidget) - : SubWidget(topWidget), + static constexpr const char* kExampleWidgetName = "Color"; + + explicit ExampleColorWidget(Widget* const parent) + : BaseWidget(parent), cur('r'), reverse(false), r(0), g(99), b(32) { - setSize(300, 300); + init(); + } + + explicit ExampleColorWidget(Window& windowToMapTo) + : BaseWidget(windowToMapTo) + { + init(); + } + + explicit ExampleColorWidget(Application& app) + : BaseWidget(app) + { + init(); + } + + void init() + { + BaseWidget::setSize(300, 300); // topWidget->getApp().addIdleCallback(this); } @@ -99,7 +120,7 @@ protected: break; } - repaint(); + BaseWidget::repaint(); } void onDisplay() override @@ -126,6 +147,10 @@ protected: } }; +typedef ExampleColorWidget ExampleColorSubWidget; +typedef ExampleColorWidget ExampleColorTopLevelWidget; +typedef ExampleColorWidget ExampleColorStandaloneWindow; + // ------------------------------------------------------ END_NAMESPACE_DGL diff --git a/tests/widgets/ExampleRectanglesWidget.hpp b/tests/widgets/ExampleRectanglesWidget.hpp index 8f705cad..d8b2960a 100644 --- a/tests/widgets/ExampleRectanglesWidget.hpp +++ b/tests/widgets/ExampleRectanglesWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -20,40 +20,55 @@ // ------------------------------------------------------ // DGL Stuff -#include "Widget.hpp" -#include "Window.hpp" +#include "../../dgl/SubWidget.hpp" +#include "../../dgl/TopLevelWidget.hpp" + +START_NAMESPACE_DGL // ------------------------------------------------------ // our widget -class ExampleRectanglesWidget : public Widget +template +class ExampleRectanglesWidget : public BaseWidget { + bool clicked[9]; + public: - ExampleRectanglesWidget(Window& parent) - : Widget(parent) + static constexpr const char* const kExampleWidgetName = "Rectangles"; + + explicit ExampleRectanglesWidget(Widget* const parentWidget) + : BaseWidget(parentWidget) { - setSize(300, 300); + init(); + } - for (int i=0; i<9; ++i) - fClicked[i] = false; + explicit ExampleRectanglesWidget(Window& windowToMapTo) + : BaseWidget(windowToMapTo) + { + init(); } - ExampleRectanglesWidget(Widget* groupWidget) - : Widget(groupWidget) + explicit ExampleRectanglesWidget(Application& app) + : BaseWidget(app) { - setSize(300, 300); + init(); + } + + void init() + { + this->setSize(300, 300); for (int i=0; i<9; ++i) - fClicked[i] = false; + clicked[i] = false; } protected: void onDisplay() override { - const int width = getWidth(); - const int height = getHeight(); + const uint width = this->getWidth(); + const uint height = this->getHeight(); - Rectangle r; + Rectangle r; r.setWidth(width/3 - 6); r.setHeight(height/3 - 6); @@ -66,7 +81,7 @@ protected: // 1st r.setY(3); - if (fClicked[0+i]) + if (clicked[0+i]) glColor3f(0.8f, 0.5f, 0.3f); else glColor3f(0.3f, 0.5f, 0.8f); @@ -76,7 +91,7 @@ protected: // 2nd r.setY(3 + height/3); - if (fClicked[3+i]) + if (clicked[3+i]) glColor3f(0.8f, 0.5f, 0.3f); else glColor3f(0.3f, 0.5f, 0.8f); @@ -86,7 +101,7 @@ protected: // 3rd r.setY(3 + height*2/3); - if (fClicked[6+i]) + if (clicked[6+i]) glColor3f(0.8f, 0.5f, 0.3f); else glColor3f(0.3f, 0.5f, 0.8f); @@ -100,10 +115,10 @@ protected: if (ev.button != 1 || ! ev.press) return false; - const int width = getWidth(); - const int height = getHeight(); + const uint width = this->getWidth(); + const uint height = this->getHeight(); - Rectangle r; + Rectangle r; r.setWidth(width/3 - 6); r.setHeight(height/3 - 6); @@ -118,8 +133,8 @@ protected: if (r.contains(ev.pos)) { - fClicked[0+i] = !fClicked[0+i]; - repaint(); + clicked[0+i] = !clicked[0+i]; + this->repaint(); break; } @@ -128,8 +143,8 @@ protected: if (r.contains(ev.pos)) { - fClicked[3+i] = !fClicked[3+i]; - repaint(); + clicked[3+i] = !clicked[3+i]; + this->repaint(); break; } @@ -138,19 +153,22 @@ protected: if (r.contains(ev.pos)) { - fClicked[6+i] = !fClicked[6+i]; - repaint(); + clicked[6+i] = !clicked[6+i]; + this->repaint(); break; } } return true; } - -private: - bool fClicked[9]; }; +typedef ExampleRectanglesWidget ExampleRectanglesSubWidget; +typedef ExampleRectanglesWidget ExampleRectanglesTopLevelWidget; +typedef ExampleRectanglesWidget ExampleRectanglesStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_RECTANGLES_WIDGET_HPP_INCLUDED diff --git a/tests/widgets/ExampleShapesWidget.hpp b/tests/widgets/ExampleShapesWidget.hpp index 967bc439..c0298e07 100644 --- a/tests/widgets/ExampleShapesWidget.hpp +++ b/tests/widgets/ExampleShapesWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 Filipe Coelho + * Copyright (C) 2012-2021 Filipe Coelho * * 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 @@ -20,25 +20,41 @@ // ------------------------------------------------------ // DGL Stuff -#include "Widget.hpp" -#include "Window.hpp" +#include "../../dgl/SubWidget.hpp" +#include "../../dgl/TopLevelWidget.hpp" + +START_NAMESPACE_DGL // ------------------------------------------------------ // our widget -class ExampleShapesWidget : public Widget +template +class ExampleShapesWidget : public BaseWidget { + Rectangle bg; + Rectangle rect; + Triangle tri; + Circle cir; + public: - ExampleShapesWidget(Window& parent) - : Widget(parent) + static constexpr const char* const kExampleWidgetName = "Shapes"; + + explicit ExampleShapesWidget(Widget* const parentWidget) + : BaseWidget(parentWidget) { - setSize(300, 300); + this->setSize(300, 300); } - ExampleShapesWidget(Widget* groupWidget) - : Widget(groupWidget) + explicit ExampleShapesWidget(Window& windowToMapTo) + : BaseWidget(windowToMapTo) { - setSize(300, 300); + this->setSize(300, 300); + } + + explicit ExampleShapesWidget(Application& app) + : BaseWidget(app) + { + this->setSize(300, 300); } protected: @@ -95,14 +111,14 @@ protected: // circle cir = Circle(width/2, height*2/3, height/6, 300); } - -private: - Rectangle bg; - Rectangle rect; - Triangle tri; - Circle cir; }; +typedef ExampleShapesWidget ExampleShapesSubWidget; +typedef ExampleShapesWidget ExampleShapesTopLevelWidget; +typedef ExampleShapesWidget ExampleShapesStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_SHAPES_WIDGET_HPP_INCLUDED