Improve “snap to grid” feel of reservation drag
There was an issue when dragging the reservation too close to the left: DropArea was no longer receiving onPositionChanged events because the hotspot was already outside its area. By default the hotspot is (0, 0), and was outside the area as soon as the reservation was dragged to day “-1” of the period. Changing hotspot to (-width, 0) would only move the problem from the left to the right side, whe dragging to the day past the last of the period. I tried to have the DropArea to have a left margin of -30 days, that way it would fall way outside the range and continue receiving drag events. However, ListView’s `clip: true` is not only to limit the visual area—it also clips the region to receive events—, and i was at square one. I had to merge all DropArea into a single element, something i should have to do regardless, and move it as a sibling of the ListView, anchor to it, and add the negative left margin. Then, i have to transform drag’s coordinates from DropArea to ListView.contentItem to know the correct position of the reservation rectangle relative to its parent. Using contentItem also obviates the need of having to use scroll offsets, as this is a Flickable concernt, not of contentItem. Finally, i changed the Y position of the hotspot to half the rectangle to give the same distance from the top and from the bottom before snapping to the previour or next row.
This commit is contained in:
parent
ab1ebd61b6
commit
a9745ec117
|
@ -10,8 +10,7 @@ Label {
|
|||
required property string reservationStatus
|
||||
|
||||
Drag.active: dragHandler.active
|
||||
Drag.hotSpot.x: 0
|
||||
Drag.hotSpot.y: 0
|
||||
Drag.hotSpot.y: height / 2
|
||||
elide: Text.ElideRight
|
||||
padding: 2
|
||||
text: holder
|
||||
|
|
|
@ -99,29 +99,16 @@ Control {
|
|||
id: verticalScroll
|
||||
|
||||
}
|
||||
delegate: DropArea {
|
||||
property real contentWidth: ListView.view.contentWidth
|
||||
required property string name
|
||||
delegate: TimelineView {
|
||||
required property TimelineModel timeline
|
||||
property real viewportWidth: ListView.view.width
|
||||
property real viewportX: ListView.view.contentX
|
||||
|
||||
height: control.rowHeight
|
||||
width: contentWidth
|
||||
|
||||
onPositionChanged: function (drag) {
|
||||
drag.source.y = y;
|
||||
drag.source.x = (Math.floor(drag.x / control.dayWidth) + .5) * control.dayWidth;
|
||||
}
|
||||
|
||||
TimelineView {
|
||||
dayWidth: control.dayWidth
|
||||
fromDate: control.fromDate
|
||||
height: parent.height
|
||||
model: parent.timeline
|
||||
height: control.rowHeight
|
||||
model: timeline
|
||||
toDate: control.toDate
|
||||
viewportWidth: parent.viewportWidth
|
||||
viewportX: parent.viewportX
|
||||
viewportWidth: ListView.view.width
|
||||
viewportX: ListView.view.contentX
|
||||
|
||||
delegate: Reservation {
|
||||
dragParent: timelineList.contentItem
|
||||
|
@ -134,7 +121,6 @@ Control {
|
|||
palette: control.palette
|
||||
}
|
||||
}
|
||||
}
|
||||
header: Rectangle {
|
||||
border.color: Fusion.outline(control.palette)
|
||||
color: control.palette.base
|
||||
|
@ -201,5 +187,16 @@ Control {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: timelineList
|
||||
anchors.leftMargin: -30 * control.dayWidth
|
||||
|
||||
onPositionChanged: function (drag) {
|
||||
const pos = timelineList.contentItem.mapFromItem(this, drag.x, drag.y);
|
||||
drag.source.y = (Math.floor(pos.y / control.rowHeight)) * control.rowHeight;
|
||||
drag.source.x = (Math.floor(pos.x / control.dayWidth) + .5) * control.dayWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue