mirror of
https://github.com/KDE/latte-dock.git
synced 2025-01-24 18:03:53 +03:00
improve SunkEvents implementation
--each origin mouse area is now informin the SunkEvents handler for the relevant origin areas at the same time and this way there is no events breakage when changing from one sunked event origin area to another --the sunked events origin and destination areas are now released only when the event is NOT inside any origin area or any destination. This way no events breakage is appearing when changing from destination area to origin area and vice versa.
This commit is contained in:
parent
33d08c92a0
commit
81e4b19b59
@ -45,9 +45,9 @@ EventsSink::~EventsSink()
|
||||
{
|
||||
}
|
||||
|
||||
QQuickItem *EventsSink::originItem() const
|
||||
QQuickItem *EventsSink::originParentItem() const
|
||||
{
|
||||
return m_originItem;
|
||||
return m_originParentItem;
|
||||
}
|
||||
|
||||
QQuickItem *EventsSink::destinationItem() const
|
||||
@ -55,22 +55,21 @@ QQuickItem *EventsSink::destinationItem() const
|
||||
return m_destinationItem;
|
||||
}
|
||||
|
||||
void EventsSink::setSink(QQuickItem *origin, QQuickItem *destination)
|
||||
void EventsSink::setSink(QQuickItem *originParent, QQuickItem *destination)
|
||||
{
|
||||
if ((m_originItem == origin) && (m_destinationItem == destination)) {
|
||||
if ((m_originParentItem == originParent) && (m_destinationItem == destination)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_originItem = origin;
|
||||
m_originParentItem = originParent;
|
||||
m_destinationItem = destination;
|
||||
|
||||
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
bool EventsSink::isActive()
|
||||
{
|
||||
return ((m_originItem != nullptr) && (m_destinationItem != nullptr));
|
||||
return ((m_originParentItem != nullptr) && (m_destinationItem != nullptr));
|
||||
}
|
||||
|
||||
void EventsSink::release()
|
||||
@ -97,16 +96,14 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
case QEvent::DragEnter:
|
||||
if (auto de = static_cast<QDragEnterEvent *>(e)) {
|
||||
QPointF point = de->posF();
|
||||
QPointF originInternal = m_originItem->mapFromScene(point);
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(point)) {
|
||||
auto de2 = new QDragEnterEvent(positionAdjustedForDestination(point).toPoint(),
|
||||
de->possibleActions(),
|
||||
de->mimeData(),
|
||||
de->mouseButtons(),
|
||||
de->keyboardModifiers());
|
||||
sunkevent = de2;
|
||||
} else {
|
||||
} else if (!destinationContains(point)) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -115,9 +112,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
case QEvent::DragMove:
|
||||
if (auto de = static_cast<QDragMoveEvent *>(e)) {
|
||||
QPointF point = de->posF();
|
||||
QPointF originInternal = m_originItem->mapFromScene(point);
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(point)) {
|
||||
auto de2 = new QDragMoveEvent(positionAdjustedForDestination(point).toPoint(),
|
||||
de->possibleActions(),
|
||||
de->mimeData(),
|
||||
@ -125,7 +120,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
de->keyboardModifiers());
|
||||
|
||||
sunkevent = de2;
|
||||
} else {
|
||||
} else if (!destinationContains(point)) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -134,9 +129,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
case QEvent::Drop:
|
||||
if (auto de = static_cast<QDropEvent *>(e)) {
|
||||
QPointF point = de->posF();
|
||||
QPointF originInternal = m_originItem->mapFromScene(point);
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(point)) {
|
||||
auto de2 = new QDropEvent(positionAdjustedForDestination(point).toPoint(),
|
||||
de->possibleActions(),
|
||||
de->mimeData(),
|
||||
@ -144,7 +137,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
de->keyboardModifiers());
|
||||
|
||||
sunkevent = de2;
|
||||
} else {
|
||||
} else if (!destinationContains(point)) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -153,9 +146,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
|
||||
case QEvent::MouseMove:
|
||||
if (auto me = dynamic_cast<QMouseEvent *>(e)) {
|
||||
QPointF originInternal = m_originItem->mapFromScene(me->windowPos());
|
||||
|
||||
if (m_view->positioner() && m_view->positioner()->isCursorInsideView() && m_originItem->contains(originInternal)) {
|
||||
if (m_view->positioner() && m_view->positioner()->isCursorInsideView() && originSinksContain(me->windowPos())) {
|
||||
auto positionadjusted = positionAdjustedForDestination(me->windowPos());
|
||||
auto me2 = new QMouseEvent(me->type(),
|
||||
positionadjusted,
|
||||
@ -164,7 +155,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
me->button(), me->buttons(), me->modifiers());
|
||||
|
||||
sunkevent = me2;
|
||||
} else {
|
||||
} else if (!destinationContains(me->windowPos())) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -172,9 +163,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
if (auto me = dynamic_cast<QMouseEvent *>(e)) {
|
||||
QPointF originInternal = m_originItem->mapFromScene(me->windowPos());
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(me->windowPos())) {
|
||||
auto positionadjusted = positionAdjustedForDestination(me->windowPos());
|
||||
auto me2 = new QMouseEvent(me->type(),
|
||||
positionadjusted,
|
||||
@ -184,7 +173,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
|
||||
qDebug() << "Sunk Event:: sunk event pressed...";
|
||||
sunkevent = me2;
|
||||
} else {
|
||||
} else if (!destinationContains(me->windowPos())) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -192,9 +181,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
|
||||
case QEvent::MouseButtonRelease:
|
||||
if (auto me = dynamic_cast<QMouseEvent *>(e)) {
|
||||
QPointF originInternal = m_originItem->mapFromScene(me->windowPos());
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(me->windowPos())) {
|
||||
auto positionadjusted = positionAdjustedForDestination(me->windowPos());
|
||||
auto me2 = new QMouseEvent(me->type(),
|
||||
positionadjusted,
|
||||
@ -203,7 +190,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
me->button(), me->buttons(), me->modifiers());
|
||||
|
||||
sunkevent = me2;
|
||||
} else {
|
||||
} else if (!destinationContains(me->windowPos())) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -216,9 +203,8 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
#else
|
||||
QPoint pos = we->position().toPoint();
|
||||
#endif
|
||||
QPointF originInternal = m_originItem->mapFromScene(pos);
|
||||
|
||||
if (m_originItem->contains(originInternal)) {
|
||||
if (originSinksContain(pos)) {
|
||||
auto positionadjusted = positionAdjustedForDestination(pos);
|
||||
auto we2 = new QWheelEvent(positionadjusted,
|
||||
positionadjusted + m_view->position(),
|
||||
@ -226,7 +212,7 @@ QEvent *EventsSink::onEvent(QEvent *e)
|
||||
we->orientation(), we->buttons(), we->modifiers(), we->phase());
|
||||
|
||||
sunkevent = we2;
|
||||
} else {
|
||||
} else if (!destinationContains(pos)) {
|
||||
release();
|
||||
}
|
||||
}
|
||||
@ -246,6 +232,25 @@ QPointF EventsSink::positionAdjustedForDestination(const QPointF &point) const
|
||||
qBound(destinationRectToScene.top(), point.y(), destinationRectToScene.bottom()));
|
||||
}
|
||||
|
||||
bool EventsSink::destinationContains(const QPointF &point) const
|
||||
{
|
||||
QRectF destinationRectToScene = m_destinationItem->mapRectToScene(QRectF(0, 0, m_destinationItem->width() - 1, m_destinationItem->height() - 1));
|
||||
|
||||
return destinationRectToScene.contains(point);
|
||||
}
|
||||
|
||||
bool EventsSink::originSinksContain(const QPointF &point) const
|
||||
{
|
||||
QRegion originsRegion;
|
||||
|
||||
for(const auto currentOrigin: m_originParentItem->childItems()) {
|
||||
QRectF currentOriginGeometry = currentOrigin->mapRectToScene(QRectF(0, 0, currentOrigin->width(), currentOrigin->height()));
|
||||
originsRegion = originsRegion.united(currentOriginGeometry.toRect());
|
||||
}
|
||||
|
||||
return originsRegion.contains(point.toPoint());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
// Qt
|
||||
#include <QEvent>
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <QQuickItem>
|
||||
|
||||
@ -33,11 +34,16 @@ class View;
|
||||
namespace Latte {
|
||||
namespace ViewPart {
|
||||
|
||||
//! This class is used in order to sunk events from children rects of originParentItem
|
||||
//! into the destination Item. Each applet container from containment qml part is responsible
|
||||
//! to initialize properly the originParentItem and the destinationItem to be used for
|
||||
//! sunk events
|
||||
|
||||
class EventsSink: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QQuickItem *originItem READ originItem NOTIFY itemsChanged)
|
||||
Q_PROPERTY(QQuickItem *originParentItem READ originParentItem NOTIFY itemsChanged)
|
||||
Q_PROPERTY(QQuickItem *destinationItem READ destinationItem NOTIFY itemsChanged)
|
||||
|
||||
public:
|
||||
@ -46,11 +52,11 @@ public:
|
||||
|
||||
bool isActive();
|
||||
|
||||
QQuickItem *originItem() const;
|
||||
QQuickItem *originParentItem() const;
|
||||
QQuickItem *destinationItem() const;
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE void setSink(QQuickItem *origin, QQuickItem *destination);
|
||||
Q_INVOKABLE void setSink(QQuickItem *originParent, QQuickItem *destination);
|
||||
|
||||
QEvent *onEvent(QEvent *e);
|
||||
|
||||
@ -63,10 +69,12 @@ private slots:
|
||||
private:
|
||||
QPointF positionAdjustedForDestination(const QPointF &point) const;
|
||||
|
||||
bool originSinksContain(const QPointF &point) const;
|
||||
bool destinationContains(const QPointF &point) const;
|
||||
private:
|
||||
QPointer<Latte::View> m_view;
|
||||
|
||||
QPointer<QQuickItem> m_originItem;
|
||||
QPointer<QQuickItem> m_originParentItem;
|
||||
QPointer<QQuickItem> m_destinationItem;
|
||||
};
|
||||
|
||||
|
@ -27,11 +27,12 @@ Item {
|
||||
|
||||
readonly property int headThickness: appletItem.metrics.margin.thickness
|
||||
readonly property int tailThickness: destination ? destination.tailThicknessMargin : headThickness
|
||||
readonly property int thickness: headThickness + tailThickness + (root.isHorizontal ? destination.height : destination.width)
|
||||
readonly property int lengthPadding: {
|
||||
if ( (root.panelAlignment === LatteCore.Types.Justify && appletItem.firstChildOfStartLayout)
|
||||
|| (root.panelAlignment === LatteCore.Types.Justify && appletItem.lastChildOfEndLayout)
|
||||
|| (root.panelAlignment !== LatteCore.Types.Justify && appletItem.firstChildOfMainLayout)
|
||||
|| (root.panelAlignment !== LatteCore.Types.Justify && appletItem.lastChildOfMainLayout)) {
|
||||
|| (root.panelAlignment === LatteCore.Types.Justify && appletItem.lastChildOfEndLayout)
|
||||
|| (root.panelAlignment !== LatteCore.Types.Justify && appletItem.firstChildOfMainLayout)
|
||||
|| (root.panelAlignment !== LatteCore.Types.Justify && appletItem.lastChildOfMainLayout)) {
|
||||
//! Fitts Law on corners
|
||||
return appletItem.lengthAppletFullMargin;
|
||||
}
|
||||
@ -41,6 +42,7 @@ Item {
|
||||
|
||||
readonly property bool active: parent ? parent.active : false
|
||||
|
||||
|
||||
Loader{
|
||||
anchors.fill: parent
|
||||
active: appletItem.debug.eventsSinkEnabled && active
|
||||
@ -53,72 +55,159 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: originParentItem
|
||||
anchors.fill: parent
|
||||
|
||||
EventsSinkOriginArea {
|
||||
id: topArea
|
||||
anchors.bottom: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//! NOTICE: Do not add any more child items. These child items are used from SinkedEvents handler in order
|
||||
//! to identify the areas from which mouse events should be sunk into the destination item
|
||||
|
||||
width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? destination.width + 2 * lengthPadding : destination.width
|
||||
height: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
EventsSinkOriginArea {
|
||||
id: topArea
|
||||
width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? destination.width + 2 * lengthPadding : thickness
|
||||
height: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
}
|
||||
}
|
||||
|
||||
states:[
|
||||
State{
|
||||
name: "horizontal"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Horizontal
|
||||
|
||||
AnchorChanges{
|
||||
target: topArea;
|
||||
anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined;
|
||||
anchors.right: undefined; anchors.left: undefined; anchors.top: undefined; anchors.bottom: parent.top;
|
||||
}
|
||||
},
|
||||
State{
|
||||
name: "vertical"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||
|
||||
AnchorChanges{
|
||||
target: topArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: undefined;
|
||||
anchors.right: undefined; anchors.left: leftArea.left; anchors.top: leftArea.top; anchors.bottom: undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
EventsSinkOriginArea {
|
||||
id: bottomArea
|
||||
anchors.top: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? destination.width + 2 * lengthPadding : parent.width
|
||||
height: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
EventsSinkOriginArea {
|
||||
id: bottomArea
|
||||
width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? destination.width + 2 * lengthPadding : thickness
|
||||
height: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
}
|
||||
}
|
||||
|
||||
states:[
|
||||
State{
|
||||
name: "horizontal"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Horizontal
|
||||
|
||||
AnchorChanges{
|
||||
target: bottomArea;
|
||||
anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: undefined;
|
||||
anchors.right: undefined; anchors.left: undefined; anchors.top: parent.bottom; anchors.bottom: undefined;
|
||||
}
|
||||
},
|
||||
State{
|
||||
name: "vertical"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||
|
||||
AnchorChanges{
|
||||
target: bottomArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: undefined;
|
||||
anchors.right: undefined; anchors.left: leftArea.left; anchors.top: undefined; anchors.bottom: leftArea.bottom;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
EventsSinkOriginArea {
|
||||
id: leftArea
|
||||
anchors.right: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? parent.height : destination.height + 2 * lengthPadding
|
||||
width: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
EventsSinkOriginArea {
|
||||
id: leftArea
|
||||
height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickness : destination.height + 2 * lengthPadding
|
||||
width: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
}
|
||||
}
|
||||
|
||||
states:[
|
||||
State{
|
||||
name: "horizontal"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Horizontal
|
||||
|
||||
AnchorChanges{
|
||||
target: leftArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: undefined;
|
||||
anchors.right: undefined; anchors.left: bottomArea.left; anchors.top: undefined; anchors.bottom: bottomArea.bottom;
|
||||
}
|
||||
},
|
||||
State{
|
||||
name: "vertical"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||
|
||||
AnchorChanges{
|
||||
target: leftArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.right: parent.left; anchors.left: undefined; anchors.top: undefined; anchors.bottom: undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
EventsSinkOriginArea {
|
||||
id: rightArea
|
||||
anchors.left: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? parent.height : destination.height + 2 * lengthPadding
|
||||
width: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
EventsSinkOriginArea {
|
||||
id: rightArea
|
||||
height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickness : destination.height + 2 * lengthPadding
|
||||
width: {
|
||||
if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
|
||||
return lengthPadding;
|
||||
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
|
||||
return tailThickness;
|
||||
} else {
|
||||
return headThickness;
|
||||
}
|
||||
}
|
||||
|
||||
states:[
|
||||
State{
|
||||
name: "horizontal"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Horizontal
|
||||
|
||||
AnchorChanges{
|
||||
target: rightArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: undefined;
|
||||
anchors.right: bottomArea.right; anchors.left: undefined; anchors.top: undefined; anchors.bottom: bottomArea.bottom;
|
||||
}
|
||||
},
|
||||
State{
|
||||
name: "vertical"
|
||||
when: plasmoid.formFactor === PlasmaCore.Types.Vertical
|
||||
|
||||
AnchorChanges{
|
||||
target: rightArea;
|
||||
anchors.horizontalCenter: undefined; anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.right: undefined; anchors.left: parent.right; anchors.top: undefined; anchors.bottom: undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,13 +20,13 @@
|
||||
import QtQuick 2.7
|
||||
|
||||
MouseArea {
|
||||
id: __destinationArea
|
||||
id: __originArea
|
||||
enabled: visible
|
||||
hoverEnabled: true
|
||||
visible: root.latteView && root.latteView.sink.originItem !== __destinationArea && width>0 && height>0
|
||||
visible: root.latteView && root.latteView.sink.originParentItem !== originParentItem && width>0 && height>0
|
||||
|
||||
onEntered: {
|
||||
root.latteView.sink.setSink(__destinationArea, destination)
|
||||
root.latteView.sink.setSink(originParentItem, destination);
|
||||
}
|
||||
|
||||
Loader{
|
||||
|
Loading…
x
Reference in New Issue
Block a user