Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Implement new timeline logic, Fix keyframes disabled after re-enabling monitor effect scene

parent f8fcdf56
Pipeline #1607 passed with stage
in 14 minutes and 22 seconds
......@@ -395,10 +395,11 @@ void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
void KeyframeWidget::slotInitMonitor(bool active)
{
Monitor *monitor = pCore->getMonitor(m_model->monitorId);
if (m_keyframeview) {
m_keyframeview->initKeyframePos();
connect(monitor, &Monitor::updateScene, m_keyframeview, &KeyframeView::slotModelChanged, Qt::UniqueConnection);
}
Monitor *monitor = pCore->getMonitor(m_model->monitorId);
connectMonitor(active);
if (active) {
connect(monitor, &Monitor::seekPosition, this, &KeyframeWidget::monitorSeek, Qt::UniqueConnection);
......
......@@ -630,7 +630,7 @@
<label>Path to shuttle device.</label>
<default></default>
</entry>
<entry name="shuttledevicenames" type="StringList">
<label>Available shuttle device names.</label>
<default></default>
......@@ -805,13 +805,13 @@
<entry name="showtitlebars" type="Bool">
<label>Show dock widget titlebars to allow un/docking.</label>
<default>true</default>
</entry>
</entry>
<entry name="colorclipcolor" type="Color">
<label>Color to preselect in the color clip dialog.</label>
<default>#000000</default>
</entry>
<entry name="rescalekeepratio" type="Bool">
<label>Keep aspect ratio in render dialog rescale widget.</label>
<default>true</default>
......
......@@ -1533,7 +1533,7 @@ void Monitor::slotEnableEffectScene(bool enable)
MonitorSceneType sceneType = enable ? m_lastMonitorSceneType : MonitorSceneDefault;
slotShowEffectScene(sceneType, true);
if (enable) {
emit seekPosition(m_glMonitor->getCurrentPos());
emit updateScene();
}
}
......
......@@ -325,7 +325,8 @@ public slots:
void refreshMonitorIfActive(bool directUpdate = false) override;
signals:
void seekPosition(int);
void seekPosition(int pos);
void updateScene();
/** @brief Request a timeline seeking if diff is true, position is a relative offset, otherwise an absolute position */
void seekTimeline(int position);
void durationChanged(int);
......
......@@ -274,14 +274,14 @@ bool TimelineFunctions::insertZone(const std::shared_ptr<TimelineItemModel> &tim
// Start undoable command
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool result = false;
bool result = true;
int trackId = trackIds.takeFirst();
if (overwrite) {
// Cut all tracks
auto it = timeline->m_allTracks.cbegin();
while (it != timeline->m_allTracks.cend()) {
int target_track = (*it)->getId();
if (timeline->getTrackById_const(target_track)->isLocked()) {
if (!trackIds.contains(target_track) && !timeline->getTrackById_const(target_track)->shouldReceiveTimelineOp()) {
++it;
continue;
}
......@@ -296,7 +296,7 @@ bool TimelineFunctions::insertZone(const std::shared_ptr<TimelineItemModel> &tim
auto it = timeline->m_allTracks.cbegin();
while (it != timeline->m_allTracks.cend()) {
int target_track = (*it)->getId();
if (timeline->getTrackById_const(target_track)->isLocked()) {
if (!trackIds.contains(target_track) && !timeline->getTrackById_const(target_track)->shouldReceiveTimelineOp()) {
++it;
continue;
}
......
......@@ -211,6 +211,7 @@ QHash<int, QByteArray> TimelineItemModel::roleNames() const
roles[ReloadThumbRole] = "reloadThumb";
roles[ThumbsFormatRole] = "thumbsFormat";
roles[AudioRecordRole] = "audioRecord";
roles[TrackActiveRole] = "trackActive";
roles[EffectNamesRole] = "effectNames";
roles[EffectsEnabledRole] = "isStackEnabled";
roles[GrabbedRole] = "isGrabbed";
......@@ -358,7 +359,9 @@ QVariant TimelineItemModel::data(const QModelIndex &index, int role) const
case IsCompositeRole: {
case AudioRecordRole:
return getTrackById_const(id)->getProperty("kdenlive:audio_rec").toInt();
return Qt::Unchecked;
}
case TrackActiveRole: {
return getTrackById_const(id)->isTimelineActive();
}
case EffectNamesRole: {
return getTrackById_const(id)->effectNames();
......@@ -430,6 +433,8 @@ void TimelineItemModel::setTrackProperty(int trackId, const QString &name, const
if (!track->isAudioTrack()) {
pCore->requestMonitorRefresh();
}
} else if (name == QLatin1String("kdenlive:timeline_active")) {
roles.push_back(TrackActiveRole);
} else if (name == QLatin1String("kdenlive:thumbs_format")) {
roles.push_back(ThumbsFormatRole);
} else if (name == QLatin1String("kdenlive:audio_rec")) {
......
......@@ -153,6 +153,7 @@ public:
EffectNamesRole, // track and clip only
EffectsEnabledRole, // track and clip only
GrabbedRole, /// clip+composition only
TrackActiveRole, /// track only
AudioRecordRole /// track only
};
......
......@@ -1116,6 +1116,18 @@ bool TrackModel::isLocked() const
return m_track->get_int("kdenlive:locked_track");
}
bool TrackModel::isTimelineActive() const
{
READ_LOCK();
return m_track->get_int("kdenlive:timeline_active");
}
bool TrackModel::shouldReceiveTimelineOp() const
{
READ_LOCK();
return m_track->get_int("kdenlive:timeline_active") && !m_track->get_int("kdenlive:locked_track");
}
bool TrackModel::isAudioTrack() const
{
return m_track->get_int("kdenlive:audio_track") == 1;
......
......@@ -85,6 +85,13 @@ public:
/* @brief Returns true if track is in locked state
*/
bool isLocked() const;
/* @brief Returns true if track is active in timeline, ie.
* will receive insert/lift/overwrite/extract operations
*/
bool isTimelineActive() const;
/* @brief Returns true if track is active and not locked
*/
bool shouldReceiveTimelineOp() const;
/* @brief Returns true if track is an audio track
*/
bool isAudioTrack() const;
......
......@@ -29,7 +29,8 @@ Rectangle {
property bool isDisabled
property bool collapsed: false
property int isComposite
property bool isLocked
property bool isLocked: false
property bool isActive: false
property bool isAudio
property bool showAudioRecord
property bool current: false
......@@ -103,13 +104,74 @@ Rectangle {
}
}
}
ColumnLayout {
id: targetColumn
width: root.baseUnit / 1.5
height: trackHeadRoot.height
Item {
width: parent.width
Layout.fillHeight: true
Layout.topMargin: 4
Layout.bottomMargin: 4
Layout.alignment: Qt.AlignVCenter
Rectangle {
id: trackTarget
color: 'grey'
anchors.fill: parent
width: height
border.width: 0
MouseArea {
anchors.fill: parent
onClicked: {
if (trackHeadRoot.isAudio) {
if (trackHeadRoot.trackId == timeline.audioTarget) {
timeline.audioTarget = -1;
} else {
timeline.audioTarget = trackHeadRoot.trackId;
}
} else {
if (trackHeadRoot.trackId == timeline.videoTarget) {
timeline.videoTarget = -1;
} else {
timeline.videoTarget = trackHeadRoot.trackId;
}
}
}
}
state: 'normalTarget'
states: [
State {
name: 'target'
when: (trackHeadRoot.isAudio && trackHeadRoot.trackId == timeline.audioTarget) || (!trackHeadRoot.isAudio && trackHeadRoot.trackId == timeline.videoTarget)
PropertyChanges {
target: trackTarget
color: 'green'
}
},
State {
name: 'noTarget'
when: !trackHeadRoot.isLocked && !trackHeadRoot.isDisabled
PropertyChanges {
target: trackTarget
color: 'grey'
}
}
]
transitions: [
Transition {
to: '*'
ColorAnimation { target: trackTarget; duration: 300 }
}
]
}
}
}
ColumnLayout {
id: trackHeadColumn
spacing: 0
anchors.fill: parent
anchors.leftMargin: 0
anchors.leftMargin: targetColumn.width
anchors.topMargin: 0
RowLayout {
spacing: 0
Layout.leftMargin: 2
......@@ -142,19 +204,7 @@ Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
if (trackHeadRoot.isAudio) {
if (trackHeadRoot.trackId == timeline.audioTarget) {
timeline.audioTarget = -1;
} else {
timeline.audioTarget = trackHeadRoot.trackId;
}
} else {
if (trackHeadRoot.trackId == timeline.videoTarget) {
timeline.videoTarget = -1;
} else {
timeline.videoTarget = trackHeadRoot.trackId;
}
}
timeline.switchTrackActive(trackHeadRoot.trackId)
}
}
state: 'normalled'
......@@ -168,8 +218,8 @@ Rectangle {
}
},
State {
name: 'target'
when: (trackHeadRoot.isAudio && trackHeadRoot.trackId == timeline.audioTarget) || (!trackHeadRoot.isAudio && trackHeadRoot.trackId == timeline.videoTarget)
name: 'active'
when: trackHeadRoot.isActive
PropertyChanges {
target: trackLed
color: 'yellow'
......@@ -184,8 +234,8 @@ Rectangle {
}
},
State {
name: 'normalled'
when: !trackHeadRoot.isLocked && !trackHeadRoot.isDisabled
name: 'inactive'
when: !trackHeadRoot.isLocked && !trackHeadRoot.isActive
PropertyChanges {
target: trackLed
color: 'grey'
......
......@@ -618,6 +618,7 @@ Rectangle {
isDisabled: model.disabled
isComposite: model.composite
isLocked: model.locked
isActive: model.trackActive
isAudio: model.audio
showAudioRecord: model.audioRecord
effectNames: model.effectNames
......
......@@ -1334,7 +1334,7 @@ void TimelineController::extractZone(QPoint zone, bool liftOnly)
auto it = m_model->m_allTracks.cbegin();
while (it != m_model->m_allTracks.cend()) {
int target_track = (*it)->getId();
if (m_model->getTrackById_const(target_track)->isLocked()) {
if (target_track != audioTarget() && target_track != videoTarget() && !m_model->getTrackById_const(target_track)->shouldReceiveTimelineOp()) {
++it;
continue;
}
......@@ -1516,11 +1516,17 @@ void TimelineController::alignAudio(int clipId)
m_audioCorrelator->addChild(envelope);
}
void TimelineController::switchTrackActive(int trackId)
{
bool active = m_model->getTrackById_const(trackId)->isTimelineActive();
m_model->setTrackProperty(trackId, QStringLiteral("kdenlive:timeline_active"), active ? QStringLiteral("0") : QStringLiteral("1"));
}
void TimelineController::switchTrackLock(bool applyToAll)
{
if (!applyToAll) {
// apply to active track only
bool locked = m_model->getTrackById_const(m_activeTrack)->getProperty("kdenlive:locked_track").toInt() == 1;
bool locked = m_model->getTrackById_const(m_activeTrack)->isLocked();
m_model->setTrackProperty(m_activeTrack, QStringLiteral("kdenlive:locked_track"), locked ? QStringLiteral("0") : QStringLiteral("1"));
} else {
// Invert track lock
......
......@@ -313,6 +313,7 @@ public:
Q_INVOKABLE void removeEffectKeyframe(int cid, int frame);
Q_INVOKABLE void updateEffectKeyframe(int cid, int oldFrame, int newFrame, const QVariant &normalizedValue = QVariant());
Q_INVOKABLE void switchTrackActive(int trackId);
void switchTrackLock(bool applyToAll = false);
void switchTargetTrack();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment