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

Commit 5c75b714 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Effects can now be applied on master (click the grid icon above track headers...

Effects can now be applied on master (click the grid icon above track headers to see master effectstack)
parent 6607e29b
......@@ -387,6 +387,7 @@ int Core::getItemPosition(const ObjectId &id)
break;
case ObjectType::BinClip:
case ObjectType::TimelineTrack:
case ObjectType::Master:
return 0;
break;
default:
......@@ -412,6 +413,7 @@ int Core::getItemIn(const ObjectId &id)
case ObjectType::TimelineComposition:
case ObjectType::BinClip:
case ObjectType::TimelineTrack:
case ObjectType::Master:
return 0;
break;
default:
......@@ -437,6 +439,9 @@ PlaylistState::ClipState Core::getItemState(const ObjectId &id)
break;
case ObjectType::TimelineTrack:
return m_mainWindow->getCurrentTimeline()->controller()->getModel()->isAudioTrack(id.second) ? PlaylistState::AudioOnly : PlaylistState::VideoOnly;
case ObjectType::Master:
return PlaylistState::Disabled;
break;
default:
qDebug() << "ERROR: unhandled object type";
break;
......@@ -462,6 +467,7 @@ int Core::getItemDuration(const ObjectId &id)
return (int)m_binWidget->getClipDuration(id.second);
break;
case ObjectType::TimelineTrack:
case ObjectType::Master:
return m_mainWindow->getCurrentTimeline()->controller()->duration();
default:
qDebug() << "ERROR: unhandled object type";
......@@ -505,6 +511,9 @@ void Core::refreshProjectItem(const ObjectId &id)
case ObjectType::BinClip:
m_monitorManager->refreshClipMonitor();
break;
case ObjectType::Master:
requestMonitorRefresh();
break;
default:
qDebug() << "ERROR: unhandled object type";
}
......@@ -581,6 +590,8 @@ std::shared_ptr<EffectStackModel> Core::getItemEffectStack(int itemType, int ite
break;
case (int)ObjectType::BinClip:
return m_binWidget->getClipEffectStack(itemId);
case (int)ObjectType::Master:
return m_mainWindow->getCurrentTimeline()->controller()->getModel()->getMasterEffectStackModel();
default:
return nullptr;
}
......@@ -639,6 +650,9 @@ void Core::invalidateItem(ObjectId itemId)
case ObjectType::BinClip:
m_binWidget->invalidateClip(QString::number(itemId.second));
break;
case ObjectType::Master:
m_mainWindow->getCurrentTimeline()->controller()->invalidateZone(0, -1);
break;
default:
// compositions should not have effects
break;
......
......@@ -50,7 +50,7 @@ enum class GroupType {
const QString groupTypeToStr(GroupType t);
GroupType groupTypeFromStr(const QString &s);
enum class ObjectType { TimelineClip, TimelineComposition, TimelineTrack, BinClip, NoItem };
enum class ObjectType { TimelineClip, TimelineComposition, TimelineTrack, BinClip, Master, NoItem };
using ObjectId = std::pair<ObjectType, int>;
enum OperationType {
......
......@@ -65,12 +65,8 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
qDebug() << "//////////////////////\nTrying to construct" << tractor.count() << "tracks.\n////////////////////////////////";
// Import master track effects
for (int i = 0; i < tractor.filter_count(); i++) {
std::unique_ptr<Mlt::Filter> filter(tractor.filter(i));
if (filter->get_int("internal_added") > 0) {
timeline->tractor()->attach(*filter.get());
}
}
std::shared_ptr<Mlt::Service> serv = std::make_shared<Mlt::Service>(tractor.get_service());
timeline->importMasterEffects(serv);
QList <int> videoTracksIndexes;
QList <int> lockedTracksIndexes;
......
......@@ -107,6 +107,7 @@ TimelineModel::TimelineModel(Mlt::Profile *profile, std::weak_ptr<DocUndoStack>
: QAbstractItemModel_shared_from_this()
, m_blockRefresh(false)
, m_tractor(new Mlt::Tractor(*profile))
, m_masterStack(nullptr)
, m_snaps(new SnapModel())
, m_undoStack(std::move(undo_stack))
, m_profile(profile)
......@@ -3140,6 +3141,26 @@ std::shared_ptr<EffectStackModel> TimelineModel::getTrackEffectStackModel(int tr
return getTrackById(trackId)->m_effectStack;
}
std::shared_ptr<EffectStackModel> TimelineModel::getMasterEffectStackModel()
{
READ_LOCK();
if (m_masterStack == nullptr) {
m_masterService.reset(new Mlt::Service(*m_tractor.get()));
m_masterStack = EffectStackModel::construct(m_masterService, {ObjectType::Master, 0}, m_undoStack);
}
return m_masterStack;
}
void TimelineModel::importMasterEffects(std::weak_ptr<Mlt::Service> service)
{
READ_LOCK();
if (m_masterStack == nullptr) {
getMasterEffectStackModel();
}
m_masterStack->importEffects(std::move(service), PlaylistState::Disabled);
}
QStringList TimelineModel::extractCompositionLumas() const
{
QStringList urls;
......
......@@ -629,6 +629,7 @@ public:
/** @brief Returns the effectstack of a given clip. */
std::shared_ptr<EffectStackModel> getClipEffectStack(int itemId);
std::shared_ptr<EffectStackModel> getTrackEffectStackModel(int trackId);
std::shared_ptr<EffectStackModel> getMasterEffectStackModel();
/** @brief Add slowmotion effect to clip in timeline.
@param clipId id of the target clip
......@@ -671,6 +672,8 @@ public:
/** @brief Do some cleanup before closing */
void prepareClose();
/** @brief Import project's master effects */
void importMasterEffects(std::weak_ptr<Mlt::Service> service);
protected:
/* @brief Register a new track. This is a call-back meant to be called from TrackModel
......@@ -772,7 +775,8 @@ signals:
protected:
std::unique_ptr<Mlt::Tractor> m_tractor;
std::shared_ptr<EffectStackModel> m_masterStack;
std::shared_ptr<Mlt::Service> m_masterService;
std::list<std::shared_ptr<TrackModel>> m_allTracks;
std::unordered_map<int, std::list<std::shared_ptr<TrackModel>>::iterator>
......
import QtQuick 2.6
import QtQml.Models 2.2
import QtQuick.Controls 1.4 as OLD
import QtQuick.Controls 1.5 as OLD
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
......@@ -738,6 +739,13 @@ Rectangle {
border.color: selected? 'red' : 'transparent'
border.width: selected? 1 : 0
z: 1
OLD.ToolButton {
iconName: "kdenlive-composite"
tooltip: i18n("Show master effects")
onClicked: {
timeline.showMasterEffects()
}
}
}
Flickable {
// Non-slider scroll area for the track headers.
......
......@@ -1572,7 +1572,7 @@ void TimelineController::invalidateZone(int in, int out)
if (!m_timelinePreview) {
return;
}
m_timelinePreview->invalidatePreview(in, out);
m_timelinePreview->invalidatePreview(in, out == -1 ? m_duration : out);
}
void TimelineController::changeItemSpeed(int clipId, double speed)
......@@ -2689,3 +2689,9 @@ bool TimelineController::hasActiveTracks() const
}
return false;
}
void TimelineController::showMasterEffects()
{
emit showItemEffectStack(i18n("Master effects"), m_model->getMasterEffectStackModel(), pCore->getCurrentFrameSize(), false);
}
......@@ -475,6 +475,8 @@ public:
/** @brief Return true if an overlay track is used */
bool hasPreviewTrack() const;
void updatePreviewConnection(bool enable);
/** @brief Display project master effects */
Q_INVOKABLE void showMasterEffects();
public slots:
void resetView();
......
  • Interesting feature but I wonder if the button could act as a toggle, so when you click again it shows the "normal" effect stack.

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