Example #1
0
        protected void LayoutLine(IList <FrameworkElement> children, PointF pos, LineMeasurement line)
        {
            float offset = 0;

            for (int i = line.StartIndex; i <= line.EndIndex; i++)
            {
                FrameworkElement layoutChild      = children[i];
                SizeF            desiredChildSize = layoutChild.DesiredSize;
                SizeF            size;
                PointF           location;

                if (Orientation == Orientation.Horizontal)
                {
                    size     = new SizeF(desiredChildSize.Width, line.TotalExtendsInNonOrientationDirection);
                    location = new PointF(pos.X + offset, pos.Y);
                    ArrangeChildVertical(layoutChild, layoutChild.VerticalAlignment, ref location, ref size);
                    offset += desiredChildSize.Width;
                }
                else
                {
                    size     = new SizeF(line.TotalExtendsInNonOrientationDirection, desiredChildSize.Height);
                    location = new PointF(pos.X, pos.Y + offset);
                    ArrangeChildHorizontal(layoutChild, layoutChild.HorizontalAlignment, ref location, ref size);
                    offset += desiredChildSize.Height;
                }

                layoutChild.Arrange(SharpDXExtensions.CreateRectangleF(location, size));
            }
        }
        private void DrawTearingTest()
        {
            using (Surface surface = _device.GetRenderTarget(0))
            {
                int   left    = _tearingPos;
                int   width   = surface.Description.Width;
                int   height  = surface.Description.Height;
                Size  size    = new Size(4, height);
                Point topLeft = new Point(left, 0);
                if (topLeft.X + size.Width >= width)
                {
                    topLeft.X = 0;
                }

                Rectangle rcTearing = SharpDXExtensions.CreateRectangle(topLeft, size);

                _device.ColorFill(surface, rcTearing, ColorConverter.FromArgb(255, 255, 255, 255));

                topLeft = new Point((rcTearing.Right + 15) % width, 0);
                if (topLeft.X + size.Width >= width)
                {
                    topLeft.X = 0;
                }

                rcTearing = SharpDXExtensions.CreateRectangle(topLeft, size);
                _device.ColorFill(surface, rcTearing, ColorConverter.FromArgb(255, 100, 100, 100));

                _tearingPos = (_tearingPos + 7) % width;
            }
        }
Example #3
0
        // public static Vector3 InFront(this Unit unit, float distance)
        // {
        //     var v = unit.Position + (unit.Vector3FromPolarAngle() * distance);
        //     return new Vector3(v.X, v.Y, 0);
        // }
        public static Vector3 InFrontSuper(this Entity unit, float distance)
        {
            var alpha = unit.RotationRad;
            var vector2FromPolarAngle = SharpDXExtensions.FromPolarCoordinates(1f, alpha);

            var v = unit.Position + (vector2FromPolarAngle.ToVector3() * distance);

            return(new Vector3(v.X, v.Y, 0));
        }
        protected override void ArrangeTemplateControl()
        {
            FrameworkElement templateControl = _initializedTemplateControl;

            if (templateControl == null)
            {
                return;
            }
            lock (_renderLock)
                if (_settings == null)
                {
                    return;
                }
            RectangleF?elementArrangeBounds = _settings.ElementArrangeBounds;
            SizeF      keyboardSize         = templateControl.DesiredSize;
            RectangleF actualBounds         = ActualBounds;

            if (actualBounds.Size.Width < keyboardSize.Width)
            {
                keyboardSize.Width = actualBounds.Size.Width;
            }
            if (actualBounds.Size.Height < keyboardSize.Height)
            {
                keyboardSize.Height = actualBounds.Size.Height;
            }
            RectangleF keyboardRect;

            if (elementArrangeBounds.HasValue)
            {
                // Arrange above or below elementArrangeBounds, horizontally centered in elementArrangeBounds
                keyboardRect = SharpDXExtensions.CreateRectangleF(new PointF(
                                                                      elementArrangeBounds.Value.Left + elementArrangeBounds.Value.Width / 2 - keyboardSize.Width / 2,
                                                                      elementArrangeBounds.Value.Bottom + keyboardSize.Height > actualBounds.Bottom ?
                                                                      elementArrangeBounds.Value.Top - keyboardSize.Height : elementArrangeBounds.Value.Bottom),
                                                                  keyboardSize);
            }
            else
            {
                // Center in actualBounds
                keyboardRect = new RectangleF(
                    actualBounds.Left + (actualBounds.Width - keyboardSize.Width) / 2,
                    actualBounds.Top + (actualBounds.Height - keyboardSize.Height) / 2,
                    keyboardSize.Width, keyboardSize.Height);
            }
            if (keyboardRect.Left < actualBounds.Left)
            {
                keyboardRect.X = actualBounds.Left;
            }
            if (keyboardRect.Right > actualBounds.Right)
            {
                keyboardRect.X = actualBounds.Right - keyboardSize.Width;
            }
            templateControl.Arrange(keyboardRect);
        }
Example #5
0
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();

            IList <FrameworkElement> visibleChildren = GetVisibleChildren();
            int visibleChildrenCount = visibleChildren.Count;

            if (_doScroll)
            {
                CalculateDesiredSize(new SizeF((float)ActualWidth, (float)ActualHeight), false, out _actualColumnWidth, out _actualRowHeight);
            }
            else
            {
                _actualColumnWidth = (float)(ActualWidth / _actualColumns);
                _actualRowHeight   = (float)(ActualHeight / _actualRows);
            }

            _actualNumVisibleCols = (int)(ActualWidth / _actualColumnWidth);
            _actualNumVisibleRows = (int)(ActualHeight / _actualRowHeight);

            if (_doScroll)
            {
                int maxScrollIndexX = Math.Max(_actualColumns - _actualNumVisibleCols, 0);
                int maxScrollIndexY = Math.Max(_actualRows - _actualNumVisibleRows, 0);

                if (_scrollIndexX > maxScrollIndexX)
                {
                    _scrollIndexX = maxScrollIndexX;
                }
                if (_scrollIndexY > maxScrollIndexY)
                {
                    _scrollIndexY = maxScrollIndexY;
                }
            }
            else
            {
                _scrollIndexX = 0;
                _scrollIndexY = 0;
            }

            // Hint: We cannot skip the arrangement of children above _scrollOffset or below the last visible child
            // because the rendering and focus system also needs the bounds of the currently invisible children
            for (int i = 0; i < visibleChildrenCount; i++)
            {
                FrameworkElement child     = visibleChildren[i];
                SizeF            childSize = new SizeF(_actualColumnWidth, _actualRowHeight);
                PointF           position  = new PointF(
                    ActualPosition.X + (i % _actualColumns - _scrollIndexX) * _actualColumnWidth,
                    ActualPosition.Y + (i / _actualColumns - _scrollIndexY) * _actualRowHeight);

                ArrangeChild(child, child.HorizontalAlignment, child.VerticalAlignment, ref position, ref childSize);
                child.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
            }
        }
Example #6
0
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();
            FrameworkElement content = Content;

            if (content != null)
            {
                PointF position      = new PointF(_innerRect.X, _innerRect.Y);
                SizeF  availableSize = CalculateInnerDesiredSize(_innerRect.Size);
                ArrangeChild(content, content.HorizontalAlignment, content.VerticalAlignment, ref position, ref availableSize);
                RectangleF childRect = SharpDXExtensions.CreateRectangleF(position, availableSize);
                content.Arrange(childRect);
            }
        }
        protected virtual void ArrangeTemplateControl()
        {
            FrameworkElement templateControl = _templateControl;

            if (templateControl == null)
            {
                return;
            }
            PointF position      = new PointF(_innerRect.X, _innerRect.Y);
            SizeF  availableSize = new SizeF(_innerRect.Width, _innerRect.Height);

            ArrangeChild(templateControl, HorizontalContentAlignment, VerticalContentAlignment,
                         ref position, ref availableSize);
            RectangleF childRect = SharpDXExtensions.CreateRectangleF(position, availableSize);

            templateControl.Arrange(childRect);
        }
Example #8
0
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();
            float x = _innerRect.Location.X;
            float y = _innerRect.Location.Y;

            foreach (FrameworkElement child in GetVisibleChildren())
            {
                // Get the coordinates relative to the canvas area.
                PointF location = new PointF(GetLeft(child, false) + x, GetTop(child, false) + y);

                // Get the child size
                SizeF childSize = child.DesiredSize;

                // Arrange the child
                child.Arrange(SharpDXExtensions.CreateRectangleF(location, childSize));
            }
        }
Example #9
0
        protected override SizeF CalculateInnerDesiredSize(SizeF totalSize)
        {
            RectangleF rect = new RectangleF(0, 0, 0, 0);

            UnregisterAllChildCanvasPositionProperties();
            foreach (FrameworkElement child in GetVisibleChildren())
            {
                SizeF childSize = new SizeF(totalSize.Width, totalSize.Height);
                child.Measure(ref childSize);

                float left = GetLeft(child, true);
                float top  = GetTop(child, true);

                rect = RectangleF.Union(rect, SharpDXExtensions.CreateRectangleF(new PointF(left, top), new SizeF(childSize.Width, childSize.Height)));
            }

            return(new SizeF(rect.Right, rect.Bottom));
        }
Example #10
0
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();
            ColumnDefinitions.SetAvailableSize(ActualWidth);
            RowDefinitions.SetAvailableSize(ActualHeight);

            foreach (FrameworkElement child in GetVisibleChildren())
            {
                int col = GetColumn(child);
                int row = GetRow(child);
                if (col >= ColumnDefinitions.Count)
                {
                    col = ColumnDefinitions.Count - 1;
                }
                if (col < 0)
                {
                    col = 0;
                }
                if (row >= RowDefinitions.Count)
                {
                    row = RowDefinitions.Count - 1;
                }
                if (row < 0)
                {
                    row = 0;
                }

                PointF position = new PointF(
                    (float)ColumnDefinitions.GetOffset(col) + _innerRect.Location.X,
                    (float)RowDefinitions.GetOffset(row) + _innerRect.Location.Y);

                SizeF childSize = new SizeF(
                    (float)ColumnDefinitions.GetLength(col, GetColumnSpan(child)),
                    (float)RowDefinitions.GetLength(row, GetRowSpan(child)));

                ArrangeChild(child, child.HorizontalAlignment, child.VerticalAlignment, ref position, ref childSize);
                child.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
            }
        }
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();

            IList <FrameworkElement> visibleChildren = GetVisibleChildren();

            if (visibleChildren.Count > 0)
            {
                float actualWidth  = (float)ActualWidth;
                float actualHeight = (float)ActualHeight;

                // First check how many children we must leave out
                float            availableSize         = Orientation == Orientation.Vertical ? actualHeight : actualWidth;
                FrameworkElement firstChild            = visibleChildren[0];
                SizeF            firstChildDesiredSize = firstChild.DesiredSize;
                SizeF            desiredEllipsisSize   = _ellipsisControl == null ? new SizeF() : _ellipsisControl.DesiredSize;
                // The first element is always shown
                availableSize -= Orientation == Orientation.Vertical ? firstChildDesiredSize.Height : firstChildDesiredSize.Width;
                List <FrameworkElement> reversedChildren = new List <FrameworkElement>(visibleChildren);
                reversedChildren.Reverse();
                reversedChildren.RemoveAt(reversedChildren.Count - 1); // Remove first (home) element
                int   numShownChildrenAfterEllipsis = 0;               // Number of children which fit behind the ellipsis control
                float ellipsisSize = Orientation == Orientation.Vertical ? desiredEllipsisSize.Height : desiredEllipsisSize.Width;
                foreach (FrameworkElement child in reversedChildren)
                {
                    SizeF desiredChildSize = child.DesiredSize;
                    float size             = Orientation == Orientation.Vertical ? desiredChildSize.Height : desiredChildSize.Width;
                    if (availableSize >= size + ellipsisSize ||
                        (availableSize >= size && numShownChildrenAfterEllipsis == visibleChildren.Count - 2))
                    {
                        availableSize -= size;
                        numShownChildrenAfterEllipsis++;
                    }
                    else
                    {
                        break;
                    }
                }
                float startPositionX = 0;
                float startPositionY = 0;
                List <FrameworkElement> childrenAfterEllipsis = new List <FrameworkElement>(visibleChildren);
                if (numShownChildrenAfterEllipsis < visibleChildren.Count - 1)
                { // Ellipsis necessary
                  // Lay out first (home) element
                    SizeF  childSize = firstChild.DesiredSize;
                    PointF position  = new PointF(ActualPosition.X + startPositionX, ActualPosition.Y + startPositionY);

                    if (Orientation == Orientation.Vertical)
                    {
                        childSize.Width = actualWidth;
                        ArrangeChildHorizontal(firstChild, firstChild.HorizontalAlignment, ref position, ref childSize);
                        startPositionY += childSize.Height;
                    }
                    else
                    {
                        childSize.Height = actualHeight;
                        ArrangeChildVertical(firstChild, firstChild.VerticalAlignment, ref position, ref childSize);
                        startPositionX += childSize.Width;
                    }

                    firstChild.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));

                    // Lay out ellipsis
                    if (_ellipsisControl != null)
                    {
                        childSize = desiredEllipsisSize;
                        position  = new PointF(ActualPosition.X + startPositionX, ActualPosition.Y + startPositionY);

                        if (Orientation == Orientation.Vertical)
                        {
                            childSize.Width = actualWidth;
                            ArrangeChildHorizontal(_ellipsisControl, _ellipsisControl.HorizontalAlignment, ref position, ref childSize);
                            startPositionY += childSize.Height;
                        }
                        else
                        {
                            childSize.Height = actualHeight;
                            ArrangeChildVertical(_ellipsisControl, _ellipsisControl.VerticalAlignment, ref position, ref childSize);
                            startPositionX += childSize.Width;
                        }

                        _ellipsisControl.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
                    }

                    int numBeforeEllipsis = childrenAfterEllipsis.Count - numShownChildrenAfterEllipsis;
                    for (int i = 1; i < numBeforeEllipsis; i++)
                    {
                        childrenAfterEllipsis[i].Arrange(RectangleF.Empty);
                    }
                    childrenAfterEllipsis.RemoveRange(0, numBeforeEllipsis);
                }
                else if (_ellipsisControl != null)
                {
                    // childrenAfterEllipsis contains all children in this case
                    _ellipsisControl.Arrange(RectangleF.Empty);
                }

                // Lay out all other elements after ellipsis
                foreach (FrameworkElement child in childrenAfterEllipsis)
                {
                    SizeF  childSize = child.DesiredSize;
                    PointF position  = new PointF(ActualPosition.X + startPositionX, ActualPosition.Y + startPositionY);

                    if (Orientation == Orientation.Vertical)
                    {
                        childSize.Width = actualWidth;
                        ArrangeChildHorizontal(child, child.HorizontalAlignment, ref position, ref childSize);
                        startPositionY += childSize.Height;
                    }
                    else
                    {
                        childSize.Height = actualHeight;
                        ArrangeChildVertical(child, child.VerticalAlignment, ref position, ref childSize);
                        startPositionX += childSize.Width;
                    }

                    child.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
                }
            }
        }
Example #12
0
        /// <summary>
        /// Creates a rectangular <see cref="GraphicsPath"/> with rounded edges, optionally with an open title
        /// region specified by the parameters <paramref name="titleInset"/> and <paramref name="titleWidth"/>.
        /// </summary>
        /// <param name="baseRect">The rect which surrounds the created path.</param>
        /// <param name="radiusX">The X radius of the rounded edges.</param>
        /// <param name="radiusY">The Y radius of the rounded edges.</param>
        /// <param name="withTitleRegion">If set to <c>true</c>, a title region will be left out.</param>
        /// <param name="titleInset">Inset of the title region behind the corner. This parameter will only be used if
        /// <paramref name="withTitleRegion"/> is set to <c>true</c>.</param>
        /// <param name="titleWidth">Width of the title region to leave out. This parameter will only be used if
        /// <paramref name="withTitleRegion"/> is set to <c>true</c>.</param>
        public static GraphicsPath CreateRoundedRectWithTitleRegionPath(RectangleF baseRect, float radiusX, float radiusY,
                                                                        bool withTitleRegion, float titleInset, float titleWidth)
        {
            GraphicsPath result = new GraphicsPath();

            if (radiusX <= 0.0f && radiusY <= 0.0f || baseRect.Width == 0 || baseRect.Height == 0)
            {
                // if corner radius is less than or equal to zero, return the original rectangle
                if (withTitleRegion)
                { // If we should leave out a title region, we need to do it manually, because we need to start next to the
                  // title.

                    titleWidth = Math.Min(titleWidth, baseRect.Width - 2 * titleInset);
                    // Right from the title to the upper right edge
                    result.AddLine(baseRect.Left + 2 * titleInset + titleWidth, baseRect.Top,
                                   baseRect.Right, baseRect.Top);
                    // Upper right edge to lower right edge
                    result.AddLine(baseRect.Right, baseRect.Top,
                                   baseRect.Right, baseRect.Bottom);
                    // Lower right edge to lower left edge
                    result.AddLine(baseRect.Right, baseRect.Bottom,
                                   baseRect.Left, baseRect.Bottom);
                    // Lower left edge to upper left edge
                    result.AddLine(baseRect.Left, baseRect.Bottom,
                                   baseRect.Left, baseRect.Top);
                    // Upper left edge to the left side of the title
                    result.AddLine(baseRect.Left, baseRect.Top, baseRect.Left + titleInset, baseRect.Top);
                }
                else
                {
                    result.AddRectangle(baseRect.ToDrawingRectF());
                }
            }
            else
            {
                if (radiusX >= baseRect.Width / 2f)
                {
                    radiusX = baseRect.Width / 2f;
                }
                if (radiusY >= baseRect.Height / 2f)
                {
                    radiusY = baseRect.Height / 2f;
                }
                // create the arc for the rectangle sides and declare a graphics path object for the drawing
                SizeF      sizeF = new SizeF(radiusX * 2f, radiusY * 2f);
                RectangleF arc   = SharpDXExtensions.CreateRectangleF(baseRect.Location, sizeF);

                if (withTitleRegion)
                {
                    titleWidth = Math.Min(titleWidth, baseRect.Width - 2 * (radiusX + titleInset));
                    // Right of the title to the upper right edge
                    result.AddLine(baseRect.Left + radiusX + titleInset + titleWidth, baseRect.Top,
                                   baseRect.Right - radiusX, baseRect.Top);
                }

                // Top right arc
                arc.X = baseRect.Right - radiusX * 2f;
                result.AddArc(arc.ToDrawingRectF(), 270, 90);

                // Bottom right arc
                arc.Y = baseRect.Bottom - radiusY * 2f;
                result.AddArc(arc.ToDrawingRectF(), 0, 90);

                // Bottom left arc
                arc.X = baseRect.Left;
                result.AddArc(arc.ToDrawingRectF(), 90, 90);

                // Top left arc
                arc.Y = baseRect.Top;
                result.AddArc(arc.ToDrawingRectF(), 180, 90);

                if (withTitleRegion)
                {
                    // Upper left edge to the left side of the title
                    result.AddLine(baseRect.Left + radiusX, baseRect.Top, baseRect.Left + radiusX + titleInset, baseRect.Top);
                }
                else
                {
                    result.CloseFigure();
                }
            }
            result.Flatten();
            return(result);
        }
Example #13
0
        protected override void ArrangeTemplateControl()
        {
            if (_templateControl == null)
            {
                _scrollOffsetX = 0;
                _scrollOffsetY = 0;
            }
            else
            {
                SizeF  desiredSize = _templateControl.DesiredSize;
                PointF position;
                SizeF  availableSize;
                if (_doScroll || AutoCentering != ScrollAutoCenteringEnum.None)
                {
                    availableSize = _innerRect.Size;
                    if (desiredSize.Width > _innerRect.Width)
                    {
                        if (!IsHorzCentering)
                        {
                            _scrollOffsetX = Math.Max(_scrollOffsetX, _innerRect.Width - desiredSize.Width);
                        }
                        availableSize.Width = desiredSize.Width;
                    }
                    else if (!IsHorzCentering)
                    {
                        _scrollOffsetX = 0;
                    }

                    if (desiredSize.Height > _innerRect.Height)
                    {
                        if (!IsVertCentering)
                        {
                            _scrollOffsetY = Math.Max(_scrollOffsetY, _innerRect.Height - desiredSize.Height);
                        }
                        availableSize.Height = desiredSize.Height;
                    }
                    else if (!IsVertCentering)
                    {
                        _scrollOffsetY = 0;
                    }
                    position = new PointF(_innerRect.X + _scrollOffsetX, _innerRect.Y + _scrollOffsetY);
                }
                else
                {
                    _scrollOffsetX = 0;
                    _scrollOffsetY = 0;
                    position       = new PointF(_innerRect.X, _innerRect.Y);
                    availableSize  = _innerRect.Size;
                }

                if (HorizontalFitToSpace)
                {
                    availableSize.Width = _innerRect.Size.Width;
                }
                if (VerticalFitToSpace)
                {
                    availableSize.Height = _innerRect.Size.Height;
                }

                ArrangeChild(_templateControl, _templateControl.HorizontalAlignment, _templateControl.VerticalAlignment,
                             ref position, ref availableSize);
                RectangleF childRect = SharpDXExtensions.CreateRectangleF(position, availableSize);
                _templateControl.Arrange(childRect);
            }
            _actualScrollOffsetX = _scrollOffsetX;
            _actualScrollOffsetY = _scrollOffsetY;
        }
Example #14
0
        protected virtual void ArrangeChildren()
        {
            bool fireScrolled = false;

            _totalHeight = 0;
            _totalWidth  = 0;
            IList <FrameworkElement> visibleChildren = GetVisibleChildren();
            int numVisibleChildren = visibleChildren.Count;

            if (numVisibleChildren > 0)
            {
                PointF actualPosition = ActualPosition;
                SizeF  actualSize     = new SizeF((float)ActualWidth, (float)ActualHeight);

                // For Orientation == vertical, this is ActualHeight, for horizontal it is ActualWidth
                float actualExtendsInOrientationDirection = GetExtendsInOrientationDirection(Orientation, actualSize);
                // For Orientation == vertical, this is ActualWidth, for horizontal it is ActualHeight
                float actualExtendsInNonOrientationDirection = GetExtendsInNonOrientationDirection(Orientation, actualSize);
                // Hint: We cannot skip the arrangement of children above _actualFirstVisibleChildIndex or below _actualLastVisibleChildIndex
                // because the rendering and focus system also needs the bounds of the currently invisible children
                float startPosition = 0;
                // If set to true, we'll check available space from the last to first visible child.
                // That is necessary if we want to scroll a specific child to the last visible position.
                bool invertLayouting = false;
                lock (_renderLock)
                    if (_pendingScrollIndex.HasValue)
                    {
                        fireScrolled = true;
                        int pendingSI = _pendingScrollIndex.Value;
                        if (_scrollToFirst)
                        {
                            _actualFirstVisibleChildIndex = pendingSI;
                        }
                        else
                        {
                            _actualLastVisibleChildIndex = pendingSI;
                            invertLayouting = true;
                        }
                        _pendingScrollIndex = null;
                    }

                // 1) Calculate scroll indices
                if (_doScroll)
                { // Calculate last visible child
                    float spaceLeft = actualExtendsInOrientationDirection;
                    if (invertLayouting)
                    {
                        CalcHelper.Bound(ref _actualLastVisibleChildIndex, 0, numVisibleChildren - 1);
                        _actualFirstVisibleChildIndex = _actualLastVisibleChildIndex + 1;
                        while (_actualFirstVisibleChildIndex > 0)
                        {
                            FrameworkElement child = visibleChildren[_actualFirstVisibleChildIndex - 1];
                            spaceLeft -= GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                            if (spaceLeft + DELTA_DOUBLE < 0)
                            {
                                break; // Found item which is not visible any more
                            }
                            _actualFirstVisibleChildIndex--;
                        }
                        if (_actualFirstVisibleChildIndex > _actualLastVisibleChildIndex)
                        {
                            // Happens if the item at _actualFirstVisibleChildIndex is bigger than the available space
                            _actualFirstVisibleChildIndex = _actualLastVisibleChildIndex;
                        }
                        if (spaceLeft > 0)
                        { // Correct the last scroll index to fill the available space
                            while (_actualLastVisibleChildIndex < numVisibleChildren - 1)
                            {
                                FrameworkElement child = visibleChildren[_actualLastVisibleChildIndex + 1];
                                spaceLeft -= GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                                if (spaceLeft + DELTA_DOUBLE < 0)
                                {
                                    break; // Found item which is not visible any more
                                }
                                _actualLastVisibleChildIndex++;
                            }
                        }
                    }
                    else
                    {
                        CalcHelper.Bound(ref _actualFirstVisibleChildIndex, 0, numVisibleChildren - 1);
                        _actualLastVisibleChildIndex = _actualFirstVisibleChildIndex - 1;
                        while (_actualLastVisibleChildIndex < numVisibleChildren - 1)
                        {
                            FrameworkElement child = visibleChildren[_actualLastVisibleChildIndex + 1];
                            spaceLeft -= GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                            if (spaceLeft + DELTA_DOUBLE < 0)
                            {
                                break; // Found item which is not visible any more
                            }
                            _actualLastVisibleChildIndex++;
                        }
                        if (_actualLastVisibleChildIndex < _actualFirstVisibleChildIndex)
                        {
                            // Happens if the item at _actualFirstVisibleChildIndex is bigger than the available space
                            _actualLastVisibleChildIndex = _actualFirstVisibleChildIndex;
                        }
                        if (spaceLeft > 0)
                        { // Correct the first scroll index to fill the available space
                            while (_actualFirstVisibleChildIndex > 0)
                            {
                                FrameworkElement child = visibleChildren[_actualFirstVisibleChildIndex - 1];
                                spaceLeft -= GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                                if (spaceLeft + DELTA_DOUBLE < 0)
                                {
                                    break; // Found item which is not visible any more
                                }
                                _actualFirstVisibleChildIndex--;
                            }
                        }
                    }
                }
                else
                {
                    _actualFirstVisibleChildIndex = 0;
                    _actualLastVisibleChildIndex  = numVisibleChildren - 1;
                }

                // 2) Calculate start position
                for (int i = 0; i < _actualFirstVisibleChildIndex; i++)
                {
                    FrameworkElement child = visibleChildren[i];
                    startPosition -= GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                }

                // 3) Arrange children
                if (Orientation == Orientation.Vertical)
                {
                    _totalWidth = actualExtendsInNonOrientationDirection;
                }
                else
                {
                    _totalHeight = actualExtendsInNonOrientationDirection;
                }
                foreach (FrameworkElement child in visibleChildren)
                {
                    SizeF childSize = child.DesiredSize;
                    // For Orientation == vertical, this is childSize.Height, for horizontal it is childSize.Width
                    float desiredExtendsInOrientationDirection = GetExtendsInOrientationDirection(Orientation, childSize);
                    if (Orientation == Orientation.Vertical)
                    {
                        PointF position = new PointF(actualPosition.X, actualPosition.Y + startPosition);

                        childSize.Width = actualExtendsInNonOrientationDirection;

                        ArrangeChildHorizontal(child, child.HorizontalAlignment, ref position, ref childSize);
                        child.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
                        _totalHeight += desiredExtendsInOrientationDirection;

                        startPosition += desiredExtendsInOrientationDirection;
                    }
                    else
                    {
                        PointF position = new PointF(actualPosition.X + startPosition, actualPosition.Y);

                        childSize.Height = actualExtendsInNonOrientationDirection;

                        ArrangeChildVertical(child, child.VerticalAlignment, ref position, ref childSize);
                        child.Arrange(SharpDXExtensions.CreateRectangleF(position, childSize));
                        _totalWidth += desiredExtendsInOrientationDirection;

                        startPosition += desiredExtendsInOrientationDirection;
                    }
                }
                // 4) Add size gap for the last item if we use logical scrolling. If we scroll to the bottom/to the right, there might be a gap from the last item
                //    to the end of the area. We need to add that gap to make the scroll bars show the correct size.
                if (_doScroll)
                {
                    float spaceLeft = actualExtendsInOrientationDirection;
                    for (int i = _actualFirstVisibleChildIndex; i <= _actualFirstVisibleChildIndex; i++)
                    {
                        FrameworkElement child     = visibleChildren[i];
                        float            childSize = GetExtendsInOrientationDirection(Orientation, child.DesiredSize);
                        if (childSize < spaceLeft + DELTA_DOUBLE)
                        {
                            spaceLeft -= childSize;
                        }
                        else
                        {
                            if (Orientation == Orientation.Vertical)
                            {
                                _totalHeight += spaceLeft;
                            }
                            else
                            {
                                _totalWidth += spaceLeft;
                            }
                            break;
                        }
                    }
                }
            }
            else
            {
                _actualFirstVisibleChildIndex = 0;
                _actualLastVisibleChildIndex  = -1;
            }
            if (fireScrolled)
            {
                InvokeScrolled();
            }
        }
Example #15
0
        protected override void ArrangeOverride()
        {
            base.ArrangeOverride();
            float offsetTop     = 0.0f;
            float offsetLeft    = 0.0f;
            float offsetRight   = 0.0f;
            float offsetBottom  = 0.0f;
            SizeF availableSize = new SizeF(_innerRect.Width, _innerRect.Height);

            int count = 0;
            // Area allocated to child
            SizeF childArea;

            IList <FrameworkElement> visibleChildren = GetVisibleChildren();

            foreach (FrameworkElement child in visibleChildren)
            {
                count++;
                //Trace.WriteLine(String.Format("DockPanel:arrange {0} {1}", count, child.Name));

                // Size of the child
                SizeF childSize = child.DesiredSize;

                switch (GetDock(child))
                {
                case Dock.Top:
                {
                    PointF location = new PointF(offsetLeft, offsetTop);
                    location.X += ActualPosition.X;
                    location.Y += ActualPosition.Y;

                    // Allocate area to child
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        childArea = new SizeF(availableSize.Width, availableSize.Height);
                    }
                    else
                    {
                        childArea = new SizeF(availableSize.Width, childSize.Height);
                    }

                    // Position the child within the child area
                    ArrangeChildHorizontal(child, child.HorizontalAlignment, ref location, ref childArea);
                    child.Arrange(SharpDXExtensions.CreateRectangleF(location, childArea));

                    offsetTop            += childArea.Height;
                    availableSize.Height -= childArea.Height;
                }
                break;

                case Dock.Bottom:
                {
                    PointF location;
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        location = new PointF(offsetLeft, _innerRect.Height - (offsetBottom + availableSize.Height));
                    }
                    else
                    {
                        location = new PointF(offsetLeft, _innerRect.Height - (offsetBottom + childSize.Height));
                    }

                    location.X += ActualPosition.X;
                    location.Y += ActualPosition.Y;

                    // Allocate area to child
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        childArea = new SizeF(availableSize.Width, availableSize.Height);
                    }
                    else
                    {
                        childArea = new SizeF(availableSize.Width, childSize.Height);
                    }

                    // Position the child within the child area
                    ArrangeChildHorizontal(child, child.HorizontalAlignment, ref location, ref childArea);
                    child.Arrange(SharpDXExtensions.CreateRectangleF(location, childArea));

                    offsetBottom         += childArea.Height;
                    availableSize.Height -= childArea.Height;
                }
                break;

                case Dock.Left:
                {
                    PointF location = new PointF(offsetLeft, offsetTop);
                    location.X += ActualPosition.X;
                    location.Y += ActualPosition.Y;

                    // Allocate area to child
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        childArea = new SizeF(availableSize.Width, availableSize.Height);
                    }
                    else
                    {
                        childArea = new SizeF(childSize.Width, availableSize.Height);
                    }

                    // Position the child within the child area
                    ArrangeChildVertical(child, child.VerticalAlignment, ref location, ref childArea);
                    child.Arrange(SharpDXExtensions.CreateRectangleF(location, childArea));

                    offsetLeft          += childArea.Width;
                    availableSize.Width -= childArea.Width;
                }
                break;

                case Dock.Right:
                {
                    PointF location;
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        location = new PointF(_innerRect.Width - (offsetRight + availableSize.Width), offsetTop);
                    }
                    else
                    {
                        location = new PointF(_innerRect.Width - (offsetRight + childSize.Width), offsetTop);
                    }
                    location.X += ActualPosition.X;
                    location.Y += ActualPosition.Y;

                    // Allocate area to child
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        childArea = new SizeF(availableSize.Width, availableSize.Height);
                    }
                    else
                    {
                        childArea = new SizeF(childSize.Width, availableSize.Height);
                    }

                    // Position the child within the child area
                    ArrangeChildVertical(child, child.VerticalAlignment, ref location, ref childArea);
                    child.Arrange(SharpDXExtensions.CreateRectangleF(location, childArea));

                    offsetRight         += childArea.Width;
                    availableSize.Width -= childArea.Width;
                }
                break;

                default: // Dock.Center
                {
                    PointF location = new PointF(offsetLeft, offsetTop);
                    location.X += ActualPosition.X;
                    location.Y += ActualPosition.Y;
                    childSize   = new SizeF(availableSize.Width, availableSize.Height);
                    if (count == visibleChildren.Count && LastChildFill)
                    {
                        child.Arrange(SharpDXExtensions.CreateRectangleF(location, childSize));
                    }
                    else
                    {
                        ArrangeChild(child, child.HorizontalAlignment, child.VerticalAlignment, ref location, ref childSize);
                        child.Arrange(SharpDXExtensions.CreateRectangleF(location, childSize));
                    }

                    // Do not remove child size from a border offset or from size - the child will
                    // stay in the "empty space" without taking place from the border layouting variables
                }
                break;
                }
            }
        }