private void OnFullSplit(object o, SplitEventArgs e) { UIElementCollection previewChildren = Preview.Children; UIElement splitee = (UIElement)o; GridLayoutModel model = Model; int spliteeIndex = previewChildren.IndexOf(splitee); int rows = model.Rows; int cols = model.Columns; _startRow = -1; _startCol = -1; for (int row = rows - 1; row >= 0; row--) { for (int col = cols - 1; col >= 0; col--) { if (model.CellChildMap[row, col] == spliteeIndex) { _dragHandles.RemoveDragHandles(); _startRow = _endRow = row; _startCol = _endCol = col; ExtendRangeToHaveEvenCellEdges(); for (row = _startRow; row <= _endRow; row++) { for (col = _startCol; col <= _endCol; col++) { if ((row != _startRow) || (col != _startCol)) { model.CellChildMap[row, col] = AddZone(); } } } OnGridDimensionsChanged(); return; } } } }
private void GridEditor_Loaded(object sender, RoutedEventArgs e) { GridLayoutModel model = (GridLayoutModel)DataContext; if (model != null) { int rows = model.Rows; int cols = model.Columns; _rowInfo = new RowColInfo[rows]; for (int row = 0; row < rows; row++) { _rowInfo[row] = new RowColInfo(model.RowPercents[row]); } _colInfo = new RowColInfo[cols]; for (int col = 0; col < cols; col++) { _colInfo[col] = new RowColInfo(model.ColumnPercents[col]); } int maxIndex = 0; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { maxIndex = Math.Max(maxIndex, model.CellChildMap[row, col]); } } for (int i = 0; i <= maxIndex; i++) { AddZone(); } } Model = model; if (Model == null) { Model = new GridLayoutModel(); DataContext = Model; } Model.PropertyChanged += OnGridDimensionsChanged; AddDragHandles(); }
public Settings() { ParseCommandLineArgs(); // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid DefaultModels = new List <LayoutModel>(5); _focusModel = new CanvasLayoutModel("Focus", _focusModelId, (int)_workArea.Width, (int)_workArea.Height); DefaultModels.Add(_focusModel); _columnsModel = new GridLayoutModel("Columns", _columnsModelId) { Rows = 1, RowPercents = new int[1] { _multiplier }, }; DefaultModels.Add(_columnsModel); _rowsModel = new GridLayoutModel("Rows", _rowsModelId) { Columns = 1, ColumnPercents = new int[1] { _multiplier }, }; DefaultModels.Add(_rowsModel); _gridModel = new GridLayoutModel("Grid", _gridModelId); DefaultModels.Add(_gridModel); _priorityGridModel = new GridLayoutModel("Priority Grid", _priorityGridModelId); DefaultModels.Add(_priorityGridModel); _blankCustomModel = new CanvasLayoutModel("Create new custom", _blankCustomModelId, (int)_workArea.Width, (int)_workArea.Height); _zoneCount = ReadRegistryInt("ZoneCount", 3); _spacing = ReadRegistryInt("Spacing", 16); _showSpacing = ReadRegistryInt("ShowSpacing", 1) == 1; UpdateLayoutModels(); }
private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args) { Logger.LogTrace(); LayoutModel selectedLayoutModel; if (GridLayoutRadioButton.IsChecked == true) { GridLayoutModel gridModel = new GridLayoutModel(LayoutNameText.Text, LayoutType.Custom) { Rows = 1, RowPercents = new List <int>(1) { GridLayoutModel.GridMultiplier }, }; selectedLayoutModel = gridModel; } else { var area = App.Overlay.WorkArea; CanvasLayoutModel canvasModel = new CanvasLayoutModel(LayoutNameText.Text, LayoutType.Custom, (int)area.Width, (int)area.Height); canvasModel.AddZone(); selectedLayoutModel = canvasModel; } selectedLayoutModel.InitTemplateZones(); try { Hide(); } catch { // See https://github.com/microsoft/PowerToys/issues/9396 Hide(); } App.Overlay.CurrentDataContext = selectedLayoutModel; App.Overlay.OpenEditor(selectedLayoutModel); }
public void UpdateForExistingHorizontalSplit(GridLayoutModel model, int splitRow, int foundCol) { Func <GridResizer, bool> cmpr = (GridResizer resizer) => { return(resizer.Orientation == Orientation.Horizontal && resizer.StartRow == splitRow); }; Func <GridResizer, bool> endCmpr = (GridResizer resizer) => { return(resizer.EndCol == foundCol); }; Func <GridResizer, bool> startCmpr = (GridResizer resizer) => { return(resizer.StartCol == foundCol + 1); }; if (!UpdateDragHandlerForExistingSplit(Orientation.Horizontal, cmpr, endCmpr, startCmpr)) { AddDragHandle(Orientation.Horizontal, splitRow, foundCol, model); } }
private void MergeClick(object sender, RoutedEventArgs e) { GridLayoutModel model = Model; MergePanel.Visibility = Visibility.Collapsed; int mergedIndex = model.CellChildMap[_startRow, _startCol]; for (int row = _startRow; row <= _endRow; row++) { for (int col = _startCol; col <= _endCol; col++) { int childIndex = model.CellChildMap[row, col]; if (childIndex != mergedIndex) { model.CellChildMap[row, col] = mergedIndex; DeleteZone(childIndex); } } } OnGridDimensionsChanged(); ClearSelection(); }
public MainWindowSettingsModel() { // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid DefaultModels = new List <LayoutModel>(5); _focusModel = new CanvasLayoutModel(Properties.Resources.Template_Layout_Focus, LayoutType.Focus); DefaultModels.Add(_focusModel); _columnsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Columns, LayoutType.Columns) { Rows = 1, RowPercents = new List <int>(1) { _multiplier }, }; DefaultModels.Add(_columnsModel); _rowsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Rows, LayoutType.Rows) { Columns = 1, ColumnPercents = new List <int>(1) { _multiplier }, }; DefaultModels.Add(_rowsModel); _gridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Grid, LayoutType.Grid); DefaultModels.Add(_gridModel); _priorityGridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Priority_Grid, LayoutType.PriorityGrid); DefaultModels.Add(_priorityGridModel); _blankCustomModel = new CanvasLayoutModel(Properties.Resources.Custom_Layout_Create_New, LayoutType.Blank); UpdateTemplateLayoutModels(); }
public Settings() { ParseCommandLineArgs(); // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid _defaultModels = new List <LayoutModel>(5); _focusModel = new CanvasLayoutModel("Focus", c_focusModelId, (int)_workArea.Width, (int)_workArea.Height); _defaultModels.Add(_focusModel); _columnsModel = new GridLayoutModel("Columns", c_columnsModelId); _columnsModel.Rows = 1; _columnsModel.RowPercents = new int[1] { c_multiplier }; _defaultModels.Add(_columnsModel); _rowsModel = new GridLayoutModel("Rows", c_rowsModelId); _rowsModel.Columns = 1; _rowsModel.ColumnPercents = new int[1] { c_multiplier }; _defaultModels.Add(_rowsModel); _gridModel = new GridLayoutModel("Grid", c_gridModelId); _defaultModels.Add(_gridModel); _priorityGridModel = new GridLayoutModel("Priority Grid", c_priorityGridModelId); _defaultModels.Add(_priorityGridModel); _blankCustomModel = new CanvasLayoutModel("Create new custom", c_blankCustomModelId, (int)_workArea.Width, (int)_workArea.Height); _zoneCount = (int)Registry.GetValue(_uniqueRegistryPath, "ZoneCount", 3); _spacing = (int)Registry.GetValue(_uniqueRegistryPath, "Spacing", 16); _showSpacing = (int)Registry.GetValue(_uniqueRegistryPath, "ShowSpacing", 1) == 1; UpdateLayoutModels(); }
public Settings() { ParseCommandLineArgs(); // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid DefaultModels = new List <LayoutModel>(5); _focusModel = new CanvasLayoutModel("Focus", LayoutType.Focus, (int)_workArea.Width, (int)_workArea.Height); DefaultModels.Add(_focusModel); _columnsModel = new GridLayoutModel("Columns", LayoutType.Columns) { Rows = 1, RowPercents = new int[1] { _multiplier }, }; DefaultModels.Add(_columnsModel); _rowsModel = new GridLayoutModel("Rows", LayoutType.Rows) { Columns = 1, ColumnPercents = new int[1] { _multiplier }, }; DefaultModels.Add(_rowsModel); _gridModel = new GridLayoutModel("Grid", LayoutType.Grid); DefaultModels.Add(_gridModel); _priorityGridModel = new GridLayoutModel("Priority Grid", LayoutType.PriorityGrid); DefaultModels.Add(_priorityGridModel); _blankCustomModel = new CanvasLayoutModel("Create new custom", LayoutType.Blank, (int)_workArea.Width, (int)_workArea.Height); UpdateLayoutModels(); }
private void ArrangeGridRects(Size arrangeSize) { GridLayoutModel model = Model; if (model == null) { return; } if (model.Rows != model.RowPercents.Count || model.Columns != model.ColumnPercents.Count) { // Merge was not finished return; } Settings settings = ((App)Application.Current).ZoneSettings; int spacing = settings.ShowSpacing ? settings.Spacing : 0; _data.RecalculateZones(spacing, arrangeSize); _data.ArrangeZones(Preview.Children, spacing); _dragHandles.InitDragHandles(model); _data.ArrangeResizers(AdornerLayer.Children, spacing); }
private void RenderPreview() { if (_model == null) { return; } Body.Children.Clear(); GridLayoutModel gridModel = _model as GridLayoutModel; if (gridModel != null) { RenderGridPreview(gridModel); } else { CanvasLayoutModel canvasModel = _model as CanvasLayoutModel; if (canvasModel != null) { RenderCanvasPreview(canvasModel); } } }
private void ModelToZones(GridLayoutModel model) { int rows = model.Rows; int cols = model.Columns; int zoneCount = 0; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { zoneCount = Math.Max(zoneCount, model.CellChildMap[row, col]); } } zoneCount++; if (zoneCount > rows * cols) { throw new ArgumentException("Invalid index found in model.CellChildMap"); } var indexCount = Enumerable.Repeat(0, zoneCount).ToList(); var indexRowLow = Enumerable.Repeat(int.MaxValue, zoneCount).ToList(); var indexRowHigh = Enumerable.Repeat(0, zoneCount).ToList(); var indexColLow = Enumerable.Repeat(int.MaxValue, zoneCount).ToList(); var indexColHigh = Enumerable.Repeat(0, zoneCount).ToList(); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int index = model.CellChildMap[row, col]; indexCount[index]++; indexRowLow[index] = Math.Min(indexRowLow[index], row); indexColLow[index] = Math.Min(indexColLow[index], col); indexRowHigh[index] = Math.Max(indexRowHigh[index], row); indexColHigh[index] = Math.Max(indexColHigh[index], col); } } for (int index = 0; index < zoneCount; index++) { if (indexCount[index] == 0) { throw new ArgumentException("Indices in model.CellChildMap are not contiguous"); } if (indexCount[index] != (indexRowHigh[index] - indexRowLow[index] + 1) * (indexColHigh[index] - indexColLow[index] + 1)) { throw new ArgumentException("One or more indices in model.CellChildMap don't form a rectangle"); } } if (model.RowPercents.Count != rows) { throw new ArgumentException("model.RowPercents has invalid size"); } if (model.ColumnPercents.Count != cols) { throw new ArgumentException("model.ColumnPercents has invalid size"); } if (model.RowPercents.Exists((x) => (x < 1))) { throw new ArgumentException("Invalid value in model.RowPercents"); } if (model.ColumnPercents.Exists((x) => (x < 1))) { throw new ArgumentException("Invalid value in model.ColumnPercents"); } var rowPrefixSum = PrefixSum(model.RowPercents); var colPrefixSum = PrefixSum(model.ColumnPercents); if (rowPrefixSum[rows] != Multiplier || colPrefixSum[cols] != Multiplier) { throw new ArgumentException(); } _zones = new List <Zone>(zoneCount); for (int index = 0; index < zoneCount; index++) { _zones.Add(new Zone { Index = index, Left = colPrefixSum[indexColLow[index]], Right = colPrefixSum[indexColHigh[index] + 1], Top = rowPrefixSum[indexRowLow[index]], Bottom = rowPrefixSum[indexRowHigh[index] + 1], }); } }
private void OnMergeDrag(object o, MouseEventArgs e) { if (_startDragPos.X == -1) { _startDragPos = e.GetPosition(Preview); } GridLayoutModel model = Model; if (_startDragPos.X != -1) { Point dragPos = e.GetPosition(Preview); _startRow = -1; _endRow = -1; _startCol = -1; _endCol = -1; int rows = model.Rows; int cols = model.Columns; double minX, maxX; if (dragPos.X < _startDragPos.X) { minX = dragPos.X; maxX = _startDragPos.X; } else { minX = _startDragPos.X; maxX = dragPos.X; } double minY, maxY; if (dragPos.Y < _startDragPos.Y) { minY = dragPos.Y; maxY = _startDragPos.Y; } else { minY = _startDragPos.Y; maxY = dragPos.Y; } for (int row = 0; row < rows; row++) { if (_startRow == -1) { if (_data.RowEnd(row) > minY) { _startRow = row; } } else if (_data.RowStart(row) > maxY) { _endRow = row - 1; break; } } if ((_startRow >= 0) && (_endRow == -1)) { _endRow = rows - 1; } for (int col = 0; col < cols; col++) { if (_startCol == -1) { if (_data.ColumnBottom(col) > minX) { _startCol = col; } } else if (_data.ColumnTop(col) > maxX) { _endCol = col - 1; break; } } if ((_startCol >= 0) && (_endCol == -1)) { _endCol = cols - 1; } ExtendRangeToHaveEvenCellEdges(); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { ((GridZone)Preview.Children[model.CellChildMap[row, col]]).IsSelected = (row >= _startRow) && (row <= _endRow) && (col >= _startCol) && (col <= _endCol); } } e.Handled = true; } OnPreviewMouseMove(e); }
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); }
private void RenderActualScalePreview(GridLayoutModel grid) { int rows = grid.Rows; int cols = grid.Columns; double spacing = grid.ShowSpacing ? grid.Spacing : 0; var rowData = GridData.PrefixSum(grid.RowPercents); var columnData = GridData.PrefixSum(grid.ColumnPercents); var workArea = App.Overlay.WorkArea; Viewbox viewbox = new Viewbox { Stretch = Stretch.Uniform, }; Body.Children.Add(viewbox); Canvas frame = new Canvas { Width = workArea.Width, Height = workArea.Height, }; viewbox.Child = frame; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int childIndex = grid.CellChildMap[row, col]; if (((row == 0) || (grid.CellChildMap[row - 1, col] != childIndex)) && ((col == 0) || (grid.CellChildMap[row, col - 1] != childIndex))) { // this is not a continuation of a span Border rect = new Border(); double left = columnData[col] * workArea.Width / GridData.Multiplier; double top = rowData[row] * workArea.Height / GridData.Multiplier; int maxRow = row; while (((maxRow + 1) < rows) && (grid.CellChildMap[maxRow + 1, col] == childIndex)) { maxRow++; } int maxCol = col; while (((maxCol + 1) < cols) && (grid.CellChildMap[row, maxCol + 1] == childIndex)) { maxCol++; } double right = columnData[maxCol + 1] * workArea.Width / GridData.Multiplier; double bottom = rowData[maxRow + 1] * workArea.Height / GridData.Multiplier; left += col == 0 ? spacing : spacing / 2; right -= maxCol == cols - 1 ? spacing : spacing / 2; top += row == 0 ? spacing : spacing / 2; bottom -= maxRow == rows - 1 ? spacing : spacing / 2; Canvas.SetTop(rect, top); Canvas.SetLeft(rect, left); rect.Width = Math.Max(1, right - left); rect.Height = Math.Max(1, bottom - top); rect.Style = (Style)FindResource("GridLayoutActualScalePreviewStyle"); frame.Children.Add(rect); } } } if (App.DebugMode) { TextBlock text = new TextBlock(); text.Text = "(" + workArea.X + "," + workArea.Y + ")"; text.FontSize = 42; frame.Children.Add(text); } }
private void RenderSmallScalePreview(GridLayoutModel grid) { foreach (int percent in grid.RowPercents) { RowDefinition def = new RowDefinition { Height = new GridLength(percent, GridUnitType.Star), }; Body.RowDefinitions.Add(def); } foreach (int percent in grid.ColumnPercents) { ColumnDefinition def = new ColumnDefinition { Width = new GridLength(percent, GridUnitType.Star), }; Body.ColumnDefinitions.Add(def); } MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; Thickness margin = new Thickness(settings.ShowSpacing ? settings.Spacing / 20 : 0); List <int> visited = new List <int>(); for (int row = 0; row < grid.Rows; row++) { for (int col = 0; col < grid.Columns; col++) { int childIndex = grid.CellChildMap[row, col]; if (!visited.Contains(childIndex)) { visited.Add(childIndex); Rectangle rect = new Rectangle(); Grid.SetRow(rect, row); Grid.SetColumn(rect, col); int span = 1; int walk = row + 1; while ((walk < grid.Rows) && grid.CellChildMap[walk, col] == childIndex) { span++; walk++; } Grid.SetRowSpan(rect, span); span = 1; walk = col + 1; while ((walk < grid.Columns) && grid.CellChildMap[row, walk] == childIndex) { span++; walk++; } Grid.SetColumnSpan(rect, span); rect.Margin = margin; rect.StrokeThickness = 1; rect.Stroke = Brushes.DarkGray; rect.Fill = Brushes.LightGray; Body.Children.Add(rect); } } } }
private void FromModel(GridLayoutModel model) { ModelToZones(model); ModelToResizers(model); }
private void ModelToResizers(GridLayoutModel model) { // Short name, to avoid clutter var grid = model.CellChildMap; int rows = model.Rows; int cols = model.Columns; _resizers = new List <Resizer>(); // Horizontal for (int row = 1; row < rows; row++) { for (int startCol = 0; startCol < cols;) { if (grid[row - 1, startCol] != grid[row, startCol]) { int endCol = startCol; while (endCol + 1 < cols && grid[row - 1, endCol + 1] != grid[row, endCol + 1]) { endCol++; } var resizer = default(Resizer); resizer.Orientation = Orientation.Horizontal; var positive = new List <int>(); var negative = new List <int>(); for (int col = startCol; col <= endCol; col++) { negative.Add(grid[row - 1, col]); positive.Add(grid[row, col]); } resizer.PositiveSideIndices = Unique(positive); resizer.NegativeSideIndices = Unique(negative); _resizers.Add(resizer); startCol = endCol + 1; } else { startCol++; } } } // Vertical for (int col = 1; col < cols; col++) { for (int startRow = 0; startRow < rows;) { if (grid[startRow, col - 1] != grid[startRow, col]) { int endRow = startRow; while (endRow + 1 < rows && grid[endRow + 1, col - 1] != grid[endRow + 1, col]) { endRow++; } var resizer = default(Resizer); resizer.Orientation = Orientation.Vertical; var positive = new List <int>(); var negative = new List <int>(); for (int row = startRow; row <= endRow; row++) { negative.Add(grid[row, col - 1]); positive.Add(grid[row, col]); } resizer.PositiveSideIndices = Unique(positive); resizer.NegativeSideIndices = Unique(negative); _resizers.Add(resizer); startRow = endRow + 1; } else { startRow++; } } } }
public void AddDragHandle(Orientation orientation, int foundRow, int foundCol, GridLayoutModel model) { int[,] indices = model.CellChildMap; int endRow = foundRow + 1; while (endRow < model.Rows && indices[endRow, foundCol] == indices[endRow - 1, foundCol]) { endRow++; } int endCol = foundCol + 1; while (endCol < model.Columns && indices[foundRow, endCol] == indices[foundRow, endCol - 1]) { endCol++; } int index = (orientation == Orientation.Horizontal) ? foundRow : foundCol + model.Rows - 1; AddDragHandle(orientation, foundRow, endRow, foundCol, endCol, index); }
private void RenderActualScalePreview(GridLayoutModel grid) { int rows = grid.Rows; int cols = grid.Columns; RowColInfo[] rowInfo = (from percent in grid.RowPercents select new RowColInfo(percent)).ToArray(); RowColInfo[] colInfo = (from percent in grid.ColumnPercents select new RowColInfo(percent)).ToArray(); int spacing = grid.ShowSpacing ? grid.Spacing : 0; var workArea = App.Overlay.WorkArea; double width = workArea.Width - (spacing * (cols + 1)); double height = workArea.Height - (spacing * (rows + 1)); double top = spacing; for (int row = 0; row < rows; row++) { double cellHeight = rowInfo[row].Recalculate(top, height); top += cellHeight + spacing; } double left = spacing; for (int col = 0; col < cols; col++) { double cellWidth = colInfo[col].Recalculate(left, width); left += cellWidth + spacing; } Viewbox viewbox = new Viewbox { Stretch = Stretch.Uniform, }; Body.Children.Add(viewbox); Canvas frame = new Canvas { Width = workArea.Width, Height = workArea.Height, }; viewbox.Child = frame; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int childIndex = grid.CellChildMap[row, col]; if (((row == 0) || (grid.CellChildMap[row - 1, col] != childIndex)) && ((col == 0) || (grid.CellChildMap[row, col - 1] != childIndex))) { // this is not a continuation of a span Border rect = new Border(); left = colInfo[col].Start; top = rowInfo[row].Start; Canvas.SetTop(rect, top); Canvas.SetLeft(rect, left); int maxRow = row; while (((maxRow + 1) < rows) && (grid.CellChildMap[maxRow + 1, col] == childIndex)) { maxRow++; } int maxCol = col; while (((maxCol + 1) < cols) && (grid.CellChildMap[row, maxCol + 1] == childIndex)) { maxCol++; } rect.Width = Math.Max(0, colInfo[maxCol].End - left); rect.Height = Math.Max(0, rowInfo[maxRow].End - top); rect.Style = (Style)FindResource("GridLayoutPreviewActualSizeStyle"); frame.Children.Add(rect); _zones.Add(new Int32Rect( (int)left, (int)top, (int)rect.Width, (int)rect.Height)); } } } if (App.DebugMode) { TextBlock text = new TextBlock(); text.Text = "(" + workArea.X + "," + workArea.Y + ")"; text.FontSize = 42; frame.Children.Add(text); } }
protected new void OnCancel(object sender, RoutedEventArgs e) { base.OnCancel(sender, e); GridLayoutModel model = EditorOverlay.Current.DataContext as GridLayoutModel; _stashedModel.RestoreTo(model); }
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; } } }
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++; } }
private void ExtendRangeToHaveEvenCellEdges() { // extend each edge of the [(_startCol, _startRow) - (_endCol, _endRow)] range based on merged cells until you have 4 straight edges with no "straddling cells" GridLayoutModel model = Model; while (_startRow > 0) { bool dirty = false; for (int col = _startCol; col <= _endCol; col++) { if (model.CellChildMap[_startRow - 1, col] == model.CellChildMap[_startRow, col]) { _startRow--; dirty = true; break; } } if (!dirty) { break; } } while (_endRow < model.Rows - 1) { bool dirty = false; for (int col = _startCol; col <= _endCol; col++) { if (model.CellChildMap[_endRow + 1, col] == model.CellChildMap[_endRow, col]) { _endRow++; dirty = true; break; } } if (!dirty) { break; } } while (_startCol > 0) { bool dirty = false; for (int row = _startRow; row <= _endRow; row++) { if (model.CellChildMap[row, _startCol - 1] == model.CellChildMap[row, _startCol]) { _startCol--; dirty = true; break; } } if (!dirty) { break; } } while (_endCol < model.Columns - 1) { bool dirty = false; for (int row = _startRow; row <= _endRow; row++) { if (model.CellChildMap[row, _endCol + 1] == model.CellChildMap[row, _endCol]) { _endCol++; dirty = true; break; } } if (!dirty) { break; } } }
private void RenderSmallScalePreview(GridLayoutModel grid) { foreach (int percent in grid.RowPercents) { RowDefinition def = new RowDefinition { Height = new GridLength(percent, GridUnitType.Star), }; Body.RowDefinitions.Add(def); } foreach (int percent in grid.ColumnPercents) { ColumnDefinition def = new ColumnDefinition { Width = new GridLength(percent, GridUnitType.Star), }; Body.ColumnDefinitions.Add(def); } Thickness margin = new Thickness(grid.ShowSpacing ? grid.Spacing / 20 : 0); List <int> visited = new List <int>(); for (int row = 0; row < grid.Rows; row++) { for (int col = 0; col < grid.Columns; col++) { int childIndex = grid.CellChildMap[row, col]; if (!visited.Contains(childIndex)) { visited.Add(childIndex); Border rect = new Border(); Grid.SetRow(rect, row); Grid.SetColumn(rect, col); int span = 1; int walk = row + 1; while ((walk < grid.Rows) && grid.CellChildMap[walk, col] == childIndex) { span++; walk++; } Grid.SetRowSpan(rect, span); span = 1; walk = col + 1; while ((walk < grid.Columns) && grid.CellChildMap[row, walk] == childIndex) { span++; walk++; } Grid.SetColumnSpan(rect, span); rect.Margin = margin; rect.Style = (Style)FindResource("GridLayoutPreviewStyle"); Body.Children.Add(rect); } } } }
private void RenderActualScalePreview(GridLayoutModel grid) { int rows = grid.Rows; int cols = grid.Columns; RowColInfo[] rowInfo = (from percent in grid.RowPercents select new RowColInfo(percent)).ToArray(); RowColInfo[] colInfo = (from percent in grid.ColumnPercents select new RowColInfo(percent)).ToArray(); Settings settings = ((App)Application.Current).ZoneSettings; int spacing = settings.ShowSpacing ? settings.Spacing : 0; int width = (int)Settings.WorkArea.Width; int height = (int)Settings.WorkArea.Height; double totalWidth = width - (spacing * (cols + 1)); double totalHeight = height - (spacing * (rows + 1)); double top = spacing; for (int row = 0; row < rows; row++) { double cellHeight = rowInfo[row].Recalculate(top, totalHeight); top += cellHeight + spacing; } double left = spacing; for (int col = 0; col < cols; col++) { double cellWidth = colInfo[col].Recalculate(left, totalWidth); left += cellWidth + spacing; } Viewbox viewbox = new Viewbox { Stretch = Stretch.Uniform, }; Body.Children.Add(viewbox); Canvas frame = new Canvas { Width = width, Height = height, }; viewbox.Child = frame; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int childIndex = grid.CellChildMap[row, col]; if (((row == 0) || (grid.CellChildMap[row - 1, col] != childIndex)) && ((col == 0) || (grid.CellChildMap[row, col - 1] != childIndex))) { // this is not a continuation of a span Rectangle rect = new Rectangle(); left = colInfo[col].Start; top = rowInfo[row].Start; Canvas.SetTop(rect, top); Canvas.SetLeft(rect, left); int maxRow = row; while (((maxRow + 1) < rows) && (grid.CellChildMap[maxRow + 1, col] == childIndex)) { maxRow++; } int maxCol = col; while (((maxCol + 1) < cols) && (grid.CellChildMap[row, maxCol + 1] == childIndex)) { maxCol++; } rect.Width = colInfo[maxCol].End - left; rect.Height = rowInfo[maxRow].End - top; rect.StrokeThickness = 1; rect.Stroke = Brushes.DarkGray; rect.Fill = Brushes.LightGray; frame.Children.Add(rect); _zones.Add(new Int32Rect( (int)left, (int)top, (int)rect.Width, (int)rect.Height)); } } } }
private bool SetCustomLayouts(List <CustomLayoutWrapper> customLayouts) { if (customLayouts == null) { return(false); } MainWindowSettingsModel.CustomModels.Clear(); bool result = true; foreach (var zoneSet in customLayouts) { if (zoneSet.Uuid == null || zoneSet.Uuid.Length == 0) { result = false; continue; } LayoutModel layout; if (zoneSet.Type == CanvasLayoutModel.ModelTypeID) { var info = JsonSerializer.Deserialize <CanvasInfoWrapper>(zoneSet.Info.GetRawText(), _options); var zones = new List <Int32Rect>(); foreach (var zone in info.Zones) { zones.Add(new Int32Rect { X = (int)zone.X, Y = (int)zone.Y, Width = (int)zone.Width, Height = (int)zone.Height }); } try { layout = new CanvasLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, zones, info.RefWidth, info.RefHeight); } catch (Exception) { continue; } layout.SensitivityRadius = info.SensitivityRadius; } else if (zoneSet.Type == GridLayoutModel.ModelTypeID) { var info = JsonSerializer.Deserialize <GridInfoWrapper>(zoneSet.Info.GetRawText(), _options); var cells = new int[info.Rows, info.Columns]; for (int row = 0; row < info.Rows; row++) { for (int column = 0; column < info.Columns; column++) { cells[row, column] = info.CellChildMap[row][column]; } } try { layout = new GridLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells); } catch (Exception) { continue; } layout.SensitivityRadius = info.SensitivityRadius; (layout as GridLayoutModel).ShowSpacing = info.ShowSpacing; (layout as GridLayoutModel).Spacing = info.Spacing; } else { result = false; continue; } MainWindowSettingsModel.CustomModels.Add(layout); } return(result); }
private void ModelToZones(GridLayoutModel model) { int rows = model.Rows; int cols = model.Columns; int zoneCount = 0; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { zoneCount = Math.Max(zoneCount, model.CellChildMap[row, col]); } } zoneCount++; if (zoneCount > rows * cols) { return; } var indexCount = Enumerable.Repeat(0, zoneCount).ToList(); var indexRowLow = Enumerable.Repeat(int.MaxValue, zoneCount).ToList(); var indexRowHigh = Enumerable.Repeat(0, zoneCount).ToList(); var indexColLow = Enumerable.Repeat(int.MaxValue, zoneCount).ToList(); var indexColHigh = Enumerable.Repeat(0, zoneCount).ToList(); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { int index = model.CellChildMap[row, col]; indexCount[index]++; indexRowLow[index] = Math.Min(indexRowLow[index], row); indexColLow[index] = Math.Min(indexColLow[index], col); indexRowHigh[index] = Math.Max(indexRowHigh[index], row); indexColHigh[index] = Math.Max(indexColHigh[index], col); } } for (int index = 0; index < zoneCount; index++) { if (indexCount[index] == 0) { return; } if (indexCount[index] != (indexRowHigh[index] - indexRowLow[index] + 1) * (indexColHigh[index] - indexColLow[index] + 1)) { return; } } if (model.RowPercents.Count != model.Rows || model.ColumnPercents.Count != model.Columns || model.RowPercents.Exists((x) => (x < 1)) || model.ColumnPercents.Exists((x) => (x < 1))) { return; } var rowPrefixSum = PrefixSum(model.RowPercents); var colPrefixSum = PrefixSum(model.ColumnPercents); if (rowPrefixSum[rows] != Multiplier || colPrefixSum[cols] != Multiplier) { return; } _zones = new List <Zone>(zoneCount); for (int index = 0; index < zoneCount; index++) { _zones.Add(new Zone { Index = index, Left = colPrefixSum[indexColLow[index]], Right = colPrefixSum[indexColHigh[index] + 1], Top = rowPrefixSum[indexRowLow[index]], Bottom = rowPrefixSum[indexRowHigh[index] + 1], }); } }