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

Delay preview creation till it is actually needed. #15823

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,14 @@ internal GeometryScalingViewModel GeoScalingViewModel
}
}

/// <summary>
/// Ensures that a preview control is initialized only when it is
/// absolutely needed. It lives here so that it can be shared by
/// all node views for reduced overhead and better management.
/// </summary>
internal Wpf.Utilities.ActionDebouncer DelayNodePreviewControl
= new Wpf.Utilities.ActionDebouncer(null);

#endregion

public WorkspaceViewModel(WorkspaceModel model, DynamoViewModel dynamoViewModel)
Expand Down Expand Up @@ -721,6 +729,9 @@ public override void Dispose()
InCanvasSearchViewModel?.Dispose();
NodeAutoCompleteSearchViewModel.LuceneUtility?.DisposeAll();
NodeAutoCompleteSearchViewModel?.Dispose();

DelayNodePreviewControl?.Dispose();
DelayNodePreviewControl = null;
}

internal void ZoomInInternal()
Expand Down
40 changes: 28 additions & 12 deletions src/DynamoCoreWpf/Views/Core/NodeView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public partial class NodeView : IViewModelView<NodeViewModel>
/// Old ZIndex of node. It's set, when mouse leaves node.
/// </summary>
private int oldZIndex;

private bool nodeWasClicked;

public NodeView TopControl
Expand Down Expand Up @@ -132,6 +131,21 @@ public NodeView()
Panel.SetZIndex(this, 1);
}

private void DelayPreviewControlAction()
{
if (!IsMouseOver) return;

TryShowPreviewBubbles();
}

private void InitialTryShowPreviewBubble()
{
// Always set old ZIndex to the last value, even if mouse is not over the node.
oldZIndex = NodeViewModel.StaticZIndex;
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like now we are setting the oldZIndex in more places than before.
Is it intentional ? could it cause issues?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, it's exactly the same as before - twice. I only moved that code from the TryShowPreviewBubbles to one level up in the new InitialTryShowPreviewBubble. That's because the nested method will only run conditionally but we need to get the stored Z height every time. Every time the mouse leaves the node control, the Z height gets set again and if we don't first read it, it defaults to -1(or was it 0?) and the node ends up hidden behind everything else.


viewModel.WorkspaceViewModel.DelayNodePreviewControl.Debounce(300, DelayPreviewControlAction);
}

private void OnNodeViewUnloaded(object sender, RoutedEventArgs e)
{
ViewModel.NodeLogic.DispatchedToUI -= NodeLogic_DispatchedToUI;
Expand Down Expand Up @@ -226,10 +240,7 @@ private void NodeModel_ConnectorAdded(Graph.Connectors.ConnectorModel obj)
{
// If the mouse does not leave the node after the connector is added,
// try to show the preview bubble without new mouse enter event.
if (IsMouseOver)
{
Dispatcher.BeginInvoke(new Action(TryShowPreviewBubbles), DispatcherPriority.Loaded);
}
if (IsMouseOver) InitialTryShowPreviewBubble();
}

void NodeLogic_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
Expand Down Expand Up @@ -506,16 +517,13 @@ private void OnNodeViewMouseEnter(object sender, MouseEventArgs e)
// if the node is located under "Hide preview bubbles" menu item and the item is clicked,
// ViewModel.DynamoViewModel.ShowPreviewBubbles will be updated AFTER node mouse enter event occurs
// so, wait while ShowPreviewBubbles binding updates value
Dispatcher.BeginInvoke(new Action(TryShowPreviewBubbles), DispatcherPriority.Loaded);
InitialTryShowPreviewBubble();
}

private void TryShowPreviewBubbles()
{
nodeWasClicked = false;

// Always set old ZIndex to the last value, even if mouse is not over the node.
oldZIndex = NodeViewModel.StaticZIndex;

// There is no need run further.
if (IsPreviewDisabled()) return;

Expand All @@ -541,21 +549,29 @@ private bool IsPreviewDisabled()
// Or preview is disabled for this node
// Or preview shouldn't be shown for some nodes (e.g. number sliders, watch nodes etc.)
// Or node is frozen.
// Or we are panning the view
return !ViewModel.DynamoViewModel.ShowPreviewBubbles ||
ViewModel.WorkspaceViewModel.IsConnecting ||
ViewModel.WorkspaceViewModel.IsSelecting || !previewEnabled ||
!ViewModel.IsPreviewInsetVisible || ViewModel.IsFrozen;
!ViewModel.IsPreviewInsetVisible || ViewModel.IsFrozen ||
ViewModel.WorkspaceViewModel.IsPanning;
}

private void OnNodeViewMouseLeave(object sender, MouseEventArgs e)
{
ViewModel.ZIndex = oldZIndex;
viewModel.WorkspaceViewModel.DelayNodePreviewControl.Cancel();

//Watch nodes doesn't have Preview so we should avoid to use any method/property in PreviewControl class due that Preview is created automatically
// The preview hasn't been instantiated yet, we should stop here
if (previewControl == null) return;

// Watch nodes doesn't have Preview so we should avoid to use any method/property in PreviewControl class due that Preview is created automatically
if (ViewModel.NodeModel != null && ViewModel.NodeModel is CoreNodeModels.Watch) return;

// If mouse in over node/preview control or preview control is pined, we can not hide preview control.
if (IsMouseOver || PreviewControl.IsMouseOver || PreviewControl.StaysOpen || IsMouseInsidePreview(e) ||
// check the field and not the property because that will trigger the instantiation
if (IsMouseOver || previewControl?.IsMouseOver == true ||
previewControl?.StaysOpen == true || IsMouseInsidePreview(e) ||
(Mouse.Captured is DragCanvas && IsMouseInsideNodeOrPreview(e.GetPosition(this)))) return;

// If it's expanded, then first condense it.
Expand Down
10 changes: 10 additions & 0 deletions src/DynamoCoreWpf/Views/Core/WorkspaceView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,11 @@ private void OnCanvasMouseDown(object sender, MouseButtonEventArgs e)
GeoScalingPopup.IsOpen = false;

if(PortContextMenu.IsOpen) DestroyPortContextMenu();

if (!ViewModel.IsPanning && e.MiddleButton == MouseButtonState.Pressed)
{
ViewModel.RequestTogglePanMode();
}
}

/// <summary>
Expand Down Expand Up @@ -846,6 +851,11 @@ private void OnMouseRelease(object sender, MouseButtonEventArgs e)
// (not node, note, not buttons from viewControlPanel such as zoom, pan and so on)
ContextMenuPopup.IsOpen = true;
}

if (ViewModel.IsPanning && e.MiddleButton == MouseButtonState.Released)
{
ViewModel.RequestTogglePanMode();
}
}

private void OnMouseMove(object sender, MouseEventArgs e)
Expand Down
Loading