work towards group editor
This commit is contained in:
@@ -23,10 +23,12 @@
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QSplitter>
|
||||
|
||||
#include "widget/nodeparamview/nodeparamview.h"
|
||||
#include "widget/nodeview/nodeview.h"
|
||||
#include "panel/node/node.h"
|
||||
#include "panel/panelmanager.h"
|
||||
#include "panel/param/param.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -35,7 +37,7 @@ namespace olive {
|
||||
NodeGroupDialog::NodeGroupDialog(NodeGroup *group, QWidget *parent) :
|
||||
super(parent),
|
||||
group_(group),
|
||||
parent_undo_(nullptr)
|
||||
prepend_undo_(nullptr)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
@@ -44,29 +46,26 @@ NodeGroupDialog::NodeGroupDialog(NodeGroup *group, QWidget *parent) :
|
||||
layout->addWidget(new QLabel(tr("Name:")), row, 0);
|
||||
|
||||
name_edit_ = new QLineEdit();
|
||||
name_edit_->setText(group->GetLabel());
|
||||
layout->addWidget(name_edit_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
QSplitter *splitter = new QSplitter(Qt::Horizontal);
|
||||
QMainWindow *splitter = new QMainWindow();
|
||||
QWidget *cw = new QWidget();
|
||||
cw->setFixedSize(0, 0);
|
||||
splitter->setCentralWidget(cw);
|
||||
layout->addWidget(splitter, row, 0, 1, 2);
|
||||
|
||||
NodeParamView *param_view = new NodeParamView(false);
|
||||
param_view->SetCreateCheckBoxes(kCheckBoxesOnNonConnected);
|
||||
splitter->addWidget(param_view);
|
||||
ParamPanel *param_view = PanelManager::instance()->CreatePanel<ParamPanel>(splitter);
|
||||
param_view->GetParamView()->SetIgnoreNodeFlags(true);
|
||||
param_view->GetParamView()->SetCreateCheckBoxes(kCheckBoxesOnNonConnected);
|
||||
splitter->addDockWidget(Qt::LeftDockWidgetArea, param_view);
|
||||
|
||||
NodeView *node_view = new NodeView();
|
||||
node_view->SetContexts({group});
|
||||
QMetaObject::invokeMethod(node_view, &NodeView::CenterOnItemsBoundingRect, Qt::QueuedConnection);
|
||||
splitter->addWidget(node_view);
|
||||
|
||||
splitter->setSizes({splitter->width() / 4, splitter->width() / 4 * 3});
|
||||
|
||||
for (auto it=group->GetInputPassthroughs().cbegin(); it!=group->GetInputPassthroughs().cend(); it++) {
|
||||
param_view->SetInputChecked(it.value(), true);
|
||||
}
|
||||
|
||||
param_view->SetContexts({group});
|
||||
NodePanel *node_view = PanelManager::instance()->CreatePanel<NodePanel>(splitter);
|
||||
node_view->GetNodeWidget()->view()->OverrideUndoStack(&undo_stack_);
|
||||
QMetaObject::invokeMethod(node_view->GetNodeWidget()->view(), &NodeView::CenterOnItemsBoundingRect, Qt::QueuedConnection);
|
||||
splitter->addDockWidget(Qt::RightDockWidgetArea, node_view);
|
||||
|
||||
row++;
|
||||
|
||||
@@ -76,24 +75,245 @@ NodeGroupDialog::NodeGroupDialog(NodeGroup *group, QWidget *parent) :
|
||||
connect(btns, &QDialogButtonBox::rejected, this, &NodeGroupDialog::reject);
|
||||
layout->addWidget(btns, row, 0, 1, 2);
|
||||
|
||||
setWindowTitle(tr("Group Editor"));
|
||||
setWindowTitle(tr("Group Editor - %1").arg(group->GetLabelOrName()));
|
||||
|
||||
// Create a project
|
||||
copied_project_ = new Project();
|
||||
copied_project_->setParent(this);
|
||||
|
||||
// Copy project nodes
|
||||
// NOTE: I hate this. What might be better is to fold the "ColorManager" and "ProjectSettings"
|
||||
// nodes into "Project" inputs and make "Project" a node too.
|
||||
for (int i=0; i<copied_project_->nodes().size(); i++) {
|
||||
Node *ours = copied_project_->nodes().at(i);
|
||||
Node *theirs = group_->project()->nodes().at(i);
|
||||
|
||||
copy_subnodes_.insert(theirs, ours);
|
||||
Node::CopyInputs(ours, theirs, false);
|
||||
}
|
||||
|
||||
// Copy group and nodes
|
||||
copy_group_ = static_cast<NodeGroup*>(group_->copy());
|
||||
copy_group_->setParent(copied_project_);
|
||||
|
||||
// Copy subnodes with positions
|
||||
const Node::PositionMap &map = group_->GetContextPositions();
|
||||
for (auto it=map.cbegin(); it!=map.cend(); it++) {
|
||||
Node *copy = it.key()->copy();
|
||||
copy->SetUUID(it.key()->GetUUID());
|
||||
copy->setParent(copied_project_);
|
||||
|
||||
copy_group_->SetNodePositionInContext(copy, it.value());
|
||||
copy_subnodes_.insert(it.key(), copy);
|
||||
}
|
||||
|
||||
for (auto it=map.cbegin(); it!=map.cend(); it++) {
|
||||
Node::CopyInputs(it.key(), copy_subnodes_.value(it.key()), false);
|
||||
}
|
||||
|
||||
// Copy edges
|
||||
for (auto it=copy_subnodes_.cbegin(); it!=copy_subnodes_.cend(); it++) {
|
||||
Node *src = it.key();
|
||||
Node *cpy = it.value();
|
||||
|
||||
for (auto jt=src->input_connections().cbegin(); jt!=src->input_connections().cend(); jt++) {
|
||||
if (Node *cpy_output = copy_subnodes_.value(jt->second)) {
|
||||
Node::ConnectEdge(cpy_output, NodeInput(cpy, jt->first.input(), jt->first.element()));
|
||||
copied_edges_.append({cpy_output, NodeInput(cpy, jt->first.input(), jt->first.element())});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node_view->SetContexts({copy_group_});
|
||||
|
||||
for (auto it=group_->GetInputPassthroughs().cbegin(); it!=group_->GetInputPassthroughs().cend(); it++) {
|
||||
const NodeInput &src_input = it.value();
|
||||
NodeInput copy_input(copy_subnodes_.value(src_input.node()), src_input.input(), src_input.element());
|
||||
param_view->GetParamView()->SetInputChecked(copy_input, true);
|
||||
}
|
||||
|
||||
param_view->SetContexts({copy_group_});
|
||||
}
|
||||
|
||||
void NodeGroupDialog::accept()
|
||||
{
|
||||
// First, validate if a connection, deleted node, or disabled passthrough is going to disconnect
|
||||
// something elsewhere in the group. Ask the user to confirm if so.
|
||||
|
||||
// Detect removed nodes
|
||||
QVector<Node*> nodes_to_delete = GetNodesToDelete();
|
||||
|
||||
// Detect new connections
|
||||
QVector<Node::OutputConnection> edges_to_connect = GetNewConnections();
|
||||
|
||||
// Warn user if operation will disconnect a node outside the group
|
||||
if (OperationWillAffectOutsideGroup(nodes_to_delete, edges_to_connect)) {
|
||||
if (QMessageBox::question(this, QString(), tr("This operation will disconnect nodes outside of this group. Do you wish to continue?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NodeViewDeleteCommand *delete_command = new NodeViewDeleteCommand();
|
||||
|
||||
// Remove deleted nodes
|
||||
foreach (Node *n, nodes_to_delete) {
|
||||
delete_command->AddNode(n, group_);
|
||||
}
|
||||
|
||||
// Disconnect old edges
|
||||
foreach (const Node::OutputConnection &edge, copied_edges_) {
|
||||
bool found = false;
|
||||
const NodeInput ©_input = edge.second;
|
||||
|
||||
for (auto it=edge.first->output_connections().cbegin(); it!=edge.first->output_connections().cend(); it++) {
|
||||
if (it->second == copy_input) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// Edge has been disconnected
|
||||
delete_command->AddEdge(copy_subnodes_.key(edge.first), NodeInput(copy_subnodes_.key(copy_input.node()), copy_input.input(), copy_input.element()));
|
||||
}
|
||||
}
|
||||
|
||||
delete_command->redo_now();
|
||||
|
||||
// Add new nodes
|
||||
MultiUndoCommand *add_command = new MultiUndoCommand();
|
||||
for (auto it=copy_group_->GetContextPositions().cbegin(); it!=copy_group_->GetContextPositions().cend(); it++) {
|
||||
Node *n = it.key();
|
||||
Node *original = copy_subnodes_.key(n);
|
||||
if (!original) {
|
||||
// If it's a new node that isn't even in the project yet, add it
|
||||
original = n->copy();
|
||||
Node::CopyInputs(n, original, false);
|
||||
add_command->add_child(new NodeAddCommand(group_->parent(), original));
|
||||
copy_subnodes_.insert(original, n);
|
||||
}
|
||||
|
||||
// Update position in context
|
||||
add_command->add_child(new NodeSetPositionCommand(original, group_, it.value()));
|
||||
}
|
||||
add_command->redo_now();
|
||||
|
||||
// Connect new edges
|
||||
MultiUndoCommand *connect_command = new MultiUndoCommand();
|
||||
edges_to_connect = GetNewConnections(); // Update list with new nodes made above if necessary
|
||||
foreach (const Node::OutputConnection &edge, edges_to_connect) {
|
||||
connect_command->add_child(new NodeEdgeAddCommand(edge.first, edge.second));
|
||||
}
|
||||
connect_command->redo_now();
|
||||
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
if (prepend_undo_) {
|
||||
command->add_child(prepend_undo_);
|
||||
}
|
||||
|
||||
command->add_child(delete_command);
|
||||
command->add_child(add_command);
|
||||
command->add_child(connect_command);
|
||||
|
||||
// Update group name
|
||||
if (name_edit_->text() != group_->GetCustomName()) {
|
||||
command->add_child(new NodeGroupSetCustomNameCommand(group_, name_edit_->text()));
|
||||
}
|
||||
|
||||
if (parent_undo_) {
|
||||
parent_undo_->add_child(command);
|
||||
} else {
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
}
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
|
||||
super::accept();
|
||||
}
|
||||
|
||||
void NodeGroupDialog::reject()
|
||||
{
|
||||
if (prepend_undo_) {
|
||||
prepend_undo_->undo_now();
|
||||
delete prepend_undo_;
|
||||
}
|
||||
|
||||
super::reject();
|
||||
}
|
||||
|
||||
QVector<Node *> NodeGroupDialog::GetNodesToDelete()
|
||||
{
|
||||
QVector<Node*> nodes_to_delete;
|
||||
|
||||
for (auto it=group_->GetContextPositions().cbegin(); it!=group_->GetContextPositions().cend(); it++) {
|
||||
Node *original = it.key();
|
||||
Node *copy = copy_subnodes_.value(original);
|
||||
|
||||
if (!copy_group_->ContextContainsNode(copy)) {
|
||||
nodes_to_delete.append(original);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes_to_delete;
|
||||
}
|
||||
|
||||
QVector<Node::OutputConnection> NodeGroupDialog::GetNewConnections()
|
||||
{
|
||||
QVector<Node::OutputConnection> edges_to_connect;
|
||||
|
||||
for (auto it=copy_group_->GetContextPositions().cbegin(); it!=copy_group_->GetContextPositions().cend(); it++) {
|
||||
const Node::InputConnections &ic = it.key()->input_connections();
|
||||
|
||||
for (auto jt=ic.cbegin(); jt!=ic.cend(); jt++) {
|
||||
// All connections inside this dialog will be valid and inside the group
|
||||
const NodeInput &copied_input = jt->first;
|
||||
Node *copied_output = jt->second;
|
||||
|
||||
NodeInput original_input(copy_subnodes_.key(copied_input.node()), copied_input.input(), copied_input.element());
|
||||
Node *original_output = copy_subnodes_.key(copied_output);
|
||||
|
||||
bool found = false;
|
||||
|
||||
if (original_output) {
|
||||
for (auto kt=original_output->output_connections().cbegin(); kt!=original_output->output_connections().cend(); kt++) {
|
||||
if (kt->second == original_input) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
edges_to_connect.append({original_output, original_input});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return edges_to_connect;
|
||||
}
|
||||
|
||||
bool NodeGroupDialog::OperationWillAffectOutsideGroup(const QVector<Node*> &deleted, const QVector<Node::OutputConnection> &connections)
|
||||
{
|
||||
// Check if a node to be deleted inputs from a node outside the group
|
||||
foreach (Node *n, deleted) {
|
||||
for (auto jt=n->input_connections().cbegin(); jt!=n->input_connections().cend(); jt++) {
|
||||
if (!group_->ContextContainsNode(jt->second)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto jt=n->output_connections().cbegin(); jt!=n->output_connections().cend(); jt++) {
|
||||
if (!group_->ContextContainsNode(jt->second.node())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a new connection will overwrite a connection from outside the group
|
||||
foreach (const Node::OutputConnection &edge, connections) {
|
||||
if (Node *current_conn = edge.second.GetConnectedOutput()) {
|
||||
if (!group_->ContextContainsNode(current_conn)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "node/group/group.h"
|
||||
#include "undo/undostack.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -34,22 +36,37 @@ class NodeGroupDialog : public QDialog
|
||||
public:
|
||||
explicit NodeGroupDialog(NodeGroup *group, QWidget *parent = nullptr);
|
||||
|
||||
void SetParentUndoCommand(MultiUndoCommand *c)
|
||||
void PrependUndoCommand(MultiUndoCommand *c)
|
||||
{
|
||||
parent_undo_ = c;
|
||||
prepend_undo_ = c;
|
||||
}
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
|
||||
virtual void reject() override;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
QVector<Node*> GetNodesToDelete();
|
||||
|
||||
QVector<Node::OutputConnection> GetNewConnections();
|
||||
|
||||
bool OperationWillAffectOutsideGroup(const QVector<Node *> &deleted, const QVector<Node::OutputConnection> &connections);
|
||||
|
||||
NodeGroup *group_;
|
||||
|
||||
QLineEdit *name_edit_;
|
||||
|
||||
MultiUndoCommand *parent_undo_;
|
||||
MultiUndoCommand *prepend_undo_;
|
||||
|
||||
Project *copied_project_;
|
||||
NodeGroup *copy_group_;
|
||||
QMap<Node*, Node*> copy_subnodes_;
|
||||
QVector<Node::OutputConnection> copied_edges_;
|
||||
|
||||
UndoStack undo_stack_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -105,10 +105,6 @@ void NodeGraph::childEvent(QChildEvent *event)
|
||||
// Remove from any contexts
|
||||
foreach (Node *context, node_children_) {
|
||||
context->RemoveNodeFromContext(node);
|
||||
|
||||
if (NodeGroup *group = dynamic_cast<NodeGroup*>(context)) {
|
||||
group->RemoveNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,28 +55,14 @@ QString NodeGroup::Description() const
|
||||
|
||||
void NodeGroup::Retranslate()
|
||||
{
|
||||
foreach (Node *n, nodes_) {
|
||||
n->Retranslate();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGroup::AddNode(Node *node)
|
||||
{
|
||||
nodes_.append(node);
|
||||
|
||||
emit NodeAddedToGroup(node);
|
||||
}
|
||||
|
||||
void NodeGroup::RemoveNode(Node *node)
|
||||
{
|
||||
if (nodes_.removeOne(node)) {
|
||||
emit NodeRemovedFromGroup(node);
|
||||
for (auto it=GetContextPositions().cbegin(); it!=GetContextPositions().cend(); it++) {
|
||||
it.key()->Retranslate();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGroup::AddInputPassthrough(const NodeInput &input)
|
||||
{
|
||||
Q_ASSERT(nodes_.contains(input.node()));
|
||||
Q_ASSERT(ContextContainsNode(input.node()));
|
||||
|
||||
for (auto it=input_passthroughs_.cbegin(); it!=input_passthroughs_.cend(); it++) {
|
||||
if (it.value() == input) {
|
||||
@@ -109,7 +95,7 @@ void NodeGroup::RemoveInputPassthrough(const NodeInput &input)
|
||||
|
||||
void NodeGroup::SetOutputPassthrough(Node *node)
|
||||
{
|
||||
Q_ASSERT(!node || nodes_.contains(node));
|
||||
Q_ASSERT(!node || ContextContainsNode(node));
|
||||
|
||||
output_passthrough_ = node;
|
||||
|
||||
@@ -145,16 +131,6 @@ QString NodeGroup::GetInputName(const QString &id) const
|
||||
return input_passthroughs_.value(id).name();
|
||||
}
|
||||
|
||||
void NodeAddToGroupCommand::redo()
|
||||
{
|
||||
group_->AddNode(node_);
|
||||
}
|
||||
|
||||
void NodeAddToGroupCommand::undo()
|
||||
{
|
||||
group_->RemoveNode(node_);
|
||||
}
|
||||
|
||||
void NodeGroupSetCustomNameCommand::redo()
|
||||
{
|
||||
old_name_ = group_->GetCustomName();
|
||||
@@ -183,16 +159,6 @@ void NodeGroupAddInputPassthrough::undo()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeRemoveFromGroupCommand::redo()
|
||||
{
|
||||
group_->RemoveNode(node_);
|
||||
}
|
||||
|
||||
void NodeRemoveFromGroupCommand::undo()
|
||||
{
|
||||
group_->AddNode(node_);
|
||||
}
|
||||
|
||||
void NodeGroupSetOutputPassthrough::redo()
|
||||
{
|
||||
old_output_ = group_->GetOutputPassthrough();
|
||||
|
||||
@@ -41,20 +41,6 @@ public:
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
void AddNode(Node *node);
|
||||
|
||||
void RemoveNode(Node *node);
|
||||
|
||||
bool ContainsNode(Node *node) const
|
||||
{
|
||||
return nodes_.contains(node);
|
||||
}
|
||||
|
||||
const QVector<Node*> &GetNodes() const
|
||||
{
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
void AddInputPassthrough(const NodeInput &input);
|
||||
|
||||
void RemoveInputPassthrough(const NodeInput &input);
|
||||
@@ -96,10 +82,6 @@ public:
|
||||
virtual QString GetInputName(const QString& id) const override;
|
||||
|
||||
signals:
|
||||
void NodeAddedToGroup(Node *node);
|
||||
|
||||
void NodeRemovedFromGroup(Node *node);
|
||||
|
||||
void InputPassthroughAdded(NodeGroup *group, const NodeInput &input);
|
||||
|
||||
void InputPassthroughRemoved(NodeGroup *group, const NodeInput &input);
|
||||
@@ -107,8 +89,6 @@ signals:
|
||||
void OutputPassthroughChanged(NodeGroup *group, Node *output);
|
||||
|
||||
private:
|
||||
QVector<Node*> nodes_;
|
||||
|
||||
QHash<QString, NodeInput> input_passthroughs_;
|
||||
|
||||
Node *output_passthrough_;
|
||||
@@ -117,56 +97,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class NodeAddToGroupCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
NodeAddToGroupCommand(Node *node, NodeGroup *group) :
|
||||
node_(node),
|
||||
group_(group)
|
||||
{}
|
||||
|
||||
virtual Project * GetRelevantProject() const override
|
||||
{
|
||||
return node_->project();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Node *node_;
|
||||
|
||||
NodeGroup *group_;
|
||||
|
||||
};
|
||||
|
||||
class NodeRemoveFromGroupCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
NodeRemoveFromGroupCommand(Node *node, NodeGroup *group) :
|
||||
node_(node),
|
||||
group_(group)
|
||||
{}
|
||||
|
||||
virtual Project * GetRelevantProject() const override
|
||||
{
|
||||
return node_->project();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Node *node_;
|
||||
|
||||
NodeGroup *group_;
|
||||
|
||||
};
|
||||
|
||||
class NodeGroupSetCustomNameCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
|
||||
+6
-26
@@ -20,40 +20,20 @@
|
||||
|
||||
#include "node.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
NodePanel::NodePanel(QWidget *parent) :
|
||||
PanelWidget(QStringLiteral("NodePanel"), parent)
|
||||
{
|
||||
QWidget *outer_widget = new QWidget(this);
|
||||
node_widget_ = new NodeWidget();
|
||||
connect(this, &NodePanel::visibilityChanged, node_widget_->view(), &NodeView::CenterOnItemsBoundingRect);
|
||||
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(outer_widget);
|
||||
outer_layout->setMargin(0);
|
||||
|
||||
toolbar_ = new NodeViewToolBar();
|
||||
outer_layout->addWidget(toolbar_);
|
||||
|
||||
// Create NodeView widget
|
||||
node_view_ = new NodeView(this);
|
||||
outer_layout->addWidget(node_view_);
|
||||
connect(this, &NodePanel::visibilityChanged, node_view_, &NodeView::CenterOnItemsBoundingRect);
|
||||
|
||||
// Connect toolbar to NodeView
|
||||
connect(toolbar_, &NodeViewToolBar::MiniMapEnabledToggled, node_view_, &NodeView::SetMiniMapEnabled);
|
||||
connect(toolbar_, &NodeViewToolBar::AddNodeClicked, node_view_, &NodeView::ShowAddMenu);
|
||||
|
||||
// Set defaults
|
||||
toolbar_->SetMiniMapEnabled(true);
|
||||
node_view_->SetMiniMapEnabled(true);
|
||||
|
||||
// Connect node view signals to this panel
|
||||
connect(node_view_, &NodeView::NodesSelected, this, &NodePanel::NodesSelected);
|
||||
connect(node_view_, &NodeView::NodesDeselected, this, &NodePanel::NodesDeselected);
|
||||
// Connect node view signals to this panel - MAY REMOVE
|
||||
connect(node_widget_->view(), &NodeView::NodesSelected, this, &NodePanel::NodesSelected);
|
||||
connect(node_widget_->view(), &NodeView::NodesDeselected, this, &NodePanel::NodesDeselected);
|
||||
|
||||
// Set it as the main widget of this panel
|
||||
SetWidgetWithPadding(outer_widget);
|
||||
SetWidgetWithPadding(node_widget_);
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
|
||||
+21
-20
@@ -21,8 +21,7 @@
|
||||
#ifndef NODEPANEL_H
|
||||
#define NODEPANEL_H
|
||||
|
||||
#include "widget/nodeview/nodeview.h"
|
||||
#include "widget/nodeview/nodeviewtoolbar.h"
|
||||
#include "widget/nodeview/nodewidget.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -36,76 +35,80 @@ class NodePanel : public PanelWidget
|
||||
public:
|
||||
NodePanel(QWidget* parent);
|
||||
|
||||
NodeWidget *GetNodeWidget() const
|
||||
{
|
||||
return node_widget_;
|
||||
}
|
||||
|
||||
void SetContexts(const QVector<Node*> &nodes)
|
||||
{
|
||||
node_view_->SetContexts(nodes);
|
||||
toolbar_->setEnabled(!nodes.isEmpty());
|
||||
node_widget_->SetContexts(nodes);
|
||||
}
|
||||
|
||||
void CloseContextsBelongingToProject(Project *project)
|
||||
{
|
||||
node_view_->CloseContextsBelongingToProject(project);
|
||||
node_widget_->view()->CloseContextsBelongingToProject(project);
|
||||
}
|
||||
|
||||
const QVector<Node*> &GetCurrentContexts() const
|
||||
{
|
||||
return node_view_->GetCurrentContexts();
|
||||
return node_widget_->view()->GetCurrentContexts();
|
||||
}
|
||||
|
||||
virtual void SelectAll() override
|
||||
{
|
||||
node_view_->SelectAll();
|
||||
node_widget_->view()->SelectAll();
|
||||
}
|
||||
|
||||
virtual void DeselectAll() override
|
||||
{
|
||||
node_view_->DeselectAll();
|
||||
node_widget_->view()->DeselectAll();
|
||||
}
|
||||
|
||||
virtual void DeleteSelected() override
|
||||
{
|
||||
node_view_->DeleteSelected();
|
||||
node_widget_->view()->DeleteSelected();
|
||||
}
|
||||
|
||||
virtual void CutSelected() override
|
||||
{
|
||||
node_view_->CopySelected(true);
|
||||
node_widget_->view()->CopySelected(true);
|
||||
}
|
||||
|
||||
virtual void CopySelected() override
|
||||
{
|
||||
node_view_->CopySelected(false);
|
||||
node_widget_->view()->CopySelected(false);
|
||||
}
|
||||
|
||||
virtual void Paste() override
|
||||
{
|
||||
node_view_->Paste();
|
||||
node_widget_->view()->Paste();
|
||||
}
|
||||
|
||||
virtual void Duplicate() override
|
||||
{
|
||||
node_view_->Duplicate();
|
||||
node_widget_->view()->Duplicate();
|
||||
}
|
||||
|
||||
virtual void SetColorLabel(int index) override
|
||||
{
|
||||
node_view_->SetColorLabel(index);
|
||||
node_widget_->view()->SetColorLabel(index);
|
||||
}
|
||||
|
||||
virtual void ZoomIn() override
|
||||
{
|
||||
node_view_->ZoomIn();
|
||||
node_widget_->view()->ZoomIn();
|
||||
}
|
||||
|
||||
virtual void ZoomOut() override
|
||||
{
|
||||
node_view_->ZoomOut();
|
||||
node_widget_->view()->ZoomOut();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void Select(const QVector<Node*>& nodes, bool center_view_on_item)
|
||||
{
|
||||
node_view_->Select(nodes, center_view_on_item);
|
||||
node_widget_->view()->Select(nodes, center_view_on_item);
|
||||
}
|
||||
|
||||
signals:
|
||||
@@ -119,9 +122,7 @@ private:
|
||||
SetTitle(tr("Node Editor"));
|
||||
}
|
||||
|
||||
NodeView* node_view_;
|
||||
|
||||
NodeViewToolBar *toolbar_;
|
||||
NodeWidget *node_widget_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ ParamPanel::ParamPanel(QWidget* parent) :
|
||||
|
||||
void ParamPanel::SelectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
//static_cast<NodeParamView*>(GetTimeBasedWidget())->SelectNodes(nodes);
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->SelectNodes(nodes);
|
||||
}
|
||||
|
||||
void ParamPanel::DeselectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
//static_cast<NodeParamView*>(GetTimeBasedWidget())->DeselectNodes(nodes);
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->DeselectNodes(nodes);
|
||||
}
|
||||
|
||||
void ParamPanel::DeleteSelected()
|
||||
|
||||
@@ -33,6 +33,11 @@ class ParamPanel : public TimeBasedPanel
|
||||
public:
|
||||
ParamPanel(QWidget* parent);
|
||||
|
||||
NodeParamView *GetParamView() const
|
||||
{
|
||||
return static_cast<NodeParamView *>(GetTimeBasedWidget());
|
||||
}
|
||||
|
||||
public slots:
|
||||
void SelectNodes(const QVector<Node*>& nodes);
|
||||
void DeselectNodes(const QVector<Node*>& nodes);
|
||||
|
||||
@@ -367,6 +367,11 @@ void PreviewAutoCacher::ProcessUpdateQueue()
|
||||
|
||||
void PreviewAutoCacher::AddNode(Node *node)
|
||||
{
|
||||
if (dynamic_cast<NodeGroup*>(node)) {
|
||||
// Group nodes are just dummy nodes, no need to copy them
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy node
|
||||
Node* copy = node->copy();
|
||||
|
||||
|
||||
+17
-21
@@ -24,34 +24,24 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
MultiUndoCommand::MultiUndoCommand() :
|
||||
done_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void MultiUndoCommand::redo()
|
||||
{
|
||||
if (!done_) {
|
||||
for (auto it=children_.cbegin(); it!=children_.cend(); it++) {
|
||||
(*it)->redo_and_set_modified();
|
||||
}
|
||||
done_ = true;
|
||||
for (auto it=children_.cbegin(); it!=children_.cend(); it++) {
|
||||
(*it)->redo_and_set_modified();
|
||||
}
|
||||
}
|
||||
|
||||
void MultiUndoCommand::undo()
|
||||
{
|
||||
if (done_) {
|
||||
for (auto it=children_.crbegin(); it!=children_.crend(); it++) {
|
||||
(*it)->undo_and_set_modified();
|
||||
}
|
||||
done_ = false;
|
||||
for (auto it=children_.crbegin(); it!=children_.crend(); it++) {
|
||||
(*it)->undo_and_set_modified();
|
||||
}
|
||||
}
|
||||
|
||||
UndoCommand::UndoCommand()
|
||||
{
|
||||
prepared_ = false;
|
||||
done_ = false;
|
||||
}
|
||||
|
||||
void UndoCommand::redo_and_set_modified()
|
||||
@@ -76,17 +66,23 @@ void UndoCommand::undo_and_set_modified()
|
||||
|
||||
void UndoCommand::redo_now()
|
||||
{
|
||||
if (!prepared_) {
|
||||
prepare();
|
||||
prepared_ = true;
|
||||
}
|
||||
if (!done_) {
|
||||
if (!prepared_) {
|
||||
prepare();
|
||||
prepared_ = true;
|
||||
}
|
||||
|
||||
redo();
|
||||
redo();
|
||||
done_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UndoCommand::undo_now()
|
||||
{
|
||||
undo();
|
||||
if (done_) {
|
||||
undo();
|
||||
done_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,12 +75,14 @@ private:
|
||||
|
||||
bool prepared_;
|
||||
|
||||
bool done_;
|
||||
|
||||
};
|
||||
|
||||
class MultiUndoCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
MultiUndoCommand();
|
||||
MultiUndoCommand() = default;
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
@@ -109,8 +111,6 @@ protected:
|
||||
private:
|
||||
std::vector<UndoCommand*> children_;
|
||||
|
||||
bool done_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
last_scroll_val_(0),
|
||||
focused_node_(nullptr),
|
||||
create_checkboxes_(kNoCheckBoxes),
|
||||
time_target_(nullptr)
|
||||
time_target_(nullptr),
|
||||
ignore_flags_(false)
|
||||
{
|
||||
// Create horizontal layout to place scroll area in (and keyframe editing eventually)
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
@@ -268,7 +269,7 @@ void NodeParamView::SetContexts(const QVector<Node *> &contexts)
|
||||
item->setVisible(true);
|
||||
|
||||
for (auto it=ctx->GetContextPositions().cbegin(); it!=ctx->GetContextPositions().cend(); it++) {
|
||||
if (!(it.key()->GetFlags() & Node::kDontShowInParamView)) {
|
||||
if (!(it.key()->GetFlags() & Node::kDontShowInParamView) || ignore_flags_) {
|
||||
AddNode(it.key(), item);
|
||||
}
|
||||
}
|
||||
@@ -351,6 +352,16 @@ void NodeParamView::DeleteSelected()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
// Do nothing, this is a placeholder if we ever need this to do anything in the future
|
||||
}
|
||||
|
||||
void NodeParamView::DeselectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
// Do nothing, this is a placeholder if we ever need this to do anything in the future
|
||||
}
|
||||
|
||||
void NodeParamView::UpdateItemTime(const rational &time)
|
||||
{
|
||||
foreach (NodeParamViewContext* item, context_items_) {
|
||||
@@ -543,6 +554,9 @@ void NodeParamView::UpdateElementY()
|
||||
|
||||
int y = it.value()->GetElementY(ic);
|
||||
|
||||
// For some reason Qt's mapToGlobal doesn't seem to handle this, so we offset here
|
||||
y += vertical_scrollbar_->value();
|
||||
|
||||
const KeyframeView::InputConnections &input_con = connections.value(input);
|
||||
int use_index = i + 1;
|
||||
if (use_index < input_con.size()) {
|
||||
|
||||
@@ -69,6 +69,14 @@ public:
|
||||
keyframe_view_->DeselectAll();
|
||||
}
|
||||
|
||||
void SetIgnoreNodeFlags(bool e)
|
||||
{
|
||||
ignore_flags_ = e;
|
||||
}
|
||||
|
||||
void SelectNodes(const QVector<Node*> &nodes);
|
||||
void DeselectNodes(const QVector<Node*> &nodes);
|
||||
|
||||
public slots:
|
||||
void SetInputChecked(const NodeInput &input, bool e);
|
||||
|
||||
@@ -123,6 +131,8 @@ private:
|
||||
|
||||
QHash<NodeInput, bool> input_checked_;
|
||||
|
||||
bool ignore_flags_;
|
||||
|
||||
private slots:
|
||||
void UpdateGlobalScrollBar();
|
||||
|
||||
|
||||
@@ -35,5 +35,7 @@ set(OLIVE_SOURCES
|
||||
widget/nodeview/nodeviewtoolbar.h
|
||||
widget/nodeview/nodeviewundo.cpp
|
||||
widget/nodeview/nodeviewundo.h
|
||||
widget/nodeview/nodewidget.cpp
|
||||
widget/nodeview/nodewidget.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <QScrollBar>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "core.h"
|
||||
#include "dialog/nodegroup/nodegroupdialog.h"
|
||||
#include "nodeviewundo.h"
|
||||
#include "node/audio/volume/volume.h"
|
||||
@@ -50,6 +49,7 @@ NodeView::NodeView(QWidget *parent) :
|
||||
create_edge_output_item_(nullptr),
|
||||
create_edge_input_item_(nullptr),
|
||||
paste_command_(nullptr),
|
||||
undo_stack_(Core::instance()->undo_stack()),
|
||||
scale_(1.0)
|
||||
{
|
||||
setScene(&scene_);
|
||||
@@ -127,7 +127,13 @@ void NodeView::ClearGraph()
|
||||
|
||||
void NodeView::DeleteSelected()
|
||||
{
|
||||
scene_.DeleteSelected();
|
||||
NodeViewDeleteCommand* command = new NodeViewDeleteCommand();
|
||||
|
||||
foreach (NodeViewContext *ctx, scene_.context_map()) {
|
||||
ctx->DeleteSelected(command);
|
||||
}
|
||||
|
||||
undo_stack_->push(command);
|
||||
}
|
||||
|
||||
void NodeView::SelectAll()
|
||||
@@ -221,7 +227,7 @@ void NodeView::SetColorLabel(int index)
|
||||
command->add_child(new NodeOverrideColorCommand(node, index));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
undo_stack_->push(command);
|
||||
}
|
||||
|
||||
void NodeView::ZoomIn()
|
||||
@@ -276,7 +282,7 @@ void NodeView::keyPressEvent(QKeyEvent *event)
|
||||
}
|
||||
}
|
||||
}
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(pos_command);
|
||||
undo_stack_->pushIfHasChildren(pos_command);
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Escape:
|
||||
@@ -555,7 +561,7 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
create_edge_expanded_items_.clear();
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
undo_stack_->pushIfHasChildren(command);
|
||||
}
|
||||
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
@@ -639,7 +645,7 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
dragging_items_.clear();
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
undo_stack_->pushIfHasChildren(command);
|
||||
|
||||
super::mouseReleaseEvent(event);
|
||||
}
|
||||
@@ -1199,7 +1205,6 @@ void NodeView::GroupNodes()
|
||||
DeselectAll();
|
||||
foreach (Node *n, nodes_to_group) {
|
||||
command->add_child(new NodeRemovePositionFromContextCommand(n, context));
|
||||
command->add_child(new NodeAddToGroupCommand(n, group));
|
||||
command->add_child(new NodeSetPositionCommand(n, group, context->GetNodePositionDataInContext(n)));
|
||||
|
||||
for (auto it=n->inputs().cbegin(); it!=n->inputs().cend(); it++) {
|
||||
@@ -1232,14 +1237,8 @@ void NodeView::GroupNodes()
|
||||
command->redo_now();
|
||||
|
||||
NodeGroupDialog ngd(group, this);
|
||||
if (ngd.exec() == QDialog::Accepted) {
|
||||
// Push to stack so it can be undone (MultiUndoCommand will ignore the request to redo again)
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
} else {
|
||||
// Undo command and delete
|
||||
command->undo_now();
|
||||
delete command;
|
||||
}
|
||||
ngd.PrependUndoCommand(command);
|
||||
ngd.exec();
|
||||
}
|
||||
|
||||
void NodeView::UngroupNodes()
|
||||
@@ -1269,13 +1268,12 @@ void NodeView::UngroupNodes()
|
||||
command->add_child(new NodeRemovePositionFromContextCommand(group, context));
|
||||
command->add_child(new NodeRemoveAndDisconnectCommand(group));
|
||||
|
||||
foreach (Node *n, group->GetNodes()) {
|
||||
command->add_child(new NodeRemovePositionFromContextCommand(n, group));
|
||||
command->add_child(new NodeRemoveFromGroupCommand(n, group));
|
||||
command->add_child(new NodeSetPositionCommand(n, context, group->GetNodePositionDataInContext(n)));
|
||||
for (auto it=group->GetContextPositions().cbegin(); it!=group->GetContextPositions().cend(); it++) {
|
||||
command->add_child(new NodeRemovePositionFromContextCommand(it.key(), group));
|
||||
command->add_child(new NodeSetPositionCommand(it.key(), context, group->GetNodePositionDataInContext(it.key())));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
undo_stack_->push(command);
|
||||
}
|
||||
|
||||
void NodeView::ShowNodeProperties()
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <QGraphicsView>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core.h"
|
||||
#include "node/graph.h"
|
||||
#include "node/nodecopypaste.h"
|
||||
#include "nodeviewedge.h"
|
||||
@@ -76,6 +77,11 @@ public:
|
||||
|
||||
void ZoomOut();
|
||||
|
||||
void OverrideUndoStack(UndoStack *stack)
|
||||
{
|
||||
undo_stack_ = stack;
|
||||
}
|
||||
|
||||
const QVector<Node*> &GetCurrentContexts() const
|
||||
{
|
||||
return contexts_;
|
||||
@@ -189,6 +195,8 @@ private:
|
||||
|
||||
QMap<NodeViewItem*, QPointF> dragging_items_;
|
||||
|
||||
UndoStack *undo_stack_;
|
||||
|
||||
double scale_;
|
||||
|
||||
static const double kMinimumScale;
|
||||
|
||||
@@ -56,13 +56,13 @@ void NodeViewContext::AddChild(Node *node)
|
||||
AddNodeInternal(node, item);
|
||||
|
||||
if (NodeGroup *group = dynamic_cast<NodeGroup*>(node)) {
|
||||
foreach (Node *n, group->GetNodes()) {
|
||||
for (auto it=group->GetContextPositions().cbegin(); it!=group->GetContextPositions().cend(); it++) {
|
||||
// Use this item as the representative for all of these nodes too
|
||||
AddNodeInternal(n, item);
|
||||
AddNodeInternal(it.key(), item);
|
||||
}
|
||||
|
||||
connect(group, &NodeGroup::NodeAddedToGroup, this, &NodeViewContext::GroupAddedNode);
|
||||
connect(group, &NodeGroup::NodeRemovedFromGroup, this, &NodeViewContext::GroupRemovedNode);
|
||||
connect(group, &NodeGroup::NodeAddedToContext, this, &NodeViewContext::GroupAddedNode);
|
||||
connect(group, &NodeGroup::NodeRemovedFromContext, this, &NodeViewContext::GroupRemovedNode);
|
||||
}
|
||||
|
||||
UpdateRect();
|
||||
@@ -78,6 +78,11 @@ void NodeViewContext::RemoveChild(Node *node)
|
||||
disconnect(node, &Node::InputConnected, this, &NodeViewContext::ChildInputConnected);
|
||||
disconnect(node, &Node::InputDisconnected, this, &NodeViewContext::ChildInputDisconnected);
|
||||
|
||||
if (NodeGroup *group = dynamic_cast<NodeGroup*>(node)) {
|
||||
disconnect(group, &NodeGroup::NodeAddedToContext, this, &NodeViewContext::GroupAddedNode);
|
||||
disconnect(group, &NodeGroup::NodeRemovedFromContext, this, &NodeViewContext::GroupRemovedNode);
|
||||
}
|
||||
|
||||
NodeViewItem *item = item_map_.take(node);
|
||||
|
||||
// Delete edges first because the edge destructor will try to reference item (maybe that should
|
||||
|
||||
@@ -58,17 +58,6 @@ void NodeViewScene::DeselectAll()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewScene::DeleteSelected()
|
||||
{
|
||||
NodeViewDeleteCommand* command = new NodeViewDeleteCommand();
|
||||
|
||||
foreach (NodeViewContext *ctx, context_map_) {
|
||||
ctx->DeleteSelected(command);
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
}
|
||||
|
||||
QVector<NodeViewItem *> NodeViewScene::GetSelectedItems() const
|
||||
{
|
||||
QVector<NodeViewItem *> items;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "nodeviewcontext.h"
|
||||
#include "nodeviewedge.h"
|
||||
#include "nodeviewitem.h"
|
||||
#include "undo/undostack.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -40,8 +41,6 @@ public:
|
||||
void SelectAll();
|
||||
void DeselectAll();
|
||||
|
||||
void DeleteSelected();
|
||||
|
||||
QVector<NodeViewItem*> GetSelectedItems() const;
|
||||
|
||||
const QHash<Node*, NodeViewContext*> &context_map() const
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/***
|
||||
|
||||
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 "nodewidget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
NodeWidget::NodeWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
outer_layout->setMargin(0);
|
||||
|
||||
toolbar_ = new NodeViewToolBar();
|
||||
outer_layout->addWidget(toolbar_);
|
||||
|
||||
// Create NodeView widget
|
||||
node_view_ = new NodeView(this);
|
||||
outer_layout->addWidget(node_view_);
|
||||
|
||||
// Connect toolbar to NodeView
|
||||
connect(toolbar_, &NodeViewToolBar::MiniMapEnabledToggled, node_view_, &NodeView::SetMiniMapEnabled);
|
||||
connect(toolbar_, &NodeViewToolBar::AddNodeClicked, node_view_, &NodeView::ShowAddMenu);
|
||||
|
||||
// Set defaults
|
||||
toolbar_->SetMiniMapEnabled(true);
|
||||
node_view_->SetMiniMapEnabled(true);
|
||||
|
||||
setSizePolicy(node_view_->sizePolicy());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/***
|
||||
|
||||
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 NODEWIDGET_H
|
||||
#define NODEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "nodeview.h"
|
||||
#include "nodeviewtoolbar.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class NodeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeWidget(QWidget *parent = nullptr);
|
||||
|
||||
NodeView *view() const
|
||||
{
|
||||
return node_view_;
|
||||
}
|
||||
|
||||
void SetContexts(const QVector<Node*> &nodes)
|
||||
{
|
||||
node_view_->SetContexts(nodes);
|
||||
toolbar_->setEnabled(!nodes.isEmpty());
|
||||
}
|
||||
|
||||
private:
|
||||
NodeView *node_view_;
|
||||
|
||||
NodeViewToolBar *toolbar_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEWIDGET_H
|
||||
@@ -220,11 +220,6 @@ void MainWindow::FolderOpen(Project* p, Folder *i, bool floating)
|
||||
{
|
||||
ProjectPanel* panel = PanelManager::instance()->CreatePanel<ProjectPanel>(this);
|
||||
|
||||
// Set custom name to distinguish it from regular ProjectPanels
|
||||
panel->setObjectName(QStringLiteral("FolderPanel"));
|
||||
|
||||
SetUniquePanelID<ProjectPanel>(panel, folder_panels_);
|
||||
|
||||
panel->set_project(p);
|
||||
panel->set_root(i);
|
||||
|
||||
@@ -823,8 +818,6 @@ T *MainWindow::AppendPanelInternal(QList<T*>& list)
|
||||
{
|
||||
T* panel = PanelManager::instance()->CreatePanel<T>(this);
|
||||
|
||||
SetUniquePanelID(panel, list);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
tabifyDockWidget(list.last(), panel);
|
||||
}
|
||||
@@ -841,20 +834,11 @@ T *MainWindow::AppendPanelInternal(QList<T*>& list)
|
||||
return panel;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void MainWindow::SetUniquePanelID(T *panel, const QList<T *> &list)
|
||||
{
|
||||
// Set unique object name so it can be identified by QMainWindow's save and restore state functions
|
||||
panel->setObjectName(panel->objectName().append(QString::number(list.size())));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *MainWindow::AppendFloatingPanelInternal(QList<T *> &list)
|
||||
{
|
||||
T* panel = PanelManager::instance()->CreatePanel<T>(this);
|
||||
|
||||
SetUniquePanelID(panel, list);
|
||||
|
||||
panel->setFloating(true);
|
||||
panel->show();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user