protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (this.view == null || this.view.Element == null) { base.SetMeasuredDimension(widthMeasureSpec, heightMeasureSpec); return; } XForms.SizeRequest measure = this.view.Element.Measure(this.initialWidth, double.PositiveInfinity, XForms.MeasureFlags.IncludeMargins); int height = (int)Context.ToPixels(this.fastCell.Height > 0 ? this.fastCell.Height : measure.Request.Height); this.SetMeasuredDimension((int)Context.ToPixels(this.initialWidth), height); }
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint) { if (!InternalChildren.Any()) { return(new SizeRequest(new Size(0, 0))); } MeasureGrid(widthConstraint, heightConstraint, true); double columnWidthSum = 0; double nonStarColumnWidthSum = 0; for (var index = 0; index < _columns.Count; index++) { ColumnDefinition c = _columns[index]; columnWidthSum += c.ActualWidth; if (!c.Width.IsStar) { nonStarColumnWidthSum += c.ActualWidth; } } double rowHeightSum = 0; double nonStarRowHeightSum = 0; for (var index = 0; index < _rows.Count; index++) { RowDefinition r = _rows[index]; rowHeightSum += r.ActualHeight; if (!r.Height.IsStar) { nonStarRowHeightSum += r.ActualHeight; } } var request = new Size(columnWidthSum + (_columns.Count - 1) * ColumnSpacing, rowHeightSum + (_rows.Count - 1) * RowSpacing); var minimum = new Size(nonStarColumnWidthSum + (_columns.Count - 1) * ColumnSpacing, nonStarRowHeightSum + (_rows.Count - 1) * RowSpacing); var result = new SizeRequest(request, minimum); return(result); }
void ExpandLastAutoRowIfNeeded(double height, bool expandToRequest) { for (var index = 0; index < InternalChildren.Count; index++) { Element element = InternalChildren[index]; var child = (View)element; if (!child.IsVisible) { continue; } RowDefinition row = GetLastAutoRow(child); if (row == null) { continue; } double assignedHeight = GetAssignedRowHeight(child); var unassignedHeight = GetUnassignedHeight(height); double h = double.IsPositiveInfinity(height) ? double.PositiveInfinity : assignedHeight + unassignedHeight; var acw = GetAssignedColumnWidth(child); SizeRequest sizeRequest = child.Measure(acw, h, MeasureFlags.IncludeMargins); double requiredHeight = expandToRequest ? sizeRequest.Request.Height : sizeRequest.Request.Height <= h ? sizeRequest.Request.Height : sizeRequest.Minimum.Height; double deltaHeight = requiredHeight - assignedHeight - (GetRowSpan(child) - 1) * RowSpacing; if (deltaHeight > 0) { row.ActualHeight += deltaHeight; } } }
double MeasureStarredRows() { double starRowHeight; for (var iteration = 0; iteration < 2; iteration++) { for (var rowspan = 1; rowspan <= _rows.Count; rowspan++) { for (var i = 0; i < _rows.Count; i++) { RowDefinition row = _rows[i]; if (!row.Height.IsStar) { continue; } if (row.ActualHeight >= 0) // if Actual is already set (by a smaller span), skip till pass 3 { continue; } double actualHeight = row.ActualHeight; double minimumHeight = row.MinimumHeight; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetRowSpan(child) != rowspan || !IsInRow(child, i) || NumberOfUnsetRowHeight(child) > 1) { continue; } double assignedHeight = GetAssignedRowHeight(child); double assignedWidth = GetAssignedColumnWidth(child); SizeRequest sizeRequest = child.Measure(assignedWidth, double.PositiveInfinity, MeasureFlags.IncludeMargins); actualHeight = Math.Max(actualHeight, sizeRequest.Request.Height - assignedHeight - RowSpacing * (GetRowSpan(child) - 1)); minimumHeight = Math.Max(minimumHeight, sizeRequest.Minimum.Height - assignedHeight - RowSpacing * (GetRowSpan(child) - 1)); } if (actualHeight >= 0) { row.ActualHeight = actualHeight; } if (minimumHeight >= 0) { row.MinimumHeight = minimumHeight; } } } } // 3. Star columns: //Measure the stars starRowHeight = 1; for (var index = 0; index < _rows.Count; index++) { RowDefinition row = _rows[index]; if (!row.Height.IsStar) { continue; } starRowHeight = row.Height.Value != 0 ? Math.Max(starRowHeight, row.ActualHeight / row.Height.Value) : 0; } return(starRowHeight); }
double MeasuredStarredColumns(double widthConstraint, double heightConstraint) { double starColWidth; for (var iteration = 0; iteration < 2; iteration++) { for (var colspan = 1; colspan <= _columns.Count; colspan++) { for (var i = 0; i < _columns.Count; i++) { ColumnDefinition col = _columns[i]; if (!col.Width.IsStar) { continue; } if (col.ActualWidth >= 0) // if Actual is already set (by a smaller span), skip { continue; } double actualWidth = col.ActualWidth; double minimumWidth = col.MinimumWidth; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetColumnSpan(child) != colspan || !IsInColumn(child, i) || NumberOfUnsetColumnWidth(child) > 1) { continue; } double assignedWidth = GetAssignedColumnWidth(child); SizeRequest sizeRequest = child.Measure(widthConstraint, heightConstraint, MeasureFlags.IncludeMargins); actualWidth = Math.Max(actualWidth, sizeRequest.Request.Width - assignedWidth - (GetColumnSpan(child) - 1) * ColumnSpacing); minimumWidth = Math.Max(minimumWidth, sizeRequest.Minimum.Width - assignedWidth - (GetColumnSpan(child) - 1) * ColumnSpacing); } if (actualWidth >= 0) { col.ActualWidth = actualWidth; } if (minimumWidth >= 0) { col.MinimumWidth = minimumWidth; } } } } //Measure the stars starColWidth = 1; for (var index = 0; index < _columns.Count; index++) { ColumnDefinition col = _columns[index]; if (!col.Width.IsStar) { continue; } starColWidth = col.Width.Value != 0 ? Math.Max(starColWidth, col.ActualWidth / col.Width.Value) : 0; } return(starColWidth); }
void CalculateAutoCells(double width, double height) { // this require multiple passes. First process the 1-span, then 2, 3, ... // And this needs to be run twice, just in case a lower-span column can be determined by a larger span for (var iteration = 0; iteration < 2; iteration++) { for (var rowspan = 1; rowspan <= _rows.Count; rowspan++) { for (var i = 0; i < _rows.Count; i++) { RowDefinition row = _rows[i]; if (!row.Height.IsAuto) { continue; } if (row.ActualHeight >= 0) // if Actual is already set (by a smaller span), skip till pass 3 { continue; } double actualHeight = row.ActualHeight; double minimumHeight = row.MinimumHeight; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetRowSpan(child) != rowspan || !IsInRow(child, i) || NumberOfUnsetRowHeight(child) > 1) { continue; } double assignedWidth = GetAssignedColumnWidth(child); double assignedHeight = GetAssignedRowHeight(child); double widthRequest = assignedWidth + GetUnassignedWidth(width); double heightRequest = double.IsPositiveInfinity(height) ? double.PositiveInfinity : assignedHeight + GetUnassignedHeight(height); SizeRequest sizeRequest = child.Measure(widthRequest, heightRequest, MeasureFlags.IncludeMargins); actualHeight = Math.Max(actualHeight, sizeRequest.Request.Height - assignedHeight - RowSpacing * (GetRowSpan(child) - 1)); minimumHeight = Math.Max(minimumHeight, sizeRequest.Minimum.Height - assignedHeight - RowSpacing * (GetRowSpan(child) - 1)); } if (actualHeight >= 0) { row.ActualHeight = actualHeight; } if (minimumHeight >= 0) { row.MinimumHeight = minimumHeight; } } } for (var colspan = 1; colspan <= _columns.Count; colspan++) { for (var i = 0; i < _columns.Count; i++) { ColumnDefinition col = _columns[i]; if (!col.Width.IsAuto) { continue; } if (col.ActualWidth >= 0) // if Actual is already set (by a smaller span), skip { continue; } double actualWidth = col.ActualWidth; double minimumWidth = col.MinimumWidth; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetColumnSpan(child) != colspan || !IsInColumn(child, i) || NumberOfUnsetColumnWidth(child) > 1) { continue; } double assignedWidth = GetAssignedColumnWidth(child); double assignedHeight = GetAssignedRowHeight(child); double widthRequest = double.IsPositiveInfinity(width) ? double.PositiveInfinity : assignedWidth + GetUnassignedWidth(width); double heightRequest = assignedHeight + GetUnassignedHeight(height); SizeRequest sizeRequest = child.Measure(widthRequest, heightRequest, MeasureFlags.IncludeMargins); actualWidth = Math.Max(actualWidth, sizeRequest.Request.Width - assignedWidth - (GetColumnSpan(child) - 1) * ColumnSpacing); minimumWidth = Math.Max(minimumWidth, sizeRequest.Minimum.Width - assignedWidth - (GetColumnSpan(child) - 1) * ColumnSpacing); } if (actualWidth >= 0) { col.ActualWidth = actualWidth; } if (minimumWidth >= 0) { col.MinimumWidth = actualWidth; } } } } }
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint) { SizeRequest desiredSize = base.OnMeasure(double.PositiveInfinity, double.PositiveInfinity); return(ImageElement.Measure(this, desiredSize, widthConstraint, heightConstraint)); }
public virtual SizeRequest GetSizeRequest(double widthConstraint, double heightConstraint) { SizeRequest cachedResult; var constraintSize = new Size(widthConstraint, heightConstraint); if (_measureCache.TryGetValue(constraintSize, out cachedResult)) { return(cachedResult); } double widthRequest = WidthRequest; double heightRequest = HeightRequest; if (widthRequest >= 0) { widthConstraint = Math.Min(widthConstraint, widthRequest); } if (heightRequest >= 0) { heightConstraint = Math.Min(heightConstraint, heightRequest); } SizeRequest result = OnMeasure(widthConstraint, heightConstraint); bool hasMinimum = result.Minimum != result.Request; Size request = result.Request; Size minimum = result.Minimum; if (heightRequest != -1) { request.Height = heightRequest; if (!hasMinimum) { minimum.Height = heightRequest; } } if (widthRequest != -1) { request.Width = widthRequest; if (!hasMinimum) { minimum.Width = widthRequest; } } double minimumHeightRequest = MinimumHeightRequest; double minimumWidthRequest = MinimumWidthRequest; if (minimumHeightRequest != -1) { minimum.Height = minimumHeightRequest; } if (minimumWidthRequest != -1) { minimum.Width = minimumWidthRequest; } minimum.Height = Math.Min(request.Height, minimum.Height); minimum.Width = Math.Min(request.Width, minimum.Width); var r = new SizeRequest(request, minimum); if (r.Request.Width > 0 && r.Request.Height > 0) { _measureCache[constraintSize] = r; } return(r); }
void CalculateNaiveLayout(LayoutInformation layout, StackOrientation orientation, double x, double y, double widthConstraint, double heightConstraint) { layout.CompressionSpace = 0; double xOffset = x; double yOffset = y; double boundsWidth = 0; double boundsHeight = 0; double minimumWidth = 0; double minimumHeight = 0; double spacing = Spacing; if (orientation == StackOrientation.Vertical) { View expander = null; for (var i = 0; i < LogicalChildrenInternal.Count; i++) { var child = (View)LogicalChildrenInternal[i]; if (!child.IsVisible) { continue; } if (child.VerticalOptions.Expands) { layout.Expanders++; if (expander != null) { // we have multiple expanders, make sure previous expanders are reset to not be fixed because they no logner are ComputeConstraintForView(child, false); } expander = child; } SizeRequest request = child.Measure(widthConstraint, double.PositiveInfinity, MeasureFlags.IncludeMargins); var bounds = new Rectangle(x, yOffset, request.Request.Width, request.Request.Height); layout.Plots[i] = bounds; layout.Requests[i] = request; layout.CompressionSpace += Math.Max(0, request.Request.Height - request.Minimum.Height); yOffset = bounds.Bottom + spacing; boundsWidth = Math.Max(boundsWidth, request.Request.Width); boundsHeight = bounds.Bottom - y; minimumHeight += request.Minimum.Height + spacing; minimumWidth = Math.Max(minimumWidth, request.Minimum.Width); } minimumHeight -= spacing; if (expander != null) { ComputeConstraintForView(expander, layout.Expanders == 1); // warning : slightly obtuse, but we either need to setup the expander or clear the last one } } else { View expander = null; for (var i = 0; i < LogicalChildrenInternal.Count; i++) { var child = (View)LogicalChildrenInternal[i]; if (!child.IsVisible) { continue; } if (child.HorizontalOptions.Expands) { layout.Expanders++; if (expander != null) { ComputeConstraintForView(child, false); } expander = child; } SizeRequest request = child.Measure(double.PositiveInfinity, heightConstraint, MeasureFlags.IncludeMargins); var bounds = new Rectangle(xOffset, y, request.Request.Width, request.Request.Height); layout.Plots[i] = bounds; layout.Requests[i] = request; layout.CompressionSpace += Math.Max(0, request.Request.Width - request.Minimum.Width); xOffset = bounds.Right + spacing; boundsWidth = bounds.Right - x; boundsHeight = Math.Max(boundsHeight, request.Request.Height); minimumWidth += request.Minimum.Width + spacing; minimumHeight = Math.Max(minimumHeight, request.Minimum.Height); } minimumWidth -= spacing; if (expander != null) { ComputeConstraintForView(expander, layout.Expanders == 1); } } layout.Bounds = new Rectangle(x, y, boundsWidth, boundsHeight); layout.MinimumSize = new Size(minimumWidth, minimumHeight); }
static double GetMaxWidth(double width, SizeRequest size) { return(Math.Max(size.Request.Width, width)); }
static double GetMaxHeight(double height, SizeRequest size) { return(Math.Max(size.Request.Height, height)); }
double MeasureStarredRows(double widthConstraint, double heightConstraint, double totalStarsHeight) { double starRowHeight; for (var iteration = 0; iteration < 2; iteration++) { for (var rowspan = 1; rowspan <= _rows.Count; rowspan++) { for (var i = 0; i < _rows.Count; i++) { RowDefinition row = _rows[i]; if (!row.Height.IsStar) { continue; } if (row.ActualHeight >= 0) // if Actual is already set (by a smaller span), skip till pass 3 { continue; } double actualHeight = row.ActualHeight; double minimumHeight = row.MinimumHeight; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetRowSpan(child) != rowspan || !IsInRow(child, i) || NumberOfUnsetRowHeight(child) > 1) { continue; } double assignedHeight = GetAssignedRowHeight(child); // If we already have column width info, use it when measuring double assignedWidth = GetAssignedColumnWidth(child); var wConstraint = assignedWidth > 0 ? assignedWidth : widthConstraint; SizeRequest sizeRequest = child.Measure(wConstraint, heightConstraint, MeasureFlags.IncludeMargins); var rowSpacing = (GetRowSpan(child) - 1) * RowSpacing; actualHeight = Math.Max(actualHeight, sizeRequest.Request.Height - assignedHeight - rowSpacing); minimumHeight = Math.Max(minimumHeight, sizeRequest.Minimum.Height - assignedHeight - rowSpacing); } if (actualHeight >= 0) { row.ActualHeight = actualHeight; } if (minimumHeight >= 0) { row.MinimumHeight = minimumHeight; } } } } starRowHeight = 0; for (var index = 0; index < _rows.Count; index++) { RowDefinition row = _rows[index]; if (!row.Height.IsStar || row.Height.Value == 0 || row.ActualHeight <= 0) { continue; } starRowHeight += row.ActualHeight; } return(Math.Max(starRowHeight / totalStarsHeight, 1)); }
double MeasuredStarredColumns(double widthConstraint, double heightConstraint, double totalStarsWidth) { double starColWidth; for (var iteration = 0; iteration < 2; iteration++) { for (var colspan = 1; colspan <= _columns.Count; colspan++) { for (var i = 0; i < _columns.Count; i++) { ColumnDefinition col = _columns[i]; if (!col.Width.IsStar) { continue; } if (col.ActualWidth >= 0) // if Actual is already set (by a smaller span), skip { continue; } double actualWidth = col.ActualWidth; double minimumWidth = col.MinimumWidth; for (var index = 0; index < InternalChildren.Count; index++) { var child = (View)InternalChildren[index]; if (!child.IsVisible || GetColumnSpan(child) != colspan || !IsInColumn(child, i) || NumberOfUnsetColumnWidth(child) > 1) { continue; } double assignedWidth = GetAssignedColumnWidth(child); // If we already have row height info, use it when measuring double assignedHeight = GetAssignedRowHeight(child); var hConstraint = assignedHeight > 0 ? assignedHeight : heightConstraint; SizeRequest sizeRequest = child.Measure(widthConstraint, hConstraint, MeasureFlags.IncludeMargins); var columnSpacing = (GetColumnSpan(child) - 1) * ColumnSpacing; actualWidth = Math.Max(actualWidth, sizeRequest.Request.Width - assignedWidth - columnSpacing); minimumWidth = Math.Max(minimumWidth, sizeRequest.Minimum.Width - assignedWidth - columnSpacing); } if (actualWidth >= 0) { col.ActualWidth = actualWidth; } if (minimumWidth >= 0) { col.MinimumWidth = minimumWidth; } } } } starColWidth = 0; for (var index = 0; index < _columns.Count; index++) { ColumnDefinition col = _columns[index]; if (!col.Width.IsStar || col.Width.Value == 0 || col.ActualWidth <= 0) { continue; } starColWidth += col.ActualWidth; } return(Math.Max(starColWidth / totalStarsWidth, 1)); }
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint) { SizeRequest desiredSize = base.OnSizeRequest(double.PositiveInfinity, double.PositiveInfinity); double desiredAspect = desiredSize.Request.Width / desiredSize.Request.Height; double constraintAspect = widthConstraint / heightConstraint; double desiredWidth = desiredSize.Request.Width; double desiredHeight = desiredSize.Request.Height; if (desiredWidth == 0 || desiredHeight == 0) { return(new SizeRequest(new Size(0, 0))); } double width = desiredWidth; double height = desiredHeight; if (constraintAspect > desiredAspect) { // constraint area is proportionally wider than image switch (Aspect) { case Aspect.AspectFit: case Aspect.AspectFill: height = Math.Min(desiredHeight, heightConstraint); width = desiredWidth * (height / desiredHeight); break; case Aspect.Fill: width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); break; } } else if (constraintAspect < desiredAspect) { // constraint area is proportionally taller than image switch (Aspect) { case Aspect.AspectFit: case Aspect.AspectFill: width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); break; case Aspect.Fill: height = Math.Min(desiredHeight, heightConstraint); width = desiredWidth * (height / desiredHeight); break; } } else { // constraint area is same aspect as image width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); } return(new SizeRequest(new Size(width, height))); }
public static SizeRequest Measure( IImageController ImageElementManager, SizeRequest desiredSize, double widthConstraint, double heightConstraint) { double desiredAspect = desiredSize.Request.Width / desiredSize.Request.Height; double constraintAspect = widthConstraint / heightConstraint; double desiredWidth = desiredSize.Request.Width; double desiredHeight = desiredSize.Request.Height; if (desiredWidth == 0 || desiredHeight == 0) { return(new SizeRequest(new Size(0, 0))); } double width = desiredWidth; double height = desiredHeight; if (constraintAspect > desiredAspect) { // constraint area is proportionally wider than image switch (ImageElementManager.Aspect) { case Aspect.AspectFit: case Aspect.AspectFill: height = Math.Min(desiredHeight, heightConstraint); width = desiredWidth * (height / desiredHeight); break; case Aspect.Fill: width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); break; } } else if (constraintAspect < desiredAspect) { // constraint area is proportionally taller than image switch (ImageElementManager.Aspect) { case Aspect.AspectFit: case Aspect.AspectFill: width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); break; case Aspect.Fill: height = Math.Min(desiredHeight, heightConstraint); width = desiredWidth * (height / desiredHeight); break; } } else { // constraint area is same aspect as image width = Math.Min(desiredWidth, widthConstraint); height = desiredHeight * (width / desiredWidth); } return(new SizeRequest(new Size(width, height))); }