Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -100,9 +100,11 @@ void SubWidget::setAbsolutePos(const Point<int>& pos) noexcept | |||||
| pData->parentWidget->repaint(); | pData->parentWidget->repaint(); | ||||
| } | } | ||||
| void SubWidget::repaint() noexcept | void SubWidget::repaint() noexcept | ||||
| { | { | ||||
| if (! isVisible()) | |||||
| return; | |||||
| if (TopLevelWidget* const topw = getTopLevelWidget()) | if (TopLevelWidget* const topw = getTopLevelWidget()) | ||||
| topw->repaint(getConstrainedAbsoluteArea()); | topw->repaint(getConstrainedAbsoluteArea()); | ||||
| } | } | ||||
| @@ -21,12 +21,6 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #define FOR_EACH_WIDGET(it) \ | |||||
| for (std::list<Widget*>::iterator it = widgets.begin(); it != widgets.end(); ++it) | |||||
| #define FOR_EACH_WIDGET_INV(rit) \ | |||||
| for (std::list<Widget*>::reverse_iterator rit = widgets.rbegin(); rit != widgets.rend(); ++rit) | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) | TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) | ||||
| @@ -45,13 +39,10 @@ TopLevelWidget::PrivateData::~PrivateData() | |||||
| void TopLevelWidget::PrivateData::display() | void TopLevelWidget::PrivateData::display() | ||||
| { | { | ||||
| printf("TopLevelWidget::PrivateData::display INIT\n"); | |||||
| const Size<uint> size(window.getSize()); | const Size<uint> size(window.getSize()); | ||||
| const uint width = size.getWidth(); | const uint width = size.getWidth(); | ||||
| const uint height = size.getHeight(); | const uint height = size.getHeight(); | ||||
| const double autoScaling = window.pData->autoScaling; | const double autoScaling = window.pData->autoScaling; | ||||
| printf("TopLevelWidget::PrivateData::display %i %i\n", width, height); | |||||
| // full viewport size | // full viewport size | ||||
| glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); | glViewport(0, -(height * autoScaling - height), width * autoScaling, height * autoScaling); | ||||
| @@ -63,6 +54,26 @@ void TopLevelWidget::PrivateData::display() | |||||
| selfw->pData->displaySubWidgets(width, height, autoScaling); | 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 | END_NAMESPACE_DGL | ||||
| @@ -33,6 +33,7 @@ struct TopLevelWidget::PrivateData { | |||||
| explicit PrivateData(TopLevelWidget* const s, Window& w); | explicit PrivateData(TopLevelWidget* const s, Window& w); | ||||
| ~PrivateData(); | ~PrivateData(); | ||||
| void display(); | void display(); | ||||
| void mouseEvent(const Events::MouseEvent& ev); | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | ||||
| }; | }; | ||||
| @@ -15,10 +15,17 @@ | |||||
| */ | */ | ||||
| #include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
| #include "../SubWidget.hpp" | |||||
| #include "../TopLevelWidget.hpp" | #include "../TopLevelWidget.hpp" | ||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #define FOR_EACH_SUBWIDGET(it) \ | |||||
| for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | |||||
| #define FOR_EACH_SUBWIDGET_INV(rit) \ | |||||
| for (std::list<SubWidget*>::reverse_iterator rit = subWidgets.rbegin(); rit != subWidgets.rend(); ++rit) | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| Widget::PrivateData::PrivateData(Widget* const s, TopLevelWidget* const tlw) | 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) | 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) | if (subWidgets.size() == 0) | ||||
| return; | return; | ||||
| for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | for (std::list<SubWidget*>::iterator it = subWidgets.begin(); it != subWidgets.end(); ++it) | ||||
| { | { | ||||
| SubWidget* const subwidget(*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<double>(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) | TopLevelWidget* Widget::PrivateData::findTopLevelWidget(Widget* const w) | ||||
| { | { | ||||
| // if (TopLevelWidget* const tlw = dynamic_cast<TopLevelWidget*>(w)) | |||||
| // return tlw; | |||||
| if (w->pData->topLevelWidget != nullptr) | if (w->pData->topLevelWidget != nullptr) | ||||
| return w->pData->topLevelWidget; | return w->pData->topLevelWidget; | ||||
| if (w->pData->parentWidget != nullptr) | if (w->pData->parentWidget != nullptr) | ||||
| @@ -41,10 +41,8 @@ struct Widget::PrivateData { | |||||
| explicit PrivateData(Widget* const s, Widget* const pw); | explicit PrivateData(Widget* const s, Widget* const pw); | ||||
| ~PrivateData(); | ~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 displaySubWidgets(uint width, uint height, double autoScaling); | ||||
| void giveMouseEventForSubWidgets(Events::MouseEvent& ev); | |||||
| static TopLevelWidget* findTopLevelWidget(Widget* const w); | static TopLevelWidget* findTopLevelWidget(Widget* const w); | ||||
| @@ -323,6 +323,19 @@ void Window::PrivateData::onPuglClose() | |||||
| close(); | 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); | static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | ||||
| PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | 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(); | pData->onPuglCreate(); | ||||
| break; | 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<uint>(event->button.time * 1000.0 + 0.5); | |||||
| ev.button = event->button.button; | |||||
| ev.press = event->type == PUGL_BUTTON_PRESS; | |||||
| ev.pos = Point<double>(event->button.x, event->button.y); | |||||
| pData->onPuglMouse(ev); | |||||
| break; | |||||
| } | |||||
| // TODO | // TODO | ||||
| default: | default: | ||||
| break; | break; | ||||
| @@ -18,6 +18,7 @@ | |||||
| #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | ||||
| #include "../Window.hpp" | #include "../Window.hpp" | ||||
| #include "../Events.hpp" | |||||
| #include "ApplicationPrivateData.hpp" | #include "ApplicationPrivateData.hpp" | ||||
| #include "pugl.hpp" | #include "pugl.hpp" | ||||
| @@ -107,6 +108,7 @@ struct Window::PrivateData : IdleCallback { | |||||
| void onPuglReshape(int width, int height); | void onPuglReshape(int width, int height); | ||||
| void onPuglCreate(); | void onPuglCreate(); | ||||
| void onPuglClose(); | void onPuglClose(); | ||||
| void onPuglMouse(const Events::MouseEvent& ev); | |||||
| // Pugl event handling entry point | // Pugl event handling entry point | ||||
| static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | ||||
| @@ -80,7 +80,6 @@ protected: | |||||
| void onDisplay() override | void onDisplay() override | ||||
| { | { | ||||
| const int iconSize = bgIcon.getWidth(); | const int iconSize = bgIcon.getWidth(); | ||||
| printf("LEFT SIDE WIDGET onDisplay %i\n", iconSize); | |||||
| glColor3f(0.027f, 0.027f, 0.027f); | glColor3f(0.027f, 0.027f, 0.027f); | ||||
| Rectangle<uint>(0, 0, getSize()).draw(); | Rectangle<uint>(0, 0, getSize()).draw(); | ||||
| @@ -201,8 +200,8 @@ protected: | |||||
| void onResize(const ResizeEvent& ev) override | 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.setWidth(width-4); | ||||
| bgIcon.setHeight(width-4); | bgIcon.setHeight(width-4); | ||||
| @@ -299,11 +298,6 @@ protected: | |||||
| void onDisplay() override | void onDisplay() override | ||||
| { | { | ||||
| static int counter = 0; | |||||
| printf("print %i\n", ++counter); | |||||
| glColor3f(0.471f, 0.971f, 0.171f); | |||||
| Rectangle<uint>(0, 0, getSize()).draw(); | |||||
| } | } | ||||
| void onReshape(uint width, uint height) override | void onReshape(uint width, uint height) override | ||||
| @@ -340,28 +334,6 @@ private: | |||||
| Widget* curWidget; | 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 | // Special handy function that runs a StandaloneWindow inside the function scope | ||||
| @@ -396,8 +368,6 @@ int main(int argc, char* argv[]) | |||||
| createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); | createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); | ||||
| else if (std::strcmp(argv[1], "shapes") == 0) | else if (std::strcmp(argv[1], "shapes") == 0) | ||||
| createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); | createAndShowExampleWidgetStandaloneWindow<ExampleShapesStandaloneWindow>(app); | ||||
| else if (std::strcmp(argv[1], "testing") == 0) | |||||
| createAndShowExampleWidgetStandaloneWindow<TestingWidgetStandaloneWindow>(app); | |||||
| else | else | ||||
| d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); | d_stderr2("Invalid demo mode, must be one of: color, rectangles, shapes"); | ||||
| } | } | ||||
| @@ -56,7 +56,7 @@ public: | |||||
| void init() | void init() | ||||
| { | { | ||||
| this->setSize(300, 300); | |||||
| BaseWidget::setSize(300, 300); | |||||
| for (int i=0; i<9; ++i) | for (int i=0; i<9; ++i) | ||||
| clicked[i] = false; | clicked[i] = false; | ||||
| @@ -65,8 +65,8 @@ public: | |||||
| protected: | protected: | ||||
| void onDisplay() override | void onDisplay() override | ||||
| { | { | ||||
| const uint width = this->getWidth(); | |||||
| const uint height = this->getHeight(); | |||||
| const uint width = BaseWidget::getWidth(); | |||||
| const uint height = BaseWidget::getHeight(); | |||||
| Rectangle<double> r; | Rectangle<double> r; | ||||
| @@ -115,8 +115,8 @@ protected: | |||||
| if (ev.button != 1 || ! ev.press) | if (ev.button != 1 || ! ev.press) | ||||
| return false; | return false; | ||||
| const uint width = this->getWidth(); | |||||
| const uint height = this->getHeight(); | |||||
| const uint width = BaseWidget::getWidth(); | |||||
| const uint height = BaseWidget::getHeight(); | |||||
| Rectangle<double> r; | Rectangle<double> r; | ||||
| @@ -134,7 +134,7 @@ protected: | |||||
| if (r.contains(ev.pos)) | if (r.contains(ev.pos)) | ||||
| { | { | ||||
| clicked[0+i] = !clicked[0+i]; | clicked[0+i] = !clicked[0+i]; | ||||
| this->repaint(); | |||||
| BaseWidget::repaint(); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -144,7 +144,7 @@ protected: | |||||
| if (r.contains(ev.pos)) | if (r.contains(ev.pos)) | ||||
| { | { | ||||
| clicked[3+i] = !clicked[3+i]; | clicked[3+i] = !clicked[3+i]; | ||||
| this->repaint(); | |||||
| BaseWidget::repaint(); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -154,7 +154,7 @@ protected: | |||||
| if (r.contains(ev.pos)) | if (r.contains(ev.pos)) | ||||
| { | { | ||||
| clicked[6+i] = !clicked[6+i]; | clicked[6+i] = !clicked[6+i]; | ||||
| this->repaint(); | |||||
| BaseWidget::repaint(); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||