DPF

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

commit 467f9199fcb73e54d94998f9d0cfb8230a39bff4
parent ab5f3d3b011096ee8966493828bcc609377d905b
Author: falkTX <falktx@falktx.com>
Date:   Sat,  8 May 2021 22:47:11 +0100

Add SubWidget area calls, rename some vars, cleanup repaint

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdgl/Geometry.hpp | 2++
Mdgl/StandaloneWindow.hpp | 1+
Mdgl/SubWidget.hpp | 20+++++++++++++++++++-
Mdgl/TopLevelWidget.hpp | 8++++++++
Mdgl/Widget.hpp | 6+++---
Mdgl/src/Geometry.cpp | 6++++++
Mdgl/src/SubWidget.cpp | 30+++++++++++++++++++++++++-----
Mdgl/src/SubWidgetPrivateData.cpp | 8++++----
Mdgl/src/SubWidgetPrivateData.hpp | 4++--
Mdgl/src/TopLevelWidget.cpp | 15+++++++++++++++
Mdgl/src/Widget.cpp | 13++++++-------
Mdgl/src/WidgetPrivateData.cpp | 20++++++--------------
Mdgl/src/WidgetPrivateData.hpp | 6++----
Mdgl/src/Window.cpp | 2+-
Mdgl/src/WindowPrivateData.cpp | 53++++++++++++++++++++++++++++++++++++++++-------------
Mdgl/src/WindowPrivateData.hpp | 8++++++++
Mtests/Demo.cpp | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mtests/Makefile | 9+++++++++
Mtests/tests.hpp | 8+++++---
Mtests/widgets/ExampleColorWidget.hpp | 35++++++++++++++++++++++++++++++-----
Mtests/widgets/ExampleRectanglesWidget.hpp | 80++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mtests/widgets/ExampleShapesWidget.hpp | 48++++++++++++++++++++++++++++++++----------------
22 files changed, 355 insertions(+), 135 deletions(-)

diff --git a/dgl/Geometry.hpp b/dgl/Geometry.hpp @@ -210,6 +210,8 @@ public: */ bool isInvalid() const noexcept; + Size<int> toInt() const noexcept; + Size<T> operator+(const Size<T>& size) noexcept; Size<T> operator-(const Size<T>& size) noexcept; Size<T>& operator=(const Size<T>& size) noexcept; diff --git 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<uint> 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 @@ -42,7 +42,7 @@ public: /** Constructor. */ - explicit SubWidget(Widget* widgetToGroupTo); + explicit SubWidget(Widget* parentWidget); /** Destructor. @@ -77,6 +77,19 @@ public: Point<int> getAbsolutePos() const noexcept; /** + Get absolute area of this subwidget. + This is the same as `Rectangle<int>(getAbsolutePos(), getSize());` + @see getConstrainedAbsoluteArea() + */ + Rectangle<int> getAbsoluteArea() const noexcept; + + /** + Get absolute area of this subwidget, with special consideration for not allowing negative values. + @see getAbsoluteArea() + */ + Rectangle<uint> getConstrainedAbsoluteArea() const noexcept; + + /** Set absolute X. */ void setAbsoluteX(int x) noexcept; @@ -96,6 +109,11 @@ public: */ void setAbsolutePos(const Point<int>& 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 @@ -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<uint>& rect) noexcept; + private: struct PrivateData; PrivateData* const pData; diff --git 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 @@ -247,6 +247,12 @@ bool Size<T>::isInvalid() const noexcept } template<typename T> +Size<int> Size<T>::toInt() const noexcept +{ + return Size<int>(fWidth, fHeight); +} + +template<typename T> Size<T> Size<T>::operator+(const Size<T>& size) noexcept { return Size<T>(fWidth+size.fWidth, fHeight+size.fHeight); diff --git 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<int> SubWidget::getAbsolutePos() const noexcept return pData->absolutePos; } +Rectangle<int> SubWidget::getAbsoluteArea() const noexcept +{ + return Rectangle<int>(getAbsolutePos(), getSize().toInt()); +} + +Rectangle<uint> SubWidget::getConstrainedAbsoluteArea() const noexcept +{ + return Rectangle<uint>(std::max(0, getAbsoluteX()), + std::max(0, getAbsoluteY()), + getSize()); +} + void SubWidget::setAbsoluteX(int x) noexcept { setAbsolutePos(Point<int>(x, getAbsoluteY())); @@ -83,8 +96,15 @@ void SubWidget::setAbsolutePos(const Point<int>& 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 @@ -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 @@ -25,10 +25,10 @@ START_NAMESPACE_DGL struct SubWidget::PrivateData { SubWidget* const self; - Widget* const parent; + Widget* const parentWidget; Point<int> 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 @@ -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<uint>& rect) noexcept +{ + pData->window.repaint(rect); +} + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git 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<uint>& 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 @@ -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 @@ -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 @@ -149,7 +149,7 @@ void Window::repaint(const Rectangle<uint>& 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 @@ -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 @@ -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 @@ -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<uint> 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; @@ -337,18 +341,70 @@ private: }; // -------------------------------------------------------------------------------------------------------------------- +// 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<uint>(0, 0, 500, 500).draw(); + // getWidth(), getHeight() + } +}; + +// -------------------------------------------------------------------------------------------------------------------- +// Special handy function that runs a StandaloneWindow inside the function scope + +template <class ExampleWidgetStandaloneWindow> +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<ExampleColorStandaloneWindow>(app); + else if (std::strcmp(argv[1], "rectangles") == 0) + createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); + else if (std::strcmp(argv[1], "shapes") == 0) + createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); + else if (std::strcmp(argv[1], "testing") == 0) + createAndShowExampleWidgetStandaloneWindow<TestingWidgetStandaloneWindow>(app); + else + d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); + } + else + { + createAndShowExampleWidgetStandaloneWindow<DemoWindow>(app); + } return 0; } diff --git 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 @@ -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 @@ -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 BaseWidget> +class ExampleColorWidget : public BaseWidget, public IdleCallback { char cur; @@ -37,13 +39,32 @@ class ExampleColorWidget : public SubWidget, Rectangle<uint> 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<SubWidget> ExampleColorSubWidget; +typedef ExampleColorWidget<TopLevelWidget> ExampleColorTopLevelWidget; +typedef ExampleColorWidget<StandaloneWindow> ExampleColorStandaloneWindow; + // ------------------------------------------------------ END_NAMESPACE_DGL diff --git a/tests/widgets/ExampleRectanglesWidget.hpp b/tests/widgets/ExampleRectanglesWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 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 @@ -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 BaseWidget> +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<int> r; + Rectangle<double> 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<int> r; + Rectangle<double> 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<SubWidget> ExampleRectanglesSubWidget; +typedef ExampleRectanglesWidget<TopLevelWidget> ExampleRectanglesTopLevelWidget; +typedef ExampleRectanglesWidget<StandaloneWindow> ExampleRectanglesStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_RECTANGLES_WIDGET_HPP_INCLUDED diff --git a/tests/widgets/ExampleShapesWidget.hpp b/tests/widgets/ExampleShapesWidget.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2015 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 @@ -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 BaseWidget> +class ExampleShapesWidget : public BaseWidget { + Rectangle<int> bg; + Rectangle<int> rect; + Triangle<int> tri; + Circle<int> 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<int>(width/2, height*2/3, height/6, 300); } - -private: - Rectangle<int> bg; - Rectangle<int> rect; - Triangle<int> tri; - Circle<int> cir; }; +typedef ExampleShapesWidget<SubWidget> ExampleShapesSubWidget; +typedef ExampleShapesWidget<TopLevelWidget> ExampleShapesTopLevelWidget; +typedef ExampleShapesWidget<StandaloneWindow> ExampleShapesStandaloneWindow; + // ------------------------------------------------------ +END_NAMESPACE_DGL + #endif // EXAMPLE_SHAPES_WIDGET_HPP_INCLUDED