/// <summary> /// Calculate the right measure spec for this child. /// Does the hard part of MeasureChildren: figuring out the MeasureSpec to /// pass to a particular child. This method figures out the right MeasureSpec /// for one dimension (height or width) of one child view.<br /> /// </summary> /// <param name="parentMeasureSpec">The requirements for this view. MeasureSpecification.</param> /// <param name="padding">The padding of this view for the current dimension and margins, if applicable. LayoutLength.</param> /// <param name="childDimension"> How big the child wants to be in the current dimension. LayoutLength.</param> /// <returns>a MeasureSpec for the child.</returns> public static MeasureSpecification GetChildMeasureSpecification(MeasureSpecification parentMeasureSpec, LayoutLength padding, LayoutLength childDimension) { MeasureSpecification.ModeType specMode = parentMeasureSpec.Mode; MeasureSpecification.ModeType resultMode = MeasureSpecification.ModeType.Unspecified; LayoutLength resultSize = new LayoutLength(Math.Max(0.0f, (parentMeasureSpec.Size.AsDecimal() - padding.AsDecimal()))); // reduce available size by the owners padding switch (specMode) { // Parent has imposed an exact size on us case MeasureSpecification.ModeType.Exactly: { if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent) { // Child wants to be our size. So be it. resultMode = MeasureSpecification.ModeType.Exactly; } else if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.WrapContent) { // Child wants to determine its own size. It can't be // bigger than us. resultMode = MeasureSpecification.ModeType.AtMost; } else { resultSize = childDimension; resultMode = MeasureSpecification.ModeType.Exactly; } break; } // Parent has imposed a maximum size on us case MeasureSpecification.ModeType.AtMost: { if (childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent) { // Child wants to be our size, but our size is not fixed. // Constrain child to not be bigger than us. resultMode = MeasureSpecification.ModeType.AtMost; } else if (childDimension.AsRoundedValue() == LayoutParamPolicies.WrapContent) { // Child wants to determine its own size. It can't be // bigger than us. resultMode = MeasureSpecification.ModeType.AtMost; } else { // Child wants a specific size... so be it resultSize = childDimension + padding; resultMode = MeasureSpecification.ModeType.Exactly; } break; } // Parent asked to see how big we want to be case MeasureSpecification.ModeType.Unspecified: { if ((childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent)) { // Child wants to be our size... find out how big it should be resultMode = MeasureSpecification.ModeType.Unspecified; } else if (childDimension.AsRoundedValue() == (LayoutParamPolicies.WrapContent)) { // Child wants to determine its own size.... find out how big // it should be resultMode = MeasureSpecification.ModeType.Unspecified; } else { // Child wants a specific size... let him have it resultSize = childDimension + padding; resultMode = MeasureSpecification.ModeType.Exactly; } break; } } // switch return(new MeasureSpecification(resultSize, resultMode)); }
/// <summary> /// Calculate the right measure spec for this child. /// Does the hard part of MeasureChildren: figuring out the MeasureSpec to /// pass to a particular child. This method figures out the right MeasureSpec /// for one dimension (height or width) of one child view.<br /> /// </summary> /// <param name="parentMeasureSpec">The requirements for this view. MeasureSpecification.</param> /// <param name="padding">The padding of this view for the current dimension and margins, if applicable. LayoutLength.</param> /// <param name="childDimension"> How big the child wants to be in the current dimension. LayoutLength.</param> /// <returns>a MeasureSpec for the child.</returns> public static MeasureSpecification GetChildMeasureSpecification(MeasureSpecification parentMeasureSpec, LayoutLength padding, LayoutLength childDimension) { MeasureSpecification.ModeType specMode = parentMeasureSpec.Mode; MeasureSpecification.ModeType resultMode = MeasureSpecification.ModeType.Unspecified; // Child only can use parent's size without parent's padding and own margin. LayoutLength resultSize = new LayoutLength(Math.Max(0.0f, parentMeasureSpec.Size.AsDecimal())); switch (specMode) { // Parent has imposed an exact size on us case MeasureSpecification.ModeType.Exactly: { if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent) { // Child wants to be our size. So be it. resultMode = MeasureSpecification.ModeType.Exactly; } else if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.WrapContent) { // Child wants to determine its own size. It can't be // bigger than us. // Don't need parent's size. Size of this child will be determined by its children. resultMode = MeasureSpecification.ModeType.AtMost; } else { // Child has its own size. resultSize = childDimension; resultMode = MeasureSpecification.ModeType.Exactly; } break; } // Parent has imposed a maximum size on us case MeasureSpecification.ModeType.AtMost: { if (childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent) { // Crashed. Cannot calculate. // Child wants to be our size, but our size is not fixed. // Constrain child to not be bigger than us. resultMode = MeasureSpecification.ModeType.AtMost; } else if (childDimension.AsRoundedValue() == LayoutParamPolicies.WrapContent) { // Child wants to determine its own size. It can't be // bigger than us. // Don't need parent's size. Size of this child will be determined by its children. resultMode = MeasureSpecification.ModeType.AtMost; } else { // Child wants a specific size... so be it resultSize = childDimension; resultMode = MeasureSpecification.ModeType.Exactly; } break; } // Parent asked to see how big we want to be case MeasureSpecification.ModeType.Unspecified: { if ((childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent)) { // Child wants to be our size... find out how big it should be // There is no one who has exact size in parent hierarchy. // Cannot calculate. resultMode = MeasureSpecification.ModeType.Unspecified; } else if (childDimension.AsRoundedValue() == (LayoutParamPolicies.WrapContent)) { // Child wants to determine its own size.... find out how big // it should be resultMode = MeasureSpecification.ModeType.Unspecified; } else { // Child wants a specific size... let him have it resultSize = childDimension; resultMode = MeasureSpecification.ModeType.Exactly; } break; } } // switch return(new MeasureSpecification(resultSize, resultMode)); }
private int CalculateVerticalSize(MeasureSpecification.ModeType gridWidthMode, MeasureSpecification.ModeType gridHeightMode, int widthSize, int heightSize) { int availableContentWidth; int availableContentHeight; int desiredChildHeight; int desiredChildWidth; Extents gridLayoutPadding = Padding; var childCount = LayoutChildren.Count; // Use first child's dimensions for layout measurement View childOwner = LayoutChildren[0].Owner; desiredChildHeight = (int)LayoutChildren[0].MeasuredHeight.Size.AsRoundedValue(); desiredChildWidth = (int)LayoutChildren[0].MeasuredWidth.Size.AsRoundedValue(); // If child has a margin then add it to desired size Extents childMargin = LayoutChildren[0].Margin; desiredChildHeight += childMargin.Top + childMargin.Bottom; desiredChildWidth += childMargin.Start + childMargin.End; _totalWidth = desiredChildWidth * _columns; // Include padding for max and min checks _totalWidth += gridLayoutPadding.Start + gridLayoutPadding.End; // Ensure width does not exceed specified at most width or less than mininum width _totalWidth = Math.Max(_totalWidth, (int)SuggestedMinimumWidth.AsRoundedValue()); // widthMode EXACTLY so grid must be the given width if (gridWidthMode == MeasureSpecification.ModeType.Exactly || gridWidthMode == MeasureSpecification.ModeType.AtMost) { // In the case of AT_MOST, widthSize is the max limit. _totalWidth = Math.Min(_totalWidth, widthSize); } availableContentWidth = _totalWidth - gridLayoutPadding.Start - gridLayoutPadding.End; widthSize = _totalWidth; // HEIGHT SPECIFICATIONS // heightMode EXACTLY so grid must be the given height if (gridHeightMode == MeasureSpecification.ModeType.Exactly || gridHeightMode == MeasureSpecification.ModeType.AtMost) { if (childCount > 0) { _totalHeight = gridLayoutPadding.Top + gridLayoutPadding.Bottom; for (int i = 0; i < childCount; i += _columns) { _totalHeight += desiredChildHeight; } // Ensure ourHeight does not exceed specified at most height _totalHeight = Math.Min(_totalHeight, heightSize); _totalHeight = Math.Max(_totalHeight, (int)SuggestedMinimumHeight.AsRoundedValue()); heightSize = _totalHeight; } // Child exists // In the case of AT_MOST, availableContentHeight is the max limit. availableContentHeight = heightSize - gridLayoutPadding.Top - gridLayoutPadding.Bottom; } else { // Grid expands to fit content // If number of columns AUTO_FIT then set to 1 column. _columns = (_columns > 0) ? _columns : 1; // Calculate numbers of rows, round down result as later check for remainder. _rows = childCount / _columns; // If number of cells not cleanly dividable by columns, add another row to house remainder cells. _rows += (childCount % _columns > 0) ? 1 : 0; heightSize = desiredChildHeight * _rows + gridLayoutPadding.Top + gridLayoutPadding.Bottom; availableContentHeight = heightSize - gridLayoutPadding.Top - gridLayoutPadding.Bottom; } // If number of columns not defined DetermineNumberOfColumns(availableContentWidth); // Locations define the start, end,top and bottom of each cell. _locations.CalculateLocations(_columns, availableContentWidth, availableContentHeight, childCount); return(availableContentHeight); }
/// <summary> /// Constructor taking size and mode type. /// </summary> /// <param name="size">size value.</param> /// <param name="mode">mode value.</param> /// <since_tizen> 6 </since_tizen> public MeasureSpecification(LayoutLength size, MeasureSpecification.ModeType mode) { Size = size; Mode = mode; }
private int CalculateHorizontalSize(MeasureSpecification.ModeType gridWidthMode, MeasureSpecification.ModeType gridHeightMode, int widthSize, int heightSize) { int availableContentWidth; int availableContentHeight; int desiredChildHeight; int desiredChildWidth; Extents gridLayoutPadding = Padding; var childCount = LayoutChildren.Count; // Use first child's dimensions for layout measurement View childOwner = LayoutChildren[0].Owner; desiredChildHeight = (int)LayoutChildren[0].MeasuredHeight.Size.AsRoundedValue(); desiredChildWidth = (int)LayoutChildren[0].MeasuredWidth.Size.AsRoundedValue(); // If child has a margin then add it to desired size Extents childMargin = LayoutChildren[0].Margin; desiredChildHeight += childMargin.Top + childMargin.Bottom; desiredChildWidth += childMargin.Start + childMargin.End; _totalHeight = desiredChildHeight * _rows; _totalHeight += gridLayoutPadding.Top + gridLayoutPadding.Bottom; _totalHeight = Math.Max(_totalHeight, (int)SuggestedMinimumHeight.AsRoundedValue()); if (gridHeightMode == MeasureSpecification.ModeType.Exactly || gridHeightMode == MeasureSpecification.ModeType.AtMost) { _totalHeight = Math.Min(_totalHeight, heightSize); } availableContentHeight = _totalHeight - gridLayoutPadding.Top - gridLayoutPadding.Bottom; heightSize = _totalHeight; if (gridWidthMode == MeasureSpecification.ModeType.Exactly || gridWidthMode == MeasureSpecification.ModeType.AtMost) { if (childCount > 0) { _totalWidth = gridLayoutPadding.Start + gridLayoutPadding.End; for (int i = 0; i < childCount; i += _rows) { _totalWidth += desiredChildWidth; } _totalWidth = Math.Min(_totalWidth, widthSize); _totalWidth = Math.Max(_totalWidth, (int)SuggestedMinimumWidth.AsRoundedValue()); widthSize = _totalWidth; } // Child exists // In the case of AT_MOST, availableContentHeight is the max limit. availableContentWidth = widthSize - gridLayoutPadding.Start - gridLayoutPadding.End; } else { _rows = (_rows > 0) ? _rows : 1; _columns = childCount / _rows; _columns += (childCount % _rows > 0) ? 1 : 0; widthSize = desiredChildWidth * _columns + gridLayoutPadding.Start + gridLayoutPadding.End; availableContentWidth = widthSize - gridLayoutPadding.Start - gridLayoutPadding.End; } // If number of rows not defined DetermineNumberOfRows(availableContentHeight); _locations.CalculateLocationsRow(_rows, availableContentWidth, availableContentHeight, childCount); return(availableContentWidth); }
// Starts of the actual measuring and layouting from the given root node. // Can be called from multiple starting roots but in series. void MeasureAndLayout(View root) { if (root != null) { // Get parent MeasureSpecification, this could be the Window or View with an exact size. Container parentNode = root.GetParent(); Size2D rootSize; Position2D rootPosition = root.Position2D; View parentView = parentNode as View; if (parentView != null) { // Get parent View's Size. If using Legacy size negotiation then should have been set already. rootSize = new Size2D(parentView.Size2D.Width, parentView.Size2D.Height); } else { // Parent not a View so assume it's a Layer which is the size of the window. rootSize = new Size2D(_window.Size.Width, _window.Size.Height); } // Determine measure specification for root. // The root layout policy could be an exact size, be match parent or wrap children. // If wrap children then at most it can be the root parent size. // If match parent then should be root parent size. // If exact then should be that size limited by the root parent size. LayoutLength width = new LayoutLength(rootSize.Width); LayoutLength height = new LayoutLength(rootSize.Height); MeasureSpecification.ModeType widthMode = MeasureSpecification.ModeType.Unspecified; MeasureSpecification.ModeType heightMode = MeasureSpecification.ModeType.Unspecified; if (root.WidthSpecification >= 0) { // exact size provided so match width exactly width = new LayoutLength(root.WidthSpecification); widthMode = MeasureSpecification.ModeType.Exactly; } else if (root.WidthSpecification == LayoutParamPolicies.MatchParent) { widthMode = MeasureSpecification.ModeType.Exactly; } if (root.HeightSpecification >= 0) { // exact size provided so match height exactly height = new LayoutLength(root.HeightSpecification); heightMode = MeasureSpecification.ModeType.Exactly; } else if (root.HeightSpecification == LayoutParamPolicies.MatchParent) { heightMode = MeasureSpecification.ModeType.Exactly; } MeasureSpecification parentWidthSpecification = new MeasureSpecification(width, widthMode); MeasureSpecification parentHeightSpecification = new MeasureSpecification(height, heightMode); // Start at root with it's parent's widthSpecification and heightSpecification MeasureHierarchy(root, parentWidthSpecification, parentHeightSpecification); // Start at root which was just measured. PerformLayout(root, new LayoutLength(rootPosition.X), new LayoutLength(rootPosition.Y), new LayoutLength(rootPosition.X) + root.Layout.MeasuredWidth.Size, new LayoutLength(rootPosition.Y) + root.Layout.MeasuredHeight.Size); bool readyToPlay = SetupCoreAnimation(); if (readyToPlay && OverrideCoreAnimation == false) { PlayAnimation(); } } }
internal bool NeedsLayout(float widthSize, float heightSize, MeasureSpecification.ModeType widthMode, MeasureSpecification.ModeType heightMode) { if (LayoutRequested) { return(true); } // Check if relayouting is required. bool specChanged = (widthSize != oldWidthMeasureSpec.Size.AsDecimal()) || (widthMode != oldWidthMeasureSpec.Mode) || (heightSize != oldHeightMeasureSpec.Size.AsDecimal()) || (heightMode != oldHeightMeasureSpec.Mode); bool isSpecExactly = (widthMode == MeasureSpecification.ModeType.Exactly) && (heightMode == MeasureSpecification.ModeType.Exactly); bool matchesSpecSize = (MeasuredWidth.Size.AsDecimal() == widthSize) && (MeasuredHeight.Size.AsDecimal() == heightSize); bool needsLayout = specChanged && (!isSpecExactly || !matchesSpecSize); return(needsLayout); }
public void SetMode(MeasureSpecification.ModeType mode) { Mode = mode; }
private MeasureSpecification CreateMeasureSpecification(float size, MeasureSpecification.ModeType mode) { return(new MeasureSpecification(new LayoutLength(size), mode)); }