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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "curveview.h"
|
||||
|
||||
CurveView::CurveView()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef CURVEVIEW_H
|
||||
#define CURVEVIEW_H
|
||||
|
||||
|
||||
class CurveView
|
||||
{
|
||||
public:
|
||||
CurveView();
|
||||
};
|
||||
|
||||
#endif // CURVEVIEW_H
|
||||
@@ -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
|
||||
)
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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*>)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user