Commit d130414a authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Allow setting effect zone for master / track effects, initial implementation

parent fb4dec0e
Pipeline #53219 canceled with stage
......@@ -381,7 +381,7 @@ void AssetParameterModel::setParameter(const QString &name, const QString &param
emit modelChanged();
}
if (updateChildRequired) {
emit updateChildren(name);
emit updateChildren({name});
}
// Update timeline view if necessary
if (m_ownerId.first == ObjectType::NoItem) {
......
......@@ -253,11 +253,12 @@ signals:
void modelChanged();
/** @brief inform child effects (in case of bin effect with timeline producers)
* that a change occurred and a param update is needed **/
void updateChildren(const QString &name);
void updateChildren(const QStringList &names);
void compositionTrackChanged();
void replugEffect(std::shared_ptr<AssetParameterModel> asset);
void rebuildEffect(std::shared_ptr<AssetParameterModel> asset);
void enabledChange(bool);
void showEffectZone(QPair <int, int>inOut, bool checked);
};
#endif
......@@ -1051,3 +1051,10 @@ void Core::setWidgetKeyBinding(const QString &mess)
window()->setWidgetKeyBinding(mess);
}
void Core::showEffectZone(QPair <int, int>inOut, bool checked)
{
if (m_guiConstructed && m_mainWindow->getCurrentTimeline()->controller()) {
m_mainWindow->getCurrentTimeline()->controller()->showRulerEffectZone(inOut, checked);
}
}
......@@ -293,6 +293,8 @@ public slots:
void buildLumaThumbs(const QStringList &values);
/** @brief Set current project modified. */
void setDocumentModified();
/** @brief Show currently selected effect zone in timeline ruler. */
void showEffectZone(QPair <int, int>inOut, bool checked);
signals:
void coreIsReady();
......@@ -310,6 +312,8 @@ signals:
void voskModelUpdate(const QStringList models);
/** @brief This signal means that VOSK and/or SRT module availability changed*/
void updateVoskAvailability();
/** @brief Update current effect zone */
void updateEffectZone(const QPoint p);
};
#endif
......@@ -32,15 +32,17 @@ EffectItemModel::EffectItemModel(const QList<QVariant> &effectData, std::unique_
, AssetParameterModel(std::move(effect), xml, effectId, std::static_pointer_cast<EffectStackModel>(stack)->getOwnerId(), originalDecimalPoint)
, m_childId(0)
{
connect(this, &AssetParameterModel::updateChildren, [&](const QString &name) {
connect(this, &AssetParameterModel::updateChildren, [&](const QStringList &names) {
if (m_childEffects.size() == 0) {
return;
}
qDebug() << "* * *SETTING EFFECT PARAM: " << name << " = " << m_asset->get(name.toUtf8().constData());
//qDebug() << "* * *SETTING EFFECT PARAM: " << name << " = " << m_asset->get(name.toUtf8().constData());
QMapIterator<int, std::shared_ptr<EffectItemModel>> i(m_childEffects);
while (i.hasNext()) {
i.next();
i.value()->filter().set(name.toUtf8().constData(), m_asset->get(name.toUtf8().constData()));
for (const QString &name : names) {
i.value()->filter().set(name.toUtf8().constData(), m_asset->get(name.toUtf8().constData()));
}
}
});
}
......@@ -205,7 +207,7 @@ void EffectItemModel::updateEnable(bool updateTimeline)
emit dataChanged(start, end, QVector<int>());
emit enabledChange(!isEnabled());
// Update timeline child producers
emit AssetParameterModel::updateChildren(QStringLiteral("disable"));
emit AssetParameterModel::updateChildren({QStringLiteral("disable")});
}
void EffectItemModel::setCollapsed(bool collapsed)
......@@ -213,11 +215,16 @@ void EffectItemModel::setCollapsed(bool collapsed)
filter().set("kdenlive:collapsed", collapsed ? 1 : 0);
}
bool EffectItemModel::isCollapsed()
bool EffectItemModel::isCollapsed() const
{
return filter().get_int("kdenlive:collapsed") == 1;
}
bool EffectItemModel::hasForcedInOut() const
{
return filter().get_int("kdenlive:force_in_out") == 1;
}
bool EffectItemModel::isAudio() const
{
AssetListType::AssetType type = EffectsRepository::get()->getType(m_assetId);
......@@ -228,3 +235,39 @@ bool EffectItemModel::isUnique() const
{
return EffectsRepository::get()->isUnique(m_assetId);
}
QPair <int, int> EffectItemModel::getInOut() const
{
return {m_asset->get_int("in"), m_asset->get_int("out")};
}
void EffectItemModel::setInOut(const QString &effectName, QPair<int, int>bounds, bool enabled)
{
QPair<int, int>currentInOut = {m_asset->get_int("in"), m_asset->get_int("out")};
Fun undo = [this, enabled, currentInOut]() {
m_asset->set("kdenlive:force_in_out", enabled ? 0 : 1);
m_asset->set("in", currentInOut.first);
m_asset->set("out", currentInOut.second);
emit AssetParameterModel::updateChildren({QStringLiteral("in"), QStringLiteral("out")});
if (!isAudio()) {
pCore->refreshProjectItem(m_ownerId);
pCore->invalidateItem(m_ownerId);
}
emit showEffectZone(currentInOut, enabled);
return true;
};
Fun redo = [this, enabled, bounds]() {
m_asset->set("kdenlive:force_in_out", enabled ? 1 : 0);
m_asset->set("in", bounds.first);
m_asset->set("out", bounds.second);
emit AssetParameterModel::updateChildren({QStringLiteral("in"), QStringLiteral("out")});
if (!isAudio()) {
pCore->refreshProjectItem(m_ownerId);
pCore->invalidateItem(m_ownerId);
}
emit showEffectZone(bounds, enabled);
return true;
};
redo();
pCore->pushUndo(undo, redo, i18n("Update zone for %1", effectName));
}
......@@ -60,8 +60,11 @@ public:
bool isUnique() const override;
void setCollapsed(bool collapsed);
bool isCollapsed();
bool isCollapsed() const;
bool hasForcedInOut() const;
bool isValid() const;
QPair <int, int> getInOut() const;
void setInOut(const QString &effectName, QPair<int, int>bounds, bool enabled);
protected:
EffectItemModel(const QList<QVariant> &effectData, std::unique_ptr<Mlt::Properties> effect, const QDomElement &xml, const QString &effectId,
......
......@@ -679,7 +679,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
} else {
qDebug() << "// NULL Keyframes---------";
}
if (m_ownerId.first == ObjectType::TimelineTrack) {
if (m_ownerId.first == ObjectType::TimelineTrack && effect->filter().get_int("kdenlive:force_in_out") == 0) {
int oldEffectOut = effect->filter().get_out();
Fun operation = [effect, out, logUndo]() {
effect->setParameter(QStringLiteral("out"), out, logUndo);
......
......@@ -57,15 +57,10 @@ CollapsibleEffectView::CollapsibleEffectView(const std::shared_ptr<EffectItemMod
: AbstractCollapsibleWidget(parent)
, m_view(nullptr)
, m_model(effectModel)
, m_regionEffect(false)
, m_blockWheel(false)
{
QString effectId = effectModel->getAssetId();
QString effectName = EffectsRepository::get()->getName(effectId);
if (effectId == QLatin1String("region")) {
m_regionEffect = true;
decoframe->setObjectName(QStringLiteral("decoframegroup"));
}
buttonUp->setIcon(QIcon::fromTheme(QStringLiteral("kdenlive-up")));
buttonUp->setToolTip(i18n("Move effect up"));
buttonDown->setIcon(QIcon::fromTheme(QStringLiteral("kdenlive-down")));
......@@ -118,12 +113,59 @@ CollapsibleEffectView::CollapsibleEffectView(const std::shared_ptr<EffectItemMod
m_enabledButton->setInactiveIcon(QIcon::fromTheme(QStringLiteral("visibility")));
enabledButton->setDefaultAction(m_enabledButton);
connect(m_model.get(), &AssetParameterModel::enabledChange, this, &CollapsibleEffectView::enableView);
connect(m_model.get(), &AssetParameterModel::showEffectZone, this, &CollapsibleEffectView::showEffectZone);
m_groupAction = new QAction(QIcon::fromTheme(QStringLiteral("folder-new")), i18n("Create Group"), this);
connect(m_groupAction, &QAction::triggered, this, &CollapsibleEffectView::slotCreateGroup);
if (m_regionEffect) {
effectName.append(':' + QUrl(Xml::getXmlParameter(m_effect, QStringLiteral("resource"))).fileName());
// In /out effect button
auto *layZone = new QHBoxLayout(zoneFrame);
layZone->setContentsMargins(0, 0, 0, 0);
layZone->setSpacing(0);
QLabel *in = new QLabel(i18n("In:"), this);
in->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
layZone->addWidget(in);
QToolButton *setIn = new QToolButton(this);
setIn->setIcon(QIcon::fromTheme(QStringLiteral("zone-in")));
setIn->setAutoRaise(true);
setIn->setToolTip(i18n("Set zone in"));
layZone->addWidget(setIn);
m_inPos = new TimecodeDisplay(pCore->timecode(), this);
layZone->addWidget(m_inPos);
layZone->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Maximum));
QLabel *out = new QLabel(i18n("Out:"), this);
out->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
layZone->addWidget(out);
QToolButton *setOut = new QToolButton(this);
setOut->setIcon(QIcon::fromTheme(QStringLiteral("zone-out")));
setOut->setAutoRaise(true);
setOut->setToolTip(i18n("Set zone out"));
layZone->addWidget(setOut);
m_outPos = new TimecodeDisplay(pCore->timecode(), this);
layZone->addWidget(m_outPos);
connect(setIn, &QToolButton::clicked, [this]() {
m_inPos->setValue(pCore->getTimelinePosition());
updateEffectZone();
});
connect(setOut, &QToolButton::clicked, [this]() {
m_outPos->setValue(pCore->getTimelinePosition());
updateEffectZone();
});
m_inOutButton = new QAction(QIcon::fromTheme(QStringLiteral("zoom-fit-width")), i18n("Use effect zone"), this);
m_inOutButton->setCheckable(true);
inOutButton->setDefaultAction(m_inOutButton);
m_inOutButton->setChecked(m_model->hasForcedInOut());
if (m_inOutButton->isChecked()) {
QPair<int, int> inOut = m_model->getInOut();
m_inPos->setValue(inOut.first);
m_outPos->setValue(inOut.second);
} else {
zoneFrame->setFixedHeight(0);
}
connect(m_inPos, &TimecodeDisplay::timeCodeEditingFinished, this, &CollapsibleEffectView::updateEffectZone);
connect(m_outPos, &TimecodeDisplay::timeCodeEditingFinished, this, &CollapsibleEffectView::updateEffectZone);
connect(m_inOutButton, &QAction::triggered, this, &CollapsibleEffectView::switchInOut);
// Color thumb
m_colorIcon->setScaledContents(true);
......@@ -180,15 +222,7 @@ CollapsibleEffectView::CollapsibleEffectView(const std::shared_ptr<EffectItemMod
}
m_menu->addAction(QIcon::fromTheme(QStringLiteral("document-save")), i18n("Save Effect"), this, SLOT(slotSaveEffect()));
m_menu->addAction(QIcon::fromTheme(QStringLiteral("document-save-all")), i18n("Save Effect Stack"), this, SIGNAL(saveStack()));
//TODO reimplement region
/*if (!m_regionEffect) {
//if (m_info.groupIndex == -1) {
// m_menu->addAction(m_groupAction);
//}
m_menu->addAction(QIcon::fromTheme(QStringLiteral("folder-new")), i18n("Create Region"), this, SLOT(slotCreateRegion()));
}*/
// setupWidget(info, metaInfo);
menuButton->setIcon(QIcon::fromTheme(QStringLiteral("kdenlive-menu")));
menuButton->setMenu(m_menu);
......@@ -355,6 +389,11 @@ void CollapsibleEffectView::slotActivateEffect(bool active)
pCore->getMonitor(m_model->monitorId)->slotShowEffectScene(needsMonitorEffectScene());
}
emit m_view->initKeyframeView(active);
if (m_inOutButton->isChecked()) {
emit showEffectZone(m_model->getInOut(), true);
} else {
emit showEffectZone({0,0}, false);
}
}
void CollapsibleEffectView::mousePressEvent(QMouseEvent *e)
......@@ -547,7 +586,7 @@ void CollapsibleEffectView::updateHeight()
return;
}
widgetFrame->setFixedHeight(m_collapse->isActive() ? 0 : m_view->height());
setFixedHeight(widgetFrame->height() + frame->minimumHeight() + 2 * (contentsMargins().top() + decoframe->lineWidth()));
setFixedHeight(widgetFrame->height() + frame->minimumHeight() + zoneFrame->minimumHeight() + 2 * (contentsMargins().top() + decoframe->lineWidth()));
emit switchHeight(m_model, height());
}
......@@ -561,7 +600,8 @@ void CollapsibleEffectView::switchCollapsed(int row)
void CollapsibleEffectView::slotSwitch(bool collapse)
{
widgetFrame->setFixedHeight(collapse ? 0 : m_view->height());
setFixedHeight(widgetFrame->height() + frame->minimumHeight() + 2 * (contentsMargins().top() + decoframe->lineWidth()));
zoneFrame->setFixedHeight(collapse || !m_inOutButton->isChecked() ? 0 :frame->height());
setFixedHeight(widgetFrame->height() + frame->minimumHeight() + zoneFrame->height()+ 2 * (contentsMargins().top() + decoframe->lineWidth()));
m_model->setCollapsed(collapse);
emit switchHeight(m_model, height());
}
......@@ -621,7 +661,6 @@ void CollapsibleEffectView::updateWidget(const ItemInfo &info, const QDomElement
m_paramWidget = nullptr;
*/
m_effect = effect;
setupWidget(info);
}
void CollapsibleEffectView::updateFrameInfo()
......@@ -643,65 +682,6 @@ void CollapsibleEffectView::setActiveKeyframe(int kf)
*/
}
void CollapsibleEffectView::setupWidget(const ItemInfo &info)
{
Q_UNUSED(info)
/*
if (m_effect.isNull()) {
// //qCDebug(KDENLIVE_LOG) << "// EMPTY EFFECT STACK";
return;
}
delete m_paramWidget;
m_paramWidget = nullptr;
if (m_effect.attribute(QStringLiteral("tag")) == QLatin1String("region")) {
m_regionEffect = true;
QDomNodeList effects = m_effect.elementsByTagName(QStringLiteral("effect"));
QDomNodeList origin_effects = m_original_effect.elementsByTagName(QStringLiteral("effect"));
m_paramWidget = new ParameterContainer(m_effect, info, metaInfo, widgetFrame);
QWidget *container = new QWidget(widgetFrame);
QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
vbox->addWidget(container);
// m_paramWidget = new ParameterContainer(m_effect.toElement(), info, metaInfo, container);
for (int i = 0; i < effects.count(); ++i) {
bool canMoveUp = true;
if (i == 0 || effects.at(i - 1).toElement().attribute(QStringLiteral("id")) == QLatin1String("speed")) {
canMoveUp = false;
}
CollapsibleEffectView *coll = new CollapsibleEffectView(effects.at(i).toElement(), origin_effects.at(i).toElement(), info, metaInfo, canMoveUp,
i == effects.count() - 1, container);
m_subParamWidgets.append(coll);
connect(coll, &CollapsibleEffectView::parameterChanged, this, &CollapsibleEffectView::slotUpdateRegionEffectParams);
// container = new QWidget(widgetFrame);
vbox->addWidget(coll);
// p = new ParameterContainer(effects.at(i).toElement(), info, isEffect, container);
}
} else {
m_paramWidget = new ParameterContainer(m_effect, info, metaInfo, widgetFrame);
connect(m_paramWidget, &ParameterContainer::disableCurrentFilter, this, &CollapsibleEffectView::slotDisable);
connect(m_paramWidget, &ParameterContainer::importKeyframes, this, &CollapsibleEffectView::importKeyframes);
if (m_effect.firstChildElement(QStringLiteral("parameter")).isNull()) {
// Effect has no parameter, don't allow expand
collapseButton->setEnabled(false);
collapseButton->setVisible(false);
widgetFrame->setVisible(false);
}
}
if (collapseButton->isEnabled() && m_info.isCollapsed) {
widgetFrame->setVisible(false);
collapseButton->setArrowType(Qt::RightArrow);
}
connect(m_paramWidget, &ParameterContainer::parameterChanged, this, &CollapsibleEffectView::parameterChanged);
connect(m_paramWidget, &ParameterContainer::startFilterJob, this, &CollapsibleEffectView::startFilterJob);
connect(this, &CollapsibleEffectView::syncEffectsPos, m_paramWidget, &ParameterContainer::syncEffectsPos);
connect(m_paramWidget, &ParameterContainer::checkMonitorPosition, this, &CollapsibleEffectView::checkMonitorPosition);
connect(m_paramWidget, &ParameterContainer::seekTimeline, this, &CollapsibleEffectView::seekTimeline);
connect(m_paramWidget, &ParameterContainer::importClipKeyframes, this, &CollapsibleEffectView::prepareImportClipKeyframes);
*/
}
bool CollapsibleEffectView::isGroup() const
{
return false;
......@@ -878,3 +858,69 @@ void CollapsibleEffectView::blockWheenEvent(bool block)
m_blockWheel = block;
}
void CollapsibleEffectView::switchInOut(bool checked)
{
QString effectId = m_model->getAssetId();
QString effectName = EffectsRepository::get()->getName(effectId);
QPair<int, int> inOut = m_model->getInOut();
zoneFrame->setFixedHeight(checked ? frame->height() : 0);
slotSwitch(m_collapse->isActive());
qDebug()<<"==== INITIAL IN / OUT: "<<inOut.first<<"-"<<inOut.second;
if (inOut.first == inOut.second || !checked) {
ObjectId owner = m_model->getOwnerId();
switch (owner.first) {
case ObjectType::TimelineClip:
{
qDebug()<<"==== SWITCHING TIMELINE CLIP";
int in = pCore->getItemIn(owner);
inOut = {in, in + pCore->getItemDuration(owner)};
break;
}
case ObjectType::TimelineTrack:
case ObjectType::Master:
{
qDebug()<<"==== SWITCHING MASTER/TRACK";
if (!checked) {
inOut = {0,0};
} else {
int in = pCore->getTimelinePosition() - 50;
inOut = {in, in + 100};
}
break;
}
default:
qDebug()<<"== UNSUPPORTED ITEM TYPE FOR EFFECT RANGE: "<<(int) owner.first;
break;
}
}
qDebug()<<"==== SWITCHING IN / OUT: "<<inOut.first<<"-"<<inOut.second;
if (inOut.first > -1) {
m_model->setInOut(effectName, inOut, checked);
m_inPos->setValue(inOut.first);
m_outPos->setValue(inOut.second);
}
}
void CollapsibleEffectView::updateInOut(QPair<int, int> inOut)
{
if (!m_inOutButton->isChecked()) {
qDebug()<<"=== CANNOT UPDATE ZONE ON EFFECT!!!";
return;
}
QString effectId = m_model->getAssetId();
QString effectName = EffectsRepository::get()->getName(effectId);
if (inOut.first > -1) {
m_model->setInOut(effectName, inOut, true);
m_inPos->setValue(inOut.first);
m_outPos->setValue(inOut.second);
}
}
void CollapsibleEffectView::updateEffectZone()
{
QString effectId = m_model->getAssetId();
QString effectName = EffectsRepository::get()->getName(effectId);
QPair<int, int> inOut = {m_inPos->getValue(), m_outPos->getValue()};
m_model->setInOut(effectName, inOut, true);
}
......@@ -34,6 +34,7 @@ class KDualAction;
class KSqueezedTextLabel;
class EffectItemModel;
class AssetParameterView;
class TimecodeDisplay;
/**)
* @class CollapsibleEffectView
......@@ -50,7 +51,6 @@ public:
~CollapsibleEffectView() override;
KSqueezedTextLabel *title;
void setupWidget(const ItemInfo &info);
void updateTimecodeFormat();
/** @brief Install event filter so that scrolling with mouse wheel does not change parameter value. */
bool eventFilter(QObject *o, QEvent *e) override;
......@@ -86,10 +86,14 @@ public:
QDomDocument toXml() const;
/** @brief Update monitor scene depending on effect enabled state. */
void updateScene();
void updateInOut(QPair<int, int> inOut);
public slots:
void slotSyncEffectsPos(int pos);
/** @brief Enable / disable an effect. */
void slotDisable(bool disable);
/** @brief Restrict an effec to an in/out point region, of full length. */
void switchInOut(bool checked);
void slotResetEffect();
void importKeyframes(const QString &keyframes);
void slotActivateEffect(bool active);
......@@ -115,6 +119,7 @@ private slots:
/** @brief A sub effect parameter was changed */
void slotUpdateRegionEffectParams(const QDomElement & /*old*/, const QDomElement & /*e*/, int /*ix*/);
void prepareImportClipKeyframes();
void updateEffectZone();
private:
AssetParameterView *m_view;
......@@ -128,15 +133,16 @@ private:
QList<QDomElement> m_subEffects;
QMenu *m_menu;
bool m_isMovable;
/** @brief True if this is a region effect, which behaves in a special way, like a group. */
bool m_regionEffect;
bool m_blockWheel;
/** @brief The add group action. */
QAction *m_groupAction;
KDualAction *m_enabledButton;
QAction *m_inOutButton;
QLabel *m_colorIcon;
QPixmap m_iconPix;
QPoint m_dragStart;
TimecodeDisplay *m_inPos;
TimecodeDisplay *m_outPos;
protected:
void mouseDoubleClickEvent(QMouseEvent *event) override;
......@@ -168,6 +174,7 @@ signals:
void switchHeight(std::shared_ptr<EffectItemModel> model, int height);
void startDrag(QPixmap, std::shared_ptr<EffectItemModel> effectModel);
void activateEffect(std::shared_ptr<EffectItemModel> effectModel);
void showEffectZone(QPair <int, int>inOut, bool checked);
void refresh();
/** @brief Requests saving the full effect stack. */
void saveStack();
......
......@@ -261,6 +261,7 @@ void EffectStackView::loadEffects()
connect(view, &CollapsibleEffectView::saveStack, this, &EffectStackView::slotSaveStack);
connect(view, &CollapsibleEffectView::createGroup, m_model.get(), &EffectStackModel::slotCreateGroup);
connect(view, &CollapsibleEffectView::activateEffect, this, &EffectStackView::slotActivateEffect);
connect(view, &CollapsibleEffectView::showEffectZone, pCore.get(), &Core::showEffectZone);
connect(this, &EffectStackView::blockWheenEvent, view, &CollapsibleEffectView::blockWheenEvent);
connect(view, &CollapsibleEffectView::seekToPos, this, [this](int pos) {
// at this point, the effects returns a pos relative to the clip. We need to convert it to a global time
......@@ -268,6 +269,16 @@ void EffectStackView::loadEffects()
emit seekToPos(pos + clipIn);
});
connect(this, &EffectStackView::switchCollapsedView, view, &CollapsibleEffectView::switchCollapsed);
connect(pCore.get(), &Core::updateEffectZone, [this](const QPoint p) {
// Update current effect zone
int i = m_model->getActiveEffect();
auto item = m_model->getEffectStackRow(i);
QModelIndex ix = m_model->getIndexFromItem(item);
CollapsibleEffectView *w = static_cast<CollapsibleEffectView *>(m_effectsTree->indexWidget(ix));
if (w) {
w->updateInOut({p.x(), p.y()});
}
});
QModelIndex ix = m_model->getIndexFromItem(effectModel);
m_effectsTree->setIndexWidget(ix, view);
auto *del = static_cast<WidgetDelegate *>(m_effectsTree->itemDelegate(ix));
......@@ -395,6 +406,7 @@ void EffectStackView::unsetModel(bool reset)
// Release ownership of smart pointer
Kdenlive::MonitorId id = Kdenlive::NoMonitor;
if (m_model) {
pCore->showEffectZone({0,0}, false);
ObjectId item = m_model->getOwnerId();
id = item.first == ObjectType::BinClip ? Kdenlive::ClipMonitor : Kdenlive::ProjectMonitor;
disconnect(m_model.get(), &EffectStackModel::dataChanged, this, &EffectStackView::refresh);
......
......@@ -93,6 +93,29 @@ Item {
color: 'orange'
visible: rulerRoot.workingPreview > -1
}
// Effect zone
RulerZone {
id: effectZone
Binding {
target: effectZone
property: "frameIn"
value: timeline.effectZone.x
}
Binding {
target: effectZone
property: "frameOut"
value: timeline.effectZone.y
}
color: 'yellow'
opacity: 0.4
anchors.bottom: parent.bottom
height: parent.height
function updateZone(start, end, update)
{
timeline.updateEffectZone(start, end, update)
}
}
// Ruler marks
Repeater {
......@@ -123,201 +146,26 @@ Item {
}
// monitor zone
Rectangle {
RulerZone {
id: zone
visible: timeline.zoneOut > timeline.zoneIn
Binding {
target: zone
property: "frameIn"
value: timeline.zoneIn
}
Binding {
target: zone
property: "frameOut"
value: timeline.zoneOut
}
color: useTimelineRuler ? Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.5) :
Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.25)
x: timeline.zoneIn * timeline.scaleFactor
width: (timeline.zoneOut - timeline.zoneIn) * timeline.scaleFactor
anchors.bottom: parent.bottom
height: parent.height / 3