Skip to content

Commit 0b3b4e8

Browse files
authored
[DYN-8546] Curve Mapper: Add Info bubble (#16166)
1 parent 4b744f1 commit 0b3b4e8

File tree

17 files changed

+130
-16
lines changed

17 files changed

+130
-16
lines changed

doc/distrib/xml/en-US/DSCoreNodes.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DynamoCore/Graph/Nodes/NodeModel.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,19 @@ internal void OnNodeInfoMessagesClearing()
209209
NodeInfoMessagesClearing?.Invoke(this);
210210
}
211211

212+
/// <summary>
213+
/// Event triggered when the node clears only warning messages
214+
/// </summary>
215+
public event Action<NodeModel> NodeWarningMessagesClearing;
216+
217+
/// <summary>
218+
/// Fires on each node that is modified to clear only warning messages, when the graph executes.
219+
/// </summary>
220+
internal void OnNodeWarningMessagesClearing()
221+
{
222+
NodeWarningMessagesClearing?.Invoke(this);
223+
}
224+
212225
internal void OnNodeExecutionBegin()
213226
{
214227
NodeExecutionBegin?.Invoke(this);
@@ -1748,7 +1761,20 @@ public virtual void ClearErrorsAndWarnings()
17481761

17491762
SetNodeStateBasedOnConnectionAndDefaults();
17501763
ClearTransientWarningsAndErrors();
1751-
OnNodeMessagesClearing();
1764+
1765+
// If persistent info is still present, ensure it is reflected in the node state
1766+
if (Infos.Any(x => x.State == ElementState.PersistentInfo))
1767+
{
1768+
// Ensure state reflects PersistentInfo if any such messages remain.
1769+
// Prevents info from being stuck or skipped in future updates.
1770+
// Without this, ClearInfoMessages won't remove them properly.
1771+
State = ElementState.PersistentInfo;
1772+
OnNodeWarningMessagesClearing();
1773+
}
1774+
else
1775+
{
1776+
OnNodeMessagesClearing();
1777+
}
17521778
}
17531779

17541780
/// <summary>
@@ -1767,6 +1793,11 @@ public virtual void ClearInfoMessages()
17671793
{
17681794
infos.RemoveWhere(x => x.State == ElementState.PersistentInfo);
17691795
}
1796+
// If there are still warnings/errors, keep the state unchanged.
1797+
else if (State == ElementState.Warning || State == ElementState.Error)
1798+
{
1799+
infos.RemoveWhere(x => x.State == ElementState.PersistentInfo || x.State == ElementState.Info);
1800+
}
17701801
State = ElementState.Active;
17711802
OnNodeInfoMessagesClearing();
17721803
}
@@ -1912,6 +1943,8 @@ public void Error(string p)
19121943
/// cleared when the node is next evaluated. If false, the info will be cleared on the next evaluation.</param>
19131944
public void Info(string p, bool isPersistent = false)
19141945
{
1946+
var initialState = State;
1947+
19151948
if (isPersistent)
19161949
{
19171950
if (!Infos.Any(x => x.Message.Equals(p) && x.State == ElementState.PersistentInfo))
@@ -1925,6 +1958,16 @@ public void Info(string p, bool isPersistent = false)
19251958
State = ElementState.Info;
19261959
infos.Add(new Info(p, ElementState.Info));
19271960
}
1961+
1962+
// Preserve more critical states such as Warning, PersistentWarning, or Error.
1963+
// We don't want to downgrade the node visually or functionally if it already has
1964+
// more important issues that should take precedence over an informational message.
1965+
if (initialState == ElementState.Warning ||
1966+
initialState == ElementState.PersistentWarning ||
1967+
initialState == ElementState.Error)
1968+
{
1969+
State = initialState;
1970+
}
19281971
}
19291972

19301973
/// <summary>

src/DynamoCore/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ Dynamo.Graph.Nodes.NodeModel.NodeInfos.get -> System.Collections.Generic.List<Dy
10161016
Dynamo.Graph.Nodes.NodeModel.NodeMessagesClearing -> System.Action<Dynamo.Graph.Nodes.NodeModel>
10171017
Dynamo.Graph.Nodes.NodeModel.NodeModel() -> void
10181018
Dynamo.Graph.Nodes.NodeModel.NodeModel(System.Collections.Generic.IEnumerable<Dynamo.Graph.Nodes.PortModel> inPorts, System.Collections.Generic.IEnumerable<Dynamo.Graph.Nodes.PortModel> outPorts) -> void
1019+
Dynamo.Graph.Nodes.NodeModel.NodeWarningMessagesClearing -> System.Action<Dynamo.Graph.Nodes.NodeModel>
10191020
Dynamo.Graph.Nodes.NodeModel.NotifyAstBuildBroken(string p) -> void
10201021
Dynamo.Graph.Nodes.NodeModel.OutPorts.get -> System.Collections.ObjectModel.ObservableCollection<Dynamo.Graph.Nodes.PortModel>
10211022
Dynamo.Graph.Nodes.NodeModel.OutputNodes.get -> System.Collections.Generic.IDictionary<int, System.Collections.Generic.HashSet<System.Tuple<int, Dynamo.Graph.Nodes.NodeModel>>>

src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,7 @@ public NodeViewModel(WorkspaceViewModel workspaceViewModel, NodeModel logic)
942942
}
943943
logic.NodeMessagesClearing += Logic_NodeMessagesClearing;
944944
logic.NodeInfoMessagesClearing += Logic_NodeInfoMessagesClearing;
945+
logic.NodeWarningMessagesClearing += Logic_NodeWarningMessagesClearing;
945946

946947
logic_PropertyChanged(this, new PropertyChangedEventArgs(nameof(IsVisible)));
947948
UpdateBubbleContent();
@@ -1030,6 +1031,36 @@ private void Logic_NodeInfoMessagesClearing(NodeModel obj)
10301031
}
10311032
}
10321033

1034+
/// <summary>
1035+
/// Clears only warning messages from the node's info bubble, preserving any existing info messages.
1036+
/// </summary>
1037+
/// <param name="obj"></param>
1038+
private void Logic_NodeWarningMessagesClearing(NodeModel obj)
1039+
{
1040+
if (ErrorBubble == null) return;
1041+
1042+
var warningsToRemove = ErrorBubble.NodeMessages.Where(x => x.Style == InfoBubbleViewModel.Style.Warning).ToList();
1043+
1044+
if (DynamoViewModel.UIDispatcher != null)
1045+
{
1046+
DynamoViewModel.UIDispatcher.Invoke(() =>
1047+
{
1048+
foreach (var itemToRemove in warningsToRemove)
1049+
{
1050+
ErrorBubble.NodeMessages.Remove(itemToRemove);
1051+
}
1052+
});
1053+
}
1054+
else
1055+
{
1056+
foreach (var itemToRemove in warningsToRemove)
1057+
{
1058+
ErrorBubble.NodeMessages.Remove(itemToRemove);
1059+
}
1060+
}
1061+
return;
1062+
}
1063+
10331064
private void DismissedNodeMessages_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
10341065
{
10351066
if (!(sender is ObservableCollection<InfoBubbleDataPacket> observableCollection)) return;
@@ -1087,7 +1118,8 @@ public override void Dispose()
10871118

10881119
NodeModel.NodeMessagesClearing -= Logic_NodeMessagesClearing;
10891120
NodeModel.NodeInfoMessagesClearing -= Logic_NodeInfoMessagesClearing;
1090-
1121+
NodeModel.NodeWarningMessagesClearing -= Logic_NodeWarningMessagesClearing;
1122+
10911123
if (ErrorBubble != null) DisposeErrorBubble();
10921124

10931125
DynamoSelection.Instance.Selection.CollectionChanged -= SelectionOnCollectionChanged;

src/Libraries/CoreNodeModels/CurveMapperNodeModel.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ public class CurveMapperNodeModel : NodeModel
2626
private double maxLimitY = 1;
2727
private List<Double> pointsCount = new List<double>() { 10.0 };
2828

29-
private List<double> outputValuesY;
30-
private List<double> outputValuesX;
3129
private List<double> renderValuesY;
3230
private List<double> renderValuesX;
3331

@@ -450,10 +448,6 @@ public void GenerateRenderValues()
450448
OnNodeModified();
451449
return;
452450
}
453-
if(!IsResizing)
454-
{
455-
ClearErrorsAndWarnings();
456-
}
457451

458452
object curve = null;
459453

@@ -528,16 +522,18 @@ public void GenerateRenderValues()
528522
break;
529523
}
530524

531-
if (curve is not null)
525+
if (curve is CurveBase dynamicCurve)
532526
{
533-
dynamic dynamicCurve = curve;
534527
RenderValuesX = dynamicCurve.GetCurveXValues(PointsCount, true);
535528
RenderValuesY = dynamicCurve.GetCurveYValues(PointsCount, true);
536529

530+
if (dynamicCurve.IsYOutOfRange)
531+
Info(Properties.Resources.CurveMapperInfoMessage, true);
532+
else
533+
ClearInfoMessages();
534+
537535
if (!IsResizing)
538-
{
539536
OnNodeModified();
540-
}
541537
}
542538
}
543539

src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,4 +748,7 @@ double[]</value>
748748
<data name="ColorPalettePortDataResultToolTip" xml:space="preserve">
749749
<value>Selected color</value>
750750
</data>
751+
<data name="CurveMapperInfoMessage" xml:space="preserve">
752+
<value>When mapping numbers along the curve, some Y values fall outside the specified Y-value domain range.</value>
753+
</data>
751754
</root>

src/Libraries/CoreNodeModels/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,4 +748,7 @@ double[]</value>
748748
<data name="ColorPalettePortDataResultToolTip" xml:space="preserve">
749749
<value>Selected color</value>
750750
</data>
751+
<data name="CurveMapperInfoMessage" xml:space="preserve">
752+
<value>When mapping numbers along the curve, some Y values fall outside the specified Y-value domain range.</value>
753+
</data>
751754
</root>

src/Libraries/CoreNodes/CurveMapper/CurveBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ public abstract class CurveBase
1616
protected double CanvasSize;
1717
protected const double renderIncrementX = 1.0;
1818

19+
private bool isYOutOfRange;
20+
public bool IsYOutOfRange
21+
{
22+
get => isYOutOfRange;
23+
set => isYOutOfRange = value;
24+
}
25+
1926
protected CurveBase(double canvasSize)
2027
{
2128
CanvasSize = canvasSize;

src/Libraries/CoreNodes/CurveMapper/GaussianCurve.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ protected override (List<double> XValues, List<double> YValues) GenerateCurve(Li
6464

6565
if (isRender)
6666
{
67+
IsYOutOfRange = A > CanvasSize;
68+
6769
for (double x = 0; x <= ControlPoint2X; x += renderIncrementX)
6870
{
6971
double y = CanvasSize - ComputeGaussianY(x, A, mu, sigma);

0 commit comments

Comments
 (0)