Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Node selection for better UX and performance #2605

Merged
merged 19 commits into from
Dec 9, 2024

Conversation

yann-lty
Copy link
Member

@yann-lty yann-lty commented Nov 25, 2024

Description

This PR addresses several issues related to the Node selection management, mostly related to performance and user experience.

Selection performance

selection_before_after

Selection precision

selection_precision_before_after

Features list

  • Address performance degradation as the number of selected nodes increases.
  • Fix node selection precision issues.
  • Implement standard modifier controls (Shift to Add to Selection, Ctrl to Deselect).

Implementation remarks

Selection management

This PR changes the selection management backend to use QItemSelectionModel, instead of manually maintaining an extra QObjectListModel. This allows to rely on Qt to perform selection commands (ClearAndSelect, Deselect, Toggle..).
It also fixes the main issue of having a lot of properties binding to the selection model, which was on top of that emitting its notify signal way to often.

Node context menu

The node context menu was one of the most costly component, due to many direct bindings it had with the selection model.
And it was created at application startup and living until application shutdown, even if unused.
It is now created dynamically only when explicitly required, and evaluate the computability status of selected nodes only on creation.

Selection User Experience

Precision

The previous implementation was performing the box select on the Python side, only considering the default node sizes.
This led to imprecision in the interactive selection, where the varying visual size of the Node was never taken into account.
Now, the selection happens on the QML side.

Modifiers

This PR changes the use of some modifiers to lean towards more standard UX.

  • Shift+Drag: box select add
  • Ctrl+Drag: box deselect

Note: To enable this change, the alternate view panning shortcut (Shift+Drag) has been moved to Alt+Drag.

@yann-lty yann-lty force-pushed the fix/nodeSelectionPerfs branch from dd49c79 to d6a89cb Compare November 25, 2024 18:04
@yann-lty yann-lty changed the title WIP: Refactor Node selection Refactor Node selection Nov 25, 2024
Copy link
Member

@fabiencastan fabiencastan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Notes:

  • The inclusion of InputNode in the selection should not impact the compute/submit option (in the same way that the "Delete Data" does not exist on InputNodes but is allowed on a selection of nodes including InputNodes). On the other hand, one CompatibilityNode included in the selection blocks the launch of a compute/submit as it should be.
  • In some software the selection is live while defining the selection (but not sure if the limited added value is worth regarding the perf impact).

meshroom/ui/qml/GraphEditor/GraphEditor.qml Outdated Show resolved Hide resolved
meshroom/ui/qml/GraphEditor/GraphEditor.qml Outdated Show resolved Hide resolved
meshroom/ui/qml/GraphEditor/GraphEditor.qml Outdated Show resolved Hide resolved
@fabiencastan fabiencastan added this to the Meshroom 2024.1.0 milestone Dec 5, 2024
Implementing this method allows to use QObjectListModel
in combination with other Qt classes that can act on a model
(eg: QSelectionItemModel, QSortFilterProxyModel...).
Forward mouse 'released' and 'clicked' events for giving
more control over node selection management.
- SelectionBox: generic Selection box component.
- DelegateSelectionBox: specialized SelectionBox to select model delegates
  from an instantiator (Repeater, ListView).

Also Introduce a Geom2D helper class to provide missing features for
intersection testing in QML.
Switch selection management backend to a QItemSelectionModel,
while keeping the current 'selectedNodes' API for now.
Use DelegateSectionBox for node selection in the graph, and
rewrite the handling of node selection / displacement.
Add and use an explicit method to remove the currently selected nodes
in a graph.
Avoid having the node context menu always evaluating the current
state of the selected nodes for its own display, by dynamically
creating it on demand with a Loader.
Use callbacks for recomputing/resubmitting actions, instead of
storing state in the UI components.
Delay the loading of the node context menu once the node selection
has been updated, for it to consider the proper selection.
Re-write the computability status of the current node selection
as properties within the node menu component.
Note that this should be further improved to better scale with the size
of the selection, as it requires to traverse the graph for each node.
Avoid to evaluate the computability/submitability status of each
node twice by caching the information when creating the node
context menu.
Remove dynamic tooltip for cut/copy actions that displays all
selected node names:
- This inline textual information is hard to process as a user.
- Avoid binding to and iteration over the selection.
Convenient function to directly work on the current node selection.
Expose `getSelectedNode` that relies on the QItemSelectionModel
for imperative code in QML that still requires to access the
selected node instances.
@yann-lty yann-lty force-pushed the fix/nodeSelectionPerfs branch from d6a89cb to a3268f4 Compare December 6, 2024 09:18
Instead of connecting to onSelectionChanged, use ItemSelectionModel.hasSelection
property, that can be use for direct bindings with the same behavior.
https://doc.qt.io/qt-6/qml-qtqml-models-itemselectionmodel.html#hasSelection-prop
Closer to the standard behavior of the Ctrl modifier key for selection.
@fabiencastan fabiencastan added the feature new feature (proposed as PR or issue planned by dev) label Dec 9, 2024
@fabiencastan fabiencastan changed the title Refactor Node selection Refactor Node selection for better UX and performance Dec 9, 2024
Implement additive selection behavior when selecting downstream
nodes from a node, using Alt+Shift+Click.
@fabiencastan fabiencastan merged commit 2d56016 into develop Dec 9, 2024
3 checks passed
@fabiencastan fabiencastan deleted the fix/nodeSelectionPerfs branch December 9, 2024 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature new feature (proposed as PR or issue planned by dev)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants