diff --git a/src/Perspex.Controls/GridSplitter.cs b/src/Perspex.Controls/GridSplitter.cs
index 9a0ef0b988..cb77cb6aad 100644
--- a/src/Perspex.Controls/GridSplitter.cs
+++ b/src/Perspex.Controls/GridSplitter.cs
@@ -2,42 +2,152 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Collections.Generic;
+using System.Linq;
using Perspex.Controls.Primitives;
using Perspex.Input;
-using Perspex.Rendering;
using Perspex.VisualTree;
namespace Perspex.Controls
{
+ ///
+ /// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior. It's GridResizeBehavior.PreviousAndNext
+ ///
public class GridSplitter : Thumb
{
private Grid _grid;
+ private DefinitionBase _prevDefinition;
+
+ private DefinitionBase _nextDefinition;
+
+ private bool _isResizingColumns;
+
+ private List _definitions;
+
///
- /// Initializes a new instance of the class.
+ /// Decide depending on set size
///
- public GridSplitter()
+ ///
+ private bool IsResizingColumns()
+ {
+ if (!double.IsNaN(Width))
+ {
+ return true;
+ }
+ if (!double.IsNaN(Height))
+ {
+ return false;
+ }
+ throw new InvalidOperationException("GridSpliter Should have width or height set. It affects whether columns or rows it resizes");
+ }
+
+ private double GetActualLength(DefinitionBase definition)
{
- Cursor = new Cursor(StandardCursorType.SizeWestEast);
+ var columnDefinition = definition as ColumnDefinition;
+ return columnDefinition?.ActualWidth ?? ((RowDefinition)definition).ActualHeight;
}
+ private double GetMinLength(DefinitionBase definition)
+ {
+ var columnDefinition = definition as ColumnDefinition;
+ return columnDefinition?.MinWidth ?? ((RowDefinition)definition).MinHeight;
+ }
+
+ private double GetMaxLength(DefinitionBase definition)
+ {
+ var columnDefinition = definition as ColumnDefinition;
+ return columnDefinition?.MaxWidth ?? ((RowDefinition)definition).MaxHeight;
+ }
+
+ private bool IsStar(DefinitionBase definition)
+ {
+ var columnDefinition = definition as ColumnDefinition;
+ return columnDefinition?.Width.IsStar ?? ((RowDefinition)definition).Height.IsStar;
+ }
+
+ private void SetLengthInStars(DefinitionBase definition, double value)
+ {
+ var columnDefinition = definition as ColumnDefinition;
+ if (columnDefinition != null)
+ {
+ columnDefinition.Width = new GridLength(value, GridUnitType.Star);
+ }
+ else
+ {
+ ((RowDefinition)definition).Height = new GridLength(value, GridUnitType.Star);
+ }
+ }
+
+
+
+
+ private void GetDeltaConstraints(out double min, out double max)
+ {
+ double prevDefinitionLen = GetActualLength(_prevDefinition);
+ double prevDefinitionMin = GetMinLength(_prevDefinition);
+ double prevDefinitionMax = GetMaxLength(_prevDefinition);
+
+ double nextDefinitionLen = GetActualLength(_nextDefinition);
+ double nextDefinitionMin = GetMinLength(_nextDefinition);
+ double nextDefinitionMax = GetMaxLength(_nextDefinition);
+
+
+ // Determine the minimum and maximum the columns can be resized
+ min = -Math.Min(prevDefinitionLen - prevDefinitionMin, nextDefinitionMax - nextDefinitionLen);
+ max = Math.Min(prevDefinitionMax - prevDefinitionLen, nextDefinitionLen - nextDefinitionMin);
+ }
+
+
protected override void OnDragDelta(VectorEventArgs e)
{
- int col = GetValue(Grid.ColumnProperty);
+ var delta = _isResizingColumns ? e.Vector.X : e.Vector.Y;
+
+ double max;
+ double min;
+ GetDeltaConstraints(out min, out max);
+ delta = Math.Min(Math.Max(delta, min), max);
- if (_grid != null && col > 0)
+
+ foreach (var definition in _definitions)
{
- var size = _grid.ColumnDefinitions[col - 1].ActualWidth + e.Vector.X;
- _grid.ColumnDefinitions[col - 1].Width = new GridLength(
- Math.Max(0, size),
- GridUnitType.Pixel);
+ if (definition == _prevDefinition)
+ {
+ SetLengthInStars(_prevDefinition, GetActualLength(_prevDefinition) + delta);
+ }
+ else if (definition == _nextDefinition)
+ {
+ SetLengthInStars(_nextDefinition, GetActualLength(_nextDefinition) - delta);
+ }
+ else if(IsStar(definition))
+ {
+ SetLengthInStars(definition, GetActualLength(definition)); // same size but in stars
+ }
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
+ //new Range
base.OnAttachedToVisualTree(e);
_grid = this.GetVisualParent();
+ _isResizingColumns = IsResizingColumns();
+ if (_isResizingColumns)
+ {
+ Cursor = new Cursor(StandardCursorType.SizeWestEast);
+ var col = GetValue(Grid.ColumnProperty);
+ _definitions = _grid.ColumnDefinitions.Cast().ToList();
+ _prevDefinition = _definitions[col - 1];
+ _nextDefinition = _definitions[col + 1];
+ }
+ else
+ {
+ Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
+ var row = GetValue(Grid.RowProperty);
+ _definitions = _grid.RowDefinitions.Cast().ToList();
+ _prevDefinition = _definitions[row - 1];
+ _nextDefinition = _definitions[row + 1];
+ }
}
}
}