18 changed files with 424 additions and 24 deletions
@ -0,0 +1,106 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.ComponentModel; |
|||
using System.Linq; |
|||
using System.Reactive.Disposables; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Perspex |
|||
{ |
|||
public static class PerspexListExtensions |
|||
{ |
|||
public static IDisposable ForEachItem<T>( |
|||
this IReadOnlyPerspexList<T> collection, |
|||
Action<T> added, |
|||
Action<T> removed) |
|||
{ |
|||
NotifyCollectionChangedEventHandler handler = (_, e) => |
|||
{ |
|||
switch (e.Action) |
|||
{ |
|||
case NotifyCollectionChangedAction.Add: |
|||
foreach (T i in e.NewItems) |
|||
{ |
|||
added(i); |
|||
} |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Replace: |
|||
foreach (T i in e.OldItems) |
|||
{ |
|||
removed(i); |
|||
} |
|||
|
|||
foreach (T i in e.NewItems) |
|||
{ |
|||
added(i); |
|||
} |
|||
|
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Remove: |
|||
foreach (T i in e.OldItems) |
|||
{ |
|||
removed(i); |
|||
} |
|||
break; |
|||
} |
|||
}; |
|||
|
|||
foreach (T i in collection) |
|||
{ |
|||
added(i); |
|||
} |
|||
|
|||
collection.CollectionChanged += handler; |
|||
|
|||
System.Diagnostics.Debug.WriteLine("Tracked " + collection.GetHashCode()); |
|||
|
|||
return Disposable.Create(() => collection.CollectionChanged -= handler); |
|||
} |
|||
|
|||
public static IDisposable TrackItemPropertyChanged<T>( |
|||
this IReadOnlyPerspexList<T> collection, |
|||
Action<Tuple<object, PropertyChangedEventArgs>> callback) |
|||
{ |
|||
List<INotifyPropertyChanged> tracked = new List<INotifyPropertyChanged>(); |
|||
|
|||
PropertyChangedEventHandler handler = (s, e) => |
|||
{ |
|||
callback(Tuple.Create(s, e)); |
|||
}; |
|||
|
|||
collection.ForEachItem( |
|||
x => |
|||
{ |
|||
var inpc = x as INotifyPropertyChanged; |
|||
|
|||
if (inpc != null) |
|||
{ |
|||
inpc.PropertyChanged += handler; |
|||
tracked.Add(inpc); |
|||
} |
|||
}, |
|||
x => |
|||
{ |
|||
var inpc = x as INotifyPropertyChanged; |
|||
|
|||
if (inpc != null) |
|||
{ |
|||
inpc.PropertyChanged -= handler; |
|||
tracked.Remove(inpc); |
|||
} |
|||
}); |
|||
|
|||
return Disposable.Create(() => |
|||
{ |
|||
foreach (var i in tracked) |
|||
{ |
|||
i.PropertyChanged -= handler; |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GridSplitter.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using Perspex.Controls.Primitives; |
|||
using Perspex.Input; |
|||
|
|||
public class GridSplitter : Thumb |
|||
{ |
|||
private Grid grid; |
|||
|
|||
protected override void OnDragDelta(VectorEventArgs e) |
|||
{ |
|||
int col = this.GetValue(Grid.ColumnProperty); |
|||
|
|||
if (grid != null && col > 0) |
|||
{ |
|||
grid.ColumnDefinitions[col - 1].Width = new GridLength( |
|||
grid.ColumnDefinitions[col - 1].ActualWidth + e.Vector.X, |
|||
GridUnitType.Pixel); |
|||
} |
|||
} |
|||
|
|||
protected override void OnVisualParentChanged(Visual oldParent) |
|||
{ |
|||
this.grid = this.GetVisualParent<Grid>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Thumb.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls.Primitives |
|||
{ |
|||
using System; |
|||
using Perspex.Input; |
|||
using Perspex.Interactivity; |
|||
|
|||
public class Thumb : TemplatedControl |
|||
{ |
|||
public static readonly RoutedEvent<VectorEventArgs> DragStartedEvent = |
|||
RoutedEvent.Register<Thumb, VectorEventArgs>("DragStarted", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<VectorEventArgs> DragDeltaEvent = |
|||
RoutedEvent.Register<Thumb, VectorEventArgs>("DragDelta", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<VectorEventArgs> DragCompletedEvent = |
|||
RoutedEvent.Register<Thumb, VectorEventArgs>("DragCompleted", RoutingStrategy.Bubble); |
|||
|
|||
Point? lastPoint; |
|||
|
|||
public Thumb() |
|||
{ |
|||
this.DragStarted += (_, e) => this.OnDragStarted(e); |
|||
this.DragDelta += (_, e) => this.OnDragDelta(e); |
|||
this.DragCompleted += (_, e) => this.OnDragCompleted(e); |
|||
} |
|||
|
|||
public event EventHandler<VectorEventArgs> DragStarted |
|||
{ |
|||
add { this.AddHandler(DragStartedEvent, value); } |
|||
remove { this.RemoveHandler(DragStartedEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<VectorEventArgs> DragDelta |
|||
{ |
|||
add { this.AddHandler(DragDeltaEvent, value); } |
|||
remove { this.RemoveHandler(DragDeltaEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<VectorEventArgs> DragCompleted |
|||
{ |
|||
add { this.AddHandler(DragCompletedEvent, value); } |
|||
remove { this.RemoveHandler(DragCompletedEvent, value); } |
|||
} |
|||
|
|||
protected virtual void OnDragStarted(VectorEventArgs e) |
|||
{ |
|||
} |
|||
|
|||
protected virtual void OnDragDelta(VectorEventArgs e) |
|||
{ |
|||
} |
|||
|
|||
protected virtual void OnDragCompleted(VectorEventArgs e) |
|||
{ |
|||
} |
|||
|
|||
protected override void OnPointerMoved(PointerEventArgs e) |
|||
{ |
|||
if (this.lastPoint.HasValue) |
|||
{ |
|||
var ev = new VectorEventArgs |
|||
{ |
|||
RoutedEvent = DragDeltaEvent, |
|||
Vector = e.GetPosition(this) - this.lastPoint.Value, |
|||
}; |
|||
|
|||
this.RaiseEvent(ev); |
|||
} |
|||
} |
|||
|
|||
protected override void OnPointerPressed(PointerEventArgs e) |
|||
{ |
|||
e.Device.Capture(this); |
|||
this.lastPoint = e.GetPosition(this); |
|||
|
|||
var ev = new VectorEventArgs |
|||
{ |
|||
RoutedEvent = DragStartedEvent, |
|||
Vector = (Vector)this.lastPoint, |
|||
}; |
|||
|
|||
this.RaiseEvent(ev); |
|||
} |
|||
|
|||
protected override void OnPointerReleased(PointerEventArgs e) |
|||
{ |
|||
if (this.lastPoint.HasValue) |
|||
{ |
|||
e.Device.Capture(null); |
|||
this.lastPoint = null; |
|||
|
|||
var ev = new VectorEventArgs |
|||
{ |
|||
RoutedEvent = DragCompletedEvent, |
|||
Vector = (Vector)e.GetPosition(this), |
|||
}; |
|||
|
|||
this.RaiseEvent(ev); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="VectorEventArgs.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using Perspex.Interactivity; |
|||
|
|||
public class VectorEventArgs : RoutedEventArgs |
|||
{ |
|||
public Vector Vector { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GridSplitterStyle.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Themes.Default |
|||
{ |
|||
using System.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Controls.Presenters; |
|||
using Perspex.Media; |
|||
using Perspex.Styling; |
|||
|
|||
public class GridSplitterStyle : Styles |
|||
{ |
|||
public GridSplitterStyle() |
|||
{ |
|||
this.AddRange(new[] |
|||
{ |
|||
new Style(x => x.OfType<GridSplitter>()) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(GridSplitter.TemplateProperty, ControlTemplate.Create<GridSplitter>(this.Template)), |
|||
new Setter(GridSplitter.WidthProperty, 4), |
|||
}, |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
private Control Template(GridSplitter control) |
|||
{ |
|||
Border border = new Border |
|||
{ |
|||
[~Border.BackgroundProperty] = control[~GridSplitter.BackgroundProperty], |
|||
}; |
|||
|
|||
return border; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue