diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp index 05c5476a..b694dd33 100644 --- a/dgl/src/SubWidget.cpp +++ b/dgl/src/SubWidget.cpp @@ -100,9 +100,11 @@ void SubWidget::setAbsolutePos(const Point& pos) noexcept pData->parentWidget->repaint(); } - void SubWidget::repaint() noexcept { + if (! isVisible()) + return; + if (TopLevelWidget* const topw = getTopLevelWidget()) topw->repaint(getConstrainedAbsoluteArea()); } diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp index 4a1cd1ab..c8fa5f28 100644 --- a/dgl/src/TopLevelWidgetPrivateData.cpp +++ b/dgl/src/TopLevelWidgetPrivateData.cpp @@ -21,12 +21,6 @@ START_NAMESPACE_DGL -#define FOR_EACH_WIDGET(it) \ - for (std::list::iterator it = widgets.begin(); it != widgets.end(); ++it) - -#define FOR_EACH_WIDGET_INV(rit) \ - for (std::list::reverse_iterator rit = widgets.rbegin(); rit != widgets.rend(); ++rit) - // ----------------------------------------------------------------------- TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) @@ -45,13 +39,10 @@ TopLevelWidget::PrivateData::~PrivateData() void TopLevelWidget::PrivateData::display() { - printf("TopLevelWidget::PrivateData::display INIT\n"); - const Size size(window.getSize()); const uint width = size.getWidth(); const uint height = size.getHeight(); const double autoScaling = window.pData->autoScaling; - printf("TopLevelWidget::PrivateData::display %i %i\n", width, height); // full viewport size glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); @@ -63,6 +54,26 @@ void TopLevelWidget::PrivateData::display() selfw->pData->displaySubWidgets(width, height, autoScaling); } +void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev) +{ + Events::MouseEvent rev = ev; + + const double autoScaling = window.pData->autoScaling; + + if (autoScaling != 1.0) + { + rev.pos.setX(ev.pos.getX() / autoScaling); + rev.pos.setY(ev.pos.getY() / autoScaling); + } + + // give top-level widget chance to catch this event first + if (self->onMouse(ev)) + return; + + // propagate event to all subwidgets recursively + selfw->pData->giveMouseEventForSubWidgets(rev); +} + // ----------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/dgl/src/TopLevelWidgetPrivateData.hpp b/dgl/src/TopLevelWidgetPrivateData.hpp index 5e3b1d89..4e9f597e 100644 --- a/dgl/src/TopLevelWidgetPrivateData.hpp +++ b/dgl/src/TopLevelWidgetPrivateData.hpp @@ -33,6 +33,7 @@ struct TopLevelWidget::PrivateData { explicit PrivateData(TopLevelWidget* const s, Window& w); ~PrivateData(); void display(); + void mouseEvent(const Events::MouseEvent& ev); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) }; diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp index 3a16c1e4..f163d47a 100644 --- a/dgl/src/WidgetPrivateData.cpp +++ b/dgl/src/WidgetPrivateData.cpp @@ -15,10 +15,17 @@ */ #include "WidgetPrivateData.hpp" +#include "../SubWidget.hpp" #include "../TopLevelWidget.hpp" START_NAMESPACE_DGL +#define FOR_EACH_SUBWIDGET(it) \ + for (std::list::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) + +#define FOR_EACH_SUBWIDGET_INV(rit) \ + for (std::list::reverse_iterator rit = subWidgets.rbegin(); rit != subWidgets.rend(); ++rit) + // ----------------------------------------------------------------------- Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) @@ -48,17 +55,40 @@ Widget::PrivateData::~PrivateData() void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, const double scaling) { - printf("Widget::PrivateData::displaySubWidgets INIT | %lu\n", subWidgets.size()); - if (subWidgets.size() == 0) return; for (std::list::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) { SubWidget* const subwidget(*it); - printf("Widget::PrivateData::displaySubWidgets %i %i -> %p\n", width, height, subwidget); - subwidget->pData->display(width, height, scaling); + if (subwidget->isVisible()) + subwidget->pData->display(width, height, scaling); + } +} + +void Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev) +{ + if (! visible) + return; + if (subWidgets.size() == 0) + return; + + const double x = ev.pos.getX(); + const double y = ev.pos.getY(); + + FOR_EACH_SUBWIDGET_INV(rit) + { + SubWidget* const widget(*rit); + + if (! widget->isVisible()) + continue; + + ev.pos = Point(x - widget->getAbsoluteX(), + y - widget->getAbsoluteY()); + + if (widget->onMouse(ev)) + return; } } @@ -66,8 +96,6 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height, TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) { -// if (TopLevelWidget* const tlw = dynamic_cast(w)) -// return tlw; if (w->pData->topLevelWidget != nullptr) return w->pData->topLevelWidget; if (w->pData->parentWidget != nullptr) diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp index 5d58721a..fa2e6f87 100644 --- a/dgl/src/WidgetPrivateData.hpp +++ b/dgl/src/WidgetPrivateData.hpp @@ -41,10 +41,8 @@ struct Widget::PrivateData { explicit PrivateData(Widget* const s, Widget* const pw); ~PrivateData(); - // NOTE display function is different depending on build type, must call displaySubWidgets at the end -// void display(uint width, uint height, double autoScaling, bool renderingSubWidget); - void displaySubWidgets(uint width, uint height, double autoScaling); + void giveMouseEventForSubWidgets(Events::MouseEvent& ev); static TopLevelWidget* findTopLevelWidget(Widget* const w); diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index bb7bce36..560d4c81 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -323,6 +323,19 @@ void Window::PrivateData::onPuglClose() close(); } +void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev) +{ + DGL_DBGp("PUGL: onMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); + +// if (fModal.childFocus != nullptr) +// return fModal.childFocus->focus(); + +#ifndef DPF_TEST_WINDOW_CPP + if (topLevelWidget != nullptr) + topLevelWidget->pData->mouseEvent(ev); +#endif +} + static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) @@ -355,6 +368,20 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu pData->onPuglCreate(); break; + case PUGL_BUTTON_PRESS: ///< Mouse button pressed, a #PuglEventButton + case PUGL_BUTTON_RELEASE: ///< Mouse button released, a #PuglEventButton + { + Events::MouseEvent ev; + ev.mod = event->button.state; + ev.flags = event->button.flags; + ev.time = static_cast(event->button.time * 1000.0 + 0.5); + ev.button = event->button.button; + ev.press = event->type == PUGL_BUTTON_PRESS; + ev.pos = Point(event->button.x, event->button.y); + pData->onPuglMouse(ev); + break; + } + // TODO default: break; diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index 76a405b4..b87a2718 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -18,6 +18,7 @@ #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED #include "../Window.hpp" +#include "../Events.hpp" #include "ApplicationPrivateData.hpp" #include "pugl.hpp" @@ -107,6 +108,7 @@ struct Window::PrivateData : IdleCallback { void onPuglReshape(int width, int height); void onPuglCreate(); void onPuglClose(); + void onPuglMouse(const Events::MouseEvent& ev); // Pugl event handling entry point static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); diff --git a/tests/Demo.cpp b/tests/Demo.cpp index 0241e03e..99062ed2 100644 --- a/tests/Demo.cpp +++ b/tests/Demo.cpp @@ -80,7 +80,6 @@ protected: void onDisplay() override { const int iconSize = bgIcon.getWidth(); - printf("LEFT SIDE WIDGET onDisplay %i\n", iconSize); glColor3f(0.027f, 0.027f, 0.027f); Rectangle(0, 0, getSize()).draw(); @@ -201,8 +200,8 @@ protected: void onResize(const ResizeEvent& ev) override { - const int width = ev.size.getWidth(); - const int height = ev.size.getHeight(); + const uint width = ev.size.getWidth(); + const uint height = ev.size.getHeight(); bgIcon.setWidth(width-4); bgIcon.setHeight(width-4); @@ -299,11 +298,6 @@ protected: void onDisplay() override { - static int counter = 0; - printf("print %i\n", ++counter); - - glColor3f(0.471f, 0.971f, 0.171f); - Rectangle(0, 0, getSize()).draw(); } void onReshape(uint width, uint height) override @@ -340,28 +334,6 @@ 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 @@ -396,8 +368,6 @@ int main(int argc, char* argv[]) 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"); } diff --git a/tests/widgets/ExampleRectanglesWidget.hpp b/tests/widgets/ExampleRectanglesWidget.hpp index d8b2960a..425dade2 100644 --- a/tests/widgets/ExampleRectanglesWidget.hpp +++ b/tests/widgets/ExampleRectanglesWidget.hpp @@ -56,7 +56,7 @@ public: void init() { - this->setSize(300, 300); + BaseWidget::setSize(300, 300); for (int i=0; i<9; ++i) clicked[i] = false; @@ -65,8 +65,8 @@ public: protected: void onDisplay() override { - const uint width = this->getWidth(); - const uint height = this->getHeight(); + const uint width = BaseWidget::getWidth(); + const uint height = BaseWidget::getHeight(); Rectangle r; @@ -115,8 +115,8 @@ protected: if (ev.button != 1 || ! ev.press) return false; - const uint width = this->getWidth(); - const uint height = this->getHeight(); + const uint width = BaseWidget::getWidth(); + const uint height = BaseWidget::getHeight(); Rectangle r; @@ -134,7 +134,7 @@ protected: if (r.contains(ev.pos)) { clicked[0+i] = !clicked[0+i]; - this->repaint(); + BaseWidget::repaint(); break; } @@ -144,7 +144,7 @@ protected: if (r.contains(ev.pos)) { clicked[3+i] = !clicked[3+i]; - this->repaint(); + BaseWidget::repaint(); break; } @@ -154,7 +154,7 @@ protected: if (r.contains(ev.pos)) { clicked[6+i] = !clicked[6+i]; - this->repaint(); + BaseWidget::repaint(); break; } }