nodecombobox: implemented node combobox widget

This commit is contained in:
itsmattkc
2020-05-09 03:22:09 +10:00
parent 3d0f11c6ef
commit 218c63f933
9 changed files with 320 additions and 18 deletions
+44 -5
View File
@@ -62,7 +62,7 @@ void NodeFactory::Destroy()
library_.clear();
}
Menu *NodeFactory::CreateMenu(QWidget* parent)
Menu *NodeFactory::CreateMenu(QWidget* parent, bool create_none_item)
{
Menu* menu = new Menu(parent);
menu->setToolTipsVisible(true);
@@ -100,18 +100,57 @@ Menu *NodeFactory::CreateMenu(QWidget* parent)
a->setToolTip(n->Description());
}
if (create_none_item) {
QAction* none_item = new QAction(QCoreApplication::translate("NodeFactory", "None"),
menu);
none_item->setData(-1);
if (menu->actions().isEmpty()) {
menu->addAction(none_item);
} else {
QAction* separator = menu->insertSeparator(menu->actions().first());
menu->insertAction(separator, none_item);
}
}
return menu;
}
Node* NodeFactory::CreateFromMenuAction(QAction *action)
{
int library_index = action->data().toInt();
int index = action->data().toInt();
if (library_index >= 0 && library_index < library_.size()) {
return library_.at(library_index)->copy();
if (index == -1) {
return nullptr;
}
return nullptr;
return library_.at(index)->copy();
}
QString NodeFactory::GetIDFromMenuAction(QAction *action)
{
int index = action->data().toInt();
if (index == -1) {
return QString();
}
return library_.at(action->data().toInt())->id();
}
QString NodeFactory::GetNameFromID(const QString &id)
{
if (!id.isEmpty()) {
foreach (Node* n, library_) {
if (n->id() == id) {
return n->Name();
}
}
}
return QString();
}
Node *NodeFactory::CreateFromID(const QString &id)
+5 -1
View File
@@ -60,10 +60,14 @@ public:
static void Destroy();
static Menu* CreateMenu(QWidget *parent);
static Menu* CreateMenu(QWidget *parent, bool create_none_item = false);
static Node* CreateFromMenuAction(QAction* action);
static QString GetIDFromMenuAction(QAction* action);
static QString GetNameFromID(const QString& id);
static Node* CreateFromID(const QString& id);
private:
+68 -9
View File
@@ -371,7 +371,7 @@ void Node::Hash(QCryptographicHash &hash, const rational& time) const
// Footage timestamp
if (stream->type() == Stream::kVideo) {
hash.addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
QString::number(input_time.denominator())).toUtf8());
QString::number(input_time.denominator())).toUtf8());
hash.addData(QString::number(static_cast<VideoStream*>(stream.get())->start_time()).toUtf8());
@@ -532,16 +532,75 @@ NodeOutput *Node::GetOutputWithID(const QString &id) const
return nullptr;
}
bool Node::OutputsTo(Node *n) const
bool Node::OutputsTo(Node *n, bool recursively) const
{
foreach (NodeParam* param, params_) {
if (param->type() == NodeParam::kOutput) {
QVector<NodeEdgePtr> edges = param->edges();
QList<NodeOutput*> outputs = GetOutputs();
foreach (NodeEdgePtr edge, edges) {
if (edge->input()->parent() == n) {
return true;
}
foreach (NodeOutput* output, outputs) {
foreach (NodeEdgePtr edge, output->edges()) {
Node* connected = edge->input()->parentNode();
if (connected == n) {
return true;
} else if (recursively && connected->OutputsTo(n, recursively)) {
return true;
}
}
}
return false;
}
bool Node::OutputsTo(const QString &id, bool recursively) const
{
QList<NodeOutput*> outputs = GetOutputs();
foreach (NodeOutput* output, outputs) {
foreach (NodeEdgePtr edge, output->edges()) {
Node* connected = edge->input()->parentNode();
if (connected->id() == id) {
return true;
} else if (recursively && connected->OutputsTo(id, recursively)) {
return true;
}
}
}
return false;
}
bool Node::InputsFrom(Node *n, bool recursively) const
{
QList<NodeInput*> inputs = GetInputsIncludingArrays();
foreach (NodeInput* input, inputs) {
foreach (NodeEdgePtr edge, input->edges()) {
Node* connected = edge->output()->parentNode();
if (connected == n) {
return true;
} else if (recursively && connected->InputsFrom(n, recursively)) {
return true;
}
}
}
return false;
}
bool Node::InputsFrom(const QString &id, bool recursively) const
{
QList<NodeInput*> inputs = GetInputsIncludingArrays();
foreach (NodeInput* input, inputs) {
foreach (NodeEdgePtr edge, input->edges()) {
Node* connected = edge->output()->parentNode();
if (connected->id() == id) {
return true;
} else if (recursively && connected->InputsFrom(id, recursively)) {
return true;
}
}
}
+26 -2
View File
@@ -229,9 +229,33 @@ public:
NodeOutput* GetOutputWithID(const QString& id) const;
/**
* @brief Returns whether this Node outputs directly to `n`
* @brief Returns whether this Node outputs to `n`
*
* @param n
*
* The node instance to check.
*
* @param recursively
*
* Whether to keep traversing down outputs to find this node (TRUE) or stick to immediate outputs
* (FALSE).
*/
bool OutputsTo(Node* n) const;
bool OutputsTo(Node* n, bool recursively) const;
/**
* @brief Same as OutputsTo(Node*), but for a node ID rather than a specific instance.
*/
bool OutputsTo(const QString& id, bool recursively) const;
/**
* @brief Returns whether this node ever receives an input from a particular node instance
*/
bool InputsFrom(Node* n, bool recursively) const;
/**
* @brief Returns whether this node ever receives an input from a node with a particular ID
*/
bool InputsFrom(const QString& id, bool recursively) const;
/**
* @brief Determines how many paths go from this node out to another node
+1
View File
@@ -27,6 +27,7 @@ add_subdirectory(footagecombobox)
add_subdirectory(keyframeview)
add_subdirectory(manageddisplay)
add_subdirectory(menu)
add_subdirectory(nodecombobox)
add_subdirectory(nodecopypaste)
add_subdirectory(nodeview)
add_subdirectory(nodeparamview)
+22
View File
@@ -0,0 +1,22 @@
# 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/nodecombobox/nodecombobox.h
widget/nodecombobox/nodecombobox.cpp
PARENT_SCOPE
)
+93
View File
@@ -0,0 +1,93 @@
/***
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/>.
***/
#include "nodecombobox.h"
#include <QAction>
#include <QDebug>
#include "node/factory.h"
#include "ui/icons/icons.h"
#include "widget/menu/menu.h"
OLIVE_NAMESPACE_ENTER
NodeComboBox::NodeComboBox(QWidget *parent) :
QComboBox(parent)
{
}
void NodeComboBox::showPopup()
{
Menu* m = NodeFactory::CreateMenu(this, true);
QAction* selected = m->exec(parentWidget()->mapToGlobal(pos()));
if (selected) {
QString new_id = NodeFactory::GetIDFromMenuAction(selected);
SetNodeInternal(new_id, true);
}
delete m;
}
const QString &NodeComboBox::GetSelectedNode() const
{
return selected_id_;
}
void NodeComboBox::SetNode(const QString &id)
{
SetNodeInternal(id, false);
}
void NodeComboBox::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
UpdateText();
}
QComboBox::changeEvent(e);
}
void NodeComboBox::UpdateText()
{
clear();
if (!selected_id_.isEmpty()) {
addItem(NodeFactory::GetNameFromID(selected_id_));
}
}
void NodeComboBox::SetNodeInternal(const QString &id, bool emit_signal)
{
if (selected_id_ != id) {
selected_id_ = id;
UpdateText();
if (emit_signal) {
emit NodeChanged(selected_id_);
}
}
}
OLIVE_NAMESPACE_EXIT
+60
View File
@@ -0,0 +1,60 @@
/***
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/>.
***/
#ifndef NODECOMBOBOX_H
#define NODECOMBOBOX_H
#include <QComboBox>
#include "node/node.h"
OLIVE_NAMESPACE_ENTER
class NodeComboBox : public QComboBox
{
Q_OBJECT
public:
NodeComboBox(QWidget* parent = nullptr);
virtual void showPopup() override;
const QString& GetSelectedNode() const;
public slots:
void SetNode(const QString& id);
protected:
virtual void changeEvent(QEvent *e) override;
signals:
void NodeChanged(const QString& id);
private:
void UpdateText();
void SetNodeInternal(const QString& id, bool emit_signal);
QString selected_id_;
};
OLIVE_NAMESPACE_EXIT
#endif // FOOTAGECOMBOBOX_H
+1 -1
View File
@@ -467,7 +467,7 @@ void NodeViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (cached_drop_item_->GetInputRect(i).contains(cached_drop_item_->mapFromScene(event->scenePos()))) { // See if we're dragging inside the hitbox
// Attempt to prevent circular dependency - ensure the receiving node doesn't output to the outputting node
if (!cached_drop_item_->GetNode()->OutputsTo(node_)) {
if (!cached_drop_item_->GetNode()->OutputsTo(node_, true)) {
drag_dest_param_ = comp_param;
highlight_their_index = i;