commit 597d7f3ee5364970623310305f2d82034fb86348
parent 5ee572955d1f03c8c883325a28b59167f1aeef54
Author: falkTX <falktx@falktx.com>
Date: Fri, 4 Jun 2021 22:45:26 +0100
Add SubWidget::toFront, fix position for subwidgets of subwidgets
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
7 files changed, 86 insertions(+), 20 deletions(-)
diff --git a/dgl/SubWidget.hpp b/dgl/SubWidget.hpp
@@ -122,6 +122,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.
*/
void setNeedsFullViewportDrawing(bool needsFullViewportForDrawing = true);
diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp
@@ -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) {}
};
diff --git a/dgl/src/OpenGL.cpp b/dgl/src/OpenGL.cpp
@@ -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
{
diff --git a/dgl/src/SubWidget.cpp b/dgl/src/SubWidget.cpp
@@ -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;
diff --git a/dgl/src/TopLevelWidgetPrivateData.cpp b/dgl/src/TopLevelWidgetPrivateData.cpp
@@ -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);
}
diff --git a/dgl/src/WidgetPrivateData.cpp b/dgl/src/WidgetPrivateData.cpp
@@ -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)
{
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -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;
}