diff --git a/src/DynamoCore/Graph/Annotations/AnnotationModel.cs b/src/DynamoCore/Graph/Annotations/AnnotationModel.cs
index eed05a32232..eb01b40f7cc 100644
--- a/src/DynamoCore/Graph/Annotations/AnnotationModel.cs
+++ b/src/DynamoCore/Graph/Annotations/AnnotationModel.cs
@@ -26,6 +26,11 @@ public class AnnotationModel : ModelBase
double lastExpandedWidth = 0;
+ ///
+ /// The default height of the group's content area when collapsed.
+ ///
+ public const double CollapsedContentHeight = 82;
+
#region Properties
///
@@ -65,16 +70,13 @@ public class AnnotationModel : ModelBase
///
public override double Width
{
- get
- {
- return width;
- }
+ get => width;
set
{
if (width == value) return;
width = value;
- RaisePropertyChanged("Width");
+ RaisePropertyChanged(nameof(Width));
}
}
@@ -85,16 +87,46 @@ public override double Width
///
public override double Height
{
- get
- {
- return height;
- }
+ get => height;
set
{
if (height == value) return;
height = value;
- RaisePropertyChanged("Height");
+ RaisePropertyChanged(nameof(Height));
+ }
+ }
+
+ private double minWidthOnCollapsed;
+ ///
+ /// Gets or sets the minimum width of the group when it is collapsed.
+ /// This value equals the combined width of the group's proxy input and output ports.
+ ///
+ public double MinWidthOnCollapsed
+ {
+ get => minWidthOnCollapsed;
+ set
+ {
+ if (minWidthOnCollapsed == value) return;
+ minWidthOnCollapsed = value;
+ }
+ }
+
+ private double minCollapsedPortAreaHeight;
+ ///
+ /// Gets or sets the minimum height of the port area when the group is collapsed.
+ /// Used to calculate the total height of the collapsed group based on proxy ports
+ ///
+ public double MinCollapsedPortAreaHeight
+ {
+ get => minCollapsedPortAreaHeight;
+ set
+ {
+ if (minCollapsedPortAreaHeight != value)
+ {
+ minCollapsedPortAreaHeight = value;
+ RaisePropertyChanged(nameof(MinCollapsedPortAreaHeight));
+ }
}
}
@@ -339,7 +371,7 @@ public NodeModel PinnedNode
///
public double WidthAdjustment
{
- get { return widthAdjustment; }
+ get => widthAdjustment;
set
{
if (value == widthAdjustment) return;
@@ -348,6 +380,34 @@ public double WidthAdjustment
}
}
+ private double widthAdjustmentCollapsed;
+ ///
+ /// Gets or sets the width adjustment applied when the group is collapsed
+ ///
+ public double WidthAdjustmentCollapsed
+ {
+ get => widthAdjustmentCollapsed;
+ set
+ {
+ if (value == widthAdjustmentCollapsed) return;
+ widthAdjustmentCollapsed = value;
+ }
+ }
+
+ private double widthAdjustmentExpanded;
+ ///
+ /// Gets or sets the width adjustment applied when the group is expanded
+ ///
+ public double WidthAdjustmentExpanded
+ {
+ get => widthAdjustmentExpanded;
+ set
+ {
+ if (value == widthAdjustmentExpanded) return;
+ widthAdjustmentExpanded = value;
+ }
+ }
+
private double heightAdjustment;
///
/// Adjustment margin to be added to the height of the
@@ -356,7 +416,7 @@ public double WidthAdjustment
///
public double HeightAdjustment
{
- get { return heightAdjustment; }
+ get => heightAdjustment;
set
{
if (value == heightAdjustment) return;
@@ -365,17 +425,51 @@ public double HeightAdjustment
}
}
+ private double heightAdjustmentCollapsed;
+ ///
+ /// Gets or sets the height adjustment applied when the group is collapsed
+ ///
+ public double HeightAdjustmentCollapsed
+ {
+ get => heightAdjustmentCollapsed;
+ set
+ {
+ if (value == heightAdjustmentCollapsed) return;
+ heightAdjustmentCollapsed = value;
+ }
+ }
+
+ private double heightAdjustmentExpanded;
+ ///
+ /// Gets or sets the height adjustment applied when the group is expanded
+ ///
+ public double HeightAdjustmentExpanded
+ {
+ get => heightAdjustmentExpanded;
+ set
+ {
+ if (value == heightAdjustmentExpanded) return;
+ heightAdjustmentExpanded = value;
+ }
+ }
+
private bool isExpanded = true;
///
/// Returns whether or not the group is expanded.
///
public bool IsExpanded
{
- get { return isExpanded; }
+ get => isExpanded;
set
{
isExpanded = value;
- UpdateBoundaryFromSelection();
+
+ // When collapsing, we defer this until after the collapsed layout
+ // is computed in CollapsedAnnotationRectangle_IsVisibleChanged.
+ if (isExpanded)
+ {
+ UpdateBoundaryFromSelection();
+ }
UpdateErrorAndWarningIconVisibility();
}
}
@@ -444,6 +538,21 @@ internal set
}
}
+ private bool isResizedWhileCollapsed;
+ ///
+ /// Gets or sets a value indicating whether the group was manually resized while collapsed
+ ///
+ public bool IsResizedWhileCollapsed
+ {
+ get => isResizedWhileCollapsed;
+ set
+ {
+ if (isResizedWhileCollapsed == value) return;
+ isResizedWhileCollapsed = value;
+ RaisePropertyChanged(nameof(IsResizedWhileCollapsed));
+ }
+ }
+
#endregion
///
@@ -577,68 +686,72 @@ internal void UpdateGroupFrozenStatus()
/// Updates the group boundary based on the nodes / notes selection.
///
internal void UpdateBoundaryFromSelection()
- {
+ {
var selectedModelsList = nodes.ToList();
-
- if (selectedModelsList.Any())
+ if (!selectedModelsList.Any())
{
- var groupModels = selectedModelsList.OrderBy(x => x.X).ToList();
+ Width = 0;
+ Height = 0;
+ return;
+ }
- //Shifting x by 10 and y to the height of textblock
- var regionX = groupModels.Min(x => x.X) - ExtendSize;
- //Increase the Y value by 10. This provides the extra space between
- // a model and textbox. Otherwise there will be some overlap
- var regionY = groupModels.Min(y => (y as NoteModel) == null ? (y.Y) : (y.Y - NoteYAdjustment)) -
- ExtendSize - (TextBlockHeight == 0.0 ? MinTextHeight : TextBlockHeight);
+ var groupModels = selectedModelsList.OrderBy(x => x.X).ToList();
- //calculates the distance between the nodes
- var xDistance = groupModels.Max(x => (x.X + x.Width)) - regionX;
- var yDistance = groupModels.Max(y => (y as NoteModel) == null ? (y.Y + y.Height) : (y.Y + y.Height - NoteYAdjustment)) - regionY;
-
- // InitialTop is to store the Y value without the Textblock height
- this.InitialTop = groupModels.Min(y => (y as NoteModel) == null ? (y.Y) : (y.Y - NoteYAdjustment));
+ //Shifting x by 10 and y to the height of textblock
+ var regionX = groupModels.Min(x => x.X) - ExtendSize;
+ //Increase the Y value by 10. This provides the extra space between
+ // a model and textbox. Otherwise there will be some overlap
+ var regionY = groupModels.Min(y => (y as NoteModel) == null ? (y.Y) : (y.Y - NoteYAdjustment)) -
+ ExtendSize - (TextBlockHeight == 0.0 ? MinTextHeight : TextBlockHeight);
+
+ //calculates the distance between the nodes
+ var xDistance = groupModels.Max(x => (x.X + x.Width)) - regionX;
+
+ // InitialTop is to store the Y value without the Textblock height
+ this.InitialTop = groupModels.Min(y => (y as NoteModel) == null ? (y.Y) : (y.Y - NoteYAdjustment));
+ bool positionChanged = regionX != X || regionY != Y;
+ this.X = regionX;
+ this.Y = regionY;
+
+ if (IsExpanded)
+ {
+ var yDistance = groupModels.Max(y => (y as NoteModel) == null ? (y.Y + y.Height) : (y.Y + y.Height - NoteYAdjustment)) - regionY;
var region = new Rect2D
{
X = regionX,
Y = regionY,
- Width = xDistance + ExtendSize + WidthAdjustment,
+ Width = xDistance + ExtendSize + Math.Max(WidthAdjustment, 0),
Height = yDistance + ExtendSize + ExtendYHeight + HeightAdjustment - TextBlockHeight
};
- bool positionChanged = region.X != X || region.Y != Y;
-
- this.X = region.X;
- this.Y = region.Y;
- this.ModelAreaHeight = IsExpanded ? region.Height : ModelAreaHeight;
+ this.ModelAreaHeight = region.Height;
Height = this.ModelAreaHeight + TextBlockHeight;
-
- if (IsExpanded)
- {
- Width = Math.Max(region.Width, TextMaxWidth + ExtendSize);
- lastExpandedWidth = Width;
- }
- else
- {
- //If the annotation is not expanded, then it will remain the same width of the last time it was expanded
- Width = lastExpandedWidth;
- }
+ Width = Math.Max(region.Width, TextMaxWidth + ExtendSize);
//Initial Height is to store the Actual height of the group.
//that is the height should be the initial height without the textblock height.
if (this.InitialHeight <= 0.0)
this.InitialHeight = region.Height;
-
- if (positionChanged)
- {
- RaisePropertyChanged(nameof(Position));
- }
}
else
{
- this.Width = 0;
- this.Height = 0;
+ // Width is based on group content when collapsed
+ Width = Math.Max(
+ (!IsResizedWhileCollapsed ? xDistance : MinWidthOnCollapsed) + ExtendSize + WidthAdjustment,
+ TextMaxWidth + ExtendSize
+ );
+
+ ModelAreaHeight = MinCollapsedPortAreaHeight + CollapsedContentHeight + (IsResizedWhileCollapsed ? HeightAdjustment : 0);
+ Height = TextBlockHeight + ModelAreaHeight;
+ }
+
+ lastExpandedWidth = Width;
+
+ if (positionChanged)
+ {
+ RaisePropertyChanged(nameof(Position));
}
}
@@ -733,6 +846,9 @@ protected override bool UpdateValueCore(UpdateValueParams updateValueParams)
case nameof(IsExpanded):
IsExpanded = Convert.ToBoolean(value);
break;
+ case nameof(IsResizedWhileCollapsed):
+ IsResizedWhileCollapsed = Convert.ToBoolean(value);
+ break;
}
return base.UpdateValueCore(updateValueParams);
@@ -790,6 +906,7 @@ protected override void DeserializeCore(XmlElement element, SaveContext context)
this.InitialHeight = helper.ReadDouble("InitialHeight", DoubleValue);
this.IsSelected = helper.ReadBoolean(nameof(IsSelected), false);
this.IsExpanded = helper.ReadBoolean(nameof(IsExpanded), true);
+ this.IsResizedWhileCollapsed = helper.ReadBoolean(nameof(IsResizedWhileCollapsed), false);
if (IsSelected)
DynamoSelection.Instance.Selection.Add(this);
@@ -835,6 +952,7 @@ protected override void DeserializeCore(XmlElement element, SaveContext context)
RaisePropertyChanged(nameof(AnnotationText));
RaisePropertyChanged(nameof(Nodes));
RaisePropertyChanged(nameof(IsExpanded));
+ RaisePropertyChanged(nameof(IsResizedWhileCollapsed));
this.ReportPosition();
}
diff --git a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs
index 26973696005..953e89b7a48 100644
--- a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs
+++ b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs
@@ -143,6 +143,11 @@ public class ExtraAnnotationViewInfo
public string PinnedNode;
public double WidthAdjustment;
public double HeightAdjustment;
+ public double WidthAdjustmentCollapsed;
+ public double HeightAdjustmentCollapsed;
+ public double WidthAdjustmentExpanded;
+ public double HeightAdjustmentExpanded;
+ public bool IsResizedWhileCollapsed;
// TODO, Determine if these are required
public double Left;
@@ -2703,6 +2708,11 @@ private void LoadAnnotation(ExtraAnnotationViewInfo annotationViewInfo)
annotationModel.GUID = annotationGuidValue;
annotationModel.HeightAdjustment = annotationViewInfo.HeightAdjustment;
annotationModel.WidthAdjustment = annotationViewInfo.WidthAdjustment;
+ annotationModel.HeightAdjustmentCollapsed = annotationViewInfo.HeightAdjustmentCollapsed;
+ annotationModel.WidthAdjustmentCollapsed = annotationViewInfo.WidthAdjustmentCollapsed;
+ annotationModel.HeightAdjustmentExpanded = annotationViewInfo.HeightAdjustmentExpanded;
+ annotationModel.WidthAdjustmentExpanded = annotationViewInfo.WidthAdjustmentExpanded;
+ annotationModel.IsResizedWhileCollapsed = annotationViewInfo.IsResizedWhileCollapsed;
annotationModel.UpdateGroupFrozenStatus();
annotationModel.ModelBaseRequested += annotationModel_GetModelBase;
diff --git a/src/DynamoCore/PublicAPI.Unshipped.txt b/src/DynamoCore/PublicAPI.Unshipped.txt
index f39f4279158..7a53584685a 100644
--- a/src/DynamoCore/PublicAPI.Unshipped.txt
+++ b/src/DynamoCore/PublicAPI.Unshipped.txt
@@ -47,6 +47,7 @@ const Dynamo.Engine.LibraryServices.Categories.Constructors = "Create" -> string
const Dynamo.Engine.LibraryServices.Categories.MemberFunctions = "Actions" -> string
const Dynamo.Engine.LibraryServices.Categories.Operators = "Operators" -> string
const Dynamo.Engine.LibraryServices.Categories.Properties = "Query" -> string
+const Dynamo.Graph.Annotations.AnnotationModel.CollapsedContentHeight = 82 -> double
const Dynamo.Graph.Nodes.BuiltinNodeCategories.ANALYZE_SOLAR = "Analyze.Solar" -> string
const Dynamo.Graph.Nodes.BuiltinNodeCategories.CORE = "Core" -> string
const Dynamo.Graph.Nodes.BuiltinNodeCategories.CORE_EVALUATE = "Core.Evaluate" -> string
@@ -700,6 +701,10 @@ Dynamo.Graph.Annotations.AnnotationModel.GroupStyleId.set -> void
Dynamo.Graph.Annotations.AnnotationModel.HasNestedGroups.get -> bool
Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustment.get -> double
Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustment.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustmentCollapsed.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustmentCollapsed.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustmentExpanded.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.HeightAdjustmentExpanded.set -> void
Dynamo.Graph.Annotations.AnnotationModel.InitialHeight.get -> double
Dynamo.Graph.Annotations.AnnotationModel.InitialHeight.set -> void
Dynamo.Graph.Annotations.AnnotationModel.InitialTop.get -> double
@@ -707,9 +712,15 @@ Dynamo.Graph.Annotations.AnnotationModel.InitialTop.set -> void
Dynamo.Graph.Annotations.AnnotationModel.IsExpanded.get -> bool
Dynamo.Graph.Annotations.AnnotationModel.IsExpanded.set -> void
Dynamo.Graph.Annotations.AnnotationModel.IsFrozen.get -> bool
+Dynamo.Graph.Annotations.AnnotationModel.IsResizedWhileCollapsed.get -> bool
+Dynamo.Graph.Annotations.AnnotationModel.IsResizedWhileCollapsed.set -> void
Dynamo.Graph.Annotations.AnnotationModel.IsVisible.get -> bool
Dynamo.Graph.Annotations.AnnotationModel.loadFromXML.get -> bool
Dynamo.Graph.Annotations.AnnotationModel.loadFromXML.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.MinCollapsedPortAreaHeight.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.MinCollapsedPortAreaHeight.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.MinWidthOnCollapsed.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.MinWidthOnCollapsed.set -> void
Dynamo.Graph.Annotations.AnnotationModel.ModelAreaHeight.get -> double
Dynamo.Graph.Annotations.AnnotationModel.ModelAreaHeight.set -> void
Dynamo.Graph.Annotations.AnnotationModel.ModelBaseRequested -> System.Func
@@ -725,6 +736,10 @@ Dynamo.Graph.Annotations.AnnotationModel.TextMaxWidth.get -> double
Dynamo.Graph.Annotations.AnnotationModel.TextMaxWidth.set -> void
Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustment.get -> double
Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustment.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustmentCollapsed.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustmentCollapsed.set -> void
+Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustmentExpanded.get -> double
+Dynamo.Graph.Annotations.AnnotationModel.WidthAdjustmentExpanded.set -> void
Dynamo.Graph.ConnectorPinModel
Dynamo.Graph.ConnectorPinModel.ConnectorId.get -> System.Guid
Dynamo.Graph.ConnectorPinModel.ConnectorId.set -> void
@@ -1280,10 +1295,13 @@ Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.GroupStyleId -> System.Guid
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.HasNestedGroups -> bool
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Height -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.HeightAdjustment -> double
+Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.HeightAdjustmentCollapsed -> double
+Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.HeightAdjustmentExpanded -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Id -> string
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.InitialHeight -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.InitialTop -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.IsExpanded -> bool
+Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.IsResizedWhileCollapsed -> bool
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Left -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Nodes -> System.Collections.Generic.IEnumerable
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.PinnedNode -> string
@@ -1292,6 +1310,8 @@ Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Title -> string
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Top -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.Width -> double
Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.WidthAdjustment -> double
+Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.WidthAdjustmentCollapsed -> double
+Dynamo.Graph.Workspaces.ExtraAnnotationViewInfo.WidthAdjustmentExpanded -> double
Dynamo.Graph.Workspaces.ExtraConnectorPinInfo
Dynamo.Graph.Workspaces.ExtraConnectorPinInfo.ConnectorGuid -> string
Dynamo.Graph.Workspaces.ExtraConnectorPinInfo.ExtraConnectorPinInfo() -> void
diff --git a/src/DynamoCoreWpf/UI/Converters.cs b/src/DynamoCoreWpf/UI/Converters.cs
index 9100638bd73..763ce4321d8 100644
--- a/src/DynamoCoreWpf/UI/Converters.cs
+++ b/src/DynamoCoreWpf/UI/Converters.cs
@@ -3891,21 +3891,32 @@ public object ConvertBack(object value, Type targetType, object parameter, Syste
///
/// Returns a dark or light color depending on the contrast ration of the color with the background color
- /// Contrast ration should be larger than 4.5:1
+ /// If the control is a Thumb (passed via the converter parameter), the dark color is slightly different
+ /// Contrast ratio should be larger than 4.5:1
/// Contrast calculation algorithm from https://stackoverflow.com/questions/70187918/adapt-given-color-pairs-to-adhere-to-w3c-accessibility-standard-for-epubs/70192373#70192373
+ ///
+ /// Expected values for controlType:
+ /// - "Thumb" : applies alternate dark color for thumb controls
+ /// - null : applies default dark color for annotation text and description
///
public class TextForegroundSaturationColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
+ var controlType = parameter as string;
+
var lightColor = (System.Windows.Media.Color)SharedDictionaryManager.DynamoColorsAndBrushesDictionary["WhiteColor"];
- var darkColor = (System.Windows.Media.Color)SharedDictionaryManager.DynamoColorsAndBrushesDictionary["DarkerGrey"];
+ var darkColorText = (System.Windows.Media.Color)SharedDictionaryManager.DynamoColorsAndBrushesDictionary["DarkerGrey"];
+ var darkColorThumb = (System.Windows.Media.Color)SharedDictionaryManager.DynamoColorsAndBrushesDictionary["MidGrey"];
var backgroundColor = (System.Windows.Media.Color)value;
- var contrastRatio = GetContrastRatio(darkColor, backgroundColor);
+ var contrastRatio = GetContrastRatio(darkColorText, backgroundColor);
- return contrastRatio < 4.5 ? new SolidColorBrush(lightColor) : new SolidColorBrush(darkColor);
+ if (contrastRatio < 4.5)
+ return new SolidColorBrush(lightColor);
+ else
+ return controlType == "Thumb" ? new SolidColorBrush(darkColorThumb) : new SolidColorBrush(darkColorText);
}
public object ConvertBack(object value, Type targetType, object parameter,
diff --git a/src/DynamoCoreWpf/ViewModels/Core/AnnotationViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/AnnotationViewModel.cs
index a908b901d13..da4e4627796 100644
--- a/src/DynamoCoreWpf/ViewModels/Core/AnnotationViewModel.cs
+++ b/src/DynamoCoreWpf/ViewModels/Core/AnnotationViewModel.cs
@@ -702,9 +702,15 @@ private void SetGroupInputPorts()
// owner
newPortViewModels = CreateProxyInPorts(originalInPorts);
- if (newPortViewModels == null) return;
+ // Set the minimum required vertical space to fit the input ports when collapsed
+ if (newPortViewModels == null)
+ {
+ annotationModel.MinCollapsedPortAreaHeight = 0;
+ return;
+ }
+
+ annotationModel.MinCollapsedPortAreaHeight = newPortViewModels.Sum(p => p.Height);
InPorts.AddRange(newPortViewModels);
- return;
}
///
@@ -717,7 +723,7 @@ private void SetGroupOutPorts()
List newPortViewModels;
// we need to store the original ports here
- // as we need thoese later for when we
+ // as we need these later for when we
// need to collapse the groups content
if (this.AnnotationModel.HasNestedGroups)
{
@@ -735,13 +741,19 @@ private void SetGroupOutPorts()
// Create proxies of the ports so we can
// visually add them to the group but they
- // should still reference their NodeModel
- // owner
+ // should still reference their NodeModel owner
newPortViewModels = CreateProxyOutPorts(originalOutPorts);
- if (newPortViewModels == null) return;
+ // If no view models were created, we leave the existing height as is
+ if (newPortViewModels == null)
+ return;
+
+ // Update the collapsed port area height to be the greater of the existing value
+ // and the height needed to render all output ports
+ var outportsHeight = newPortViewModels.Sum(p => p.Height);
+ annotationModel.MinCollapsedPortAreaHeight = Math.Max(annotationModel.MinCollapsedPortAreaHeight, outportsHeight);
+
OutPorts.AddRange(newPortViewModels);
- return;
}
internal IEnumerable GetGroupInPorts(IEnumerable ownerNodes = null)
@@ -976,8 +988,11 @@ private void CollapseConnectors()
}
}
- private void RedrawConnectors()
+ private void RedrawConnectors(bool isCollapsedCheck = false)
{
+ if (isCollapsedCheck && IsExpanded && !annotationModel.IsResizedWhileCollapsed)
+ return;
+
var allNodes = this.Nodes
.OfType()
.SelectMany(x => x.Nodes.OfType())
@@ -1068,6 +1083,7 @@ private void ManageAnnotationMVExpansionAndCollapse()
if (annotationModel.IsExpanded)
{
+ ToggleSizeAdjustmentsForCollapse(false);
this.ShowGroupContents();
}
else
@@ -1075,6 +1091,9 @@ private void ManageAnnotationMVExpansionAndCollapse()
this.SetGroupInputPorts();
this.SetGroupOutPorts();
this.CollapseGroupContents(true);
+ ToggleSizeAdjustmentsForCollapse(true);
+
+ RaisePropertyChanged(nameof(Height));
RaisePropertyChanged(nameof(NodeContentCount));
}
WorkspaceViewModel.HasUnsavedChanges = true;
@@ -1084,6 +1103,35 @@ private void ManageAnnotationMVExpansionAndCollapse()
ReportNodesPosition();
}
+ ///
+ /// Switches the width and height adjustment values when toggling
+ /// between collapsed and expanded group states.
+ ///
+ private void ToggleSizeAdjustmentsForCollapse(bool isCollapsing)
+ {
+ if (isCollapsing)
+ {
+ annotationModel.WidthAdjustmentExpanded = annotationModel.WidthAdjustment;
+ annotationModel.HeightAdjustmentExpanded = annotationModel.HeightAdjustment;
+
+ // Reset to collapsed value so first resize ignores expanded height adjustment
+ annotationModel.HeightAdjustment = annotationModel.HeightAdjustmentCollapsed;
+
+ if (annotationModel.IsResizedWhileCollapsed)
+ {
+ annotationModel.WidthAdjustment = annotationModel.WidthAdjustmentCollapsed;
+ }
+ }
+ else
+ {
+ annotationModel.WidthAdjustmentCollapsed = annotationModel.WidthAdjustment;
+ annotationModel.HeightAdjustmentCollapsed = annotationModel.HeightAdjustment;
+
+ annotationModel.WidthAdjustment = annotationModel.WidthAdjustmentExpanded;
+ annotationModel.HeightAdjustment = annotationModel.HeightAdjustmentExpanded;
+ }
+ }
+
private void UpdateFontSize(object parameter)
{
if (parameter == null) return;
@@ -1199,6 +1247,7 @@ private void model_PropertyChanged(object sender, System.ComponentModel.Property
RaisePropertyChanged("Width");
RaisePropertyChanged(nameof(ModelAreaRect));
UpdateAllGroupedGroups();
+ RedrawConnectors(false);
break;
case "Height":
RaisePropertyChanged("Height");
diff --git a/src/DynamoCoreWpf/ViewModels/Core/Converters/SerializationConverters.cs b/src/DynamoCoreWpf/ViewModels/Core/Converters/SerializationConverters.cs
index 0a44f399147..cb7429a3080 100644
--- a/src/DynamoCoreWpf/ViewModels/Core/Converters/SerializationConverters.cs
+++ b/src/DynamoCoreWpf/ViewModels/Core/Converters/SerializationConverters.cs
@@ -127,10 +127,20 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
writer.WriteValue(anno.AnnotationDescriptionText);
writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.IsExpanded));
writer.WriteValue(anno.IsExpanded);
+ writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.IsResizedWhileCollapsed));
+ writer.WriteValue(anno.IsResizedWhileCollapsed);
writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.WidthAdjustment));
writer.WriteValue(anno.WidthAdjustment);
writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.HeightAdjustment));
writer.WriteValue(anno.HeightAdjustment);
+ writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.WidthAdjustmentCollapsed));
+ writer.WriteValue(anno.WidthAdjustmentCollapsed);
+ writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.HeightAdjustmentCollapsed));
+ writer.WriteValue(anno.HeightAdjustmentCollapsed);
+ writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.WidthAdjustmentExpanded));
+ writer.WriteValue(anno.WidthAdjustmentExpanded);
+ writer.WritePropertyName(nameof(ExtraAnnotationViewInfo.HeightAdjustmentExpanded));
+ writer.WriteValue(anno.HeightAdjustmentExpanded);
writer.WritePropertyName("Nodes");
writer.WriteStartArray();
foreach (var m in anno.Nodes)
diff --git a/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml b/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml
index c783a5e6827..ca51ddb1ac0 100644
--- a/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml
+++ b/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml
@@ -403,6 +403,26 @@
+
+
-
-
-
-
+ MouseLeave="Thumb_MouseLeave" />
@@ -976,7 +980,7 @@
-
+
@@ -1054,6 +1058,7 @@
Background="#EEEEEE"
CornerRadius="{Binding Path=ActualHeight, ElementName=NodeCount}"
Width="{Binding Path=ActualHeight, ElementName=NodeCount}"
+ VerticalAlignment="Bottom"
Height="32"
Margin="10">
+
+
diff --git a/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml.cs b/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml.cs
index 8c5dfbc89d0..ee9e4fd3636 100644
--- a/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml.cs
+++ b/src/DynamoCoreWpf/Views/Core/AnnotationView.xaml.cs
@@ -45,7 +45,6 @@ public AnnotationView()
// Because the size of the CollapsedAnnotationRectangle doesn't necessarily change
// when going from Visible to collapse (and other way around), we need to also listen
// to IsVisibleChanged. Both of these handlers will set the ModelAreaHeight on the ViewModel
- this.CollapsedAnnotationRectangle.SizeChanged += CollapsedAnnotationRectangle_SizeChanged;
this.CollapsedAnnotationRectangle.IsVisibleChanged += CollapsedAnnotationRectangle_IsVisibleChanged;
}
@@ -54,7 +53,6 @@ private void AnnotationView_Unloaded(object sender, RoutedEventArgs e)
Loaded -= AnnotationView_Loaded;
DataContextChanged -= AnnotationView_DataContextChanged;
this.GroupTextBlock.SizeChanged -= GroupTextBlock_SizeChanged;
- this.CollapsedAnnotationRectangle.SizeChanged -= CollapsedAnnotationRectangle_SizeChanged;
this.CollapsedAnnotationRectangle.IsVisibleChanged -= CollapsedAnnotationRectangle_IsVisibleChanged;
}
@@ -375,25 +373,23 @@ private void SetTextHeight()
this.GroupNameControl.DesiredSize.Height;
}
- private void CollapsedAnnotationRectangle_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- SetModelAreaHeight();
- }
-
private void CollapsedAnnotationRectangle_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
- SetModelAreaHeight();
- }
+ var model = ViewModel.AnnotationModel;
+ if (!model.IsExpanded)
+ {
+ // Measure port widths and update min width
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ var (maxInPortWidth, totalInPortHeight) = MeasurePortBounds(inputPortControl);
+ var (maxOutPortWidth, totalOutPortHeight) = MeasurePortBounds(outputPortControl);
- private void SetModelAreaHeight()
- {
- // We only want to change the ModelAreaHeight
- // if the CollapsedAnnotationRectangle is visible,
- // as if its not it will be equal to the height of the
- // contained nodes + the TextBlockHeight
- if (ViewModel is null || !this.CollapsedAnnotationRectangle.IsVisible) return;
- ViewModel.ModelAreaHeight = this.CollapsedAnnotationRectangle.ActualHeight;
- ViewModel.AnnotationModel.UpdateBoundaryFromSelection();
+ model.MinWidthOnCollapsed = maxInPortWidth + maxOutPortWidth + 10;
+ model.MinCollapsedPortAreaHeight = Math.Max(totalInPortHeight, totalOutPortHeight);
+
+ model.UpdateBoundaryFromSelection();
+ }), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
+ }
}
private void contextMenu_Click(object sender, RoutedEventArgs e)
@@ -422,6 +418,30 @@ private void AnnotationRectangleThumb_DragDelta(object sender, System.Windows.Co
}
}
+ private void CollapsedAnnotationRectangleThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+ {
+ // Mark the group as being resized while collapsed
+ ViewModel.AnnotationModel.IsResizedWhileCollapsed = true;
+
+ var model = ViewModel.AnnotationModel;
+ var xAdjust = ViewModel.Width + e.HorizontalChange;
+ var yAdjust = ViewModel.Height + e.VerticalChange;
+
+ double minHeight = model.MinCollapsedPortAreaHeight + model.TextBlockHeight + AnnotationModel.CollapsedContentHeight;
+
+ if (xAdjust >= Math.Max(model.TextMaxWidth, model.MinWidthOnCollapsed))
+ {
+ model.WidthAdjustment += e.HorizontalChange;
+ ViewModel.WorkspaceViewModel.HasUnsavedChanges = true;
+ }
+
+ if (yAdjust >= minHeight)
+ {
+ model.HeightAdjustment += e.VerticalChange;
+ ViewModel.WorkspaceViewModel.HasUnsavedChanges = true;
+ }
+ }
+
private void Thumb_MouseEnter(object sender, MouseEventArgs e)
{
ViewModel.WorkspaceViewModel.CurrentCursor = CursorLibrary.GetCursor(CursorSet.ResizeDiagonal);
@@ -471,5 +491,25 @@ private void GroupStyleAnnotation_SubmenuOpened(object sender, RoutedEventArgs e
// Tracking loading group style items
Logging.Analytics.TrackEvent(Actions.Load, Categories.GroupStyleOperations, nameof(GroupStyleItem) + "s");
}
+
+ private (double maxWidth, double totalHeight) MeasurePortBounds(ItemsControl portControl)
+ {
+ double maxWidth = 0;
+ double totalHeight = 0;
+
+ foreach (var item in portControl.Items)
+ {
+ if (portControl.ItemContainerGenerator.ContainerFromItem(item) is FrameworkElement container && container.IsVisible)
+ {
+ container.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
+ var size = container.DesiredSize;
+
+ maxWidth = Math.Max(maxWidth, size.Width);
+ totalHeight += size.Height;
+ }
+ }
+
+ return (maxWidth, totalHeight);
+ }
}
}