Browse Source

Merged GridSplitter related classes into one.

pull/362/head
susloparov 11 years ago
parent
commit
bd4acc6e5e
  1. 258
      src/Perspex.Controls/GridSplitter.cs

258
src/Perspex.Controls/GridSplitter.cs

@ -2,6 +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;
@ -11,8 +13,11 @@ using Perspex.VisualTree;
namespace Perspex.Controls
{
/// <summary>
/// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior, GridResizeBehavior.PreviousAndNext
/// Represents the control that redistributes space between columns or rows of a Grid control.
/// </summary>
/// <remarks>
/// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior, GridResizeBehavior.PreviousAndNext.
/// </remarks>
public class GridSplitter : Thumb
{
/// <summary>
@ -23,93 +28,58 @@ namespace Perspex.Controls
protected Grid _grid;
private IGridColumnsResizer _resizer;
private DefinitionBase _prevDefinition;
/// <summary>
/// Gets or sets the orientation of the GridsSlitter, if null, it's inferred from column/row defenition(should be auto).
/// </summary>
public Orientation? Orientation { get { return GetValue(OrientationProperty); } set { SetValue(OrientationProperty, value); } }
private DefinitionBase _nextDefinition;
private bool _isResizingColumns;
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);
}
private List<DefinitionBase> _definitions;
/// <summary>
/// If orientation is not set, method automatically calculates orientation based column/row auto size
/// Gets or sets the orientation of the GridsSlitter.
/// </summary>
/// <returns></returns>
private void AutoSetOrientation()
{
if (Orientation.HasValue)
/// <remarks>
/// if null, it's inferred from column/row definition (should be auto).
/// </remarks>
public Orientation? Orientation {
get
{
return;
return GetValue(OrientationProperty);
}
if (_grid.ColumnDefinitions[GetValue(Grid.ColumnProperty)].Width.IsAuto)
{
Orientation = Perspex.Controls.Orientation.Vertical;
return;
}
if (_grid.RowDefinitions[GetValue(Grid.RowProperty)].Height.IsAuto)
set
{
Orientation = Perspex.Controls.Orientation.Horizontal;
return;
SetValue(OrientationProperty, value);
}
throw new InvalidOperationException("GridSpliter Should have Orientation, width or height set.");
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
static GridSplitter()
{
_grid = this.GetVisualParent<Grid>();
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);
PseudoClass(OrientationProperty, o => o == Perspex.Controls.Orientation.Vertical, ":vertical");
PseudoClass(OrientationProperty, o => o == Perspex.Controls.Orientation.Horizontal, ":horizontal");
}
}
internal interface IGridColumnsResizer
{
void DragDelta(VectorEventArgs e);
}
internal abstract class GridColumnsResizer<T> : IGridColumnsResizer
where T : DefinitionBase
{
protected PerspexList<T> _definitions;
protected T _nextDefinition;
protected T _prevDefinition;
private void GetDeltaConstraints(out double min, out double max)
{
double prevDefinitionLen = GetActualLength(_prevDefinition);
double prevDefinitionMin = GetMinLength(_prevDefinition);
double prevDefinitionMax = GetMaxLength(_prevDefinition);
public abstract Cursor Cursor { get; }
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);
}
public void DragDelta(VectorEventArgs e)
protected override void OnDragDelta(VectorEventArgs e)
{
var delta = GetDelta(e);
var delta = Orientation.Value == Perspex.Controls.Orientation.Vertical ? e.Vector.X : e.Vector.Y;
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)
@ -122,120 +92,92 @@ namespace Perspex.Controls
}
else if (IsStar(definition))
{
SetLengthInStars(definition, GetActualLength(definition)); // same size but in stars
SetLengthInStars(definition, GetActualLength(definition)); // same size but in stars.
}
}
}
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 void GetDeltaConstraints(out double min, out double max)
{
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);
}
}
internal class HorizontalGridColumnsResizer : GridColumnsResizer<RowDefinition>
{
public HorizontalGridColumnsResizer(Grid _grid, int splitterRow)
/// <summary>
/// If orientation is not set, method automatically calculates orientation based column/row auto size.
/// </summary>
private void AutoSetOrientation()
{
_definitions = _grid.RowDefinitions;
_nextDefinition = _definitions[splitterRow + 1];
_prevDefinition = _definitions[splitterRow - 1];
if (Orientation.HasValue)
{
return;
}
if (_grid.ColumnDefinitions[GetValue(Grid.ColumnProperty)].Width.IsAuto)
{
Orientation = Perspex.Controls.Orientation.Vertical;
return;
}
if (_grid.RowDefinitions[GetValue(Grid.RowProperty)].Height.IsAuto)
{
Orientation = Perspex.Controls.Orientation.Horizontal;
return;
}
throw new InvalidOperationException("GridSpliter Should have Orientation, width or height set.");
}
public override Cursor Cursor => new Cursor(StandardCursorType.SizeNorthSouth);
protected override double GetActualLength(RowDefinition definition)
private double GetActualLength(DefinitionBase definition)
{
return definition.ActualHeight;
var columnDefinition = definition as ColumnDefinition;
return columnDefinition?.ActualWidth ?? ((RowDefinition)definition).ActualHeight;
}
protected override double GetMaxLength(RowDefinition definition)
private double GetMinLength(DefinitionBase definition)
{
return definition.MaxHeight;
var columnDefinition = definition as ColumnDefinition;
return columnDefinition?.MinWidth ?? ((RowDefinition)definition).MinHeight;
}
protected override double GetMinLength(RowDefinition definition)
private double GetMaxLength(DefinitionBase definition)
{
return definition.MinHeight;
var columnDefinition = definition as ColumnDefinition;
return columnDefinition?.MaxWidth ?? ((RowDefinition)definition).MaxHeight;
}
protected override bool IsStar(RowDefinition definition)
private bool IsStar(DefinitionBase definition)
{
return definition.Height.IsStar;
var columnDefinition = definition as ColumnDefinition;
return columnDefinition?.Width.IsStar ?? ((RowDefinition)definition).Height.IsStar;
}
protected override double GetDelta(VectorEventArgs vectorEventArgs)
private void SetLengthInStars(DefinitionBase definition, double value)
{
return vectorEventArgs.Vector.Y;
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 override void SetLengthInStars(RowDefinition definition, double value)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
definition.Height = new GridLength(value, GridUnitType.Star);
base.OnAttachedToVisualTree(e);
_grid = this.GetVisualParent<Grid>();
AutoSetOrientation();
if (Orientation.Value == Perspex.Controls.Orientation.Vertical)
{
Cursor = new Cursor(StandardCursorType.SizeWestEast);
var col = GetValue(Grid.ColumnProperty);
_definitions = _grid.ColumnDefinitions.Cast<DefinitionBase>().ToList();
_prevDefinition = _definitions[col - 1];
_nextDefinition = _definitions[col + 1];
}
else
{
Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
var row = GetValue(Grid.RowProperty);
_definitions = _grid.RowDefinitions.Cast<DefinitionBase>().ToList();
_prevDefinition = _definitions[row - 1];
_nextDefinition = _definitions[row + 1];
}
}
}
}
internal class VerticalColumnsResizer : GridColumnsResizer<ColumnDefinition>
{
public VerticalColumnsResizer(Grid _grid, int splitterColumn)
{
_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;
}
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);
}
}
}
Loading…
Cancel
Save