Пример #1
0
        private int AddZone()
        {
            GridZone zone;

            if (Model != null)
            {
                IList <int> freeZones = Model.FreeZones;

                // first check free list
                if (freeZones.Count > 0)
                {
                    int freeIndex = freeZones[0];
                    freeZones.RemoveAt(0);
                    zone            = (GridZone)Preview.Children[freeIndex];
                    zone.Visibility = Visibility.Visible;
                    return(freeIndex);
                }
            }

            zone                = new GridZone();
            zone.Split         += OnSplit;
            zone.MergeDrag     += OnMergeDrag;
            zone.MergeComplete += OnMergeComplete;
            zone.FullSplit     += OnFullSplit;
            Preview.Children.Add(zone);
            return(Preview.Children.Count - 1);
        }
Пример #2
0
        private void HandleGridZoneKeyUp(GridZone gridZone, KeyEventArgs e)
        {
            if (e.Key != Key.S)
            {
                return;
            }

            Orientation orient = Orientation.Horizontal;

            Debug.Assert(Preview.Children.Count > Preview.Children.IndexOf(gridZone), "Zone index out of range");

            int offset;

            if (((App)Application.Current).MainWindowSettings.IsShiftKeyPressed)
            {
                orient = Orientation.Vertical;
                offset = gridZone.SnapAtHalfX();
            }
            else
            {
                offset = gridZone.SnapAtHalfY();
            }

            gridZone.DoSplit(orient, offset);
        }
Пример #3
0
        private void SetZonePanelSize(GridZone panel, GridData.Zone zone)
        {
            Size   actualSize = WorkAreaSize();
            double spacing    = Model.ShowSpacing ? Model.Spacing : 0;

            double topSpacing    = zone.Top == 0 ? spacing : spacing / 2;
            double bottomSpacing = zone.Bottom == GridData.Multiplier ? spacing : spacing / 2;
            double leftSpacing   = zone.Left == 0 ? spacing : spacing / 2;
            double rightSpacing  = zone.Right == GridData.Multiplier ? spacing : spacing / 2;

            Canvas.SetTop(panel, (actualSize.Height * zone.Top / GridData.Multiplier) + topSpacing);
            Canvas.SetLeft(panel, (actualSize.Width * zone.Left / GridData.Multiplier) + leftSpacing);
            panel.MinWidth  = Math.Max(1, (actualSize.Width * (zone.Right - zone.Left) / GridData.Multiplier) - leftSpacing - rightSpacing);
            panel.MinHeight = Math.Max(1, (actualSize.Height * (zone.Bottom - zone.Top) / GridData.Multiplier) - topSpacing - bottomSpacing);
        }
Пример #4
0
        private void DeleteZone(int index)
        {
            IList <int> freeZones = Model.FreeZones;

            if (freeZones.Contains(index))
            {
                return;
            }

            freeZones.Add(index);
            GridZone zone = (GridZone)Preview.Children[index];

            zone.Visibility = Visibility.Hidden;
            zone.MinHeight  = 0;
            zone.MinWidth   = 0;
        }
Пример #5
0
        public void ArrangeZones(UIElementCollection zones, int spacing)
        {
            if (zones.Count == 0)
            {
                return;
            }

            int rows = _model.Rows;
            int cols = _model.Columns;

            int[,] cells = _model.CellChildMap;

            if (cells.Length < rows * cols)
            {
                // Merge was not finished yet, rows and cols values are invalid
                return;
            }

            double left, top;

            for (int row = 0; row < rows; row++)
            {
                for (int col = 0; col < cols; col++)
                {
                    int i = cells[row, col];
                    if (((row == 0) || (cells[row - 1, col] != i)) &&
                        ((col == 0) || (cells[row, col - 1] != i)))
                    {
                        // this is not a continuation of a span
                        GridZone zone = (GridZone)zones[i];
                        left = _colInfo[col].Start;
                        top  = _rowInfo[row].Start;
                        Canvas.SetLeft(zone, left);
                        Canvas.SetTop(zone, top);
                        zone.LabelID.Content = i + 1;

                        int maxRow = row;
                        while (((maxRow + 1) < rows) && (cells[maxRow + 1, col] == i))
                        {
                            maxRow++;
                        }

                        zone.HorizontalSnapPoints = null;
                        if (maxRow > row)
                        {
                            zone.HorizontalSnapPoints = new double[maxRow - row];
                            int pointsIndex = 0;
                            for (int walk = row; walk < maxRow; walk++)
                            {
                                zone.HorizontalSnapPoints[pointsIndex++] = _rowInfo[walk].End + (spacing / 2) - top;
                            }
                        }

                        int maxCol = col;
                        while (((maxCol + 1) < cols) && (cells[row, maxCol + 1] == i))
                        {
                            maxCol++;
                        }

                        zone.VerticalSnapPoints = null;
                        if (maxCol > col)
                        {
                            zone.VerticalSnapPoints = new double[maxCol - col];
                            int pointsIndex = 0;
                            for (int walk = col; walk < maxCol; walk++)
                            {
                                zone.VerticalSnapPoints[pointsIndex++] = _colInfo[walk].End + (spacing / 2) - left;
                            }
                        }

                        zone.MinWidth  = _colInfo[maxCol].End - left;
                        zone.MinHeight = _rowInfo[maxRow].End - top;
                    }
                }
            }
        }
Пример #6
0
        private void OnSplit(object o, SplitEventArgs e)
        {
            MergeCancelClick(null, null);

            UIElementCollection previewChildren = Preview.Children;
            GridZone            splitee         = (GridZone)o;

            int             spliteeIndex = previewChildren.IndexOf(splitee);
            GridLayoutModel model        = Model;

            int rows = model.Rows;
            int cols = model.Columns;

            Tuple <int, int> rowCol = _data.RowColByIndex(spliteeIndex);
            int foundRow            = rowCol.Item1;
            int foundCol            = rowCol.Item2;

            int newChildIndex = AddZone();

            double offset = e.Offset;
            double space  = e.Space;

            if (e.Orientation == Orientation.Vertical)
            {
                if (splitee.VerticalSnapPoints != null)
                {
                    offset += Canvas.GetLeft(splitee);
                    int  count = splitee.VerticalSnapPoints.Length;
                    bool foundExistingSplit = false;
                    int  splitCol           = foundCol;

                    for (int i = 0; i <= count; i++)
                    {
                        if (foundExistingSplit)
                        {
                            int walkRow = foundRow;
                            while ((walkRow < rows) && (_data.GetIndex(walkRow, foundCol + i) == spliteeIndex))
                            {
                                _data.SetIndex(walkRow++, foundCol + i, newChildIndex);
                            }
                        }

                        if (_data.ColumnBottom(foundCol + i) == offset)
                        {
                            foundExistingSplit = true;
                            splitCol           = foundCol + i;

                            // use existing division
                        }
                    }

                    if (foundExistingSplit)
                    {
                        _data.ReplaceIndicesToMaintainOrder(Preview.Children.Count);
                        _dragHandles.UpdateForExistingVerticalSplit(model, foundRow, splitCol);
                        OnGridDimensionsChanged();
                        return;
                    }

                    while (_data.ColumnBottom(foundCol) < offset)
                    {
                        foundCol++;
                    }

                    offset -= _data.ColumnTop(foundCol);
                }

                _dragHandles.UpdateAfterVerticalSplit(foundCol);
                _data.SplitColumn(foundCol, spliteeIndex, newChildIndex, space, offset, ActualWidth);
                _dragHandles.AddDragHandle(Orientation.Vertical, foundRow, foundCol, model);
            }
            else
            {
                // Horizontal
                if (splitee.HorizontalSnapPoints != null)
                {
                    offset += Canvas.GetTop(splitee);
                    int  count = splitee.HorizontalSnapPoints.Length;
                    bool foundExistingSplit = false;
                    int  splitRow           = foundRow;

                    for (int i = 0; i <= count; i++)
                    {
                        if (foundExistingSplit)
                        {
                            int walkCol = foundCol;
                            while ((walkCol < cols) && (_data.GetIndex(foundRow + i, walkCol) == spliteeIndex))
                            {
                                _data.SetIndex(foundRow + i, walkCol++, newChildIndex);
                            }
                        }

                        if (_data.RowEnd(foundRow + i) == offset)
                        {
                            foundExistingSplit = true;
                            splitRow           = foundRow + i;

                            // use existing division
                        }
                    }

                    if (foundExistingSplit)
                    {
                        _data.ReplaceIndicesToMaintainOrder(Preview.Children.Count);
                        _dragHandles.UpdateForExistingHorizontalSplit(model, splitRow, foundCol);
                        OnGridDimensionsChanged();
                        return;
                    }

                    while (_data.RowEnd(foundRow) < offset)
                    {
                        foundRow++;
                    }

                    offset -= _data.RowStart(foundRow);
                }

                _dragHandles.UpdateAfterHorizontalSplit(foundRow);
                _data.SplitRow(foundRow, spliteeIndex, newChildIndex, space, offset, ActualHeight);
                _dragHandles.AddDragHandle(Orientation.Horizontal, foundRow, foundCol, model);
            }

            Size actualSize = new Size(ActualWidth, ActualHeight);

            ArrangeGridRects(actualSize);
        }
Пример #7
0
        private void SetupUI()
        {
            Size actualSize = WorkAreaSize();

            if (actualSize.Width < 1 || _data == null || _data.Zones == null || Model == null)
            {
                return;
            }

            int spacing = Model.ShowSpacing ? Model.Spacing : 0;

            _data.MinZoneWidth  = Convert.ToInt32(GridData.Multiplier / actualSize.Width * (MinZoneSize + (2 * spacing)));
            _data.MinZoneHeight = Convert.ToInt32(GridData.Multiplier / actualSize.Height * (MinZoneSize + (2 * spacing)));

            Preview.Children.Clear();
            AdornerLayer.Children.Clear();

            Preview.Width  = actualSize.Width;
            Preview.Height = actualSize.Height;

            MagneticSnap snapX = new MagneticSnap(GridData.PrefixSum(Model.ColumnPercents).GetRange(1, Model.ColumnPercents.Count - 1), actualSize.Width);
            MagneticSnap snapY = new MagneticSnap(GridData.PrefixSum(Model.RowPercents).GetRange(1, Model.RowPercents.Count - 1), actualSize.Height);

            for (int zoneIndex = 0; zoneIndex < _data.Zones.Count; zoneIndex++)
            {
                // this is needed for the lambda
                int zoneIndexCopy = zoneIndex;

                var zone      = _data.Zones[zoneIndex];
                var zonePanel = new GridZone(spacing, snapX, snapY, (orientation, offset) => _data.CanSplit(zoneIndexCopy, offset, orientation), zone);
                zonePanel.UpdateShiftState(((App)Application.Current).MainWindowSettings.IsShiftKeyPressed);
                Preview.Children.Add(zonePanel);
                zonePanel.Split         += OnSplit;
                zonePanel.MergeDrag     += OnMergeDrag;
                zonePanel.MergeComplete += OnMergeComplete;
                SetZonePanelSize(zonePanel, zone);
                zonePanel.LabelID.Content = zoneIndex + 1;
            }

            foreach (var resizer in _data.Resizers)
            {
                var resizerThumb = new GridResizer();
                resizerThumb.DragStarted   += Resizer_DragStarted;
                resizerThumb.DragDelta     += Resizer_DragDelta;
                resizerThumb.DragCompleted += Resizer_DragCompleted;
                resizerThumb.Orientation    = resizer.Orientation;
                AdornerLayer.Children.Add(resizerThumb);

                if (resizer.Orientation == Orientation.Horizontal)
                {
                    resizerThumb.LeftReferenceZone   = resizer.PositiveSideIndices[0];
                    resizerThumb.RightReferenceZone  = resizer.PositiveSideIndices.Last();
                    resizerThumb.TopReferenceZone    = resizer.PositiveSideIndices[0];
                    resizerThumb.BottomReferenceZone = resizer.NegativeSideIndices[0];
                }
                else
                {
                    resizerThumb.LeftReferenceZone   = resizer.PositiveSideIndices[0];
                    resizerThumb.RightReferenceZone  = resizer.NegativeSideIndices[0];
                    resizerThumb.TopReferenceZone    = resizer.PositiveSideIndices[0];
                    resizerThumb.BottomReferenceZone = resizer.PositiveSideIndices.Last();
                }

                PlaceResizer(resizerThumb);
            }
        }
Пример #8
0
        private void ArrangeGridRects(Size arrangeSize)
        {
            GridLayoutModel model = Model;

            if (model == null)
            {
                return;
            }

            Settings settings = ((App)Application.Current).ZoneSettings;

            int spacing, gutter;

            spacing = gutter = settings.ShowSpacing ? settings.Spacing : 0;

            int cols = model.Columns;
            int rows = model.Rows;

            double totalWidth  = arrangeSize.Width - (gutter * 2) - (spacing * (cols - 1));
            double totalHeight = arrangeSize.Height - (gutter * 2) - (spacing * (rows - 1));

            double top = gutter;

            for (int row = 0; row < rows; row++)
            {
                double cellHeight = _rowInfo[row].Recalculate(top, totalHeight);
                top += cellHeight + spacing;
            }

            double left = gutter;

            for (int col = 0; col < cols; col++)
            {
                double cellWidth = _colInfo[col].Recalculate(left, totalWidth);
                left += cellWidth + spacing;
            }

            for (int row = 0; row < rows; row++)
            {
                for (int col = 0; col < cols; col++)
                {
                    int i = model.CellChildMap[row, col];
                    if (((row == 0) || (model.CellChildMap[row - 1, col] != i)) &&
                        ((col == 0) || (model.CellChildMap[row, col - 1] != i)))
                    {
                        // this is not a continuation of a span
                        GridZone zone = (GridZone)Preview.Children[i];
                        left = _colInfo[col].Start;
                        top  = _rowInfo[row].Start;
                        Canvas.SetLeft(zone, left);
                        Canvas.SetTop(zone, top);

                        int maxRow = row;
                        while (((maxRow + 1) < rows) && (model.CellChildMap[maxRow + 1, col] == i))
                        {
                            maxRow++;
                        }

                        zone.HorizontalSnapPoints = null;
                        if (maxRow > row)
                        {
                            zone.HorizontalSnapPoints = new double[maxRow - row];
                            int pointsIndex = 0;
                            for (int walk = row; walk < maxRow; walk++)
                            {
                                zone.HorizontalSnapPoints[pointsIndex++] = _rowInfo[walk].End + (spacing / 2) - top;
                            }
                        }

                        int maxCol = col;
                        while (((maxCol + 1) < cols) && (model.CellChildMap[row, maxCol + 1] == i))
                        {
                            maxCol++;
                        }

                        zone.VerticalSnapPoints = null;
                        if (maxCol > col)
                        {
                            zone.VerticalSnapPoints = new double[maxCol - col];
                            int pointsIndex = 0;
                            for (int walk = col; walk < maxCol; walk++)
                            {
                                zone.VerticalSnapPoints[pointsIndex++] = _colInfo[walk].End + (spacing / 2) - left;
                            }
                        }

                        zone.MinWidth  = _colInfo[maxCol].End - left;
                        zone.MinHeight = _rowInfo[maxRow].End - top;
                    }
                }
            }

            AddDragHandles();
            int childIndex = 0;
            UIElementCollection adornerChildren = AdornerLayer.Children;

            for (int row = 0; row < rows - 1; row++)
            {
                GridResizer resizer  = (GridResizer)adornerChildren[childIndex++];
                int         startCol = -1;
                int         endCol   = cols - 1;
                for (int col = 0; col < cols; col++)
                {
                    if ((startCol == -1) && (model.CellChildMap[row, col] != model.CellChildMap[row + 1, col]))
                    {
                        startCol = col;
                    }
                    else if ((startCol != -1) && (model.CellChildMap[row, col] == model.CellChildMap[row + 1, col]))
                    {
                        endCol = col - 1;
                        break;
                    }
                }

                if (startCol != -1)
                {
                    // hard coding this as (resizer.ActualHeight / 2) will still evaluate to 0 here ... a layout hasn't yet happened
                    Canvas.SetTop(resizer, _rowInfo[row].End + (spacing / 2) - 24);
                    Canvas.SetLeft(resizer, (_colInfo[endCol].End + _colInfo[startCol].Start) / 2);
                }
                else
                {
                    resizer.Visibility = Visibility.Collapsed;
                }
            }

            for (int col = 0; col < cols - 1; col++)
            {
                GridResizer resizer  = (GridResizer)adornerChildren[childIndex++];
                int         startRow = -1;
                int         endRow   = rows - 1;
                for (int row = 0; row < rows; row++)
                {
                    if ((startRow == -1) && (model.CellChildMap[row, col] != model.CellChildMap[row, col + 1]))
                    {
                        startRow = row;
                    }
                    else if ((startRow != -1) && (model.CellChildMap[row, col] == model.CellChildMap[row, col + 1]))
                    {
                        endRow = row - 1;
                        break;
                    }
                }

                if (startRow != -1)
                {
                    Canvas.SetLeft(resizer, _colInfo[col].End + (spacing / 2) - 24); // hard coding this as (resizer.ActualWidth / 2) will still evaluate to 0 here ... a layout hasn't yet happened
                    Canvas.SetTop(resizer, (_rowInfo[endRow].End + _rowInfo[startRow].Start) / 2);
                }
                else
                {
                    resizer.Visibility = Visibility.Collapsed;
                }
            }
        }
Пример #9
0
        private void OnSplit(object o, SplitEventArgs e)
        {
            UIElementCollection previewChildren = Preview.Children;
            GridZone            splitee         = (GridZone)o;

            int             spliteeIndex = previewChildren.IndexOf(splitee);
            GridLayoutModel model        = Model;

            int rows     = model.Rows;
            int cols     = model.Columns;
            int foundRow = -1;
            int foundCol = -1;

            for (int row = 0; row < rows; row++)
            {
                for (int col = 0; col < cols; col++)
                {
                    if (model.CellChildMap[row, col] == spliteeIndex)
                    {
                        foundRow = row;
                        foundCol = col;
                        break;
                    }
                }

                if (foundRow != -1)
                {
                    break;
                }
            }

            int newChildIndex = AddZone();

            double offset = e.Offset;

            if (e.Orientation == Orientation.Vertical)
            {
                if (splitee.VerticalSnapPoints != null)
                {
                    offset += Canvas.GetLeft(splitee);
                    int  count = splitee.VerticalSnapPoints.Length;
                    bool foundExistingSplit = false;

                    for (int i = 0; i <= count; i++)
                    {
                        if (foundExistingSplit)
                        {
                            int walkRow = foundRow;
                            while ((walkRow < rows) && (model.CellChildMap[walkRow, foundCol + i] == spliteeIndex))
                            {
                                model.CellChildMap[walkRow++, foundCol + i] = newChildIndex;
                            }
                        }

                        if (_colInfo[foundCol + i].End == offset)
                        {
                            foundExistingSplit = true;

                            // use existing division
                        }
                    }

                    if (foundExistingSplit)
                    {
                        OnGridDimensionsChanged();
                        return;
                    }

                    while (_colInfo[foundCol].End < offset)
                    {
                        foundCol++;
                    }

                    offset -= _colInfo[foundCol].Start;
                }

                AddDragHandle(Orientation.Vertical, cols - 1);
                cols++;
                int[,] newCellChildMap = new int[rows, cols];
                int[]        newColPercents = new int[cols];
                RowColInfo[] newColInfo     = new RowColInfo[cols];

                int sourceCol = 0;
                for (int col = 0; col < cols; col++)
                {
                    for (int row = 0; row < rows; row++)
                    {
                        if ((col > foundCol) && (model.CellChildMap[row, sourceCol] == spliteeIndex))
                        {
                            newCellChildMap[row, col] = newChildIndex;
                        }
                        else
                        {
                            newCellChildMap[row, col] = model.CellChildMap[row, sourceCol];
                        }
                    }

                    if (col != foundCol)
                    {
                        sourceCol++;
                    }
                }

                model.CellChildMap = newCellChildMap;

                sourceCol = 0;
                for (int col = 0; col < cols; col++)
                {
                    if (col == foundCol)
                    {
                        RowColInfo[] split = _colInfo[col].Split(offset);
                        newColPercents[col] = split[0].Percent;
                        newColInfo[col++]   = split[0];
                        newColPercents[col] = split[1].Percent;
                        newColInfo[col]     = split[1];
                        sourceCol++;
                    }
                    else
                    {
                        newColPercents[col] = model.ColumnPercents[sourceCol];
                        newColInfo[col]     = _colInfo[sourceCol++];
                    }
                }

                _colInfo             = newColInfo;
                model.ColumnPercents = newColPercents;

                model.Columns++;
            }
            else
            {
                // Horizontal
                if (splitee.HorizontalSnapPoints != null)
                {
                    offset += Canvas.GetTop(splitee);
                    int  count = splitee.HorizontalSnapPoints.Length;
                    bool foundExistingSplit = false;

                    for (int i = 0; i <= count; i++)
                    {
                        if (foundExistingSplit)
                        {
                            int walkCol = foundCol;
                            while ((walkCol < cols) && (model.CellChildMap[foundRow + i, walkCol] == spliteeIndex))
                            {
                                model.CellChildMap[foundRow + i, walkCol] = newChildIndex;
                            }
                        }

                        if (_rowInfo[foundRow + i].End == offset)
                        {
                            foundExistingSplit = true;

                            // use existing division
                        }
                    }

                    if (foundExistingSplit)
                    {
                        OnGridDimensionsChanged();
                        return;
                    }

                    while (_rowInfo[foundRow].End < offset)
                    {
                        foundRow++;
                    }

                    offset -= _rowInfo[foundRow].Start;
                }

                AddDragHandle(Orientation.Horizontal, rows - 1);
                rows++;
                int[,] newCellChildMap = new int[rows, cols];
                int[]        newRowPercents = new int[rows];
                RowColInfo[] newRowInfo     = new RowColInfo[rows];

                int sourceRow = 0;
                for (int row = 0; row < rows; row++)
                {
                    for (int col = 0; col < cols; col++)
                    {
                        if ((row > foundRow) && (model.CellChildMap[sourceRow, col] == spliteeIndex))
                        {
                            newCellChildMap[row, col] = newChildIndex;
                        }
                        else
                        {
                            newCellChildMap[row, col] = model.CellChildMap[sourceRow, col];
                        }
                    }

                    if (row != foundRow)
                    {
                        sourceRow++;
                    }
                }

                model.CellChildMap = newCellChildMap;

                sourceRow = 0;
                for (int row = 0; row < rows; row++)
                {
                    if (row == foundRow)
                    {
                        RowColInfo[] split = _rowInfo[row].Split(offset);
                        newRowPercents[row] = split[0].Percent;
                        newRowInfo[row++]   = split[0];
                        newRowPercents[row] = split[1].Percent;
                        newRowInfo[row]     = split[1];
                        sourceRow++;
                    }
                    else
                    {
                        newRowPercents[row] = model.RowPercents[sourceRow];
                        newRowInfo[row]     = _rowInfo[sourceRow++];
                    }
                }

                _rowInfo          = newRowInfo;
                model.RowPercents = newRowPercents;

                model.Rows++;
            }
        }