Browse Source

Merged Horizontal and Vertical Grid splitter back into single class

pull/362/head
susloparov 11 years ago
parent
commit
7070ad51ed
  1. 8
      samples/XamlTestApplicationPcl/Views/MainWindow.paml
  2. 168
      src/Perspex.Controls/GridSplitter.cs
  3. 2
      src/Perspex.Diagnostics/Views/LogicalTreeView.cs
  4. 2
      src/Perspex.Diagnostics/Views/VisualTreeView.cs
  5. 3
      src/Perspex.Themes.Default/DefaultTheme.paml
  6. 51
      src/Perspex.Themes.Default/GridSplitter.paml
  7. 24
      src/Perspex.Themes.Default/HorizontalGridSplitter.paml
  8. 5
      src/Perspex.Themes.Default/Perspex.Themes.Default.csproj
  9. 24
      src/Perspex.Themes.Default/VerticalGridSplitter.paml

8
samples/XamlTestApplicationPcl/Views/MainWindow.paml

@ -224,13 +224,13 @@
<TextBlock Text="GridSplitter" FontWeight="Medium" FontSize="20" Foreground="#212121" />
<Grid Height="500" Width="500" ColumnDefinitions="*,Auto,*,Auto,*" RowDefinitions="*,Auto,*">
<Border Grid.Column="0" Grid.Row="0" Background="Red" />
<HorizontalGridSplitter Grid.Column="0" Grid.Row="1" />
<GridSplitter Grid.Column="0" Grid.Row="1" />
<Border Grid.Column="0" Grid.Row="2" Background="Yellow" />
<VerticalGridSplitter Grid.Column="1" Grid.RowSpan="3" />
<GridSplitter Grid.Column="1" Grid.RowSpan="3" />
<Border Grid.Column="2" Grid.RowSpan="3" Background="Green" />
<VerticalGridSplitter Grid.Column="3" Grid.RowSpan="3" />
<GridSplitter Grid.Column="3" Grid.RowSpan="3" />
<Border Grid.Column="4" Grid.Row="0" Background="Blue" />
<HorizontalGridSplitter Grid.Column="4" Grid.Row="1" />
<GridSplitter Grid.Column="4" Grid.Row="1" />
<Border Grid.Column="4" Grid.Row="3" Background="Pink" />
</Grid>
</StackPanel>

168
src/Perspex.Controls/GridSplitter.cs

@ -11,62 +11,97 @@ using Perspex.VisualTree;
namespace Perspex.Controls
{
/// <summary>
/// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior. It's GridResizeBehavior.PreviousAndNext
/// Unlike WPF GridSplitter, Perspex GridSplitter has only one Behavior, GridResizeBehavior.PreviousAndNext
/// </summary>
public abstract class GridSplitterBase<T> : Thumb
where T : DefinitionBase
public class GridSplitter : Thumb
{
protected PerspexList<T> _definitions;
/// <summary>
/// Defines the <see cref="Orientation"/> property.
/// </summary>
public static readonly PerspexProperty<Orientation?> OrientationProperty =
PerspexProperty.Register<GridSplitter, Orientation?>(nameof(Orientation));
protected Grid _grid;
protected T _nextDefinition;
private IGridColumnsResizer _resizer;
/// <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); } }
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);
}
/// <summary>
/// Decide depending on set size
/// If orientation is not set, method automatically calculates orientation based column/row auto size
/// </summary>
/// <returns></returns>
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<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);
}
}
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<T> : IGridColumnsResizer
where T : DefinitionBase
{
protected PerspexList<T> _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<Grid>();
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<RowDefinition>
internal class HorizontalGridColumnsResizer : GridColumnsResizer<RowDefinition>
{
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<ColumnDefinition>
internal class VerticalColumnsResizer : GridColumnsResizer<ColumnDefinition>
{
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];
}
}
}

2
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,

2
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,

3
src/Perspex.Themes.Default/DefaultTheme.paml

@ -5,8 +5,7 @@
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.CheckBox.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ContentControl.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.DropDown.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.VerticalGridSplitter.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.HorizontalGridSplitter.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.GridSplitter.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ItemsControl.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ListBox.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ListBoxItem.paml"/>

51
src/Perspex.Themes.Default/GridSplitter.paml

@ -0,0 +1,51 @@
<Styles xmlns="https://github.com/perspex">
<Style Selector="GridSplitter:vertical">
<Setter Property="Width" Value="6"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Styles>
<Style Selector="Ellipse">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Width" Value="4"/>
<Setter Property="Height" Value="4"/>
<Setter Property="Fill" Value="#404040"/>
<Setter Property="Margin" Value="1"/>
</Style>
</StackPanel.Styles>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="GridSplitter:horizontal">
<Setter Property="Height" Value="6"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Styles>
<Style Selector="Ellipse">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Width" Value="4"/>
<Setter Property="Height" Value="4"/>
<Setter Property="Fill" Value="#404040"/>
<Setter Property="Margin" Value="1"/>
</Style>
</StackPanel.Styles>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
</Styles>

24
src/Perspex.Themes.Default/HorizontalGridSplitter.paml

@ -1,24 +0,0 @@
<Style xmlns="https://github.com/perspex" Selector="HorizontalGridSplitter">
<Setter Property="Height" Value="6"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Styles>
<Style Selector="Ellipse">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Width" Value="4"/>
<Setter Property="Height" Value="4"/>
<Setter Property="Fill" Value="#404040"/>
<Setter Property="Margin" Value="1"/>
</Style>
</StackPanel.Styles>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>

5
src/Perspex.Themes.Default/Perspex.Themes.Default.csproj

@ -119,7 +119,7 @@
<EmbeddedResource Include="FocusAdorner.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="VerticalGridSplitter.paml">
<EmbeddedResource Include="GridSplitter.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="ItemsControl.paml">
@ -187,9 +187,6 @@
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="HorizontalGridSplitter.paml" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

24
src/Perspex.Themes.Default/VerticalGridSplitter.paml

@ -1,24 +0,0 @@
<Style xmlns="https://github.com/perspex" Selector="VerticalGridSplitter">
<Setter Property="Width" Value="6"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Styles>
<Style Selector="Ellipse">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Width" Value="4"/>
<Setter Property="Height" Value="4"/>
<Setter Property="Fill" Value="#404040"/>
<Setter Property="Margin" Value="1"/>
</Style>
</StackPanel.Styles>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
Loading…
Cancel
Save