Пример #1
0
        /// <summary>
        /// Calculates a rectangle that contains the specified location
        /// </summary>
        /// <param name="location">The location to test against</param>
        /// <returns>If the specified location is enclosed within the rectangle, returned rectangle is
        /// identical to the current one. Otherwise, returned rectangle's edges are extended to ensure
        /// the location is enclosed by the returned rectangle</returns>
        public MatrixRect GrowTo(MatrixLoc location)
        {
            MatrixRect rect = this;

            if (location.Row < rect.Row)
            {
                rect.RowCount += rect.Row - location.Row;
                rect.Row       = location.Row;
            }
            else if (location.Row >= rect.LastRow)
            {
                rect.RowCount += location.Row - rect.LastRow + 1;
            }

            if (location.Column < rect.Column)
            {
                rect.ColumnCount += rect.Column - location.Column;
                rect.Column       = location.Column;
            }
            else if (location.Column >= rect.LastColumn)
            {
                rect.ColumnCount += location.Column - rect.LastColumn + 1;
            }

            return(rect);
        }
Пример #2
0
        /// <summary>
        /// Resizes the container to the specified size
        /// </summary>
        /// <param name="newSize">New size to which the container is to be resized</param>
        /// <param name="justify">Resize justification, which indicates the edge at which widgets are to
        /// remain in their current positions (i.e. right justification will make the left edge move left/right
        /// while right edge's location stays constant)</param>
        public void Resize(MatrixSize newSize, WidgetContainerResizeJustify justify)
        {
            if (newSize.RowCount > 256 || newSize.ColumnCount > 256)
            {
                throw new ApplicationException(string.Format("Attemp to allocate too much ({0} x {1})",
                                                             newSize.RowCount, newSize.ColumnCount));
            }
            else if (newSize == this.Bounds.Size)
            {
                return;
            }

            Validate();

            MatrixSize currentSize = this.Size;
            MatrixSize originShift = currentSize - newSize;

            if (!justify.HasFlag(WidgetContainerResizeJustify.Bottom))
            {
                originShift.RowCount = 0;
            }
            if (!justify.HasFlag(WidgetContainerResizeJustify.Right))
            {
                originShift.ColumnCount = 0;
            }

            MatrixRect newContainerBounds = new MatrixRect(
                _containerBounds.Location + originShift, newSize);

            // Cells in the intersection of original bounding rectangle and the new bounding
            // rectangle are the ones that will survive the resize operation. Once we identify
            // the intersection of the two rectangles, we need to iterate through the original
            // array and copy those cells into the new array
            MatrixRect existingCellBounds = _containerBounds.Intersect(newContainerBounds);

            // normalize existing cell bounding box around 0-based arrays.
            existingCellBounds.Location =
                new MatrixLoc(originShift.RowCount > 0 ? originShift.RowCount : 0,
                              originShift.ColumnCount > 0 ? originShift.ColumnCount : 0);

            Array2D <WidgetData> newArray = new Array2D <WidgetData>(newSize);

            foreach (var loc in existingCellBounds)
            {
                newArray[loc - originShift] = _widgetArray[loc];
            }

            _widgetArray     = newArray;
            _containerBounds = newContainerBounds;

            this.IsDirty = true;

            Validate();

            OnContainerResized();

            Validate();
        }
Пример #3
0
        /// <summary>
        /// Returns a new rectangle which represents the intersection between current rectangle
        /// and the second one which is passed in
        /// </summary>
        /// <param name="other">The other rectangle to test against</param>
        /// <returns>A rectangle which represents the intersection</returns>
        public MatrixRect Intersect(MatrixRect other)
        {
            MatrixLoc topLeft = new MatrixLoc(Math.Max(this.Row, other.Row),
                                              Math.Max(this.Column, other.Column));
            MatrixLoc bottomRight = new MatrixLoc(Math.Min(this.LastRow, other.LastRow),
                                                  Math.Min(this.LastColumn, other.LastColumn));
            MatrixSize size = bottomRight - topLeft;

            if (size.ColumnCount < 0)
            {
                size.ColumnCount = 0;
            }
            if (size.RowCount < 0)
            {
                size.RowCount = 0;
            }

            return(new MatrixRect(topLeft, size));
        }
Пример #4
0
        private void SetWidget(MatrixLoc location, WidgetData widget)
        {
            WidgetData removedWidget = null;

            Validate();

            // the same widget is being inserted at the same spot where it is already located,
            // let not do anything and just exit
            if (widget != null && widget.Parent == this && widget.Location == location)
            {
                return;
            }

            MatrixRect neededBounds = _containerBounds.GrowTo(location);

            // If the cell being modified within the bounds of the current array, let's make sure
            // the existing cell is empty.  Otherwise, we need to reallocate the array before
            // we can assign the widget to it.
            if (neededBounds.Size == _containerBounds.Size)
            {
                removedWidget = ClearWidget(location);
            }
            else if (widget != null)
            {
                WidgetContainerResizeJustify resizeJustify =
                    (_containerBounds.Row == neededBounds.Row ?
                     WidgetContainerResizeJustify.Top : WidgetContainerResizeJustify.Bottom) |
                    (_containerBounds.Column == neededBounds.Column ?
                     WidgetContainerResizeJustify.Left : WidgetContainerResizeJustify.Right);

                Resize(neededBounds.Size, resizeJustify);
            }

            Validate();

            if (widget != null)
            {
                if (widget.HasOwner)
                {
                    widget.Parent.Remove(widget);
                }

                _widgetArray[_containerBounds.ToIndex(location)] = widget;

                widget.SetOwner(this, location);
                widget.IsDirtyChanged += OnChildIsDirtyChanged;

                if (removedWidget != null)
                {
                    OnWidgetReplaced(location, removedWidget, widget);
                    removedWidget = null;
                }
                else
                {
                    OnWidgetAdded(location, widget);
                }
            }

            if (removedWidget != null)
            {
                OnWidgetRemoved(location, removedWidget);
            }

            Validate();

            IsDirty = true;
        }