change: change code style to Linux style except indent.

This commit is contained in:
Mike Solar
2025-08-03 03:09:40 +08:00
parent 65ab76edc8
commit 74f73ab3be
789 changed files with 77113 additions and 68888 deletions
File diff suppressed because it is too large Load Diff
+149 -143
View File
@@ -33,7 +33,8 @@
#include "widget/handmovableview/handmovableview.h"
#include "widget/menu/menu.h"
namespace olive {
namespace olive
{
/**
* @brief A widget for viewing and editing node graphs
@@ -41,248 +42,253 @@ namespace olive {
* This widget takes a NodeGraph object and constructs a QGraphicsScene representing its data, viewing and allowing
* the user to make modifications to it.
*/
class NodeView : public HandMovableView
{
Q_OBJECT
class NodeView : public HandMovableView {
Q_OBJECT
public:
NodeView(QWidget* parent = nullptr);
NodeView(QWidget *parent = nullptr);
virtual ~NodeView() override;
virtual ~NodeView() override;
void SetContexts(const QVector<Node *> &nodes);
void SetContexts(const QVector<Node *> &nodes);
const QVector<Node*> &GetContexts() const
{
if (overlay_view_) {
return overlay_view_->GetContexts();
} else {
return contexts_;
}
}
const QVector<Node *> &GetContexts() const
{
if (overlay_view_) {
return overlay_view_->GetContexts();
} else {
return contexts_;
}
}
bool IsGroupOverlay() const
{
return overlay_view_;
}
bool IsGroupOverlay() const
{
return overlay_view_;
}
void CloseContextsBelongingToProject(Project *project);
void CloseContextsBelongingToProject(Project *project);
void ClearGraph();
void ClearGraph();
/**
/**
* @brief Delete selected nodes from graph (user-friendly/undoable)
*/
void DeleteSelected();
void DeleteSelected();
void SelectAll();
void DeselectAll();
void SelectAll();
void DeselectAll();
void Select(const QVector<Node::ContextPair> &nodes, bool center_view_on_item);
void Select(const QVector<Node::ContextPair> &nodes,
bool center_view_on_item);
void CopySelected(bool cut);
void Paste();
void CopySelected(bool cut);
void Paste();
void Duplicate();
void Duplicate();
void SetColorLabel(int index);
void SetColorLabel(int index);
void ZoomIn();
void ZoomIn();
void ZoomOut();
void ZoomOut();
const QVector<Node*> &GetCurrentContexts() const
{
return contexts_;
}
const QVector<Node *> &GetCurrentContexts() const
{
return contexts_;
}
public slots:
void SetMiniMapEnabled(bool e)
{
minimap_->setVisible(e);
}
void SetMiniMapEnabled(bool e)
{
minimap_->setVisible(e);
}
void ShowAddMenu()
{
Menu *m = CreateAddMenu(nullptr);
m->exec(QCursor::pos());
delete m;
}
void ShowAddMenu()
{
Menu *m = CreateAddMenu(nullptr);
m->exec(QCursor::pos());
delete m;
}
void CenterOnItemsBoundingRect();
void CenterOnItemsBoundingRect();
void CenterOnNode(olive::Node *n);
void CenterOnNode(olive::Node *n);
void LabelSelectedNodes();
void LabelSelectedNodes();
signals:
void NodesSelected(const QVector<Node*>& nodes);
void NodesSelected(const QVector<Node *> &nodes);
void NodesDeselected(const QVector<Node*>& nodes);
void NodesDeselected(const QVector<Node *> &nodes);
void NodeSelectionChanged(const QVector<Node*>& nodes);
void NodeSelectionChangedWithContexts(const QVector<Node::ContextPair>& nodes);
void NodeSelectionChanged(const QVector<Node *> &nodes);
void
NodeSelectionChangedWithContexts(const QVector<Node::ContextPair> &nodes);
void NodeGroupOpened(NodeGroup *group);
void NodeGroupClosed();
void NodeGroupOpened(NodeGroup *group);
void NodeGroupClosed();
void EscPressed();
void EscPressed();
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent* event) override;
virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dragMoveEvent(QDragMoveEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
virtual void dragLeaveEvent(QDragLeaveEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dragMoveEvent(QDragMoveEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
virtual void dragLeaveEvent(QDragLeaveEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void ZoomIntoCursorPosition(QWheelEvent *event, double multiplier, const QPointF &cursor_pos) override;
virtual void ZoomIntoCursorPosition(QWheelEvent *event, double multiplier,
const QPointF &cursor_pos) override;
virtual bool event(QEvent *event) override;
virtual bool event(QEvent *event) override;
virtual bool eventFilter(QObject *object, QEvent *event) override;
virtual bool eventFilter(QObject *object, QEvent *event) override;
virtual void changeEvent(QEvent *e) override;
virtual void changeEvent(QEvent *e) override;
private:
void DetachItemsFromCursor(bool delete_nodes_too = true);
void DetachItemsFromCursor(bool delete_nodes_too = true);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void MoveAttachedNodesToCursor(const QPoint &p);
void ProcessMovingAttachedNodes(const QPoint &pos);
QVector<Node*> ProcessDroppingAttachedNodes(MultiUndoCommand *command, Node *select_context, const QPoint &pos);
Node *GetContextAtMousePos(const QPoint &p);
void MoveAttachedNodesToCursor(const QPoint &p);
void ProcessMovingAttachedNodes(const QPoint &pos);
QVector<Node *> ProcessDroppingAttachedNodes(MultiUndoCommand *command,
Node *select_context,
const QPoint &pos);
Node *GetContextAtMousePos(const QPoint &p);
void ConnectSelectionChangedSignal();
void DisconnectSelectionChangedSignal();
void ConnectSelectionChangedSignal();
void DisconnectSelectionChangedSignal();
void ZoomFromKeyboard(double multiplier);
void ZoomFromKeyboard(double multiplier);
void ClearCreateEdgeInputIfNecessary();
void ClearCreateEdgeInputIfNecessary();
QPointF GetEstimatedPositionForContext(NodeViewItem *item, Node *context) const;
QPointF GetEstimatedPositionForContext(NodeViewItem *item,
Node *context) const;
NodeViewItem *GetAssumedItemForSelectedNode(Node *node);
bool GetAssumedPositionForSelectedNode(Node *node, Node::Position *pos);
NodeViewItem *GetAssumedItemForSelectedNode(Node *node);
bool GetAssumedPositionForSelectedNode(Node *node, Node::Position *pos);
Menu *CreateAddMenu(Menu *parent);
Menu *CreateAddMenu(Menu *parent);
void PositionNewEdge(const QPoint &pos);
void PositionNewEdge(const QPoint &pos);
void AddContext(Node *n);
void AddContext(Node *n);
void RemoveContext(Node *n);
void RemoveContext(Node *n);
bool IsItemAttachedToCursor(NodeViewItem *item) const;
bool IsItemAttachedToCursor(NodeViewItem *item) const;
void ExpandItem(NodeViewItem *item);
void ExpandItem(NodeViewItem *item);
void CollapseItem(NodeViewItem *item);
void CollapseItem(NodeViewItem *item);
void EndEdgeDrag(bool cancel = false);
void EndEdgeDrag(bool cancel = false);
void PostPaste(const QVector<Node*> &new_nodes, const Node::PositionMap &map);
void PostPaste(const QVector<Node *> &new_nodes,
const Node::PositionMap &map);
void ResizeOverlay();
void ResizeOverlay();
NodeViewMiniMap *minimap_;
NodeViewMiniMap *minimap_;
NodeViewContext *GetContextItemFromNodeItem(NodeViewItem *item);
NodeViewContext *GetContextItemFromNodeItem(NodeViewItem *item);
struct AttachedItem {
NodeViewItem* item;
Node *node;
QPointF original_pos;
};
struct AttachedItem {
NodeViewItem *item;
Node *node;
QPointF original_pos;
};
void SetAttachedItems(const QVector<AttachedItem> &items);
QVector<AttachedItem> attached_items_;
void SetAttachedItems(const QVector<AttachedItem> &items);
QVector<AttachedItem> attached_items_;
NodeViewEdge* drop_edge_;
NodeInput drop_input_;
NodeViewEdge *drop_edge_;
NodeInput drop_input_;
NodeViewEdge* create_edge_;
NodeViewItem* create_edge_output_item_;
NodeViewItem* create_edge_input_item_;
NodeInput create_edge_input_;
bool create_edge_already_exists_;
bool create_edge_from_output_;
NodeViewEdge *create_edge_;
NodeViewItem *create_edge_output_item_;
NodeViewItem *create_edge_input_item_;
NodeInput create_edge_input_;
bool create_edge_already_exists_;
bool create_edge_from_output_;
QVector<NodeViewItem*> create_edge_expanded_items_;
QVector<NodeViewItem *> create_edge_expanded_items_;
NodeViewScene scene_;
NodeViewScene scene_;
QVector<Node*> selected_nodes_;
QVector<Node *> selected_nodes_;
QVector<Node*> contexts_;
QVector<Node*> last_set_filter_nodes_;
QMap<Node*, QPointF> context_offsets_;
QVector<Node *> contexts_;
QVector<Node *> last_set_filter_nodes_;
QMap<Node *, QPointF> context_offsets_;
QMap<NodeViewItem*, QPointF> dragging_items_;
QMap<NodeViewItem *, QPointF> dragging_items_;
NodeView* overlay_view_;
NodeView *overlay_view_;
double scale_;
double scale_;
bool dont_emit_selection_signals_;
bool dont_emit_selection_signals_;
static const double kMinimumScale;
static const double kMinimumScale;
static const int kMaximumContexts;
static const int kMaximumContexts;
private slots:
/**
/**
* @brief Receiver for when the scene's selected items change
*/
void UpdateSelectionCache();
void UpdateSelectionCache();
/**
/**
* @brief Receiver for when the user right clicks (or otherwise requests a context menu)
*/
void ShowContextMenu(const QPoint &pos);
void ShowContextMenu(const QPoint &pos);
/**
/**
* @brief Receiver for when the user requests a new node from the add menu
*/
void CreateNodeSlot(QAction* action);
void CreateNodeSlot(QAction *action);
/**
/**
* @brief Receiver for setting the direction from the context menu
*/
void ContextMenuSetDirection(QAction* action);
void ContextMenuSetDirection(QAction *action);
/**
/**
* @brief Opens the selected node in a Viewer
*/
void OpenSelectedNodeInViewer();
void OpenSelectedNodeInViewer();
void UpdateSceneBoundingRect();
void UpdateSceneBoundingRect();
void RepositionMiniMap();
void RepositionMiniMap();
void UpdateViewportOnMiniMap();
void UpdateViewportOnMiniMap();
void MoveToScenePoint(const QPointF &pos);
void MoveToScenePoint(const QPointF &pos);
void NodeRemovedFromGraph();
void NodeRemovedFromGraph();
void GroupNodes();
void GroupNodes();
void UngroupNodes();
void UngroupNodes();
void ShowNodeProperties();
void ShowNodeProperties();
void ItemAboutToBeDeleted(NodeViewItem *item);
void CloseOverlay();
void ItemAboutToBeDeleted(NodeViewItem *item);
void CloseOverlay();
};
}
+36 -30
View File
@@ -25,43 +25,49 @@
#include "common/define.h"
namespace olive {
namespace olive
{
class NodeViewCommon {
public:
enum FlowDirection {
kInvalidDirection = -1,
kTopToBottom,
kBottomToTop,
kLeftToRight,
kRightToLeft
};
enum FlowDirection {
kInvalidDirection = -1,
kTopToBottom,
kBottomToTop,
kLeftToRight,
kRightToLeft
};
static Qt::Orientation GetFlowOrientation(FlowDirection dir) {
if (dir == kTopToBottom || dir == kBottomToTop) {
return Qt::Vertical;
} else {
return Qt::Horizontal;
}
}
static Qt::Orientation GetFlowOrientation(FlowDirection dir)
{
if (dir == kTopToBottom || dir == kBottomToTop) {
return Qt::Vertical;
} else {
return Qt::Horizontal;
}
}
static bool IsFlowVertical(FlowDirection dir)
{
return dir == kTopToBottom || dir == kBottomToTop;
}
static bool IsFlowVertical(FlowDirection dir)
{
return dir == kTopToBottom || dir == kBottomToTop;
}
static bool IsFlowHorizontal(FlowDirection dir)
{
return dir == kLeftToRight || dir == kRightToLeft;
}
static bool DirectionsAreOpposing(FlowDirection a, FlowDirection b) {
return ((a == NodeViewCommon::kLeftToRight && b == NodeViewCommon::kRightToLeft)
|| (a == NodeViewCommon::kRightToLeft && b == NodeViewCommon::kLeftToRight)
|| (a == NodeViewCommon::kTopToBottom && b == NodeViewCommon::kBottomToTop)
|| (a == NodeViewCommon::kBottomToTop && b == NodeViewCommon::kTopToBottom));
}
static bool IsFlowHorizontal(FlowDirection dir)
{
return dir == kLeftToRight || dir == kRightToLeft;
}
static bool DirectionsAreOpposing(FlowDirection a, FlowDirection b)
{
return ((a == NodeViewCommon::kLeftToRight &&
b == NodeViewCommon::kRightToLeft) ||
(a == NodeViewCommon::kRightToLeft &&
b == NodeViewCommon::kLeftToRight) ||
(a == NodeViewCommon::kTopToBottom &&
b == NodeViewCommon::kBottomToTop) ||
(a == NodeViewCommon::kBottomToTop &&
b == NodeViewCommon::kTopToBottom));
}
};
}
+247 -212
View File
@@ -16,344 +16,379 @@
#include "nodeviewitem.h"
#include "ui/colorcoding.h"
namespace olive {
namespace olive
{
#define super QGraphicsRectItem
NodeViewContext::NodeViewContext(Node *context, QGraphicsItem *item) :
super(item),
context_(context)
NodeViewContext::NodeViewContext(Node *context, QGraphicsItem *item)
: super(item)
, context_(context)
{
Block *block = dynamic_cast<Block*>(context_);
if (block && block->track() && block->track()->sequence()) {
rational timebase = block->track()->sequence()->GetVideoParams().frame_rate_as_time_base();
lbl_ = QCoreApplication::translate("NodeViewContext",
"%1 [%2] :: %3 - %4").arg(block->GetLabelAndName(),
Track::Reference::TypeToTranslatedString(block->track()->type()),
QString::fromStdString(Timecode::time_to_timecode(block->in(), timebase, Core::instance()->GetTimecodeDisplay())),
QString::fromStdString(Timecode::time_to_timecode(block->out(), timebase, Core::instance()->GetTimecodeDisplay())));
} else {
lbl_ = context_->GetLabelAndName();
}
Block *block = dynamic_cast<Block *>(context_);
if (block && block->track() && block->track()->sequence()) {
rational timebase = block->track()
->sequence()
->GetVideoParams()
.frame_rate_as_time_base();
lbl_ =
QCoreApplication::translate("NodeViewContext", "%1 [%2] :: %3 - %4")
.arg(block->GetLabelAndName(),
Track::Reference::TypeToTranslatedString(
block->track()->type()),
QString::fromStdString(Timecode::time_to_timecode(
block->in(), timebase,
Core::instance()->GetTimecodeDisplay())),
QString::fromStdString(Timecode::time_to_timecode(
block->out(), timebase,
Core::instance()->GetTimecodeDisplay())));
} else {
lbl_ = context_->GetLabelAndName();
}
const Node::PositionMap &map = context_->GetContextPositions();
for (auto it=map.cbegin(); it!=map.cend(); it++) {
AddChild(it.key());
}
const Node::PositionMap &map = context_->GetContextPositions();
for (auto it = map.cbegin(); it != map.cend(); it++) {
AddChild(it.key());
}
connect(context_, &Node::NodeAddedToContext, this, &NodeViewContext::AddChild, Qt::DirectConnection);
connect(context_, &Node::NodePositionInContextChanged, this, &NodeViewContext::SetChildPosition, Qt::DirectConnection);
connect(context_, &Node::NodeRemovedFromContext, this, &NodeViewContext::RemoveChild, Qt::DirectConnection);
connect(context_, &Node::NodeAddedToContext, this,
&NodeViewContext::AddChild, Qt::DirectConnection);
connect(context_, &Node::NodePositionInContextChanged, this,
&NodeViewContext::SetChildPosition, Qt::DirectConnection);
connect(context_, &Node::NodeRemovedFromContext, this,
&NodeViewContext::RemoveChild, Qt::DirectConnection);
}
NodeViewContext::~NodeViewContext()
{
// Delete edges before items, because the edge constructor references the items
qDeleteAll(edges_);
edges_.clear();
// Delete edges before items, because the edge constructor references the items
qDeleteAll(edges_);
edges_.clear();
}
void NodeViewContext::AddChild(Node *node)
{
if (!context_) {
return;
}
if (!context_) {
return;
}
NodeViewItem *item = new NodeViewItem(node, context_, this);
item->SetFlowDirection(flow_dir_);
NodeViewItem *item = new NodeViewItem(node, context_, this);
item->SetFlowDirection(flow_dir_);
AddNodeInternal(node, item);
AddNodeInternal(node, item);
if (NodeGroup *group = dynamic_cast<NodeGroup*>(node)) {
for (auto it=group->GetContextPositions().cbegin(); it!=group->GetContextPositions().cend(); it++) {
// Use this item as the representative for all of these nodes too
AddNodeInternal(it.key(), item);
}
if (NodeGroup *group = dynamic_cast<NodeGroup *>(node)) {
for (auto it = group->GetContextPositions().cbegin();
it != group->GetContextPositions().cend(); it++) {
// Use this item as the representative for all of these nodes too
AddNodeInternal(it.key(), item);
}
connect(group, &NodeGroup::NodeAddedToContext, this, &NodeViewContext::GroupAddedNode);
connect(group, &NodeGroup::NodeRemovedFromContext, this, &NodeViewContext::GroupRemovedNode);
}
connect(group, &NodeGroup::NodeAddedToContext, this,
&NodeViewContext::GroupAddedNode);
connect(group, &NodeGroup::NodeRemovedFromContext, this,
&NodeViewContext::GroupRemovedNode);
}
UpdateRect();
UpdateRect();
}
void NodeViewContext::SetChildPosition(Node *node, const QPointF &pos)
{
item_map_.value(node)->SetNodePosition(pos);
item_map_.value(node)->SetNodePosition(pos);
}
void NodeViewContext::RemoveChild(Node *node)
{
disconnect(node, &Node::InputConnected, this, &NodeViewContext::ChildInputConnected);
disconnect(node, &Node::InputDisconnected, this, &NodeViewContext::ChildInputDisconnected);
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);
}
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);
NodeViewItem *item = item_map_.take(node);
// Remove from scene before emitting signal so that any drag functions that might be happening
// now can be handled before the item is destroyed
scene()->removeItem(item);
// Remove from scene before emitting signal so that any drag functions that might be happening
// now can be handled before the item is destroyed
scene()->removeItem(item);
emit ItemAboutToBeDeleted(item);
emit ItemAboutToBeDeleted(item);
// Delete edges first because the edge destructor will try to reference item (maybe that should
// be changed...)
QVector<NodeViewEdge*> edges_to_remove = item->GetAllEdgesRecursively();
foreach (NodeViewEdge *edge, edges_to_remove) {
if (node == item->GetNode() || edge->output() == node || edge->input().node() == node) {
ChildInputDisconnected(edge->output(), edge->input());
}
}
// Delete edges first because the edge destructor will try to reference item (maybe that should
// be changed...)
QVector<NodeViewEdge *> edges_to_remove = item->GetAllEdgesRecursively();
foreach (NodeViewEdge *edge, edges_to_remove) {
if (node == item->GetNode() || edge->output() == node ||
edge->input().node() == node) {
ChildInputDisconnected(edge->output(), 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->GetNode() == node) {
if (dynamic_cast<NodeGroup*>(item->GetNode())) {
for (auto it=item_map_.begin(); it!=item_map_.end(); ) {
if (it.value() == item) {
it = item_map_.erase(it);
} else {
it++;
}
}
}
// 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->GetNode() == node) {
if (dynamic_cast<NodeGroup *>(item->GetNode())) {
for (auto it = item_map_.begin(); it != item_map_.end();) {
if (it.value() == item) {
it = item_map_.erase(it);
} else {
it++;
}
}
}
delete item;
}
delete item;
}
UpdateRect();
UpdateRect();
}
void NodeViewContext::ChildInputConnected(Node *output, const NodeInput &input)
{
// Add edge
if (!input.IsHidden()) {
if (NodeViewItem* output_item = item_map_.value(output)) {
AddEdgeInternal(output, input, output_item, item_map_.value(input.node())->GetItemForInput(input));
}
}
// Add edge
if (!input.IsHidden()) {
if (NodeViewItem *output_item = item_map_.value(output)) {
AddEdgeInternal(
output, input, output_item,
item_map_.value(input.node())->GetItemForInput(input));
}
}
}
bool NodeViewContext::ChildInputDisconnected(Node *output, const NodeInput &input)
bool NodeViewContext::ChildInputDisconnected(Node *output,
const NodeInput &input)
{
// Remove edge
for (int i=0; i<edges_.size(); i++) {
NodeViewEdge *e = edges_.at(i);
if (e->output() == output && e->input() == input) {
delete e;
edges_.removeAt(i);
return true;
}
}
// Remove edge
for (int i = 0; i < edges_.size(); i++) {
NodeViewEdge *e = edges_.at(i);
if (e->output() == output && e->input() == input) {
delete e;
edges_.removeAt(i);
return true;
}
}
return false;
return false;
}
qreal GetTextOffset(const QFontMetricsF &fm)
{
return fm.height()/2;
return fm.height() / 2;
}
void NodeViewContext::UpdateRect()
{
QFont f;
QFontMetricsF fm(f);
qreal lbl_offset = GetTextOffset(fm);
QFont f;
QFontMetricsF fm(f);
qreal lbl_offset = GetTextOffset(fm);
QRectF cbr = childrenBoundingRect();
QRectF rect = cbr;
int pad = NodeViewItem::DefaultItemHeight();
rect.adjust(-pad, - lbl_offset*2 - fm.height() - pad, pad, pad);
setRect(rect);
QRectF cbr = childrenBoundingRect();
QRectF rect = cbr;
int pad = NodeViewItem::DefaultItemHeight();
rect.adjust(-pad, -lbl_offset * 2 - fm.height() - pad, pad, pad);
setRect(rect);
last_titlebar_height_ = rect.y() + (cbr.y() - rect.y()) - pad;
last_titlebar_height_ = rect.y() + (cbr.y() - rect.y()) - pad;
}
void NodeViewContext::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
flow_dir_ = dir;
flow_dir_ = dir;
foreach (NodeViewItem *item, item_map_) {
item->SetFlowDirection(dir);
}
foreach (NodeViewItem *item, item_map_) {
item->SetFlowDirection(dir);
}
}
void NodeViewContext::SetCurvedEdges(bool e)
{
curved_edges_ = e;
curved_edges_ = e;
foreach (NodeViewEdge *edge, edges_) {
edge->SetCurved(e);
}
foreach (NodeViewEdge *edge, edges_) {
edge->SetCurved(e);
}
}
int NodeViewContext::DeleteSelected(NodeViewDeleteCommand *command)
{
int count = 0;
int count = 0;
// Delete any selected edges
foreach (NodeViewEdge *edge, edges_) {
if (edge->isSelected()) {
command->AddEdge(edge->output(), edge->input());
}
}
// Delete any selected edges
foreach (NodeViewEdge *edge, edges_) {
if (edge->isSelected()) {
command->AddEdge(edge->output(), edge->input());
}
}
// Delete any selected nodes
foreach (NodeViewItem *node, item_map_) {
if (node->isSelected()) {
command->AddNode(node->GetNode(), context_);
count++;
}
}
// Delete any selected nodes
foreach (NodeViewItem *node, item_map_) {
if (node->isSelected()) {
command->AddNode(node->GetNode(), context_);
count++;
}
}
return count;
return count;
}
void NodeViewContext::Select(const QVector<Node *> &nodes)
{
foreach (Node *n, nodes) {
if (NodeViewItem *item = item_map_.value(n)) {
item->setSelected(true);
}
}
foreach (Node *n, nodes) {
if (NodeViewItem *item = item_map_.value(n)) {
item->setSelected(true);
}
}
}
QVector<NodeViewItem *> NodeViewContext::GetSelectedItems() const
{
QVector<NodeViewItem *> items;
QVector<NodeViewItem *> items;
for (auto it=item_map_.cbegin(); it!=item_map_.cend(); it++) {
if (it.value()->isSelected()) {
if (!items.contains(it.value())) {
items.append(it.value());
}
}
}
for (auto it = item_map_.cbegin(); it != item_map_.cend(); it++) {
if (it.value()->isSelected()) {
if (!items.contains(it.value())) {
items.append(it.value());
}
}
}
return items;
return items;
}
QPointF NodeViewContext::MapScenePosToNodePosInContext(const QPointF &pos) const
{
for (auto it=item_map_.cbegin(); it!=item_map_.cend(); it++) {
QPointF pos_inside_parent = it.value()->mapToParent(it.value()->mapFromScene(pos));
return NodeViewItem::ScreenToNodePoint(pos_inside_parent, flow_dir_);
}
return QPointF(0, 0);
for (auto it = item_map_.cbegin(); it != item_map_.cend(); it++) {
QPointF pos_inside_parent =
it.value()->mapToParent(it.value()->mapFromScene(pos));
return NodeViewItem::ScreenToNodePoint(pos_inside_parent, flow_dir_);
}
return QPointF(0, 0);
}
void NodeViewContext::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
void NodeViewContext::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
// Set pen and brush
Color color = context_->color();
QColor c = QtUtils::toQColor(color);
QPen pen(c, 2);
if (option->state & QStyle::State_Selected) {
pen.setStyle(Qt::DotLine);
}
painter->setPen(pen);
// Set pen and brush
Color color = context_->color();
QColor c = QtUtils::toQColor(color);
QPen pen(c, 2);
if (option->state & QStyle::State_Selected) {
pen.setStyle(Qt::DotLine);
}
painter->setPen(pen);
QColor bg = c;
bg.setAlpha(128);
painter->setBrush(bg);
QColor bg = c;
bg.setAlpha(128);
painter->setBrush(bg);
// Draw semi-transparent rect for whole item
int rounded = painter->fontMetrics().height();
painter->drawRoundedRect(rect(), rounded, rounded);
// Draw semi-transparent rect for whole item
int rounded = painter->fontMetrics().height();
painter->drawRoundedRect(rect(), rounded, rounded);
// Draw solid background for titlebar
QRectF titlebar_rect = rect();
titlebar_rect.setHeight(last_titlebar_height_ - rect().top());
painter->setClipRect(titlebar_rect);
painter->setBrush(c);
painter->drawRoundedRect(rect(), rounded, rounded);
painter->setClipping(false);
// Draw solid background for titlebar
QRectF titlebar_rect = rect();
titlebar_rect.setHeight(last_titlebar_height_ - rect().top());
painter->setClipRect(titlebar_rect);
painter->setBrush(c);
painter->drawRoundedRect(rect(), rounded, rounded);
painter->setClipping(false);
// Draw titlebar text
painter->setPen(ColorCoding::GetUISelectorColor(color));
// Draw titlebar text
painter->setPen(ColorCoding::GetUISelectorColor(color));
int offset = GetTextOffset(painter->fontMetrics());
int offset = GetTextOffset(painter->fontMetrics());
QRectF text_rect = rect();
text_rect.adjust(offset, offset, -offset, -offset);
painter->drawText(text_rect, lbl_);
QRectF text_rect = rect();
text_rect.adjust(offset, offset, -offset, -offset);
painter->drawText(text_rect, lbl_);
}
QVariant NodeViewContext::itemChange(GraphicsItemChange change, const QVariant &value)
QVariant NodeViewContext::itemChange(GraphicsItemChange change,
const QVariant &value)
{
return super::itemChange(change, value);
return super::itemChange(change, value);
}
void NodeViewContext::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
bool clicked_inside_titlebar = (event->pos().y() < last_titlebar_height_);
bool clicked_inside_titlebar = (event->pos().y() < last_titlebar_height_);
setFlag(ItemIsMovable, clicked_inside_titlebar);
setFlag(ItemIsSelectable, clicked_inside_titlebar);
setFlag(ItemIsMovable, clicked_inside_titlebar);
setFlag(ItemIsSelectable, clicked_inside_titlebar);
super::mousePressEvent(event);
super::mousePressEvent(event);
}
void NodeViewContext::AddNodeInternal(Node *node, NodeViewItem *item)
{
connect(node, &Node::InputConnected, this, &NodeViewContext::ChildInputConnected);
connect(node, &Node::InputDisconnected, this, &NodeViewContext::ChildInputDisconnected);
connect(node, &Node::InputConnected, this,
&NodeViewContext::ChildInputConnected);
connect(node, &Node::InputDisconnected, this,
&NodeViewContext::ChildInputDisconnected);
item_map_.insert(node, item);
item_map_.insert(node, item);
if (node == context_) {
item->SetLabelAsOutput(true);
}
if (node == context_) {
item->SetLabelAsOutput(true);
}
for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) {
if (!it->second.IsHidden()) {
if (NodeViewItem *other_item = item_map_.value(it->second.node())) {
AddEdgeInternal(node, it->second, item, other_item->GetItemForInput(it->second));
}
}
}
for (auto it = node->output_connections().cbegin();
it != node->output_connections().cend(); it++) {
if (!it->second.IsHidden()) {
if (NodeViewItem *other_item = item_map_.value(it->second.node())) {
AddEdgeInternal(node, it->second, item,
other_item->GetItemForInput(it->second));
}
}
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
if (!it->first.IsHidden()) {
if (NodeViewItem *other_item = item_map_.value(it->second)) {
AddEdgeInternal(it->second, it->first, other_item, item->GetItemForInput(it->first));
}
}
}
for (auto it = node->input_connections().cbegin();
it != node->input_connections().cend(); it++) {
if (!it->first.IsHidden()) {
if (NodeViewItem *other_item = item_map_.value(it->second)) {
AddEdgeInternal(it->second, it->first, other_item,
item->GetItemForInput(it->first));
}
}
}
}
void NodeViewContext::AddEdgeInternal(Node *output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
void NodeViewContext::AddEdgeInternal(Node *output, const NodeInput &input,
NodeViewItem *from, NodeViewItem *to)
{
if (from == to) {
return;
}
if (from == to) {
return;
}
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, from, to, this);
NodeViewEdge *edge_ui = new NodeViewEdge(output, input, from, to, this);
edge_ui->Adjust();
edge_ui->SetCurved(curved_edges_);
edge_ui->Adjust();
edge_ui->SetCurved(curved_edges_);
edges_.append(edge_ui);
edges_.append(edge_ui);
}
void NodeViewContext::GroupAddedNode(Node *node)
{
NodeGroup *group = static_cast<NodeGroup*>(sender());
NodeGroup *group = static_cast<NodeGroup *>(sender());
AddNodeInternal(node, item_map_.value(group));
AddNodeInternal(node, item_map_.value(group));
}
void NodeViewContext::GroupRemovedNode(Node *node)
{
NodeGroup *group = static_cast<NodeGroup*>(sender());
NodeGroup *group = static_cast<NodeGroup *>(sender());
if (item_map_.value(node) == item_map_.value(group)) {
item_map_.remove(node);
}
if (item_map_.value(node) == item_map_.value(group)) {
item_map_.remove(node);
}
}
}
+45 -42
View File
@@ -9,85 +9,88 @@
#include "nodeviewcommon.h"
#include "nodeviewedge.h"
namespace olive {
class NodeViewContext : public QObject, public QGraphicsRectItem
namespace olive
{
Q_OBJECT
class NodeViewContext : public QObject, public QGraphicsRectItem {
Q_OBJECT
public:
NodeViewContext(Node *context, QGraphicsItem *item = nullptr);
NodeViewContext(Node *context, QGraphicsItem *item = nullptr);
virtual ~NodeViewContext() override;
virtual ~NodeViewContext() override;
Node *GetContext() const
{
return context_;
}
Node *GetContext() const
{
return context_;
}
void UpdateRect();
void UpdateRect();
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void SetCurvedEdges(bool e);
void SetCurvedEdges(bool e);
int DeleteSelected(NodeViewDeleteCommand *command);
int DeleteSelected(NodeViewDeleteCommand *command);
void Select(const QVector<Node*> &nodes);
void Select(const QVector<Node *> &nodes);
QVector<NodeViewItem*> GetSelectedItems() const;
QVector<NodeViewItem *> GetSelectedItems() const;
QPointF MapScenePosToNodePosInContext(const QPointF &pos) const;
QPointF MapScenePosToNodePosInContext(const QPointF &pos) const;
NodeViewItem *GetItemFromMap(Node *node) const
{
return item_map_.value(node);
}
NodeViewItem *GetItemFromMap(Node *node) const
{
return item_map_.value(node);
}
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
public slots:
void AddChild(Node *node);
void AddChild(Node *node);
void SetChildPosition(Node *node, const QPointF &pos);
void SetChildPosition(Node *node, const QPointF &pos);
void RemoveChild(Node *node);
void RemoveChild(Node *node);
void ChildInputConnected(Node *output, const NodeInput& input);
void ChildInputConnected(Node *output, const NodeInput &input);
bool ChildInputDisconnected(Node *output, const NodeInput& input);
bool ChildInputDisconnected(Node *output, const NodeInput &input);
signals:
void ItemAboutToBeDeleted(NodeViewItem *item);
void ItemAboutToBeDeleted(NodeViewItem *item);
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change,
const QVariant &value) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private:
void AddNodeInternal(Node *node, NodeViewItem *item);
void AddNodeInternal(Node *node, NodeViewItem *item);
void AddEdgeInternal(Node *output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to);
void AddEdgeInternal(Node *output, const NodeInput &input,
NodeViewItem *from, NodeViewItem *to);
Node *context_;
Node *context_;
QString lbl_;
QString lbl_;
NodeViewCommon::FlowDirection flow_dir_;
NodeViewCommon::FlowDirection flow_dir_;
bool curved_edges_;
bool curved_edges_;
int last_titlebar_height_;
int last_titlebar_height_;
QMap<Node*, NodeViewItem*> item_map_;
QMap<Node *, NodeViewItem *> item_map_;
QVector<NodeViewEdge*> edges_;
QVector<NodeViewEdge *> edges_;
private slots:
void GroupAddedNode(Node *node);
void GroupRemovedNode(Node *node);
void GroupAddedNode(Node *node);
void GroupRemovedNode(Node *node);
};
}
+138 -134
View File
@@ -30,226 +30,230 @@
#include "nodeviewitem.h"
#include "nodeviewscene.h"
namespace olive {
namespace olive
{
#define super QGraphicsPathItem
NodeViewEdge::NodeViewEdge(Node *output, const NodeInput &input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent) :
super(parent),
output_(output),
input_(input),
from_item_(from_item),
to_item_(to_item)
NodeViewItem *from_item, NodeViewItem *to_item,
QGraphicsItem *parent)
: super(parent)
, output_(output)
, input_(input)
, from_item_(from_item)
, to_item_(to_item)
{
Init();
SetConnected(true);
Init();
SetConnected(true);
from_item_->AddEdge(this);
to_item_->AddEdge(this);
from_item_->AddEdge(this);
to_item_->AddEdge(this);
}
NodeViewEdge::NodeViewEdge(QGraphicsItem *parent) :
QGraphicsPathItem(parent),
from_item_(nullptr),
to_item_(nullptr)
NodeViewEdge::NodeViewEdge(QGraphicsItem *parent)
: QGraphicsPathItem(parent)
, from_item_(nullptr)
, to_item_(nullptr)
{
Init();
Init();
}
NodeViewEdge::~NodeViewEdge()
{
if (from_item_) {
from_item_->RemoveEdge(this);
}
if (from_item_) {
from_item_->RemoveEdge(this);
}
if (to_item_) {
to_item_->RemoveEdge(this);
}
if (to_item_) {
to_item_->RemoveEdge(this);
}
}
void NodeViewEdge::set_from_item(NodeViewItem *i)
{
if (from_item_) {
from_item_->RemoveEdge(this);
}
if (from_item_) {
from_item_->RemoveEdge(this);
}
from_item_ = i;
from_item_ = i;
if (from_item_) {
from_item_->AddEdge(this);
}
if (from_item_) {
from_item_->AddEdge(this);
}
Adjust();
Adjust();
}
void NodeViewEdge::set_to_item(NodeViewItem *i)
{
if (to_item_) {
to_item_->RemoveEdge(this);
}
if (to_item_) {
to_item_->RemoveEdge(this);
}
to_item_ = i;
to_item_ = i;
if (to_item_) {
to_item_->AddEdge(this);
}
if (to_item_) {
to_item_->AddEdge(this);
}
Adjust();
Adjust();
}
void NodeViewEdge::Adjust()
{
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(), to_item()->GetInputPoint());
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(), to_item()->GetInputPoint());
}
void NodeViewEdge::SetConnected(bool c)
{
connected_ = c;
connected_ = c;
update();
update();
}
void NodeViewEdge::SetHighlighted(bool e)
{
highlighted_ = e;
highlighted_ = e;
update();
update();
}
void NodeViewEdge::SetPoints(const QPointF &start, const QPointF &end)
{
cached_start_ = start;
cached_end_ = end;
cached_start_ = start;
cached_end_ = end;
UpdateCurve();
UpdateCurve();
}
void NodeViewEdge::SetCurved(bool e)
{
curved_ = e;
curved_ = e;
UpdateCurve();
UpdateCurve();
}
void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
void NodeViewEdge::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *)
{
QPalette::ColorGroup group;
QPalette::ColorRole role;
QPalette::ColorGroup group;
QPalette::ColorRole role;
if (connected_) {
group = QPalette::Active;
} else {
group = QPalette::Disabled;
}
if (connected_) {
group = QPalette::Active;
} else {
group = QPalette::Disabled;
}
if (highlighted_ != bool(option->state & QStyle::State_Selected)) {
role = QPalette::Highlight;
} else {
role = QPalette::Text;
}
if (highlighted_ != bool(option->state & QStyle::State_Selected)) {
role = QPalette::Highlight;
} else {
role = QPalette::Text;
}
// Draw main path
QColor edge_color = qApp->palette().color(group, role);
// Draw main path
QColor edge_color = qApp->palette().color(group, role);
painter->setPen(QPen(edge_color, edge_width_));
painter->setBrush(Qt::NoBrush);
painter->drawPath(path());
painter->setPen(QPen(edge_color, edge_width_));
painter->setBrush(Qt::NoBrush);
painter->drawPath(path());
}
void NodeViewEdge::Init()
{
connected_ = false;
highlighted_ = false;
curved_ = true;
connected_ = false;
highlighted_ = false;
curved_ = true;
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsSelectable);
// Ensures this UI object is drawn behind other objects
setZValue(-1);
// Ensures this UI object is drawn behind other objects
setZValue(-1);
// Use font metrics to set edge width for basic high DPI support
edge_width_ = QFontMetrics(QFont()).height() / 12;
// Use font metrics to set edge width for basic high DPI support
edge_width_ = QFontMetrics(QFont()).height() / 12;
}
void NodeViewEdge::UpdateCurve()
{
const QPointF &start = cached_start_;
const QPointF &end = cached_end_;
const QPointF &start = cached_start_;
const QPointF &end = cached_end_;
QPainterPath path;
path.moveTo(start);
QPainterPath path;
path.moveTo(start);
double angle = std::atan2(end.y() - start.y(), end.x() - start.x());
double angle = std::atan2(end.y() - start.y(), end.x() - start.x());
if (curved_) {
if (curved_) {
double half_x = lerp(start.x(), end.x(), 0.5);
double half_y = lerp(start.y(), end.y(), 0.5);
double half_x = lerp(start.x(), end.x(), 0.5);
double half_y = lerp(start.y(), end.y(), 0.5);
QPointF cp1, cp2;
QPointF cp1, cp2;
NodeViewCommon::FlowDirection from_flow =
from_item_ ? from_item_->GetFlowDirection() :
NodeViewCommon::kInvalidDirection;
NodeViewCommon::FlowDirection to_flow =
to_item_ ? to_item_->GetFlowDirection() :
NodeViewCommon::kInvalidDirection;
NodeViewCommon::FlowDirection from_flow = from_item_ ? from_item_->GetFlowDirection() : NodeViewCommon::kInvalidDirection;
NodeViewCommon::FlowDirection to_flow = to_item_ ? to_item_->GetFlowDirection() : NodeViewCommon::kInvalidDirection;
if (from_flow == NodeViewCommon::kInvalidDirection &&
to_flow == NodeViewCommon::kInvalidDirection) {
// This is a technically unsupported scenario, but to avoid issues, we'll use a fallback
from_flow = NodeViewCommon::kLeftToRight;
to_flow = NodeViewCommon::kLeftToRight;
} else if (from_flow == NodeViewCommon::kInvalidDirection) {
from_flow = to_flow;
} else if (to_flow == NodeViewCommon::kInvalidDirection) {
to_flow = from_flow;
}
if (from_flow == NodeViewCommon::kInvalidDirection && to_flow == NodeViewCommon::kInvalidDirection) {
// This is a technically unsupported scenario, but to avoid issues, we'll use a fallback
from_flow = NodeViewCommon::kLeftToRight;
to_flow = NodeViewCommon::kLeftToRight;
} else if (from_flow == NodeViewCommon::kInvalidDirection) {
from_flow = to_flow;
} else if (to_flow == NodeViewCommon::kInvalidDirection) {
to_flow = from_flow;
}
if (NodeViewCommon::GetFlowOrientation(from_flow) == Qt::Horizontal) {
cp1 = QPointF(half_x, start.y());
} else {
cp1 = QPointF(start.x(), half_y);
}
if (NodeViewCommon::GetFlowOrientation(from_flow) == Qt::Horizontal) {
cp1 = QPointF(half_x, start.y());
} else {
cp1 = QPointF(start.x(), half_y);
}
if (NodeViewCommon::GetFlowOrientation(to_flow) == Qt::Horizontal) {
cp2 = QPointF(half_x, end.y());
} else {
cp2 = QPointF(end.x(), half_y);
}
if (NodeViewCommon::GetFlowOrientation(to_flow) == Qt::Horizontal) {
cp2 = QPointF(half_x, end.y());
} else {
cp2 = QPointF(end.x(), half_y);
}
path.cubicTo(cp1, cp2, end);
path.cubicTo(cp1, cp2, end);
if (!qFuzzyCompare(start.x(), end.x())) {
double continue_x = end.x() - std::cos(angle);
if (!qFuzzyCompare(start.x(), end.x())) {
double continue_x = end.x() - std::cos(angle);
double x1 = start.x();
double x2 = cp1.x();
double x3 = cp2.x();
double x4 = end.x();
double y1 = start.y();
double y2 = cp1.y();
double y3 = cp2.y();
double y4 = end.y();
double x1 = start.x();
double x2 = cp1.x();
double x3 = cp2.x();
double x4 = end.x();
double y1 = start.y();
double y2 = cp1.y();
double y3 = cp2.y();
double y4 = end.y();
if (start.x() >= end.x()) {
std::swap(x1, x4);
std::swap(x2, x3);
std::swap(y1, y4);
std::swap(y2, y3);
}
if (start.x() >= end.x()) {
std::swap(x1, x4);
std::swap(x2, x3);
std::swap(y1, y4);
std::swap(y2, y3);
}
double t = Bezier::CubicXtoT(continue_x, x1, x2, x3, x4);
double y = Bezier::CubicTtoY(y1, y2, y3, y4, t);
double t = Bezier::CubicXtoT(continue_x, x1, x2, x3, x4);
double y = Bezier::CubicTtoY(y1, y2, y3, y4, t);
angle = std::atan2(end.y() - y, end.x() - continue_x);
}
angle = std::atan2(end.y() - y, end.x() - continue_x);
}
} else {
path.lineTo(end);
}
} else {
path.lineTo(end);
}
setPath(mapFromScene(path));
setPath(mapFromScene(path));
}
}
+58 -58
View File
@@ -27,7 +27,8 @@
#include "nodeviewcommon.h"
#include "node/node.h"
namespace olive {
namespace olive
{
class NodeViewItem;
@@ -36,49 +37,47 @@ class NodeViewItem;
*
* A fairly simple line widget use to visualize a connection between two node parameters (a NodeEdge).
*/
class NodeViewEdge : public QGraphicsPathItem
{
class NodeViewEdge : public QGraphicsPathItem {
public:
NodeViewEdge(Node *output, const NodeInput& input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent = nullptr);
NodeViewEdge(Node *output, const NodeInput &input, NodeViewItem *from_item,
NodeViewItem *to_item, QGraphicsItem *parent = nullptr);
NodeViewEdge(QGraphicsItem* parent = nullptr);
NodeViewEdge(QGraphicsItem *parent = nullptr);
virtual ~NodeViewEdge() override;
virtual ~NodeViewEdge() override;
Node *output() const
{
return output_;
}
Node *output() const
{
return output_;
}
const NodeInput& input() const
{
return input_;
}
const NodeInput &input() const
{
return input_;
}
int element() const
{
return element_;
}
int element() const
{
return element_;
}
NodeViewItem* from_item() const
{
return from_item_;
}
NodeViewItem *from_item() const
{
return from_item_;
}
NodeViewItem* to_item() const
{
return to_item_;
}
NodeViewItem *to_item() const
{
return to_item_;
}
void set_from_item(NodeViewItem *i);
void set_from_item(NodeViewItem *i);
void set_to_item(NodeViewItem *i);
void set_to_item(NodeViewItem *i);
void Adjust();
void Adjust();
/**
/**
* @brief Set the connected state of this line
*
* When the edge is not connected, it visually depicts this by coloring the line grey. When an edge is connected or
@@ -88,59 +87,60 @@ public:
* Using SetEdge() automatically sets this to true. Under most circumstances this should be left alone, and only
* be set when an edge is being created/dragged.
*/
void SetConnected(bool c);
void SetConnected(bool c);
bool IsConnected() const
{
return connected_;
}
bool IsConnected() const
{
return connected_;
}
/**
/**
* @brief Set highlighted state
*
* Changes color of edge.
*/
void SetHighlighted(bool e);
void SetHighlighted(bool e);
/**
/**
* @brief Set points to create curve from
*/
void SetPoints(const QPointF& start, const QPointF& end);
void SetPoints(const QPointF &start, const QPointF &end);
/**
/**
* @brief Set whether edges should be drawn as curved or as straight lines
*/
void SetCurved(bool e);
void SetCurved(bool e);
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
private:
void Init();
void Init();
void UpdateCurve();
void UpdateCurve();
Node *output_;
Node *output_;
NodeInput input_;
NodeInput input_;
int element_;
int element_;
NodeViewItem* from_item_;
NodeViewItem *from_item_;
NodeViewItem* to_item_;
NodeViewItem *to_item_;
int edge_width_;
int edge_width_;
bool connected_;
bool connected_;
bool highlighted_;
bool highlighted_;
bool curved_;
QPointF cached_start_;
QPointF cached_end_;
bool curved_;
QPointF cached_start_;
QPointF cached_end_;
};
}
File diff suppressed because it is too large Load Diff
+122 -115
View File
@@ -30,7 +30,8 @@
#include "nodeviewcommon.h"
#include "nodeviewitemconnector.h"
namespace olive {
namespace olive
{
class NodeViewItem;
class NodeViewEdge;
@@ -42,195 +43,201 @@ class NodeViewEdge;
*
* To retrieve the NodeViewItem for a certain Node, use NodeView::NodeToUIObject().
*/
class NodeViewItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
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(node, QString(), -1, context, parent)
{
}
NodeViewItem(Node *node, const QString &input, int element, Node *context,
QGraphicsItem *parent = nullptr);
NodeViewItem(Node *node, Node *context, QGraphicsItem *parent = nullptr)
: NodeViewItem(node, QString(), -1, context, parent)
{
}
virtual ~NodeViewItem() override;
virtual ~NodeViewItem() override;
Node::Position GetNodePositionData() const;
QPointF GetNodePosition() const;
void SetNodePosition(const QPointF& pos);
void SetNodePosition(const Node::Position& pos);
Node::Position GetNodePositionData() const;
QPointF GetNodePosition() const;
void SetNodePosition(const QPointF &pos);
void SetNodePosition(const Node::Position &pos);
QVector<NodeViewEdge*> GetAllEdgesRecursively() const;
QVector<NodeViewEdge *> GetAllEdgesRecursively() const;
/**
/**
* @brief Get currently attached node
*/
Node* GetNode() const
{
return node_;
}
Node *GetNode() const
{
return node_;
}
NodeInput GetInput() const
{
return NodeInput(node_, input_, element_);
}
NodeInput GetInput() const
{
return NodeInput(node_, input_, element_);
}
Node *GetContext() const
{
return context_;
}
Node *GetContext() const
{
return context_;
}
/**
/**
* @brief Get expanded state
*/
bool IsExpanded() const
{
return expanded_;
}
bool IsExpanded() const
{
return expanded_;
}
const QVector<NodeViewEdge*> &edges() const
{
return edges_;
}
const QVector<NodeViewEdge *> &edges() const
{
return edges_;
}
/**
/**
* @brief Set expanded state
*/
void SetExpanded(bool e, bool hide_titlebar = false);
void ToggleExpanded();
void SetExpanded(bool e, bool hide_titlebar = false);
void ToggleExpanded();
QPointF GetInputPoint() const;
QPointF GetOutputPoint() const;
QPointF GetInputPoint() const;
QPointF GetOutputPoint() const;
/**
/**
* @brief Sets the direction nodes are flowing
*/
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
NodeViewCommon::FlowDirection GetFlowDirection() const
{
return flow_dir_;
}
NodeViewCommon::FlowDirection GetFlowDirection() const
{
return flow_dir_;
}
static int DefaultTextPadding();
static int DefaultTextPadding();
static int DefaultItemHeight();
static int DefaultItemHeight();
static int DefaultItemWidth();
static int DefaultItemWidth();
static int DefaultItemBorder();
static int DefaultItemBorder();
static QPointF NodeToScreenPoint(QPointF p, NodeViewCommon::FlowDirection direction);
static QPointF ScreenToNodePoint(QPointF p, NodeViewCommon::FlowDirection direction);
static QPointF NodeToScreenPoint(QPointF p,
NodeViewCommon::FlowDirection direction);
static QPointF ScreenToNodePoint(QPointF p,
NodeViewCommon::FlowDirection direction);
static qreal DefaultItemHorizontalPadding(NodeViewCommon::FlowDirection dir);
static qreal DefaultItemVerticalPadding(NodeViewCommon::FlowDirection dir);
qreal DefaultItemHorizontalPadding() const;
qreal DefaultItemVerticalPadding() const;
static qreal
DefaultItemHorizontalPadding(NodeViewCommon::FlowDirection dir);
static qreal DefaultItemVerticalPadding(NodeViewCommon::FlowDirection dir);
qreal DefaultItemHorizontalPadding() const;
qreal DefaultItemVerticalPadding() const;
void AddEdge(NodeViewEdge* edge);
void RemoveEdge(NodeViewEdge* edge);
void AddEdge(NodeViewEdge *edge);
void RemoveEdge(NodeViewEdge *edge);
bool IsLabelledAsOutputOfContext() const
{
return label_as_output_;
}
bool IsLabelledAsOutputOfContext() const
{
return label_as_output_;
}
void SetLabelAsOutput(bool e);
void SetLabelAsOutput(bool e);
void SetHighlighted(bool e);
void SetHighlighted(bool e);
NodeViewItem *GetItemForInput(NodeInput input);
NodeViewItem *GetItemForInput(NodeInput input);
bool IsOutputItem() const
{
return input_.isEmpty();
}
bool IsOutputItem() const
{
return input_.isEmpty();
}
void ReadjustAllEdges();
void ReadjustAllEdges();
void UpdateFlowDirectionOfInputItem(NodeViewItem *child);
void UpdateFlowDirectionOfInputItem(NodeViewItem *child);
bool CanBeExpanded() const;
bool CanBeExpanded() const;
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change,
const QVariant &value) override;
private:
void UpdateContextRect();
void UpdateContextRect();
void DrawNodeTitle(QPainter *painter, QString text, const QRectF &rect, Qt::Alignment vertical_align, int icon_full_size);
void DrawNodeTitle(QPainter *painter, QString text, const QRectF &rect,
Qt::Alignment vertical_align, int icon_full_size);
int DrawExpandArrow(QPainter *painter);
int DrawExpandArrow(QPainter *painter);
/**
/**
* @brief Internal update function when logical position changes
*/
void UpdateNodePosition();
void UpdateNodePosition();
void UpdateInputConnectorPosition();
void UpdateOutputConnectorPosition();
void UpdateInputConnectorPosition();
void UpdateOutputConnectorPosition();
bool IsInputValid(const QString &input);
bool IsInputValid(const QString &input);
void SetRectSize(int height_units = 1);
void SetRectSize(int height_units = 1);
void UpdateChildrenPositions();
void UpdateChildrenPositions();
int GetLogicalHeightWithChildren() const;
int GetLogicalHeightWithChildren() const;
/**
/**
* @brief Reference to attached Node
*/
Node *node_;
QString input_;
int element_;
Node *node_;
QString input_;
int element_;
Node *context_;
Node *context_;
/**
/**
* @brief Cached list of node inputs
*/
QVector<NodeViewItem*> children_;
QVector<NodeViewItem *> children_;
/// Sizing variables to use when drawing
int node_border_width_;
/// Sizing variables to use when drawing
int node_border_width_;
/**
/**
* @brief Expanded state
*/
bool expanded_;
bool expanded_;
bool highlighted_;
bool highlighted_;
NodeViewCommon::FlowDirection flow_dir_;
NodeViewCommon::FlowDirection flow_dir_;
QVector<NodeViewEdge*> edges_;
QVector<NodeViewEdge *> edges_;
QPointF cached_node_pos_;
QPointF cached_node_pos_;
QRect last_arrow_rect_;
bool arrow_click_;
QRect last_arrow_rect_;
bool arrow_click_;
NodeViewItemConnector *input_connector_;
NodeViewItemConnector *output_connector_;
NodeViewItemConnector *input_connector_;
NodeViewItemConnector *output_connector_;
bool has_connectable_inputs_;
bool has_connectable_inputs_;
bool label_as_output_;
bool label_as_output_;
private slots:
void NodeAppearanceChanged();
void NodeAppearanceChanged();
void RepopulateInputs();
void InputArraySizeChanged(const QString &input);
void RepopulateInputs();
void InputArraySizeChanged(const QString &input);
};
}
+52 -50
View File
@@ -27,73 +27,75 @@
#include "nodeviewitem.h"
namespace olive {
NodeViewItemConnector::NodeViewItemConnector(bool is_output, QGraphicsItem *parent) :
QGraphicsPolygonItem(parent),
output_(is_output)
namespace olive
{
QColor c = qApp->palette().text().color();
setPen(QPen(c, NodeViewItem::DefaultItemBorder()));
setBrush(c);
NodeViewItemConnector::NodeViewItemConnector(bool is_output,
QGraphicsItem *parent)
: QGraphicsPolygonItem(parent)
, output_(is_output)
{
QColor c = qApp->palette().text().color();
setPen(QPen(c, NodeViewItem::DefaultItemBorder()));
setBrush(c);
}
void NodeViewItemConnector::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
QFont f;
QFontMetricsF fm(f);
QFont f;
QFontMetricsF fm(f);
int triangle_sz = fm.height()/2;
int triangle_sz_half = triangle_sz / 2;
int triangle_sz = fm.height() / 2;
int triangle_sz_half = triangle_sz / 2;
QPolygonF p;
p.resize(3);
QPolygonF p;
p.resize(3);
switch (dir) {
case NodeViewCommon::kLeftToRight:
// Triangle pointing right
p[0] = QPointF(0, -triangle_sz_half);
p[1] = QPointF(triangle_sz_half, 0);
p[2] = QPointF(0, triangle_sz_half);
break;
case NodeViewCommon::kTopToBottom:
// Triangle pointing down
p[0] = QPointF(-triangle_sz_half, 0);
p[1] = QPointF(0, triangle_sz_half);
p[2] = QPointF(triangle_sz_half, 0);
break;
case NodeViewCommon::kBottomToTop:
// Triangle pointing up
p[0] = QPointF(-triangle_sz_half, 0);
p[1] = QPointF(0, -triangle_sz_half);
p[2] = QPointF(triangle_sz_half, 0);
break;
case NodeViewCommon::kRightToLeft:
// Triangle pointing left
p[0] = QPointF(0, -triangle_sz_half);
p[1] = QPointF(-triangle_sz_half, 0);
p[2] = QPointF(0, triangle_sz_half);
break;
case NodeViewCommon::kInvalidDirection:
break;
}
switch (dir) {
case NodeViewCommon::kLeftToRight:
// Triangle pointing right
p[0] = QPointF(0, -triangle_sz_half);
p[1] = QPointF(triangle_sz_half, 0);
p[2] = QPointF(0, triangle_sz_half);
break;
case NodeViewCommon::kTopToBottom:
// Triangle pointing down
p[0] = QPointF(-triangle_sz_half, 0);
p[1] = QPointF(0, triangle_sz_half);
p[2] = QPointF(triangle_sz_half, 0);
break;
case NodeViewCommon::kBottomToTop:
// Triangle pointing up
p[0] = QPointF(-triangle_sz_half, 0);
p[1] = QPointF(0, -triangle_sz_half);
p[2] = QPointF(triangle_sz_half, 0);
break;
case NodeViewCommon::kRightToLeft:
// Triangle pointing left
p[0] = QPointF(0, -triangle_sz_half);
p[1] = QPointF(-triangle_sz_half, 0);
p[2] = QPointF(0, triangle_sz_half);
break;
case NodeViewCommon::kInvalidDirection:
break;
}
setPolygon(p);
setPolygon(p);
}
QPainterPath NodeViewItemConnector::shape() const
{
// Yes, we skip QGraphicsPolygonItem because it adds the polygon. QGraphicsItem adds the
// boundingRect which we modify below
return QGraphicsItem::shape(); // clazy:exclude=skipped-base-method
// Yes, we skip QGraphicsPolygonItem because it adds the polygon. QGraphicsItem adds the
// boundingRect which we modify below
return QGraphicsItem::shape(); // clazy:exclude=skipped-base-method
}
QRectF NodeViewItemConnector::boundingRect() const
{
QRectF b = this->polygon().boundingRect();
const int radius = QFontMetrics(QFont()).height()/2;
b.adjust(-radius, -radius, radius, radius);
return b;
QRectF b = this->polygon().boundingRect();
const int radius = QFontMetrics(QFont()).height() / 2;
b.adjust(-radius, -radius, radius, radius);
return b;
}
}
+12 -13
View File
@@ -25,26 +25,25 @@
#include "nodeviewcommon.h"
namespace olive {
class NodeViewItemConnector : public QGraphicsPolygonItem
namespace olive
{
class NodeViewItemConnector : public QGraphicsPolygonItem {
public:
NodeViewItemConnector(bool is_output, QGraphicsItem *parent = nullptr);
NodeViewItemConnector(bool is_output, QGraphicsItem *parent = nullptr);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
bool IsOutput() const
{
return output_;
}
bool IsOutput() const
{
return output_;
}
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;
private:
bool output_;
bool output_;
};
}
+74 -69
View File
@@ -22,134 +22,139 @@
#include <QMouseEvent>
namespace olive {
namespace olive
{
#define super QGraphicsView
NodeViewMiniMap::NodeViewMiniMap(NodeViewScene *scene, QWidget *parent) :
super(parent),
resizing_(false)
NodeViewMiniMap::NodeViewMiniMap(NodeViewScene *scene, QWidget *parent)
: super(parent)
, resizing_(false)
{
connect(scene, &QGraphicsScene::sceneRectChanged, this, &NodeViewMiniMap::SceneChanged);
setScene(scene);
connect(scene, &QGraphicsScene::sceneRectChanged, this,
&NodeViewMiniMap::SceneChanged);
setScene(scene);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setViewportUpdateMode(FullViewportUpdate);
setFrameShape(QFrame::Panel);
setFrameShadow(QFrame::Plain);
setMouseTracking(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setViewportUpdateMode(FullViewportUpdate);
setFrameShape(QFrame::Panel);
setFrameShadow(QFrame::Plain);
setMouseTracking(true);
QMetaObject::invokeMethod(this, &NodeViewMiniMap::SetDefaultSize, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, &NodeViewMiniMap::SetDefaultSize,
Qt::QueuedConnection);
resize_triangle_sz_ = fontMetrics().height() / 2;
resize_triangle_sz_ = fontMetrics().height() / 2;
}
void NodeViewMiniMap::SetViewportRect(const QPolygonF &rect)
{
viewport_rect_ = rect;
viewport_rect_ = rect;
viewport()->update();
viewport()->update();
}
void NodeViewMiniMap::drawForeground(QPainter *painter, const QRectF &rect)
{
super::drawForeground(painter, rect);
super::drawForeground(painter, rect);
QColor viewport_color = palette().text().color();
QColor viewport_color = palette().text().color();
// Draw resize triangle
painter->save();
painter->resetTransform();
// Draw resize triangle
painter->save();
painter->resetTransform();
QPointF triangle[3] = {QPointF(0, 0), QPointF(resize_triangle_sz_, 0), QPointF(0, resize_triangle_sz_)};
painter->setBrush(viewport_color);
painter->setPen(viewport_color);
painter->drawPolygon(triangle, 3);
QPointF triangle[3] = { QPointF(0, 0), QPointF(resize_triangle_sz_, 0),
QPointF(0, resize_triangle_sz_) };
painter->setBrush(viewport_color);
painter->setPen(viewport_color);
painter->drawPolygon(triangle, 3);
painter->restore();
painter->restore();
// Draw viewport rectangle
viewport_color.setAlphaF(0.25);
painter->setBrush(viewport_color);
// Draw viewport rectangle
viewport_color.setAlphaF(0.25);
painter->setBrush(viewport_color);
painter->drawPolygon(viewport_rect_);
painter->drawPolygon(viewport_rect_);
}
void NodeViewMiniMap::resizeEvent(QResizeEvent *event)
{
super::resizeEvent(event);
super::resizeEvent(event);
emit Resized();
emit Resized();
SceneChanged(sceneRect());
SceneChanged(sceneRect());
}
void NodeViewMiniMap::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if (MouseInsideResizeTriangle(event)) {
// Resizing!
resizing_ = true;
resize_anchor_ = QCursor::pos();
} else {
EmitMoveSignal(event);
}
}
if (event->button() == Qt::LeftButton) {
if (MouseInsideResizeTriangle(event)) {
// Resizing!
resizing_ = true;
resize_anchor_ = QCursor::pos();
} else {
EmitMoveSignal(event);
}
}
}
void NodeViewMiniMap::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
if (resizing_) {
QPointF movement = QCursor::pos() - resize_anchor_;
resize(QSize(width() - movement.x(), height() - movement.y()));
resize_anchor_ = QCursor::pos();
} else {
EmitMoveSignal(event);
}
} else {
if (MouseInsideResizeTriangle(event)) {
setCursor(Qt::SizeFDiagCursor);
} else {
unsetCursor();
}
}
if (event->buttons() & Qt::LeftButton) {
if (resizing_) {
QPointF movement = QCursor::pos() - resize_anchor_;
resize(QSize(width() - movement.x(), height() - movement.y()));
resize_anchor_ = QCursor::pos();
} else {
EmitMoveSignal(event);
}
} else {
if (MouseInsideResizeTriangle(event)) {
setCursor(Qt::SizeFDiagCursor);
} else {
unsetCursor();
}
}
}
void NodeViewMiniMap::mouseReleaseEvent(QMouseEvent *event)
{
resizing_ = false;
resizing_ = false;
}
void NodeViewMiniMap::SceneChanged(const QRectF &bounding)
{
double x_scale = double(this->width()) / bounding.width();
double y_scale = double(this->height()) / bounding.height();
double x_scale = double(this->width()) / bounding.width();
double y_scale = double(this->height()) / bounding.height();
double min_scale = qMin(x_scale, y_scale);
double min_scale = qMin(x_scale, y_scale);
QTransform transform;
transform.scale(min_scale, min_scale);
QTransform transform;
transform.scale(min_scale, min_scale);
setTransform(transform);
setTransform(transform);
}
void NodeViewMiniMap::SetDefaultSize()
{
if (parentWidget()) {
resize(parentWidget()->width()/4, parentWidget()->height()/4);
}
if (parentWidget()) {
resize(parentWidget()->width() / 4, parentWidget()->height() / 4);
}
}
bool NodeViewMiniMap::MouseInsideResizeTriangle(QMouseEvent *event)
{
return event->pos().x() <= resize_triangle_sz_ && event->pos().y() <= resize_triangle_sz_;
return event->pos().x() <= resize_triangle_sz_ &&
event->pos().y() <= resize_triangle_sz_;
}
void NodeViewMiniMap::EmitMoveSignal(QMouseEvent *event)
{
emit MoveToScenePoint(mapToScene(event->pos()));
emit MoveToScenePoint(mapToScene(event->pos()));
}
}
+24 -23
View File
@@ -25,50 +25,51 @@
#include "nodeviewscene.h"
namespace olive {
class NodeViewMiniMap : public QGraphicsView
namespace olive
{
Q_OBJECT
class NodeViewMiniMap : public QGraphicsView {
Q_OBJECT
public:
NodeViewMiniMap(NodeViewScene *scene, QWidget *parent = nullptr);
NodeViewMiniMap(NodeViewScene *scene, QWidget *parent = nullptr);
public slots:
void SetViewportRect(const QPolygonF &rect);
void SetViewportRect(const QPolygonF &rect);
signals:
void Resized();
void Resized();
void MoveToScenePoint(const QPointF &pos);
void MoveToScenePoint(const QPointF &pos);
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override{}
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override
{
}
private slots:
void SceneChanged(const QRectF &bounding);
void SceneChanged(const QRectF &bounding);
void SetDefaultSize();
void SetDefaultSize();
private:
bool MouseInsideResizeTriangle(QMouseEvent *event);
bool MouseInsideResizeTriangle(QMouseEvent *event);
void EmitMoveSignal(QMouseEvent *event);
void EmitMoveSignal(QMouseEvent *event);
int resize_triangle_sz_;
int resize_triangle_sz_;
QPolygonF viewport_rect_;
QPolygonF viewport_rect_;
bool resizing_;
QPoint resize_anchor_;
bool resizing_;
QPoint resize_anchor_;
};
}
+45 -44
View File
@@ -25,94 +25,95 @@
#include "nodeviewedge.h"
#include "nodeviewitem.h"
namespace olive {
namespace olive
{
NodeViewScene::NodeViewScene(QObject *parent) :
QGraphicsScene(parent),
direction_(NodeViewCommon::kLeftToRight),
curved_edges_(true)
NodeViewScene::NodeViewScene(QObject *parent)
: QGraphicsScene(parent)
, direction_(NodeViewCommon::kLeftToRight)
, curved_edges_(true)
{
}
void NodeViewScene::SetFlowDirection(NodeViewCommon::FlowDirection direction)
{
direction_ = direction;
direction_ = direction;
foreach (NodeViewContext *ctx, context_map_) {
ctx->SetFlowDirection(direction_);
}
foreach (NodeViewContext *ctx, context_map_) {
ctx->SetFlowDirection(direction_);
}
}
void NodeViewScene::SelectAll()
{
foreach (QGraphicsItem* i, items()) {
i->setSelected(true);
}
foreach (QGraphicsItem *i, items()) {
i->setSelected(true);
}
}
void NodeViewScene::DeselectAll()
{
foreach (QGraphicsItem* i, items()) {
i->setSelected(false);
}
foreach (QGraphicsItem *i, items()) {
i->setSelected(false);
}
}
QVector<NodeViewItem *> NodeViewScene::GetSelectedItems() const
{
QVector<NodeViewItem *> items;
QVector<NodeViewItem *> items;
foreach (NodeViewContext *ctx, context_map_) {
items.append(ctx->GetSelectedItems());
}
foreach (NodeViewContext *ctx, context_map_) {
items.append(ctx->GetSelectedItems());
}
return items;
return items;
}
NodeViewContext *NodeViewScene::AddContext(Node *node)
{
NodeViewContext *context_item = context_map_.value(node);
NodeViewContext *context_item = context_map_.value(node);
if (!context_item) {
context_item = new NodeViewContext(node);
if (!context_item) {
context_item = new NodeViewContext(node);
context_item->SetFlowDirection(GetFlowDirection());
context_item->SetCurvedEdges(GetEdgesAreCurved());
context_item->SetFlowDirection(GetFlowDirection());
context_item->SetCurvedEdges(GetEdgesAreCurved());
QPointF pos(0, 0);
QRectF item_rect = context_item->rect();
while (!items(item_rect).isEmpty()) {
pos.setY(pos.y() + item_rect.height());
item_rect = context_item->rect().translated(pos);
}
context_item->setPos(pos);
QPointF pos(0, 0);
QRectF item_rect = context_item->rect();
while (!items(item_rect).isEmpty()) {
pos.setY(pos.y() + item_rect.height());
item_rect = context_item->rect().translated(pos);
}
context_item->setPos(pos);
addItem(context_item);
addItem(context_item);
context_map_.insert(node, context_item);
}
context_map_.insert(node, context_item);
}
return context_item;
return context_item;
}
void NodeViewScene::RemoveContext(Node *node)
{
delete context_map_.take(node);
delete context_map_.take(node);
}
Qt::Orientation NodeViewScene::GetFlowOrientation() const
{
return NodeViewCommon::GetFlowOrientation(direction_);
return NodeViewCommon::GetFlowOrientation(direction_);
}
void NodeViewScene::SetEdgesAreCurved(bool curved)
{
if (curved_edges_ != curved) {
curved_edges_ = curved;
if (curved_edges_ != curved) {
curved_edges_ = curved;
foreach (NodeViewContext *ctx, context_map_) {
ctx->SetCurvedEdges(curved_edges_);
}
}
foreach (NodeViewContext *ctx, context_map_) {
ctx->SetCurvedEdges(curved_edges_);
}
}
}
}
+30 -31
View File
@@ -30,56 +30,55 @@
#include "nodeviewitem.h"
#include "undo/undostack.h"
namespace olive {
class NodeViewScene : public QGraphicsScene
namespace olive
{
Q_OBJECT
class NodeViewScene : public QGraphicsScene {
Q_OBJECT
public:
NodeViewScene(QObject *parent = nullptr);
NodeViewScene(QObject *parent = nullptr);
void SelectAll();
void DeselectAll();
void SelectAll();
void DeselectAll();
QVector<NodeViewItem*> GetSelectedItems() const;
QVector<NodeViewItem *> GetSelectedItems() const;
const QHash<Node*, NodeViewContext*> &context_map() const
{
return context_map_;
}
const QHash<Node *, NodeViewContext *> &context_map() const
{
return context_map_;
}
Qt::Orientation GetFlowOrientation() const;
Qt::Orientation GetFlowOrientation() const;
NodeViewCommon::FlowDirection GetFlowDirection() const
{
return direction_;
}
NodeViewCommon::FlowDirection GetFlowDirection() const
{
return direction_;
}
void SetFlowDirection(NodeViewCommon::FlowDirection direction);
void SetFlowDirection(NodeViewCommon::FlowDirection direction);
bool GetEdgesAreCurved() const
{
return curved_edges_;
}
bool GetEdgesAreCurved() const
{
return curved_edges_;
}
public slots:
NodeViewContext *AddContext(Node *node);
void RemoveContext(Node *node);
NodeViewContext *AddContext(Node *node);
void RemoveContext(Node *node);
/**
/**
* @brief Set whether edges in this scene should be curved or not
*/
void SetEdgesAreCurved(bool curved);
void SetEdgesAreCurved(bool curved);
private:
QHash<Node*, NodeViewContext*> context_map_;
QHash<Node *, NodeViewContext *> context_map_;
Project* graph_;
Project *graph_;
NodeViewCommon::FlowDirection direction_;
bool curved_edges_;
NodeViewCommon::FlowDirection direction_;
bool curved_edges_;
};
}
+28 -25
View File
@@ -5,51 +5,54 @@
#include "ui/icons/icons.h"
namespace olive {
namespace olive
{
#define super QWidget
NodeViewToolBar::NodeViewToolBar(QWidget *parent) :
QWidget(parent)
NodeViewToolBar::NodeViewToolBar(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
add_node_btn_ = new QPushButton();
connect(add_node_btn_, &QPushButton::clicked, this, &NodeViewToolBar::AddNodeClicked);
layout->addWidget(add_node_btn_);
add_node_btn_ = new QPushButton();
connect(add_node_btn_, &QPushButton::clicked, this,
&NodeViewToolBar::AddNodeClicked);
layout->addWidget(add_node_btn_);
minimap_btn_ = new QPushButton();
minimap_btn_->setCheckable(true);
connect(minimap_btn_, &QPushButton::clicked, this, &NodeViewToolBar::MiniMapEnabledToggled);
layout->addWidget(minimap_btn_);
minimap_btn_ = new QPushButton();
minimap_btn_->setCheckable(true);
connect(minimap_btn_, &QPushButton::clicked, this,
&NodeViewToolBar::MiniMapEnabledToggled);
layout->addWidget(minimap_btn_);
layout->addStretch();
layout->addStretch();
Retranslate();
UpdateIcons();
Retranslate();
UpdateIcons();
}
void NodeViewToolBar::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
Retranslate();
} else if (e->type() == QEvent::StyleChange) {
UpdateIcons();
}
super::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
Retranslate();
} else if (e->type() == QEvent::StyleChange) {
UpdateIcons();
}
super::changeEvent(e);
}
void NodeViewToolBar::Retranslate()
{
add_node_btn_->setToolTip(tr("Add Node"));
minimap_btn_->setToolTip(tr("Toggle Mini-Map"));
add_node_btn_->setToolTip(tr("Add Node"));
minimap_btn_->setToolTip(tr("Toggle Mini-Map"));
}
void NodeViewToolBar::UpdateIcons()
{
add_node_btn_->setIcon(icon::Add);
minimap_btn_->setIcon(icon::MiniMap);
add_node_btn_->setIcon(icon::Add);
minimap_btn_->setIcon(icon::MiniMap);
}
}
+16 -17
View File
@@ -4,37 +4,36 @@
#include <QPushButton>
#include <QWidget>
namespace olive {
class NodeViewToolBar : public QWidget
namespace olive
{
Q_OBJECT
class NodeViewToolBar : public QWidget {
Q_OBJECT
public:
NodeViewToolBar(QWidget *parent = nullptr);
NodeViewToolBar(QWidget *parent = nullptr);
public slots:
void SetMiniMapEnabled(bool e)
{
minimap_btn_->setChecked(e);
}
void SetMiniMapEnabled(bool e)
{
minimap_btn_->setChecked(e);
}
signals:
void AddNodeClicked();
void AddNodeClicked();
void MiniMapEnabledToggled(bool e);
void MiniMapEnabledToggled(bool e);
protected:
virtual void changeEvent(QEvent *e) override;
virtual void changeEvent(QEvent *e) override;
private:
void Retranslate();
void Retranslate();
void UpdateIcons();
void UpdateIcons();
QPushButton *add_node_btn_;
QPushButton *minimap_btn_;
QPushButton *add_node_btn_;
QPushButton *minimap_btn_;
};
}
+21 -18
View File
@@ -22,30 +22,33 @@
#include <QVBoxLayout>
namespace olive {
NodeWidget::NodeWidget(QWidget *parent) :
QWidget(parent)
namespace olive
{
QVBoxLayout *outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(0, 0, 0, 0);
toolbar_ = new NodeViewToolBar();
outer_layout->addWidget(toolbar_);
NodeWidget::NodeWidget(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *outer_layout = new QVBoxLayout(this);
outer_layout->setContentsMargins(0, 0, 0, 0);
// Create NodeView widget
node_view_ = new NodeView(this);
outer_layout->addWidget(node_view_);
toolbar_ = new NodeViewToolBar();
outer_layout->addWidget(toolbar_);
// Connect toolbar to NodeView
connect(toolbar_, &NodeViewToolBar::MiniMapEnabledToggled, node_view_, &NodeView::SetMiniMapEnabled);
connect(toolbar_, &NodeViewToolBar::AddNodeClicked, node_view_, &NodeView::ShowAddMenu);
// Create NodeView widget
node_view_ = new NodeView(this);
outer_layout->addWidget(node_view_);
// Set defaults
toolbar_->SetMiniMapEnabled(true);
node_view_->SetMiniMapEnabled(true);
// Connect toolbar to NodeView
connect(toolbar_, &NodeViewToolBar::MiniMapEnabledToggled, node_view_,
&NodeView::SetMiniMapEnabled);
connect(toolbar_, &NodeViewToolBar::AddNodeClicked, node_view_,
&NodeView::ShowAddMenu);
setSizePolicy(node_view_->sizePolicy());
// Set defaults
toolbar_->SetMiniMapEnabled(true);
node_view_->SetMiniMapEnabled(true);
setSizePolicy(node_view_->sizePolicy());
}
}
+16 -17
View File
@@ -26,30 +26,29 @@
#include "nodeview.h"
#include "nodeviewtoolbar.h"
namespace olive {
class NodeWidget : public QWidget
namespace olive
{
Q_OBJECT
class NodeWidget : public QWidget {
Q_OBJECT
public:
NodeWidget(QWidget *parent = nullptr);
NodeWidget(QWidget *parent = nullptr);
NodeView *view() const
{
return node_view_;
}
NodeView *view() const
{
return node_view_;
}
void SetContexts(const QVector<Node*> &nodes)
{
node_view_->SetContexts(nodes);
toolbar_->setEnabled(!nodes.isEmpty());
}
void SetContexts(const QVector<Node *> &nodes)
{
node_view_->SetContexts(nodes);
toolbar_->setEnabled(!nodes.isEmpty());
}
private:
NodeView *node_view_;
NodeViewToolBar *toolbar_;
NodeView *node_view_;
NodeViewToolBar *toolbar_;
};
}