Skip to content

Commit

Permalink
add keyframes for colors in text filters
Browse files Browse the repository at this point in the history
GPS Text
Text: Simple
Timer
  • Loading branch information
ddennedy committed Aug 30, 2023
1 parent b9c73c8 commit 38af070
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 38 deletions.
9 changes: 6 additions & 3 deletions src/models/keyframesmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <Logger.h>

#include <QTimer>
#include <QRegularExpression>

static const quintptr NO_PARENT_ID = quintptr(-1);

Expand Down Expand Up @@ -449,6 +450,8 @@ void KeyframesModel::addKeyframe(int parameterIndex, int position)
if (m_filter && parameterIndex < m_propertyNames.count()) {
QString name = m_propertyNames[parameterIndex];
auto parameter = m_metadata->keyframes()->parameter(m_metadataIndex[parameterIndex]);
static auto regex = QRegularExpression("=#[0-9A-Fa-f]{6,8};");

if (parameter->isRectangle()) {
auto value = m_filter->getRect(name, position);
Mlt::Animation anim = m_filter->getAnimation(name);
Expand Down Expand Up @@ -483,9 +486,9 @@ void KeyframesModel::addKeyframe(int parameterIndex, int position)
m_filter->blockSignals(false);
emit keyframeAdded(name, position);
}
} else {
// Strings and color values
auto value = m_filter->get(name, position);
} else if (regex.match(m_filter->get(name)).hasMatch()) {
// Color values
auto value = m_filter->getColor(name, position);
Mlt::Animation anim = m_filter->getAnimation(name);
if (anim.is_valid() && !anim.is_key(position)) {
mlt_keyframe_type keyframeType = m_filter->getKeyframeType(anim, position, mlt_keyframe_type(-1));
Expand Down
3 changes: 1 addition & 2 deletions src/qml/filters/crop_rectangle/ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,8 @@ Shotcut.KeyframableFilter {
Component.onCompleted: isReady = true
onValueChanged: {
if (isReady) {
updateFilter('color', value, colorKeyframesButton, getPosition());
filter.set('disable', 0);
updateFilter('color', value, colorKeyframesButton, getPosition());
}
}
onPickStarted: {
Expand Down Expand Up @@ -459,7 +459,6 @@ Shotcut.KeyframableFilter {
Connections {
function onChanged() {
setRectControls();
setRectControls();
}

function onInChanged() {
Expand Down
15 changes: 15 additions & 0 deletions src/qml/filters/dynamictext/meta.qml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ Metadata {
name: qsTr('Position / Size')
property: 'geometry'
isRectangle: true
},
Parameter {
name: qsTr('Font color')
property: 'fgcolour'
isCurve: false
},
Parameter {
name: qsTr('Outline')
property: 'olcolour'
isCurve: false
},
Parameter {
name: qsTr('Background')
property: 'bgcolour'
isCurve: false
}
]
}
Expand Down
1 change: 1 addition & 0 deletions src/qml/filters/dynamictext/ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ Item {
parameters: textFilterUi.parameterList.concat(['argument'])
onBeforePresetLoaded: {
filter.resetProperty(textFilterUi.rectProperty);
textFilterUi.resetColorKeyframes();
}
onPresetSelected: {
setControls();
Expand Down
17 changes: 16 additions & 1 deletion src/qml/filters/gpstext/meta.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Meltytech, LLC
* Copyright (c) 2022-2023 Meltytech, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,6 +35,21 @@ Metadata {
name: qsTr('Position / Size')
property: 'geometry'
isRectangle: true
},
Parameter {
name: qsTr('Font color')
property: 'fgcolour'
isCurve: false
},
Parameter {
name: qsTr('Outline')
property: 'olcolour'
isCurve: false
},
Parameter {
name: qsTr('Background')
property: 'bgcolour'
isCurve: false
}
]
}
Expand Down
1 change: 1 addition & 0 deletions src/qml/filters/gpstext/ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ Item {
parameters: textFilterUi.parameterList.concat(['argument'])
onBeforePresetLoaded: {
filter.resetProperty(textFilterUi.rectProperty);
textFilterUi.resetColorKeyframes();
}
onPresetSelected: {
setControls();
Expand Down
15 changes: 15 additions & 0 deletions src/qml/filters/timer/meta.qml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ Metadata {
name: qsTr('Position / Size')
property: 'geometry'
isRectangle: true
},
Parameter {
name: qsTr('Font color')
property: 'fgcolour'
isCurve: false
},
Parameter {
name: qsTr('Outline')
property: 'olcolour'
isCurve: false
},
Parameter {
name: qsTr('Background')
property: 'bgcolour'
isCurve: false
}
]
}
Expand Down
1 change: 1 addition & 0 deletions src/qml/filters/timer/ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Item {
parameters: textFilterUi.parameterList.concat(['format', 'direction', 'start', 'duration'])
onBeforePresetLoaded: {
filter.resetProperty(textFilterUi.rectProperty);
textFilterUi.resetColorKeyframes();
}
onPresetSelected: {
setControls();
Expand Down
120 changes: 90 additions & 30 deletions src/qml/modules/Shotcut/Controls/TextFilterUi.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ GridLayout {
property string middleValue: '_shotcut:middleValue'
property string endValue: '_shotcut:endValue'
property var parameterList: [rectProperty, halignProperty, valignProperty, 'size', 'style', 'fgcolour', 'family', 'weight', 'olcolour', 'outline', 'bgcolour', 'pad', useFontSizeProperty]
property var keyframableParameters: ['fgcolour', 'olcolour', 'bgcolour']
property bool blockUpdate: true

function getPosition() {
return Math.max(producer.position - (filter.in - producer.in), 0);
}

function updateFilter(position) {
function updateFilterRect(position) {
if (position !== null) {
filter.blockSignals = true;
if (position <= 0 && filter.animateIn > 0)
Expand Down Expand Up @@ -87,11 +89,8 @@ GridLayout {
}

function setControls() {
fgColor.value = filter.get('fgcolour');
fontButton.text = filter.get('family');
outlineColor.value = filter.get('olcolour');
outlineSpinner.value = filter.getDouble('outline');
bgColor.value = filter.get('bgcolour');
padSpinner.value = filter.getDouble('pad');
var align = filter.get(halignProperty);
if (align === 'left')
Expand Down Expand Up @@ -128,12 +127,50 @@ GridLayout {
rectW.value = filterRect.width.toFixed();
rectH.value = filterRect.height.toFixed();
}
blockUpdate = true;
fgColor.value = filter.getColor('fgcolour', position);
outlineColor.value = filter.getColor('olcolour', position);
bgColor.value = filter.getColor('bgcolour', position);
blockUpdate = false;
var enabled = position <= 0 || (position >= (filter.animateIn - 1) && position <= (filter.duration - filter.animateOut)) || position >= (filter.duration - 1);
rectX.enabled = enabled;
rectY.enabled = enabled;
rectW.enabled = enabled;
rectH.enabled = enabled;
fgColor.enabled = enabled;
positionKeyframesButton.checked = filter.keyframeCount(rectProperty) > 0 && filter.animateIn <= 0 && filter.animateOut <= 0;
fgcolorKeyframesButton.checked = filter.keyframeCount('fgcolour') > 0 && filter.animateIn <= 0 && filter.animateOut <= 0;
olcolorKeyframesButton.checked = filter.keyframeCount('olcolour') > 0 && filter.animateIn <= 0 && filter.animateOut <= 0;
bgcolorKeyframesButton.checked = filter.keyframeCount('bgcolour') > 0 && filter.animateIn <= 0 && filter.animateOut <= 0;
}

function resetColorKeyframes() {
for (var i in keyframableParameters)
filter.resetProperty(keyframableParameters[i]);
}

function updateFilter(parameter, value, button, position) {
if (blockUpdate)
return;
if (button.checked && position !== null) {
filter.set(parameter, value, position);
} else if (position !== null) {
filter.set(parameter, value);
}
}

function toggleKeyframes(isEnabled, parameter, value) {
if (isEnabled) {
blockUpdate = true;
filter.clearSimpleAnimation(parameter);
blockUpdate = false;
// Set this keyframe value.
filter.set(parameter, value, getPosition());
} else {
// Remove keyframes and set the parameter.
filter.resetProperty(parameter);
filter.set(parameter, value);
}
}

function applyTracking(motionTrackerRow, operation, frame) {
Expand Down Expand Up @@ -196,12 +233,19 @@ GridLayout {
Layout.alignment: Qt.AlignRight
}

Shotcut.ColorPicker {
id: fgColor
RowLayout {
Shotcut.ColorPicker {
id: fgColor

eyedropper: false
alpha: true
onValueChanged: filter.set('fgcolour', value)
eyedropper: false
alpha: true
onValueChanged: updateFilter('fgcolour', value, fgcolorKeyframesButton, getPosition())
}

Shotcut.KeyframesButton {
id: fgcolorKeyframesButton
onToggled: toggleKeyframes(checked, 'fgcolour', fgColor.value)
}
}

RowLayout {
Expand Down Expand Up @@ -263,12 +307,20 @@ GridLayout {
Layout.alignment: Qt.AlignRight
}

Shotcut.ColorPicker {
id: outlineColor
RowLayout {
Shotcut.ColorPicker {
id: outlineColor

eyedropper: false
alpha: true
enabled: fgColor.enabled
onValueChanged: updateFilter('olcolour', value, olcolorKeyframesButton, getPosition())
}

eyedropper: false
alpha: true
onValueChanged: filter.set('olcolour', value)
Shotcut.KeyframesButton {
id: olcolorKeyframesButton
onToggled: toggleKeyframes(checked, 'olcolour', outlineColor.value)
}
}

Label {
Expand All @@ -291,12 +343,20 @@ GridLayout {
Layout.alignment: Qt.AlignRight
}

Shotcut.ColorPicker {
id: bgColor
RowLayout {
Shotcut.ColorPicker {
id: bgColor

eyedropper: false
alpha: true
onValueChanged: filter.set('bgcolour', value)
eyedropper: false
alpha: true
enabled: fgColor.enabled
onValueChanged: updateFilter('bgcolour', value, bgcolorKeyframesButton, getPosition())
}

Shotcut.KeyframesButton {
id: bgcolorKeyframesButton
onToggled: toggleKeyframes(checked, 'bgcolour', bgColor.value)
}
}

Label {
Expand Down Expand Up @@ -334,7 +394,7 @@ GridLayout {
onValueModified: {
if (filterRect.x !== value) {
filterRect.x = value;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}
}
Expand All @@ -357,7 +417,7 @@ GridLayout {
onValueModified: {
if (filterRect.y !== value) {
filterRect.y = value;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}
}
Expand All @@ -367,7 +427,7 @@ GridLayout {
onClicked: {
rectX.value = rectY.value = 0;
filterRect.x = filterRect.y = 0;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}

Expand Down Expand Up @@ -411,7 +471,7 @@ GridLayout {
onValueModified: {
if (filterRect.width !== value) {
filterRect.width = value;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}
}
Expand All @@ -434,7 +494,7 @@ GridLayout {
onValueModified: {
if (filterRect.height !== value) {
filterRect.height = value;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}
}
Expand All @@ -446,7 +506,7 @@ GridLayout {
rectH.value = profile.height;
filterRect.width = profile.width;
filterRect.height = profile.height;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}

Expand Down Expand Up @@ -550,7 +610,7 @@ GridLayout {
rectY.value = filterRect.y;
rectW.value = filterRect.width;
rectH.value = filterRect.height;
updateFilter(getPosition());
updateFilterRect(getPosition());
}
}

Expand All @@ -560,19 +620,19 @@ GridLayout {
}

function onInChanged() {
updateFilter(null);
updateFilterRect(null);
}

function onOutChanged() {
updateFilter(null);
updateFilterRect(null);
}

function onAnimateInChanged() {
updateFilter(null);
updateFilterRect(null);
}

function onAnimateOutChanged() {
updateFilter(null);
updateFilterRect(null);
}

target: filter
Expand Down
2 changes: 1 addition & 1 deletion src/qmltypes/qmlfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void QmlFilter::set(QString name, QString value, int position)
}
}

void QmlFilter::set(QString name, QColor value, int position, mlt_keyframe_type keyframeType)
void QmlFilter::set(QString name, const QColor &value, int position, mlt_keyframe_type keyframeType)
{
if (!m_service.is_valid()) return;
if (position < 0) {
Expand Down
Loading

0 comments on commit 38af070

Please sign in to comment.