From ef06e796674b206bcacdd38fb70de9028cae8d0e Mon Sep 17 00:00:00 2001 From: susloparov Date: Thu, 10 Dec 2015 18:57:25 +0600 Subject: [PATCH 1/7] First grid splitter implementation --- src/Perspex.Controls/GridSplitter.cs | 130 ++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 10 deletions(-) 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]; + } } } } From 981ec53d074c12a0d6dd2afb64ae6f04e789971f Mon Sep 17 00:00:00 2001 From: susloparov Date: Thu, 10 Dec 2015 20:28:38 +0600 Subject: [PATCH 2/7] Seperated GridSplitter into HorizontalGridSplitter and VerticalGridSplitter --- src/Perspex.Controls/GridSplitter.cs | 194 +++++++++++------- .../Views/LogicalTreeView.cs | 2 +- .../Views/VisualTreeView.cs | 2 +- src/Perspex.Themes.Default/DefaultTheme.paml | 4 +- ...itter.paml => HorizontalGridSplitter.paml} | 4 +- .../Perspex.Themes.Default.csproj | 5 +- .../VerticalGridSplitter.paml | 8 + 7 files changed, 138 insertions(+), 81 deletions(-) rename src/Perspex.Themes.Default/{GridSplitter.paml => HorizontalGridSplitter.paml} (53%) create mode 100644 src/Perspex.Themes.Default/VerticalGridSplitter.paml diff --git a/src/Perspex.Controls/GridSplitter.cs b/src/Perspex.Controls/GridSplitter.cs index cb77cb6aad..b4e76ad41e 100644 --- a/src/Perspex.Controls/GridSplitter.cs +++ b/src/Perspex.Controls/GridSplitter.cs @@ -2,8 +2,8 @@ // 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.Collections; using Perspex.Controls.Primitives; using Perspex.Input; using Perspex.VisualTree; @@ -13,17 +13,16 @@ namespace Perspex.Controls /// /// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior. It's GridResizeBehavior.PreviousAndNext /// - public class GridSplitter : Thumb + public abstract class GridSplitterBase : Thumb + where T : DefinitionBase { - private Grid _grid; - - private DefinitionBase _prevDefinition; + protected PerspexList _definitions; - private DefinitionBase _nextDefinition; + protected Grid _grid; - private bool _isResizingColumns; + protected T _nextDefinition; - private List _definitions; + protected T _prevDefinition; /// /// Decide depending on set size @@ -42,73 +41,40 @@ namespace Perspex.Controls throw new InvalidOperationException("GridSpliter Should have width or height set. It affects whether columns or rows it resizes"); } - private double GetActualLength(DefinitionBase definition) - { - 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; - } + protected abstract double GetActualLength(T definition); - 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); - } - } + protected abstract double GetMinLength(T definition); + protected abstract double GetMaxLength(T definition); + protected abstract bool IsStar(T definition); + protected abstract void SetLengthInStars(T definition, double value); 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); + var prevDefinitionLen = GetActualLength(_prevDefinition); + var prevDefinitionMin = GetMinLength(_prevDefinition); + var prevDefinitionMax = GetMaxLength(_prevDefinition); + var nextDefinitionLen = GetActualLength(_nextDefinition); + var nextDefinitionMin = GetMinLength(_nextDefinition); + var 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) { - var delta = _isResizingColumns ? e.Vector.X : e.Vector.Y; + var delta = GetDelta(e); double max; double min; GetDeltaConstraints(out min, out max); delta = Math.Min(Math.Max(delta, min), max); - foreach (var definition in _definitions) { if (definition == _prevDefinition) @@ -119,35 +85,115 @@ namespace Perspex.Controls { SetLengthInStars(_nextDefinition, GetActualLength(_nextDefinition) - delta); } - else if(IsStar(definition)) + else if (IsStar(definition)) { SetLengthInStars(definition, GetActualLength(definition)); // same size but in stars } } } + protected abstract double GetDelta(VectorEventArgs vectorEventArgs); + 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]; - } } } -} + + public class HorizontalGridSplitter : GridSplitterBase + { + public HorizontalGridSplitter() + { + Cursor = new Cursor(StandardCursorType.SizeNorthSouth); + } + + protected override double GetActualLength(RowDefinition definition) + { + return definition.ActualHeight; + } + + protected override double GetMaxLength(RowDefinition definition) + { + return definition.MaxHeight; + } + + protected override double GetMinLength(RowDefinition definition) + { + return definition.MinHeight; + } + + protected override bool IsStar(RowDefinition definition) + { + return definition.Height.IsStar; + } + + protected override double GetDelta(VectorEventArgs vectorEventArgs) + { + return vectorEventArgs.Vector.Y; + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + var row = GetValue(Grid.RowProperty); + _definitions = _grid.RowDefinitions; + _prevDefinition = _definitions[row - 1]; + _nextDefinition = _definitions[row + 1]; + } + + protected override void SetLengthInStars(RowDefinition definition, double value) + { + definition.Height = new GridLength(value, GridUnitType.Star); + } + } + + public class VerticalGridSplitter : GridSplitterBase + { + + + + public VerticalGridSplitter() + { + Cursor = new Cursor(StandardCursorType.SizeWestEast); + } + + protected override double GetActualLength(ColumnDefinition definition) + { + return definition.ActualWidth; + } + + protected override double GetMaxLength(ColumnDefinition definition) + { + return definition.MaxWidth; + } + + protected override double GetMinLength(ColumnDefinition definition) + { + return definition.MinWidth; + } + + protected override bool IsStar(ColumnDefinition definition) + { + return definition.Width.IsStar; + } + protected override double GetDelta(VectorEventArgs vectorEventArgs) + { + return vectorEventArgs.Vector.X; + } + + protected override void SetLengthInStars(ColumnDefinition definition, double value) + { + definition.Width = new GridLength(value, GridUnitType.Star); + } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + var col = GetValue(Grid.ColumnProperty); + _definitions = _grid.ColumnDefinitions; + _prevDefinition = _definitions[col - 1]; + _nextDefinition = _definitions[col + 1]; + } + } +} \ No newline at end of file diff --git a/src/Perspex.Diagnostics/Views/LogicalTreeView.cs b/src/Perspex.Diagnostics/Views/LogicalTreeView.cs index 276506bf09..434b7a574f 100644 --- a/src/Perspex.Diagnostics/Views/LogicalTreeView.cs +++ b/src/Perspex.Diagnostics/Views/LogicalTreeView.cs @@ -52,7 +52,7 @@ namespace Perspex.Diagnostics.Views }, [!ItemsControl.ItemsProperty] = this.WhenAnyValue(x => x.ViewModel.Nodes), }), - new GridSplitter + new VerticalGridSplitter { [Grid.ColumnProperty] = 1, Width = 4, diff --git a/src/Perspex.Diagnostics/Views/VisualTreeView.cs b/src/Perspex.Diagnostics/Views/VisualTreeView.cs index df7277e396..0ef992ead3 100644 --- a/src/Perspex.Diagnostics/Views/VisualTreeView.cs +++ b/src/Perspex.Diagnostics/Views/VisualTreeView.cs @@ -53,7 +53,7 @@ namespace Perspex.Diagnostics.Views }, [!ItemsControl.ItemsProperty] = this.WhenAnyValue(x => x.ViewModel.Nodes), }), - new GridSplitter + new VerticalGridSplitter { [Grid.ColumnProperty] = 1, Width = 4, diff --git a/src/Perspex.Themes.Default/DefaultTheme.paml b/src/Perspex.Themes.Default/DefaultTheme.paml index 5902e568b3..4dd9df8d32 100644 --- a/src/Perspex.Themes.Default/DefaultTheme.paml +++ b/src/Perspex.Themes.Default/DefaultTheme.paml @@ -1,12 +1,12 @@  - - + + diff --git a/src/Perspex.Themes.Default/GridSplitter.paml b/src/Perspex.Themes.Default/HorizontalGridSplitter.paml similarity index 53% rename from src/Perspex.Themes.Default/GridSplitter.paml rename to src/Perspex.Themes.Default/HorizontalGridSplitter.paml index ee0757a3f5..7cdd47fc30 100644 --- a/src/Perspex.Themes.Default/GridSplitter.paml +++ b/src/Perspex.Themes.Default/HorizontalGridSplitter.paml @@ -1,5 +1,5 @@ - From e7872e1a0c20e93c02fa9e7d707b2b2adc9455b7 Mon Sep 17 00:00:00 2001 From: susloparov Date: Thu, 10 Dec 2015 20:39:49 +0600 Subject: [PATCH 3/7] Added GridSplitter example to XamlTestApplication, Layout tab. --- .../XamlTestApplicationPcl/Views/MainWindow.paml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/samples/XamlTestApplicationPcl/Views/MainWindow.paml b/samples/XamlTestApplicationPcl/Views/MainWindow.paml index c7680382d4..c815a4eb98 100644 --- a/samples/XamlTestApplicationPcl/Views/MainWindow.paml +++ b/samples/XamlTestApplicationPcl/Views/MainWindow.paml @@ -220,6 +220,19 @@ + + + + + + + + + + + + + From 0a4730d9ba21fa407b2cbd18a0cbf13883457653 Mon Sep 17 00:00:00 2001 From: susloparov Date: Thu, 10 Dec 2015 20:40:06 +0600 Subject: [PATCH 4/7] Styled GridSplitters --- .../HorizontalGridSplitter.paml | 18 +++++++++++++++++- .../VerticalGridSplitter.paml | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Perspex.Themes.Default/HorizontalGridSplitter.paml b/src/Perspex.Themes.Default/HorizontalGridSplitter.paml index 7cdd47fc30..99236635ae 100644 --- a/src/Perspex.Themes.Default/HorizontalGridSplitter.paml +++ b/src/Perspex.Themes.Default/HorizontalGridSplitter.paml @@ -1,8 +1,24 @@  + + + + + + \ No newline at end of file diff --git a/src/Perspex.Themes.Default/VerticalGridSplitter.paml b/src/Perspex.Themes.Default/VerticalGridSplitter.paml index 1132840de1..0b61ad0fae 100644 --- a/src/Perspex.Themes.Default/VerticalGridSplitter.paml +++ b/src/Perspex.Themes.Default/VerticalGridSplitter.paml @@ -1,8 +1,24 @@  + + + + + + From 7070ad51ed238a649229c7ef4682a482fda72534 Mon Sep 17 00:00:00 2001 From: susloparov Date: Wed, 16 Dec 2015 13:58:23 +0600 Subject: [PATCH 5/7] Merged Horizontal and Vertical Grid splitter back into single class --- .../Views/MainWindow.paml | 8 +- src/Perspex.Controls/GridSplitter.cs | 168 +++++++++++------- .../Views/LogicalTreeView.cs | 2 +- .../Views/VisualTreeView.cs | 2 +- src/Perspex.Themes.Default/DefaultTheme.paml | 3 +- src/Perspex.Themes.Default/GridSplitter.paml | 51 ++++++ .../HorizontalGridSplitter.paml | 24 --- .../Perspex.Themes.Default.csproj | 5 +- .../VerticalGridSplitter.paml | 24 --- 9 files changed, 164 insertions(+), 123 deletions(-) create mode 100644 src/Perspex.Themes.Default/GridSplitter.paml delete mode 100644 src/Perspex.Themes.Default/HorizontalGridSplitter.paml delete mode 100644 src/Perspex.Themes.Default/VerticalGridSplitter.paml diff --git a/samples/XamlTestApplicationPcl/Views/MainWindow.paml b/samples/XamlTestApplicationPcl/Views/MainWindow.paml index c815a4eb98..afc2d592e9 100644 --- a/samples/XamlTestApplicationPcl/Views/MainWindow.paml +++ b/samples/XamlTestApplicationPcl/Views/MainWindow.paml @@ -224,13 +224,13 @@ - + - + - + - + diff --git a/src/Perspex.Controls/GridSplitter.cs b/src/Perspex.Controls/GridSplitter.cs index b4e76ad41e..a5228d3862 100644 --- a/src/Perspex.Controls/GridSplitter.cs +++ b/src/Perspex.Controls/GridSplitter.cs @@ -11,62 +11,97 @@ using Perspex.VisualTree; namespace Perspex.Controls { /// - /// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior. It's GridResizeBehavior.PreviousAndNext + /// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior, GridResizeBehavior.PreviousAndNext /// - public abstract class GridSplitterBase : Thumb - where T : DefinitionBase + public class GridSplitter : Thumb { - protected PerspexList _definitions; + /// + /// Defines the property. + /// + public static readonly PerspexProperty OrientationProperty = + PerspexProperty.Register(nameof(Orientation)); protected Grid _grid; - protected T _nextDefinition; + private IGridColumnsResizer _resizer; + + /// + /// Gets or sets the orientation of the GridsSlitter, if null, it's inferred from column/row defenition(should be auto). + /// + public Orientation? Orientation { get { return GetValue(OrientationProperty); } set { SetValue(OrientationProperty, value); } } - protected T _prevDefinition; + + static GridSplitter() + { + PseudoClass(OrientationProperty, o => o == Perspex.Controls.Orientation.Vertical, ":vertical"); + PseudoClass(OrientationProperty, o => o == Perspex.Controls.Orientation.Horizontal, ":horizontal"); + } + + + protected override void OnDragDelta(VectorEventArgs e) + { + _resizer.DragDelta(e); + } /// - /// Decide depending on set size + /// If orientation is not set, method automatically calculates orientation based column/row auto size /// /// - private bool IsResizingColumns() + private void AutoSetOrientation() { - if (!double.IsNaN(Width)) + if (Orientation.HasValue) + { + return; + } + if (_grid.ColumnDefinitions[GetValue(Grid.ColumnProperty)].Width.IsAuto) { - return true; + Orientation = Perspex.Controls.Orientation.Vertical; + return; } - if (!double.IsNaN(Height)) + if (_grid.RowDefinitions[GetValue(Grid.RowProperty)].Height.IsAuto) { - return false; + Orientation = Perspex.Controls.Orientation.Horizontal; + return; } - throw new InvalidOperationException("GridSpliter Should have width or height set. It affects whether columns or rows it resizes"); + throw new InvalidOperationException("GridSpliter Should have Orientation, width or height set."); } - protected abstract double GetActualLength(T definition); - - protected abstract double GetMinLength(T definition); - - protected abstract double GetMaxLength(T definition); + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + _grid = this.GetVisualParent(); + AutoSetOrientation(); + switch (Orientation) + { + case Perspex.Controls.Orientation.Vertical: + _resizer = new VerticalColumnsResizer(_grid, GetValue(Grid.ColumnProperty)); + break; + case Perspex.Controls.Orientation.Horizontal: + _resizer = new HorizontalGridColumnsResizer(_grid, GetValue(Grid.RowProperty)); + break; + default: + throw new ArgumentOutOfRangeException(); + } + base.OnAttachedToVisualTree(e); + } + } - protected abstract bool IsStar(T definition); + internal interface IGridColumnsResizer + { + void DragDelta(VectorEventArgs e); + } - protected abstract void SetLengthInStars(T definition, double value); + internal abstract class GridColumnsResizer : IGridColumnsResizer + where T : DefinitionBase + { + protected PerspexList _definitions; - private void GetDeltaConstraints(out double min, out double max) - { - var prevDefinitionLen = GetActualLength(_prevDefinition); - var prevDefinitionMin = GetMinLength(_prevDefinition); - var prevDefinitionMax = GetMaxLength(_prevDefinition); + protected T _nextDefinition; - var nextDefinitionLen = GetActualLength(_nextDefinition); - var nextDefinitionMin = GetMinLength(_nextDefinition); - var nextDefinitionMax = GetMaxLength(_nextDefinition); + protected T _prevDefinition; - // Determine the minimum and maximum the columns can be resized - min = -Math.Min(prevDefinitionLen - prevDefinitionMin, nextDefinitionMax - nextDefinitionLen); - max = Math.Min(prevDefinitionMax - prevDefinitionLen, nextDefinitionLen - nextDefinitionMin); - } + public abstract Cursor Cursor { get; } - protected override void OnDragDelta(VectorEventArgs e) + public void DragDelta(VectorEventArgs e) { var delta = GetDelta(e); @@ -92,22 +127,45 @@ namespace Perspex.Controls } } + protected abstract double GetActualLength(T definition); + + protected abstract double GetMinLength(T definition); + + protected abstract double GetMaxLength(T definition); + + protected abstract bool IsStar(T definition); + + protected abstract void SetLengthInStars(T definition, double value); + protected abstract double GetDelta(VectorEventArgs vectorEventArgs); - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + protected void GetDeltaConstraints(out double min, out double max) { - base.OnAttachedToVisualTree(e); - _grid = this.GetVisualParent(); + var _prevDefinitionLen = GetActualLength(_prevDefinition); + var _prevDefinitionMin = GetMinLength(_prevDefinition); + var _prevDefinitionMax = GetMaxLength(_prevDefinition); + + var _nextDefinitionLen = GetActualLength(_nextDefinition); + var _nextDefinitionMin = GetMinLength(_nextDefinition); + var _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); } } - public class HorizontalGridSplitter : GridSplitterBase + internal class HorizontalGridColumnsResizer : GridColumnsResizer { - public HorizontalGridSplitter() + public HorizontalGridColumnsResizer(Grid _grid, int splitterRow) { - Cursor = new Cursor(StandardCursorType.SizeNorthSouth); + _definitions = _grid.RowDefinitions; + _nextDefinition = _definitions[splitterRow + 1]; + _prevDefinition = _definitions[splitterRow - 1]; } + public override Cursor Cursor => new Cursor(StandardCursorType.SizeNorthSouth); + protected override double GetActualLength(RowDefinition definition) { return definition.ActualHeight; @@ -133,31 +191,23 @@ namespace Perspex.Controls return vectorEventArgs.Vector.Y; } - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var row = GetValue(Grid.RowProperty); - _definitions = _grid.RowDefinitions; - _prevDefinition = _definitions[row - 1]; - _nextDefinition = _definitions[row + 1]; - } - protected override void SetLengthInStars(RowDefinition definition, double value) { definition.Height = new GridLength(value, GridUnitType.Star); } } - public class VerticalGridSplitter : GridSplitterBase + internal class VerticalColumnsResizer : GridColumnsResizer { - - - - public VerticalGridSplitter() + public VerticalColumnsResizer(Grid _grid, int splitterColumn) { - Cursor = new Cursor(StandardCursorType.SizeWestEast); + _definitions = _grid.ColumnDefinitions; + _nextDefinition = _definitions[splitterColumn + 1]; + _prevDefinition = _definitions[splitterColumn - 1]; } + public override Cursor Cursor => new Cursor(StandardCursorType.SizeWestEast); + protected override double GetActualLength(ColumnDefinition definition) { return definition.ActualWidth; @@ -177,6 +227,7 @@ namespace Perspex.Controls { return definition.Width.IsStar; } + protected override double GetDelta(VectorEventArgs vectorEventArgs) { return vectorEventArgs.Vector.X; @@ -186,14 +237,5 @@ namespace Perspex.Controls { definition.Width = new GridLength(value, GridUnitType.Star); } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var col = GetValue(Grid.ColumnProperty); - _definitions = _grid.ColumnDefinitions; - _prevDefinition = _definitions[col - 1]; - _nextDefinition = _definitions[col + 1]; - } } } \ No newline at end of file diff --git a/src/Perspex.Diagnostics/Views/LogicalTreeView.cs b/src/Perspex.Diagnostics/Views/LogicalTreeView.cs index 434b7a574f..276506bf09 100644 --- a/src/Perspex.Diagnostics/Views/LogicalTreeView.cs +++ b/src/Perspex.Diagnostics/Views/LogicalTreeView.cs @@ -52,7 +52,7 @@ namespace Perspex.Diagnostics.Views }, [!ItemsControl.ItemsProperty] = this.WhenAnyValue(x => x.ViewModel.Nodes), }), - new VerticalGridSplitter + new GridSplitter { [Grid.ColumnProperty] = 1, Width = 4, diff --git a/src/Perspex.Diagnostics/Views/VisualTreeView.cs b/src/Perspex.Diagnostics/Views/VisualTreeView.cs index 0ef992ead3..df7277e396 100644 --- a/src/Perspex.Diagnostics/Views/VisualTreeView.cs +++ b/src/Perspex.Diagnostics/Views/VisualTreeView.cs @@ -53,7 +53,7 @@ namespace Perspex.Diagnostics.Views }, [!ItemsControl.ItemsProperty] = this.WhenAnyValue(x => x.ViewModel.Nodes), }), - new VerticalGridSplitter + new GridSplitter { [Grid.ColumnProperty] = 1, Width = 4, diff --git a/src/Perspex.Themes.Default/DefaultTheme.paml b/src/Perspex.Themes.Default/DefaultTheme.paml index 4dd9df8d32..121cf86879 100644 --- a/src/Perspex.Themes.Default/DefaultTheme.paml +++ b/src/Perspex.Themes.Default/DefaultTheme.paml @@ -5,8 +5,7 @@ - - + diff --git a/src/Perspex.Themes.Default/GridSplitter.paml b/src/Perspex.Themes.Default/GridSplitter.paml new file mode 100644 index 0000000000..6c5f936ec2 --- /dev/null +++ b/src/Perspex.Themes.Default/GridSplitter.paml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Perspex.Themes.Default/HorizontalGridSplitter.paml b/src/Perspex.Themes.Default/HorizontalGridSplitter.paml deleted file mode 100644 index 99236635ae..0000000000 --- a/src/Perspex.Themes.Default/HorizontalGridSplitter.paml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/Perspex.Themes.Default/Perspex.Themes.Default.csproj b/src/Perspex.Themes.Default/Perspex.Themes.Default.csproj index 700f41a2a2..2ec676592d 100644 --- a/src/Perspex.Themes.Default/Perspex.Themes.Default.csproj +++ b/src/Perspex.Themes.Default/Perspex.Themes.Default.csproj @@ -119,7 +119,7 @@ Designer - + Designer @@ -187,9 +187,6 @@ Designer - - -