Start showing parameters for same track mixes

parent ec6bd612
<!DOCTYPE kpartgui>
<transition tag="luma" id="luma" type="hidden">
<name>Luma</name>
<description>Applies a stationary transition between the current and next frames.</description>
<author>Dan Dennedy</author>
<parameter type="list" name="resource" default="" paramlist="%lumaPaths" optional="1">
<paramlistdisplay>%lumaNames</paramlistdisplay>
<name>Wipe Method</name>
</parameter>
<parameter type="double" name="softness" max="100" min="0" default="0" factor="100">
<name>Softness</name>
</parameter>
</transition>
......@@ -30,6 +30,7 @@
#include "transitions/transitionsrepository.hpp"
#include "effects/effectsrepository.hpp"
#include "transitions/view/transitionstackview.hpp"
#include "transitions/view/mixstackview.hpp"
#include "view/assetparameterview.hpp"
......@@ -53,6 +54,7 @@ AssetPanel::AssetPanel(QWidget *parent)
, m_lay(new QVBoxLayout(this))
, m_assetTitle(new KSqueezedTextLabel(this))
, m_container(new QWidget(this))
, m_mixWidget(new MixStackView(this))
, m_transitionWidget(new TransitionStackView(this))
, m_effectStackWidget(new EffectStackView(this))
{
......@@ -120,6 +122,7 @@ AssetPanel::AssetPanel(QWidget *parent)
auto *lay = new QVBoxLayout(m_container);
lay->setContentsMargins(0, 0, 0, 0);
lay->addWidget(m_transitionWidget);
lay->addWidget(m_mixWidget);
lay->addWidget(m_effectStackWidget);
m_sc = new QScrollArea;
m_sc->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
......@@ -135,6 +138,7 @@ AssetPanel::AssetPanel(QWidget *parent)
m_infoMessage->hide();
m_sc->setWidget(m_container);
m_transitionWidget->setVisible(false);
m_mixWidget->setVisible(false);
m_effectStackWidget->setVisible(false);
updatePalette();
connect(m_effectStackWidget, &EffectStackView::checkScrollBar, this, &AssetPanel::slotCheckWheelEventFilter);
......@@ -165,6 +169,28 @@ void AssetPanel::showTransition(int tid, const std::shared_ptr<AssetParameterMod
m_transitionWidget->setModel(transitionModel, QSize(), true);
}
void AssetPanel::showMix(int cid, const std::shared_ptr<AssetParameterModel> &transitionModel)
{
if (cid == -1) {
clear();
return;
}
ObjectId id = {ObjectType::TimelineMix, cid};
if (m_mixWidget->stackOwner() == id) {
// already on this effect stack, do nothing
return;
}
clear();
m_switchAction->setVisible(true);
m_titleAction->setVisible(false);
m_assetTitle->clear();
m_mixWidget->setVisible(true);
m_timelineButton->setVisible(false);
m_enableStackButton->setVisible(false);
m_mixWidget->setModel(transitionModel, QSize(), true);
}
void AssetPanel::showEffectStack(const QString &itemName, const std::shared_ptr<EffectStackModel> &effectsModel, QSize frameSize, bool showKeyframes)
{
if (effectsModel == nullptr) {
......@@ -260,11 +286,14 @@ void AssetPanel::clear()
m_switchAction->setVisible(false);
m_transitionWidget->setVisible(false);
m_transitionWidget->unsetModel();
m_mixWidget->setVisible(false);
m_mixWidget->unsetModel();
m_effectStackWidget->setVisible(false);
m_splitButton->setVisible(false);
m_timelineButton->setVisible(false);
m_switchBuiltStack->setVisible(false);
m_effectStackWidget->unsetModel();
m_assetTitle->setText(QString());
}
......
......@@ -44,6 +44,7 @@ class AssetParameterView;
class EffectStackModel;
class EffectStackView;
class TransitionStackView;
class MixStackView;
class QLabel;
class AssetPanel : public QWidget
......@@ -55,6 +56,8 @@ public:
/* @brief Shows the parameters of the given transition model */
void showTransition(int tid, const std::shared_ptr<AssetParameterModel> &transition_model);
/* @brief Shows the parameters of the given mix model */
void showMix(int cid, const std::shared_ptr<AssetParameterModel> &transitionModel);
/* @brief Shows the parameters of the given effect stack model */
void showEffectStack(const QString &itemName, const std::shared_ptr<EffectStackModel> &effectsModel, QSize frameSize, bool showKeyframes);
......@@ -85,6 +88,7 @@ protected:
KSqueezedTextLabel *m_assetTitle;
QWidget *m_container;
TransitionStackView *m_transitionWidget;
MixStackView *m_mixWidget;
EffectStackView *m_effectStackWidget;
private:
......
......@@ -1003,3 +1003,8 @@ void AssetParameterModel::passProperties(Mlt::Properties &target)
target.set("_profile", pCore->getCurrentProfile()->get_profile(), 0);
target.set_lcnumeric(m_asset->get_lcnumeric());
}
Mlt::Properties *AssetParameterModel::getAsset()
{
return m_asset.get();
}
......@@ -187,6 +187,9 @@ public:
/** @brief Returns the current value of an effect parameter */
const QString getParam(const QString &paramName);
/** @brief Returns the current asset */
Mlt::Properties *getAsset();
protected:
/* @brief Helper function to retrieve the type of a parameter given the string corresponding to it*/
......
......@@ -50,7 +50,7 @@ enum class GroupType {
const QString groupTypeToStr(GroupType t);
GroupType groupTypeFromStr(const QString &s);
enum class ObjectType { TimelineClip, TimelineComposition, TimelineTrack, BinClip, Master, NoItem };
enum class ObjectType { TimelineClip, TimelineComposition, TimelineTrack, TimelineMix, BinClip, Master, NoItem };
using ObjectId = std::pair<ObjectType, int>;
enum OperationType {
......
......@@ -351,6 +351,7 @@ void MainWindow::init()
getMainTimeline()->controller()->getModel()->switchComposition(cid, compositionId);
});
connect(m_timelineTabs, &TimelineTabs::showMixModel, m_assetPanel, &AssetPanel::showMix);
connect(m_timelineTabs, &TimelineTabs::showTransitionModel, m_assetPanel, &AssetPanel::showTransition);
connect(m_timelineTabs, &TimelineTabs::showTransitionModel, this, [&] () {
m_effectStackDock->raise();
......
......@@ -273,7 +273,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
}
}
for (auto compo : compositions) {
timeline->plantMix(tid, *compo);
timeline->plantMix(tid, compo);
}
std::shared_ptr<Mlt::Service> serv = std::make_shared<Mlt::Service>(track.get_service());
timeline->importTrackEffects(tid, serv);
......
......@@ -4383,6 +4383,13 @@ std::shared_ptr<EffectStackModel> TimelineModel::getClipEffectStackModel(int cli
return std::static_pointer_cast<EffectStackModel>(m_allClips.at(clipId)->m_effectStack);
}
std::shared_ptr<EffectStackModel> TimelineModel::getClipMixStackModel(int clipId) const
{
READ_LOCK();
Q_ASSERT(isClip(clipId));
return std::static_pointer_cast<EffectStackModel>(m_allClips.at(clipId)->m_effectStack);
}
std::shared_ptr<EffectStackModel> TimelineModel::getTrackEffectStackModel(int trackId)
{
READ_LOCK();
......@@ -4639,7 +4646,7 @@ bool TimelineModel::requestClearSelection(bool onDeletion)
TRACE();
if (m_selectedMix > -1) {
m_selectedMix = -1;
emit selectedMixChanged();
emit selectedMixChanged(-1, nullptr);
}
if (m_currentSelection == -1) {
TRACE_RES(true);
......@@ -4683,8 +4690,11 @@ bool TimelineModel::requestClearSelection(bool onDeletion)
void TimelineModel::requestMixSelection(int cid)
{
requestClearSelection();
m_selectedMix = cid;
emit selectedMixChanged();
int tid = getItemTrackId(cid);
if (tid > -1) {
m_selectedMix = cid;
emit selectedMixChanged(cid, getTrackById_const(tid)->mixModel(cid));
}
}
void TimelineModel::requestClearSelection(bool onDeletion, Fun &undo, Fun &redo)
......@@ -4909,9 +4919,9 @@ void TimelineModel::switchComposition(int cid, const QString &compoId)
}
}
void TimelineModel::plantMix(int tid, Mlt::Transition &t)
void TimelineModel::plantMix(int tid, Mlt::Transition *t)
{
getTrackById_const(tid)->getTrackService()->plant_transition(t, 0, 1);
getTrackById_const(tid)->getTrackService()->plant_transition(*t, 0, 1);
getTrackById_const(tid)->loadMix(t);
}
......
......@@ -250,6 +250,8 @@ public:
std::shared_ptr<AssetParameterModel> getCompositionParameterModel(int compoId) const;
/* @brief Given a clip Id, returns its underlying effect stack model */
std::shared_ptr<EffectStackModel> getClipEffectStackModel(int clipId) const;
/* @brief Given a clip Id, returns its mix transition stack model */
std::shared_ptr<EffectStackModel> getClipMixStackModel(int clipId) const;
/* @brief Returns the position of clip (-1 if it is not inserted)
@param clipId Id of the clip to test
......@@ -421,7 +423,7 @@ public:
void switchComposition(int cid, const QString &compoId);
/** @brief Plant a same track composition in track tid
*/
void plantMix(int tid, Mlt::Transition &t);
void plantMix(int tid, Mlt::Transition *t);
bool removeMix(int cid);
protected:
......@@ -801,7 +803,7 @@ signals:
/* @brief Signal sent whenever the selection changes */
void selectionChanged();
/* @brief Signal sent whenever the selected mix changes */
void selectedMixChanged();
void selectedMixChanged(int cid, const std::shared_ptr<AssetParameterModel> &asset);
/* @brief Signal when a track is deleted so we make sure we don't store its id */
void checkTrackDeletion(int tid);
/* @brief Emitted when a clip is deleted to check if it was not used in timeline qml */
......
......@@ -1012,7 +1012,7 @@ bool TrackModel::checkConsistency()
int mainId = -1;
int mixIn = t.get_in();
for ( auto it = m_sameCompositions.begin(); it != m_sameCompositions.end(); ++it ) {
if (it->second->get_in() == mixIn) {
if (static_cast<Mlt::Transition *>(it->second->getAsset())->get_in() == mixIn) {
// Found mix in list
mainId = it->first;
break;
......@@ -1523,7 +1523,7 @@ bool TrackModel::requestRemoveMix(std::pair<int, int> clipIds, Fun &undo, Fun &r
switchPlaylist(clipIds.second, secondInPos, 1, 0);
}
// Delete transition
Mlt::Transition &transition = *m_sameCompositions[clipIds.second].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[clipIds.second]->getAsset());
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(transition);
......@@ -1552,25 +1552,31 @@ bool TrackModel::requestRemoveMix(std::pair<int, int> clipIds, Fun &undo, Fun &r
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
movedClip->setMixDuration(mixDuration, mixCutPos);
// Insert mix transition
QString assetName;
std::unique_ptr<Mlt::Transition> t;
if (isAudioTrack()) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(mixPosition, mixPosition + mixDuration);
t->set("kdenlive:mixcut", mixCutPos);
if (src_track == 0) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("mix");
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(mixPosition, mixPosition + mixDuration);
t->set("kdenlive:mixcut", mixCutPos);
if (src_track == 0) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("luma");
}
QDomElement xml = TransitionsRepository::get()->getXml(assetName);
std::shared_ptr<AssetParameterModel> asset(new AssetParameterModel(std::move(t), xml, assetName, {ObjectType::TimelineMix, clipIds.second}, QString()));
m_sameCompositions[clipIds.second] = asset;
m_mixList.insert(clipIds.first, clipIds.second);
QModelIndex ix2 = ptr->makeClipIndexFromID(clipIds.second);
emit ptr->dataChanged(ix2, ix2, {TimelineModel::MixRole,TimelineModel::MixCutRole});
......@@ -1696,7 +1702,7 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
}
if (m_sameCompositions.count(i.key()) > 0) {
// There is a mix at clip start, adjust direction
Mlt::Transition &transition = *m_sameCompositions[i.key()].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[i.key()]->getAsset());
transition.set("reverse", i.value());
}
}
......@@ -1745,7 +1751,7 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
}
if (m_sameCompositions.count(i.key()) > 0) {
// There is a mix at clip start, adjust direction
Mlt::Transition &transition = *m_sameCompositions[i.key()].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[i.key()]->getAsset());
transition.set("reverse", 1 - i.value());
}
}
......@@ -1759,25 +1765,30 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
movedClip->setMixDuration(mixDuration, secondClipCut);
// Insert mix transition
QString assetName;
std::unique_ptr<Mlt::Transition>t;
if (isAudioTrack()) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(mixPosition, mixPosition + mixDuration);
t->set("kdenlive:mixcut", secondClipCut);
if (dest_track == 0) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("mix");
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(mixPosition, mixPosition + mixDuration);
t->set("kdenlive:mixcut", secondClipCut);
if (dest_track == 0) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("luma");
}
QDomElement xml = TransitionsRepository::get()->getXml(assetName);
std::shared_ptr<AssetParameterModel> asset(new AssetParameterModel(std::move(t), xml, assetName, {ObjectType::TimelineMix, clipIds.second}, QString()));
m_sameCompositions[clipIds.second] = asset;
m_mixList.insert(clipIds.first, clipIds.second);
}
return true;
......@@ -1785,7 +1796,7 @@ bool TrackModel::requestClipMix(std::pair<int, int> clipIds, int mixDuration, bo
Fun destroy_mix = [clipIds, this]() {
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[clipIds.second].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[clipIds.second]->getAsset());
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipIds.second));
movedClip->setMixDuration(0);
QModelIndex ix = ptr->makeClipIndexFromID(clipIds.second);
......@@ -1917,7 +1928,7 @@ bool TrackModel::deleteMix(int clipId, bool final, bool notify)
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole,TimelineModel::MixCutRole});
}
if (final) {
Mlt::Transition &transition = *m_sameCompositions[clipId].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[clipId]->getAsset());
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(transition);
......@@ -1946,23 +1957,28 @@ bool TrackModel::createMix(MixInfo info, bool isAudio)
int out = in + movedClip->getMixDuration();
movedClip->setMixDuration(out - in);
bool reverse = movedClip->getSubPlaylistIndex() == 0;
QString assetName;
std::unique_ptr<Mlt::Transition> t;
if (isAudio) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(in, out);
if (reverse) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[info.secondClipId] = t;
assetName = QStringLiteral("mix");
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(in, out);
if (reverse) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[info.secondClipId] = t;
assetName = QStringLiteral("luma");
}
QDomElement xml = TransitionsRepository::get()->getXml(assetName);
std::shared_ptr<AssetParameterModel> asset(new AssetParameterModel(std::move(t), xml, assetName, {ObjectType::TimelineMix, info.secondClipId}, QString()));
m_sameCompositions[info.secondClipId] = asset;
m_mixList.insert(info.firstClipId, info.secondClipId);
return true;
}
......@@ -1981,23 +1997,28 @@ bool TrackModel::createMix(std::pair<int, int> clipIds, std::pair<int, int> mixD
emit ptr->dataChanged(ix, ix, {TimelineModel::MixRole,TimelineModel::MixCutRole});
bool reverse = movedClip->getSubPlaylistIndex() == 0;
// Insert mix transition
QString assetName;
std::unique_ptr<Mlt::Transition> t;
if (isAudioTrack()) {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "mix"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "mix"));
t->set_in_and_out(mixData.first, mixData.first + mixData.second);
if (reverse) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("mix");
} else {
std::shared_ptr<Mlt::Transition> t(new Mlt::Transition(*ptr->getProfile(), "luma"));
t.reset(new Mlt::Transition(*ptr->getProfile(), "luma"));
t->set_in_and_out(mixData.first, mixData.first + mixData.second);
if (reverse) {
t->set("reverse", 1);
}
m_track->plant_transition(*t.get(), 0, 1);
m_sameCompositions[clipIds.second] = t;
assetName = QStringLiteral("luma");
}
QDomElement xml = TransitionsRepository::get()->getXml(assetName);
std::shared_ptr<AssetParameterModel> asset(new AssetParameterModel(std::move(t), xml, assetName, {ObjectType::TimelineMix, clipIds.second}, QString()));
m_sameCompositions[clipIds.second] = asset;
m_mixList.insert(clipIds.first, clipIds.second);
return true;
}
......@@ -2007,7 +2028,7 @@ bool TrackModel::createMix(std::pair<int, int> clipIds, std::pair<int, int> mixD
void TrackModel::setMixDuration(int cid, int mixDuration, int mixCut)
{
m_allClips[cid]->setMixDuration(mixDuration, mixCut);
m_sameCompositions[cid]->set("kdenlive:mixcut", mixCut);
m_sameCompositions[cid]->getAsset()->set("kdenlive:mixcut", mixCut);
}
void TrackModel::syncronizeMixes(bool finalMove)
......@@ -2021,7 +2042,7 @@ void TrackModel::syncronizeMixes(bool finalMove)
if (m_allClips.find(firstClip) == m_allClips.end() || m_allClips.find(secondClipId) == m_allClips.end()) {
// One of the clip was removed, delete the mix
qDebug()<<"=== CLIPS: "<<firstClip<<" / "<<secondClipId<<" ARE MISSING!!!!";
Mlt::Transition &transition = *m_sameCompositions[secondClipId].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[secondClipId]->getAsset());
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
field->disconnect_service(transition);
......@@ -2041,7 +2062,7 @@ void TrackModel::syncronizeMixes(bool finalMove)
mixOut = mixIn + 1;
}
}
Mlt::Transition &transition = *m_sameCompositions[secondClipId].get();
Mlt::Transition &transition = *static_cast<Mlt::Transition*>(m_sameCompositions[secondClipId]->getAsset());
if (mixIn == mixOut) {
QScopedPointer<Mlt::Field> field(m_track->field());
field->lock();
......@@ -2090,19 +2111,31 @@ bool TrackModel::hasEndMix(int cid) const
return m_mixList.contains(cid);
}
bool TrackModel::loadMix(Mlt::Transition &t)
bool TrackModel::loadMix(Mlt::Transition *t)
{
int in = t.get_in();
int out = t.get_out();
bool reverse = t.get_int("reverse") == 1;
int in = t->get_in();
int out = t->get_out();
bool reverse = t->get_int("reverse") == 1;
int cid1 = getClipByPosition(in, reverse ? 1 : 0);
int cid2 = getClipByPosition(out, reverse ? 0 : 1);
if (cid1 < 0 || cid2 < 0) {
return false;
}
std::shared_ptr<Mlt::Transition>tr(&t);
m_sameCompositions[cid2] = tr;
const QString assetId(t->get("mlt_service"));
std::unique_ptr<Mlt::Transition>tr(t);
QDomElement xml = TransitionsRepository::get()->getXml(assetId);
qDebug()<<"=====\n\nLOADING MIX: "<<assetId<<", XML: \n\n"<<xml.ownerDocument().toString()<<"\n\n==================";
std::shared_ptr<AssetParameterModel> asset(new AssetParameterModel(std::move(tr), xml, assetId, {ObjectType::TimelineMix, cid2}, QString()));
m_sameCompositions[cid2] = asset;
m_mixList.insert(cid1, cid2);
setMixDuration(cid2, t.get_length() - 1, t.get_int("kdenlive:mixcut"));
setMixDuration(cid2, t->get_length() - 1, t->get_int("kdenlive:mixcut"));
return true;
}
const std::shared_ptr<AssetParameterModel> TrackModel::mixModel(int cid)
{
if (m_sameCompositions.count(cid) > 0) {
return m_sameCompositions[cid];
}
return nullptr;
}
......@@ -36,6 +36,7 @@ class TimelineModel;
class ClipModel;
class CompositionModel;
class EffectStackModel;
class AssetParameterModel;
class MixInfo
{
......@@ -135,9 +136,11 @@ public:
/** @brief Switch a clip from one playlist to the other */
bool switchPlaylist(int clipId, int position, int sourcePlaylist, int destPlaylist);
/** @brief Load a same track transition from project */
bool loadMix(Mlt::Transition &t);
bool loadMix(Mlt::Transition *t);
/** @brief Set mix duration and mix cut pos on a clip */
void setMixDuration(int cid, int mixDuration, int mixCut);
/** @brief Get the assetparameter model for a mix */
const std::shared_ptr<AssetParameterModel> mixModel(int cid);
protected:
/* @brief This will lock the track: it will no longer allow insertion/deletion/resize of items
......@@ -339,7 +342,7 @@ private:
protected:
std::shared_ptr<EffectStackModel> m_effectStack;
// A list of same track transitions for this track, in the form: {second_clip_id, transition}
std::unordered_map<int, std::shared_ptr<Mlt::Transition>> m_sameCompositions;
std::unordered_map<int, std::shared_ptr<AssetParameterModel>> m_sameCompositions;
};
#endif
......@@ -122,7 +122,10 @@ void TimelineController::setModel(std::shared_ptr<TimelineItemModel> model)
connect(m_model.get(), &TimelineModel::invalidateZone, this, &TimelineController::invalidateZone, Qt::DirectConnection);
connect(m_model.get(), &TimelineModel::durationUpdated, this, &TimelineController::checkDuration);
connect(m_model.get(), &TimelineModel::selectionChanged, this, &TimelineController::selectionChanged);
connect(m_model.get(), &TimelineModel::selectedMixChanged, this, &TimelineController::selectedMixChanged);
connect(m_model.get(), &TimelineModel::selectedMixChanged, [this] (int cid, const std::shared_ptr<AssetParameterModel> &asset) {
emit showMixModel(cid, asset);
emit selectedMixChanged();
});
connect(m_model.get(), &TimelineModel::checkTrackDeletion, this, &TimelineController::checkTrackDeletion, Qt::DirectConnection);
}
......
......@@ -664,6 +664,8 @@ signals:
void zoneMoved(const QPoint &zone);
/* @brief Requests that a given parameter model is displayed in the asset panel */
void showTransitionModel(int tid, std::shared_ptr<AssetParameterModel>);
/* @brief Requests that a given mix is displayed in the asset panel */
void showMixModel(int cid, const std::shared_ptr<AssetParameterModel> &asset);
void showItemEffectStack(const QString &clipName, std::shared_ptr<EffectStackModel>, QSize frameSize, bool showKeyframes);
/* @brief notify of chunks change
*/
......
......@@ -83,6 +83,7 @@ void TimelineTabs::connectTimeline(TimelineWidget *timeline)
connect(this, &TimelineTabs::changeZoom, timeline, &TimelineWidget::slotChangeZoom);
connect(this, &TimelineTabs::fitZoom, timeline, &TimelineWidget::slotFitZoom);
connect(timeline->controller(), &TimelineController::showTransitionModel, this, &TimelineTabs::showTransitionModel);
connect(timeline->controller(), &TimelineController::showMixModel, this, &TimelineTabs::showMixModel);
connect(timeline->controller(), &TimelineController::updateZoom, this, [&](double value) { emit updateZoom(getCurrentTimeline()->zoomForScale(value)); });
connect(timeline->controller(), &TimelineController::showItemEffectStack, this, &TimelineTabs::showItemEffectStack);
}
......@@ -96,6 +97,7 @@ void TimelineTabs::disconnectTimeline(TimelineWidget *timeline)
disconnect(this, &TimelineTabs::showAudioThumbnailsChanged, timeline->controller(), &TimelineController::showAudioThumbnailsChanged);
disconnect(this, &TimelineTabs::changeZoom, timeline, &TimelineWidget::slotChangeZoom);
disconnect(timeline->controller(), &TimelineController::showTransitionModel, this, &TimelineTabs::showTransitionModel);
disconnect(timeline->controller(), &TimelineController::showMixModel, this, &TimelineTabs::showMixModel);
disconnect(timeline->controller(), &TimelineController::showItemEffectStack, this, &TimelineTabs::showItemEffectStack);
delete timeline;
}
......@@ -84,6 +84,8 @@ signals:
void fitZoom();
/* @brief Requests that a given parameter model is displayed in the asset panel */
void showTransitionModel(int tid, std::shared_ptr<AssetParameterModel>);
/* @brief Requests that a given mix is displayed in the asset panel */
void showMixModel(int cid, std::shared_ptr<AssetParameterModel>);
/* @brief Requests that a given effectstack model is displayed in the asset panel */
void showItemEffectStack(const QString &clipName, std::shared_ptr<EffectStackModel>, QSize, bool);
/** @brief Zoom level changed in timeline, update slider
......
......@@ -6,5 +6,6 @@ set(kdenlive_SRCS
transitions/transitionlist/model/transitionfilter.cpp
transitions/view/transitionparameterview.cpp
transitions/view/transitionstackview.cpp
transitions/view/mixstackview.cpp
PARENT_SCOPE)
/***************************************************************************
* Copyright (C) 2017 by Nicolas Carion *
* This file is part of Kdenlive. See www.kdenlive.org. *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/