4 using System.Diagnostics;
6 using SiliconStudio.Core;
7 using SiliconStudio.Core.Mathematics;
9 namespace SiliconStudio.Paradox.UI.Panels
14 [DebuggerDisplay(
"Canvas - Name={Name}")]
50 element.DependencyProperties.Set(useAbsolutionPositionPropertyKey,
false);
52 InvalidateCanvasMeasure(propertyOwner, propertyKey, propertyOldValue);
58 element.DependencyProperties.Set(useAbsolutionPositionPropertyKey,
true);
60 InvalidateCanvasMeasure(propertyOwner, propertyKey, propertyOldValue);
66 var parentCanvas = element.Parent as
Canvas;
68 if (parentCanvas != null)
69 parentCanvas.InvalidateMeasure();
72 private static void PinOriginValueValidator(ref
Vector3 value)
74 value.X = Math.Min(1, Math.Max(0, value.X));
75 value.Y = Math.Min(1, Math.Max(0, value.Y));
76 value.Z = Math.Min(1, Math.Max(0, value.Z));
79 private static void ValidateRelativeSize(ref
Vector3 value)
81 if (value.X < 0 || value.Y < 0 || value.Z < 0)
82 throw new InvalidOperationException(
"All the components of the a relative size must be positive");
90 foreach (var child
in VisualChildrenCollection)
93 var childAvailableSizeWithMargin = ComputeAvailableSize(child, availableSizeWithoutMargins,
false);
96 var childRelativeSize = child.DependencyProperties.Get(RelativeSizePropertyKey);
97 for (var i = 0; i < 3; i++)
99 if (
float.IsNaN(childRelativeSize[i]))
102 childAvailableSizeWithMargin[i] = childRelativeSize[i] > 0? childRelativeSize[i] * availableSizeWithoutMargins[i]: 0f;
105 child.Measure(childAvailableSizeWithMargin);
109 var desiredSizeWithoutMargin = Vector3.Zero;
110 foreach (var child
in VisualChildrenCollection)
112 if(child.IsCollapsed)
116 var childExtremityCorner = Vector3.Zero;
117 var pinOrigin = child.DependencyProperties.Get(PinOriginPropertyKey);
118 var childRelativeSize = child.DependencyProperties.Get(RelativeSizePropertyKey);
119 var childUseAbsolutionPosition = child.DependencyProperties.Get(useAbsolutionPositionPropertyKey);
120 var childAbsolutePosition = child.DependencyProperties.Get(AbsolutePositionPropertyKey);
121 var childRelativePosition = child.DependencyProperties.Get(RelativePositionPropertyKey);
122 for (var i = 0; i < 3; i++)
124 if (!
float.IsNaN(childRelativeSize[i]))
126 childExtremityCorner[i] = childRelativeSize[i] > 0? child.DesiredSizeWithMargins[i] / childRelativeSize[i]: 0f;
128 else if (childUseAbsolutionPosition && !
float.IsNaN(childAbsolutePosition[i]))
130 childExtremityCorner[i] = childAbsolutePosition[i] + (1f - pinOrigin[i]) * child.DesiredSizeWithMargins[i];
132 else if (!
float.IsNaN(childRelativePosition[i]))
134 if (pinOrigin[i] > 0 && childRelativePosition[i] > 0)
135 childExtremityCorner[i] = pinOrigin[i] * child.DesiredSizeWithMargins[i] / childRelativePosition[i];
136 if (pinOrigin[i] < 1 && childRelativePosition[i] < 1)
137 childExtremityCorner[i] = Math.Max(childExtremityCorner[i], (1 - pinOrigin[i]) * child.DesiredSizeWithMargins[i] / (1 - childRelativePosition[i]));
141 childExtremityCorner[i] = 0;
146 desiredSizeWithoutMargin =
new Vector3(
147 Math.Max(desiredSizeWithoutMargin.X, childExtremityCorner.X),
148 Math.Max(desiredSizeWithoutMargin.Y, childExtremityCorner.Y),
149 Math.Max(desiredSizeWithoutMargin.Z, childExtremityCorner.Z));
152 return desiredSizeWithoutMargin;
158 foreach (var child
in VisualChildrenCollection)
161 var availableSize = ComputeAvailableSize(child, finalSizeWithoutMargins,
true);
162 var childProvidedSize =
new Vector3(
163 Math.Min(availableSize.X, child.DesiredSizeWithMargins.X),
164 Math.Min(availableSize.Y, child.DesiredSizeWithMargins.Y),
165 Math.Min(availableSize.Z, child.DesiredSizeWithMargins.Z));
168 child.Arrange(childProvidedSize, IsCollapsed);
171 var pinOrigin = child.DependencyProperties.Get(PinOriginPropertyKey);
172 var childOrigin = ComputeAbsolutePinPosition(child, ref finalSizeWithoutMargins) - Vector3.Modulate(pinOrigin, child.RenderSize);
175 var childOriginParentCenter = childOrigin - finalSizeWithoutMargins / 2;
178 child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(childOriginParentCenter));
182 return base.ArrangeOverride(finalSizeWithoutMargins);
193 var relativePosition = child.DependencyProperties.Get(RelativePositionPropertyKey);
194 var absolutePosition = child.DependencyProperties.Get(AbsolutePositionPropertyKey);
195 var useAbsolutionPosition = child.DependencyProperties.Get(useAbsolutionPositionPropertyKey);
197 for (var dim = 0; dim < 3; ++dim)
199 if (
float.IsNaN(absolutePosition[dim]) || !useAbsolutionPosition && !float.IsNaN(relativePosition[dim]))
200 absolutePosition[dim] = relativePosition[dim] == 0f ? 0f : relativePosition[dim] * parentSize[dim];
203 return absolutePosition;
216 var pinPosition = ComputeAbsolutePinPosition(child, ref availableSize);
217 var pinOrigin = child.DependencyProperties.Get(PinOriginPropertyKey);
218 var relativeSize = child.DependencyProperties.Get(RelativeSizePropertyKey);
219 var childAvailableSize = Vector3.Zero;
221 for (var dim = 0; dim < 3; dim++)
223 if (!ignoreRelativeSize && !
float.IsNaN(relativeSize[dim]))
225 childAvailableSize[dim] = relativeSize[dim] > 0? relativeSize[dim] * availableSize[dim]: 0f;
227 else if (pinPosition[dim] < 0 || pinPosition[dim] > availableSize[dim])
229 childAvailableSize[dim] = 0;
233 var availableBeforeElement = float.PositiveInfinity;
234 if (pinPosition[dim] >= 0 && pinOrigin[dim] > 0)
235 availableBeforeElement = pinPosition[dim] / pinOrigin[dim];
237 var availableAfterElement = float.PositiveInfinity;
238 if (pinPosition[dim] <= availableSize[dim] && !
float.IsPositiveInfinity(pinPosition[dim]) && pinOrigin[dim] < 1)
239 availableAfterElement = (availableSize[dim] - pinPosition[dim]) / (1f - pinOrigin[dim]);
241 childAvailableSize[dim] = Math.Min(availableBeforeElement, availableAfterElement);
245 return childAvailableSize;
static void InvalidateCanvasMeasure(object propertyOwner, PropertyKey< Vector3 > propertyKey, Vector3 propertyOldValue)
Provides a base class for all the User Interface elements in Paradox applications.
override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins)
When overridden in a derived class, measures the size in layout required for possible child elements ...
Represents a three dimensional mathematical vector.
Vector3 ComputeAbsolutePinPosition(UIElement child, ref Vector3 parentSize)
Compute the child absolute position in the canvas according to parent size and the child layout prope...
Defines an area within which you can position and size child elements with respect to in the Canvas a...
Vector3 ComputeAvailableSize(UIElement child, Vector3 availableSize, bool ignoreRelativeSize)
Compute the space available to the provided child based on size available to the canvas and the child...
override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins)
When overridden in a derived class, positions possible child elements and determines a size for a UIE...
SiliconStudio.Core.Mathematics.Vector3 Vector3
A class that represents a tag propety.
Provides a base class for all Panel elements. Use Panel elements to position and arrange child object...