public override SpecificLayout GetBestLayout(LayoutQuery query) { double width = query.MaxWidth; if (this.pixelWidth > 0) { width = Math.Floor(query.MaxWidth / this.pixelWidth) * this.pixelWidth; } double height = query.MaxHeight; if (this.pixelHeight > 0) { height = Math.Floor(query.MaxHeight / this.pixelHeight) * this.pixelHeight; } if (width != query.MaxWidth || height != query.MaxHeight) { query = query.WithDimensions(width, height); } SpecificLayout internalLayout = this.layoutToManage.GetBestLayout(query); if (internalLayout != null) { Size size = new Size(Math.Ceiling(internalLayout.Width / this.pixelWidth) * this.pixelWidth, Math.Ceiling(internalLayout.Height / this.pixelHeight) * this.pixelHeight); Specific_ContainerLayout result = new Specific_ContainerLayout(null, size, new LayoutScore(), internalLayout, new Thickness(0)); return(this.prepareLayoutForQuery(result, query)); } return(null); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { Specific_ContainerLayout result; // Determine whether there's room for the border double borderWidth = this.BorderThickness.Left + this.BorderThickness.Right; double borderHeight = this.BorderThickness.Top + this.BorderThickness.Bottom; LayoutQuery subQuery = query.WithDimensions(query.MaxWidth - borderWidth, query.MaxHeight - borderHeight); if (subQuery.MaxWidth < 0 || subQuery.MaxHeight < 0) { return(null); } // Query sublayout if it exists if (this.SubLayout != null) { SpecificLayout best_subLayout = this.SubLayout.GetBestLayout(subQuery); if (best_subLayout != null) { result = this.makeSpecificLayout(this.view, new Size(best_subLayout.Width + borderWidth, best_subLayout.Height + borderHeight), LayoutScore.Zero, best_subLayout, this.BorderThickness); result.ChildFillsAvailableSpace = this.ChildFillsAvailableSpace; this.prepareLayoutForQuery(result, query); return(result); } return(null); } // if there is no subLayout, for now we just return an empty size Specific_ContainerLayout empty = this.makeSpecificLayout(this.view, new Size(), LayoutScore.Zero, null, new Thickness()); if (query.Accepts(empty)) { result = empty; } else { result = null; } this.prepareLayoutForQuery(result, query); return(result); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { // The score of a Specific_ScrollLayout is defined in returnLayout: // If the child layout has negative score, the Specific_ScrollLayout refuses to do a layout // If the child layout has nonnegative score, the Specific_ScrollLayout's score equals // (this.resultingScore * (what fraction of the child layout is visible)) if (query.MinScore.CompareTo(this.resultingScore) > 0) { // Demands too high of a score: no solution return(null); } if (query.MaxHeight <= 0) { return(null); } // what fraction of the score of the sublayout will appear onscreen at once double scoreFraction = Math.Max(query.MinScore.DividedBy(this.resultingScore), 0); // what fraction of the child's height we need to include in the size of the ScrollView double requiredHeightFraction = scoreFraction; // the child's height divided by the ScrollView's height double requiredHeightMultiplier; if (requiredHeightFraction != 0) { requiredHeightMultiplier = 1 / requiredHeightFraction; } else { requiredHeightMultiplier = double.PositiveInfinity; } // the maximum child height double maxChildHeight = query.MaxHeight * requiredHeightMultiplier; if (query.MinimizesWidth()) { // For a min-width query, first shrink the width as much as possible before continuing SpecificLayout minWidth_childLayout = this.subLayout.GetBestLayout(new MinWidth_LayoutQuery(query.MaxWidth, maxChildHeight, this.requiredChildScore)); if (minWidth_childLayout == null) { return(null); } query = query.WithDimensions(minWidth_childLayout.Width, minWidth_childLayout.Height); } SpecificLayout childLayout = this.subLayout.GetBestLayout(new MinHeight_LayoutQuery(query.MaxWidth, maxChildHeight, this.requiredChildScore)); if (childLayout == null) { return(null); } if (!query.MinimizesHeight()) { // For a max-score (or min-width) query, use as much height as was allowed Size size = new Size(childLayout.Width, Math.Min(query.MaxHeight, childLayout.Height)); SpecificLayout result = this.makeLayout(size, childLayout); if (query.Accepts(result)) { return(this.prepareLayoutForQuery(result, query)); } return(null); } else { // For a min-height query, use only as much size as is needed double requiredScrollviewHeight = childLayout.Height * requiredHeightFraction; Size size = new Size(childLayout.Width, requiredScrollviewHeight); SpecificLayout result = this.makeLayout(size, childLayout); if (!query.Accepts(result)) { // Check for possible rounding error SpecificLayout larger = this.makeLayout(new Size(size.Width, size.Height + this.pixelSize), childLayout); if (query.Accepts(larger)) { return(this.prepareLayoutForQuery(larger, query)); } return(null); } return(this.prepareLayoutForQuery(result, query)); } }