From 0cafbb25942dcfd1e2835f3409cd439fb2ad992e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 10 Oct 2020 19:46:08 +1100 Subject: [PATCH] nodeview: minor optimizations and behavior improvements --- app/widget/nodeview/nodeview.cpp | 166 ++++--------------------------- app/widget/nodeview/nodeview.h | 10 +- 2 files changed, 26 insertions(+), 150 deletions(-) diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index c7f18e1af..d3cfdd3b9 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -57,6 +57,10 @@ NodeView::NodeView(QWidget *parent) : scene_.setSceneRect(-1000000, -1000000, 2000000, 2000000); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + select_blocks_internal_timer_.setSingleShot(true); + select_blocks_internal_timer_.setInterval(100); + connect(&select_blocks_internal_timer_, &QTimer::timeout, this, &NodeView::SelectBlocksInternal); } NodeView::~NodeView() @@ -206,7 +210,7 @@ void NodeView::SelectBlocks(const QList &blocks) selected_blocks_.append(blocks); - SelectBlocksInternal(); + QueueSelectBlocksInternal(); } void NodeView::DeselectBlocks(const QList &blocks) @@ -227,7 +231,7 @@ void NodeView::DeselectBlocks(const QList &blocks) selected_blocks_.removeOne(b); } - SelectBlocksInternal(); + QueueSelectBlocksInternal(); } void NodeView::CopySelected(bool cut) @@ -380,8 +384,8 @@ void NodeView::mouseMoveEvent(QMouseEvent *event) QRect edge_detect_rect(event->pos(), event->pos()); - // FIXME: Hardcoded numbers - edge_detect_rect.adjust(-20, -20, 20, 20); + int edge_detect_radius = fontMetrics().height(); + edge_detect_rect.adjust(-edge_detect_radius, -edge_detect_radius, edge_detect_radius, edge_detect_radius); QList items = this->items(edge_detect_rect); @@ -661,140 +665,6 @@ void NodeView::ContextMenuFilterChanged(QAction *action) } } -void NodeView::PlaceNode(NodeViewItem *n, const QPointF &pos) -{ - QRectF destination_rect = n->rect(); - destination_rect.translate(n->pos()); - - double x_movement = destination_rect.width() * 1.5; - double y_movement = destination_rect.height() * 1.5; - - QList items = scene()->items(destination_rect); - - n->setPos(pos); - - foreach (QGraphicsItem* item, items) { - if (item == n) { - continue; - } - - NodeViewItem* node_item = dynamic_cast(item); - - if (!node_item) { - continue; - } - - qDebug() << "Moving" << node_item->GetNode() << "for" << n->GetNode(); - - QPointF new_pos; - - if (item->pos() == pos) { - qDebug() << "Same pos, need more info"; - - // Item positions are exact, we'll need more information to determine where this item should go - Node* ours = n->GetNode(); - Node* theirs = node_item->GetNode(); - - bool moved = false; - - new_pos = item->pos(); - - // Heuristic to determine whether to move the other item above or below - foreach (NodeEdgePtr our_edge, ours->output()->edges()) { - foreach (NodeEdgePtr their_edge, theirs->output()->edges()) { - if (our_edge->output()->parentNode() == their_edge->output()->parentNode()) { - qDebug() << " They share a node that they output to"; - if (our_edge->input()->index() > their_edge->input()->index()) { - // Their edge should go above ours - qDebug() << " Our edge goes BELOW theirs"; - new_pos.setY(new_pos.y() - y_movement); - } else { - // Our edge should go below ours - qDebug() << " Our edge goes ABOVE theirs"; - new_pos.setY(new_pos.y() + y_movement); - } - - moved = true; - - break; - } - } - } - - // If we find anything, just move at random - if (!moved) { - new_pos.setY(new_pos.y() - y_movement); - } - - } else if (item->pos().x() == pos.x()) { - qDebug() << "Same X, moving vertically"; - - // Move strictly up or down - new_pos = item->pos(); - - if (item->pos().y() < pos.y()) { - // Move further up - new_pos.setY(pos.y() - y_movement); - } else { - // Move further down - new_pos.setY(pos.y() + y_movement); - } - } else if (item->pos().y() == pos.y()) { - qDebug() << "Same Y, moving horizontally"; - - // Move strictly left or right - new_pos = item->pos(); - - if (item->pos().x() < pos.x()) { - // Move further up - new_pos.setX(pos.x() - x_movement); - } else { - // Move further down - new_pos.setX(pos.x() + x_movement); - } - } else { - qDebug() << "Diff pos, pushing in angle"; - - // The item does not have equal X or Y, attempt to push it away from `pos` in the direction it's in - double x_diff = item->pos().x() - pos.x(); - double y_diff = item->pos().y() - pos.y(); - - double slope = y_diff / x_diff; - double y_int = item->pos().y() - slope * item->pos().x(); - - if (qAbs(slope) > 1.0) { - // Vertical difference is greater than horizontal difference, prioritize vertical movement - double desired_y = pos.y(); - - if (item->pos().y() > pos.y()) { - desired_y += y_movement; - } else { - desired_y -= y_movement; - } - - double x = (desired_y - y_int) / slope; - - new_pos = QPointF(x, desired_y); - } else { - // Horizontal difference is greater than vertical difference, prioritize horizontal movement - double desired_x = pos.x(); - - if (item->pos().x() > pos.x()) { - desired_x += x_movement; - } else { - desired_x -= x_movement; - } - - double y = slope * desired_x + y_int; - - new_pos = QPointF(desired_x, y); - } - } - - PlaceNode(node_item, new_pos); - } -} - void NodeView::AttachNodesToCursor(const QList &nodes) { QList items; @@ -859,7 +729,7 @@ void NodeView::UpdateBlockFilter() } bool first = true; - QRectF last_rect; + QPointF last_bottom_right; QList currently_visible; @@ -891,10 +761,13 @@ void NodeView::UpdateBlockFilter() if (first) { first = false; } else { - QPointF desired_anchor_pos = last_rect.bottomRight() + QPointF(0, 2); + QPointF desired_anchor_pos = last_bottom_right + QPointF(0, 2); QPointF necessary_movement = anchor.topRight() - desired_anchor_pos; + // Calculate the bottom right from which we'll anchor the next rect + last_bottom_right = anchor.bottomRight() - necessary_movement; + b->SetPosition(b->GetPosition() - necessary_movement); foreach (Node* d, deps) { d->SetPosition(d->GetPosition() - necessary_movement); @@ -923,9 +796,6 @@ void NodeView::UpdateBlockFilter() // And lastly, add them all to our currently visible list currently_visible.append(deps); - - // Cache this rect so we can calculate other rects - last_rect = anchor; } // Show only edges between those dependencies @@ -950,10 +820,16 @@ void NodeView::DisassociateNode(Node *n, bool remove_from_map) disconnect(n, &Node::destroyed, this, &NodeView::AssociatedNodeDestroyed); } +void NodeView::QueueSelectBlocksInternal() +{ + select_blocks_internal_timer_.stop(); + select_blocks_internal_timer_.start(); +} + void NodeView::SelectBlocksInternal() { // Block scene signals while our selection is changing a lot - scene_.blockSignals(true); + DisconnectSelectionChangedSignal(); if (filter_mode_ == kFilterShowSelectedBlocks) { UpdateBlockFilter(); @@ -970,7 +846,7 @@ void NodeView::SelectBlocksInternal() SelectWithDependencies(nodes); // Stop blocking signals and send a change signal now that all of our processing is done - scene_.blockSignals(false); + ConnectSelectionChangedSignal(); SceneSelectionChangedSlot(); if (!selected_blocks_.isEmpty()) { diff --git a/app/widget/nodeview/nodeview.h b/app/widget/nodeview/nodeview.h index 573aaa79d..5bcf7799e 100644 --- a/app/widget/nodeview/nodeview.h +++ b/app/widget/nodeview/nodeview.h @@ -84,11 +84,7 @@ protected: virtual void wheelEvent(QWheelEvent* event) override; - //virtual void scrollContentsBy(int dx, int dy) override; - private: - void PlaceNode(NodeViewItem* n, const QPointF& pos); - void AttachNodesToCursor(const QList& nodes); void AttachItemsToCursor(const QList& items); @@ -107,7 +103,9 @@ private: void AssociateNodeWithSelectedBlocks(Node* n); void DisassociateNode(Node* n, bool remove_from_map); - void SelectBlocksInternal(); + void QueueSelectBlocksInternal(); + + QTimer select_blocks_internal_timer_; NodeGraph* graph_; @@ -188,6 +186,8 @@ private slots: */ void ContextMenuFilterChanged(QAction* action); + void SelectBlocksInternal(); + }; OLIVE_NAMESPACE_EXIT