diff --git a/src/core/Boxes/animationbox.cpp b/src/core/Boxes/animationbox.cpp index a484f6833..478850b3f 100644 --- a/src/core/Boxes/animationbox.cpp +++ b/src/core/Boxes/animationbox.cpp @@ -96,6 +96,22 @@ void AnimationBox::animationDataChanged() { prp_afterWholeInfluenceRangeChanged(); } +void AnimationBox::setStretch(const qreal stretch) +{ + { + prp_pushUndoRedoName(tr("Stretch")); + UndoRedo ur; + const auto oldValue = mStretch; + const auto newValue = stretch; + ur.fUndo = [this, oldValue]() { setStretch(oldValue); }; + ur.fRedo = [this, newValue]() { setStretch(newValue); }; + prp_addUndoRedo(ur); + } + mStretch = stretch; + prp_afterWholeInfluenceRangeChanged(); + updateAnimationRange(); +} + bool AnimationBox::shouldScheduleUpdate() { if(!mSrcFramesCache) return false; return BoundingBox::shouldScheduleUpdate(); diff --git a/src/core/Boxes/animationbox.h b/src/core/Boxes/animationbox.h index 672523036..4434fcd6f 100644 --- a/src/core/Boxes/animationbox.h +++ b/src/core/Boxes/animationbox.h @@ -41,11 +41,7 @@ class CORE_EXPORT AnimationBox : public BoundingBox { public: virtual void changeSourceFile() = 0; void animationDataChanged(); - virtual void setStretch(const qreal stretch) { - mStretch = stretch; - prp_afterWholeInfluenceRangeChanged(); - updateAnimationRange(); - } + virtual void setStretch(const qreal stretch); void anim_setAbsFrame(const int frame); diff --git a/src/core/Boxes/videobox.cpp b/src/core/Boxes/videobox.cpp index 286dd0a35..51dd53366 100644 --- a/src/core/Boxes/videobox.cpp +++ b/src/core/Boxes/videobox.cpp @@ -24,6 +24,7 @@ // Fork of enve - Copyright (C) 2016-2020 Maurycy Liebner #include "videobox.h" +#include "ReadWrite/evformat.h" extern "C" { #include @@ -60,7 +61,7 @@ VideoBox::VideoBox() : AnimationBox("Video", eBoxType::video), const auto flar = getDurationRectangle()->ref(); mSound = enve::make_shared(flar); ca_addChild(mSound); - mSound->hide(); + //mSound->hide(); // should be on by default mSound->SWT_hide(); connect(this, &eBoxOrSound::parentChanged, @@ -103,12 +104,18 @@ void VideoBox::fileHandlerAfterAssigned(VideoFileHandler *obj) { void VideoBox::writeBoundingBox(eWriteStream& dst) const { AnimationBox::writeBoundingBox(dst); dst.writeFilePath(mFileHandler->path()); + dst << getStretch(); } void VideoBox::readBoundingBox(eReadStream& src) { AnimationBox::readBoundingBox(src); const QString path = src.readFilePath(); setFilePathNoRename(path); + if (src.evFileVersion() >= EvFormat::avStretch) { + qreal stretch; + src >> stretch; + setStretch(stretch); + } } QDomElement VideoBox::prp_writePropertyXEV_impl(const XevExporter& exp) const { @@ -163,27 +170,26 @@ const VideoBox::VideoSpecs VideoBox::getSpecs() return specs; } -void VideoBox::soundDataChanged() { +void VideoBox::soundDataChanged() +{ const auto pScene = getParentScene(); const auto soundHandler = mFileHandler ? mFileHandler->getSoundHandler() : nullptr; const auto durRect = getDurationRectangle(); - if(soundHandler) { - if(!mSound->SWT_isVisible()) { - if(pScene) { - pScene->getSoundComposition()->addSound(mSound); - } + if (soundHandler) { + if (!mSound->SWT_isVisible()) { + if (pScene) { pScene->getSoundComposition()->addSound(mSound); } } durRect->setSoundCacheHandler(&soundHandler->getCacheHandler()); } else { - if(mSound->SWT_isVisible()) { - if(pScene) { - pScene->getSoundComposition()->removeSound(mSound); - } + if (mSound->SWT_isVisible()) { + if (pScene) { pScene->getSoundComposition()->removeSound(mSound); } } durRect->setSoundCacheHandler(nullptr); } mSound->setSoundDataHandler(soundHandler); mSound->SWT_setVisible(soundHandler); - mSound->setVisible(soundHandler); + + // why? this does not make any sense to me + //mSound->setVisible(soundHandler); } diff --git a/src/core/ReadWrite/evformat.h b/src/core/ReadWrite/evformat.h index 6d584beaa..5d45c54ff 100644 --- a/src/core/ReadWrite/evformat.h +++ b/src/core/ReadWrite/evformat.h @@ -45,6 +45,7 @@ namespace EvFormat { formatOptions = 30, formatOptions2 = 31, subPathOffset = 32, + avStretch = 33, nextVersion }; diff --git a/src/core/Sound/eindependentsound.cpp b/src/core/Sound/eindependentsound.cpp index 7f618337c..3b1d1bd26 100644 --- a/src/core/Sound/eindependentsound.cpp +++ b/src/core/Sound/eindependentsound.cpp @@ -25,128 +25,155 @@ #include "eindependentsound.h" +#include + +#include "ReadWrite/evformat.h" +#include "typemenu.h" #include "Timeline/fixedlenanimationrect.h" #include "fileshandler.h" +#include "ReadWrite/basicreadwrite.h" -SoundFileHandler* soundFileHandlerGetter(const QString& path) { +SoundFileHandler* soundFileHandlerGetter(const QString& path) +{ return FilesHandler::sInstance->getFileHandler(path); } -qsptr createIndependentSoundDur( - eIndependentSound* const sound) { +qsptr createIndependentSoundDur(eIndependentSound* const sound) +{ const auto result = enve::make_shared(*sound, true); return result; } -eIndependentSound::eIndependentSound() : - eSoundObjectBase(createIndependentSoundDur(this)), - mFileHandler(this, - [](const QString& path) { - return soundFileHandlerGetter(path); - }, - [this](SoundFileHandler* obj) { - fileHandlerAfterAssigned(obj); - }, - [this](ConnContext& conn, SoundFileHandler* obj) { - fileHandlerConnector(conn, obj); - }) { - -} - -void eIndependentSound::fileHandlerConnector(ConnContext &conn, SoundFileHandler *obj) { +eIndependentSound::eIndependentSound() + : eSoundObjectBase(createIndependentSoundDur(this)) + , mFileHandler(this, + [](const QString& path) { + return soundFileHandlerGetter(path); + }, + [this](SoundFileHandler* obj) { + fileHandlerAfterAssigned(obj); + }, + [this](ConnContext& conn, SoundFileHandler* obj) { + fileHandlerConnector(conn, obj); + }) +{} + +void eIndependentSound::fileHandlerConnector(ConnContext &conn, + SoundFileHandler *obj) +{ conn << connect(obj, &SoundFileHandler::pathChanged, this, &eSoundObjectBase::prp_afterWholeInfluenceRangeChanged); conn << connect(obj, &SoundFileHandler::reloaded, this, &eSoundObjectBase::prp_afterWholeInfluenceRangeChanged); } -void eIndependentSound::fileHandlerAfterAssigned(SoundFileHandler *obj) { +void eIndependentSound::fileHandlerAfterAssigned(SoundFileHandler *obj) +{ if(obj) { - const auto newDataHandler = FileDataCacheHandler:: - sGetDataHandler(obj->path()); + const auto newDataHandler = FileDataCacheHandler::sGetDataHandler(obj->path()); setSoundDataHandler(newDataHandler); } else { setSoundDataHandler(nullptr); } } -#include -#include "typemenu.h" -void eIndependentSound::prp_setupTreeViewMenu(PropertyMenu * const menu) { - if(menu->hasActionsForType()) return; + +void eIndependentSound::prp_setupTreeViewMenu(PropertyMenu * const menu) +{ + if (menu->hasActionsForType()) { return; } menu->addedActionsForType(); eSoundObjectBase::prp_setupTreeViewMenu(menu); - const auto widget = menu->getParentWidget(); - const PropertyMenu::PlainSelectedOp stretchOp = - [this, widget](eIndependentSound * sound) { + + const PropertyMenu::PlainTriggeredOp stretchOp = [this]() { bool ok = false; - const int stretch = QInputDialog::getInt( - widget, "Stretch " + sound->prp_getName(), - "Stretch:", qRound(getStretch()*100), - -1000, 1000, 1, &ok); - if(!ok) return; - sound->setStretch(stretch*0.01); + const int stretch = QInputDialog::getInt(nullptr, + tr("Stretch"), + tr("Stretch"), + qRound(getStretch() * 100), + -1000, + 1000, + 1, + &ok); + if (!ok) { return; } + setStretch(stretch * 0.01); }; - menu->addPlainAction(QIcon::fromTheme("width"), tr("Stretch"), stretchOp); + menu->addPlainAction(QIcon::fromTheme("width"), + tr("Stretch"), + stretchOp); const PropertyMenu::PlainTriggeredOp deleteOp = [this]() { removeFromParent_k(); }; - menu->addPlainAction(QIcon::fromTheme("trash"), tr("Delete"), deleteOp); + menu->addPlainAction(QIcon::fromTheme("trash"), + tr("Delete"), + deleteOp); } bool eIndependentSound::SWT_shouldBeVisible(const SWT_RulesCollection &rules, const bool parentSatisfies, - const bool parentMainTarget) const { + const bool parentMainTarget) const +{ Q_UNUSED(parentMainTarget); - if(rules.fRule == SWT_BoxRule::visible && !isVisible()) return false; - if(rules.fRule == SWT_BoxRule::selected && !isSelected()) return false; - if(rules.fType == SWT_Type::sound) return true; - if(rules.fType == SWT_Type::graphics) return false; + if (rules.fRule == SWT_BoxRule::visible && !isVisible()) { return false; } + if (rules.fRule == SWT_BoxRule::selected && !isSelected()) { return false; } + if (rules.fType == SWT_Type::sound) { return true; } + if (rules.fType == SWT_Type::graphics) { return false; } return parentSatisfies; } -void eIndependentSound::setFilePathNoRename(const QString &path) { +void eIndependentSound::setFilePathNoRename(const QString &path) +{ mFileHandler.assign(path); } -void eIndependentSound::setFilePath(const QString &path) { +void eIndependentSound::setFilePath(const QString &path) +{ setFilePathNoRename(path); rename(QFileInfo(path).completeBaseName()); } -void eIndependentSound::updateDurationRectLength() { - if(cacheHandler() && getParentScene()) { +void eIndependentSound::updateDurationRectLength() +{ + if (cacheHandler() && getParentScene()) { const qreal secs = durationSeconds(); const qreal fps = getCanvasFPS(); - const int frames = qCeil(qAbs(secs*fps*getStretch())); - const auto flaRect = static_cast( - getDurationRectangle()); + const int frames = qCeil(qAbs(secs * fps * getStretch())); + const auto flaRect = static_cast(getDurationRectangle()); flaRect->setAnimationFrameDuration(frames); } } -#include "ReadWrite/basicreadwrite.h" -void eIndependentSound::prp_writeProperty_impl(eWriteStream& dst) const { +void eIndependentSound::prp_writeProperty_impl(eWriteStream& dst) const +{ eBoxOrSound::prp_writeProperty_impl(dst); dst.writeFilePath(mFileHandler.path()); + dst << getStretch(); } -void eIndependentSound::prp_readProperty_impl(eReadStream& src) { +void eIndependentSound::prp_readProperty_impl(eReadStream& src) +{ eBoxOrSound::prp_readProperty_impl(src); const QString filePath = src.readFilePath(); - if(!filePath.isEmpty()) setFilePathNoRename(filePath); + if (!filePath.isEmpty()) { setFilePathNoRename(filePath); } + if (src.evFileVersion() >= EvFormat::avStretch) { + qreal stretch; + src >> stretch; + setStretch(stretch); + } } -QDomElement eIndependentSound::prp_writePropertyXEV_impl(const XevExporter& exp) const { +QDomElement eIndependentSound::prp_writePropertyXEV_impl(const XevExporter& exp) const +{ auto result = eBoxOrSound::prp_writePropertyXEV_impl(exp); const QString& absSrc = mFileHandler.path(); XevExportHelpers::setAbsAndRelFileSrc(absSrc, result, exp); return result; } -void eIndependentSound::prp_readPropertyXEV_impl(const QDomElement& ele, const XevImporter& imp) { +void eIndependentSound::prp_readPropertyXEV_impl(const QDomElement& ele, + const XevImporter& imp) +{ eBoxOrSound::prp_readPropertyXEV_impl(ele, imp); const QString absSrc = XevExportHelpers::getAbsAndRelFileSrc(ele, imp); - if(!absSrc.isEmpty()) setFilePathNoRename(absSrc); + if (!absSrc.isEmpty()) { setFilePathNoRename(absSrc); } } diff --git a/src/core/Sound/esoundobjectbase.cpp b/src/core/Sound/esoundobjectbase.cpp index 02007825e..792834747 100644 --- a/src/core/Sound/esoundobjectbase.cpp +++ b/src/core/Sound/esoundobjectbase.cpp @@ -79,7 +79,17 @@ const HddCachableCacheHandler *eSoundObjectBase::getCacheHandler() const { return &mCacheHandler->getCacheHandler(); } -void eSoundObjectBase::setStretch(const qreal stretch) { +void eSoundObjectBase::setStretch(const qreal stretch) +{ + { + prp_pushUndoRedoName(tr("Stretch")); + UndoRedo ur; + const auto oldValue = mStretch; + const auto newValue = stretch; + ur.fUndo = [this, oldValue]() { setStretch(oldValue); }; + ur.fRedo = [this, newValue]() { setStretch(newValue); }; + prp_addUndoRedo(ur); + } mStretch = stretch; updateDurationRectLength(); prp_afterWholeInfluenceRangeChanged();