Merge branch 'master' into nodeview-redux

This commit is contained in:
itsmattkc
2021-05-21 11:13:42 +10:00
66 changed files with 1066 additions and 569 deletions
+4 -2
View File
@@ -22,12 +22,14 @@ set(OLIVE_SOURCES
widget/nodeparamview/nodeparamviewarraywidget.cpp
widget/nodeparamview/nodeparamviewconnectedlabel.h
widget/nodeparamview/nodeparamviewconnectedlabel.cpp
widget/nodeparamview/nodeparamviewdockarea.h
widget/nodeparamview/nodeparamviewdockarea.cpp
widget/nodeparamview/nodeparamviewitem.h
widget/nodeparamview/nodeparamviewitem.cpp
widget/nodeparamview/nodeparamviewkeyframecontrol.h
widget/nodeparamview/nodeparamviewkeyframecontrol.cpp
widget/nodeparamview/nodeparamviewrichtext.h
widget/nodeparamview/nodeparamviewrichtext.cpp
widget/nodeparamview/nodeparamviewtextedit.h
widget/nodeparamview/nodeparamviewtextedit.cpp
widget/nodeparamview/nodeparamviewundo.h
widget/nodeparamview/nodeparamviewundo.cpp
widget/nodeparamview/nodeparamviewwidgetbridge.h
+1 -1
View File
@@ -55,7 +55,7 @@ NodeParamView::NodeParamView(QWidget *parent) :
connect(param_widget_container_, &NodeParamViewParamContainer::Resized, this, &NodeParamView::UpdateGlobalScrollBar);
scroll_area->setWidget(param_widget_container_);
param_widget_area_ = new QMainWindow();
param_widget_area_ = new NodeParamViewDockArea();
// Disable dock widgets from tabbing and disable glitchy animations
param_widget_area_->setDockOptions(static_cast<QMainWindow::DockOption>(0));
+2 -2
View File
@@ -21,11 +21,11 @@
#ifndef NODEPARAMVIEW_H
#define NODEPARAMVIEW_H
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
#include "node/node.h"
#include "nodeparamviewdockarea.h"
#include "nodeparamviewitem.h"
#include "widget/keyframeview/keyframeview.h"
#include "widget/timebased/timebasedwidget.h"
@@ -121,7 +121,7 @@ private:
// This may look weird, but QMainWindow is just a QWidget with a fancy layout that allows
// docking windows
QMainWindow* param_widget_area_;
NodeParamViewDockArea* param_widget_area_;
QVector<Node*> pinned_nodes_;
@@ -0,0 +1,35 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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/>.
***/
#include "nodeparamviewdockarea.h"
namespace olive {
NodeParamViewDockArea::NodeParamViewDockArea(QWidget *parent) :
QMainWindow(parent)
{
}
QMenu *NodeParamViewDockArea::createPopupMenu()
{
return nullptr;
}
}
@@ -0,0 +1,40 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 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/>.
***/
#ifndef NODEPARAMVIEWDOCKAREA_H
#define NODEPARAMVIEWDOCKAREA_H
#include <QMainWindow>
namespace olive {
class NodeParamViewDockArea : public QMainWindow
{
Q_OBJECT
public:
explicit NodeParamViewDockArea(QWidget *parent = nullptr);
virtual QMenu *createPopupMenu() override;
};
}
#endif // NODEPARAMVIEWDOCKAREA_H
@@ -18,46 +18,46 @@
***/
#include "nodeparamviewrichtext.h"
#include "nodeparamviewtextedit.h"
#include <QHBoxLayout>
#include <QPushButton>
#include "dialog/richtext/richtext.h"
#include "dialog/text/text.h"
#include "ui/icons/icons.h"
namespace olive {
NodeParamViewRichText::NodeParamViewRichText(QWidget *parent) :
NodeParamViewTextEdit::NodeParamViewTextEdit(QWidget *parent) :
QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
line_edit_ = new QTextEdit();
line_edit_ = new QPlainTextEdit();
line_edit_->setUndoRedoEnabled(true);
connect(line_edit_, &QTextEdit::textChanged, this, &NodeParamViewRichText::InnerWidgetTextChanged);
connect(line_edit_, &QPlainTextEdit::textChanged, this, &NodeParamViewTextEdit::InnerWidgetTextChanged);
layout->addWidget(line_edit_);
QPushButton* edit_btn = new QPushButton();
edit_btn->setIcon(icon::ToolEdit);
edit_btn->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
layout->addWidget(edit_btn);
connect(edit_btn, &QPushButton::clicked, this, &NodeParamViewRichText::ShowRichTextDialog);
connect(edit_btn, &QPushButton::clicked, this, &NodeParamViewTextEdit::ShowTextDialog);
}
void NodeParamViewRichText::ShowRichTextDialog()
void NodeParamViewTextEdit::ShowTextDialog()
{
RichTextDialog d(this->text(), this);
TextDialog d(this->text(), this);
if (d.exec() == QDialog::Accepted) {
QString s = d.text();
line_edit_->setText(s);
line_edit_->setPlainText(s);
emit textEdited(s);
}
}
void NodeParamViewRichText::InnerWidgetTextChanged()
void NodeParamViewTextEdit::InnerWidgetTextChanged()
{
emit textEdited(this->text());
}
@@ -18,32 +18,32 @@
***/
#ifndef NODEPARAMVIEWRICHTEXT_H
#define NODEPARAMVIEWRICHTEXT_H
#ifndef NODEPARAMVIEWTEXTEDIT_H
#define NODEPARAMVIEWTEXTEDIT_H
#include <QTextEdit>
#include <QPlainTextEdit>
#include <QWidget>
#include "common/define.h"
namespace olive {
class NodeParamViewRichText : public QWidget
class NodeParamViewTextEdit : public QWidget
{
Q_OBJECT
public:
NodeParamViewRichText(QWidget* parent = nullptr);
NodeParamViewTextEdit(QWidget* parent = nullptr);
QString text() const
{
return line_edit_->toPlainText().replace('\n', QStringLiteral("<br>"));
return line_edit_->toPlainText();
}
public slots:
void setText(QString s)
void setText(const QString &s)
{
line_edit_->blockSignals(true);
line_edit_->setPlainText(s.replace(QStringLiteral("<br>"), QStringLiteral("\n")));
line_edit_->setPlainText(s);
line_edit_->blockSignals(false);
}
@@ -65,10 +65,10 @@ signals:
void textEdited(const QString &);
private:
QTextEdit* line_edit_;
QPlainTextEdit* line_edit_;
private slots:
void ShowRichTextDialog();
void ShowTextDialog();
void InnerWidgetTextChanged();
@@ -76,4 +76,4 @@ private slots:
}
#endif // NODEPARAMVIEWRICHTEXT_H
#endif // NODEPARAMVIEWTEXTEDIT_H
@@ -30,7 +30,7 @@
#include "node/node.h"
#include "node/project/sequence/sequence.h"
#include "nodeparamviewarraywidget.h"
#include "nodeparamviewrichtext.h"
#include "nodeparamviewtextedit.h"
#include "nodeparamviewundo.h"
#include "undo/undostack.h"
#include "widget/colorbutton/colorbutton.h"
@@ -143,9 +143,9 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
case NodeValue::kText:
{
NodeParamViewRichText* line_edit = new NodeParamViewRichText();
NodeParamViewTextEdit* line_edit = new NodeParamViewTextEdit();
widgets_.append(line_edit);
connect(line_edit, &NodeParamViewRichText::textEdited, this, &NodeParamViewWidgetBridge::WidgetCallback);
connect(line_edit, &NodeParamViewTextEdit::textEdited, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
}
case NodeValue::kBoolean:
@@ -358,7 +358,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
case NodeValue::kText:
{
// Sender is a NodeParamViewRichText
SetInputValue(static_cast<NodeParamViewRichText*>(sender())->text(), 0);
SetInputValue(static_cast<NodeParamViewTextEdit*>(sender())->text(), 0);
break;
}
case NodeValue::kBoolean:
@@ -498,7 +498,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
}
case NodeValue::kText:
{
NodeParamViewRichText* e = static_cast<NodeParamViewRichText*>(widgets_.first());
NodeParamViewTextEdit* e = static_cast<NodeParamViewTextEdit*>(widgets_.first());
e->setTextPreservingCursor(input_.GetValueAtTime(node_time).toString());
break;
}
+9 -4
View File
@@ -1230,11 +1230,11 @@ public:
if (timeline_->type() == Track::kVideo) {
relevant_input = ViewerOutput::kTextureInput;
} else {
} else if (timeline_->type() == Track::kAudio) {
relevant_input = ViewerOutput::kSamplesInput;
}
if (!timeline_->parent()->IsInputConnected(relevant_input)) {
if (!relevant_input.isEmpty() && !timeline_->parent()->IsInputConnected(relevant_input)) {
direct_ = NodeInput(timeline_->parent(), relevant_input);
Node::ConnectEdge(track_, direct_);
@@ -1289,15 +1289,20 @@ private:
merge_ = new MergeNode();
base_ = NodeInput(merge_, MergeNode::kBaseIn);
blend_ = NodeInput(merge_, MergeNode::kBlendIn);
} else {
} else if (timeline_->type() == Track::kAudio) {
merge_ = new MathNode();
base_ = NodeInput(merge_, MathNode::kParamAIn);
blend_ = NodeInput(merge_, MathNode::kParamBIn);
} else {
merge_ = nullptr;
}
merge_->setParent(&memory_manager_);
} else {
merge_ = nullptr;
}
if (merge_) {
merge_->setParent(&memory_manager_);
}
}
TrackList* timeline_;
+26 -2
View File
@@ -77,7 +77,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
// Create list of TimelineViews - these MUST correspond to the ViewType enum
view_splitter_ = new QSplitter(Qt::Vertical);
view_splitter_->setChildrenCollapsible(false);
vert_layout->addWidget(view_splitter_);
// Video view
@@ -86,6 +85,9 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
// Audio view
views_.append(new TimelineAndTrackView(Qt::AlignTop));
// Subtitle view
views_.append(new TimelineAndTrackView(Qt::AlignTop));
// Create tools
tools_.resize(olive::Tool::kCount);
tools_.fill(nullptr);
@@ -155,7 +157,17 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
}
// Split viewer 50/50
view_splitter_->setSizes({INT_MAX, INT_MAX});
QList<int> view_sizes;
view_sizes.reserve(views_.size());
view_sizes.append(height()/2); // Video
view_sizes.append(height()/2); // Audio
view_sizes.append(0); // Subtitle (hidden by default)
view_splitter_->setSizes(view_sizes);
// Video and audio are not collapsible, subtitle is
view_splitter_->setCollapsible(Track::kVideo, false);
view_splitter_->setCollapsible(Track::kAudio, false);
view_splitter_->setCollapsible(Track::kSubtitle, true);
// FIXME: Magic number
SetScale(90.0);
@@ -786,11 +798,23 @@ void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event)
if (hover_tool) {
hover_tool->HoverMove(event);
// Special cast for subtitle adding - ensure section is visible
if (dynamic_cast<AddTool*>(hover_tool)
&& Core::instance()->GetSelectedAddableObject() == Tool::kAddableSubtitle) {
QList<int> sz = view_splitter_->sizes();
int &subtitle_section_height = sz[Track::kSubtitle];
if (subtitle_section_height == 0) {
subtitle_section_height = height() / Track::kCount;
view_splitter_->setSizes(sz);
}
}
}
}
}
}
void TimelineWidget::ViewMouseReleased(TimelineViewMouseEvent *event)
{
if (active_tool_) {
+13 -1
View File
@@ -20,6 +20,7 @@
#include "add.h"
#include "core.h"
#include "node/block/subtitle/subtitle.h"
#include "node/factory.h"
#include "node/generator/solid/solid.h"
#include "node/generator/text/text.h"
@@ -54,6 +55,9 @@ void AddTool::MousePress(TimelineViewMouseEvent *event)
case olive::Tool::kAddableTone:
add_type = Track::kAudio;
break;
case olive::Tool::kAddableSubtitle:
add_type = Track::kSubtitle;
break;
case olive::Tool::kAddableEmpty:
// Leave as "none", which means this block can be placed on any track
break;
@@ -93,7 +97,12 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
if (!ghost_->GetAdjustedLength().isNull()) {
MultiUndoCommand* command = new MultiUndoCommand();
ClipBlock* clip = new ClipBlock();
ClipBlock* clip;
if (Core::instance()->GetSelectedAddableObject() == olive::Tool::kAddableSubtitle) {
clip = new SubtitleBlock();
} else {
clip = new ClipBlock();
}
clip->set_length_and_media_out(ghost_->GetAdjustedLength());
clip->SetLabel(olive::Tool::GetAddableObjectName(Core::instance()->GetSelectedAddableObject()));
@@ -140,6 +149,9 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
// Not implemented yet
qWarning() << "Unimplemented add object:" << Core::instance()->GetSelectedAddableObject();
break;
case olive::Tool::kAddableSubtitle:
// The block itself is the node we want
break;
case olive::Tool::kAddableCount:
// Invalid value, do nothing
break;
@@ -60,7 +60,7 @@ void TimelineView::mousePressEvent(QMouseEvent *event)
TimelineViewMouseEvent timeline_event = CreateMouseEvent(event);
if (HandPress(event)
|| (!GetItemAtScenePos(timeline_event.GetFrame(), timeline_event.GetTrack().index()) && PlayheadPress(event))) {
|| (!GetItemAtScenePos(timeline_event.GetFrame(), timeline_event.GetTrack().index()) && Core::instance()->tool() != Tool::kAdd && PlayheadPress(event))) {
// Let the parent handle this
return;
}