Beispiel #1
0
        /// <summary>
        /// Overridden to provide measurement support for this native view
        /// </summary>
        /// <param name="parentWidth">Parent width.</param>
        /// <param name="parentHeight">Parent height.</param>
        protected override void onMeasure(nfloat parentWidth, nfloat parentHeight)
        {
            // Resolve width for absolute and parent ratio
            nfloat width  = LayoutParameters.TryResolveWidth(this, parentWidth, parentHeight);
            nfloat height = LayoutParameters.TryResolveHeight(this, parentWidth, parentHeight);

            // Do we need to measure our content?
            CGSize sizeMeasured = CGSize.Empty;

            if (width == nfloat.MaxValue || height == nfloat.MaxValue)
            {
                CGSize sizeToFit = new CGSize(width, height);
                //sizeMeasured = Measurer!=null ? Measurer(_view, sizeToFit) : _view.SizeThatFits(sizeToFit);

                var size = _view.SizeThatFits(sizeToFit);
                if (LayoutParameters.MaxWidth != 0 && size.Width > LayoutParameters.MaxWidth)
                {
                    size = _view.SizeThatFits(new CGSize(LayoutParameters.MaxWidth, height));
                }
                sizeMeasured = Measurer != null?Measurer(_view, sizeToFit) : size;
            }

            // Set the measured size
            SetMeasuredSize(LayoutParameters.ResolveSize(new CGSize(width, height), sizeMeasured));
        }
Beispiel #2
0
        // Do measurement when in horizontal orientation
        private void MeasureHorizontal(nfloat parentWidth, nfloat parentHeight)
        {
            // Work out our height
            nfloat layoutWidth  = LayoutParameters.TryResolveWidth(this, parentWidth, parentHeight);
            nfloat layoutHeight = LayoutParameters.TryResolveHeight(this, parentWidth, parentHeight);

            // Work out the total fixed size
            int visibleViewCount = 0;
            var paddings         = Padding.TotalWidth();

            _rows      = new List <WrapRow>();
            _goneViews = new List <View>();

            var row = new WrapRow();

            _rows.Add(row);
            Func <nfloat> spacing = () => visibleViewCount == 0 ? 0 : Spacing;

            foreach (var v in SubViews)
            {
                if (v.Gone)
                {
                    _goneViews.Add(v);
                    continue;
                }

                v.Measure(parentWidth - paddings - v.LayoutParameters.Margins.TotalWidth(), adjustLayoutHeight(layoutHeight, v));

                var width = v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth();

                if (row.Width + width + spacing() > parentWidth)
                {
                    visibleViewCount = 0;
                    var newRow = new WrapRow();
                    newRow.YPosition = row.YPosition + row.Height;
                    row = newRow;
                    _rows.Add(row);
                }
                row.Width += v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth() + spacing();
                row.Height = NMath.Max(row.Height, v.GetMeasuredSize().Height);

                visibleViewCount++;
                layoutWidth = NMath.Max(layoutWidth, row.Width);
                row.Views.Add(v);
            }

            layoutHeight = row.YPosition + row.Height;

            CGSize sizeMeasured = CGSize.Empty;

            layoutHeight += Padding.TotalHeight();
            layoutWidth  += Padding.TotalWidth();

            // And finally, set our measure dimensions
            SetMeasuredSize(LayoutParameters.ResolveSize(new CGSize(layoutWidth, layoutHeight), sizeMeasured));
        }
Beispiel #3
0
        /// <summary>
        /// Overridden to provide measurement support for this native view
        /// </summary>
        /// <param name="parentWidth">Parent width.</param>
        /// <param name="parentHeight">Parent height.</param>
        protected override void onMeasure(float parentWidth, float parentHeight)
        {
            // Resolve width for absolute and parent ratio
            float width  = LayoutParameters.TryResolveWidth(this, parentWidth);
            float height = LayoutParameters.TryResolveHeight(this, parentHeight);

            // Do we need to measure our content?
            SizeF sizeMeasured = SizeF.Empty;

            if (_view != null && (width == float.MaxValue || height == float.MaxValue))
            {
                SizeF sizeToFit = new SizeF(width, height);
                sizeMeasured = Measurer != null?Measurer(_view, sizeToFit) : _view.SizeThatFits(sizeToFit);
            }

            // Set the measured size
            SetMeasuredSize(LayoutParameters.ResolveSize(new SizeF(width, height), sizeMeasured));
        }
Beispiel #4
0
        // Do measurement when in vertical orientation
        private void MeasureVertical(nfloat parentWidth, nfloat parentHeight)
        {
            // Work out our width
            var width  = LayoutParameters.TryResolveWidth(this, parentWidth, parentHeight);
            var height = LayoutParameters.TryResolveHeight(this, parentWidth, parentHeight);

            // Allow room for padding
            if (width != nfloat.MaxValue)
            {
                width -= Padding.TotalWidth();
            }

            // Work out the total fixed size
            nfloat totalFixedSize   = 0;
            double totalWeight      = 0;
            int    visibleViewCount = 0;

            foreach (var v in SubViews.Where(x => !x.Gone))
            {
                if (v.LayoutParameters.HeightUnits == Units.ParentRatio)
                {
                    // We'll deal with this later

                    // For now, lets just total up the specified weights
                    totalWeight += v.LayoutParameters.Weight;
                }
                else
                {
                    // Lay it out
                    v.Measure(adjustLayoutWidth(width, v), nfloat.MaxValue);
                    totalFixedSize += v.GetMeasuredSize().Height;
                }

                // Include margins
                totalFixedSize += v.LayoutParameters.Margins.TotalHeight();
                visibleViewCount++;
            }


            // Also need to include our own padding
            totalFixedSize += Padding.TotalHeight();

            // And spacing between controls
            if (visibleViewCount > 1)
            {
                totalFixedSize += (visibleViewCount - 1) * Spacing;
            }

            nfloat totalVariableSize = 0;

            if (LayoutParameters.HeightUnits == Units.ContentRatio || height == nfloat.MaxValue)
            {
                // This is a weird case: we have a height of wrap content, but child items that want to fill parent too.
                // Temporarily switch those items to wrap content and use their natural size
                foreach (var v in SubViews.Where(x => !x.Gone && x.LayoutParameters.HeightUnits == Units.ParentRatio))
                {
                    v.Measure(adjustLayoutWidth(width, v), nfloat.MaxValue);
                    totalVariableSize += v.GetMeasuredSize().Height;
                }
            }
            else
            {
                // If we've had an explicit weight passed to us, ignore the calculated total weight and use it instead
                if (_totalWeight != 0)
                {
                    totalWeight = _totalWeight;
                }

                // Work out how much room we've got to share around
                nfloat room = height - totalFixedSize;

                // Layout the fill parent items
                foreach (var v in SubViews.Where(x => !x.Gone && x.LayoutParameters.HeightUnits == Units.ParentRatio))
                {
                    // Work out size
                    if (room < 0)
                    {
                        room = 0;
                    }
                    nfloat size = (nfloat)(totalWeight == 0 ? room : room * v.LayoutParameters.Weight / totalWeight);

                    // Measure it
                    v.Measure(adjustLayoutWidth(width, v), size);

                    // Update total size
                    totalVariableSize += v.GetMeasuredSize().Height;

                    // Adjust the weighting calculation in case the view didn't accept our measurement
                    room        -= v.GetMeasuredSize().Height;
                    totalWeight -= v.LayoutParameters.Weight;
                }
            }

            CGSize sizeMeasured = CGSize.Empty;

            if (width == nfloat.MaxValue)
            {
                // Work out the maximum width of all children that aren't fill parent
                sizeMeasured.Width = 0;
                foreach (var v in SubViews.Where(x => !x.Gone && x.LayoutParameters.WidthUnits != Units.ParentRatio))
                {
                    nfloat totalChildWidth = v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth();
                    if (totalChildWidth > sizeMeasured.Width)
                    {
                        sizeMeasured.Width = totalChildWidth;
                    }
                }

                // Set the width of all children that are fill parent
                foreach (var v in SubViews.Where(x => !x.Gone && x.LayoutParameters.WidthUnits == Units.ParentRatio))
                {
                    v.Measure(sizeMeasured.Width, v.GetMeasuredSize().Height);
                }

                sizeMeasured.Width += Padding.TotalWidth();
            }
            else
            {
                width += Padding.TotalWidth();
            }

            if (height == nfloat.MaxValue)
            {
                height = totalFixedSize + totalVariableSize;
            }

            if (LayoutParameters.ParentIsScorllView(this))
            {
                height = totalFixedSize + totalVariableSize;
                if (LayoutParameters.HeightUnits == Units.ParentRatio)
                {
                    height = height < parentHeight ? parentHeight : height;
                }
            }

            // And finally, set our measure dimensions
            SetMeasuredSize(LayoutParameters.ResolveSize(new CGSize(width, height), sizeMeasured));
        }
Beispiel #5
0
        protected override void onMeasure(float parentWidth, float parentHeight)
        {
            var unresolved = new List <View>();

            var width  = LayoutParameters.TryResolveWidth(this, parentWidth);
            var height = LayoutParameters.TryResolveHeight(this, parentHeight);

            // Remove padding
            if (width != float.MaxValue)
            {
                width -= Padding.TotalWidth();
            }
            if (height != float.MaxValue)
            {
                height -= Padding.TotalHeight();
            }

            // Measure all subviews where both dimensions can be resolved
            bool  haveResolvedSize = false;
            float maxWidth = 0, maxHeight = 0;

            foreach (var v in SubViews.Where(x => !x.Gone))
            {
                // Try to resolve subview width
                var subViewWidth = float.MaxValue;
                if (v.LayoutParameters.WidthUnits == Units.ParentRatio)
                {
                    if (width == float.MaxValue)
                    {
                        unresolved.Add(v);
                        continue;
                    }
                    else
                    {
                        subViewWidth = width - v.LayoutParameters.Margins.TotalWidth();
                    }
                }

                // Try to resolve subview height
                var subViewHeight = float.MaxValue;
                if (v.LayoutParameters.HeightUnits == Units.ParentRatio)
                {
                    if (height == float.MaxValue)
                    {
                        unresolved.Add(v);
                        continue;
                    }
                    else
                    {
                        subViewHeight = height - v.LayoutParameters.Margins.TotalHeight();
                    }
                }

                // Measure it
                v.Measure(subViewWidth, subViewHeight);

                if (!haveResolvedSize)
                {
                    maxWidth         = v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth();
                    maxHeight        = v.GetMeasuredSize().Height + v.LayoutParameters.Margins.TotalHeight();
                    haveResolvedSize = true;
                }
                else
                {
                    maxWidth  = Math.Max(maxWidth, v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth());
                    maxHeight = Math.Max(maxHeight, v.GetMeasuredSize().Height + v.LayoutParameters.Margins.TotalHeight());
                }
            }

            // Now resolve the unresolved subviews by either using the dimensions of the view
            // that were resolved, or none were, use their natural size
            foreach (var v in unresolved)
            {
                var subViewWidth = float.MaxValue;
                if (v.LayoutParameters.WidthUnits == Units.ParentRatio && haveResolvedSize)
                {
                    subViewWidth = maxWidth - v.LayoutParameters.Margins.TotalWidth();
                }

                var subViewHeight = float.MaxValue;
                if (v.LayoutParameters.HeightUnits == Units.ParentRatio && haveResolvedSize)
                {
                    subViewHeight = maxHeight - v.LayoutParameters.Margins.TotalHeight();
                }

                // Measure it
                v.Measure(subViewWidth, subViewHeight);
            }

            SizeF sizeMeasured = SizeF.Empty;

            if (width == float.MaxValue)
            {
                sizeMeasured.Width = SubViews.Max(x => x.GetMeasuredSize().Width + x.LayoutParameters.Margins.TotalWidth()) + Padding.TotalWidth();
            }

            if (height == float.MaxValue)
            {
                sizeMeasured.Height = SubViews.Max(x => x.GetMeasuredSize().Height + x.LayoutParameters.Margins.TotalHeight()) + Padding.TotalHeight();
            }

            // Done!
            SetMeasuredSize(LayoutParameters.ResolveSize(new SizeF(width, height), sizeMeasured));
        }
Beispiel #6
0
        // Do measurement when in horizontal orientation
        private void MeasureHorizontal(nfloat parentWidth, nfloat parentHeight)
        {
            // Work out our height
            nfloat layoutWidth  = LayoutParameters.TryResolveWidth(this, parentWidth, parentHeight);
            nfloat layoutHeight = LayoutParameters.TryResolveHeight(this, parentWidth, parentHeight);

            // Work out the total fixed size
            var paddings = Padding.TotalWidth();

            _goneViews     = new List <View>();
            _arrangedViews = new View[RowDefinitions.Count, ColumnDefinitions.Count];
            var columnWidthFillParentSubviews = new List <View>();

            //calculating columns
            var minWidth = (nfloat)ColumnDefinitions.Sum(x => x.MinWidth);

            foreach (var v in SubViews.Where(x => !x.Gone))
            {
                _arrangedViews[v.Row, v.Column] = v;
                var columnDefinition = ColumnDefinitions[v.Column];
                var rowDefinition    = RowDefinitions[v.Column];

                nfloat width;
                if (columnDefinition.Width > 0)
                {
                    width = columnDefinition.Width;
                }
                else if (columnDefinition.MaxWidth > 0)
                {
                    width = columnDefinition.MaxWidth;
                }
                else
                {
                    width = parentWidth - paddings;
                }

                nfloat height;
                if (rowDefinition.Height > 0)
                {
                    height = rowDefinition.Height;
                }
                else
                {
                    height = adjustLayoutHeight(layoutHeight, v);
                }

                if (v.LayoutParameters.WidthUnits != Units.ParentRatio)
                {
                    v.Measure(width - v.LayoutParameters.Margins.TotalWidth(), height);
                }
                else
                {
                    v._measuredSize      = new CGSize(0, 0);
                    v._measuredSizeValid = true;
                    columnWidthFillParentSubviews.Add(v);
                }
            }

            {
                nfloat totalWeight = 0;
                nfloat totalWidth  = 0;
                var    columnId    = -1;
                foreach (var column in ColumnDefinitions)
                {
                    columnId++;
                    column.CalculatedWidth = 0;

                    if (column.Width > 0)
                    {
                        column.CalculatedWidth = column.Width;
                    }
                    else if (column.Width == AutoSize.WrapContent)
                    {
                        for (int rowId = 0; rowId < RowDefinitions.Count; rowId++)
                        {
                            var v = _arrangedViews[rowId, columnId];

                            if (v != null)
                            {
                                column.CalculatedWidth = NMath.Max(column.CalculatedWidth, v.GetMeasuredSize().Width + v.LayoutParameters.Margins.TotalWidth());
                            }
                        }
                    }
                    else if (column.Width == AutoSize.FillParent)
                    {
                        totalWeight += column.Weight;
                    }
                    totalWidth += column.CalculatedWidth;
                }

                var room = layoutWidth - totalWidth;
                foreach (var column in ColumnDefinitions.Where(x => x.Width == AutoSize.FillParent))
                {
                    columnId++;

                    column.CalculatedWidth = room * column.Weight / totalWeight;
                }
            }

            {
                var totalWeight = 0;
                var totalHeight = 0;
                var rowId       = -1;
                foreach (var row in RowDefinitions)
                {
                    rowId++;

                    if (row.Height > 0)
                    {
                        row.CalculatedHeight = row.Height;
                        continue;
                    }


                    if (row.Height == AutoSize.WrapContent)
                    {
                        row.CalculatedHeight = 0;
                        for (int columnId = 0; columnId < ColumnDefinitions.Count; columnId++)
                        {
                            var v = _arrangedViews[rowId, columnId];

                            if (v != null)
                            {
                                row.CalculatedHeight = NMath.Max(row.CalculatedHeight, v.GetMeasuredSize().Height);
                            }
                        }
                    }
                }


                var room = layoutHeight - totalHeight;
                foreach (var row in RowDefinitions.Where(x => x.Height == AutoSize.FillParent))
                {
                    row.CalculatedHeight = room * row.Weight / totalWeight;
                }
            }

            CGSize sizeMeasured = CGSize.Empty;

            foreach (var item in ColumnDefinitions)
            {
                sizeMeasured.Width += item.CalculatedWidth;
            }
            sizeMeasured.Width += ColSpacing * (ColumnDefinitions.Count - 1);
            foreach (var item in RowDefinitions)
            {
                sizeMeasured.Height += item.CalculatedHeight;
            }
            sizeMeasured.Height += RowSpacing * (RowDefinitions.Count - 1);

            foreach (var v in columnWidthFillParentSubviews)
            {
                v.Measure(ColumnDefinitions[v.Column].CalculatedWidth, RowDefinitions[v.Row].CalculatedHeight);
            }

            // And finally, set our measure dimensions
            SetMeasuredSize(LayoutParameters.ResolveSize(new CGSize(layoutWidth, layoutHeight), sizeMeasured));
        }