R8: finish app/ pure C ABI migration (P3-P9) and make OTIO required
- app/ no longer includes engine C++ headers nor holds engine C++ types: engine access goes through the oakengine C ABI plus C++ wrappers (oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types (tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes, subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp) - engine: new C ABI functions for block/track/clip/transition navigation and predicates, links, caches, waveform/playback, disk folder, sequence_track_list, node_free, footage_is_valid, block_get_track, get_brush; loadotio/saveotio ported to the current engine API - OTIO is now a required dependency: CI and CD build it on every platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps include requirement silently disabled OTIO everywhere), runtime libraries are bundled into packages and copied next to macOS binaries (oak_copy_otio_runtime) - fix ProjectViewModel drag&drop mime read/write size mismatch (segfault) - unify color label naming (k_olive -> "Oak") in the app-side mirror - docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh) - gtest suite: 1925 passed, 0 failed
This commit is contained in:
+276
-300
File diff suppressed because it is too large
Load Diff
@@ -51,9 +51,9 @@ public:
|
||||
|
||||
virtual ~NodeView() override;
|
||||
|
||||
void set_contexts(const QVector<Node *> &nodes);
|
||||
void set_contexts(const QVector<oak::Node> &nodes);
|
||||
|
||||
const QVector<Node *> &get_contexts() const
|
||||
const QVector<oak::Node> &get_contexts() const
|
||||
{
|
||||
if (overlay_view_) {
|
||||
return overlay_view_->get_contexts();
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
return overlay_view_;
|
||||
}
|
||||
|
||||
void close_contexts_belonging_to_project(Project *project);
|
||||
void close_contexts_belonging_to_project(oak::Project project);
|
||||
|
||||
void clear_graph();
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
void zoom_out();
|
||||
|
||||
const QVector<Node *> &get_current_contexts() const
|
||||
const QVector<oak::Node> &get_current_contexts() const
|
||||
{
|
||||
return contexts_;
|
||||
}
|
||||
@@ -163,10 +163,10 @@ private:
|
||||
|
||||
void move_attached_nodes_to_cursor(const QPoint &p);
|
||||
void process_moving_attached_nodes(const QPoint &pos);
|
||||
QVector<Node *> process_dropping_attached_nodes(void *command,
|
||||
Node *select_context,
|
||||
QVector<oak::Node> process_dropping_attached_nodes(void *command,
|
||||
oak::Node select_context,
|
||||
const QPoint &pos);
|
||||
Node *get_context_at_mouse_pos(const QPoint &p);
|
||||
oak::Node get_context_at_mouse_pos(const QPoint &p);
|
||||
|
||||
void connect_selection_changed_signal();
|
||||
void disconnect_selection_changed_signal();
|
||||
@@ -176,18 +176,18 @@ private:
|
||||
void clear_create_edge_input_if_necessary();
|
||||
|
||||
QPointF get_estimated_position_for_context(NodeViewItem *item,
|
||||
Node *context) const;
|
||||
oak::Node context) const;
|
||||
|
||||
NodeViewItem *get_assumed_item_for_selected_node(Node *node);
|
||||
bool get_assumed_position_for_selected_node(Node *node, Node::Position *pos);
|
||||
NodeViewItem *get_assumed_item_for_selected_node(oak::Node node);
|
||||
bool get_assumed_position_for_selected_node(oak::Node node, NodeViewItemPosition *pos);
|
||||
|
||||
Menu *create_add_menu(Menu *parent);
|
||||
|
||||
void position_new_edge(const QPoint &pos);
|
||||
|
||||
void add_context(Node *n);
|
||||
void add_context(oak::Node n);
|
||||
|
||||
void remove_context(Node *n);
|
||||
void remove_context(oak::Node n);
|
||||
|
||||
bool is_item_attached_to_cursor(NodeViewItem *item) const;
|
||||
|
||||
@@ -197,8 +197,8 @@ private:
|
||||
|
||||
void end_edge_drag(bool cancel = false);
|
||||
|
||||
void post_paste(const QVector<Node *> &new_nodes,
|
||||
const Node::PositionMap &map);
|
||||
void post_paste(const QVector<oak::Node> &new_nodes,
|
||||
const QHash<oak::Node, NodeViewItemPosition> &map);
|
||||
|
||||
void resize_overlay();
|
||||
|
||||
@@ -208,7 +208,7 @@ private:
|
||||
|
||||
struct AttachedItem {
|
||||
NodeViewItem *item;
|
||||
Node *node;
|
||||
oak::Node node;
|
||||
QPointF original_pos;
|
||||
};
|
||||
|
||||
@@ -216,12 +216,12 @@ private:
|
||||
QVector<AttachedItem> attached_items_;
|
||||
|
||||
NodeViewEdge *drop_edge_;
|
||||
NodeInput drop_input_;
|
||||
oak::Input drop_input_;
|
||||
|
||||
NodeViewEdge *create_edge_;
|
||||
NodeViewItem *create_edge_output_item_;
|
||||
NodeViewItem *create_edge_input_item_;
|
||||
NodeInput create_edge_input_;
|
||||
oak::Input create_edge_input_;
|
||||
bool create_edge_already_exists_;
|
||||
bool create_edge_from_output_;
|
||||
|
||||
@@ -229,11 +229,11 @@ private:
|
||||
|
||||
NodeViewScene scene_;
|
||||
|
||||
QVector<Node *> selected_nodes_;
|
||||
QVector<oak::Node> selected_nodes_;
|
||||
|
||||
QVector<Node *> contexts_;
|
||||
QVector<Node *> last_set_filter_nodes_;
|
||||
QMap<Node *, QPointF> context_offsets_;
|
||||
QVector<oak::Node> contexts_;
|
||||
QVector<oak::Node> last_set_filter_nodes_;
|
||||
QHash<oak::Node, QPointF> context_offsets_;
|
||||
|
||||
QMap<NodeViewItem *, QPointF> dragging_items_;
|
||||
|
||||
@@ -245,7 +245,7 @@ private:
|
||||
|
||||
EngineEventBridge *bridge_ = nullptr;
|
||||
|
||||
QHash<Node *, int64_t> removed_from_graph_subs_;
|
||||
QHash<oak::Node, int64_t> removed_from_graph_subs_;
|
||||
|
||||
QAction *show_in_param_editor_action_;
|
||||
|
||||
|
||||
@@ -24,16 +24,17 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
#include "core.h"
|
||||
#include "node/block/block.h"
|
||||
#include "node/output/track/track.h"
|
||||
#include "node/project.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "common/trackreferencehandle.h"
|
||||
#include "nodeviewitem.h"
|
||||
#include "ui/colorcoding.h"
|
||||
#include "common/colorcodingapp.h"
|
||||
#include "oakengine/timeline.h"
|
||||
#include "oakutil/qtutils.h"
|
||||
#include "widget/timelinewidget/cliphandle.h"
|
||||
|
||||
#include "widget/viewer/vieweroutpututils.h"
|
||||
namespace olive
|
||||
@@ -41,95 +42,109 @@ namespace olive
|
||||
|
||||
#define super QGraphicsRectItem
|
||||
|
||||
NodeViewContext::NodeViewContext(Node *context, QGraphicsItem *item)
|
||||
NodeViewContext::NodeViewContext(oak::Node context, QGraphicsItem *item)
|
||||
: super(item)
|
||||
, context_(context)
|
||||
, bridge_(new EngineEventBridge(this))
|
||||
{
|
||||
Block *block = dynamic_cast<Block *>(context_);
|
||||
if (block && block->track() && block->track()->sequence()) {
|
||||
Rational timebase = viewer_output_video_params(block->track()->sequence())
|
||||
// Block contexts (clips/transitions nested in the node graph) show their
|
||||
// track placement in the title. All engine queries go through the C ABI:
|
||||
// oakengine_node_is_block() replaces dynamic_cast<Block*> (Block is
|
||||
// abstract and carries no own type id), and the track type ordinals are
|
||||
// the TrackReference mirror values (== engine Track::Type, pinned by the
|
||||
// static_asserts in trackreferencehandle.h).
|
||||
OakEngineNode *track_node =
|
||||
oakengine_node_is_block(context_.handle()) ?
|
||||
block_track_handle(
|
||||
reinterpret_cast<OakEngineBlock *>(context_.handle())) :
|
||||
nullptr;
|
||||
OakEngineNode *track_seq =
|
||||
track_node ? oakengine_track_get_sequence(track_node) : nullptr;
|
||||
if (track_seq) {
|
||||
Rational timebase = viewer_output_video_params(track_seq)
|
||||
.frame_rate_as_time_base();
|
||||
QString type_label;
|
||||
switch (block->track()->type()) {
|
||||
case Track::k_video:
|
||||
switch (oakengine_track_get_type(track_node)) {
|
||||
case TrackReference::k_video:
|
||||
type_label = QCoreApplication::translate("NodeViewContext", "V");
|
||||
break;
|
||||
case Track::k_audio:
|
||||
case TrackReference::k_audio:
|
||||
type_label = QCoreApplication::translate("NodeViewContext", "A");
|
||||
break;
|
||||
case Track::k_subtitle:
|
||||
case TrackReference::k_subtitle:
|
||||
type_label = QCoreApplication::translate("NodeViewContext", "S");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int in_num = 0, in_den = 1, out_num = 0, out_den = 1;
|
||||
oakengine_block_get_in_rational(context_.handle(), &in_num, &in_den);
|
||||
oakengine_block_get_out_rational(context_.handle(), &out_num, &out_den);
|
||||
|
||||
lbl_ =
|
||||
QCoreApplication::translate("NodeViewContext", "%1 [%2] :: %3 - %4")
|
||||
.arg(block->get_label_and_name(),
|
||||
.arg(context_.label_and_name(),
|
||||
type_label,
|
||||
QString::fromStdString(Timecode::time_to_timecode(
|
||||
block->in(), timebase,
|
||||
Rational(in_num, in_den), timebase,
|
||||
Core::instance()->get_timecode_display())),
|
||||
QString::fromStdString(Timecode::time_to_timecode(
|
||||
block->out(), timebase,
|
||||
Rational(out_num, out_den), timebase,
|
||||
Core::instance()->get_timecode_display())));
|
||||
} else {
|
||||
lbl_ = context_->get_label_and_name();
|
||||
lbl_ = context_.label_and_name();
|
||||
}
|
||||
|
||||
connect(bridge_, &EngineEventBridge::node_node_added_to_context, this,
|
||||
[this](OakEngineNode *source, OakEngineNode *node) {
|
||||
Node *src = reinterpret_cast<Node *>(source);
|
||||
if (src == context_) {
|
||||
add_child(reinterpret_cast<Node *>(node));
|
||||
if (source == context_.handle()) {
|
||||
add_child(node);
|
||||
} else {
|
||||
group_added_node(reinterpret_cast<Node *>(node), src);
|
||||
group_added_node(node, source);
|
||||
}
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::node_node_removed_from_context, this,
|
||||
[this](OakEngineNode *source, OakEngineNode *node) {
|
||||
Node *src = reinterpret_cast<Node *>(source);
|
||||
if (src == context_) {
|
||||
remove_child(reinterpret_cast<Node *>(node));
|
||||
if (source == context_.handle()) {
|
||||
remove_child(node);
|
||||
} else {
|
||||
group_removed_node(reinterpret_cast<Node *>(node), src);
|
||||
group_removed_node(node, source);
|
||||
}
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::node_context_position_changed, this,
|
||||
[this](OakEngineNode *, OakEngineNode *node, double x, double y) {
|
||||
set_child_position(reinterpret_cast<Node *>(node),
|
||||
QPointF(x, y));
|
||||
set_child_position(node, QPointF(x, y));
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::node_input_connected, this,
|
||||
[this](OakEngineNode *source, OakEngineNode *output,
|
||||
const QString &input, int element) {
|
||||
child_input_connected(reinterpret_cast<Node *>(output),
|
||||
NodeInput(reinterpret_cast<Node *>(source), input,
|
||||
element));
|
||||
child_input_connected(output,
|
||||
oak::Input(source, input, element));
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::node_input_disconnected, this,
|
||||
[this](OakEngineNode *source, OakEngineNode *output,
|
||||
const QString &input, int element) {
|
||||
child_input_disconnected(reinterpret_cast<Node *>(output),
|
||||
NodeInput(reinterpret_cast<Node *>(source), input,
|
||||
element));
|
||||
child_input_disconnected(output,
|
||||
oak::Input(source, input, element));
|
||||
});
|
||||
|
||||
node_subs_[context_].append(bridge_->subscribe(
|
||||
reinterpret_cast<void *>(context_),
|
||||
node_subs_[context_.handle()].append(bridge_->subscribe(
|
||||
context_.handle(),
|
||||
OAKENGINE_EVENT_NODE_NODE_ADDED_TO_CONTEXT));
|
||||
node_subs_[context_].append(bridge_->subscribe(
|
||||
reinterpret_cast<void *>(context_),
|
||||
node_subs_[context_.handle()].append(bridge_->subscribe(
|
||||
context_.handle(),
|
||||
OAKENGINE_EVENT_NODE_CONTEXT_POSITION_CHANGED));
|
||||
node_subs_[context_].append(bridge_->subscribe(
|
||||
reinterpret_cast<void *>(context_),
|
||||
node_subs_[context_.handle()].append(bridge_->subscribe(
|
||||
context_.handle(),
|
||||
OAKENGINE_EVENT_NODE_NODE_REMOVED_FROM_CONTEXT));
|
||||
|
||||
const Node::PositionMap &map = context_->get_context_positions();
|
||||
for (auto it = map.cbegin(); it != map.cend(); it++) {
|
||||
add_child(it.key());
|
||||
const int ctx_count = context_.context_node_count();
|
||||
for (int i = 0; i < ctx_count; i++) {
|
||||
oak::Node child = context_.context_node_at(i).node;
|
||||
if (!child.is_null()) {
|
||||
add_child(child.handle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,22 +155,26 @@ NodeViewContext::~NodeViewContext()
|
||||
edges_.clear();
|
||||
}
|
||||
|
||||
void NodeViewContext::add_child(Node *node)
|
||||
void NodeViewContext::add_child(OakEngineNode *node)
|
||||
{
|
||||
if (!context_) {
|
||||
if (context_.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NodeViewItem *item = new NodeViewItem(node, context_, this);
|
||||
NodeViewItem *item = new NodeViewItem(oak::Node(node), context_, this);
|
||||
item->set_flow_direction(flow_dir_);
|
||||
|
||||
add_node_internal(node, item);
|
||||
|
||||
if (oakengine_node_is_group(reinterpret_cast<OakEngineNode *>(node))) {
|
||||
for (auto it = node->get_context_positions().cbegin();
|
||||
it != node->get_context_positions().cend(); it++) {
|
||||
// Use this item as the representative for all of these nodes too
|
||||
add_node_internal(it.key(), item);
|
||||
oak::Node group_node(node);
|
||||
if (group_node.is_group()) {
|
||||
const int grp_count = group_node.context_node_count();
|
||||
for (int i = 0; i < grp_count; i++) {
|
||||
oak::Node grp_child = group_node.context_node_at(i).node;
|
||||
if (!grp_child.is_null()) {
|
||||
// Use this item as the representative for all of these nodes too
|
||||
add_node_internal(grp_child.handle(), item);
|
||||
}
|
||||
}
|
||||
|
||||
node_subs_[node].append(bridge_->subscribe(
|
||||
@@ -169,12 +188,12 @@ void NodeViewContext::add_child(Node *node)
|
||||
update_rect();
|
||||
}
|
||||
|
||||
void NodeViewContext::set_child_position(Node *node, const QPointF &pos)
|
||||
void NodeViewContext::set_child_position(OakEngineNode *node, const QPointF &pos)
|
||||
{
|
||||
item_map_.value(node)->set_node_position(pos);
|
||||
}
|
||||
|
||||
void NodeViewContext::remove_child(Node *node)
|
||||
void NodeViewContext::remove_child(OakEngineNode *node)
|
||||
{
|
||||
foreach (int64_t id, node_subs_.take(node)) {
|
||||
bridge_->unsubscribe(id);
|
||||
@@ -192,17 +211,16 @@ void NodeViewContext::remove_child(Node *node)
|
||||
// be changed...)
|
||||
QVector<NodeViewEdge *> edges_to_remove = item->get_all_edges_recursively();
|
||||
foreach (NodeViewEdge *edge, edges_to_remove) {
|
||||
if (node == item->get_node() || edge->output() == node ||
|
||||
edge->input().node() == node) {
|
||||
child_input_disconnected(edge->output(), edge->input());
|
||||
if (item->get_node() == oak::Node(node) || edge->output() == oak::Node(node) ||
|
||||
edge->input().node_handle() == node) {
|
||||
child_input_disconnected(edge->output().handle(), edge->input());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this item is specifically for this node and the node is a group. If so, remove it for
|
||||
// all other entries in the map.
|
||||
if (item->get_node() == node) {
|
||||
if (oakengine_node_is_group(reinterpret_cast<OakEngineNode *>(
|
||||
item->get_node()))) {
|
||||
if (item->get_node() == oak::Node(node)) {
|
||||
if (item->get_node().is_group()) {
|
||||
for (auto it = item_map_.begin(); it != item_map_.end();) {
|
||||
if (it.value() == item) {
|
||||
it = item_map_.erase(it);
|
||||
@@ -218,25 +236,25 @@ void NodeViewContext::remove_child(Node *node)
|
||||
update_rect();
|
||||
}
|
||||
|
||||
void NodeViewContext::child_input_connected(Node *output, const NodeInput &input)
|
||||
void NodeViewContext::child_input_connected(OakEngineNode *output, const oak::Input &input)
|
||||
{
|
||||
// Add edge
|
||||
if (!input.is_hidden()) {
|
||||
if (NodeViewItem *output_item = item_map_.value(output)) {
|
||||
add_edge_internal(
|
||||
output, input, output_item,
|
||||
item_map_.value(input.node())->get_item_for_input(input));
|
||||
item_map_.value(input.node_handle())->get_item_for_input(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NodeViewContext::child_input_disconnected(Node *output,
|
||||
const NodeInput &input)
|
||||
bool NodeViewContext::child_input_disconnected(OakEngineNode *output,
|
||||
const oak::Input &input)
|
||||
{
|
||||
// Remove edge
|
||||
for (int i = 0; i < edges_.size(); i++) {
|
||||
NodeViewEdge *e = edges_.at(i);
|
||||
if (e->output() == output && e->input() == input) {
|
||||
if (e->output() == oak::Node(output) && e->input() == input) {
|
||||
delete e;
|
||||
edges_.removeAt(i);
|
||||
return true;
|
||||
@@ -284,8 +302,8 @@ void NodeViewContext::set_curved_edges(bool e)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewContext::get_selected_for_deletion(QVector<Node *> &nodes,
|
||||
QVector<Node *> &contexts,
|
||||
void NodeViewContext::get_selected_for_deletion(QVector<OakEngineNode *> &nodes,
|
||||
QVector<OakEngineNode *> &contexts,
|
||||
QVector<NodeViewEdge *> &edges) const
|
||||
{
|
||||
// Collect any selected edges
|
||||
@@ -298,15 +316,15 @@ void NodeViewContext::get_selected_for_deletion(QVector<Node *> &nodes,
|
||||
// Collect any selected nodes
|
||||
foreach (NodeViewItem *node, item_map_) {
|
||||
if (node->isSelected()) {
|
||||
nodes.append(node->get_node());
|
||||
contexts.append(context_);
|
||||
nodes.append(node->get_node().handle());
|
||||
contexts.append(context_.handle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewContext::select(const QVector<Node *> &nodes)
|
||||
void NodeViewContext::select(const QVector<OakEngineNode *> &nodes)
|
||||
{
|
||||
foreach (Node *n, nodes) {
|
||||
foreach (OakEngineNode *n, nodes) {
|
||||
if (NodeViewItem *item = item_map_.value(n)) {
|
||||
item->setSelected(true);
|
||||
}
|
||||
@@ -343,7 +361,7 @@ void NodeViewContext::paint(QPainter *painter,
|
||||
QWidget *widget)
|
||||
{
|
||||
// Set pen and brush
|
||||
Color color = context_->color();
|
||||
Color color = AppColorCoding::get_color(context_.effective_color_label());
|
||||
QColor c = QtUtils::to_q_color(color);
|
||||
QPen pen(c, 2);
|
||||
if (option->state & QStyle::State_Selected) {
|
||||
@@ -368,7 +386,7 @@ void NodeViewContext::paint(QPainter *painter,
|
||||
painter->setClipping(false);
|
||||
|
||||
// Draw titlebar text
|
||||
painter->setPen(ColorCoding::get_ui_selector_color(color));
|
||||
painter->setPen(AppColorCoding::get_ui_selector_color(color));
|
||||
|
||||
int offset = get_text_offset(painter->fontMetrics());
|
||||
|
||||
@@ -393,7 +411,7 @@ void NodeViewContext::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
super::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void NodeViewContext::add_node_internal(Node *node, NodeViewItem *item)
|
||||
void NodeViewContext::add_node_internal(OakEngineNode *node, NodeViewItem *item)
|
||||
{
|
||||
node_subs_[node].append(bridge_->subscribe(
|
||||
reinterpret_cast<void *>(node),
|
||||
@@ -404,39 +422,46 @@ void NodeViewContext::add_node_internal(Node *node, NodeViewItem *item)
|
||||
|
||||
item_map_.insert(node, item);
|
||||
|
||||
if (node == context_) {
|
||||
if (node == context_.handle()) {
|
||||
item->set_label_as_output(true);
|
||||
}
|
||||
|
||||
for (auto it = node->output_connections().cbegin();
|
||||
it != node->output_connections().cend(); it++) {
|
||||
if (!it->second.is_hidden()) {
|
||||
if (NodeViewItem *other_item = item_map_.value(it->second.node())) {
|
||||
add_edge_internal(node, it->second, item,
|
||||
other_item->get_item_for_input(it->second));
|
||||
// Iterate output connections via the wrapper
|
||||
oak::Node wrapped(node);
|
||||
const int out_count = wrapped.output_connection_count();
|
||||
for (int i = 0; i < out_count; i++) {
|
||||
oak::NodeConnection conn = wrapped.output_connection_at_ex(i);
|
||||
if (!conn.hidden) {
|
||||
if (NodeViewItem *other_item = item_map_.value(conn.node.handle())) {
|
||||
oak::Input ai(conn.node.handle(), conn.input_id, conn.element);
|
||||
add_edge_internal(node, ai, item,
|
||||
other_item->get_item_for_input(ai));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = node->input_connections().cbegin();
|
||||
it != node->input_connections().cend(); it++) {
|
||||
if (!it->first.is_hidden()) {
|
||||
if (NodeViewItem *other_item = item_map_.value(it->second)) {
|
||||
add_edge_internal(it->second, it->first, other_item,
|
||||
item->get_item_for_input(it->first));
|
||||
// Iterate input connections via the wrapper
|
||||
const int in_count = wrapped.input_connection_count_all();
|
||||
for (int i = 0; i < in_count; i++) {
|
||||
oak::NodeConnection conn = wrapped.input_connection_at_all(i);
|
||||
if (!conn.hidden) {
|
||||
if (NodeViewItem *other_item = item_map_.value(conn.source_node.handle())) {
|
||||
oak::Input ai(conn.node.handle(), conn.input_id, conn.element);
|
||||
add_edge_internal(conn.source_node.handle(), ai, other_item,
|
||||
item->get_item_for_input(ai));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewContext::add_edge_internal(Node *output, const NodeInput &input,
|
||||
void NodeViewContext::add_edge_internal(OakEngineNode *output, const oak::Input &input,
|
||||
NodeViewItem *from, NodeViewItem *to)
|
||||
{
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
|
||||
NodeViewEdge *edge_ui = new NodeViewEdge(output, input, from, to, this);
|
||||
NodeViewEdge *edge_ui = new NodeViewEdge(oak::Node(output), input, from, to, this);
|
||||
|
||||
edge_ui->adjust();
|
||||
edge_ui->set_curved(curved_edges_);
|
||||
@@ -444,12 +469,12 @@ void NodeViewContext::add_edge_internal(Node *output, const NodeInput &input,
|
||||
edges_.append(edge_ui);
|
||||
}
|
||||
|
||||
void NodeViewContext::group_added_node(Node *node, Node *group)
|
||||
void NodeViewContext::group_added_node(OakEngineNode *node, OakEngineNode *group)
|
||||
{
|
||||
add_node_internal(node, item_map_.value(group));
|
||||
}
|
||||
|
||||
void NodeViewContext::group_removed_node(Node *node, Node *group)
|
||||
void NodeViewContext::group_removed_node(OakEngineNode *node, OakEngineNode *group)
|
||||
{
|
||||
if (item_map_.value(node) == item_map_.value(group)) {
|
||||
item_map_.remove(node);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <QHash>
|
||||
|
||||
#include "engineeventbridge.h"
|
||||
#include "node/node.h"
|
||||
#include "oakutil/oaknode.h"
|
||||
#include "nodeviewcommon.h"
|
||||
#include "nodeviewedge.h"
|
||||
|
||||
@@ -34,11 +34,11 @@ namespace olive
|
||||
class NodeViewContext : public QObject, public QGraphicsRectItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeViewContext(Node *context, QGraphicsItem *item = nullptr);
|
||||
NodeViewContext(oak::Node context, QGraphicsItem *item = nullptr);
|
||||
|
||||
virtual ~NodeViewContext() override;
|
||||
|
||||
Node *get_context() const
|
||||
oak::Node get_context() const
|
||||
{
|
||||
return context_;
|
||||
}
|
||||
@@ -49,17 +49,17 @@ public:
|
||||
|
||||
void set_curved_edges(bool e);
|
||||
|
||||
void get_selected_for_deletion(QVector<Node *> &nodes,
|
||||
QVector<Node *> &contexts,
|
||||
void get_selected_for_deletion(QVector<OakEngineNode *> &nodes,
|
||||
QVector<OakEngineNode *> &contexts,
|
||||
QVector<NodeViewEdge *> &edges) const;
|
||||
|
||||
void select(const QVector<Node *> &nodes);
|
||||
void select(const QVector<OakEngineNode *> &nodes);
|
||||
|
||||
QVector<NodeViewItem *> get_selected_items() const;
|
||||
|
||||
QPointF map_scene_pos_to_node_pos_in_context(const QPointF &pos) const;
|
||||
|
||||
NodeViewItem *get_item_from_map(Node *node) const
|
||||
NodeViewItem *get_item_from_map(OakEngineNode *node) const
|
||||
{
|
||||
return item_map_.value(node);
|
||||
}
|
||||
@@ -69,19 +69,17 @@ public:
|
||||
QWidget *widget = nullptr) override;
|
||||
|
||||
public:
|
||||
// Not slots: signatures use the engine C++ type Node*, which must not be
|
||||
// exposed to MOC (it would pull Node::staticMetaObject across the ABI
|
||||
// boundary). They are invoked from lambdas / directly, never as connect()
|
||||
// targets.
|
||||
void add_child(Node *node);
|
||||
// Not slots: they are invoked from EngineEventBridge lambdas / directly,
|
||||
// never as connect() targets.
|
||||
void add_child(OakEngineNode *node);
|
||||
|
||||
void set_child_position(Node *node, const QPointF &pos);
|
||||
void set_child_position(OakEngineNode *node, const QPointF &pos);
|
||||
|
||||
void remove_child(Node *node);
|
||||
void remove_child(OakEngineNode *node);
|
||||
|
||||
void child_input_connected(Node *output, const NodeInput &input);
|
||||
void child_input_connected(OakEngineNode *output, const oak::Input &input);
|
||||
|
||||
bool child_input_disconnected(Node *output, const NodeInput &input);
|
||||
bool child_input_disconnected(OakEngineNode *output, const oak::Input &input);
|
||||
|
||||
signals:
|
||||
void item_about_to_be_deleted(NodeViewItem *item);
|
||||
@@ -93,12 +91,12 @@ protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void add_node_internal(Node *node, NodeViewItem *item);
|
||||
void add_node_internal(OakEngineNode *node, NodeViewItem *item);
|
||||
|
||||
void add_edge_internal(Node *output, const NodeInput &input,
|
||||
void add_edge_internal(OakEngineNode *output, const oak::Input &input,
|
||||
NodeViewItem *from, NodeViewItem *to);
|
||||
|
||||
Node *context_;
|
||||
oak::Node context_;
|
||||
|
||||
QString lbl_;
|
||||
|
||||
@@ -108,20 +106,19 @@ private:
|
||||
|
||||
int last_titlebar_height_;
|
||||
|
||||
QMap<Node *, NodeViewItem *> item_map_;
|
||||
QMap<OakEngineNode *, NodeViewItem *> item_map_;
|
||||
|
||||
QVector<NodeViewEdge *> edges_;
|
||||
|
||||
EngineEventBridge *bridge_ = nullptr;
|
||||
|
||||
QHash<Node *, QVector<int64_t>> node_subs_;
|
||||
QHash<OakEngineNode *, QVector<int64_t>> node_subs_;
|
||||
|
||||
private:
|
||||
// Ordinary member functions (NOT slots): signatures use Node*, which must
|
||||
// not be exposed to MOC. Invoked from lambdas only.
|
||||
void group_added_node(Node *node, Node *group);
|
||||
// Ordinary member functions (NOT slots): invoked from lambdas only.
|
||||
void group_added_node(OakEngineNode *node, OakEngineNode *group);
|
||||
|
||||
void group_removed_node(Node *node, Node *group);
|
||||
void group_removed_node(OakEngineNode *node, OakEngineNode *group);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace olive
|
||||
|
||||
#define super QGraphicsPathItem
|
||||
|
||||
NodeViewEdge::NodeViewEdge(Node *output, const NodeInput &input,
|
||||
NodeViewEdge::NodeViewEdge(oak::Node output, const oak::Input &input,
|
||||
NodeViewItem *from_item, NodeViewItem *to_item,
|
||||
QGraphicsItem *parent)
|
||||
: super(parent)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <QPalette>
|
||||
|
||||
#include "nodeviewcommon.h"
|
||||
#include "node/node.h"
|
||||
#include "oakutil/oaknode.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -40,19 +40,20 @@ class NodeViewItem;
|
||||
*/
|
||||
class NodeViewEdge : public QGraphicsPathItem {
|
||||
public:
|
||||
NodeViewEdge(Node *output, const NodeInput &input, NodeViewItem *from_item,
|
||||
NodeViewEdge(oak::Node output, const oak::Input &input,
|
||||
NodeViewItem *from_item,
|
||||
NodeViewItem *to_item, QGraphicsItem *parent = nullptr);
|
||||
|
||||
NodeViewEdge(QGraphicsItem *parent = nullptr);
|
||||
|
||||
virtual ~NodeViewEdge() override;
|
||||
|
||||
Node *output() const
|
||||
oak::Node output() const
|
||||
{
|
||||
return output_;
|
||||
}
|
||||
|
||||
const NodeInput &input() const
|
||||
const oak::Input &input() const
|
||||
{
|
||||
return input_;
|
||||
}
|
||||
@@ -122,9 +123,9 @@ private:
|
||||
|
||||
void update_curve();
|
||||
|
||||
Node *output_;
|
||||
oak::Node output_;
|
||||
|
||||
NodeInput input_;
|
||||
oak::Input input_;
|
||||
|
||||
int element_;
|
||||
|
||||
|
||||
@@ -32,19 +32,30 @@
|
||||
#include "oakutil/qtutils.h"
|
||||
#include "common/configwrapper.h"
|
||||
#include "core.h"
|
||||
#include "node/value.h"
|
||||
#include "pluginSupport/oliveplugininstance.h"
|
||||
#include "common/nodevaluehandle.h"
|
||||
#include "nodeview.h"
|
||||
#include "nodeviewscene.h"
|
||||
#include "ui/colorcoding.h"
|
||||
#include "common/colorcodingapp.h"
|
||||
#include "ui/icons/icons.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
NodeViewItem::NodeViewItem(Node *node, const QString &input, int element,
|
||||
Node *context, QGraphicsItem *parent)
|
||||
static QVector<QString> node_input_list(oak::Node n)
|
||||
{
|
||||
const int count = n.input_count();
|
||||
QVector<QString> result;
|
||||
result.reserve(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
result.append(n.input_id(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeViewItem::NodeViewItem(oak::Node node, const QString &input,
|
||||
int element, oak::Node context,
|
||||
QGraphicsItem *parent)
|
||||
: QGraphicsRectItem(parent)
|
||||
, node_(node)
|
||||
, input_(input)
|
||||
@@ -71,9 +82,9 @@ NodeViewItem::NodeViewItem(Node *node, const QString &input, int element,
|
||||
output_connector_ = new NodeViewItemConnector(true, this);
|
||||
|
||||
bridge_ = new EngineEventBridge(this);
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_LABEL_CHANGED);
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_COLOR_CHANGED);
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_MESSAGE_COUNT_CHANGED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_LABEL_CHANGED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_COLOR_CHANGED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_MESSAGE_COUNT_CHANGED);
|
||||
connect(bridge_, &EngineEventBridge::node_label_changed, this,
|
||||
&NodeViewItem::node_appearance_changed);
|
||||
connect(bridge_, &EngineEventBridge::node_color_changed, this,
|
||||
@@ -82,8 +93,8 @@ NodeViewItem::NodeViewItem(Node *node, const QString &input, int element,
|
||||
&NodeViewItem::node_appearance_changed);
|
||||
|
||||
if (is_output_item()) {
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_INPUT_ADDED);
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_INPUT_REMOVED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_INPUT_ADDED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_INPUT_REMOVED);
|
||||
connect(bridge_, &EngineEventBridge::node_input_added, this,
|
||||
&NodeViewItem::repopulate_inputs);
|
||||
connect(bridge_, &EngineEventBridge::node_input_removed, this,
|
||||
@@ -95,13 +106,17 @@ NodeViewItem::NodeViewItem(Node *node, const QString &input, int element,
|
||||
setFlag(QGraphicsItem::ItemIsMovable);
|
||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
|
||||
if (context_) {
|
||||
set_node_position(context_->get_node_position_data_in_context(node_));
|
||||
if (!context_.is_null()) {
|
||||
QPointF ctx_pos;
|
||||
bool ctx_expanded = false;
|
||||
context_.context_position_of(node_, &ctx_pos, &ctx_expanded);
|
||||
set_node_position(ctx_pos);
|
||||
set_expanded(ctx_expanded);
|
||||
}
|
||||
} else {
|
||||
output_connector_->setVisible(false);
|
||||
|
||||
bridge_->subscribe(reinterpret_cast<void *>(node_), OAKENGINE_EVENT_NODE_INPUT_ARRAY_SIZE_CHANGED);
|
||||
bridge_->subscribe(node_.handle(), OAKENGINE_EVENT_NODE_INPUT_ARRAY_SIZE_CHANGED);
|
||||
connect(bridge_, &EngineEventBridge::node_input_array_size_changed, this,
|
||||
[this](OakEngineNode *, const QString &input, int, int) {
|
||||
input_array_size_changed(input);
|
||||
@@ -117,9 +132,9 @@ NodeViewItem::~NodeViewItem()
|
||||
Q_ASSERT(edges_.isEmpty());
|
||||
}
|
||||
|
||||
Node::Position NodeViewItem::get_node_position_data() const
|
||||
NodeViewItemPosition NodeViewItem::get_node_position_data() const
|
||||
{
|
||||
return Node::Position(get_node_position(), is_expanded());
|
||||
return NodeViewItemPosition{get_node_position(), is_expanded()};
|
||||
}
|
||||
|
||||
QPointF NodeViewItem::get_node_position() const
|
||||
@@ -134,7 +149,7 @@ void NodeViewItem::set_node_position(const QPointF &pos)
|
||||
update_node_position();
|
||||
}
|
||||
|
||||
void NodeViewItem::set_node_position(const Node::Position &pos)
|
||||
void NodeViewItem::set_node_position(const NodeViewItemPosition &pos)
|
||||
{
|
||||
set_node_position(pos.position);
|
||||
set_expanded(pos.expanded);
|
||||
@@ -280,8 +295,8 @@ void NodeViewItem::set_expanded(bool e, bool hide_titlebar)
|
||||
|
||||
expanded_ = e;
|
||||
|
||||
if (context_) {
|
||||
context_->set_node_expanded_in_context(node_, e);
|
||||
if (!context_.is_null()) {
|
||||
context_.set_context_expanded_of(node_, e);
|
||||
}
|
||||
|
||||
if (is_output_item()) {
|
||||
@@ -290,11 +305,11 @@ void NodeViewItem::set_expanded(bool e, bool hide_titlebar)
|
||||
}
|
||||
|
||||
if (expanded_) {
|
||||
node_->retranslate();
|
||||
node_.retranslate();
|
||||
|
||||
if (is_output_item()) {
|
||||
// Create items for each input of the node
|
||||
foreach (const QString &input, node_->inputs()) {
|
||||
foreach (const QString &input, node_input_list(node_)) {
|
||||
if (is_input_valid(input)) {
|
||||
NodeViewItem *item =
|
||||
new NodeViewItem(node_, input, -1, context_, this);
|
||||
@@ -310,7 +325,7 @@ void NodeViewItem::set_expanded(bool e, bool hide_titlebar)
|
||||
}
|
||||
} else {
|
||||
// Create items for each element of the input array
|
||||
int arr_sz = node_->input_array_size(input_);
|
||||
int arr_sz = oak::Input(node_, input_).array_size();
|
||||
children_.resize(arr_sz);
|
||||
for (int i = 0; i < arr_sz; i++) {
|
||||
NodeViewItem *item =
|
||||
@@ -368,8 +383,7 @@ void NodeViewItem::paint(QPainter *painter,
|
||||
if (is_output_item()) {
|
||||
// Set output item colors
|
||||
painter->setPen(Qt::black);
|
||||
painter->setBrush(
|
||||
node_->brush(single_unit_rect.top(), single_unit_rect.bottom()));
|
||||
painter->setBrush(node_.brush(single_unit_rect.top(), single_unit_rect.bottom()));
|
||||
} else {
|
||||
// Set input item colors
|
||||
painter->setPen(Qt::NoPen);
|
||||
@@ -394,17 +408,16 @@ void NodeViewItem::paint(QPainter *painter,
|
||||
if (label_as_output_) {
|
||||
node_name = QCoreApplication::translate("NodeViewItem", "Output");
|
||||
} else {
|
||||
node_label = node_->get_label();
|
||||
node_name = node_->short_name();
|
||||
node_label = node_.get_label();
|
||||
node_name = node_.short_name();
|
||||
}
|
||||
} else {
|
||||
if (element_ == -1) {
|
||||
node_name = node_->get_input_name(input_);
|
||||
node_name = oak::Input(node_, input_).name();
|
||||
} else {
|
||||
node_name = QString::number(
|
||||
element_ +
|
||||
node_->get_input_property(input_, QStringLiteral("arraystart"))
|
||||
.toInt());
|
||||
int64_t arraystart = 0;
|
||||
oak::Input(node_, input_).property_int("arraystart", &arraystart);
|
||||
node_name = QString::number(element_ + static_cast<int>(arraystart));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +426,8 @@ void NodeViewItem::paint(QPainter *painter,
|
||||
|
||||
if (is_output_item()) {
|
||||
// Determine the text color (automatically calculate from node background color)
|
||||
painter->setPen(ColorCoding::get_ui_selector_color(node_->color()));
|
||||
painter->setPen(AppColorCoding::get_ui_selector_color(
|
||||
AppColorCoding::get_color(node_.effective_color_label())));
|
||||
} else {
|
||||
// Just use text item
|
||||
painter->setPen(app_pal.text().color());
|
||||
@@ -444,11 +458,7 @@ void NodeViewItem::paint(QPainter *painter,
|
||||
}
|
||||
|
||||
if (is_output_item()) {
|
||||
auto *instance = node_->getPluginInstance();
|
||||
auto *olive_instance =
|
||||
dynamic_cast<plugin::OlivePluginInstance *>(instance);
|
||||
int message_count =
|
||||
olive_instance ? olive_instance->persistent_message_count() : 0;
|
||||
int message_count = node_.plugin_message_count();
|
||||
|
||||
if (message_count > 0) {
|
||||
QString badge_text = QString::number(message_count);
|
||||
@@ -537,15 +547,17 @@ void NodeViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
QVariant NodeViewItem::itemChange(QGraphicsItem::GraphicsItemChange change,
|
||||
const QVariant &value)
|
||||
{
|
||||
if (node_) {
|
||||
if (change == ItemPositionHasChanged) {
|
||||
readjust_all_edges();
|
||||
if (node_.is_null()) {
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
update_context_rect();
|
||||
} else if (change == ItemSelectedHasChanged) {
|
||||
if (value.toBool()) {
|
||||
qDebug() << "Selected node:" << node_;
|
||||
}
|
||||
if (change == ItemPositionHasChanged) {
|
||||
readjust_all_edges();
|
||||
|
||||
update_context_rect();
|
||||
} else if (change == ItemSelectedHasChanged) {
|
||||
if (value.toBool()) {
|
||||
qDebug() << "Selected node:" << node_.handle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,14 +773,14 @@ void NodeViewItem::update_output_connector_position()
|
||||
|
||||
bool NodeViewItem::is_input_valid(const QString &input)
|
||||
{
|
||||
if (!node_->is_input_connectable(input) || node_->is_input_hidden(input)) {
|
||||
oak::Input in(node_, input);
|
||||
if (!in.is_connectable() || in.is_hidden()) {
|
||||
return false;
|
||||
}
|
||||
// For OFX plugin nodes, only show texture inputs in the node graph
|
||||
// to avoid excessively tall nodes with dozens of scalar parameters.
|
||||
// Scalar parameters are still visible in the parameter panel.
|
||||
if (node_->getPluginInstance() != nullptr &&
|
||||
node_->get_input_data_type(input) != NodeValue::k_texture) {
|
||||
if (node_.has_plugin() && in.data_type() != NodeValueType::k_texture) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -789,8 +801,8 @@ bool NodeViewItem::can_be_expanded() const
|
||||
if (is_output_item()) {
|
||||
return has_connectable_inputs_;
|
||||
} else {
|
||||
return node_->get_input_flags(input_) & k_input_flag_array &&
|
||||
element_ == -1 && !node_->is_input_connected(input_);
|
||||
return oak::Input(node_, input_).flags() & k_input_flag_array &&
|
||||
element_ == -1 && !oak::Input(node_, input_).is_connected();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,7 +857,7 @@ void NodeViewItem::repopulate_inputs()
|
||||
if (is_output_item()) {
|
||||
has_connectable_inputs_ = false;
|
||||
|
||||
foreach (const QString &input, node_->inputs()) {
|
||||
foreach (const QString &input, node_input_list(node_)) {
|
||||
if (is_input_valid(input)) {
|
||||
has_connectable_inputs_ = true;
|
||||
break;
|
||||
@@ -881,19 +893,20 @@ void NodeViewItem::set_highlighted(bool e)
|
||||
update();
|
||||
}
|
||||
|
||||
NodeViewItem *NodeViewItem::get_item_for_input(NodeInput input)
|
||||
NodeViewItem *NodeViewItem::get_item_for_input(oak::Input input)
|
||||
{
|
||||
if (oakengine_node_is_group(reinterpret_cast<OakEngineNode *>(node_))) {
|
||||
if (node_.is_group()) {
|
||||
if (input.node() != node_) {
|
||||
// Translate input to group input
|
||||
// WRAPPER-GAP: oakengine_group_get_id_of_passthrough (group passthrough lookup has no wrapper)
|
||||
char id[256];
|
||||
if (oakengine_group_get_id_of_passthrough(
|
||||
reinterpret_cast<OakEngineNode *>(node_),
|
||||
reinterpret_cast<OakEngineNode *>(input.node()),
|
||||
input.input().toUtf8().constData(), input.element(),
|
||||
node_.handle(),
|
||||
input.node_handle(),
|
||||
input.input_id().toUtf8().constData(), input.element(),
|
||||
id, sizeof(id)) > 0) {
|
||||
input.set_node(node_);
|
||||
input.set_input(QString::fromUtf8(id));
|
||||
input.set_node_handle(node_.handle());
|
||||
input.set_input_id(QString::fromUtf8(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,7 +915,7 @@ NodeViewItem *NodeViewItem::get_item_for_input(NodeInput input)
|
||||
if (input_.isEmpty()) {
|
||||
// Look for the input in our children
|
||||
foreach (NodeViewItem *i, children_) {
|
||||
if (i->input_ == input.input()) {
|
||||
if (i->input_ == input.input_id()) {
|
||||
return i->get_item_for_input(input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <QLinearGradient>
|
||||
#include <QWidget>
|
||||
|
||||
#include "node/node.h"
|
||||
#include "oakutil/oaknode.h"
|
||||
#include "nodeviewcommon.h"
|
||||
#include "nodeviewitemconnector.h"
|
||||
#include "engineeventbridge.h"
|
||||
@@ -38,6 +38,14 @@ namespace olive
|
||||
class NodeViewItem;
|
||||
class NodeViewEdge;
|
||||
|
||||
/**
|
||||
* @brief Local UI-only position aggregate (replaces engine Node::Position).
|
||||
*/
|
||||
struct NodeViewItemPosition {
|
||||
QPointF position;
|
||||
bool expanded = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A visual widget representation of a Node object to be used in a NodeView
|
||||
*
|
||||
@@ -48,36 +56,37 @@ class NodeViewEdge;
|
||||
class NodeViewItem : public QObject, public QGraphicsRectItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeViewItem(Node *node, const QString &input, int element, Node *context,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
NodeViewItem(Node *node, Node *context, QGraphicsItem *parent = nullptr)
|
||||
NodeViewItem(oak::Node node, const QString &input, int element,
|
||||
oak::Node context, QGraphicsItem *parent = nullptr);
|
||||
NodeViewItem(oak::Node node, oak::Node context,
|
||||
QGraphicsItem *parent = nullptr)
|
||||
: NodeViewItem(node, QString(), -1, context, parent)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~NodeViewItem() override;
|
||||
|
||||
Node::Position get_node_position_data() const;
|
||||
NodeViewItemPosition get_node_position_data() const;
|
||||
QPointF get_node_position() const;
|
||||
void set_node_position(const QPointF &pos);
|
||||
void set_node_position(const Node::Position &pos);
|
||||
void set_node_position(const NodeViewItemPosition &pos);
|
||||
|
||||
QVector<NodeViewEdge *> get_all_edges_recursively() const;
|
||||
|
||||
/**
|
||||
* @brief Get currently attached node
|
||||
*/
|
||||
Node *get_node() const
|
||||
oak::Node get_node() const
|
||||
{
|
||||
return node_;
|
||||
}
|
||||
|
||||
NodeInput get_input() const
|
||||
oak::Input get_input() const
|
||||
{
|
||||
return NodeInput(node_, input_, element_);
|
||||
return oak::Input(node_, input_, element_);
|
||||
}
|
||||
|
||||
Node *get_context() const
|
||||
oak::Node get_context() const
|
||||
{
|
||||
return context_;
|
||||
}
|
||||
@@ -145,7 +154,7 @@ public:
|
||||
|
||||
void set_highlighted(bool e);
|
||||
|
||||
NodeViewItem *get_item_for_input(NodeInput input);
|
||||
NodeViewItem *get_item_for_input(oak::Input input);
|
||||
|
||||
bool is_output_item() const
|
||||
{
|
||||
@@ -197,11 +206,11 @@ private:
|
||||
/**
|
||||
* @brief Reference to attached Node
|
||||
*/
|
||||
Node *node_;
|
||||
oak::Node node_;
|
||||
QString input_;
|
||||
int element_;
|
||||
|
||||
Node *context_;
|
||||
oak::Node context_;
|
||||
|
||||
/**
|
||||
* @brief Cached list of node inputs
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "nodeviewscene.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "nodeviewedge.h"
|
||||
#include "nodeviewitem.h"
|
||||
|
||||
@@ -70,7 +69,7 @@ QVector<NodeViewItem *> NodeViewScene::get_selected_items() const
|
||||
return items;
|
||||
}
|
||||
|
||||
NodeViewContext *NodeViewScene::add_context(Node *node)
|
||||
NodeViewContext *NodeViewScene::add_context(oak::Node node)
|
||||
{
|
||||
NodeViewContext *context_item = context_map_.value(node);
|
||||
|
||||
@@ -96,7 +95,7 @@ NodeViewContext *NodeViewScene::add_context(Node *node)
|
||||
return context_item;
|
||||
}
|
||||
|
||||
void NodeViewScene::remove_context(Node *node)
|
||||
void NodeViewScene::remove_context(oak::Node node)
|
||||
{
|
||||
delete context_map_.take(node);
|
||||
}
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QTimer>
|
||||
|
||||
#include "node/project.h"
|
||||
#include "nodeviewcontext.h"
|
||||
#include "nodeviewedge.h"
|
||||
#include "nodeviewitem.h"
|
||||
#include "undo/undostack.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -44,7 +42,7 @@ public:
|
||||
|
||||
QVector<NodeViewItem *> get_selected_items() const;
|
||||
|
||||
const QHash<Node *, NodeViewContext *> &context_map() const
|
||||
const QHash<oak::Node, NodeViewContext *> &context_map() const
|
||||
{
|
||||
return context_map_;
|
||||
}
|
||||
@@ -64,11 +62,9 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
// Not slots: signatures use the engine C++ type Node*, which must not be
|
||||
// exposed to MOC (it would pull Node::staticMetaObject across the ABI
|
||||
// boundary). They are called directly, never used as connect() targets.
|
||||
NodeViewContext *add_context(Node *node);
|
||||
void remove_context(Node *node);
|
||||
// Not slots: they are called directly, never used as connect() targets.
|
||||
NodeViewContext *add_context(oak::Node node);
|
||||
void remove_context(oak::Node node);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
@@ -77,9 +73,7 @@ public slots:
|
||||
void set_edges_are_curved(bool curved);
|
||||
|
||||
private:
|
||||
QHash<Node *, NodeViewContext *> context_map_;
|
||||
|
||||
Project *graph_;
|
||||
QHash<oak::Node, NodeViewContext *> context_map_;
|
||||
|
||||
NodeViewCommon::FlowDirection direction_;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
return node_view_;
|
||||
}
|
||||
|
||||
void set_contexts(const QVector<Node *> &nodes)
|
||||
void set_contexts(const QVector<oak::Node> &nodes)
|
||||
{
|
||||
node_view_->set_contexts(nodes);
|
||||
toolbar_->setEnabled(!nodes.isEmpty());
|
||||
|
||||
Reference in New Issue
Block a user