Fix Transform effect when current clip is not below play head / timeline cursor (3ffc0d7e) · 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
3ffc0d7e
authored
Sep 02, 2025
by
balooii balooii
Committed by
Jean-Baptiste Mardelle
Sep 05, 2025
Browse files
parent
8bcc4e38
Loading
Loading
Loading
Loading
Changes
Pipelines
Loading
Original line number
Diff line number
Diff line
@@ -14,6 +14,7 @@ set(kdenlive_SRCS
assets/keyframes/model/rotoscoping/rotohelper.cpp
assets/keyframes/model/corners/cornershelper.cpp
assets/keyframes/model/rect/recthelper.cpp
assets/keyframes/model/rect/rotatedrecthelper.cpp
assets/keyframes/model/keyframemodel.cpp
assets/keyframes/model/keyframemodellist.cpp
assets/keyframes/view/keyframeview.cpp
Original line number
Diff line number
Diff line
@@ -19,7 +19,6 @@ KeyframeMonitorHelper::KeyframeMonitorHelper(Monitor *monitor, std::shared_ptrm_active
false
m_requestedSceneType
sceneType
m_rotatable
sceneType
==
MonitorSceneType
::
MonitorSceneRotatedGeometry
bool
KeyframeMonitorHelper
::
connectMonitor
bool
activate
@@ -30,11 +29,9 @@ bool KeyframeMonitorHelper::connectMonitor(bool activate)
m_active
activate
if
activate
connect
m_monitor
Monitor
::
effectPointsChanged
this
KeyframeMonitorHelper
::
slotUpdateFromMonitorData
Qt
::
UniqueConnection
);
connect
m_monitor
Monitor
::
effectRotationChanged
this
KeyframeMonitorHelper
::
slotUpdateRotationFromMonitorData
Qt
::
UniqueConnection
);
else
m_monitor
->
setEffectKeyframe
false
true
);
disconnect
m_monitor
Monitor
::
effectPointsChanged
this
KeyframeMonitorHelper
::
slotUpdateFromMonitorData
);
disconnect
m_monitor
Monitor
::
effectRotationChanged
this
KeyframeMonitorHelper
::
slotUpdateRotationFromMonitorData
);
return
m_active
@@ -77,17 +74,13 @@ void KeyframeMonitorHelper::refreshParams(int pos)
QVariantList
points
QVariantList
types
QString
rectAtPosData
double
rotation
std
::
shared_ptr
KeyframeModelList
keyframes
m_model
->
getKeyframeModel
();
for
const
auto
ix
std
::
as_const
m_indexes
))
auto
type
m_model
->
data
ix
AssetParameterModel
::
TypeRole
).
value
ParamType
();
QString
name
m_model
->
data
ix
AssetParameterModel
::
NameRole
).
toString
();
if
type
==
ParamType
::
AnimatedRect
||
name
==
QLatin1String
"rotation"
)))
if
type
!=
ParamType
::
AnimatedRect
continue
if
name
==
QLatin1String
"rotation"
))
rotation
keyframes
->
getInterpolatedValue
pos
ix
).
toDouble
();
else
KeyframeModel
kfr
keyframes
->
getKeyModel
ix
);
bool
ok
rectAtPosData
kfr
->
getInterpolatedValue
pos
).
toString
();
@@ -107,11 +100,7 @@ void KeyframeMonitorHelper::refreshParams(int pos)
kf
kfr
->
getNextKeyframe
kf
first
ok
);
if
m_monitor
if
m_rotatable
m_monitor
->
setEffectSceneProperty
QStringLiteral
"rotation"
),
rotation
);
if
rectAtPosData
isEmpty
())
QStringList
data
rectAtPosData
split
QLatin1Char
' '
));
if
data
size
()
@@ -164,17 +153,3 @@ void KeyframeMonitorHelper::slotUpdateFromMonitorData(const QVariantList ¢er
break
void
KeyframeMonitorHelper
::
slotUpdateRotationFromMonitorData
double
rotation
if
m_indexes
isEmpty
())
for
const
auto
ix
std
::
as_const
m_indexes
))
QString
paramName
m_model
->
data
ix
AssetParameterModel
::
NameRole
).
toString
();
if
paramName
==
QLatin1String
"rotation"
))
m_model
->
setParameter
paramName
QString
::
number
rotation
),
true
ix
);
Q_EMIT
updateKeyframeData
ix
QVariant
rotation
));
break
Original line number
Diff line number
Diff line
@@ -65,13 +65,9 @@ protected:
QList
QPersistentModelIndex
m_indexes
bool
m_active
MonitorSceneType
m_requestedSceneType
MonitorSceneNone
};
/** @brief Whether this helper manages rotation parameters (for now only used for Transform effect based on qtblend)
*/
bool
m_rotatable
false
};
private
Q_SLOTS
virtual
void
slotUpdateFromMonitorData
const
QVariantList
);
virtual
void
slotUpdateRotationFromMonitorData
double
rotation
);
public
Q_SLOTS
/**
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
*/
#include
"rotatedrecthelper.hpp"
#include
"assets/keyframes/model/keyframemodellist.hpp"
#include
"assets/model/assetparametermodel.hpp"
#include
"monitor/monitor.h"
#include
RotatedRectHelper
::
RotatedRectHelper
Monitor
monitor
std
::
shared_ptr
AssetParameterModel
model
QObject
parent
KeyframeMonitorHelper
monitor
std
::
move
model
),
MonitorSceneRotatedGeometry
parent
bool
RotatedRectHelper
::
connectMonitor
bool
activate
if
activate
==
m_active
return
false
m_active
activate
if
activate
connect
m_monitor
Monitor
::
effectChanged
this
RotatedRectHelper
::
slotUpdateFromMonitorRect
Qt
::
UniqueConnection
);
connect
m_monitor
Monitor
::
effectRotationChanged
this
RotatedRectHelper
::
slotUpdateRotationFromMonitorData
Qt
::
UniqueConnection
);
else
m_monitor
->
setEffectKeyframe
false
true
);
// Note: We intentionally keep both geometry and rotation signals connected for continuous updates even when not active (clip not below playhead)
return
m_active
void
RotatedRectHelper
::
refreshParams
int
pos
// First call parent implementation to handle AnimatedRect updates (x, y, width, height)
KeyframeMonitorHelper
::
refreshParams
pos
);
// Now handle rotation-specific parts
double
rotation
std
::
shared_ptr
KeyframeModelList
keyframes
m_model
->
getKeyframeModel
();
// Find rotation parameter and get its interpolated value
for
const
auto
ix
std
::
as_const
m_indexes
))
QString
name
m_model
->
data
ix
AssetParameterModel
::
NameRole
).
toString
();
if
name
==
QLatin1String
"rotation"
))
rotation
keyframes
->
getInterpolatedValue
pos
ix
).
toDouble
();
break
if
m_monitor
m_monitor
->
setEffectSceneProperty
QStringLiteral
"rotation"
),
rotation
);
void
RotatedRectHelper
::
slotUpdateFromMonitorRect
const
QRectF
rect
QPersistentModelIndex
rectIndex
findAnimatedRectParameter
();
if
rectIndex
isValid
())
return
// Get current value to preserve opacity if it exists
QString
currentValue
m_model
->
getKeyframeModel
()
->
getInterpolatedValue
rectIndex
).
toString
();
QStringList
parts
currentValue
split
QLatin1Char
' '
));
// Create new rect value with updated coordinates
// Format of AnimatedRect string: "x y width height opacity" (opacity is optional)
QString
newValue
QStringLiteral
"%1 %2 %3 %4"
).
arg
int
rect
())).
arg
int
rect
())).
arg
int
rect
width
())).
arg
int
rect
height
()));
if
parts
size
()
newValue
append
QStringLiteral
" %1"
).
arg
parts
at
)));
// Update the model
m_model
->
setParameter
QLatin1String
""
),
newValue
true
rectIndex
);
Q_EMIT
updateKeyframeData
rectIndex
QVariant
newValue
));
void
RotatedRectHelper
::
slotUpdateRotationFromMonitorData
double
rotation
QPersistentModelIndex
rotationIndex
findRotationParameter
();
if
rotationIndex
isValid
())
return
m_model
->
setParameter
QLatin1String
"rotation"
),
QString
::
number
rotation
),
true
rotationIndex
);
Q_EMIT
updateKeyframeData
rotationIndex
QVariant
rotation
));
QPersistentModelIndex
RotatedRectHelper
::
findRotationParameter
()
const
for
const
auto
ix
std
::
as_const
m_indexes
))
QString
paramName
m_model
->
data
ix
AssetParameterModel
::
NameRole
).
toString
();
if
paramName
==
QLatin1String
"rotation"
))
return
ix
return
QPersistentModelIndex
();
QPersistentModelIndex
RotatedRectHelper
::
findAnimatedRectParameter
()
const
for
const
auto
ix
std
::
as_const
m_indexes
))
auto
type
m_model
->
data
ix
AssetParameterModel
::
TypeRole
).
value
ParamType
();
if
type
==
ParamType
::
AnimatedRect
return
ix
return
QPersistentModelIndex
();
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
*/
#pragma once
#include
"assets/keyframes/model/keyframemonitorhelper.hpp"
#include
#include
#include
#include
class
Monitor
class
AssetParameterModel
/** @class RotatedRectHelper
@brief Helper class for managing rotated rectangular effects that receive data from the monitor's qml overlay.
This class extends KeyframeMonitorHelper to handle both AnimatedRect geometry (x, y, width, height)
and rotation parameters for effects that support rotated rectangles. It translates monitor overlay
interactions into keyframe data updates for both geometry and rotation components.
In practice, this is used currently only for qtblend aka Transform effect.
*/
class
RotatedRectHelper
public
KeyframeMonitorHelper
Q_OBJECT
public:
/** @brief Construct a helper for managing rotated rectangle effects with monitor interaction.
@param monitor The Monitor instance this helper will interact with for overlay updates
@param model The asset parameter model this helper will manage keyframes for
@param parent Optional QObject parent
*/
explicit
RotatedRectHelper
Monitor
monitor
std
::
shared_ptr
AssetParameterModel
model
QObject
parent
nullptr
);
bool
connectMonitor
bool
activate
override
/** @brief Send data update to the monitor for both geometry and rotation parameters.
*/
void
refreshParams
int
pos
override
private
Q_SLOTS
/** @brief Handle rectangle geometry updates from the monitor overlay.
@param rect The new rectangle geometry from the monitor overlay
*/
void
slotUpdateFromMonitorRect
const
QRectF
rect
);
/** @brief Handle rotation updates from the monitor overlay.
@param rotation The new rotation value in degrees from the monitor overlay
*/
void
slotUpdateRotationFromMonitorData
double
rotation
);
private:
/** @brief Find the rotation parameter index in the managed parameters.
@return QPersistentModelIndex of the rotation parameter, or invalid index if not found
*/
QPersistentModelIndex
findRotationParameter
()
const
/** @brief Find the AnimatedRect parameter index in the managed parameters.
@return QPersistentModelIndex of the AnimatedRect parameter, or invalid index if not found
*/
QPersistentModelIndex
findAnimatedRectParameter
()
const
};
Loading
US