monitor snapping: Bring back snapping when resizing for non-rotated frames (8126fa11) · Commits · Multimedia / Kdenlive · GitLab
Admin message
Join us at
Akademy
to celebrate KDE's 30th anniversary!
Travel support requests
are open till May 31st.
Register now
Commit
8126fa11
authored
Aug 07, 2025
by
balooii balooii
Committed by
Jean-Baptiste Mardelle
Aug 07, 2025
Browse files
parent
a02cb9c3
Loading
Loading
Loading
Loading
Original line number
Diff line number
Diff line
@@ -162,6 +162,7 @@ ecm_target_qml_sources(kdenliveLib
monitor/view/OverlayLabel.qml
monitor/view/ResizeHandle.qml
monitor/view/ResizeLogic.js
monitor/view/SnappingLogic.js
monitor/view/RotationHandle.qml
timeline2/view/qml/Timeline.qml
timeline2/view/qml/TimelineLogic.js
Original line number
Diff line number
Diff line
@@ -6,6 +6,7 @@
import
QtQuick
2.15
import
org
kde
kdenlive
as
import
SnappingLogic.js
as
SnappingLogic
Item
id
root
@@ -64,11 +65,7 @@ Item {
if
KdenliveSettings
showMonitorGrid
return
position
var
deltax
Math
round
position
root
scalex
var
deltay
Math
round
position
root
scaley
deltax
Math
round
deltax
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridH
deltay
Math
round
deltay
KdenliveSettings
monitorGridV
KdenliveSettings
monitorGridV
return
Qt
point
deltax
root
scalex
deltay
root
scaley
return
SnappingLogic
getSnappedPoint
position
root
scalex
root
scaley
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridV
function
updateClickCapture
()
Original line number
Diff line number
Diff line
@@ -8,6 +8,7 @@ import QtQuick.Shapes 1.15
import
org
kde
kdenlive
as
import
ResizeLogic.js
as
ResizeLogic
import
SnappingLogic.js
as
SnappingLogic
Item
id
root
@@ -90,108 +91,14 @@ Item {
if
KdenliveSettings
showMonitorGrid
return
position
var
deltax
Math
round
position
root
scalex
var
deltay
Math
round
position
root
scaley
deltax
Math
round
deltax
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridH
deltay
Math
round
deltay
KdenliveSettings
monitorGridV
KdenliveSettings
monitorGridV
return
Qt
point
deltax
root
scalex
deltay
root
scaley
return
SnappingLogic
getSnappedPoint
position
root
scalex
root
scaley
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridV
function
getRotatedBoundingRect
frameRect
rotationAngle
if
Math
abs
rotationAngle
0.1
return
frameRect
const
angleRad
rotationAngle
Math
PI
180.0
const
absCos
Math
abs
Math
cos
angleRad
));
const
absSin
Math
abs
Math
sin
angleRad
));
const
originalWidth
frameRect
width
const
originalHeight
frameRect
height
const
rotatedWidth
originalWidth
absCos
originalHeight
absSin
const
rotatedHeight
originalWidth
absSin
originalHeight
absCos
const
centerX
frameRect
originalWidth
const
centerY
frameRect
originalHeight
const
centerX
rotatedWidth
const
centerY
rotatedHeight
return
Qt
rect
rotatedWidth
rotatedHeight
);
function
getSnappedPos
frameRect
rotationAngle
function
getSnappedRect
frameRect
rotationAngle
if
KdenliveSettings
showMonitorGrid
return
frameRect
// Continue with the bounded rectangle of frameRect to support rotation
var
boundingRect
getRotatedBoundingRect
frameRect
rotationAngle
||
// Convert bounding rect to grid coordinates
var
gridX
boundingRect
root
scalex
var
gridY
boundingRect
root
scaley
var
gridWidth
boundingRect
width
root
scalex
var
gridHeight
boundingRect
height
root
scaley
// Get positions of the frame's edges
var
leftEdge
gridX
var
rightEdge
gridX
gridWidth
var
topEdge
gridY
var
bottomEdge
gridY
gridHeight
var
gridH
KdenliveSettings
monitorGridH
var
gridV
KdenliveSettings
monitorGridV
// Find nearest grid lines for each edge
var
nearestLeftGrid
Math
round
leftEdge
gridH
gridH
var
nearestRightGrid
Math
round
rightEdge
gridH
gridH
var
nearestTopGrid
Math
round
topEdge
gridV
gridV
var
nearestBottomGrid
Math
round
bottomEdge
gridV
gridV
// Calculate distances (in grid units)
var
leftDist
Math
abs
leftEdge
nearestLeftGrid
var
rightDist
Math
abs
rightEdge
nearestRightGrid
var
topDist
Math
abs
topEdge
nearestTopGrid
var
bottomDist
Math
abs
bottomEdge
nearestBottomGrid
// Snap tolerance (in grid units)
var
snapTolerance
Math
max
gridH
gridV
0.3
var
adjustedX
gridX
var
adjustedY
gridY
// Find closest horizontal edge
var
minHorizontalDist
Math
min
leftDist
rightDist
if
minHorizontalDist
<=
snapTolerance
if
leftDist
<=
rightDist
// Snap left edge
adjustedX
nearestLeftGrid
else
// Snap right edge
adjustedX
nearestRightGrid
gridWidth
// Find closest vertical edge
var
minVerticalDist
Math
min
topDist
bottomDist
if
minVerticalDist
<=
snapTolerance
if
topDist
<=
bottomDist
// Snap top edge
adjustedY
nearestTopGrid
else
// Snap bottom edge
adjustedY
nearestBottomGrid
gridHeight
// Calculate the offset between original and snapped bounding rect
var
offsetX
adjustedX
gridX
root
scalex
var
offsetY
adjustedY
gridY
root
scaley
// Apply the offset to the original frame position
return
Qt
rect
frameRect
offsetX
frameRect
offsetY
frameRect
width
frameRect
height
return
SnappingLogic
getSnappedRect
frameRect
rotationAngle
root
scalex
root
scaley
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridV
function
updateClickCapture
()
@@ -613,7 +520,7 @@ Item {
delta
+=
mouseClickPos
frameClicksize
var
snapFrameRect
Qt
rect
delta
delta
_framesize
width
root
scalex
_framesize
height
root
scaley
var
snappedRect
getSnapped
Pos
snapFrameRect
root
_rotation
var
snappedRect
getSnapped
Rect
snapFrameRect
root
_rotation
root
pendingFramesize
snappedRect
root
scalex
root
pendingFramesize
snappedRect
root
scaley
Original line number
Diff line number
Diff line
@@ -6,6 +6,7 @@
import
QtQuick
import
org
kde
kdenlive
as
import
ResizeLogic.js
as
ResizeLogic
import
SnappingLogic.js
as
SnappingLogic
Rectangle
id
handle
@@ -112,7 +113,27 @@ Rectangle {
rotationAngle
handle
resize
adjustedFrame
// Apply snapping to the resized frame (similar to how move operations work)
// Convert to screen coordinates for snapping
var
snapFrameRect
Qt
rect
adjustedFrame
scalex
adjustedFrame
scaley
adjustedFrame
width
scalex
adjustedFrame
height
scaley
var
snappedRect
KdenliveSettings
showMonitorGrid
SnappingLogic
getSnappedResizeRect
snapFrameRect
rotationAngle
handleType
scalex
scaley
KdenliveSettings
monitorGridH
KdenliveSettings
monitorGridV
snapFrameRect
// Convert back to logical coordinates
var
snappedFrame
Qt
rect
snappedRect
scalex
snappedRect
scaley
snappedRect
width
scalex
snappedRect
height
scaley
handle
resize
snappedFrame
if
isKeyframe
&&
KdenliveSettings
autoKeyframe
handle
addRemoveKeyframe
()
Original line number
Diff line number
Diff line
/*
SPDX-FileCopyrightText: 2025 Kdenlive contributors
SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
// Get snapped position for moving a point
function
getSnappedPoint
position
scalex
scaley
gridH
gridV
var
deltax
Math
round
position
scalex
var
deltay
Math
round
position
scaley
deltax
Math
round
deltax
gridH
gridH
deltay
Math
round
deltay
gridV
gridV
return
Qt
point
deltax
scalex
deltay
scaley
// Get the rotated bounding rectangle for the frame
function
getRotatedBoundingRect
frameRect
rotationAngle
if
Math
abs
rotationAngle
0.1
return
frameRect
const
angleRad
rotationAngle
Math
PI
180.0
const
absCos
Math
abs
Math
cos
angleRad
));
const
absSin
Math
abs
Math
sin
angleRad
));
const
originalWidth
frameRect
width
const
originalHeight
frameRect
height
const
rotatedWidth
originalWidth
absCos
originalHeight
absSin
const
rotatedHeight
originalWidth
absSin
originalHeight
absCos
const
centerX
frameRect
originalWidth
const
centerY
frameRect
originalHeight
const
centerX
rotatedWidth
const
centerY
rotatedHeight
return
Qt
rect
rotatedWidth
rotatedHeight
);
// Get snapped resize position for a frame based on handle type
function
getSnappedResizeRect
frameRect
rotationAngle
handleType
scalex
scaley
gridH
gridV
if
Math
abs
rotationAngle
0.1
// todo: not implemented yet
return
frameRect
// Convert frameRect to grid coordinates
var
gridX
frameRect
scalex
var
gridY
frameRect
scaley
var
gridWidth
frameRect
width
scalex
var
gridHeight
frameRect
height
scaley
var
snapTolerance
Math
max
gridH
gridV
0.3
var
adjustedFrame
Qt
rect
gridX
gridY
gridWidth
gridHeight
// Determine which edges to snap based on handle type
var
snapLeft
handleType
includes
LEFT
var
snapRight
handleType
includes
RIGHT
var
snapTop
handleType
includes
TOP
var
snapBottom
handleType
includes
BOTTOM
// Snap horizontal edges
if
snapLeft
var
leftEdge
gridX
var
nearestLeftGrid
Math
round
leftEdge
gridH
gridH
var
leftDist
Math
abs
leftEdge
nearestLeftGrid
if
leftDist
<=
snapTolerance
var
deltaX
nearestLeftGrid
leftEdge
adjustedFrame
nearestLeftGrid
adjustedFrame
width
gridWidth
deltaX
// Expand/shrink from left
else
if
snapRight
var
rightEdge
gridX
gridWidth
var
nearestRightGrid
Math
round
rightEdge
gridH
gridH
var
rightDist
Math
abs
rightEdge
nearestRightGrid
if
rightDist
<=
snapTolerance
adjustedFrame
width
nearestRightGrid
gridX
// Expand/shrink from right
// Snap vertical edges
if
snapTop
var
topEdge
gridY
var
nearestTopGrid
Math
round
topEdge
gridV
gridV
var
topDist
Math
abs
topEdge
nearestTopGrid
if
topDist
<=
snapTolerance
var
deltaY
nearestTopGrid
topEdge
adjustedFrame
nearestTopGrid
adjustedFrame
height
gridHeight
deltaY
// Expand/shrink from top
else
if
snapBottom
var
bottomEdge
gridY
gridHeight
var
nearestBottomGrid
Math
round
bottomEdge
gridV
gridV
var
bottomDist
Math
abs
bottomEdge
nearestBottomGrid
if
bottomDist
<=
snapTolerance
adjustedFrame
height
nearestBottomGrid
gridY
// Expand/shrink from bottom
// Convert back to screen coordinates
return
Qt
rect
adjustedFrame
scalex
adjustedFrame
scaley
adjustedFrame
width
scalex
adjustedFrame
height
scaley
// Get snapped position for moving a frame
function
getSnappedRect
frameRect
rotationAngle
scalex
scaley
gridH
gridV
// Continue with the bounded rectangle of frameRect to support rotation
var
boundingRect
getRotatedBoundingRect
frameRect
rotationAngle
||
// Convert bounding rect to grid coordinates
var
gridX
boundingRect
scalex
var
gridY
boundingRect
scaley
var
gridWidth
boundingRect
width
scalex
var
gridHeight
boundingRect
height
scaley
// Get positions of the frame's edges
var
leftEdge
gridX
var
rightEdge
gridX
gridWidth
var
topEdge
gridY
var
bottomEdge
gridY
gridHeight
// Find nearest grid lines for each edge
var
nearestLeftGrid
Math
round
leftEdge
gridH
gridH
var
nearestRightGrid
Math
round
rightEdge
gridH
gridH
var
nearestTopGrid
Math
round
topEdge
gridV
gridV
var
nearestBottomGrid
Math
round
bottomEdge
gridV
gridV
// Calculate distances (in grid units)
var
leftDist
Math
abs
leftEdge
nearestLeftGrid
var
rightDist
Math
abs
rightEdge
nearestRightGrid
var
topDist
Math
abs
topEdge
nearestTopGrid
var
bottomDist
Math
abs
bottomEdge
nearestBottomGrid
// Snap tolerance (in grid units)
var
snapTolerance
Math
max
gridH
gridV
0.3
var
adjustedX
gridX
var
adjustedY
gridY
// Find closest horizontal edge
var
minHorizontalDist
Math
min
leftDist
rightDist
if
minHorizontalDist
<=
snapTolerance
if
leftDist
<=
rightDist
// Snap left edge
adjustedX
nearestLeftGrid
else
// Snap right edge
adjustedX
nearestRightGrid
gridWidth
// Find closest vertical edge
var
minVerticalDist
Math
min
topDist
bottomDist
if
minVerticalDist
<=
snapTolerance
if
topDist
<=
bottomDist
// Snap top edge
adjustedY
nearestTopGrid
else
// Snap bottom edge
adjustedY
nearestBottomGrid
gridHeight
// Calculate the offset between original and snapped bounding rect
var
offsetX
adjustedX
gridX
scalex
var
offsetY
adjustedY
gridY
scaley
// Apply the offset to the original frame position
return
Qt
rect
frameRect
offsetX
frameRect
offsetY
frameRect
width
frameRect
height
Loading
US