Browse Source

First grid splitter implementation

pull/362/head
susloparov 10 years ago
parent
commit
ef06e79667
  1. 130
      src/Perspex.Controls/GridSplitter.cs

130
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
{
/// <summary>
/// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior. It's GridResizeBehavior.PreviousAndNext
/// </summary>
public class GridSplitter : Thumb
{
private Grid _grid;
private DefinitionBase _prevDefinition;
private DefinitionBase _nextDefinition;
private bool _isResizingColumns;
private List<DefinitionBase> _definitions;
/// <summary>
/// Initializes a new instance of the <see cref="GridSplitter"/> class.
/// Decide depending on set size
/// </summary>
public GridSplitter()
/// <returns></returns>
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<Grid>();
_isResizingColumns = IsResizingColumns();
if (_isResizingColumns)
{
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];
}
}
}
}

Loading…
Cancel
Save