Signed-off-by: falkTX <falktx@falktx.com>pull/282/head
| @@ -121,6 +121,12 @@ public: | |||
| */ | |||
| void repaint() noexcept override; | |||
| /** | |||
| Bring this widget to the "front" of the parent widget. | |||
| Makes the widget behave as if it was the last to be registered on the parent widget, thus being "in front". | |||
| */ | |||
| virtual void toFront(); | |||
| /** | |||
| Indicate that this subwidget will draw out of bounds, and thus needs the entire viewport available for drawing. | |||
| */ | |||
| @@ -156,37 +156,43 @@ public: | |||
| /** | |||
| Mouse press or release event. | |||
| @a button The button number starting from 1 (1 = left, 2 = middle, 3 = right). | |||
| @a press True if the button was pressed, false if released. | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a button The button number starting from 1 (1 = left, 2 = middle, 3 = right). | |||
| @a press True if the button was pressed, false if released. | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a absolutePos The absolute coordinates of the pointer. | |||
| @see onMouse | |||
| */ | |||
| struct MouseEvent : BaseEvent { | |||
| uint button; | |||
| bool press; | |||
| Point<double> pos; | |||
| Point<double> absolutePos; | |||
| /** Constuctor */ | |||
| MouseEvent() noexcept | |||
| : BaseEvent(), | |||
| button(0), | |||
| press(false), | |||
| pos(0.0, 0.0) {} | |||
| pos(0.0, 0.0), | |||
| absolutePos(0.0, 0.0) {} | |||
| }; | |||
| /** | |||
| Mouse motion event. | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a absolutePos The absolute coordinates of the pointer. | |||
| @see onMotion | |||
| */ | |||
| struct MotionEvent : BaseEvent { | |||
| Point<double> pos; | |||
| Point<double> absolutePos; | |||
| /** Constuctor */ | |||
| MotionEvent() noexcept | |||
| : BaseEvent(), | |||
| pos(0.0, 0.0) {} | |||
| pos(0.0, 0.0), | |||
| absolutePos(0.0, 0.0) {} | |||
| }; | |||
| /** | |||
| @@ -198,13 +204,15 @@ public: | |||
| Some systems and devices support finer resolution and/or higher values for fast scrolls, | |||
| so programs should handle any value gracefully. | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a delta The scroll distance. | |||
| @a direction The direction of the scroll or "smooth". | |||
| @a pos The widget-relative coordinates of the pointer. | |||
| @a absolutePos The absolute coordinates of the pointer. | |||
| @a delta The scroll distance. | |||
| @a direction The direction of the scroll or "smooth". | |||
| @see onScroll | |||
| */ | |||
| struct ScrollEvent : BaseEvent { | |||
| Point<double> pos; | |||
| Point<double> absolutePos; | |||
| Point<double> delta; | |||
| ScrollDirection direction; | |||
| @@ -212,6 +220,7 @@ public: | |||
| ScrollEvent() noexcept | |||
| : BaseEvent(), | |||
| pos(0.0, 0.0), | |||
| absolutePos(0.0, 0.0), | |||
| delta(0.0, 0.0), | |||
| direction(kScrollSmooth) {} | |||
| }; | |||
| @@ -582,7 +582,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||
| const int w = static_cast<int>(self->getWidth()); | |||
| const int h = static_cast<int>(self->getHeight()); | |||
| if (viewportScaleFactor != 0.0) | |||
| if (viewportScaleFactor != 0.0 && viewportScaleFactor != 1.0) | |||
| { | |||
| glViewport(x, | |||
| -static_cast<int>(height * viewportScaleFactor - height + absolutePos.getY() + 0.5), | |||
| @@ -598,10 +598,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||
| else if (needsFullViewportForDrawing || (absolutePos.isZero() && self->getSize() == Size<uint>(width, height))) | |||
| { | |||
| // full viewport size | |||
| glViewport(0, | |||
| -static_cast<int>(height - height + 0.5), | |||
| static_cast<int>(width + 0.5), | |||
| static_cast<int>(height + 0.5)); | |||
| glViewport(0, 0, static_cast<int>(width), static_cast<int>(height)); | |||
| } | |||
| else | |||
| { | |||
| @@ -15,6 +15,7 @@ | |||
| */ | |||
| #include "SubWidgetPrivateData.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| #include "../TopLevelWidget.hpp" | |||
| START_NAMESPACE_DGL | |||
| @@ -118,6 +119,14 @@ void SubWidget::repaint() noexcept | |||
| } | |||
| } | |||
| void SubWidget::toFront() | |||
| { | |||
| std::list<SubWidget*>& subwidgets(pData->parentWidget->pData->subWidgets); | |||
| subwidgets.remove(this); | |||
| subwidgets.push_back(this); | |||
| } | |||
| void SubWidget::setNeedsFullViewportDrawing(const bool needsFullViewportForDrawing) | |||
| { | |||
| pData->needsFullViewportForDrawing = needsFullViewportForDrawing; | |||
| @@ -92,6 +92,8 @@ bool TopLevelWidget::PrivateData::mouseEvent(const MouseEvent& ev) | |||
| rev.pos.setX(ev.pos.getX() / autoScaleFactor); | |||
| rev.pos.setY(ev.pos.getY() / autoScaleFactor); | |||
| rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor); | |||
| rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor); | |||
| } | |||
| // give top-level widget chance to catch this event first | |||
| @@ -116,6 +118,8 @@ bool TopLevelWidget::PrivateData::motionEvent(const MotionEvent& ev) | |||
| rev.pos.setX(ev.pos.getX() / autoScaleFactor); | |||
| rev.pos.setY(ev.pos.getY() / autoScaleFactor); | |||
| rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor); | |||
| rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor); | |||
| } | |||
| // give top-level widget chance to catch this event first | |||
| @@ -140,6 +144,8 @@ bool TopLevelWidget::PrivateData::scrollEvent(const ScrollEvent& ev) | |||
| rev.pos.setX(ev.pos.getX() / autoScaleFactor); | |||
| rev.pos.setY(ev.pos.getY() / autoScaleFactor); | |||
| rev.absolutePos.setX(ev.absolutePos.getX() / autoScaleFactor); | |||
| rev.absolutePos.setY(ev.absolutePos.getY() / autoScaleFactor); | |||
| rev.delta.setX(ev.delta.getX() / autoScaleFactor); | |||
| rev.delta.setY(ev.delta.getY() / autoScaleFactor); | |||
| } | |||
| @@ -130,8 +130,20 @@ bool Widget::PrivateData::giveMouseEventForSubWidgets(MouseEvent& ev) | |||
| if (subWidgets.size() == 0) | |||
| return false; | |||
| const double x = ev.pos.getX(); | |||
| const double y = ev.pos.getY(); | |||
| double x = ev.absolutePos.getX(); | |||
| double y = ev.absolutePos.getY(); | |||
| if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self)) | |||
| { | |||
| if (selfw->pData->needsViewportScaling) | |||
| { | |||
| x -= selfw->getAbsoluteX(); | |||
| y -= selfw->getAbsoluteY(); | |||
| ev.absolutePos.setX(x); | |||
| ev.absolutePos.setY(y); | |||
| } | |||
| } | |||
| FOR_EACH_SUBWIDGET_INV(rit) | |||
| { | |||
| @@ -157,8 +169,20 @@ bool Widget::PrivateData::giveMotionEventForSubWidgets(MotionEvent& ev) | |||
| if (subWidgets.size() == 0) | |||
| return false; | |||
| const double x = ev.pos.getX(); | |||
| const double y = ev.pos.getY(); | |||
| double x = ev.absolutePos.getX(); | |||
| double y = ev.absolutePos.getY(); | |||
| if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self)) | |||
| { | |||
| if (selfw->pData->needsViewportScaling) | |||
| { | |||
| x -= selfw->getAbsoluteX(); | |||
| y -= selfw->getAbsoluteY(); | |||
| ev.absolutePos.setX(x); | |||
| ev.absolutePos.setY(y); | |||
| } | |||
| } | |||
| FOR_EACH_SUBWIDGET_INV(rit) | |||
| { | |||
| @@ -184,8 +208,20 @@ bool Widget::PrivateData::giveScrollEventForSubWidgets(ScrollEvent& ev) | |||
| if (subWidgets.size() == 0) | |||
| return false; | |||
| const double x = ev.pos.getX(); | |||
| const double y = ev.pos.getY(); | |||
| double x = ev.absolutePos.getX(); | |||
| double y = ev.absolutePos.getY(); | |||
| if (SubWidget* const selfw = dynamic_cast<SubWidget*>(self)) | |||
| { | |||
| if (selfw->pData->needsViewportScaling) | |||
| { | |||
| x -= selfw->getAbsoluteX(); | |||
| y -= selfw->getAbsoluteY(); | |||
| ev.absolutePos.setX(x); | |||
| ev.absolutePos.setY(y); | |||
| } | |||
| } | |||
| FOR_EACH_SUBWIDGET_INV(rit) | |||
| { | |||
| @@ -945,6 +945,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
| ev.button = event->button.button; | |||
| ev.press = event->type == PUGL_BUTTON_PRESS; | |||
| ev.pos = Point<double>(event->button.x, event->button.y); | |||
| ev.absolutePos = ev.pos; | |||
| pData->onPuglMouse(ev); | |||
| break; | |||
| } | |||
| @@ -957,6 +958,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
| ev.flags = event->motion.flags; | |||
| ev.time = static_cast<uint>(event->motion.time * 1000.0 + 0.5); | |||
| ev.pos = Point<double>(event->motion.x, event->motion.y); | |||
| ev.absolutePos = ev.pos; | |||
| pData->onPuglMotion(ev); | |||
| break; | |||
| } | |||
| @@ -971,6 +973,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
| ev.pos = Point<double>(event->scroll.x, event->scroll.y); | |||
| ev.delta = Point<double>(event->scroll.dx, event->scroll.dy); | |||
| ev.direction = static_cast<ScrollDirection>(event->scroll.direction); | |||
| ev.absolutePos = ev.pos; | |||
| pData->onPuglScroll(ev); | |||
| break; | |||
| } | |||