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

Start displaying effectstack (wip)

parent af379e9c
......@@ -21,6 +21,8 @@
#include "assetpanel.hpp"
#include "effects/effectstack/model/effectstackmodel.hpp"
#include "effects/effectstack/model/effectitemmodel.hpp"
#include "effects/effectstack/view/effectstackview.hpp"
#include "kdenlivesettings.h"
#include "model/assetparametermodel.hpp"
#include "transitions/transitionsrepository.hpp"
......@@ -39,9 +41,12 @@ AssetPanel::AssetPanel(QWidget *parent)
, m_lay(new QVBoxLayout(this))
, m_assetTitle(new QLabel(this))
, m_transitionWidget(new AssetParameterView(this))
, m_effectStackWidget(new EffectStackView(this))
{
m_lay->addWidget(m_assetTitle);
m_lay->addWidget(m_transitionWidget);
m_lay->addWidget(m_effectStackWidget);
m_lay->addStretch();
m_transitionWidget->setVisible(false);
updatePalette();
}
......@@ -60,13 +65,17 @@ void AssetPanel::showTransition(std::shared_ptr<AssetParameterModel> transitionM
void AssetPanel::showEffectStack(std::shared_ptr<EffectStackModel> effectsModel)
{
clear();
// TODO
m_assetTitle->setText(i18n("Properties of clip ..."));
m_effectStackWidget->setVisible(true);
m_effectStackWidget->setModel(effectsModel);
}
void AssetPanel::clear()
{
m_transitionWidget->setVisible(false);
m_transitionWidget->unsetModel();
m_effectStackWidget->setVisible(false);
m_effectStackWidget->unsetModel();
m_assetTitle->setText(QString());
}
......@@ -75,6 +84,7 @@ void AssetPanel::updatePalette()
QString styleSheet = getStyleSheet();
setStyleSheet(styleSheet);
m_transitionWidget->setStyleSheet(styleSheet);
m_effectStackWidget->setStyleSheet(styleSheet);
}
// static
......
......@@ -33,6 +33,7 @@
class AssetParameterModel;
class AssetParameterView;
class EffectStackModel;
class EffectStackView;
class QLabel;
class AssetPanel : public QScrollArea
......@@ -61,6 +62,7 @@ protected:
QVBoxLayout *m_lay;
QLabel *m_assetTitle;
AssetParameterView *m_transitionWidget;
EffectStackView *m_effectStackWidget;
};
#endif
......@@ -34,8 +34,8 @@ AssetParameterView::AssetParameterView(QWidget *parent)
: QWidget(parent)
{
m_lay = new QVBoxLayout(this);
m_lay->setContentsMargins(2, 0, 2, 0);
m_lay->setSpacing(0);
m_lay->setContentsMargins(2, 2, 2, 2);
m_lay->setSpacing(2);
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
}
......@@ -53,7 +53,6 @@ void AssetParameterView::setModel(const std::shared_ptr<AssetParameterModel> &mo
m_lay->addWidget(w);
m_widgets.push_back(w);
}
m_lay->addStretch();
}
void AssetParameterView::unsetModel()
......@@ -87,3 +86,9 @@ void AssetParameterView::refresh(const QModelIndex &topLeft, const QModelIndex &
m_widgets[i]->slotRefresh();
}
}
int AssetParameterView::contentHeight() const
{
return m_lay->sizeHint().height();
}
......@@ -48,6 +48,9 @@ public:
/** Set the widget to display no model (this yield ownership on the smart-ptr)*/
void unsetModel();
/** Returns the preferred widget height */
int contentHeight() const;
protected:
/** @brief This is a handler for the dataChanged slot of the model.
It basically instructs the widgets in the given range to be refreshed */
......
......@@ -2,10 +2,13 @@ set(kdenlive_SRCS
${kdenlive_SRCS}
effects/effectsrepository.cpp
effects/effectlist/view/effectlistwidget.cpp
effects/effectlist/view/effectlistwidget.cpp
effects/effectlist/model/effecttreemodel.cpp
effects/effectlist/model/effectfilter.cpp
effects/effectstack/model/abstracteffectitem.cpp
effects/effectstack/model/effectitemmodel.cpp
effects/effectstack/model/effectstackmodel.cpp
effects/effectstack/view/effectstackview.cpp
effects/effectstack/view/collapsibleeffectview.cpp
PARENT_SCOPE)
......@@ -52,6 +52,9 @@ bool AbstractEffectItem::isEnabled() const
bool parentEnabled = true;
if (auto ptr = std::static_pointer_cast<AbstractEffectItem>(m_parentItem.lock())) {
parentEnabled = ptr->isEnabled();
} else {
// Root item, always return true
return true;
}
return m_enabled && m_effectStackEnabled && parentEnabled;
}
......
......@@ -54,3 +54,9 @@ void EffectStackModel::setEffectStackEnabled(bool enabled)
std::static_pointer_cast<EffectItemModel>(rootItem->child(i))->setEffectStackEnabled(enabled);
}
}
std::shared_ptr<EffectItemModel> EffectStackModel::effect(int row)
{
return std::static_pointer_cast<EffectItemModel>(rootItem->child(row));
}
......@@ -30,6 +30,7 @@
It is responsible for planting and managing effects into the producer it holds a pointer to.
*/
class TreeItem;
class EffectItemModel;
class EffectStackModel : public AbstractTreeModel
{
......@@ -49,6 +50,9 @@ public:
*/
void setEffectStackEnabled(bool enabled);
/* @brief Returns an effect from the stack (at the given row) */
std::shared_ptr<EffectItemModel> effect(int row);
protected:
std::weak_ptr<Mlt::Service> m_service;
......
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2017 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* 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/>. *
***************************************************************************/
#ifndef COLLAPSIBLEEFFECTVIEW_H
#define COLLAPSIBLEEFFECTVIEW_H
#include "effectstack/abstractcollapsiblewidget.h"
#include "mltcontroller/effectscontroller.h"
#include "effectstack/parametercontainer.h"
#include "timecode.h"
#include <QDomElement>
#include <memory>
class QLabel;
class KDualAction;
class AssetParameterModel;
class AssetParameterView;
/**)
* @class CollapsibleEffectView
* @brief A dialog for editing markers and guides.
* @author Jean-Baptiste Mardelle
*/
class CollapsibleEffectView : public AbstractCollapsibleWidget
{
Q_OBJECT
public:
explicit CollapsibleEffectView(std::shared_ptr<AssetParameterModel> effectModel, QWidget *parent = nullptr);
~CollapsibleEffectView();
QLabel *title;
void setupWidget(const ItemInfo &info, EffectMetaInfo *metaInfo);
void updateTimecodeFormat();
void setActive(bool activate) override;
/** @brief Install event filter so that scrolling with mouse wheel does not change parameter value. */
bool eventFilter(QObject *o, QEvent *e) override;
/** @brief Update effect GUI to reflect parameted changes. */
void updateWidget(const ItemInfo &info, const QDomElement &effect, EffectMetaInfo *metaInfo);
/** @brief Returns effect xml. */
QDomElement effect() const;
/** @brief Returns effect xml with keyframe offset for saving. */
QDomElement effectForSave() const;
int groupIndex() const;
bool isGroup() const override;
int effectIndex() const;
void setGroupIndex(int ix);
void setGroupName(const QString &groupName);
/** @brief Remove this effect from its group. */
void removeFromGroup();
QString infoString() const;
bool isActive() const;
bool isEnabled() const;
/** @brief Should the wheel event be sent to parent widget for scrolling. */
bool filterWheelEvent;
/** @brief Parent group was collapsed, update. */
void groupStateChanged(bool collapsed);
/** @brief Show / hide up / down buttons. */
void adjustButtons(int ix, int max);
/** @brief Returns this effect's monitor scene type if any is needed. */
MonitorSceneType needsMonitorEffectScene() const;
/** @brief Set clip in / out points. */
void setRange(int inPoint, int outPoint);
/** @brief Import keyframes from a clip's data. */
void setKeyframes(const QString &tag, const QString &keyframes);
/** @brief Pass frame size info (dar, etc). */
void updateFrameInfo();
/** @brief Select active keyframe. */
void setActiveKeyframe(int kf);
/** @brief Returns true if effect can be moved (false for speed effect). */
bool isMovable() const;
public slots:
void slotSyncEffectsPos(int pos);
void slotDisable(bool disable, bool emitInfo = true);
void slotResetEffect();
void importKeyframes(const QString &keyframes);
private slots:
void setWidgetHeight(qreal value);
void animationFinished();
private slots:
void slotSwitch(bool expand);
void slotShow(bool show);
void slotDeleteEffect();
void slotEffectUp();
void slotEffectDown();
void slotSaveEffect();
void slotCreateGroup();
void slotCreateRegion();
void slotUnGroup();
/** @brief A sub effect parameter was changed */
void slotUpdateRegionEffectParams(const QDomElement & /*old*/, const QDomElement & /*e*/, int /*ix*/);
/** @brief Dis/enable effect before processing an operation (color picker) */
void slotDisableEffect(bool disable);
void prepareImportClipKeyframes();
private:
ParameterContainer *m_paramWidget;
AssetParameterView *m_view;
KDualAction *m_collapse;
QList<CollapsibleEffectView *> m_subParamWidgets;
QDomElement m_effect;
ItemInfo m_itemInfo;
QDomElement m_original_effect;
QList<QDomElement> m_subEffects;
QMenu *m_menu;
QPoint m_clickPoint;
EffectInfo m_info;
bool m_isMovable;
/** @brief True if this is a region effect, which behaves in a special way, like a group. */
bool m_regionEffect;
/** @brief The add group action. */
QAction *m_groupAction;
KDualAction *m_enabledButton;
QLabel *m_colorIcon;
QPixmap m_iconPix;
/** @brief Check if collapsed state changed and inform MLT. */
void updateCollapsedState();
protected:
void mouseDoubleClickEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
signals:
void parameterChanged(const QDomElement &, const QDomElement &, int);
void syncEffectsPos(int);
void effectStateChanged(bool, int ix, MonitorSceneType effectNeedsMonitorScene);
void deleteEffect(const QDomElement &);
void activateEffect(int);
void checkMonitorPosition(int);
void seekTimeline(int);
/** @brief Start an MLT filter job on this clip. */
void startFilterJob(QMap<QString, QString> &, QMap<QString, QString> &, QMap<QString, QString> &);
/** @brief An effect was reset, trigger param reload. */
void resetEffect(int ix);
/** @brief Ask for creation of a group. */
void createGroup(int ix);
void unGroup(CollapsibleEffectView *);
void createRegion(int, const QUrl &);
void deleteGroup(const QDomDocument &);
void importClipKeyframes(GraphicsRectItem, ItemInfo, QDomElement, const QMap<QString, QString> &keyframes = QMap<QString, QString>());
};
#endif
/***************************************************************************
* Copyright (C) 2017 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* 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/>. *
***************************************************************************/
#include "effectstackview.hpp"
#include "collapsibleeffectview.hpp"
#include "effects/effectstack/model/effectstackmodel.hpp"
#include "effects/effectstack/model/effectitemmodel.hpp"
#include "assets/view/assetparameterview.hpp"
#include <QVBoxLayout>
#include <QFontDatabase>
EffectStackView::EffectStackView(QWidget *parent) : QWidget(parent)
{
m_lay = new QVBoxLayout(this);
m_lay->setContentsMargins(0, 0, 0, 0);
m_lay->setSpacing(2);
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
}
void EffectStackView::setModel(std::shared_ptr<EffectStackModel>model)
{
unsetModel();
m_model = model;
int max = m_model->rowCount();
for (int i = 0; i < max; i++) {
CollapsibleEffectView *view = new CollapsibleEffectView(m_model->effect(i), this);
m_lay->addWidget(view);
m_widgets.push_back(view);
}
m_lay->addStretch();
}
void EffectStackView::unsetModel()
{
// clear layout
m_widgets.clear();
QLayoutItem *child;
while ((child = m_lay->takeAt(0)) != nullptr) {
delete child->widget();
delete child->spacerItem();
}
// Release ownership of smart pointer
m_model.reset();
}
/***************************************************************************
* Copyright (C) 2017 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* 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/>. *
***************************************************************************/
#ifndef EFFECTSTACKVIEW_H
#define EFFECTSTACKVIEW_H
#include <QWidget>
#include <memory>
class QVBoxLayout;
class CollapsibleEffectView;
class AssetParameterModel;
class EffectStackModel;
class EffectStackView : public QWidget
{
Q_OBJECT
public:
EffectStackView(QWidget *parent = nullptr);
void setModel(std::shared_ptr<EffectStackModel>model);
void unsetModel();
private:
QVBoxLayout *m_lay;
std::shared_ptr<EffectStackModel> m_model;
std::vector<CollapsibleEffectView *> m_widgets;
const QString getStyleSheet();
};
#endif
......@@ -316,6 +316,7 @@ void MainWindow::init()
m_assetPanel = new AssetPanel(this);
connect(m_timelineTabs, &TimelineTabs::showTransitionModel, m_assetPanel, &AssetPanel::showTransition);
connect(m_timelineTabs, &TimelineTabs::showClipEffectStack, m_assetPanel, &AssetPanel::showEffectStack);
m_assetPanel->showTransition(model);
m_effectStackDock = addDock(i18n("Properties"), QStringLiteral("effect_stack"), m_assetPanel);
......
......@@ -1531,3 +1531,10 @@ std::shared_ptr<AssetParameterModel> TimelineModel::getCompositionParameterModel
Q_ASSERT(isComposition(compoId));
return std::static_pointer_cast<AssetParameterModel>(m_allCompositions.at(compoId));
}
std::shared_ptr<EffectStackModel> TimelineModel::getClipEffectStackModel(int clipId) const
{
READ_LOCK();
Q_ASSERT(isClip(clipId));
return std::static_pointer_cast<EffectStackModel>(m_allClips.at(clipId)->m_effectStack);
}
......@@ -37,6 +37,7 @@
#endif
class AssetParameterModel;
class EffectStackModel;
class ClipModel;
class CompositionModel;
class DocUndoStack;
......@@ -172,6 +173,8 @@ public:
/* @brief Given a composition Id, returns its underlying parameter model */
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 Returns the position of clip (-1 if it is not inserted)
@param clipId Id of the clip to test
......
......@@ -139,7 +139,7 @@ Rectangle {
onDropped: {
console.log("Add effect: ", dropData)
controller.addClipEffect(clipRoot.clipId, dropData);
drag.acceptProposedAction()
drag.acceptProposedAction
}
}
......
......@@ -373,8 +373,7 @@ void TimelineController::addAsset(const QVariantMap data)
QString effect = data.value(QStringLiteral("kdenlive/effect")).toString();
if (!m_selection.selectedClips.isEmpty()) {
for (int id : m_selection.selectedClips) {
// TODO: manage effects in model
// m_model->addEffect(id, effect);
m_model->addClipEffect(id, effect);
}
}
}
......@@ -389,6 +388,8 @@ void TimelineController::showAsset(int id)
qDebug() << "show asset" << id;
if (m_model->isComposition(id)) {
emit showTransitionModel(m_model->getCompositionParameterModel(id));
} else if (m_model->isClip(id)) {
emit showClipEffectStack(m_model->getClipEffectStackModel(id));
}
}
......
......@@ -249,6 +249,7 @@ signals:
void zoneMoved(const QPoint &zone);
/* @brief Requests that a given parameter model is displayed in the asset panel */
void showTransitionModel(std::shared_ptr<AssetParameterModel>);
void showClipEffectStack(std::shared_ptr<EffectStackModel>);
};
#endif
......@@ -69,4 +69,5 @@ void TimelineTabs::connectTimeline(TimelineWidget *timeline)
connect(this, &TimelineTabs::showAudioThumbnailsChanged, timeline->controller(), &TimelineController::showAudioThumbnailsChanged);
connect(this, &TimelineTabs::changeZoom, timeline, &TimelineWidget::slotChangeZoom);
connect(timeline->controller(), &TimelineController::showTransitionModel, this, &TimelineTabs::showTransitionModel);
connect(timeline->controller(), &TimelineController::showClipEffectStack, this, &TimelineTabs::showClipEffectStack);
}
......@@ -30,7 +30,7 @@
class TimelineWidget;
class AssetParameterModel;
class EffectStackModel;
class TimelineTabs : public QTabWidget
{
Q_OBJECT
......@@ -71,6 +71,8 @@ signals:
void changeZoom(int value, bool zoomOnMouse);
/* @brief Requests that a given parameter model is displayed in the asset panel */
void showTransitionModel(std::shared_ptr<AssetParameterModel>);
/* @brief Requests that a given effectstack model is displayed in the asset panel */
void showClipEffectStack(std::shared_ptr<EffectStackModel>);
private:
TimelineWidget *m_mainTimeline;
......
Supports Markdown
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