Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -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; | |||
| @@ -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. | |||
| @@ -42,7 +42,7 @@ public: | |||
| /** | |||
| Constructor. | |||
| */ | |||
| explicit SubWidget(Widget* widgetToGroupTo); | |||
| explicit SubWidget(Widget* parentWidget); | |||
| /** | |||
| Destructor. | |||
| @@ -76,6 +76,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. | |||
| */ | |||
| @@ -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. | |||
| @@ -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; | |||
| @@ -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: | |||
| /** | |||
| @@ -246,6 +246,12 @@ bool Size<T>::isInvalid() const noexcept | |||
| return fWidth <= 0 || fHeight <= 0; | |||
| } | |||
| 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 | |||
| { | |||
| @@ -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&) | |||
| @@ -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); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| @@ -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) | |||
| @@ -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); | |||
| } | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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<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; | |||
| } | |||
| @@ -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 $@ | |||
| @@ -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(); | |||
| } | |||
| }; | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||