implemented basic animation curve editor widgets

Frontend is largely done, it just needs backend and connecting to other
widgets to function correctly.
This commit is contained in:
itsmattkc
2019-12-28 00:27:13 +11:00
parent 3c9b16555f
commit d82acf9b7e
16 changed files with 215 additions and 31 deletions
+4
View File
@@ -6,6 +6,10 @@ CurvePanel::CurvePanel(QWidget *parent) :
// FIXME: This won't work if there's ever more than one of this panel
setObjectName("CurvePanel");
// Create main widget and set it
widget_ = new CurveWidget();
setWidget(widget_);
// Set strings
Retranslate();
}
+3
View File
@@ -1,6 +1,7 @@
#ifndef CURVEPANEL_H
#define CURVEPANEL_H
#include "widget/curvewidget/curvewidget.h"
#include "widget/panel/panel.h"
class CurvePanel : public PanelWidget
@@ -14,6 +15,8 @@ protected:
private:
void Retranslate();
CurveWidget* widget_;
};
#endif // CURVEPANEL_H
+1
View File
@@ -17,6 +17,7 @@
add_subdirectory(audiomonitor)
add_subdirectory(clickablelabel)
add_subdirectory(columnedgridlayout)
add_subdirectory(curvewidget)
add_subdirectory(flowlayout)
add_subdirectory(focusablelineedit)
add_subdirectory(footagecombobox)
-6
View File
@@ -1,6 +0,0 @@
#include "curveview.h"
CurveView::CurveView()
{
}
-11
View File
@@ -1,11 +0,0 @@
#ifndef CURVEVIEW_H
#define CURVEVIEW_H
class CurveView
{
public:
CurveView();
};
#endif // CURVEVIEW_H
+24
View File
@@ -0,0 +1,24 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2019 Olive Team
#
# 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 3 of the License, or
# (at your option) any later version.
#
# 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/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/curvewidget/curveview.h
widget/curvewidget/curveview.cpp
widget/curvewidget/curvewidget.h
widget/curvewidget/curvewidget.cpp
PARENT_SCOPE
)
+41 -2
View File
@@ -1,6 +1,45 @@
#include "curveview.h"
CurveView::CurveView()
{
#include <QtMath>
#include "common/qtversionabstraction.h"
CurveView::CurveView(QWidget *parent) :
TimelineViewBase(parent)
{
setAlignment(Qt::AlignLeft | Qt::AlignBottom);
setDragMode(RubberBandDrag);
setViewportUpdateMode(FullViewportUpdate);
text_padding_ = QFontMetricsWidth(fontMetrics(), QStringLiteral("i"));
}
void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
{
QVector<QLine> lines;
//painter->setPen(palette().window().color());
int grid_interval = 100;
int x_start = qCeil(rect.left() / grid_interval) * grid_interval;
int y_start = qCeil(rect.top() / grid_interval) * grid_interval;
QPoint viewport_edges(0, qRound(rect.height()));
QPointF scene_edges = mapToScene(viewport_edges);
//QRectF scene_edges = mapToScene(viewport()->geometry()).boundingRect();
// Add vertical lines
for (int i=x_start;i<rect.right();i+=grid_interval) {
painter->drawText(i + text_padding_, qRound(scene_edges.y()) - text_padding_, QString::number(i));
lines.append(QLine(i, qRound(rect.top()), i, qRound(rect.bottom())));
}
// Add horizontal lines
for (int i=y_start;i<rect.bottom();i+=grid_interval) {
painter->drawText(qRound(scene_edges.x()) + text_padding_, i - text_padding_, QString::number(-i));
lines.append(QLine(qRound(rect.left()), i, qRound(rect.right()), i));
}
painter->drawLines(lines);
}
+10 -2
View File
@@ -1,11 +1,19 @@
#ifndef CURVEVIEW_H
#define CURVEVIEW_H
#include "widget/timelinewidget/view/timelineviewbase.h"
class CurveView
class CurveView : public TimelineViewBase
{
public:
CurveView();
CurveView(QWidget* parent = nullptr);
protected:
virtual void drawBackground(QPainter* painter, const QRectF& rect) override;
private:
int text_padding_;
};
#endif // CURVEVIEW_H
+45
View File
@@ -0,0 +1,45 @@
#include "curvewidget.h"
#include <QLabel>
#include <QVBoxLayout>
#include "widget/nodeparamview/nodeparamviewkeyframecontrol.h"
CurveWidget::CurveWidget(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout* layout = new QVBoxLayout(this);
QHBoxLayout* top_controls = new QHBoxLayout();
NodeParamViewKeyframeControl* key_controls = new NodeParamViewKeyframeControl(false);
key_controls->SetEnableButtonVisible(false);
key_controls->SetPreviousButtonEnabled(false);
key_controls->SetToggleButtonEnabled(false);
key_controls->SetNextButtonEnabled(false);
top_controls->addWidget(key_controls);
top_controls->addStretch();
linear_button_ = new QPushButton(tr("Linear"));
linear_button_->setCheckable(true);
linear_button_->setEnabled(false);
top_controls->addWidget(linear_button_);
bezier_button_ = new QPushButton(tr("Bezier"));
bezier_button_->setCheckable(true);
bezier_button_->setEnabled(false);
top_controls->addWidget(bezier_button_);
hold_button_ = new QPushButton(tr("Hold"));
hold_button_->setCheckable(true);
hold_button_->setEnabled(false);
top_controls->addWidget(hold_button_);
layout->addLayout(top_controls);
view_ = new CurveView();
layout->addWidget(view_);
layout->addWidget(new QLabel("Values"));
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef CURVEWIDGET_H
#define CURVEWIDGET_H
#include <QPushButton>
#include <QWidget>
#include "curveview.h"
class CurveWidget : public QWidget
{
public:
CurveWidget(QWidget* parent = nullptr);
private:
QPushButton* linear_button_;
QPushButton* bezier_button_;
QPushButton* hold_button_;
CurveView* view_;
};
#endif // CURVEWIDGET_H
@@ -131,6 +131,8 @@ void NodeParamView::SetNodes(QList<Node *> nodes)
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged);
items_.append(item);
QTimer::singleShot(1, item, &NodeParamViewItem::SignalAllKeyframes);
}
if (!nodes_.isEmpty()) {
+15 -1
View File
@@ -88,6 +88,19 @@ void NodeParamViewItem::SetTime(const rational &time)
}
}
void NodeParamViewItem::SignalAllKeyframes()
{
foreach (NodeParam* param, node_->parameters()) {
if (param->type() == NodeParam::kInput) {
NodeInput* input = static_cast<NodeInput*>(param);
foreach (NodeKeyframePtr key, input->keyframes()) {
InputAddedKeyframeInternal(input, key);
}
}
}
}
void NodeParamViewItem::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
@@ -146,7 +159,8 @@ void NodeParamViewItem::SetupUI()
// Hacky but effective way to make sure this widget is always as far right as possible
int control_column = 10;
NodeParamViewKeyframeControl* key_control = new NodeParamViewKeyframeControl(input);
NodeParamViewKeyframeControl* key_control = new NodeParamViewKeyframeControl();
key_control->SetInput(input);
content_layout_->addWidget(key_control, row_count, control_column);
connect(key_control, &NodeParamViewKeyframeControl::KeyframeEnableChanged, this, &NodeParamViewItem::UserChangedKeyframeEnable);
connect(key_control, &NodeParamViewKeyframeControl::GoToPreviousKey, this, &NodeParamViewItem::GoToPreviousKey);
@@ -47,6 +47,9 @@ public:
void SetTime(const rational& time);
public slots:
void SignalAllKeyframes();
signals:
void KeyframeAdded(NodeKeyframePtr key, int y);
@@ -4,16 +4,18 @@
#include "ui/icons/icons.h"
NodeParamViewKeyframeControl::NodeParamViewKeyframeControl(NodeInput* input, QWidget *parent) :
NodeParamViewKeyframeControl::NodeParamViewKeyframeControl(bool right_align, QWidget *parent) :
QWidget(parent),
input_(input)
input_(nullptr)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
// Automatically right aligns all buttons
layout->addStretch();
if (right_align) {
// Automatically right aligns all buttons
layout->addStretch();
}
prev_key_btn_ = CreateNewToolButton(icon::TriLeft);
prev_key_btn_->setIconSize(prev_key_btn_->iconSize() / 2);
@@ -38,10 +40,6 @@ NodeParamViewKeyframeControl::NodeParamViewKeyframeControl(NodeInput* input, QWi
connect(toggle_key_btn_, &QPushButton::toggled, this, &NodeParamViewKeyframeControl::KeyframeToggled);
connect(enable_key_btn_, &QPushButton::toggled, this, &NodeParamViewKeyframeControl::ShowButtonsFromKeyframeEnable);
connect(enable_key_btn_, &QPushButton::toggled, this, &NodeParamViewKeyframeControl::KeyframeEnableChanged);
connect(input_, &NodeInput::KeyframeEnableChanged, this, &NodeParamViewKeyframeControl::SetKeyframeEnabled);
// Pick up keyframing value
ShowButtonsFromKeyframeEnable(input_->is_keyframing());
}
NodeInput *NodeParamViewKeyframeControl::GetConnectedInput() const
@@ -59,6 +57,11 @@ void NodeParamViewKeyframeControl::SetNextButtonEnabled(bool enabled)
next_key_btn_->setEnabled(enabled);
}
void NodeParamViewKeyframeControl::SetToggleButtonEnabled(bool enable)
{
toggle_key_btn_->setEnabled(enable);
}
void NodeParamViewKeyframeControl::SetToggleButtonChecked(bool checked)
{
// Suppress KeyframeToggled() signal from this object
@@ -69,6 +72,27 @@ void NodeParamViewKeyframeControl::SetToggleButtonChecked(bool checked)
blockSignals(false);
}
void NodeParamViewKeyframeControl::SetEnableButtonVisible(bool visible)
{
enable_key_btn_->setVisible(visible);
}
void NodeParamViewKeyframeControl::SetInput(NodeInput *input)
{
if (input_ != nullptr) {
disconnect(input_, &NodeInput::KeyframeEnableChanged, this, &NodeParamViewKeyframeControl::SetKeyframeEnabled);
}
input_ = input;
if (input_ != nullptr) {
connect(input_, &NodeInput::KeyframeEnableChanged, this, &NodeParamViewKeyframeControl::SetKeyframeEnabled);
// Pick up keyframing value
ShowButtonsFromKeyframeEnable(input_->is_keyframing());
}
}
void NodeParamViewKeyframeControl::SetKeyframeEnabled(bool e)
{
// Suppress KeyframeEnableChanged() signal from this object
@@ -10,13 +10,17 @@ class NodeParamViewKeyframeControl : public QWidget
{
Q_OBJECT
public:
NodeParamViewKeyframeControl(NodeInput* input, QWidget* parent = nullptr);
NodeParamViewKeyframeControl(bool right_align = true, QWidget* parent = nullptr);
NodeInput* GetConnectedInput() const;
void SetPreviousButtonEnabled(bool enabled);
void SetNextButtonEnabled(bool enabled);
void SetToggleButtonEnabled(bool enable);
void SetToggleButtonChecked(bool checked);
void SetEnableButtonVisible(bool visible);
void SetInput(NodeInput* input);
public slots:
void SetKeyframeEnabled(bool e);
+5
View File
@@ -27,6 +27,7 @@
// Panel objects
#include "panel/panelmanager.h"
#include "panel/audiomonitor/audiomonitor.h"
#include "panel/curve/curve.h"
#include "panel/node/node.h"
#include "panel/param/param.h"
#include "panel/project/project.h"
@@ -137,6 +138,10 @@ void MainWindow::ProjectOpen(Project* p)
task_man_panel->setFloating(true);
task_man_panel->setVisible(false);
CurvePanel* curve_panel = PanelManager::instance()->CreatePanel<CurvePanel>(this);
addDockWidget(Qt::BottomDockWidgetArea, curve_panel);
task_man_panel->setFloating(true);
connect(node_panel, SIGNAL(SelectionChanged(QList<Node*>)), param_panel, SLOT(SetNodes(QList<Node*>)));
}