161 changed files with 0 additions and 14094 deletions
@ -1,97 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Application.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using Perspex.Controls; |
|||
using Perspex.Input; |
|||
using Perspex.Styling; |
|||
using Perspex.Threading; |
|||
using Splat; |
|||
|
|||
public class Application |
|||
{ |
|||
private DataTemplates dataTemplates; |
|||
|
|||
private Styles styles; |
|||
|
|||
public Application() |
|||
{ |
|||
Current = this; |
|||
this.FocusManager = new FocusManager(); |
|||
this.InputManager = new InputManager(); |
|||
} |
|||
|
|||
public static Application Current |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public DataTemplates DataTemplates |
|||
{ |
|||
get |
|||
{ |
|||
if (this.dataTemplates == null) |
|||
{ |
|||
this.dataTemplates = new DataTemplates(); |
|||
} |
|||
|
|||
return this.dataTemplates; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.dataTemplates = value; |
|||
} |
|||
} |
|||
|
|||
public IFocusManager FocusManager |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public InputManager InputManager |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public Styles Styles |
|||
{ |
|||
get |
|||
{ |
|||
if (this.styles == null) |
|||
{ |
|||
this.styles = new Styles(); |
|||
} |
|||
|
|||
return this.styles; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.styles = value; |
|||
} |
|||
} |
|||
|
|||
public void RegisterServices() |
|||
{ |
|||
Styler styler = new Styler(); |
|||
Locator.CurrentMutable.Register(() => this.FocusManager, typeof(IFocusManager)); |
|||
Locator.CurrentMutable.Register(() => this.InputManager, typeof(IInputManager)); |
|||
Locator.CurrentMutable.Register(() => styler, typeof(IStyler)); |
|||
} |
|||
|
|||
public void Run(ICloseable closable) |
|||
{ |
|||
DispatcherFrame frame = new DispatcherFrame(); |
|||
closable.Closed += (s, e) => frame.Continue = false; |
|||
Dispatcher.PushFrame(frame); |
|||
} |
|||
} |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Perspex |
|||
{ |
|||
public enum BindingMode |
|||
{ |
|||
Default, |
|||
OneWay, |
|||
TwoWay, |
|||
OneTime, |
|||
OneWayToSource, |
|||
} |
|||
|
|||
public struct Binding |
|||
{ |
|||
public BindingMode Mode |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public BindingPriority Priority |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public PerspexProperty Property |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public PerspexObject Source |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public static Binding operator !(Binding binding) |
|||
{ |
|||
return binding.WithMode(BindingMode.TwoWay); |
|||
} |
|||
|
|||
public static Binding operator ~(Binding binding) |
|||
{ |
|||
return binding.WithMode(BindingMode.TwoWay); |
|||
} |
|||
|
|||
public Binding WithMode(BindingMode mode) |
|||
{ |
|||
this.Mode = mode; |
|||
return this; |
|||
} |
|||
|
|||
public Binding WithPriority(BindingPriority priority) |
|||
{ |
|||
this.Priority = priority; |
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
@ -1,39 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="BindingExtensions.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Controls; |
|||
|
|||
/// <summary>
|
|||
/// Provides binding utility extension methods.
|
|||
/// </summary>
|
|||
public static class BindingExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Binds a property in a template to the same property in the templated parent.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The property type.</typeparam>
|
|||
/// <param name="o">The control in the template.</param>
|
|||
/// <param name="templatedParent">The templated parent.</param>
|
|||
/// <param name="property">The property.</param>
|
|||
/// <returns>
|
|||
/// A disposable which can be used to terminate the binding.
|
|||
/// </returns>
|
|||
public static IDisposable TemplateBinding<T>( |
|||
this PerspexObject o, |
|||
ITemplatedControl templatedParent, |
|||
PerspexProperty<T> property) |
|||
{ |
|||
return o.Bind(property, templatedParent.GetObservable(property), BindingPriority.TemplatedParent); |
|||
} |
|||
} |
|||
} |
|||
@ -1,177 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Classes.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.Linq; |
|||
using System.Reactive; |
|||
using System.Reactive.Subjects; |
|||
|
|||
public class Classes : ICollection<string>, INotifyCollectionChanged |
|||
{ |
|||
private List<string> inner; |
|||
|
|||
private Subject<NotifyCollectionChangedEventArgs> beforeChanged |
|||
= new Subject<NotifyCollectionChangedEventArgs>(); |
|||
|
|||
private Subject<NotifyCollectionChangedEventArgs> changed |
|||
= new Subject<NotifyCollectionChangedEventArgs>(); |
|||
|
|||
private Subject<NotifyCollectionChangedEventArgs> afterChanged |
|||
= new Subject<NotifyCollectionChangedEventArgs>(); |
|||
|
|||
public Classes() |
|||
{ |
|||
this.inner = new List<string>(); |
|||
} |
|||
|
|||
public Classes(params string[] classes) |
|||
{ |
|||
this.inner = new List<string>(classes); |
|||
} |
|||
|
|||
public Classes(IEnumerable<string> classes) |
|||
{ |
|||
this.inner = new List<string>(classes); |
|||
} |
|||
|
|||
public event NotifyCollectionChangedEventHandler CollectionChanged; |
|||
|
|||
public int Count |
|||
{ |
|||
get { return this.inner.Count; } |
|||
} |
|||
|
|||
public bool IsReadOnly |
|||
{ |
|||
get { return false; } |
|||
} |
|||
|
|||
public IObservable<NotifyCollectionChangedEventArgs> BeforeChanged |
|||
{ |
|||
get { return this.beforeChanged; } |
|||
} |
|||
|
|||
public IObservable<NotifyCollectionChangedEventArgs> Changed |
|||
{ |
|||
get { return this.changed; } |
|||
} |
|||
|
|||
public IObservable<NotifyCollectionChangedEventArgs> AfterChanged |
|||
{ |
|||
get { return this.afterChanged; } |
|||
} |
|||
|
|||
public void Add(string item) |
|||
{ |
|||
this.Add(Enumerable.Repeat(item, 1)); |
|||
} |
|||
|
|||
public void Add(params string[] items) |
|||
{ |
|||
this.Add((IEnumerable<string>)items); |
|||
} |
|||
|
|||
public void Add(IEnumerable<string> items) |
|||
{ |
|||
items = items.Except(this.inner); |
|||
|
|||
NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( |
|||
NotifyCollectionChangedAction.Add, |
|||
items); |
|||
|
|||
this.beforeChanged.OnNext(e); |
|||
this.inner.AddRange(items); |
|||
this.RaiseChanged(e); |
|||
} |
|||
|
|||
public void Clear() |
|||
{ |
|||
NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( |
|||
NotifyCollectionChangedAction.Reset); |
|||
|
|||
this.beforeChanged.OnNext(e); |
|||
this.inner.Clear(); |
|||
this.RaiseChanged(e); |
|||
} |
|||
|
|||
public bool Contains(string item) |
|||
{ |
|||
return this.inner.Contains(item); |
|||
} |
|||
|
|||
public void CopyTo(string[] array, int arrayIndex) |
|||
{ |
|||
this.inner.CopyTo(array, arrayIndex); |
|||
} |
|||
|
|||
public IEnumerator<string> GetEnumerator() |
|||
{ |
|||
return this.inner.GetEnumerator(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return string.Join(" ", this); |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return this.inner.GetEnumerator(); |
|||
} |
|||
|
|||
public bool Remove(string item) |
|||
{ |
|||
return this.Remove(Enumerable.Repeat(item, 1)); |
|||
} |
|||
|
|||
public bool Remove(params string[] items) |
|||
{ |
|||
return this.Remove((IEnumerable<string>)items); |
|||
} |
|||
|
|||
public bool Remove(IEnumerable<string> items) |
|||
{ |
|||
items = items.Intersect(this.inner); |
|||
|
|||
if (items.Any()) |
|||
{ |
|||
NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( |
|||
NotifyCollectionChangedAction.Remove, |
|||
items); |
|||
|
|||
this.beforeChanged.OnNext(e); |
|||
|
|||
foreach (string item in items) |
|||
{ |
|||
this.inner.Remove(item); |
|||
} |
|||
|
|||
this.RaiseChanged(e); |
|||
return true; |
|||
} |
|||
else |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
private void RaiseChanged(NotifyCollectionChangedEventArgs e) |
|||
{ |
|||
if (this.CollectionChanged != null) |
|||
{ |
|||
this.CollectionChanged(this, e); |
|||
} |
|||
|
|||
this.changed.OnNext(e); |
|||
this.afterChanged.OnNext(e); |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Contract.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
|
|||
internal static class Contract |
|||
{ |
|||
public static void Requires<TException>(bool condition) where TException : Exception, new() |
|||
{ |
|||
#if DEBUG
|
|||
if (!condition) |
|||
{ |
|||
throw new TException(); |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
} |
|||
@ -1,37 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ControlExtensions.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Styling; |
|||
|
|||
public static class ControlExtensions |
|||
{ |
|||
public static IEnumerable<Control> GetTemplateControls(this ITemplatedControl control) |
|||
{ |
|||
return GetTemplateControls(control, (IVisual)control); |
|||
} |
|||
|
|||
public static IEnumerable<Control> GetTemplateControls(ITemplatedControl templated, IVisual parent) |
|||
{ |
|||
IVisual visual = parent as IVisual; |
|||
|
|||
foreach (IVisual child in visual.VisualChildren.OfType<Control>().Where(x => x.TemplatedParent == templated)) |
|||
{ |
|||
yield return (Control)child; |
|||
|
|||
foreach (IVisual grandchild in GetTemplateControls(templated, child)) |
|||
{ |
|||
yield return (Control)grandchild; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,62 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Border.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
|
|||
public class Border : Decorator |
|||
{ |
|||
static Border() |
|||
{ |
|||
AffectsRender(BackgroundProperty); |
|||
AffectsRender(BorderBrushProperty); |
|||
} |
|||
|
|||
public override void Render(IDrawingContext context) |
|||
{ |
|||
Brush background = this.Background; |
|||
Brush borderBrush = this.BorderBrush; |
|||
double borderThickness = this.BorderThickness; |
|||
Rect rect = new Rect(this.ActualSize).Deflate(BorderThickness / 2); |
|||
|
|||
if (background != null) |
|||
{ |
|||
context.FillRectange(background, rect); |
|||
} |
|||
|
|||
if (borderBrush != null && borderThickness > 0) |
|||
{ |
|||
context.DrawRectange(new Pen(borderBrush, borderThickness), rect); |
|||
} |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
Control content = this.Content; |
|||
|
|||
if (content != null) |
|||
{ |
|||
Thickness padding = this.Padding + new Thickness(this.BorderThickness); |
|||
content.Arrange(new Rect(finalSize).Deflate(padding)); |
|||
} |
|||
|
|||
return finalSize; |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
return LayoutHelper.MeasureDecorator( |
|||
this, |
|||
this.Content, |
|||
availableSize, |
|||
this.Padding + new Thickness(this.BorderThickness)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,48 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Button.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
|
|||
public class Button : ContentControl |
|||
{ |
|||
public static readonly RoutedEvent<RoutedEventArgs> ClickEvent = |
|||
RoutedEvent.Register<Button, RoutedEventArgs>("Click", RoutingStrategy.Bubble); |
|||
|
|||
static Button() |
|||
{ |
|||
FocusableProperty.OverrideDefaultValue(typeof(Button), true); |
|||
} |
|||
|
|||
public Button() |
|||
{ |
|||
this.PointerPressed += (s, e) => |
|||
{ |
|||
this.Classes.Add(":pressed"); |
|||
e.Device.Capture(this); |
|||
}; |
|||
|
|||
this.PointerReleased += (s, e) => |
|||
{ |
|||
e.Device.Capture(null); |
|||
this.Classes.Remove(":pressed"); |
|||
|
|||
if (this.Classes.Contains(":pointerover")) |
|||
{ |
|||
RoutedEventArgs click = new RoutedEventArgs(ClickEvent, this); |
|||
this.RaiseEvent(click); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
public event EventHandler<RoutedEventArgs> Click |
|||
{ |
|||
add { this.AddHandler(ClickEvent, value); } |
|||
remove { this.RemoveHandler(ClickEvent, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="CheckBox.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class CheckBox : ToggleButton |
|||
{ |
|||
} |
|||
} |
|||
@ -1,53 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ColumnDefinition.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class ColumnDefinition : DefinitionBase |
|||
{ |
|||
public static readonly PerspexProperty<double> MaxWidthProperty = |
|||
PerspexProperty.Register<ColumnDefinition, double>("MaxWidth", double.PositiveInfinity); |
|||
|
|||
public static readonly PerspexProperty<double> MinWidthProperty = |
|||
PerspexProperty.Register<ColumnDefinition, double>("MinWidth"); |
|||
|
|||
public static readonly PerspexProperty<GridLength> WidthProperty = |
|||
PerspexProperty.Register<ColumnDefinition, GridLength>("Width", new GridLength(1, GridUnitType.Star)); |
|||
|
|||
public ColumnDefinition() |
|||
{ |
|||
} |
|||
|
|||
public ColumnDefinition(GridLength width) |
|||
{ |
|||
this.Width = width; |
|||
} |
|||
|
|||
public double ActualWidth |
|||
{ |
|||
get; |
|||
internal set; |
|||
} |
|||
|
|||
public double MaxWidth |
|||
{ |
|||
get { return this.GetValue(MaxWidthProperty); } |
|||
set { this.SetValue(MaxWidthProperty, value); } |
|||
} |
|||
|
|||
public double MinWidth |
|||
{ |
|||
get { return this.GetValue(MinWidthProperty); } |
|||
set { this.SetValue(MinWidthProperty, value); } |
|||
} |
|||
|
|||
public GridLength Width |
|||
{ |
|||
get { return this.GetValue(WidthProperty); } |
|||
set { this.SetValue(WidthProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ColumnDefinitions.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class ColumnDefinitions : PerspexList<ColumnDefinition> |
|||
{ |
|||
} |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ContentControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
public class ContentControl : TemplatedControl, ILogical |
|||
{ |
|||
public static readonly PerspexProperty<object> ContentProperty = |
|||
PerspexProperty.Register<ContentControl, object>("Content"); |
|||
|
|||
public ContentControl() |
|||
{ |
|||
this.GetObservableWithHistory(ContentProperty).Subscribe(x => |
|||
{ |
|||
if (x.Item1 is Control) |
|||
{ |
|||
((IVisual)x.Item1).VisualParent = null; |
|||
((ILogical)x.Item1).LogicalParent = null; |
|||
} |
|||
|
|||
if (x.Item2 is Control) |
|||
{ |
|||
((IVisual)x.Item2).VisualParent = this; |
|||
((ILogical)x.Item2).LogicalParent = this; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public object Content |
|||
{ |
|||
get { return this.GetValue(ContentProperty); } |
|||
set { this.SetValue(ContentProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<ILogical> ILogical.LogicalChildren |
|||
{ |
|||
get |
|||
{ |
|||
ILogical logicalChild = this.Content as ILogical; |
|||
return Enumerable.Repeat(logicalChild, logicalChild != null ? 1 : 0); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,188 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ContentPresenter.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
|
|||
public class ContentPresenter : Control, IVisual |
|||
{ |
|||
public static readonly PerspexProperty<object> ContentProperty = |
|||
ContentControl.ContentProperty.AddOwner<Control>(); |
|||
|
|||
public static readonly PerspexProperty<Func<object, Visual>> DataTemplateProperty = |
|||
PerspexProperty.Register<ContentPresenter, Func<object, Visual>>("DataTemplate"); |
|||
|
|||
private IVisual visualChild; |
|||
|
|||
public ContentPresenter() |
|||
{ |
|||
this.GetObservableWithHistory(ContentProperty).Subscribe(this.ContentChanged); |
|||
} |
|||
|
|||
public object Content |
|||
{ |
|||
get { return this.GetValue(ContentProperty); } |
|||
set { this.SetValue(ContentProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.ExistingVisualChildren |
|||
{ |
|||
get { return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.VisualChildren |
|||
{ |
|||
get |
|||
{ |
|||
object content = this.Content; |
|||
|
|||
if (this.visualChild == null && content != null) |
|||
{ |
|||
if (content is Visual) |
|||
{ |
|||
this.visualChild = (Visual)content; |
|||
} |
|||
else |
|||
{ |
|||
DataTemplate dataTemplate = this.FindDataTemplate(content); |
|||
|
|||
if (dataTemplate != null) |
|||
{ |
|||
this.visualChild = dataTemplate.Build(content); |
|||
} |
|||
else |
|||
{ |
|||
this.visualChild = new TextBlock |
|||
{ |
|||
Text = content.ToString(), |
|||
}; |
|||
} |
|||
} |
|||
|
|||
if (this.visualChild != null) |
|||
{ |
|||
this.visualChild.VisualParent = this; |
|||
((Control)this.visualChild).TemplatedParent = null; |
|||
} |
|||
} |
|||
|
|||
return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0); |
|||
} |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; |
|||
|
|||
if (child != null) |
|||
{ |
|||
double left; |
|||
double top; |
|||
double width; |
|||
double height; |
|||
|
|||
switch (child.HorizontalAlignment) |
|||
{ |
|||
case HorizontalAlignment.Left: |
|||
left = 0; |
|||
width = child.DesiredSize.Value.Width; |
|||
break; |
|||
case HorizontalAlignment.Center: |
|||
left = (finalSize.Width / 2) - (child.DesiredSize.Value.Width / 2); |
|||
width = child.DesiredSize.Value.Width; |
|||
break; |
|||
case HorizontalAlignment.Right: |
|||
left = finalSize.Width - child.DesiredSize.Value.Width; |
|||
width = child.DesiredSize.Value.Width; |
|||
break; |
|||
default: |
|||
left = 0; |
|||
width = finalSize.Width; |
|||
break; |
|||
} |
|||
|
|||
switch (child.VerticalAlignment) |
|||
{ |
|||
case VerticalAlignment.Top: |
|||
top = 0; |
|||
height = child.DesiredSize.Value.Height; |
|||
break; |
|||
case VerticalAlignment.Center: |
|||
top = (finalSize.Height / 2) - (child.DesiredSize.Value.Height / 2); |
|||
height = child.DesiredSize.Value.Height; |
|||
break; |
|||
case VerticalAlignment.Bottom: |
|||
top = finalSize.Height - child.DesiredSize.Value.Height; |
|||
height = child.DesiredSize.Value.Height; |
|||
break; |
|||
default: |
|||
top = 0; |
|||
height = finalSize.Height; |
|||
break; |
|||
} |
|||
|
|||
child.Arrange(new Rect(left, top, width, height)); |
|||
} |
|||
|
|||
return finalSize; |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; |
|||
|
|||
if (child != null) |
|||
{ |
|||
child.Measure(availableSize); |
|||
return child.DesiredSize.Value; |
|||
} |
|||
|
|||
return new Size(); |
|||
} |
|||
|
|||
private void ContentChanged(Tuple<object, object> content) |
|||
{ |
|||
if (content.Item1 != null) |
|||
{ |
|||
this.visualChild.VisualParent = null; |
|||
ILogical logical = content.Item1 as ILogical; |
|||
|
|||
if (logical != null) |
|||
{ |
|||
logical.LogicalParent = null; |
|||
} |
|||
} |
|||
|
|||
if (content.Item2 != null) |
|||
{ |
|||
Control control = content.Item2 as Control; |
|||
|
|||
if (control == null) |
|||
{ |
|||
control = this.GetDataTemplate(content.Item2).Build(content.Item2); |
|||
} |
|||
|
|||
control.TemplatedParent = null; |
|||
((IVisual)control).VisualParent = this; |
|||
this.visualChild = control; |
|||
|
|||
ILogical logical = content.Item2 as ILogical; |
|||
|
|||
if (logical != null) |
|||
{ |
|||
logical.LogicalParent = (ILogical)this.TemplatedParent; |
|||
} |
|||
} |
|||
|
|||
this.InvalidateMeasure(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,268 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Control.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Input; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
using Perspex.Styling; |
|||
using Splat; |
|||
|
|||
public class Control : InputElement, ILogical, IStyleable, IStyled |
|||
{ |
|||
public static readonly PerspexProperty<Brush> BackgroundProperty = |
|||
PerspexProperty.Register<Control, Brush>("Background", inherits: true); |
|||
|
|||
public static readonly PerspexProperty<Brush> BorderBrushProperty = |
|||
PerspexProperty.Register<Control, Brush>("BorderBrush"); |
|||
|
|||
public static readonly PerspexProperty<double> BorderThicknessProperty = |
|||
PerspexProperty.Register<Control, double>("BorderThickness"); |
|||
|
|||
public static readonly PerspexProperty<double> FontSizeProperty = |
|||
PerspexProperty.Register<Control, double>( |
|||
"FontSize", |
|||
defaultValue: 12.0, |
|||
inherits: true); |
|||
|
|||
public static readonly PerspexProperty<Brush> ForegroundProperty = |
|||
PerspexProperty.Register<Control, Brush>("Foreground", new SolidColorBrush(0xff000000), true); |
|||
|
|||
public static readonly PerspexProperty<Control> ParentProperty = |
|||
PerspexProperty.Register<Control, Control>("Parent"); |
|||
|
|||
public static readonly PerspexProperty<ITemplatedControl> TemplatedParentProperty = |
|||
PerspexProperty.Register<Control, ITemplatedControl>("TemplatedParent", inherits: true); |
|||
|
|||
private Classes classes; |
|||
|
|||
private DataTemplates dataTemplates; |
|||
|
|||
private string id; |
|||
|
|||
private Styles styles; |
|||
|
|||
static Control() |
|||
{ |
|||
AffectsMeasure(IsVisibleProperty); |
|||
} |
|||
|
|||
public Control() |
|||
{ |
|||
this.classes = new Classes(); |
|||
this.AddPseudoClass(IsPointerOverProperty, ":pointerover"); |
|||
this.AddPseudoClass(IsFocusedProperty, ":focus"); |
|||
} |
|||
|
|||
public Brush Background |
|||
{ |
|||
get { return this.GetValue(BackgroundProperty); } |
|||
set { this.SetValue(BackgroundProperty, value); } |
|||
} |
|||
|
|||
public Brush BorderBrush |
|||
{ |
|||
get { return this.GetValue(BorderBrushProperty); } |
|||
set { this.SetValue(BorderBrushProperty, value); } |
|||
} |
|||
|
|||
public double BorderThickness |
|||
{ |
|||
get { return this.GetValue(BorderThicknessProperty); } |
|||
set { this.SetValue(BorderThicknessProperty, value); } |
|||
} |
|||
|
|||
public Classes Classes |
|||
{ |
|||
get |
|||
{ |
|||
return this.classes; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
if (this.classes != value) |
|||
{ |
|||
this.classes.Clear(); |
|||
this.classes.Add(value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public DataTemplates DataTemplates |
|||
{ |
|||
get |
|||
{ |
|||
if (this.dataTemplates == null) |
|||
{ |
|||
this.dataTemplates = new DataTemplates(); |
|||
} |
|||
|
|||
return this.dataTemplates; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.dataTemplates = value; |
|||
} |
|||
} |
|||
|
|||
public double FontSize |
|||
{ |
|||
get { return this.GetValue(FontSizeProperty); } |
|||
set { this.SetValue(FontSizeProperty, value); } |
|||
} |
|||
|
|||
public Brush Foreground |
|||
{ |
|||
get { return this.GetValue(ForegroundProperty); } |
|||
set { this.SetValue(ForegroundProperty, value); } |
|||
} |
|||
|
|||
public string Id |
|||
{ |
|||
get |
|||
{ |
|||
return this.id; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
if (this.id != null) |
|||
{ |
|||
throw new InvalidOperationException("ID already set."); |
|||
} |
|||
|
|||
if (((IVisual)this).VisualParent != null) |
|||
{ |
|||
throw new InvalidOperationException("Cannot set ID : control already added to tree."); |
|||
} |
|||
|
|||
this.id = value; |
|||
} |
|||
} |
|||
|
|||
public Control Parent |
|||
{ |
|||
get { return this.GetValue(ParentProperty); } |
|||
protected set { this.SetValue(ParentProperty, value); } |
|||
} |
|||
|
|||
public Styles Styles |
|||
{ |
|||
get |
|||
{ |
|||
if (this.styles == null) |
|||
{ |
|||
this.styles = new Styles(); |
|||
} |
|||
|
|||
return this.styles; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.styles = value; |
|||
} |
|||
} |
|||
|
|||
public ITemplatedControl TemplatedParent |
|||
{ |
|||
get { return this.GetValue(TemplatedParentProperty); } |
|||
internal set { this.SetValue(TemplatedParentProperty, value); } |
|||
} |
|||
|
|||
ILogical ILogical.LogicalParent |
|||
{ |
|||
get { return this.Parent; } |
|||
set { this.Parent = (Control)value; } |
|||
} |
|||
|
|||
IEnumerable<ILogical> ILogical.LogicalChildren |
|||
{ |
|||
get { return Enumerable.Empty<ILogical>(); } |
|||
} |
|||
|
|||
protected override void OnAttachedToVisualTree(ILayoutRoot root) |
|||
{ |
|||
IStyler styler = Locator.Current.GetService<IStyler>(); |
|||
styler.ApplyStyles(this); |
|||
} |
|||
|
|||
protected void AddPseudoClass(PerspexProperty<bool> property, string className) |
|||
{ |
|||
this.GetObservable(property).Subscribe(x => |
|||
{ |
|||
if (x) |
|||
{ |
|||
this.classes.Add(className); |
|||
} |
|||
else |
|||
{ |
|||
this.classes.Remove(className); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
protected virtual DataTemplate FindDataTemplate(object content) |
|||
{ |
|||
Control control = content as Control; |
|||
|
|||
if (control != null) |
|||
{ |
|||
return new DataTemplate(x => control); |
|||
} |
|||
|
|||
ILogical node = this; |
|||
|
|||
while (node != null) |
|||
{ |
|||
control = node as Control; |
|||
|
|||
if (control != null) |
|||
{ |
|||
foreach (DataTemplate dt in control.DataTemplates.Reverse()) |
|||
{ |
|||
if (dt.Match(content)) |
|||
{ |
|||
return dt; |
|||
} |
|||
} |
|||
} |
|||
|
|||
node = node.LogicalParent; |
|||
|
|||
if (node == null && control != null) |
|||
{ |
|||
node = control.TemplatedParent as ILogical; |
|||
} |
|||
} |
|||
|
|||
if (Application.Current != null && Application.Current.DataTemplates != null) |
|||
{ |
|||
foreach (DataTemplate dt in Application.Current.DataTemplates.Reverse()) |
|||
{ |
|||
if (dt.Match(content)) |
|||
{ |
|||
return dt; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
protected DataTemplate GetDataTemplate(object content) |
|||
{ |
|||
return this.FindDataTemplate(content) ?? DataTemplate.Default; |
|||
} |
|||
} |
|||
} |
|||
@ -1,39 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ControlTemplate.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
|
|||
public class ControlTemplate |
|||
{ |
|||
private Func<ITemplatedControl, Control> build; |
|||
|
|||
public ControlTemplate(Func<ITemplatedControl, Control> build) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(build != null); |
|||
|
|||
this.build = build; |
|||
} |
|||
|
|||
public static ControlTemplate Create<TControl>(Func<TControl, Control> build) |
|||
where TControl : ITemplatedControl |
|||
{ |
|||
Contract.Requires<NullReferenceException>(build != null); |
|||
|
|||
return new ControlTemplate(c => build((TControl)c)); |
|||
} |
|||
|
|||
public Control Build(ITemplatedControl templatedParent) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(templatedParent != null); |
|||
|
|||
Control root = this.build(templatedParent); |
|||
root.TemplatedParent = templatedParent; |
|||
return root; |
|||
} |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Controls.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
using System.Collections.Generic; |
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class Controls : PerspexList<Control> |
|||
{ |
|||
public Controls() |
|||
{ |
|||
} |
|||
|
|||
public Controls(IEnumerable<Control> items) |
|||
: base(items) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="DataTemplate.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Reflection; |
|||
|
|||
public class DataTemplate |
|||
{ |
|||
public static readonly DataTemplate Default = |
|||
new DataTemplate(typeof(object), o => new TextBlock { Text = o.ToString() }); |
|||
|
|||
public DataTemplate(Func<object, Control> build) |
|||
: this(o => true, build) |
|||
{ |
|||
} |
|||
|
|||
public DataTemplate(Type type, Func<object, Control> build) |
|||
: this(o => IsInstance(o, type), build) |
|||
{ |
|||
} |
|||
|
|||
public DataTemplate(Func<object, bool> match, Func<object, Control> build) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(match != null); |
|||
Contract.Requires<ArgumentNullException>(build != null); |
|||
|
|||
this.Match = match; |
|||
this.Build = build; |
|||
} |
|||
|
|||
public static bool IsInstance(object o, Type t) |
|||
{ |
|||
return t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()); |
|||
} |
|||
|
|||
public Func<object, bool> Match { get; private set; } |
|||
|
|||
public Func<object, Control> Build { get; private set; } |
|||
} |
|||
|
|||
public class DataTemplate<T> : DataTemplate |
|||
{ |
|||
public DataTemplate(Func<T, Control> build) |
|||
: base(typeof(T), Cast(build)) |
|||
{ |
|||
} |
|||
|
|||
public DataTemplate(Func<T, bool> match, Func<T, Control> build) |
|||
: base(CastMatch(match), Cast(build)) |
|||
{ |
|||
} |
|||
|
|||
private static Func<object, bool> CastMatch(Func<T, bool> f) |
|||
{ |
|||
return o => (o is T) ? f((T)o) : false; |
|||
} |
|||
|
|||
private static Func<object, TResult> Cast<TResult>(Func<T, TResult> f) |
|||
{ |
|||
return o => f((T)o); |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="DataTemplates.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.Linq; |
|||
using System.Reactive; |
|||
using System.Reactive.Subjects; |
|||
|
|||
public class DataTemplates : PerspexList<DataTemplate> |
|||
{ |
|||
} |
|||
} |
|||
@ -1,84 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Decorator.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Layout; |
|||
|
|||
public class Decorator : Control, IVisual |
|||
{ |
|||
public static readonly PerspexProperty<Control> ContentProperty = |
|||
PerspexProperty.Register<Decorator, Control>("Content"); |
|||
|
|||
public static readonly PerspexProperty<Thickness> PaddingProperty = |
|||
PerspexProperty.Register<Decorator, Thickness>("Padding"); |
|||
|
|||
public Decorator() |
|||
{ |
|||
this.GetObservableWithHistory(ContentProperty).Subscribe(x => |
|||
{ |
|||
if (x.Item1 != null) |
|||
{ |
|||
((IVisual)this).RemoveVisualChild(x.Item1); |
|||
((ILogical)this).RemoveLogicalChild(x.Item1); |
|||
} |
|||
|
|||
if (x.Item2 != null) |
|||
{ |
|||
((IVisual)this).AddVisualChild(x.Item2); |
|||
((ILogical)this).AddLogicalChild(x.Item2); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Control Content |
|||
{ |
|||
get { return this.GetValue(ContentProperty); } |
|||
set { this.SetValue(ContentProperty, value); } |
|||
} |
|||
|
|||
public Thickness Padding |
|||
{ |
|||
get { return this.GetValue(PaddingProperty); } |
|||
set { this.SetValue(PaddingProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.ExistingVisualChildren |
|||
{ |
|||
get { return ((IVisual)this).VisualChildren; } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.VisualChildren |
|||
{ |
|||
get |
|||
{ |
|||
Control content = this.Content; |
|||
return Enumerable.Repeat(content, content != null ? 1 : 0); |
|||
} |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
Control content = this.Content; |
|||
|
|||
if (content != null) |
|||
{ |
|||
content.Arrange(new Rect(finalSize).Deflate(this.Padding)); |
|||
} |
|||
|
|||
return finalSize; |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
return LayoutHelper.MeasureDecorator(this, this.Content, availableSize, this.Padding); |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="DefinitionBase.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class DefinitionBase : PerspexObject |
|||
{ |
|||
public static readonly PerspexProperty<string> SharedSizeGroupProperty = |
|||
PerspexProperty.Register<DefinitionBase, string>("SharedSizeGroup", inherits: true); |
|||
|
|||
public string SharedSizeGroup |
|||
{ |
|||
get { return this.GetValue(SharedSizeGroupProperty); } |
|||
set { this.SetValue(SharedSizeGroupProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,805 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Grid.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
public class Grid : Panel |
|||
{ |
|||
public static readonly PerspexProperty<int> ColumnProperty = |
|||
PerspexProperty.RegisterAttached<Grid, Control, int>("Column"); |
|||
|
|||
public static readonly PerspexProperty<int> ColumnSpanProperty = |
|||
PerspexProperty.RegisterAttached<Grid, Control, int>("ColumnSpan", 1); |
|||
|
|||
public static readonly PerspexProperty<bool> IsSharedSizeScopeProperty = |
|||
PerspexProperty.RegisterAttached<Grid, Control, bool>("IsSharedSizeScopeProperty"); |
|||
|
|||
public static readonly PerspexProperty<int> RowProperty = |
|||
PerspexProperty.RegisterAttached<Grid, Control, int>("Row"); |
|||
|
|||
public static readonly PerspexProperty<int> RowSpanProperty = |
|||
PerspexProperty.RegisterAttached<Grid, Control, int>("RowSpan", 1); |
|||
|
|||
private Segment[,] rowMatrix; |
|||
private Segment[,] colMatrix; |
|||
|
|||
public Grid() |
|||
{ |
|||
this.ColumnDefinitions = new ColumnDefinitions(); |
|||
this.RowDefinitions = new RowDefinitions(); |
|||
} |
|||
|
|||
public ColumnDefinitions ColumnDefinitions |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public RowDefinitions RowDefinitions |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public static int GetColumn(PerspexObject element) |
|||
{ |
|||
return element.GetValue(ColumnProperty); |
|||
} |
|||
|
|||
public static int GetColumnSpan(PerspexObject element) |
|||
{ |
|||
return element.GetValue(ColumnSpanProperty); |
|||
} |
|||
|
|||
public static int GetRow(PerspexObject element) |
|||
{ |
|||
return element.GetValue(RowProperty); |
|||
} |
|||
|
|||
public static int GetRowSpan(PerspexObject element) |
|||
{ |
|||
return element.GetValue(RowSpanProperty); |
|||
} |
|||
|
|||
public static void SetColumn(PerspexObject element, int value) |
|||
{ |
|||
element.SetValue(ColumnProperty, value); |
|||
} |
|||
|
|||
public static void SetColumnSpan(PerspexObject element, int value) |
|||
{ |
|||
element.SetValue(ColumnSpanProperty, value); |
|||
} |
|||
|
|||
public static void SetRow(PerspexObject element, int value) |
|||
{ |
|||
element.SetValue(RowProperty, value); |
|||
} |
|||
|
|||
public static void SetRowSpan(PerspexObject element, int value) |
|||
{ |
|||
element.SetValue(RowSpanProperty, value); |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size constraint) |
|||
{ |
|||
Size totalSize = constraint; |
|||
int colCount = this.ColumnDefinitions.Count; |
|||
int rowCount = this.RowDefinitions.Count; |
|||
double totalStarsX = 0; |
|||
double totalStarsY = 0; |
|||
bool emptyRows = rowCount == 0; |
|||
bool emptyCols = colCount == 0; |
|||
bool hasChildren = this.Children.Count > 0; |
|||
|
|||
if (emptyRows) |
|||
{ |
|||
rowCount = 1; |
|||
} |
|||
|
|||
if (emptyCols) |
|||
{ |
|||
colCount = 1; |
|||
} |
|||
|
|||
this.CreateMatrices(rowCount, colCount); |
|||
|
|||
if (emptyRows) |
|||
{ |
|||
this.rowMatrix[0, 0] = new Segment(0, 0, double.PositiveInfinity, GridUnitType.Star); |
|||
this.rowMatrix[0, 0].Stars = 1.0; |
|||
totalStarsY += 1.0; |
|||
} |
|||
else |
|||
{ |
|||
for (int i = 0; i < rowCount; i++) |
|||
{ |
|||
RowDefinition rowdef = this.RowDefinitions[i]; |
|||
GridLength height = rowdef.Height; |
|||
|
|||
rowdef.ActualHeight = double.PositiveInfinity; |
|||
this.rowMatrix[i, i] = new Segment(0, rowdef.MinHeight, rowdef.MaxHeight, height.GridUnitType); |
|||
|
|||
if (height.GridUnitType == GridUnitType.Pixel) |
|||
{ |
|||
this.rowMatrix[i, i].OfferedSize = Clamp(height.Value, this.rowMatrix[i, i].Min, this.rowMatrix[i, i].Max); |
|||
this.rowMatrix[i, i].DesiredSize = this.rowMatrix[i, i].OfferedSize; |
|||
rowdef.ActualHeight = this.rowMatrix[i, i].OfferedSize; |
|||
} |
|||
else if (height.GridUnitType == GridUnitType.Star) |
|||
{ |
|||
this.rowMatrix[i, i].Stars = height.Value; |
|||
totalStarsY += height.Value; |
|||
} |
|||
else if (height.GridUnitType == GridUnitType.Auto) |
|||
{ |
|||
this.rowMatrix[i, i].OfferedSize = Clamp(0, this.rowMatrix[i, i].Min, this.rowMatrix[i, i].Max); |
|||
this.rowMatrix[i, i].DesiredSize = this.rowMatrix[i, i].OfferedSize; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (emptyCols) |
|||
{ |
|||
this.colMatrix[0, 0] = new Segment(0, 0, double.PositiveInfinity, GridUnitType.Star); |
|||
this.colMatrix[0, 0].Stars = 1.0; |
|||
totalStarsX += 1.0; |
|||
} |
|||
else |
|||
{ |
|||
for (int i = 0; i < colCount; i++) |
|||
{ |
|||
ColumnDefinition coldef = this.ColumnDefinitions[i]; |
|||
GridLength width = coldef.Width; |
|||
|
|||
coldef.ActualWidth = double.PositiveInfinity; |
|||
this.colMatrix[i, i] = new Segment(0, coldef.MinWidth, coldef.MaxWidth, width.GridUnitType); |
|||
|
|||
if (width.GridUnitType == GridUnitType.Pixel) |
|||
{ |
|||
this.colMatrix[i, i].OfferedSize = Clamp(width.Value, this.colMatrix[i, i].Min, this.colMatrix[i, i].Max); |
|||
this.colMatrix[i, i].DesiredSize = this.colMatrix[i, i].OfferedSize; |
|||
coldef.ActualWidth = this.colMatrix[i, i].OfferedSize; |
|||
} |
|||
else if (width.GridUnitType == GridUnitType.Star) |
|||
{ |
|||
this.colMatrix[i, i].Stars = width.Value; |
|||
totalStarsX += width.Value; |
|||
} |
|||
else if (width.GridUnitType == GridUnitType.Auto) |
|||
{ |
|||
this.colMatrix[i, i].OfferedSize = Clamp(0, this.colMatrix[i, i].Min, this.colMatrix[i, i].Max); |
|||
this.colMatrix[i, i].DesiredSize = this.colMatrix[i, i].OfferedSize; |
|||
} |
|||
} |
|||
} |
|||
|
|||
List<GridNode> sizes = new List<GridNode>(); |
|||
GridNode node; |
|||
GridNode separator = new GridNode(null, 0, 0, 0); |
|||
int separatorIndex; |
|||
|
|||
sizes.Add(separator); |
|||
|
|||
// Pre-process the grid children so that we know what types of elements we have so
|
|||
// we can apply our special measuring rules.
|
|||
GridWalker gridWalker = new GridWalker(this, this.rowMatrix, this.colMatrix); |
|||
|
|||
for (int i = 0; i < 6; i++) |
|||
{ |
|||
// These bools tell us which grid element type we should be measuring. i.e.
|
|||
// 'star/auto' means we should measure elements with a star row and auto col
|
|||
bool autoAuto = i == 0; |
|||
bool starAuto = i == 1; |
|||
bool autoStar = i == 2; |
|||
bool starAutoAgain = i == 3; |
|||
bool nonStar = i == 4; |
|||
bool remainingStar = i == 5; |
|||
|
|||
if (hasChildren) |
|||
{ |
|||
this.ExpandStarCols(totalSize); |
|||
this.ExpandStarRows(totalSize); |
|||
} |
|||
|
|||
foreach (Control child in this.Children) |
|||
{ |
|||
int col, row; |
|||
int colspan, rowspan; |
|||
double childSizeX = 0; |
|||
double childSizeY = 0; |
|||
bool starCol = false; |
|||
bool starRow = false; |
|||
bool autoCol = false; |
|||
bool autoRow = false; |
|||
|
|||
col = Math.Min(GetColumn(child), colCount - 1); |
|||
row = Math.Min(GetRow(child), rowCount - 1); |
|||
colspan = Math.Min(GetColumnSpan(child), colCount - col); |
|||
rowspan = Math.Min(GetRowSpan(child), rowCount - row); |
|||
|
|||
for (int r = row; r < row + rowspan; r++) |
|||
{ |
|||
starRow |= this.rowMatrix[r, r].Type == GridUnitType.Star; |
|||
autoRow |= this.rowMatrix[r, r].Type == GridUnitType.Auto; |
|||
} |
|||
|
|||
for (int c = col; c < col + colspan; c++) |
|||
{ |
|||
starCol |= this.colMatrix[c, c].Type == GridUnitType.Star; |
|||
autoCol |= this.colMatrix[c, c].Type == GridUnitType.Auto; |
|||
} |
|||
|
|||
// This series of if statements checks whether or not we should measure
|
|||
// the current element and also if we need to override the sizes
|
|||
// passed to the Measure call.
|
|||
|
|||
// If the element has Auto rows and Auto columns and does not span Star
|
|||
// rows/cols it should only be measured in the auto_auto phase.
|
|||
// There are similar rules governing auto/star and star/auto elements.
|
|||
// NOTE: star/auto elements are measured twice. The first time with
|
|||
// an override for height, the second time without it.
|
|||
if (autoRow && autoCol && !starRow && !starCol) |
|||
{ |
|||
if (!autoAuto) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
childSizeX = double.PositiveInfinity; |
|||
childSizeY = double.PositiveInfinity; |
|||
} |
|||
else if (starRow && autoCol && !starCol) |
|||
{ |
|||
if (!(starAuto || starAutoAgain)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
if (starAuto && gridWalker.HasAutoStar) |
|||
{ |
|||
childSizeY = double.PositiveInfinity; |
|||
} |
|||
|
|||
childSizeX = double.PositiveInfinity; |
|||
} |
|||
else if (autoRow && starCol && !starRow) |
|||
{ |
|||
if (!autoStar) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
childSizeY = double.PositiveInfinity; |
|||
} |
|||
else if ((autoRow || autoCol) && !(starRow || starCol)) |
|||
{ |
|||
if (!nonStar) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
if (autoRow) |
|||
{ |
|||
childSizeY = double.PositiveInfinity; |
|||
} |
|||
|
|||
if (autoCol) |
|||
{ |
|||
childSizeX = double.PositiveInfinity; |
|||
} |
|||
} |
|||
else if (!(starRow || starCol)) |
|||
{ |
|||
if (!nonStar) |
|||
{ |
|||
continue; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (!remainingStar) |
|||
{ |
|||
continue; |
|||
} |
|||
} |
|||
|
|||
for (int r = row; r < row + rowspan; r++) |
|||
{ |
|||
childSizeY += this.rowMatrix[r, r].OfferedSize; |
|||
} |
|||
|
|||
for (int c = col; c < col + colspan; c++) |
|||
{ |
|||
childSizeX += this.colMatrix[c, c].OfferedSize; |
|||
} |
|||
|
|||
child.Measure(new Size(childSizeX, childSizeY)); |
|||
Size desired = child.DesiredSize.Value; |
|||
|
|||
// Elements distribute their height based on two rules:
|
|||
// 1) Elements with rowspan/colspan == 1 distribute their height first
|
|||
// 2) Everything else distributes in a LIFO manner.
|
|||
// As such, add all UIElements with rowspan/colspan == 1 after the separator in
|
|||
// the list and everything else before it. Then to process, just keep popping
|
|||
// elements off the end of the list.
|
|||
if (!starAuto) |
|||
{ |
|||
node = new GridNode(this.rowMatrix, row + rowspan - 1, row, desired.Height); |
|||
separatorIndex = sizes.IndexOf(separator); |
|||
sizes.Insert(node.Row == node.Column ? separatorIndex + 1 : separatorIndex, node); |
|||
} |
|||
|
|||
node = new GridNode(this.colMatrix, col + colspan - 1, col, desired.Width); |
|||
|
|||
separatorIndex = sizes.IndexOf(separator); |
|||
sizes.Insert(node.Row == node.Column ? separatorIndex + 1 : separatorIndex, node); |
|||
} |
|||
|
|||
sizes.Remove(separator); |
|||
|
|||
while (sizes.Count > 0) |
|||
{ |
|||
node = sizes.Last(); |
|||
node.Matrix[node.Row, node.Column].DesiredSize = Math.Max(node.Matrix[node.Row, node.Column].DesiredSize, node.Size); |
|||
this.AllocateDesiredSize(rowCount, colCount); |
|||
sizes.Remove(node); |
|||
} |
|||
|
|||
sizes.Add(separator); |
|||
} |
|||
|
|||
// Once we have measured and distributed all sizes, we have to store
|
|||
// the results. Every time we want to expand the rows/cols, this will
|
|||
// be used as the baseline.
|
|||
this.SaveMeasureResults(); |
|||
|
|||
sizes.Remove(separator); |
|||
|
|||
double gridSizeX = 0; |
|||
double gridSizeY = 0; |
|||
|
|||
for (int c = 0; c < colCount; c++) |
|||
{ |
|||
gridSizeX += this.colMatrix[c, c].DesiredSize; |
|||
} |
|||
|
|||
for (int r = 0; r < rowCount; r++) |
|||
{ |
|||
gridSizeY += this.rowMatrix[r, r].DesiredSize; |
|||
} |
|||
|
|||
return new Size(gridSizeX, gridSizeY); |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
int colCount = this.ColumnDefinitions.Count; |
|||
int rowCount = this.RowDefinitions.Count; |
|||
int colMatrixDim = this.colMatrix.GetUpperBound(0) + 1; |
|||
int rowMatrixDim = this.rowMatrix.GetUpperBound(0) + 1; |
|||
|
|||
this.RestoreMeasureResults(); |
|||
|
|||
double totalConsumedX = 0; |
|||
double totalConsumedY = 0; |
|||
|
|||
for (int c = 0; c < colMatrixDim; c++) |
|||
{ |
|||
this.colMatrix[c, c].OfferedSize = this.colMatrix[c, c].DesiredSize; |
|||
totalConsumedX += this.colMatrix[c, c].OfferedSize; |
|||
} |
|||
|
|||
for (int r = 0; r < rowMatrixDim; r++) |
|||
{ |
|||
this.rowMatrix[r, r].OfferedSize = this.rowMatrix[r, r].DesiredSize; |
|||
totalConsumedY += this.rowMatrix[r, r].OfferedSize; |
|||
} |
|||
|
|||
if (totalConsumedX != finalSize.Width) |
|||
{ |
|||
this.ExpandStarCols(finalSize); |
|||
} |
|||
|
|||
if (totalConsumedY != finalSize.Height) |
|||
{ |
|||
this.ExpandStarRows(finalSize); |
|||
} |
|||
|
|||
for (int c = 0; c < colCount; c++) |
|||
{ |
|||
this.ColumnDefinitions[c].ActualWidth = this.colMatrix[c, c].OfferedSize; |
|||
} |
|||
|
|||
for (int r = 0; r < rowCount; r++) |
|||
{ |
|||
this.RowDefinitions[r].ActualHeight = this.rowMatrix[r, r].OfferedSize; |
|||
} |
|||
|
|||
foreach (Control child in this.Children) |
|||
{ |
|||
int col = Math.Min(GetColumn(child), colMatrixDim - 1); |
|||
int row = Math.Min(GetRow(child), rowMatrixDim - 1); |
|||
int colspan = Math.Min(GetColumnSpan(child), colMatrixDim - col); |
|||
int rowspan = Math.Min(GetRowSpan(child), rowMatrixDim - row); |
|||
|
|||
double childFinalX = 0; |
|||
double childFinalY = 0; |
|||
double childFinalW = 0; |
|||
double childFinalH = 0; |
|||
|
|||
for (int c = 0; c < col; c++) |
|||
{ |
|||
childFinalX += this.colMatrix[c, c].OfferedSize; |
|||
} |
|||
|
|||
for (int c = col; c < col + colspan; c++) |
|||
{ |
|||
childFinalW += this.colMatrix[c, c].OfferedSize; |
|||
} |
|||
|
|||
for (int r = 0; r < row; r++) |
|||
{ |
|||
childFinalY += this.rowMatrix[r, r].OfferedSize; |
|||
} |
|||
|
|||
for (int r = row; r < row + rowspan; r++) |
|||
{ |
|||
childFinalH += this.rowMatrix[r, r].OfferedSize; |
|||
} |
|||
|
|||
child.Arrange(new Rect(childFinalX, childFinalY, childFinalW, childFinalH)); |
|||
} |
|||
|
|||
return finalSize; |
|||
} |
|||
|
|||
private static double Clamp(double val, double min, double max) |
|||
{ |
|||
if (val < min) |
|||
{ |
|||
return min; |
|||
} |
|||
else if (val > max) |
|||
{ |
|||
return max; |
|||
} |
|||
else |
|||
{ |
|||
return val; |
|||
} |
|||
} |
|||
|
|||
private void CreateMatrices(int rowCount, int colCount) |
|||
{ |
|||
if (this.rowMatrix == null || this.colMatrix == null || |
|||
this.rowMatrix.GetUpperBound(0) != rowCount - 1 || |
|||
this.colMatrix.GetUpperBound(0) != colCount - 1) |
|||
{ |
|||
this.rowMatrix = new Segment[rowCount, rowCount]; |
|||
this.colMatrix = new Segment[colCount, colCount]; |
|||
} |
|||
} |
|||
|
|||
private void ExpandStarCols(Size availableSize) |
|||
{ |
|||
int columnsCount = this.ColumnDefinitions.Count; |
|||
double width = availableSize.Width; |
|||
|
|||
for (int i = 0; i < this.colMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
if (this.colMatrix[i, i].Type == GridUnitType.Star) |
|||
{ |
|||
this.colMatrix[i, i].OfferedSize = 0; |
|||
} |
|||
else |
|||
{ |
|||
width = Math.Max(availableSize.Width - this.colMatrix[i, i].OfferedSize, 0); |
|||
} |
|||
} |
|||
|
|||
this.AssignSize(this.colMatrix, 0, this.colMatrix.GetUpperBound(0), ref width, GridUnitType.Star, false); |
|||
width = Math.Max(0, width); |
|||
|
|||
if (columnsCount > 0) |
|||
{ |
|||
for (int i = 0; i < this.colMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
if (this.colMatrix[i, i].Type == GridUnitType.Star) |
|||
{ |
|||
this.ColumnDefinitions[i].ActualWidth = this.colMatrix[i, i].OfferedSize; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void ExpandStarRows(Size availableSize) |
|||
{ |
|||
int rowCount = this.RowDefinitions.Count; |
|||
double height = availableSize.Height; |
|||
|
|||
// When expanding star rows, we need to zero out their height before
|
|||
// calling AssignSize. AssignSize takes care of distributing the
|
|||
// available size when there are Mins and Maxs applied.
|
|||
for (int i = 0; i < this.rowMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
if (this.rowMatrix[i, i].Type == GridUnitType.Star) |
|||
{ |
|||
this.rowMatrix[i, i].OfferedSize = 0.0; |
|||
} |
|||
else |
|||
{ |
|||
height = Math.Max(availableSize.Height - this.rowMatrix[i, i].OfferedSize, 0); |
|||
} |
|||
} |
|||
|
|||
this.AssignSize(this.rowMatrix, 0, this.rowMatrix.GetUpperBound(0), ref height, GridUnitType.Star, false); |
|||
|
|||
if (rowCount > 0) |
|||
{ |
|||
for (int i = 0; i < this.rowMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
if (this.rowMatrix[i, i].Type == GridUnitType.Star) |
|||
{ |
|||
this.RowDefinitions[i].ActualHeight = this.rowMatrix[i, i].OfferedSize; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void AssignSize( |
|||
Segment[,] matrix, |
|||
int start, |
|||
int end, |
|||
ref double size, |
|||
GridUnitType type, |
|||
bool desiredSize) |
|||
{ |
|||
double count = 0; |
|||
bool assigned; |
|||
|
|||
// Count how many segments are of the correct type. If we're measuring Star rows/cols
|
|||
// we need to count the number of stars instead.
|
|||
for (int i = start; i <= end; i++) |
|||
{ |
|||
double segmentSize = desiredSize ? matrix[i, i].DesiredSize : matrix[i, i].OfferedSize; |
|||
if (segmentSize < matrix[i, i].Max) |
|||
{ |
|||
count += type == GridUnitType.Star ? matrix[i, i].Stars : 1; |
|||
} |
|||
} |
|||
|
|||
do |
|||
{ |
|||
double contribution = size / count; |
|||
|
|||
assigned = false; |
|||
|
|||
for (int i = start; i <= end; i++) |
|||
{ |
|||
double segmentSize = desiredSize ? matrix[i, i].DesiredSize : matrix[i, i].OfferedSize; |
|||
|
|||
if (!(matrix[i, i].Type == type && segmentSize < matrix[i, i].Max)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
double newsize = segmentSize; |
|||
newsize += contribution * (type == GridUnitType.Star ? matrix[i, i].Stars : 1); |
|||
newsize = Math.Min(newsize, matrix[i, i].Max); |
|||
assigned |= newsize > segmentSize; |
|||
size -= newsize - segmentSize; |
|||
|
|||
if (desiredSize) |
|||
{ |
|||
matrix[i, i].DesiredSize = newsize; |
|||
} |
|||
else |
|||
{ |
|||
matrix[i, i].OfferedSize = newsize; |
|||
} |
|||
} |
|||
} |
|||
while (assigned); |
|||
} |
|||
|
|||
private void AllocateDesiredSize(int rowCount, int colCount) |
|||
{ |
|||
// First allocate the heights of the RowDefinitions, then allocate
|
|||
// the widths of the ColumnDefinitions.
|
|||
for (int i = 0; i < 2; i++) |
|||
{ |
|||
Segment[,] matrix = i == 0 ? this.rowMatrix : this.colMatrix; |
|||
int count = i == 0 ? rowCount : colCount; |
|||
|
|||
for (int row = count - 1; row >= 0; row--) |
|||
{ |
|||
for (int col = row; col >= 0; col--) |
|||
{ |
|||
bool spansStar = false; |
|||
for (int j = row; j >= col; j--) |
|||
{ |
|||
spansStar |= matrix[j, j].Type == GridUnitType.Star; |
|||
} |
|||
|
|||
// This is the amount of pixels which must be available between the grid rows
|
|||
// at index 'col' and 'row'. i.e. if 'row' == 0 and 'col' == 2, there must
|
|||
// be at least 'matrix [row][col].size' pixels of height allocated between
|
|||
// all the rows in the range col -> row.
|
|||
double current = matrix[row, col].DesiredSize; |
|||
|
|||
// Count how many pixels have already been allocated between the grid rows
|
|||
// in the range col -> row. The amount of pixels allocated to each grid row/column
|
|||
// is found on the diagonal of the matrix.
|
|||
double totalAllocated = 0; |
|||
|
|||
for (int k = row; k >= col; k--) |
|||
{ |
|||
totalAllocated += matrix[k, k].DesiredSize; |
|||
} |
|||
|
|||
// If the size requirement has not been met, allocate the additional required
|
|||
// size between 'pixel' rows, then 'star' rows, finally 'auto' rows, until all
|
|||
// height has been assigned.
|
|||
if (totalAllocated < current) |
|||
{ |
|||
double additional = current - totalAllocated; |
|||
|
|||
if (spansStar) |
|||
{ |
|||
this.AssignSize(matrix, col, row, ref additional, GridUnitType.Star, true); |
|||
} |
|||
else |
|||
{ |
|||
this.AssignSize(matrix, col, row, ref additional, GridUnitType.Pixel, true); |
|||
this.AssignSize(matrix, col, row, ref additional, GridUnitType.Auto, true); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
for (int r = 0; r < this.rowMatrix.GetUpperBound(0) + 1; r++) |
|||
{ |
|||
this.rowMatrix[r, r].OfferedSize = this.rowMatrix[r, r].DesiredSize; |
|||
} |
|||
|
|||
for (int c = 0; c < this.colMatrix.GetUpperBound(0) + 1; c++) |
|||
{ |
|||
this.colMatrix[c, c].OfferedSize = this.colMatrix[c, c].DesiredSize; |
|||
} |
|||
} |
|||
|
|||
private void SaveMeasureResults() |
|||
{ |
|||
for (int i = 0; i < this.rowMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
for (int j = 0; j < this.rowMatrix.GetUpperBound(0) + 1; j++) |
|||
{ |
|||
this.rowMatrix[i, j].OriginalSize = this.rowMatrix[i, j].OfferedSize; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < this.colMatrix.GetUpperBound(0); i++) |
|||
{ |
|||
for (int j = 0; j < this.colMatrix.GetUpperBound(0); j++) |
|||
{ |
|||
this.colMatrix[i, j].OriginalSize = this.colMatrix[i, j].OfferedSize; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void RestoreMeasureResults() |
|||
{ |
|||
for (int i = 0; i < this.rowMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
for (int j = 0; j < this.rowMatrix.GetUpperBound(0) + 1; j++) |
|||
{ |
|||
this.rowMatrix[i, j].OfferedSize = this.rowMatrix[i, j].OriginalSize; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < this.colMatrix.GetUpperBound(0) + 1; i++) |
|||
{ |
|||
for (int j = 0; j < this.colMatrix.GetUpperBound(0) + 1; j++) |
|||
{ |
|||
this.colMatrix[i, j].OfferedSize = this.colMatrix[i, j].OriginalSize; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private struct Segment |
|||
{ |
|||
public double OriginalSize; |
|||
public double Max; |
|||
public double Min; |
|||
public double DesiredSize; |
|||
public double OfferedSize; |
|||
public double Stars; |
|||
public GridUnitType Type; |
|||
|
|||
public Segment(double offeredSize, double min, double max, GridUnitType type) |
|||
{ |
|||
this.OriginalSize = 0; |
|||
this.Min = min; |
|||
this.Max = max; |
|||
this.DesiredSize = 0; |
|||
this.OfferedSize = offeredSize; |
|||
this.Stars = 0; |
|||
this.Type = type; |
|||
} |
|||
|
|||
public void Init(double offeredSize, double min, double max, GridUnitType type) |
|||
{ |
|||
this.OfferedSize = offeredSize; |
|||
this.Min = min; |
|||
this.Max = max; |
|||
this.Type = type; |
|||
} |
|||
} |
|||
|
|||
private struct GridNode |
|||
{ |
|||
public int Row; |
|||
public int Column; |
|||
public double Size; |
|||
public Segment[,] Matrix; |
|||
|
|||
public GridNode(Segment[,] matrix, int row, int col, double size) |
|||
{ |
|||
this.Matrix = matrix; |
|||
this.Row = row; |
|||
this.Column = col; |
|||
this.Size = size; |
|||
} |
|||
} |
|||
|
|||
private class GridWalker |
|||
{ |
|||
public GridWalker(Grid grid, Segment[,] rowMatrix, Segment[,] colMatrix) |
|||
{ |
|||
foreach (Control child in grid.Children) |
|||
{ |
|||
bool starCol = false; |
|||
bool starRow = false; |
|||
bool autoCol = false; |
|||
bool autoRow = false; |
|||
|
|||
int col = Math.Min(Grid.GetColumn(child), colMatrix.GetUpperBound(0)); |
|||
int row = Math.Min(Grid.GetRow(child), rowMatrix.GetUpperBound(0)); |
|||
int colspan = Math.Min(Grid.GetColumnSpan(child), colMatrix.GetUpperBound(0)); |
|||
int rowspan = Math.Min(Grid.GetRowSpan(child), rowMatrix.GetUpperBound(0)); |
|||
|
|||
for (int r = row; r < row + rowspan; r++) |
|||
{ |
|||
starRow |= rowMatrix[r, r].Type == GridUnitType.Star; |
|||
autoRow |= rowMatrix[r, r].Type == GridUnitType.Auto; |
|||
} |
|||
|
|||
for (int c = col; c < col + colspan; c++) |
|||
{ |
|||
starCol |= colMatrix[c, c].Type == GridUnitType.Star; |
|||
autoCol |= colMatrix[c, c].Type == GridUnitType.Auto; |
|||
} |
|||
|
|||
this.HasAutoAuto |= autoRow && autoCol && !starRow && !starCol; |
|||
this.HasStarAuto |= starRow && autoCol; |
|||
this.HasAutoStar |= autoRow && starCol; |
|||
} |
|||
} |
|||
|
|||
public bool HasAutoAuto { get; private set; } |
|||
|
|||
public bool HasStarAuto { get; private set; } |
|||
|
|||
public bool HasAutoStar { get; private set; } |
|||
} |
|||
} |
|||
} |
|||
@ -1,121 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GridLength.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
|
|||
public enum GridUnitType |
|||
{ |
|||
Auto = 0, |
|||
Pixel = 1, |
|||
Star = 2, |
|||
} |
|||
|
|||
public struct GridLength : IEquatable<GridLength> |
|||
{ |
|||
private GridUnitType type; |
|||
|
|||
private double value; |
|||
|
|||
public GridLength(double value) |
|||
: this(value, GridUnitType.Pixel) |
|||
{ |
|||
} |
|||
|
|||
public GridLength(double value, GridUnitType type) |
|||
{ |
|||
if (value < 0 || double.IsNaN(value) || double.IsInfinity(value)) |
|||
{ |
|||
throw new ArgumentException("Invalid value", "value"); |
|||
} |
|||
|
|||
if (type < GridUnitType.Auto || type > GridUnitType.Star) |
|||
{ |
|||
throw new ArgumentException("Invalid value", "type"); |
|||
} |
|||
|
|||
this.type = type; |
|||
this.value = value; |
|||
} |
|||
|
|||
public static GridLength Auto |
|||
{ |
|||
get { return new GridLength(0, GridUnitType.Auto); } |
|||
} |
|||
|
|||
public GridUnitType GridUnitType |
|||
{ |
|||
get { return this.type; } |
|||
} |
|||
|
|||
public bool IsAbsolute |
|||
{ |
|||
get { return this.type == GridUnitType.Pixel; } |
|||
} |
|||
|
|||
public bool IsAuto |
|||
{ |
|||
get { return this.type == GridUnitType.Auto; } |
|||
} |
|||
|
|||
public bool IsStar |
|||
{ |
|||
get { return this.type == GridUnitType.Star; } |
|||
} |
|||
|
|||
public double Value |
|||
{ |
|||
get { return this.value; } |
|||
} |
|||
|
|||
public static bool operator ==(GridLength a, GridLength b) |
|||
{ |
|||
return (a.IsAuto && b.IsAuto) || (a.value == b.value && a.type == b.type); |
|||
} |
|||
|
|||
public static bool operator !=(GridLength gl1, GridLength gl2) |
|||
{ |
|||
return !(gl1 == gl2); |
|||
} |
|||
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (o == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!(o is GridLength)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this == (GridLength)o; |
|||
} |
|||
|
|||
public bool Equals(GridLength gridLength) |
|||
{ |
|||
return this == gridLength; |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
return this.value.GetHashCode() ^ this.type.GetHashCode(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsAuto) |
|||
{ |
|||
return "Auto"; |
|||
} |
|||
|
|||
string s = this.value.ToString(); |
|||
return this.IsStar ? s + "*" : s; |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ContentControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
public class HeaderedContentControl : ContentControl, ILogical, IHeadered |
|||
{ |
|||
public static readonly PerspexProperty<object> HeaderProperty = |
|||
PerspexProperty.Register<ContentControl, object>("Header"); |
|||
|
|||
public object Header |
|||
{ |
|||
get { return this.GetValue(HeaderProperty); } |
|||
set { this.SetValue(HeaderProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<ILogical> ILogical.LogicalChildren |
|||
{ |
|||
get |
|||
{ |
|||
ILogical logicalContent = this.Content as ILogical; |
|||
ILogical logicalHeader = this.Header as ILogical; |
|||
|
|||
if (logicalContent != null) |
|||
{ |
|||
yield return logicalContent; |
|||
} |
|||
|
|||
if (logicalHeader != null) |
|||
{ |
|||
yield return logicalHeader; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="HeaderedItemsControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
|
|||
public class HeaderedItemsControl : ItemsControl |
|||
{ |
|||
public static readonly PerspexProperty<object> HeaderProperty = |
|||
HeaderedContentControl.HeaderProperty.AddOwner<HeaderedItemsControl>(); |
|||
|
|||
public object Header |
|||
{ |
|||
get { return this.GetValue(HeaderProperty); } |
|||
set { this.SetValue(HeaderProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ITemplatedControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
public interface ITemplatedControl |
|||
{ |
|||
IEnumerable<IVisual> VisualChildren { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets an observable for a <see cref="PerspexProperty"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="property">The property to get the observable for.</param>
|
|||
/// <returns>The observable.</returns>
|
|||
IObservable<T> GetObservable<T>(PerspexProperty<T> property); |
|||
} |
|||
} |
|||
@ -1,115 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Image.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using Perspex.Media.Imaging; |
|||
|
|||
public class Image : Control |
|||
{ |
|||
public static readonly PerspexProperty<Bitmap> SourceProperty = |
|||
PerspexProperty.Register<Image, Bitmap>("Source"); |
|||
|
|||
public static readonly PerspexProperty<Stretch> StretchProperty = |
|||
PerspexProperty.Register<Image, Stretch>("Stretch", Stretch.Uniform); |
|||
|
|||
public Bitmap Source |
|||
{ |
|||
get { return this.GetValue(SourceProperty); } |
|||
set { this.SetValue(SourceProperty, value); } |
|||
} |
|||
|
|||
public Stretch Stretch |
|||
{ |
|||
get { return (Stretch)this.GetValue(StretchProperty); } |
|||
set { this.SetValue(StretchProperty, value); } |
|||
} |
|||
|
|||
public override void Render(IDrawingContext drawingContext) |
|||
{ |
|||
Brush background = this.Background; |
|||
Bitmap source = this.Source; |
|||
|
|||
if (background != null) |
|||
{ |
|||
drawingContext.FillRectange(background, new Rect(this.ActualSize)); |
|||
} |
|||
|
|||
if (source != null) |
|||
{ |
|||
Rect viewPort = new Rect(this.ActualSize); |
|||
Size sourceSize = new Size(source.PixelWidth, source.PixelHeight); |
|||
Vector scale = CalculateScaling(this.ActualSize, sourceSize, this.Stretch); |
|||
Size scaledSize = sourceSize * scale; |
|||
Rect destRect = viewPort |
|||
.Center(new Rect(scaledSize)) |
|||
.Intersect(viewPort); |
|||
Rect sourceRect = new Rect(sourceSize) |
|||
.Center(new Rect(destRect.Size / scale)); |
|||
|
|||
drawingContext.DrawImage(source, 1, sourceRect, destRect); |
|||
} |
|||
} |
|||
|
|||
private static Vector CalculateScaling(Size availableSize, Size imageSize, Stretch stretch) |
|||
{ |
|||
double scaleX = 1; |
|||
double scaleY = 1; |
|||
|
|||
if (stretch != Stretch.None) |
|||
{ |
|||
scaleX = availableSize.Width / imageSize.Width; |
|||
scaleY = availableSize.Height / imageSize.Height; |
|||
|
|||
switch (stretch) |
|||
{ |
|||
case Stretch.Uniform: |
|||
scaleX = scaleY = Math.Min(scaleX, scaleY); |
|||
break; |
|||
case Stretch.UniformToFill: |
|||
scaleX = scaleY = Math.Max(scaleX, scaleY); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return new Vector(scaleX, scaleY); |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
double width = 0; |
|||
double height = 0; |
|||
Vector scale = new Vector(); |
|||
|
|||
if (this.Source != null) |
|||
{ |
|||
width = this.Source.PixelWidth; |
|||
height = this.Source.PixelHeight; |
|||
|
|||
if (this.Width > 0) |
|||
{ |
|||
availableSize = new Size(this.Width, availableSize.Height); |
|||
} |
|||
|
|||
if (this.Height > 0) |
|||
{ |
|||
availableSize = new Size(availableSize.Width, this.Height); |
|||
} |
|||
|
|||
scale = CalculateScaling(availableSize, new Size(width, height), this.Stretch); |
|||
} |
|||
|
|||
return new Size(width * scale.X, height * scale.Y); |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
return finalSize; |
|||
} |
|||
} |
|||
} |
|||
@ -1,137 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ItemsControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.ComponentModel; |
|||
using System.Linq; |
|||
|
|||
public class ItemsControl : TemplatedControl |
|||
{ |
|||
private static readonly ItemsPanelTemplate DefaultPanel = |
|||
new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); |
|||
|
|||
public static readonly PerspexProperty<IEnumerable> ItemsProperty = |
|||
PerspexProperty.Register<ItemsControl, IEnumerable>("Items"); |
|||
|
|||
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty = |
|||
PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel", defaultValue: DefaultPanel); |
|||
|
|||
private Dictionary<object, Control> controlsByItem = new Dictionary<object, Control>(); |
|||
|
|||
private Dictionary<Control, object> itemsByControl = new Dictionary<Control, object>(); |
|||
|
|||
public ItemsControl() |
|||
{ |
|||
this.GetObservableWithHistory(ItemsProperty).Subscribe(this.ItemsChanged); |
|||
} |
|||
|
|||
public IEnumerable Items |
|||
{ |
|||
get { return this.GetValue(ItemsProperty); } |
|||
set { this.SetValue(ItemsProperty, value); } |
|||
} |
|||
|
|||
public ItemsPanelTemplate ItemsPanel |
|||
{ |
|||
get { return this.GetValue(ItemsPanelProperty); } |
|||
set { this.SetValue(ItemsPanelProperty, value); } |
|||
} |
|||
|
|||
public Control GetControlForItem(object item) |
|||
{ |
|||
Control result; |
|||
this.controlsByItem.TryGetValue(item, out result); |
|||
return result; |
|||
} |
|||
|
|||
public object GetItemForControl(Control control) |
|||
{ |
|||
object result; |
|||
this.itemsByControl.TryGetValue(control, out result); |
|||
return result; |
|||
} |
|||
|
|||
public IEnumerable<Control> GetAllItemControls() |
|||
{ |
|||
return this.controlsByItem.Values; |
|||
} |
|||
|
|||
internal Control CreateItemControl(object item) |
|||
{ |
|||
Control control = this.CreateItemControlOverride(item); |
|||
this.itemsByControl.Add(control, item); |
|||
this.controlsByItem.Add(item, control); |
|||
return control; |
|||
} |
|||
|
|||
internal void RemoveItemControls(IEnumerable items) |
|||
{ |
|||
foreach (object i in items) |
|||
{ |
|||
Control control = this.GetControlForItem(i); |
|||
this.controlsByItem.Remove(i); |
|||
this.itemsByControl.Remove(control); |
|||
} |
|||
} |
|||
|
|||
internal void ClearItemControls() |
|||
{ |
|||
this.controlsByItem.Clear(); |
|||
this.itemsByControl.Clear(); |
|||
} |
|||
|
|||
protected virtual Control CreateItemControlOverride(object item) |
|||
{ |
|||
return (item as Control) ?? this.GetDataTemplate(item).Build(item); |
|||
} |
|||
|
|||
private void ItemsChanged(Tuple<IEnumerable, IEnumerable> value) |
|||
{ |
|||
INotifyPropertyChanged inpc = value.Item1 as INotifyPropertyChanged; |
|||
|
|||
if (inpc != null) |
|||
{ |
|||
inpc.PropertyChanged -= ItemsPropertyChanged; |
|||
} |
|||
|
|||
if (value.Item2 == null || !value.Item2.OfType<object>().Any()) |
|||
{ |
|||
this.Classes.Add(":empty"); |
|||
} |
|||
else |
|||
{ |
|||
this.Classes.Remove(":empty"); |
|||
} |
|||
|
|||
inpc = value.Item2 as INotifyPropertyChanged; |
|||
|
|||
if (inpc != null) |
|||
{ |
|||
inpc.PropertyChanged += ItemsPropertyChanged; |
|||
} |
|||
} |
|||
|
|||
private void ItemsPropertyChanged(object sender, PropertyChangedEventArgs e) |
|||
{ |
|||
if (e.PropertyName == "Count") |
|||
{ |
|||
if (((IList)sender).Count == 0) |
|||
{ |
|||
this.Classes.Add(":empty"); |
|||
} |
|||
else |
|||
{ |
|||
this.Classes.Remove(":empty"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class ItemsPanelTemplate |
|||
{ |
|||
public ItemsPanelTemplate(Func<Panel> build) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(build != null); |
|||
|
|||
this.Build = build; |
|||
} |
|||
|
|||
public Func<Panel> Build { get; private set; } |
|||
} |
|||
} |
|||
@ -1,190 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ItemsControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.Linq; |
|||
using Perspex.Layout; |
|||
|
|||
public class ItemsPresenter : Control, IVisual |
|||
{ |
|||
public static readonly PerspexProperty<IEnumerable> ItemsProperty = |
|||
ItemsControl.ItemsProperty.AddOwner<ItemsPresenter>(); |
|||
|
|||
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty = |
|||
ItemsControl.ItemsPanelProperty.AddOwner<ItemsPresenter>(); |
|||
|
|||
private Panel panel; |
|||
|
|||
public ItemsPresenter() |
|||
{ |
|||
this.GetObservableWithHistory(ItemsProperty).Subscribe(this.ItemsChanged); |
|||
} |
|||
|
|||
public IEnumerable Items |
|||
{ |
|||
get { return this.GetValue(ItemsProperty); } |
|||
set { this.SetValue(ItemsProperty, value); } |
|||
} |
|||
|
|||
public ItemsPanelTemplate ItemsPanel |
|||
{ |
|||
get { return this.GetValue(ItemsPanelProperty); } |
|||
set { this.SetValue(ItemsPanelProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.ExistingVisualChildren |
|||
{ |
|||
get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.VisualChildren |
|||
{ |
|||
get { return Enumerable.Repeat(this.GetPanel(), 1); } |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
Panel panel = this.GetPanel(); |
|||
panel.Measure(availableSize); |
|||
return panel.DesiredSize.Value; |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
this.GetPanel().Arrange(new Rect(finalSize)); |
|||
return finalSize; |
|||
} |
|||
|
|||
private Control CreateItemControl(object item) |
|||
{ |
|||
ItemsControl i = this.TemplatedParent as ItemsControl; |
|||
|
|||
if (i != null) |
|||
{ |
|||
return i.CreateItemControl(item); |
|||
} |
|||
else |
|||
{ |
|||
return this.GetDataTemplate(item).Build(item) as Control; |
|||
} |
|||
} |
|||
|
|||
private IEnumerable<Control> CreateItemControls(IEnumerable items) |
|||
{ |
|||
if (items != null) |
|||
{ |
|||
return items |
|||
.Cast<object>() |
|||
.Select(x => this.CreateItemControl(x)) |
|||
.OfType<Control>(); |
|||
} |
|||
else |
|||
{ |
|||
return Enumerable.Empty<Control>(); |
|||
} |
|||
} |
|||
|
|||
private void ClearItemControls() |
|||
{ |
|||
ItemsControl i = this.TemplatedParent as ItemsControl; |
|||
|
|||
if (i != null) |
|||
{ |
|||
i.ClearItemControls(); |
|||
} |
|||
} |
|||
|
|||
private void RemoveItemControls(IEnumerable items) |
|||
{ |
|||
ItemsControl i = this.TemplatedParent as ItemsControl; |
|||
|
|||
if (i != null) |
|||
{ |
|||
i.RemoveItemControls(items); |
|||
} |
|||
} |
|||
|
|||
private Panel GetPanel() |
|||
{ |
|||
if (this.panel == null && this.ItemsPanel != null) |
|||
{ |
|||
this.panel = this.ItemsPanel.Build(); |
|||
((IVisual)this.panel).VisualParent = this; |
|||
this.ItemsChanged(Tuple.Create(default(IEnumerable), this.Items)); |
|||
} |
|||
|
|||
return this.panel; |
|||
} |
|||
|
|||
private void ItemsChanged(Tuple<IEnumerable, IEnumerable> value) |
|||
{ |
|||
if (value.Item1 != null) |
|||
{ |
|||
INotifyCollectionChanged incc = value.Item1 as INotifyCollectionChanged; |
|||
|
|||
if (incc != null) |
|||
{ |
|||
incc.CollectionChanged -= this.ItemsCollectionChanged; |
|||
} |
|||
} |
|||
|
|||
this.ClearItemControls(); |
|||
|
|||
if (this.panel != null) |
|||
{ |
|||
var controls = this.CreateItemControls(value.Item2).ToList(); |
|||
|
|||
foreach (var control in controls) |
|||
{ |
|||
control.TemplatedParent = null; |
|||
} |
|||
|
|||
this.panel.Children = new Controls(controls); |
|||
|
|||
INotifyCollectionChanged incc = value.Item2 as INotifyCollectionChanged; |
|||
|
|||
if (incc != null) |
|||
{ |
|||
incc.CollectionChanged += this.ItemsCollectionChanged; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
|||
{ |
|||
if (this.panel != null) |
|||
{ |
|||
// TODO: Handle Move and Replace.
|
|||
switch (e.Action) |
|||
{ |
|||
case NotifyCollectionChangedAction.Add: |
|||
var controls = this.CreateItemControls(e.NewItems).ToList(); |
|||
|
|||
foreach (var control in controls) |
|||
{ |
|||
control.TemplatedParent = null; |
|||
} |
|||
|
|||
this.panel.Children.AddRange(controls); |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Remove: |
|||
this.RemoveItemControls(e.OldItems); |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Reset: |
|||
this.ItemsChanged(Tuple.Create(this.Items, this.Items)); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,99 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="LogicalChildren.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Collections.Specialized; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// Manages parenting for a collection of logical child controls.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The type of the controls.</typeparam>
|
|||
/// <remarks>
|
|||
/// Unfortunately, because of ObservableCollection's handling of clear (the cleared items
|
|||
/// aren't passed to the CollectionChanged event) we have to hold two lists of child controls:
|
|||
/// the ones in Panel.Children and the ones here - held in case the ObservableCollection
|
|||
/// gets cleared. It's either that or write a proper PerspexList which is too much work
|
|||
/// for now.
|
|||
/// </remarks>
|
|||
internal class LogicalChildren<T> where T : class, ILogical, IVisual |
|||
{ |
|||
private T parent; |
|||
|
|||
private PerspexList<T> childrenCollection; |
|||
|
|||
private List<T> inner = new List<T>(); |
|||
|
|||
public LogicalChildren(T parent, PerspexList<T> childrenCollection) |
|||
{ |
|||
this.parent = parent; |
|||
this.childrenCollection = childrenCollection; |
|||
this.Add(childrenCollection); |
|||
childrenCollection.CollectionChanged += this.CollectionChanged; |
|||
} |
|||
|
|||
public void Change(PerspexList<T> childrenCollection) |
|||
{ |
|||
this.childrenCollection.CollectionChanged -= this.CollectionChanged; |
|||
this.Remove(this.inner.ToList()); |
|||
this.childrenCollection = childrenCollection; |
|||
this.Add(childrenCollection); |
|||
childrenCollection.CollectionChanged += this.CollectionChanged; |
|||
} |
|||
|
|||
private void Add(IEnumerable<T> items) |
|||
{ |
|||
foreach (T item in items) |
|||
{ |
|||
this.inner.Add(item); |
|||
item.LogicalParent = this.parent; |
|||
item.VisualParent = this.parent; |
|||
} |
|||
} |
|||
|
|||
private void Remove(IEnumerable<T> items) |
|||
{ |
|||
foreach (T item in items) |
|||
{ |
|||
this.inner.Remove(item); |
|||
item.LogicalParent = null; |
|||
item.VisualParent = null; |
|||
} |
|||
} |
|||
|
|||
private void Reset(IEnumerable<T> newState) |
|||
{ |
|||
this.Add(newState.Except(this.inner)); |
|||
this.Remove(this.inner.Except(newState)); |
|||
} |
|||
|
|||
private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
|||
{ |
|||
switch (e.Action) |
|||
{ |
|||
case NotifyCollectionChangedAction.Add: |
|||
this.Add(e.NewItems.Cast<T>()); |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Remove: |
|||
this.Remove(e.OldItems.Cast<T>()); |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Replace: |
|||
this.Remove(e.OldItems.Cast<T>()); |
|||
this.Add(e.NewItems.Cast<T>()); |
|||
break; |
|||
|
|||
case NotifyCollectionChangedAction.Reset: |
|||
this.Reset((IEnumerable<T>)sender); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,64 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Panel.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Collections.Specialized; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
/// <summary>
|
|||
/// Base class for controls that can contain multiple children.
|
|||
/// </summary>
|
|||
public class Panel : Control, ILogical, IVisual |
|||
{ |
|||
private Controls children; |
|||
|
|||
private LogicalChildren<Control> logicalChildren; |
|||
|
|||
public Controls Children |
|||
{ |
|||
get |
|||
{ |
|||
if (this.children == null) |
|||
{ |
|||
this.children = new Controls(); |
|||
this.logicalChildren = new LogicalChildren<Control>(this, this.children); |
|||
} |
|||
|
|||
return this.children; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.children = value; |
|||
|
|||
if (this.logicalChildren != null) |
|||
{ |
|||
this.logicalChildren.Change(this.children); |
|||
} |
|||
else |
|||
{ |
|||
this.logicalChildren = new LogicalChildren<Control>(this, this.children); |
|||
} |
|||
} |
|||
} |
|||
|
|||
IEnumerable<ILogical> ILogical.LogicalChildren |
|||
{ |
|||
get { return this.children ?? Enumerable.Empty<ILogical>(); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.VisualChildren |
|||
{ |
|||
get { return this.children ?? Enumerable.Empty<IVisual>(); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,53 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RowDefinition.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class RowDefinition : DefinitionBase |
|||
{ |
|||
public static readonly PerspexProperty<double> MaxHeightProperty = |
|||
PerspexProperty.Register<RowDefinition, double>("MaxHeight", double.PositiveInfinity); |
|||
|
|||
public static readonly PerspexProperty<double> MinHeightProperty = |
|||
PerspexProperty.Register<RowDefinition, double>("MinHeight"); |
|||
|
|||
public static readonly PerspexProperty<GridLength> HeightProperty = |
|||
PerspexProperty.Register<RowDefinition, GridLength>("Height", new GridLength(1, GridUnitType.Star)); |
|||
|
|||
public RowDefinition() |
|||
{ |
|||
} |
|||
|
|||
public RowDefinition(GridLength height) |
|||
{ |
|||
this.Height = height; |
|||
} |
|||
|
|||
public double ActualHeight |
|||
{ |
|||
get; |
|||
internal set; |
|||
} |
|||
|
|||
public double MaxHeight |
|||
{ |
|||
get { return this.GetValue(MaxHeightProperty); } |
|||
set { this.SetValue(MaxHeightProperty, value); } |
|||
} |
|||
|
|||
public double MinHeight |
|||
{ |
|||
get { return this.GetValue(MinHeightProperty); } |
|||
set { this.SetValue(MinHeightProperty, value); } |
|||
} |
|||
|
|||
public GridLength Height |
|||
{ |
|||
get { return this.GetValue(HeightProperty); } |
|||
set { this.SetValue(HeightProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RowDefinitions.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class RowDefinitions : PerspexList<RowDefinition> |
|||
{ |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="SelectingItemsControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class SelectingItemsControl : ItemsControl |
|||
{ |
|||
public static readonly PerspexProperty<object> SelectedItemProperty = |
|||
PerspexProperty.Register<SelectingItemsControl, object>("SelectedItem"); |
|||
|
|||
public object SelectedItem |
|||
{ |
|||
get { return this.GetValue(SelectedItemProperty); } |
|||
set { this.SetValue(SelectedItemProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,155 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="StackPanel.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
public enum Orientation |
|||
{ |
|||
Vertical, |
|||
Horizontal, |
|||
} |
|||
|
|||
public class StackPanel : Panel |
|||
{ |
|||
public static readonly PerspexProperty<double> GapProperty = |
|||
PerspexProperty.Register<StackPanel, double>("Gap"); |
|||
|
|||
public static readonly PerspexProperty<Orientation> OrientationProperty = |
|||
PerspexProperty.Register<StackPanel, Orientation>("Orientation"); |
|||
|
|||
public double Gap |
|||
{ |
|||
get { return this.GetValue(GapProperty); } |
|||
set { this.SetValue(GapProperty, value); } |
|||
} |
|||
|
|||
public Orientation Orientation |
|||
{ |
|||
get { return this.GetValue(OrientationProperty); } |
|||
set { this.SetValue(OrientationProperty, value); } |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
double childAvailableWidth = double.PositiveInfinity; |
|||
double childAvailableHeight = double.PositiveInfinity; |
|||
|
|||
if (this.Orientation == Orientation.Vertical) |
|||
{ |
|||
childAvailableWidth = availableSize.Width; |
|||
|
|||
if (!double.IsNaN(this.Width)) |
|||
{ |
|||
childAvailableWidth = this.Width; |
|||
} |
|||
|
|||
childAvailableWidth = Math.Min(childAvailableWidth, this.MaxWidth); |
|||
childAvailableWidth = Math.Max(childAvailableWidth, this.MinWidth); |
|||
} |
|||
else |
|||
{ |
|||
childAvailableHeight = availableSize.Height; |
|||
|
|||
if (!double.IsNaN(this.Height)) |
|||
{ |
|||
childAvailableHeight = this.Height; |
|||
} |
|||
|
|||
childAvailableHeight = Math.Min(childAvailableHeight, this.MaxHeight); |
|||
childAvailableHeight = Math.Max(childAvailableHeight, this.MinHeight); |
|||
} |
|||
|
|||
double measuredWidth = 0; |
|||
double measuredHeight = 0; |
|||
double gap = this.Gap; |
|||
|
|||
foreach (Control child in this.Children) |
|||
{ |
|||
child.Measure(new Size(childAvailableWidth, childAvailableHeight)); |
|||
Size size = child.DesiredSize.Value; |
|||
|
|||
if (Orientation == Orientation.Vertical) |
|||
{ |
|||
measuredHeight += size.Height + gap; |
|||
measuredWidth = Math.Max(measuredWidth, size.Width); |
|||
} |
|||
else |
|||
{ |
|||
measuredWidth += size.Width + gap; |
|||
measuredHeight = Math.Max(measuredHeight, size.Height); |
|||
} |
|||
} |
|||
|
|||
return new Size(measuredWidth, measuredHeight); |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
double arrangedWidth = finalSize.Width; |
|||
double arrangedHeight = finalSize.Height; |
|||
double gap = this.Gap; |
|||
|
|||
if (Orientation == Orientation.Vertical) |
|||
{ |
|||
arrangedHeight = 0; |
|||
} |
|||
else |
|||
{ |
|||
arrangedWidth = 0; |
|||
} |
|||
|
|||
foreach (Control child in this.Children.Where(x => x.DesiredSize.HasValue)) |
|||
{ |
|||
double childWidth = child.DesiredSize.Value.Width; |
|||
double childHeight = child.DesiredSize.Value.Height; |
|||
|
|||
if (Orientation == Orientation.Vertical) |
|||
{ |
|||
childWidth = finalSize.Width; |
|||
|
|||
Rect childFinal = new Rect(0, arrangedHeight, childWidth, childHeight); |
|||
|
|||
if (childFinal.IsEmpty) |
|||
{ |
|||
child.Arrange(new Rect()); |
|||
} |
|||
else |
|||
{ |
|||
child.Arrange(childFinal); |
|||
} |
|||
|
|||
arrangedWidth = Math.Max(arrangedWidth, childWidth); |
|||
arrangedHeight += childHeight + gap; |
|||
} |
|||
else |
|||
{ |
|||
childHeight = finalSize.Height; |
|||
Rect childFinal = new Rect(arrangedWidth, 0, childWidth, childHeight); |
|||
child.Arrange(childFinal); |
|||
arrangedWidth += childWidth + gap; |
|||
arrangedHeight = Math.Max(arrangedHeight, childHeight); |
|||
} |
|||
} |
|||
|
|||
if (Orientation == Orientation.Vertical) |
|||
{ |
|||
arrangedHeight = Math.Max(arrangedHeight - gap, finalSize.Height); |
|||
} |
|||
else |
|||
{ |
|||
arrangedWidth = Math.Max(arrangedWidth - gap, finalSize.Width); |
|||
} |
|||
|
|||
return new Size(arrangedWidth, arrangedHeight); |
|||
} |
|||
} |
|||
} |
|||
@ -1,67 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TabControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
|
|||
public class TabControl : SelectingItemsControl, ILogical |
|||
{ |
|||
public static readonly PerspexProperty<object> SelectedContentProperty = |
|||
PerspexProperty.Register<TabControl, object>("SelectedContent"); |
|||
|
|||
private TabStrip tabStrip; |
|||
|
|||
public TabControl() |
|||
{ |
|||
this.GetObservable(SelectedItemProperty).Skip(1).Subscribe(this.SelectedItemChanged); |
|||
} |
|||
|
|||
IEnumerable<ILogical> ILogical.LogicalChildren |
|||
{ |
|||
get { return this.Items.OfType<TabItem>(); } |
|||
} |
|||
|
|||
protected override void OnTemplateApplied() |
|||
{ |
|||
this.tabStrip = this.GetTemplateControls() |
|||
.OfType<TabStrip>() |
|||
.FirstOrDefault(); |
|||
|
|||
if (this.tabStrip != null) |
|||
{ |
|||
if (this.IsSet(SelectedItemProperty)) |
|||
{ |
|||
this.SelectedItem = SelectedItem; |
|||
} |
|||
|
|||
this.tabStrip.GetObservable(TabStrip.SelectedItemProperty).Subscribe(x => |
|||
{ |
|||
this.SelectedItem = x; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private void SelectedItemChanged(object item) |
|||
{ |
|||
this.SelectedItem = item; |
|||
|
|||
ContentControl content = item as ContentControl; |
|||
|
|||
if (content != null) |
|||
{ |
|||
this.SetValue(SelectedContentProperty, content.Content); |
|||
} |
|||
else |
|||
{ |
|||
this.SetValue(SelectedContentProperty, item); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,26 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TabItem.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class TabItem : HeaderedContentControl |
|||
{ |
|||
public static readonly PerspexProperty<bool> IsSelectedProperty = |
|||
PerspexProperty.Register<TabItem, bool>("IsSelected"); |
|||
|
|||
public TabItem() |
|||
{ |
|||
this.AddPseudoClass(IsSelectedProperty, ":selected"); |
|||
AffectsRender(IsSelectedProperty); |
|||
} |
|||
|
|||
public bool IsSelected |
|||
{ |
|||
get { return this.GetValue(IsSelectedProperty); } |
|||
set { this.SetValue(IsSelectedProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,86 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TabStrip.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Linq; |
|||
using Perspex.Input; |
|||
|
|||
public class TabStrip : SelectingItemsControl |
|||
{ |
|||
private static readonly ItemsPanelTemplate PanelTemplate = new ItemsPanelTemplate( |
|||
() => new StackPanel()); |
|||
|
|||
static TabStrip() |
|||
{ |
|||
ItemsPanelProperty.OverrideDefaultValue(typeof(TabStrip), PanelTemplate); |
|||
} |
|||
|
|||
public TabStrip() |
|||
{ |
|||
this.PointerPressed += this.OnPointerPressed; |
|||
this.GetObservable(ItemsProperty).Subscribe(this.ItemsChanged); |
|||
this.GetObservable(SelectedItemProperty).Subscribe(this.SelectedItemChanged); |
|||
} |
|||
|
|||
protected override Control CreateItemControlOverride(object item) |
|||
{ |
|||
TabItem result = item as TabItem; |
|||
|
|||
if (result == null) |
|||
{ |
|||
result = new TabItem |
|||
{ |
|||
Content = this.GetDataTemplate(item).Build(item), |
|||
}; |
|||
} |
|||
|
|||
result.IsSelected = this.SelectedItem == item; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private void ItemsChanged(IEnumerable items) |
|||
{ |
|||
if (items != null) |
|||
{ |
|||
this.SelectedItem = |
|||
items.OfType<TabItem>().FirstOrDefault(x => x.IsSelected) ?? |
|||
items.OfType<object>().FirstOrDefault(); |
|||
} |
|||
else |
|||
{ |
|||
this.SelectedItem = null; |
|||
} |
|||
} |
|||
|
|||
private void OnPointerPressed(object sender, PointerEventArgs e) |
|||
{ |
|||
IVisual source = (IVisual)e.Source; |
|||
ContentPresenter presenter = source.GetVisualAncestor<ContentPresenter>(); |
|||
|
|||
if (presenter != null) |
|||
{ |
|||
TabItem item = presenter.TemplatedParent as TabItem; |
|||
|
|||
if (item != null) |
|||
{ |
|||
this.SelectedItem = item; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void SelectedItemChanged(object selectedItem) |
|||
{ |
|||
foreach (TabItem item in this.GetAllItemControls()) |
|||
{ |
|||
item.IsSelected = item == selectedItem; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,94 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TemplatedControl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Perspex.Media; |
|||
using Splat; |
|||
|
|||
public class TemplatedControl : Control, IVisual, ITemplatedControl |
|||
{ |
|||
public static readonly PerspexProperty<ControlTemplate> TemplateProperty = |
|||
PerspexProperty.Register<TemplatedControl, ControlTemplate>("Template"); |
|||
|
|||
public ControlTemplate Template |
|||
{ |
|||
get { return this.GetValue(TemplateProperty); } |
|||
set { this.SetValue(TemplateProperty, value); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.ExistingVisualChildren |
|||
{ |
|||
get { return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0); } |
|||
} |
|||
|
|||
IEnumerable<IVisual> ITemplatedControl.VisualChildren |
|||
{ |
|||
get |
|||
{ |
|||
var template = this.Template; |
|||
|
|||
if (this.visualChild == null && template != null) |
|||
{ |
|||
this.Log().Debug(string.Format( |
|||
"Creating template for {0} (#{1:x8})", |
|||
this.GetType().Name, |
|||
this.GetHashCode())); |
|||
|
|||
this.visualChild = template.Build(this); |
|||
this.visualChild.VisualParent = this; |
|||
this.OnTemplateApplied(); |
|||
} |
|||
|
|||
return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0); |
|||
} |
|||
} |
|||
|
|||
IEnumerable<IVisual> IVisual.VisualChildren |
|||
{ |
|||
get { return ((ITemplatedControl)this).VisualChildren; } |
|||
} |
|||
|
|||
public sealed override void Render(IDrawingContext context) |
|||
{ |
|||
} |
|||
|
|||
protected override Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; |
|||
|
|||
if (child != null) |
|||
{ |
|||
child.Arrange(new Rect(finalSize)); |
|||
return child.ActualSize; |
|||
} |
|||
else |
|||
{ |
|||
return new Size(); |
|||
} |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; |
|||
|
|||
if (child != null) |
|||
{ |
|||
child.Measure(availableSize); |
|||
return child.DesiredSize.Value; |
|||
} |
|||
|
|||
return new Size(); |
|||
} |
|||
|
|||
protected virtual void OnTemplateApplied() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TextBlock.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class TextBlock : Control |
|||
{ |
|||
public static readonly PerspexProperty<string> TextProperty = |
|||
PerspexProperty.Register<TextBlock, string>("Text"); |
|||
|
|||
static TextBlock() |
|||
{ |
|||
AffectsMeasure(TextProperty); |
|||
} |
|||
|
|||
public string Text |
|||
{ |
|||
get { return this.GetValue(TextProperty); } |
|||
set { this.SetValue(TextProperty, value); } |
|||
} |
|||
|
|||
private FormattedText FormattedText |
|||
{ |
|||
get |
|||
{ |
|||
return new FormattedText |
|||
{ |
|||
FontFamilyName = "Segoe UI", |
|||
FontSize = this.FontSize, |
|||
Text = this.Text, |
|||
}; |
|||
} |
|||
} |
|||
|
|||
public override void Render(IDrawingContext context) |
|||
{ |
|||
Brush background = this.Background; |
|||
|
|||
if (background != null) |
|||
{ |
|||
context.FillRectange(background, new Rect(this.ActualSize)); |
|||
} |
|||
|
|||
context.DrawText(this.Foreground, new Rect(this.ActualSize), this.FormattedText); |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
if (!string.IsNullOrEmpty(this.Text)) |
|||
{ |
|||
return this.FormattedText.Measure(availableSize); |
|||
} |
|||
|
|||
return new Size(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,133 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TextBox.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using Perspex.Input; |
|||
using Perspex.Platform; |
|||
using Perspex.Styling; |
|||
using Splat; |
|||
|
|||
public class TextBox : TemplatedControl |
|||
{ |
|||
public static readonly PerspexProperty<string> TextProperty = |
|||
TextBlock.TextProperty.AddOwner<TextBox>(); |
|||
|
|||
private int caretIndex; |
|||
|
|||
private TextBoxView textBoxView; |
|||
|
|||
static TextBox() |
|||
{ |
|||
FocusableProperty.OverrideDefaultValue(typeof(TextBox), true); |
|||
} |
|||
|
|||
public TextBox() |
|||
{ |
|||
this.GotFocus += (s, e) => this.textBoxView.GotFocus(); |
|||
this.LostFocus += (s, e) => this.textBoxView.LostFocus(); |
|||
this.KeyDown += this.OnKeyDown; |
|||
this.PointerPressed += this.OnPointerPressed; |
|||
} |
|||
|
|||
public int CaretIndex |
|||
{ |
|||
get |
|||
{ |
|||
return this.caretIndex; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
value = Math.Min(Math.Max(value, 0), this.Text.Length); |
|||
|
|||
if (this.caretIndex != value) |
|||
{ |
|||
this.caretIndex = value; |
|||
this.textBoxView.CaretMoved(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public string Text |
|||
{ |
|||
get { return this.GetValue(TextProperty); } |
|||
set { this.SetValue(TextProperty, value); } |
|||
} |
|||
|
|||
protected override void OnTemplateApplied() |
|||
{ |
|||
Decorator textContainer = this.GetVisualDescendents() |
|||
.OfType<Decorator>() |
|||
.FirstOrDefault(x => x.Id == "textContainer"); |
|||
|
|||
if (textContainer == null) |
|||
{ |
|||
throw new Exception( |
|||
"TextBox template doesn't contain a textContainer " + |
|||
"or textContainer is not a Decorator."); |
|||
} |
|||
|
|||
textContainer.Content = this.textBoxView = new TextBoxView(this); |
|||
this.GetObservable(TextProperty).Subscribe(_ => this.textBoxView.InvalidateText()); |
|||
} |
|||
|
|||
private void OnKeyDown(object sender, KeyEventArgs e) |
|||
{ |
|||
string text = this.Text; |
|||
|
|||
switch (e.Key) |
|||
{ |
|||
case Key.Left: |
|||
--this.CaretIndex; |
|||
break; |
|||
|
|||
case Key.Right: |
|||
++this.CaretIndex; |
|||
break; |
|||
|
|||
case Key.Back: |
|||
if (this.caretIndex > 0) |
|||
{ |
|||
this.Text = text.Substring(0, this.caretIndex - 1) + text.Substring(this.caretIndex); |
|||
--this.CaretIndex; |
|||
} |
|||
|
|||
break; |
|||
|
|||
case Key.Delete: |
|||
if (this.caretIndex < text.Length) |
|||
{ |
|||
this.Text = text.Substring(0, this.caretIndex) + text.Substring(this.caretIndex + 1); |
|||
} |
|||
|
|||
break; |
|||
|
|||
default: |
|||
if (!string.IsNullOrEmpty(e.Text)) |
|||
{ |
|||
this.Text = text.Substring(0, this.caretIndex) + e.Text + text.Substring(this.caretIndex); |
|||
++this.CaretIndex; |
|||
} |
|||
|
|||
break; |
|||
} |
|||
|
|||
e.Handled = true; |
|||
} |
|||
|
|||
private void OnPointerPressed(object sender, PointerEventArgs e) |
|||
{ |
|||
IPlatformRenderInterface platform = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
this.CaretIndex = platform.TextService.GetCaretIndex( |
|||
this.textBoxView.FormattedText, |
|||
e.GetPosition(this.textBoxView), |
|||
this.ActualSize); |
|||
} |
|||
} |
|||
} |
|||
@ -1,126 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TextBoxView.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
using Perspex.Platform; |
|||
using Perspex.Threading; |
|||
using Splat; |
|||
|
|||
internal class TextBoxView : Control |
|||
{ |
|||
private TextBox parent; |
|||
|
|||
private FormattedText formattedText; |
|||
|
|||
private DispatcherTimer caretTimer; |
|||
|
|||
private bool caretBlink; |
|||
|
|||
public TextBoxView(TextBox parent) |
|||
{ |
|||
this.caretTimer = new DispatcherTimer(); |
|||
this.caretTimer.Interval = TimeSpan.FromMilliseconds(500); |
|||
this.caretTimer.Tick += this.CaretTimerTick; |
|||
this.parent = parent; |
|||
} |
|||
|
|||
public FormattedText FormattedText |
|||
{ |
|||
get |
|||
{ |
|||
if (this.formattedText == null) |
|||
{ |
|||
this.formattedText = this.CreateFormattedText(); |
|||
} |
|||
|
|||
return this.formattedText; |
|||
} |
|||
} |
|||
|
|||
public new void GotFocus() |
|||
{ |
|||
this.caretBlink = true; |
|||
this.caretTimer.Start(); |
|||
} |
|||
|
|||
public new void LostFocus() |
|||
{ |
|||
this.caretTimer.Stop(); |
|||
this.InvalidateVisual(); |
|||
} |
|||
|
|||
public void InvalidateText() |
|||
{ |
|||
this.formattedText = null; |
|||
this.InvalidateMeasure(); |
|||
} |
|||
|
|||
internal void CaretMoved() |
|||
{ |
|||
this.caretBlink = true; |
|||
this.caretTimer.Stop(); |
|||
this.caretTimer.Start(); |
|||
this.InvalidateVisual(); |
|||
} |
|||
|
|||
public override void Render(IDrawingContext context) |
|||
{ |
|||
Rect rect = new Rect(this.ActualSize); |
|||
|
|||
context.DrawText(Brushes.Black, rect, this.FormattedText); |
|||
|
|||
if (this.parent.IsFocused) |
|||
{ |
|||
IPlatformRenderInterface platform = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
Point caretPos = platform.TextService.GetCaretPosition( |
|||
this.formattedText, |
|||
this.parent.CaretIndex, |
|||
this.ActualSize); |
|||
double[] lineHeights = platform.TextService.GetLineHeights(this.formattedText, this.ActualSize); |
|||
Brush caretBrush = Brushes.Black; |
|||
|
|||
if (this.caretBlink) |
|||
{ |
|||
context.DrawLine( |
|||
new Pen(caretBrush, 1), |
|||
caretPos, |
|||
new Point(caretPos.X, caretPos.Y + lineHeights[0])); |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size constraint) |
|||
{ |
|||
if (!string.IsNullOrEmpty(this.parent.Text)) |
|||
{ |
|||
return this.FormattedText.Measure(constraint); |
|||
} |
|||
|
|||
return new Size(); |
|||
} |
|||
|
|||
private FormattedText CreateFormattedText() |
|||
{ |
|||
return new FormattedText |
|||
{ |
|||
FontFamilyName = "Segoe UI", |
|||
FontSize = this.FontSize, |
|||
Text = this.parent.Text, |
|||
}; |
|||
} |
|||
|
|||
private void CaretTimerTick(object sender, EventArgs e) |
|||
{ |
|||
this.caretBlink = !this.caretBlink; |
|||
this.InvalidateVisual(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ToggleButton.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
|
|||
public class ToggleButton : Button |
|||
{ |
|||
public static readonly PerspexProperty<bool> IsCheckedProperty = |
|||
PerspexProperty.Register<ToggleButton, bool>("IsChecked"); |
|||
|
|||
public ToggleButton() |
|||
{ |
|||
this.Click += (s, e) => this.IsChecked = !this.IsChecked; |
|||
this.AddPseudoClass(IsCheckedProperty, ":checked"); |
|||
} |
|||
|
|||
public bool IsChecked |
|||
{ |
|||
get { return this.GetValue(IsCheckedProperty); } |
|||
set { this.SetValue(IsCheckedProperty, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,107 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TreeDataTemplate.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
|
|||
public class TreeDataTemplate : DataTemplate |
|||
{ |
|||
public TreeDataTemplate( |
|||
Func<object, Control> build, |
|||
Func<object, IEnumerable> itemsSelector) |
|||
: this(o => true, build, itemsSelector) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Type type, |
|||
Func<object, Control> build, |
|||
Func<object, IEnumerable> itemsSelector) |
|||
: this(o => IsInstance(o, type), build, itemsSelector) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Type type, |
|||
Func<object, Control> build, |
|||
Func<object, IEnumerable> itemsSelector, |
|||
Func<object, bool> isExpanded) |
|||
: this(o => IsInstance(o, type), build, itemsSelector, isExpanded) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Func<object, bool> match, |
|||
Func<object, Control> build, |
|||
Func<object, IEnumerable> itemsSelector) |
|||
: this(match, build, itemsSelector, _ => false) |
|||
{ |
|||
this.ItemsSelector = itemsSelector; |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Func<object, bool> match, |
|||
Func<object, Control> build, |
|||
Func<object, IEnumerable> itemsSelector, |
|||
Func<object, bool> isExpanded) |
|||
: base(match, build) |
|||
{ |
|||
this.ItemsSelector = itemsSelector; |
|||
this.IsExpanded = isExpanded; |
|||
} |
|||
|
|||
public Func<object, IEnumerable> ItemsSelector { get; private set; } |
|||
|
|||
public Func<object, bool> IsExpanded { get; private set; } |
|||
} |
|||
|
|||
public class TreeDataTemplate<T> : TreeDataTemplate |
|||
{ |
|||
public TreeDataTemplate( |
|||
Func<T, Control> build, |
|||
Func<T, IEnumerable> itemsSelector) |
|||
: base(typeof(T), Cast(build), Cast(itemsSelector)) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Func<T, Control> build, |
|||
Func<T, IEnumerable> itemsSelector, |
|||
Func<T, bool> isExpanded) |
|||
: base(typeof(T), Cast(build), Cast(itemsSelector), Cast(isExpanded)) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Func<T, bool> match, |
|||
Func<T, Control> build, |
|||
Func<T, IEnumerable> itemsSelector) |
|||
: base(CastMatch(match), Cast(build), Cast(itemsSelector)) |
|||
{ |
|||
} |
|||
|
|||
public TreeDataTemplate( |
|||
Func<T, bool> match, |
|||
Func<T, Control> build, |
|||
Func<T, IEnumerable> itemsSelector, |
|||
Func<T, bool> isExpanded) |
|||
: base(CastMatch(match), Cast(build), Cast(itemsSelector), Cast(isExpanded)) |
|||
{ |
|||
} |
|||
|
|||
private static Func<object, bool> CastMatch(Func<T, bool> f) |
|||
{ |
|||
return o => (o is T) ? f((T)o) : false; |
|||
} |
|||
|
|||
private static Func<object, TResult> Cast<TResult>(Func<T, TResult> f) |
|||
{ |
|||
return o => f((T)o); |
|||
} |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TreeView.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Input; |
|||
|
|||
public class TreeView : SelectingItemsControl |
|||
{ |
|||
public TreeView() |
|||
{ |
|||
this.PointerPressed += this.OnPointerPressed; |
|||
} |
|||
|
|||
protected override Control CreateItemControlOverride(object item) |
|||
{ |
|||
TreeViewItem result = item as TreeViewItem; |
|||
|
|||
if (result == null) |
|||
{ |
|||
TreeDataTemplate template = this.GetTreeDataTemplate(item); |
|||
|
|||
result = new TreeViewItem |
|||
{ |
|||
Header = template.Build(item), |
|||
Items = template.ItemsSelector(item), |
|||
IsExpanded = template.IsExpanded(item), |
|||
}; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private TreeDataTemplate GetTreeDataTemplate(object item) |
|||
{ |
|||
DataTemplate template = this.GetDataTemplate(item); |
|||
TreeDataTemplate treeTemplate = template as TreeDataTemplate; |
|||
|
|||
if (treeTemplate == null) |
|||
{ |
|||
treeTemplate = new TreeDataTemplate(template.Build, x => null); |
|||
} |
|||
|
|||
return treeTemplate; |
|||
} |
|||
|
|||
private void OnPointerPressed(object sender, PointerEventArgs e) |
|||
{ |
|||
IVisual source = (IVisual)e.Source; |
|||
ContentPresenter contentPresenter = source.GetVisualAncestor<ContentPresenter>(); |
|||
|
|||
if (contentPresenter != null) |
|||
{ |
|||
TreeViewItem item = contentPresenter.TemplatedParent as TreeViewItem; |
|||
|
|||
if (item != null) |
|||
{ |
|||
foreach (var i in this.GetVisualDescendents().OfType<TreeViewItem>()) |
|||
{ |
|||
i.IsSelected = i == item; |
|||
} |
|||
|
|||
this.SelectedItem = this.GetItemForControl(item); |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="TreeViewItem.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
public class TreeViewItem : HeaderedItemsControl |
|||
{ |
|||
public static readonly PerspexProperty<bool> IsExpandedProperty = |
|||
PerspexProperty.Register<TreeViewItem, bool>("IsExpanded"); |
|||
|
|||
public static readonly PerspexProperty<bool> IsSelectedProperty = |
|||
PerspexProperty.Register<TreeViewItem, bool>("IsSelected"); |
|||
|
|||
TreeView parent; |
|||
|
|||
public TreeViewItem() |
|||
{ |
|||
this.AddPseudoClass(IsSelectedProperty, ":selected"); |
|||
AffectsRender(IsSelectedProperty); |
|||
} |
|||
|
|||
public bool IsExpanded |
|||
{ |
|||
get { return this.GetValue(IsExpandedProperty); } |
|||
set { this.SetValue(IsExpandedProperty, value); } |
|||
} |
|||
|
|||
public bool IsSelected |
|||
{ |
|||
get { return this.GetValue(IsSelectedProperty); } |
|||
set { this.SetValue(IsSelectedProperty, value); } |
|||
} |
|||
|
|||
protected override Control CreateItemControlOverride(object item) |
|||
{ |
|||
if (this.parent != null) |
|||
{ |
|||
return this.parent.CreateItemControl(item); |
|||
} |
|||
else |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
protected override void OnVisualParentChanged(IVisual oldParent) |
|||
{ |
|||
this.parent = this.GetVisualAncestor<TreeView>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,71 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Debug.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Diagnostics |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Controls; |
|||
|
|||
public static class Debug |
|||
{ |
|||
public static string PrintVisualTree(IVisual visual) |
|||
{ |
|||
StringBuilder result = new StringBuilder(); |
|||
PrintVisualTree(visual, result, 0); |
|||
return result.ToString(); |
|||
} |
|||
|
|||
private static void PrintVisualTree(IVisual visual, StringBuilder builder, int indent) |
|||
{ |
|||
Control control = visual as Control; |
|||
|
|||
builder.Append(Indent(indent - 1)); |
|||
|
|||
if (indent > 0) |
|||
{ |
|||
builder.Append(" +- "); |
|||
} |
|||
|
|||
builder.Append(visual.GetType().Name); |
|||
|
|||
if (control != null) |
|||
{ |
|||
builder.Append(" "); |
|||
builder.AppendLine(control.Classes.ToString()); |
|||
|
|||
foreach (var value in control.GetSetValues()) |
|||
{ |
|||
builder.Append(Indent(indent)); |
|||
builder.Append(" | "); |
|||
builder.Append(value.Item1.Name); |
|||
builder.Append(" = "); |
|||
builder.Append(value.Item2 ?? "(null)"); |
|||
builder.Append(" ["); |
|||
builder.Append(value.Item3); |
|||
builder.AppendLine("]"); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
builder.AppendLine(); |
|||
} |
|||
|
|||
foreach (var child in visual.VisualChildren) |
|||
{ |
|||
PrintVisualTree(child, builder, indent + 1); |
|||
} |
|||
} |
|||
|
|||
private static string Indent(int indent) |
|||
{ |
|||
return string.Join("", Enumerable.Repeat(" ", Math.Max(indent, 0))); |
|||
} |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="DevTools.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Diagnostics |
|||
{ |
|||
using Perspex.Controls; |
|||
|
|||
public class DevTools : Control |
|||
{ |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ICloseable.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
|
|||
public interface ICloseable |
|||
{ |
|||
event EventHandler Closed; |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IHeadered.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
public interface IHeadered |
|||
{ |
|||
object Header { get; set; } |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ILogical.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
public interface ILogical |
|||
{ |
|||
ILogical LogicalParent { get; set; } |
|||
|
|||
IEnumerable<ILogical> LogicalChildren { get; } |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IObservableDescription.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
public interface IObservableDescription |
|||
{ |
|||
string Description { get; } |
|||
} |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IVisual.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using Perspex.Media; |
|||
|
|||
/// <summary>
|
|||
/// Represents a node in the visual scene graph.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The <see cref="IVisual"/> interface defines the interface required for a renderer to
|
|||
/// render a scene graph. You should not usually need to reference this interface unless
|
|||
/// you are writing a renderer; instead use the extension methods defined in
|
|||
/// <see cref="VisualExtensions"/> to traverse the scene graph. This interface is
|
|||
/// implemented by <see cref="Visual"/>. It should not be necessary to implement it
|
|||
/// anywhere else.
|
|||
/// </remarks>
|
|||
public interface IVisual |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bounds of the scene graph node.
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
Rect Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this scene graph node is visible.
|
|||
/// </summary>
|
|||
bool IsVisible { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the opacity of the scene graph node.
|
|||
/// </summary>
|
|||
double Opacity { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the render transform of the scene graph node.
|
|||
/// </summary>
|
|||
Transform RenderTransform { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the transform origin of the scene graph node.
|
|||
/// </summary>
|
|||
Origin TransformOrigin { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the scene graph node's child nodes.
|
|||
/// </summary>
|
|||
PerspexList<IVisual> VisualChildren { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the scene graph node's parent node.
|
|||
/// </summary>
|
|||
IVisual VisualParent { get; } |
|||
|
|||
/// <summary>
|
|||
/// Renders the scene graph node to a <see cref="IDrawingContext"/>.
|
|||
/// </summary>
|
|||
/// <param name="context">The context.</param>
|
|||
void Render(IDrawingContext context); |
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IFocusManager.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
using Perspex.Controls; |
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
public class FocusManager : IFocusManager |
|||
{ |
|||
public IInputElement Current |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public void Focus(IInputElement control) |
|||
{ |
|||
Interactive current = this.Current as Interactive; |
|||
Interactive next = control as Interactive; |
|||
|
|||
if (current != null) |
|||
{ |
|||
current.RaiseEvent(new RoutedEventArgs |
|||
{ |
|||
RoutedEvent = Control.LostFocusEvent, |
|||
Source = current, |
|||
OriginalSource = current, |
|||
}); |
|||
} |
|||
|
|||
this.Current = control; |
|||
|
|||
if (next != null) |
|||
{ |
|||
next.RaiseEvent(new RoutedEventArgs |
|||
{ |
|||
RoutedEvent = Control.GotFocusEvent, |
|||
Source = next, |
|||
OriginalSource = next, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IFocusManager.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
public interface IFocusManager |
|||
{ |
|||
IInputElement Current { get; } |
|||
|
|||
void Focus(IInputElement focusable); |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IInputDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
public interface IInputDevice |
|||
{ |
|||
} |
|||
} |
|||
@ -1,37 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IInputElement.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
|
|||
public interface IInputElement |
|||
{ |
|||
event EventHandler<RoutedEventArgs> GotFocus; |
|||
|
|||
event EventHandler<RoutedEventArgs> LostFocus; |
|||
|
|||
event EventHandler<KeyEventArgs> KeyDown; |
|||
|
|||
event EventHandler<PointerEventArgs> PointerEnter; |
|||
|
|||
event EventHandler<PointerEventArgs> PointerLeave; |
|||
|
|||
event EventHandler<PointerEventArgs> PointerPressed; |
|||
|
|||
event EventHandler<PointerEventArgs> PointerReleased; |
|||
|
|||
bool Focusable { get; } |
|||
|
|||
bool IsFocused { get; } |
|||
|
|||
bool IsPointerOver { get; } |
|||
|
|||
void Focus(); |
|||
|
|||
void RaiseEvent(RoutedEventArgs e); |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IInputManager.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using Perspex.Input.Raw; |
|||
using Perspex.Layout; |
|||
|
|||
public interface IInputManager |
|||
{ |
|||
IObservable<RawInputEventArgs> RawEventReceived { get; } |
|||
|
|||
void Process(RawInputEventArgs e); |
|||
|
|||
void SetPointerOver(IPointerDevice device, IVisual visual, Point p); |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IKeyboardDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
|
|||
[Flags] |
|||
public enum ModifierKeys |
|||
{ |
|||
None = 0, |
|||
Alt = 1, |
|||
Control = 2, |
|||
Shift = 4, |
|||
Windows = 8, |
|||
} |
|||
|
|||
[Flags] |
|||
public enum KeyStates |
|||
{ |
|||
None = 0, |
|||
Down = 1, |
|||
Toggled = 2, |
|||
} |
|||
|
|||
public interface IKeyboardDevice : IInputDevice |
|||
{ |
|||
ModifierKeys Modifiers { get; } |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IMouseDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
public interface IMouseDevice : IPointerDevice |
|||
{ |
|||
Point Position { get; } |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IPointerDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
|
|||
public interface IPointerDevice : IInputDevice |
|||
{ |
|||
Interactive Captured { get; } |
|||
|
|||
void Capture(Interactive visual); |
|||
|
|||
Point GetPosition(IVisual relativeTo); |
|||
} |
|||
} |
|||
@ -1,128 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Control.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Input; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
using Perspex.Styling; |
|||
using Splat; |
|||
|
|||
public class InputElement : Interactive, IInputElement |
|||
{ |
|||
public static readonly PerspexProperty<bool> FocusableProperty = |
|||
PerspexProperty.Register<InputElement, bool>("Focusable"); |
|||
|
|||
public static readonly PerspexProperty<bool> IsFocusedProperty = |
|||
PerspexProperty.Register<InputElement, bool>("IsFocused", false); |
|||
|
|||
public static readonly PerspexProperty<bool> IsPointerOverProperty = |
|||
PerspexProperty.Register<InputElement, bool>("IsPointerOver"); |
|||
|
|||
public static readonly RoutedEvent<RoutedEventArgs> GotFocusEvent = |
|||
RoutedEvent.Register<InputElement, RoutedEventArgs>("GotFocus", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<RoutedEventArgs> LostFocusEvent = |
|||
RoutedEvent.Register<InputElement, RoutedEventArgs>("LostFocus", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<KeyEventArgs> KeyDownEvent = |
|||
RoutedEvent.Register<InputElement, KeyEventArgs>("KeyDown", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<KeyEventArgs> PreviewKeyDownEvent = |
|||
RoutedEvent.Register<InputElement, KeyEventArgs>("PreviewKeyDown", RoutingStrategy.Tunnel); |
|||
|
|||
public static readonly RoutedEvent<PointerEventArgs> PointerEnterEvent = |
|||
RoutedEvent.Register<InputElement, PointerEventArgs>("PointerEnter", RoutingStrategy.Direct); |
|||
|
|||
public static readonly RoutedEvent<PointerEventArgs> PointerLeaveEvent = |
|||
RoutedEvent.Register<InputElement, PointerEventArgs>("PointerLeave", RoutingStrategy.Direct); |
|||
|
|||
public static readonly RoutedEvent<PointerEventArgs> PointerPressedEvent = |
|||
RoutedEvent.Register<InputElement, PointerEventArgs>("PointerPressed", RoutingStrategy.Bubble); |
|||
|
|||
public static readonly RoutedEvent<PointerEventArgs> PointerReleasedEvent = |
|||
RoutedEvent.Register<InputElement, PointerEventArgs>("PointerReleased", RoutingStrategy.Bubble); |
|||
|
|||
public InputElement() |
|||
{ |
|||
this.GotFocus += (s, e) => this.IsFocused = true; |
|||
this.LostFocus += (s, e) => this.IsFocused = false; |
|||
this.PointerEnter += (s, e) => this.IsPointerOver = true; |
|||
this.PointerLeave += (s, e) => this.IsPointerOver = false; |
|||
} |
|||
|
|||
public event EventHandler<RoutedEventArgs> GotFocus |
|||
{ |
|||
add { this.AddHandler(GotFocusEvent, value); } |
|||
remove { this.RemoveHandler(GotFocusEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<RoutedEventArgs> LostFocus |
|||
{ |
|||
add { this.AddHandler(LostFocusEvent, value); } |
|||
remove { this.RemoveHandler(LostFocusEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<KeyEventArgs> KeyDown |
|||
{ |
|||
add { this.AddHandler(KeyDownEvent, value); } |
|||
remove { this.RemoveHandler(KeyDownEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<PointerEventArgs> PointerEnter |
|||
{ |
|||
add { this.AddHandler(PointerEnterEvent, value); } |
|||
remove { this.RemoveHandler(PointerEnterEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<PointerEventArgs> PointerLeave |
|||
{ |
|||
add { this.AddHandler(PointerLeaveEvent, value); } |
|||
remove { this.RemoveHandler(PointerLeaveEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<PointerEventArgs> PointerPressed |
|||
{ |
|||
add { this.AddHandler(PointerPressedEvent, value); } |
|||
remove { this.RemoveHandler(PointerPressedEvent, value); } |
|||
} |
|||
|
|||
public event EventHandler<PointerEventArgs> PointerReleased |
|||
{ |
|||
add { this.AddHandler(PointerReleasedEvent, value); } |
|||
remove { this.RemoveHandler(PointerReleasedEvent, value); } |
|||
} |
|||
|
|||
public bool Focusable |
|||
{ |
|||
get { return this.GetValue(FocusableProperty); } |
|||
set { this.SetValue(FocusableProperty, value); } |
|||
} |
|||
|
|||
public bool IsFocused |
|||
{ |
|||
get { return this.GetValue(IsFocusedProperty); } |
|||
private set { this.SetValue(IsFocusedProperty, value); } |
|||
} |
|||
|
|||
public bool IsPointerOver |
|||
{ |
|||
get { return this.GetValue(IsPointerOverProperty); } |
|||
internal set { this.SetValue(IsPointerOverProperty, value); } |
|||
} |
|||
|
|||
public void Focus() |
|||
{ |
|||
Locator.Current.GetService<IFocusManager>().Focus(this); |
|||
} |
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="InputManager.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive.Subjects; |
|||
using Perspex.Controls; |
|||
using Perspex.Input.Raw; |
|||
|
|||
public class InputManager : IInputManager |
|||
{ |
|||
private List<Control> pointerOvers = new List<Control>(); |
|||
|
|||
private Subject<RawInputEventArgs> rawEventReceived = new Subject<RawInputEventArgs>(); |
|||
|
|||
public IObservable<RawInputEventArgs> RawEventReceived |
|||
{ |
|||
get { return this.rawEventReceived; } |
|||
} |
|||
|
|||
public void Process(RawInputEventArgs e) |
|||
{ |
|||
this.rawEventReceived.OnNext(e); |
|||
} |
|||
|
|||
public void SetPointerOver(IPointerDevice device, IVisual visual, Point p) |
|||
{ |
|||
IEnumerable<IVisual> hits = visual.GetVisualsAt(p); |
|||
|
|||
foreach (var control in this.pointerOvers.ToList().Except(hits).Cast<Control>()) |
|||
{ |
|||
PointerEventArgs e = new PointerEventArgs |
|||
{ |
|||
RoutedEvent = InputElement.PointerLeaveEvent, |
|||
Device = device, |
|||
OriginalSource = control, |
|||
Source = control, |
|||
}; |
|||
|
|||
this.pointerOvers.Remove(control); |
|||
control.RaiseEvent(e); |
|||
} |
|||
|
|||
foreach (var control in hits.Except(this.pointerOvers).Cast<Control>()) |
|||
{ |
|||
PointerEventArgs e = new PointerEventArgs |
|||
{ |
|||
RoutedEvent = InputElement.PointerEnterEvent, |
|||
Device = device, |
|||
OriginalSource = control, |
|||
Source = control, |
|||
}; |
|||
|
|||
this.pointerOvers.Add(control); |
|||
control.RaiseEvent(e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,214 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Key.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
public enum Key |
|||
{ |
|||
None = 0, |
|||
Cancel = 1, |
|||
Back = 2, |
|||
Tab = 3, |
|||
LineFeed = 4, |
|||
Clear = 5, |
|||
Return = 6, |
|||
Enter = 6, |
|||
Pause = 7, |
|||
CapsLock = 8, |
|||
Capital = 8, |
|||
HangulMode = 9, |
|||
KanaMode = 9, |
|||
JunjaMode = 10, |
|||
FinalMode = 11, |
|||
KanjiMode = 12, |
|||
HanjaMode = 12, |
|||
Escape = 13, |
|||
ImeConvert = 14, |
|||
ImeNonConvert = 15, |
|||
ImeAccept = 16, |
|||
ImeModeChange = 17, |
|||
Space = 18, |
|||
PageUp = 19, |
|||
Prior = 19, |
|||
PageDown = 20, |
|||
Next = 20, |
|||
End = 21, |
|||
Home = 22, |
|||
Left = 23, |
|||
Up = 24, |
|||
Right = 25, |
|||
Down = 26, |
|||
Select = 27, |
|||
Print = 28, |
|||
Execute = 29, |
|||
Snapshot = 30, |
|||
PrintScreen = 30, |
|||
Insert = 31, |
|||
Delete = 32, |
|||
Help = 33, |
|||
D0 = 34, |
|||
D1 = 35, |
|||
D2 = 36, |
|||
D3 = 37, |
|||
D4 = 38, |
|||
D5 = 39, |
|||
D6 = 40, |
|||
D7 = 41, |
|||
D8 = 42, |
|||
D9 = 43, |
|||
A = 44, |
|||
B = 45, |
|||
C = 46, |
|||
D = 47, |
|||
E = 48, |
|||
F = 49, |
|||
G = 50, |
|||
H = 51, |
|||
I = 52, |
|||
J = 53, |
|||
K = 54, |
|||
L = 55, |
|||
M = 56, |
|||
N = 57, |
|||
O = 58, |
|||
P = 59, |
|||
Q = 60, |
|||
R = 61, |
|||
S = 62, |
|||
T = 63, |
|||
U = 64, |
|||
V = 65, |
|||
W = 66, |
|||
X = 67, |
|||
Y = 68, |
|||
Z = 69, |
|||
LWin = 70, |
|||
RWin = 71, |
|||
Apps = 72, |
|||
Sleep = 73, |
|||
NumPad0 = 74, |
|||
NumPad1 = 75, |
|||
NumPad2 = 76, |
|||
NumPad3 = 77, |
|||
NumPad4 = 78, |
|||
NumPad5 = 79, |
|||
NumPad6 = 80, |
|||
NumPad7 = 81, |
|||
NumPad8 = 82, |
|||
NumPad9 = 83, |
|||
Multiply = 84, |
|||
Add = 85, |
|||
Separator = 86, |
|||
Subtract = 87, |
|||
Decimal = 88, |
|||
Divide = 89, |
|||
F1 = 90, |
|||
F2 = 91, |
|||
F3 = 92, |
|||
F4 = 93, |
|||
F5 = 94, |
|||
F6 = 95, |
|||
F7 = 96, |
|||
F8 = 97, |
|||
F9 = 98, |
|||
F10 = 99, |
|||
F11 = 100, |
|||
F12 = 101, |
|||
F13 = 102, |
|||
F14 = 103, |
|||
F15 = 104, |
|||
F16 = 105, |
|||
F17 = 106, |
|||
F18 = 107, |
|||
F19 = 108, |
|||
F20 = 109, |
|||
F21 = 110, |
|||
F22 = 111, |
|||
F23 = 112, |
|||
F24 = 113, |
|||
NumLock = 114, |
|||
Scroll = 115, |
|||
LeftShift = 116, |
|||
RightShift = 117, |
|||
LeftCtrl = 118, |
|||
RightCtrl = 119, |
|||
LeftAlt = 120, |
|||
RightAlt = 121, |
|||
BrowserBack = 122, |
|||
BrowserForward = 123, |
|||
BrowserRefresh = 124, |
|||
BrowserStop = 125, |
|||
BrowserSearch = 126, |
|||
BrowserFavorites = 127, |
|||
BrowserHome = 128, |
|||
VolumeMute = 129, |
|||
VolumeDown = 130, |
|||
VolumeUp = 131, |
|||
MediaNextTrack = 132, |
|||
MediaPreviousTrack = 133, |
|||
MediaStop = 134, |
|||
MediaPlayPause = 135, |
|||
LaunchMail = 136, |
|||
SelectMedia = 137, |
|||
LaunchApplication1 = 138, |
|||
LaunchApplication2 = 139, |
|||
OemSemicolon = 140, |
|||
Oem1 = 140, |
|||
OemPlus = 141, |
|||
OemComma = 142, |
|||
OemMinus = 143, |
|||
OemPeriod = 144, |
|||
OemQuestion = 145, |
|||
Oem2 = 145, |
|||
OemTilde = 146, |
|||
Oem3 = 146, |
|||
AbntC1 = 147, |
|||
AbntC2 = 148, |
|||
OemOpenBrackets = 149, |
|||
Oem4 = 149, |
|||
OemPipe = 150, |
|||
Oem5 = 150, |
|||
OemCloseBrackets = 151, |
|||
Oem6 = 151, |
|||
OemQuotes = 152, |
|||
Oem7 = 152, |
|||
Oem8 = 153, |
|||
OemBackslash = 154, |
|||
Oem102 = 154, |
|||
ImeProcessed = 155, |
|||
System = 156, |
|||
OemAttn = 157, |
|||
DbeAlphanumeric = 157, |
|||
OemFinish = 158, |
|||
DbeKatakana = 158, |
|||
DbeHiragana = 159, |
|||
OemCopy = 159, |
|||
DbeSbcsChar = 160, |
|||
OemAuto = 160, |
|||
DbeDbcsChar = 161, |
|||
OemEnlw = 161, |
|||
OemBackTab = 162, |
|||
DbeRoman = 162, |
|||
DbeNoRoman = 163, |
|||
Attn = 163, |
|||
CrSel = 164, |
|||
DbeEnterWordRegisterMode = 164, |
|||
ExSel = 165, |
|||
DbeEnterImeConfigureMode = 165, |
|||
EraseEof = 166, |
|||
DbeFlushString = 166, |
|||
Play = 167, |
|||
DbeCodeInput = 167, |
|||
DbeNoCodeInput = 168, |
|||
Zoom = 168, |
|||
NoName = 169, |
|||
DbeDetermineString = 169, |
|||
DbeEnterDialogConversionMode = 170, |
|||
Pa1 = 170, |
|||
OemClear = 171, |
|||
DeadCharProcessed = 172, |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PointerEventArgs.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
|
|||
public class KeyEventArgs : RoutedEventArgs |
|||
{ |
|||
public IKeyboardDevice Device { get; set; } |
|||
|
|||
public Key Key { get; set; } |
|||
|
|||
public string Text { get; set; } |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="KeyboardDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Input.Raw; |
|||
using Splat; |
|||
|
|||
public abstract class KeyboardDevice : IKeyboardDevice |
|||
{ |
|||
public KeyboardDevice() |
|||
{ |
|||
this.InputManager.RawEventReceived |
|||
.OfType<RawKeyEventArgs>() |
|||
.Where(x => x.Device == this) |
|||
.Subscribe(this.ProcessRawEvent); |
|||
} |
|||
|
|||
public IInputManager InputManager |
|||
{ |
|||
get { return Locator.Current.GetService<IInputManager>(); } |
|||
} |
|||
|
|||
public IFocusManager FocusManager |
|||
{ |
|||
get { return Locator.Current.GetService<IFocusManager>(); } |
|||
} |
|||
|
|||
public IInputElement FocusedElement |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
|
|||
public abstract ModifierKeys Modifiers { get; } |
|||
|
|||
private void ProcessRawEvent(RawKeyEventArgs e) |
|||
{ |
|||
IInputElement element = this.FocusedElement; |
|||
|
|||
if (element != null) |
|||
{ |
|||
switch (e.Type) |
|||
{ |
|||
case RawKeyEventType.KeyDown: |
|||
element.RaiseEvent(new KeyEventArgs |
|||
{ |
|||
RoutedEvent = Control.PreviewKeyDownEvent, |
|||
Device = this, |
|||
Key = e.Key, |
|||
Text = e.Text, |
|||
Source = element, |
|||
OriginalSource = element, |
|||
}); |
|||
element.RaiseEvent(new KeyEventArgs |
|||
{ |
|||
RoutedEvent = Control.KeyDownEvent, |
|||
Device = this, |
|||
Key = e.Key, |
|||
Text = e.Text, |
|||
Source = element, |
|||
OriginalSource = element, |
|||
}); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,153 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="MouseDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Input.Raw; |
|||
using Splat; |
|||
|
|||
public abstract class MouseDevice : IMouseDevice |
|||
{ |
|||
public MouseDevice() |
|||
{ |
|||
this.InputManager.RawEventReceived |
|||
.OfType<RawMouseEventArgs>() |
|||
.Where(x => x.Device == this) |
|||
.Subscribe(this.ProcessRawEvent); |
|||
} |
|||
|
|||
public Interactive Captured |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
|
|||
public IInputManager InputManager |
|||
{ |
|||
get { return Locator.Current.GetService<IInputManager>(); } |
|||
} |
|||
|
|||
public Point Position |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
|
|||
public virtual void Capture(Interactive visual) |
|||
{ |
|||
this.Captured = visual; |
|||
} |
|||
|
|||
public Point GetPosition(IVisual relativeTo) |
|||
{ |
|||
Point p = this.GetClientPosition(); |
|||
IVisual v = relativeTo; |
|||
|
|||
while (v != null) |
|||
{ |
|||
p -= v.Bounds.Position; |
|||
v = v.VisualParent; |
|||
} |
|||
|
|||
return p; |
|||
} |
|||
|
|||
protected abstract Point GetClientPosition(); |
|||
|
|||
private void ProcessRawEvent(RawMouseEventArgs e) |
|||
{ |
|||
this.Position = e.Position; |
|||
|
|||
switch (e.Type) |
|||
{ |
|||
case RawMouseEventType.Move: |
|||
this.MouseMove((IMouseDevice)e.Device, (IVisual)e.Root, e.Position); |
|||
break; |
|||
case RawMouseEventType.LeftButtonDown: |
|||
this.MouseDown((IMouseDevice)e.Device, (IVisual)e.Root, e.Position); |
|||
break; |
|||
case RawMouseEventType.LeftButtonUp: |
|||
this.MouseUp((IMouseDevice)e.Device, (IVisual)e.Root, e.Position); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
private void MouseMove(IMouseDevice device, IVisual visual, Point p) |
|||
{ |
|||
if (this.Captured == null) |
|||
{ |
|||
this.InputManager.SetPointerOver(this, visual, p); |
|||
} |
|||
else |
|||
{ |
|||
Point offset = new Point(); |
|||
|
|||
foreach (IVisual ancestor in this.Captured.GetVisualAncestors()) |
|||
{ |
|||
offset += ancestor.Bounds.Position; |
|||
} |
|||
|
|||
this.InputManager.SetPointerOver(this, this.Captured, p - offset); |
|||
} |
|||
} |
|||
|
|||
private void MouseDown(IMouseDevice device, IVisual visual, Point p) |
|||
{ |
|||
IVisual hit = visual.GetVisualAt(p); |
|||
|
|||
if (hit != null) |
|||
{ |
|||
Interactive interactive = this.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>(); |
|||
IInputElement focusable = |
|||
this.Captured as IInputElement ?? |
|||
hit.GetVisualAncestorsAndSelf() |
|||
.OfType<IInputElement>() |
|||
.FirstOrDefault(x => x.Focusable); |
|||
|
|||
if (interactive != null) |
|||
{ |
|||
interactive.RaiseEvent(new PointerEventArgs |
|||
{ |
|||
Device = this, |
|||
RoutedEvent = Control.PointerPressedEvent, |
|||
OriginalSource = interactive, |
|||
Source = interactive, |
|||
}); |
|||
} |
|||
|
|||
if (focusable != null && focusable.Focusable) |
|||
{ |
|||
focusable.Focus(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void MouseUp(IMouseDevice device, IVisual visual, Point p) |
|||
{ |
|||
IVisual hit = visual.GetVisualAt(p); |
|||
|
|||
if (hit != null) |
|||
{ |
|||
Interactive source = this.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>(); |
|||
|
|||
if (source != null) |
|||
{ |
|||
source.RaiseEvent(new PointerEventArgs |
|||
{ |
|||
Device = this, |
|||
RoutedEvent = Control.PointerReleasedEvent, |
|||
OriginalSource = source, |
|||
Source = source, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PointerEventArgs.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input |
|||
{ |
|||
using System; |
|||
|
|||
public class PointerEventArgs : RoutedEventArgs |
|||
{ |
|||
public IPointerDevice Device { get; set; } |
|||
|
|||
public Point GetPosition(IVisual relativeTo) |
|||
{ |
|||
return this.Device.GetPosition(relativeTo); |
|||
} |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RawInputEventArgs.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input.Raw |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Layout; |
|||
|
|||
public class RawInputEventArgs : EventArgs |
|||
{ |
|||
public RawInputEventArgs(IInputDevice device) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(device != null); |
|||
|
|||
this.Device = device; |
|||
} |
|||
|
|||
public IInputDevice Device { get; private set; } |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RawKeyEventArgs.cs" company="Tricycle">
|
|||
// Copyright 2014 Tricycle. All rights reserved.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input.Raw |
|||
{ |
|||
public enum RawKeyEventType |
|||
{ |
|||
KeyDown, |
|||
KeyUp |
|||
} |
|||
|
|||
public class RawKeyEventArgs : RawInputEventArgs |
|||
{ |
|||
public RawKeyEventArgs(KeyboardDevice device, RawKeyEventType type, Key key, string text) |
|||
: base(device) |
|||
{ |
|||
this.Key = key; |
|||
this.Type = type; |
|||
this.Text = text; |
|||
} |
|||
|
|||
public Key Key { get; set; } |
|||
|
|||
public string Text { get; set; } |
|||
|
|||
public RawKeyEventType Type { get; set; } |
|||
} |
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RawMouseEventArgs.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Input.Raw |
|||
{ |
|||
using System; |
|||
using Perspex.Layout; |
|||
|
|||
public enum RawMouseEventType |
|||
{ |
|||
Move, |
|||
LeftButtonDown, |
|||
LeftButtonUp, |
|||
} |
|||
|
|||
public class RawMouseEventArgs : RawInputEventArgs |
|||
{ |
|||
public RawMouseEventArgs( |
|||
IInputDevice device, |
|||
ILayoutRoot root, |
|||
RawMouseEventType type, |
|||
Point position) |
|||
: base(device) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(device != null); |
|||
Contract.Requires<ArgumentNullException>(root != null); |
|||
|
|||
this.Root = root; |
|||
this.Position = position; |
|||
this.Type = type; |
|||
} |
|||
|
|||
public ILayoutRoot Root { get; private set; } |
|||
|
|||
public Point Position { get; private set; } |
|||
|
|||
public RawMouseEventType Type { get; private set; } |
|||
} |
|||
} |
|||
@ -1,124 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Interactive.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reactive; |
|||
using System.Reactive.Linq; |
|||
using Perspex.Layout; |
|||
|
|||
public class Interactive : Layoutable |
|||
{ |
|||
private Dictionary<RoutedEvent, List<Delegate>> eventHandlers = new Dictionary<RoutedEvent, List<Delegate>>(); |
|||
|
|||
public void AddHandler(RoutedEvent routedEvent, Delegate handler) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(routedEvent != null); |
|||
Contract.Requires<NullReferenceException>(handler != null); |
|||
|
|||
List<Delegate> delegates; |
|||
|
|||
if (!this.eventHandlers.TryGetValue(routedEvent, out delegates)) |
|||
{ |
|||
delegates = new List<Delegate>(); |
|||
this.eventHandlers.Add(routedEvent, delegates); |
|||
} |
|||
|
|||
delegates.Add(handler); |
|||
} |
|||
|
|||
public IObservable<EventPattern<T>> GetObservable<T>(RoutedEvent<T> routedEvent) where T : RoutedEventArgs |
|||
{ |
|||
Contract.Requires<NullReferenceException>(routedEvent != null); |
|||
|
|||
return Observable.FromEventPattern<T>( |
|||
handler => this.AddHandler(routedEvent, handler), |
|||
handler => this.RemoveHandler(routedEvent, handler)); |
|||
} |
|||
|
|||
public void RemoveHandler(RoutedEvent routedEvent, Delegate handler) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(routedEvent != null); |
|||
Contract.Requires<NullReferenceException>(handler != null); |
|||
|
|||
List<Delegate> delegates; |
|||
|
|||
if (this.eventHandlers.TryGetValue(routedEvent, out delegates)) |
|||
{ |
|||
delegates.Remove(handler); |
|||
} |
|||
} |
|||
|
|||
public void RaiseEvent(RoutedEventArgs e) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(e != null); |
|||
|
|||
if (e.RoutedEvent != null) |
|||
{ |
|||
switch (e.RoutedEvent.RoutingStrategy) |
|||
{ |
|||
case RoutingStrategy.Bubble: |
|||
this.BubbleEvent(e); |
|||
break; |
|||
case RoutingStrategy.Direct: |
|||
this.RaiseEventImpl(e); |
|||
break; |
|||
case RoutingStrategy.Tunnel: |
|||
this.TunnelEvent(e); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void BubbleEvent(RoutedEventArgs e) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(e != null); |
|||
|
|||
foreach (var target in this.GetVisualAncestorsAndSelf().OfType<Interactive>()) |
|||
{ |
|||
target.RaiseEventImpl(e); |
|||
|
|||
if (e.Handled) |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void TunnelEvent(RoutedEventArgs e) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(e != null); |
|||
|
|||
foreach (var target in this.GetVisualAncestorsAndSelf().OfType<Interactive>().Reverse()) |
|||
{ |
|||
target.RaiseEventImpl(e); |
|||
|
|||
if (e.Handled) |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void RaiseEventImpl(RoutedEventArgs e) |
|||
{ |
|||
Contract.Requires<NullReferenceException>(e != null); |
|||
|
|||
List<Delegate> delegates; |
|||
|
|||
if (this.eventHandlers.TryGetValue(e.RoutedEvent, out delegates)) |
|||
{ |
|||
foreach (Delegate handler in delegates) |
|||
{ |
|||
handler.DynamicInvoke(this, e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ILayoutManager.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
using System; |
|||
using System.Reactive; |
|||
using Perspex.Controls; |
|||
|
|||
public interface ILayoutManager |
|||
{ |
|||
IObservable<Unit> LayoutNeeded { get; } |
|||
|
|||
void ExecuteLayoutPass(); |
|||
|
|||
void InvalidateMeasure(ILayoutable item); |
|||
|
|||
void InvalidateArrange(ILayoutable item); |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ILayoutRoot.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
public interface ILayoutRoot : ILayoutable |
|||
{ |
|||
Size ClientSize { get; } |
|||
|
|||
ILayoutManager LayoutManager { get; } |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ILayoutable.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
public interface ILayoutable |
|||
{ |
|||
Size? DesiredSize { get; } |
|||
|
|||
void Arrange(Rect rect); |
|||
|
|||
void Measure(Size availableSize); |
|||
|
|||
void InvalidateArrange(); |
|||
|
|||
void InvalidateMeasure(); |
|||
} |
|||
} |
|||
@ -1,59 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="LayoutHelper.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Controls; |
|||
|
|||
public static class LayoutHelper |
|||
{ |
|||
public static Size ApplyLayoutConstraints(Layoutable control, Size constraints) |
|||
{ |
|||
double width = (control.Width > 0) ? control.Width : constraints.Width; |
|||
double height = (control.Height > 0) ? control.Height : constraints.Height; |
|||
width = Math.Min(width, control.MaxWidth); |
|||
width = Math.Max(width, control.MinWidth); |
|||
height = Math.Min(height, control.MaxHeight); |
|||
height = Math.Max(height, control.MinHeight); |
|||
return new Size(width, height); |
|||
} |
|||
|
|||
public static Size MeasureDecorator( |
|||
Control decorator, |
|||
Control content, |
|||
Size availableSize, |
|||
Thickness padding) |
|||
{ |
|||
double width = 0; |
|||
double height = 0; |
|||
|
|||
if (content != null) |
|||
{ |
|||
content.Measure(availableSize.Deflate(padding)); |
|||
Size s = content.DesiredSize.Value.Inflate(padding); |
|||
width = s.Width; |
|||
height = s.Height; |
|||
} |
|||
|
|||
if (decorator.Width > 0) |
|||
{ |
|||
width = decorator.Width; |
|||
} |
|||
|
|||
if (decorator.Height > 0) |
|||
{ |
|||
height = decorator.Height; |
|||
} |
|||
|
|||
return new Size(width, height); |
|||
} |
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="LayoutManager.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reactive; |
|||
using System.Reactive.Subjects; |
|||
using Perspex.Controls; |
|||
|
|||
public class LayoutManager : ILayoutManager |
|||
{ |
|||
private ILayoutRoot root; |
|||
|
|||
private Subject<Unit> layoutNeeded; |
|||
|
|||
public LayoutManager() |
|||
{ |
|||
this.layoutNeeded = new Subject<Unit>(); |
|||
} |
|||
|
|||
public IObservable<Unit> LayoutNeeded |
|||
{ |
|||
get { return this.layoutNeeded; } |
|||
} |
|||
|
|||
public void ExecuteLayoutPass() |
|||
{ |
|||
if (this.root != null) |
|||
{ |
|||
this.root.Measure(this.root.ClientSize); |
|||
this.root.Arrange(new Rect(this.root.ClientSize)); |
|||
} |
|||
|
|||
this.root = null; |
|||
} |
|||
|
|||
public void InvalidateMeasure(ILayoutable item) |
|||
{ |
|||
IVisual visual = item as IVisual; |
|||
this.root = visual.GetVisualAncestorOrSelf<ILayoutRoot>(); |
|||
this.layoutNeeded.OnNext(Unit.Default); |
|||
} |
|||
|
|||
public void InvalidateArrange(ILayoutable item) |
|||
{ |
|||
IVisual visual = item as IVisual; |
|||
this.root = visual.GetVisualAncestorOrSelf<ILayoutRoot>(); |
|||
this.layoutNeeded.OnNext(Unit.Default); |
|||
} |
|||
} |
|||
} |
|||
@ -1,261 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Layoutable.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Layout |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
public enum HorizontalAlignment |
|||
{ |
|||
Stretch, |
|||
Left, |
|||
Center, |
|||
Right, |
|||
} |
|||
|
|||
public enum VerticalAlignment |
|||
{ |
|||
Stretch, |
|||
Top, |
|||
Center, |
|||
Bottom, |
|||
} |
|||
|
|||
public class Layoutable : Visual, ILayoutable |
|||
{ |
|||
public static readonly PerspexProperty<double> WidthProperty = |
|||
PerspexProperty.Register<Layoutable, double>("Width", double.NaN); |
|||
|
|||
public static readonly PerspexProperty<double> HeightProperty = |
|||
PerspexProperty.Register<Layoutable, double>("Height", double.NaN); |
|||
|
|||
public static readonly PerspexProperty<double> MinWidthProperty = |
|||
PerspexProperty.Register<Layoutable, double>("MinWidth"); |
|||
|
|||
public static readonly PerspexProperty<double> MaxWidthProperty = |
|||
PerspexProperty.Register<Layoutable, double>("MaxWidth", double.PositiveInfinity); |
|||
|
|||
public static readonly PerspexProperty<double> MinHeightProperty = |
|||
PerspexProperty.Register<Layoutable, double>("MinHeight"); |
|||
|
|||
public static readonly PerspexProperty<double> MaxHeightProperty = |
|||
PerspexProperty.Register<Layoutable, double>("MaxHeight", double.PositiveInfinity); |
|||
|
|||
public static readonly PerspexProperty<Thickness> MarginProperty = |
|||
PerspexProperty.Register<Layoutable, Thickness>("Margin"); |
|||
|
|||
public static readonly PerspexProperty<HorizontalAlignment> HorizontalAlignmentProperty = |
|||
PerspexProperty.Register<Layoutable, HorizontalAlignment>("HorizontalAlignment"); |
|||
|
|||
public static readonly PerspexProperty<VerticalAlignment> VerticalAlignmentProperty = |
|||
PerspexProperty.Register<Layoutable, VerticalAlignment>("VerticalAlignment"); |
|||
|
|||
public double Width |
|||
{ |
|||
get { return this.GetValue(WidthProperty); } |
|||
set { this.SetValue(WidthProperty, value); } |
|||
} |
|||
|
|||
public double Height |
|||
{ |
|||
get { return this.GetValue(HeightProperty); } |
|||
set { this.SetValue(HeightProperty, value); } |
|||
} |
|||
|
|||
public double MinWidth |
|||
{ |
|||
get { return this.GetValue(MinWidthProperty); } |
|||
set { this.SetValue(MinWidthProperty, value); } |
|||
} |
|||
|
|||
public double MaxWidth |
|||
{ |
|||
get { return this.GetValue(MaxWidthProperty); } |
|||
set { this.SetValue(MaxWidthProperty, value); } |
|||
} |
|||
|
|||
public double MinHeight |
|||
{ |
|||
get { return this.GetValue(MinHeightProperty); } |
|||
set { this.SetValue(MinHeightProperty, value); } |
|||
} |
|||
|
|||
public double MaxHeight |
|||
{ |
|||
get { return this.GetValue(MaxHeightProperty); } |
|||
set { this.SetValue(MaxHeightProperty, value); } |
|||
} |
|||
|
|||
public Thickness Margin |
|||
{ |
|||
get { return this.GetValue(MarginProperty); } |
|||
set { this.SetValue(MarginProperty, value); } |
|||
} |
|||
|
|||
public HorizontalAlignment HorizontalAlignment |
|||
{ |
|||
get { return this.GetValue(HorizontalAlignmentProperty); } |
|||
set { this.SetValue(HorizontalAlignmentProperty, value); } |
|||
} |
|||
|
|||
public VerticalAlignment VerticalAlignment |
|||
{ |
|||
get { return this.GetValue(VerticalAlignmentProperty); } |
|||
set { this.SetValue(VerticalAlignmentProperty, value); } |
|||
} |
|||
|
|||
public Size ActualSize |
|||
{ |
|||
get { return ((IVisual)this).Bounds.Size; } |
|||
} |
|||
|
|||
public Size? DesiredSize |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public void Measure(Size availableSize) |
|||
{ |
|||
availableSize = availableSize.Deflate(this.Margin); |
|||
this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize); |
|||
} |
|||
|
|||
public void Arrange(Rect rect) |
|||
{ |
|||
if (this.DesiredSize.HasValue) |
|||
{ |
|||
this.ArrangeCore(rect); |
|||
} |
|||
} |
|||
|
|||
public void InvalidateMeasure() |
|||
{ |
|||
ILayoutRoot root = this.GetVisualAncestorOrSelf<ILayoutRoot>(); |
|||
|
|||
if (root != null && root.LayoutManager != null) |
|||
{ |
|||
root.LayoutManager.InvalidateMeasure(this); |
|||
} |
|||
} |
|||
|
|||
public void InvalidateArrange() |
|||
{ |
|||
ILayoutRoot root = this.GetVisualAncestorOrSelf<ILayoutRoot>(); |
|||
|
|||
if (root != null) |
|||
{ |
|||
root.LayoutManager.InvalidateArrange(this); |
|||
} |
|||
} |
|||
|
|||
protected static void AffectsArrange(PerspexProperty property) |
|||
{ |
|||
property.Changed.Subscribe(AffectsArrangeInvalidate); |
|||
} |
|||
|
|||
protected static void AffectsMeasure(PerspexProperty property) |
|||
{ |
|||
property.Changed.Subscribe(AffectsMeasureInvalidate); |
|||
} |
|||
|
|||
protected virtual void ArrangeCore(Rect finalRect) |
|||
{ |
|||
double originX = finalRect.X + this.Margin.Left; |
|||
double originY = finalRect.Y + this.Margin.Top; |
|||
double sizeX = Math.Max(0, finalRect.Width - this.Margin.Left - this.Margin.Right); |
|||
double sizeY = Math.Max(0, finalRect.Height - this.Margin.Top - this.Margin.Bottom); |
|||
|
|||
if (this.HorizontalAlignment != HorizontalAlignment.Stretch) |
|||
{ |
|||
sizeX = Math.Min(sizeX, this.DesiredSize.Value.Width); |
|||
} |
|||
|
|||
if (this.VerticalAlignment != VerticalAlignment.Stretch) |
|||
{ |
|||
sizeY = Math.Min(sizeY, this.DesiredSize.Value.Height); |
|||
} |
|||
|
|||
Size taken = this.ArrangeOverride(new Size(sizeX, sizeY)); |
|||
|
|||
sizeX = Math.Min(taken.Width, sizeX); |
|||
sizeY = Math.Min(taken.Height, sizeY); |
|||
|
|||
switch (this.HorizontalAlignment) |
|||
{ |
|||
case HorizontalAlignment.Center: |
|||
originX += (finalRect.Width - sizeX) / 2; |
|||
break; |
|||
case HorizontalAlignment.Right: |
|||
originX += finalRect.Width - sizeX; |
|||
break; |
|||
} |
|||
|
|||
switch (this.VerticalAlignment) |
|||
{ |
|||
case VerticalAlignment.Center: |
|||
originY += (finalRect.Height - sizeY) / 2; |
|||
break; |
|||
case VerticalAlignment.Bottom: |
|||
originY += finalRect.Height - sizeY; |
|||
break; |
|||
} |
|||
|
|||
((IVisual)this).Bounds = new Rect(originX, originY, sizeX, sizeY); |
|||
} |
|||
|
|||
protected virtual Size ArrangeOverride(Size finalSize) |
|||
{ |
|||
return finalSize; |
|||
} |
|||
|
|||
protected virtual Size MeasureCore(Size availableSize) |
|||
{ |
|||
if (this.IsVisible) |
|||
{ |
|||
availableSize = LayoutHelper.ApplyLayoutConstraints(this, availableSize) |
|||
.Deflate(this.Margin); |
|||
var measured = this.MeasureOverride(availableSize); |
|||
|
|||
return measured.Inflate(this.Margin); |
|||
} |
|||
else |
|||
{ |
|||
return new Size(); |
|||
} |
|||
} |
|||
|
|||
protected virtual Size MeasureOverride(Size availableSize) |
|||
{ |
|||
return new Size(); |
|||
} |
|||
|
|||
private static void AffectsArrangeInvalidate(PerspexPropertyChangedEventArgs e) |
|||
{ |
|||
ILayoutable control = e.Sender as ILayoutable; |
|||
|
|||
if (control != null) |
|||
{ |
|||
control.InvalidateArrange(); |
|||
} |
|||
} |
|||
|
|||
private static void AffectsMeasureInvalidate(PerspexPropertyChangedEventArgs e) |
|||
{ |
|||
ILayoutable control = e.Sender as ILayoutable; |
|||
|
|||
if (control != null) |
|||
{ |
|||
control.InvalidateMeasure(); |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -1,37 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="LogicalExtensions.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Styling; |
|||
|
|||
public static class LogicalExtensions |
|||
{ |
|||
public static T FindControl<T>(this ILogical control, string id) where T : Control |
|||
{ |
|||
return control.GetLogicalDescendents() |
|||
.OfType<T>() |
|||
.FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public static IEnumerable<ILogical> GetLogicalDescendents(this ILogical control) |
|||
{ |
|||
foreach (ILogical child in control.LogicalChildren) |
|||
{ |
|||
yield return child; |
|||
|
|||
foreach (ILogical descendent in child.GetLogicalDescendents()) |
|||
{ |
|||
yield return descendent; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Brush.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Describes how an area is painted.
|
|||
/// </summary>
|
|||
public abstract class Brush |
|||
{ |
|||
} |
|||
} |
|||
@ -1,301 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Brushes.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Predefined brushes.
|
|||
/// </summary>
|
|||
public static class Brushes |
|||
{ |
|||
static Brushes() |
|||
{ |
|||
AliceBlue = new SolidColorBrush(Colors.AliceBlue); |
|||
AntiqueWhite = new SolidColorBrush(Colors.AntiqueWhite); |
|||
Aqua = new SolidColorBrush(Colors.Aqua); |
|||
Aquamarine = new SolidColorBrush(Colors.Aquamarine); |
|||
Azure = new SolidColorBrush(Colors.Azure); |
|||
Beige = new SolidColorBrush(Colors.Beige); |
|||
Bisque = new SolidColorBrush(Colors.Bisque); |
|||
Black = new SolidColorBrush(Colors.Black); |
|||
BlanchedAlmond = new SolidColorBrush(Colors.BlanchedAlmond); |
|||
Blue = new SolidColorBrush(Colors.Blue); |
|||
BlueViolet = new SolidColorBrush(Colors.BlueViolet); |
|||
Brown = new SolidColorBrush(Colors.Brown); |
|||
BurlyWood = new SolidColorBrush(Colors.BurlyWood); |
|||
CadetBlue = new SolidColorBrush(Colors.CadetBlue); |
|||
Chartreuse = new SolidColorBrush(Colors.Chartreuse); |
|||
Chocolate = new SolidColorBrush(Colors.Chocolate); |
|||
Coral = new SolidColorBrush(Colors.Coral); |
|||
CornflowerBlue = new SolidColorBrush(Colors.CornflowerBlue); |
|||
Cornsilk = new SolidColorBrush(Colors.Cornsilk); |
|||
Crimson = new SolidColorBrush(Colors.Crimson); |
|||
Cyan = new SolidColorBrush(Colors.Cyan); |
|||
DarkBlue = new SolidColorBrush(Colors.DarkBlue); |
|||
DarkCyan = new SolidColorBrush(Colors.DarkCyan); |
|||
DarkGoldenrod = new SolidColorBrush(Colors.DarkGoldenrod); |
|||
DarkGray = new SolidColorBrush(Colors.DarkGray); |
|||
DarkGreen = new SolidColorBrush(Colors.DarkGreen); |
|||
DarkKhaki = new SolidColorBrush(Colors.DarkKhaki); |
|||
DarkMagenta = new SolidColorBrush(Colors.DarkMagenta); |
|||
DarkOliveGreen = new SolidColorBrush(Colors.DarkOliveGreen); |
|||
DarkOrange = new SolidColorBrush(Colors.DarkOrange); |
|||
DarkOrchid = new SolidColorBrush(Colors.DarkOrchid); |
|||
DarkRed = new SolidColorBrush(Colors.DarkRed); |
|||
DarkSalmon = new SolidColorBrush(Colors.DarkSalmon); |
|||
DarkSeaGreen = new SolidColorBrush(Colors.DarkSeaGreen); |
|||
DarkSlateBlue = new SolidColorBrush(Colors.DarkSlateBlue); |
|||
DarkSlateGray = new SolidColorBrush(Colors.DarkSlateGray); |
|||
DarkTurquoise = new SolidColorBrush(Colors.DarkTurquoise); |
|||
DarkViolet = new SolidColorBrush(Colors.DarkViolet); |
|||
DeepPink = new SolidColorBrush(Colors.DeepPink); |
|||
DeepSkyBlue = new SolidColorBrush(Colors.DeepSkyBlue); |
|||
DimGray = new SolidColorBrush(Colors.DimGray); |
|||
DodgerBlue = new SolidColorBrush(Colors.DodgerBlue); |
|||
Firebrick = new SolidColorBrush(Colors.Firebrick); |
|||
FloralWhite = new SolidColorBrush(Colors.FloralWhite); |
|||
ForestGreen = new SolidColorBrush(Colors.ForestGreen); |
|||
Fuchsia = new SolidColorBrush(Colors.Fuchsia); |
|||
Gainsboro = new SolidColorBrush(Colors.Gainsboro); |
|||
GhostWhite = new SolidColorBrush(Colors.GhostWhite); |
|||
Gold = new SolidColorBrush(Colors.Gold); |
|||
Goldenrod = new SolidColorBrush(Colors.Goldenrod); |
|||
Gray = new SolidColorBrush(Colors.Gray); |
|||
Green = new SolidColorBrush(Colors.Green); |
|||
GreenYellow = new SolidColorBrush(Colors.GreenYellow); |
|||
Honeydew = new SolidColorBrush(Colors.Honeydew); |
|||
HotPink = new SolidColorBrush(Colors.HotPink); |
|||
IndianRed = new SolidColorBrush(Colors.IndianRed); |
|||
Indigo = new SolidColorBrush(Colors.Indigo); |
|||
Ivory = new SolidColorBrush(Colors.Ivory); |
|||
Khaki = new SolidColorBrush(Colors.Khaki); |
|||
Lavender = new SolidColorBrush(Colors.Lavender); |
|||
LavenderBlush = new SolidColorBrush(Colors.LavenderBlush); |
|||
LawnGreen = new SolidColorBrush(Colors.LawnGreen); |
|||
LemonChiffon = new SolidColorBrush(Colors.LemonChiffon); |
|||
LightBlue = new SolidColorBrush(Colors.LightBlue); |
|||
LightCoral = new SolidColorBrush(Colors.LightCoral); |
|||
LightCyan = new SolidColorBrush(Colors.LightCyan); |
|||
LightGoldenrodYellow = new SolidColorBrush(Colors.LightGoldenrodYellow); |
|||
LightGray = new SolidColorBrush(Colors.LightGray); |
|||
LightGreen = new SolidColorBrush(Colors.LightGreen); |
|||
LightPink = new SolidColorBrush(Colors.LightPink); |
|||
LightSalmon = new SolidColorBrush(Colors.LightSalmon); |
|||
LightSeaGreen = new SolidColorBrush(Colors.LightSeaGreen); |
|||
LightSkyBlue = new SolidColorBrush(Colors.LightSkyBlue); |
|||
LightSlateGray = new SolidColorBrush(Colors.LightSlateGray); |
|||
LightSteelBlue = new SolidColorBrush(Colors.LightSteelBlue); |
|||
LightYellow = new SolidColorBrush(Colors.LightYellow); |
|||
Lime = new SolidColorBrush(Colors.Lime); |
|||
LimeGreen = new SolidColorBrush(Colors.LimeGreen); |
|||
Linen = new SolidColorBrush(Colors.Linen); |
|||
Magenta = new SolidColorBrush(Colors.Magenta); |
|||
Maroon = new SolidColorBrush(Colors.Maroon); |
|||
MediumAquamarine = new SolidColorBrush(Colors.MediumAquamarine); |
|||
MediumBlue = new SolidColorBrush(Colors.MediumBlue); |
|||
MediumOrchid = new SolidColorBrush(Colors.MediumOrchid); |
|||
MediumPurple = new SolidColorBrush(Colors.MediumPurple); |
|||
MediumSeaGreen = new SolidColorBrush(Colors.MediumSeaGreen); |
|||
MediumSlateBlue = new SolidColorBrush(Colors.MediumSlateBlue); |
|||
MediumSpringGreen = new SolidColorBrush(Colors.MediumSpringGreen); |
|||
MediumTurquoise = new SolidColorBrush(Colors.MediumTurquoise); |
|||
MediumVioletRed = new SolidColorBrush(Colors.MediumVioletRed); |
|||
MidnightBlue = new SolidColorBrush(Colors.MidnightBlue); |
|||
MintCream = new SolidColorBrush(Colors.MintCream); |
|||
MistyRose = new SolidColorBrush(Colors.MistyRose); |
|||
Moccasin = new SolidColorBrush(Colors.Moccasin); |
|||
NavajoWhite = new SolidColorBrush(Colors.NavajoWhite); |
|||
Navy = new SolidColorBrush(Colors.Navy); |
|||
OldLace = new SolidColorBrush(Colors.OldLace); |
|||
Olive = new SolidColorBrush(Colors.Olive); |
|||
OliveDrab = new SolidColorBrush(Colors.OliveDrab); |
|||
Orange = new SolidColorBrush(Colors.Orange); |
|||
OrangeRed = new SolidColorBrush(Colors.OrangeRed); |
|||
Orchid = new SolidColorBrush(Colors.Orchid); |
|||
PaleGoldenrod = new SolidColorBrush(Colors.PaleGoldenrod); |
|||
PaleGreen = new SolidColorBrush(Colors.PaleGreen); |
|||
PaleTurquoise = new SolidColorBrush(Colors.PaleTurquoise); |
|||
PaleVioletRed = new SolidColorBrush(Colors.PaleVioletRed); |
|||
PapayaWhip = new SolidColorBrush(Colors.PapayaWhip); |
|||
PeachPuff = new SolidColorBrush(Colors.PeachPuff); |
|||
Peru = new SolidColorBrush(Colors.Peru); |
|||
Pink = new SolidColorBrush(Colors.Pink); |
|||
Plum = new SolidColorBrush(Colors.Plum); |
|||
PowderBlue = new SolidColorBrush(Colors.PowderBlue); |
|||
Purple = new SolidColorBrush(Colors.Purple); |
|||
Red = new SolidColorBrush(Colors.Red); |
|||
RosyBrown = new SolidColorBrush(Colors.RosyBrown); |
|||
RoyalBlue = new SolidColorBrush(Colors.RoyalBlue); |
|||
SaddleBrown = new SolidColorBrush(Colors.SaddleBrown); |
|||
Salmon = new SolidColorBrush(Colors.Salmon); |
|||
SandyBrown = new SolidColorBrush(Colors.SandyBrown); |
|||
SeaGreen = new SolidColorBrush(Colors.SeaGreen); |
|||
SeaShell = new SolidColorBrush(Colors.SeaShell); |
|||
Sienna = new SolidColorBrush(Colors.Sienna); |
|||
Silver = new SolidColorBrush(Colors.Silver); |
|||
SkyBlue = new SolidColorBrush(Colors.SkyBlue); |
|||
SlateBlue = new SolidColorBrush(Colors.SlateBlue); |
|||
SlateGray = new SolidColorBrush(Colors.SlateGray); |
|||
Snow = new SolidColorBrush(Colors.Snow); |
|||
SpringGreen = new SolidColorBrush(Colors.SpringGreen); |
|||
SteelBlue = new SolidColorBrush(Colors.SteelBlue); |
|||
Tan = new SolidColorBrush(Colors.Tan); |
|||
Teal = new SolidColorBrush(Colors.Teal); |
|||
Thistle = new SolidColorBrush(Colors.Thistle); |
|||
Tomato = new SolidColorBrush(Colors.Tomato); |
|||
Transparent = new SolidColorBrush(Colors.Transparent); |
|||
Turquoise = new SolidColorBrush(Colors.Turquoise); |
|||
Violet = new SolidColorBrush(Colors.Violet); |
|||
Wheat = new SolidColorBrush(Colors.Wheat); |
|||
White = new SolidColorBrush(Colors.White); |
|||
WhiteSmoke = new SolidColorBrush(Colors.WhiteSmoke); |
|||
Yellow = new SolidColorBrush(Colors.Yellow); |
|||
YellowGreen = new SolidColorBrush(Colors.YellowGreen); |
|||
} |
|||
|
|||
public static SolidColorBrush AliceBlue { get; private set; } |
|||
public static SolidColorBrush AntiqueWhite { get; private set; } |
|||
public static SolidColorBrush Aqua { get; private set; } |
|||
public static SolidColorBrush Aquamarine { get; private set; } |
|||
public static SolidColorBrush Azure { get; private set; } |
|||
public static SolidColorBrush Beige { get; private set; } |
|||
public static SolidColorBrush Bisque { get; private set; } |
|||
public static SolidColorBrush Black { get; private set; } |
|||
public static SolidColorBrush BlanchedAlmond { get; private set; } |
|||
public static SolidColorBrush Blue { get; private set; } |
|||
public static SolidColorBrush BlueViolet { get; private set; } |
|||
public static SolidColorBrush Brown { get; private set; } |
|||
public static SolidColorBrush BurlyWood { get; private set; } |
|||
public static SolidColorBrush CadetBlue { get; private set; } |
|||
public static SolidColorBrush Chartreuse { get; private set; } |
|||
public static SolidColorBrush Chocolate { get; private set; } |
|||
public static SolidColorBrush Coral { get; private set; } |
|||
public static SolidColorBrush CornflowerBlue { get; private set; } |
|||
public static SolidColorBrush Cornsilk { get; private set; } |
|||
public static SolidColorBrush Crimson { get; private set; } |
|||
public static SolidColorBrush Cyan { get; private set; } |
|||
public static SolidColorBrush DarkBlue { get; private set; } |
|||
public static SolidColorBrush DarkCyan { get; private set; } |
|||
public static SolidColorBrush DarkGoldenrod { get; private set; } |
|||
public static SolidColorBrush DarkGray { get; private set; } |
|||
public static SolidColorBrush DarkGreen { get; private set; } |
|||
public static SolidColorBrush DarkKhaki { get; private set; } |
|||
public static SolidColorBrush DarkMagenta { get; private set; } |
|||
public static SolidColorBrush DarkOliveGreen { get; private set; } |
|||
public static SolidColorBrush DarkOrange { get; private set; } |
|||
public static SolidColorBrush DarkOrchid { get; private set; } |
|||
public static SolidColorBrush DarkRed { get; private set; } |
|||
public static SolidColorBrush DarkSalmon { get; private set; } |
|||
public static SolidColorBrush DarkSeaGreen { get; private set; } |
|||
public static SolidColorBrush DarkSlateBlue { get; private set; } |
|||
public static SolidColorBrush DarkSlateGray { get; private set; } |
|||
public static SolidColorBrush DarkTurquoise { get; private set; } |
|||
public static SolidColorBrush DarkViolet { get; private set; } |
|||
public static SolidColorBrush DeepPink { get; private set; } |
|||
public static SolidColorBrush DeepSkyBlue { get; private set; } |
|||
public static SolidColorBrush DimGray { get; private set; } |
|||
public static SolidColorBrush DodgerBlue { get; private set; } |
|||
public static SolidColorBrush Firebrick { get; private set; } |
|||
public static SolidColorBrush FloralWhite { get; private set; } |
|||
public static SolidColorBrush ForestGreen { get; private set; } |
|||
public static SolidColorBrush Fuchsia { get; private set; } |
|||
public static SolidColorBrush Gainsboro { get; private set; } |
|||
public static SolidColorBrush GhostWhite { get; private set; } |
|||
public static SolidColorBrush Gold { get; private set; } |
|||
public static SolidColorBrush Goldenrod { get; private set; } |
|||
public static SolidColorBrush Gray { get; private set; } |
|||
public static SolidColorBrush Green { get; private set; } |
|||
public static SolidColorBrush GreenYellow { get; private set; } |
|||
public static SolidColorBrush Honeydew { get; private set; } |
|||
public static SolidColorBrush HotPink { get; private set; } |
|||
public static SolidColorBrush IndianRed { get; private set; } |
|||
public static SolidColorBrush Indigo { get; private set; } |
|||
public static SolidColorBrush Ivory { get; private set; } |
|||
public static SolidColorBrush Khaki { get; private set; } |
|||
public static SolidColorBrush Lavender { get; private set; } |
|||
public static SolidColorBrush LavenderBlush { get; private set; } |
|||
public static SolidColorBrush LawnGreen { get; private set; } |
|||
public static SolidColorBrush LemonChiffon { get; private set; } |
|||
public static SolidColorBrush LightBlue { get; private set; } |
|||
public static SolidColorBrush LightCoral { get; private set; } |
|||
public static SolidColorBrush LightCyan { get; private set; } |
|||
public static SolidColorBrush LightGoldenrodYellow { get; private set; } |
|||
public static SolidColorBrush LightGray { get; private set; } |
|||
public static SolidColorBrush LightGreen { get; private set; } |
|||
public static SolidColorBrush LightPink { get; private set; } |
|||
public static SolidColorBrush LightSalmon { get; private set; } |
|||
public static SolidColorBrush LightSeaGreen { get; private set; } |
|||
public static SolidColorBrush LightSkyBlue { get; private set; } |
|||
public static SolidColorBrush LightSlateGray { get; private set; } |
|||
public static SolidColorBrush LightSteelBlue { get; private set; } |
|||
public static SolidColorBrush LightYellow { get; private set; } |
|||
public static SolidColorBrush Lime { get; private set; } |
|||
public static SolidColorBrush LimeGreen { get; private set; } |
|||
public static SolidColorBrush Linen { get; private set; } |
|||
public static SolidColorBrush Magenta { get; private set; } |
|||
public static SolidColorBrush Maroon { get; private set; } |
|||
public static SolidColorBrush MediumAquamarine { get; private set; } |
|||
public static SolidColorBrush MediumBlue { get; private set; } |
|||
public static SolidColorBrush MediumOrchid { get; private set; } |
|||
public static SolidColorBrush MediumPurple { get; private set; } |
|||
public static SolidColorBrush MediumSeaGreen { get; private set; } |
|||
public static SolidColorBrush MediumSlateBlue { get; private set; } |
|||
public static SolidColorBrush MediumSpringGreen { get; private set; } |
|||
public static SolidColorBrush MediumTurquoise { get; private set; } |
|||
public static SolidColorBrush MediumVioletRed { get; private set; } |
|||
public static SolidColorBrush MidnightBlue { get; private set; } |
|||
public static SolidColorBrush MintCream { get; private set; } |
|||
public static SolidColorBrush MistyRose { get; private set; } |
|||
public static SolidColorBrush Moccasin { get; private set; } |
|||
public static SolidColorBrush NavajoWhite { get; private set; } |
|||
public static SolidColorBrush Navy { get; private set; } |
|||
public static SolidColorBrush OldLace { get; private set; } |
|||
public static SolidColorBrush Olive { get; private set; } |
|||
public static SolidColorBrush OliveDrab { get; private set; } |
|||
public static SolidColorBrush Orange { get; private set; } |
|||
public static SolidColorBrush OrangeRed { get; private set; } |
|||
public static SolidColorBrush Orchid { get; private set; } |
|||
public static SolidColorBrush PaleGoldenrod { get; private set; } |
|||
public static SolidColorBrush PaleGreen { get; private set; } |
|||
public static SolidColorBrush PaleTurquoise { get; private set; } |
|||
public static SolidColorBrush PaleVioletRed { get; private set; } |
|||
public static SolidColorBrush PapayaWhip { get; private set; } |
|||
public static SolidColorBrush PeachPuff { get; private set; } |
|||
public static SolidColorBrush Peru { get; private set; } |
|||
public static SolidColorBrush Pink { get; private set; } |
|||
public static SolidColorBrush Plum { get; private set; } |
|||
public static SolidColorBrush PowderBlue { get; private set; } |
|||
public static SolidColorBrush Purple { get; private set; } |
|||
public static SolidColorBrush Red { get; private set; } |
|||
public static SolidColorBrush RosyBrown { get; private set; } |
|||
public static SolidColorBrush RoyalBlue { get; private set; } |
|||
public static SolidColorBrush SaddleBrown { get; private set; } |
|||
public static SolidColorBrush Salmon { get; private set; } |
|||
public static SolidColorBrush SandyBrown { get; private set; } |
|||
public static SolidColorBrush SeaGreen { get; private set; } |
|||
public static SolidColorBrush SeaShell { get; private set; } |
|||
public static SolidColorBrush Sienna { get; private set; } |
|||
public static SolidColorBrush Silver { get; private set; } |
|||
public static SolidColorBrush SkyBlue { get; private set; } |
|||
public static SolidColorBrush SlateBlue { get; private set; } |
|||
public static SolidColorBrush SlateGray { get; private set; } |
|||
public static SolidColorBrush Snow { get; private set; } |
|||
public static SolidColorBrush SpringGreen { get; private set; } |
|||
public static SolidColorBrush SteelBlue { get; private set; } |
|||
public static SolidColorBrush Tan { get; private set; } |
|||
public static SolidColorBrush Teal { get; private set; } |
|||
public static SolidColorBrush Thistle { get; private set; } |
|||
public static SolidColorBrush Tomato { get; private set; } |
|||
public static SolidColorBrush Transparent { get; private set; } |
|||
public static SolidColorBrush Turquoise { get; private set; } |
|||
public static SolidColorBrush Violet { get; private set; } |
|||
public static SolidColorBrush Wheat { get; private set; } |
|||
public static SolidColorBrush White { get; private set; } |
|||
public static SolidColorBrush WhiteSmoke { get; private set; } |
|||
public static SolidColorBrush Yellow { get; private set; } |
|||
public static SolidColorBrush YellowGreen { get; private set; } |
|||
} |
|||
} |
|||
@ -1,110 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Color.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
/// <summary>
|
|||
/// An ARGB color.
|
|||
/// </summary>
|
|||
public struct Color |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the Alpha component of the color.
|
|||
/// </summary>
|
|||
public byte A { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the Red component of the color.
|
|||
/// </summary>
|
|||
public byte R { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the Green component of the color.
|
|||
/// </summary>
|
|||
public byte G { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the Blue component of the color.
|
|||
/// </summary>
|
|||
public byte B { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Color"/> from alpha, red, green and blue components.
|
|||
/// </summary>
|
|||
/// <param name="a">The alpha component.</param>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
/// <returns>The color.</returns>
|
|||
public static Color FromArgb(byte a, byte r, byte g, byte b) |
|||
{ |
|||
return new Color |
|||
{ |
|||
A = a, |
|||
R = r, |
|||
G = g, |
|||
B = b, |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Color"/> from red, green and blue components.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
/// <returns>The color.</returns>
|
|||
public static Color FromRgb(byte r, byte g, byte b) |
|||
{ |
|||
return new Color |
|||
{ |
|||
A = 0xff, |
|||
R = r, |
|||
G = g, |
|||
B = b, |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Color"/> from an integer.
|
|||
/// </summary>
|
|||
/// <param name="value">The integer value.</param>
|
|||
/// <returns>The color.</returns>
|
|||
public static Color FromUInt32(uint value) |
|||
{ |
|||
return new Color |
|||
{ |
|||
A = (byte)((value >> 24) & 0xff), |
|||
R = (byte)((value >> 16) & 0xff), |
|||
G = (byte)((value >> 8) & 0xff), |
|||
B = (byte)(value & 0xff), |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the string representation of the color.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The string representation of the color.
|
|||
/// </returns>
|
|||
public override string ToString() |
|||
{ |
|||
uint rgb = ((uint)this.A << 24) | ((uint)this.R << 16) | ((uint)this.G << 8) | (uint)this.B; |
|||
return string.Format("#{0:x8}", rgb); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the integer representation of the color.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The integer representation of the color.
|
|||
/// </returns>
|
|||
public uint ToUint32() |
|||
{ |
|||
return ((uint)this.A << 24) | ((uint)this.R << 16) | ((uint)this.G << 8) | (uint)this.B; |
|||
} |
|||
} |
|||
} |
|||
@ -1,716 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Colors.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class Colors |
|||
{ |
|||
public static Color AliceBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xfff0f8ff); } |
|||
} |
|||
|
|||
public static Color AntiqueWhite |
|||
{ |
|||
get { return Color.FromUInt32(0xfffaebd7); } |
|||
} |
|||
|
|||
public static Color Aqua |
|||
{ |
|||
get { return Color.FromUInt32(0xff00ffff); } |
|||
} |
|||
|
|||
public static Color Aquamarine |
|||
{ |
|||
get { return Color.FromUInt32(0xff7fffd4); } |
|||
} |
|||
|
|||
public static Color Azure |
|||
{ |
|||
get { return Color.FromUInt32(0xfff0ffff); } |
|||
} |
|||
|
|||
public static Color Beige |
|||
{ |
|||
get { return Color.FromUInt32(0xfff5f5dc); } |
|||
} |
|||
|
|||
public static Color Bisque |
|||
{ |
|||
get { return Color.FromUInt32(0xffffe4c4); } |
|||
} |
|||
|
|||
public static Color Black |
|||
{ |
|||
get { return Color.FromUInt32(0xff000000); } |
|||
} |
|||
|
|||
public static Color BlanchedAlmond |
|||
{ |
|||
get { return Color.FromUInt32(0xffffebcd); } |
|||
} |
|||
|
|||
public static Color Blue |
|||
{ |
|||
get { return Color.FromUInt32(0xff0000ff); } |
|||
} |
|||
|
|||
public static Color BlueViolet |
|||
{ |
|||
get { return Color.FromUInt32(0xff8a2be2); } |
|||
} |
|||
|
|||
public static Color Brown |
|||
{ |
|||
get { return Color.FromUInt32(0xffa52a2a); } |
|||
} |
|||
|
|||
public static Color BurlyWood |
|||
{ |
|||
get { return Color.FromUInt32(0xffdeb887); } |
|||
} |
|||
|
|||
public static Color CadetBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff5f9ea0); } |
|||
} |
|||
|
|||
public static Color Chartreuse |
|||
{ |
|||
get { return Color.FromUInt32(0xff7fff00); } |
|||
} |
|||
|
|||
public static Color Chocolate |
|||
{ |
|||
get { return Color.FromUInt32(0xffd2691e); } |
|||
} |
|||
|
|||
public static Color Coral |
|||
{ |
|||
get { return Color.FromUInt32(0xffff7f50); } |
|||
} |
|||
|
|||
public static Color CornflowerBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff6495ed); } |
|||
} |
|||
|
|||
public static Color Cornsilk |
|||
{ |
|||
get { return Color.FromUInt32(0xfffff8dc); } |
|||
} |
|||
|
|||
public static Color Crimson |
|||
{ |
|||
get { return Color.FromUInt32(0xffdc143c); } |
|||
} |
|||
|
|||
public static Color Cyan |
|||
{ |
|||
get { return Color.FromUInt32(0xff00ffff); } |
|||
} |
|||
|
|||
public static Color DarkBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff00008b); } |
|||
} |
|||
|
|||
public static Color DarkCyan |
|||
{ |
|||
get { return Color.FromUInt32(0xff008b8b); } |
|||
} |
|||
|
|||
public static Color DarkGoldenrod |
|||
{ |
|||
get { return Color.FromUInt32(0xffb8860b); } |
|||
} |
|||
|
|||
public static Color DarkGray |
|||
{ |
|||
get { return Color.FromUInt32(0xffa9a9a9); } |
|||
} |
|||
|
|||
public static Color DarkGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff006400); } |
|||
} |
|||
|
|||
public static Color DarkKhaki |
|||
{ |
|||
get { return Color.FromUInt32(0xffbdb76b); } |
|||
} |
|||
|
|||
public static Color DarkMagenta |
|||
{ |
|||
get { return Color.FromUInt32(0xff8b008b); } |
|||
} |
|||
|
|||
public static Color DarkOliveGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff556b2f); } |
|||
} |
|||
|
|||
public static Color DarkOrange |
|||
{ |
|||
get { return Color.FromUInt32(0xffff8c00); } |
|||
} |
|||
|
|||
public static Color DarkOrchid |
|||
{ |
|||
get { return Color.FromUInt32(0xff9932cc); } |
|||
} |
|||
|
|||
public static Color DarkRed |
|||
{ |
|||
get { return Color.FromUInt32(0xff8b0000); } |
|||
} |
|||
|
|||
public static Color DarkSalmon |
|||
{ |
|||
get { return Color.FromUInt32(0xffe9967a); } |
|||
} |
|||
|
|||
public static Color DarkSeaGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff8fbc8f); } |
|||
} |
|||
|
|||
public static Color DarkSlateBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff483d8b); } |
|||
} |
|||
|
|||
public static Color DarkSlateGray |
|||
{ |
|||
get { return Color.FromUInt32(0xff2f4f4f); } |
|||
} |
|||
|
|||
public static Color DarkTurquoise |
|||
{ |
|||
get { return Color.FromUInt32(0xff00ced1); } |
|||
} |
|||
|
|||
public static Color DarkViolet |
|||
{ |
|||
get { return Color.FromUInt32(0xff9400d3); } |
|||
} |
|||
|
|||
public static Color DeepPink |
|||
{ |
|||
get { return Color.FromUInt32(0xffff1493); } |
|||
} |
|||
|
|||
public static Color DeepSkyBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff00bfff); } |
|||
} |
|||
|
|||
public static Color DimGray |
|||
{ |
|||
get { return Color.FromUInt32(0xff696969); } |
|||
} |
|||
|
|||
public static Color DodgerBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff1e90ff); } |
|||
} |
|||
|
|||
public static Color Firebrick |
|||
{ |
|||
get { return Color.FromUInt32(0xffb22222); } |
|||
} |
|||
|
|||
public static Color FloralWhite |
|||
{ |
|||
get { return Color.FromUInt32(0xfffffaf0); } |
|||
} |
|||
|
|||
public static Color ForestGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff228b22); } |
|||
} |
|||
|
|||
public static Color Fuchsia |
|||
{ |
|||
get { return Color.FromUInt32(0xffff00ff); } |
|||
} |
|||
|
|||
public static Color Gainsboro |
|||
{ |
|||
get { return Color.FromUInt32(0xffdcdcdc); } |
|||
} |
|||
|
|||
public static Color GhostWhite |
|||
{ |
|||
get { return Color.FromUInt32(0xfff8f8ff); } |
|||
} |
|||
|
|||
public static Color Gold |
|||
{ |
|||
get { return Color.FromUInt32(0xffffd700); } |
|||
} |
|||
|
|||
public static Color Goldenrod |
|||
{ |
|||
get { return Color.FromUInt32(0xffdaa520); } |
|||
} |
|||
|
|||
public static Color Gray |
|||
{ |
|||
get { return Color.FromUInt32(0xff808080); } |
|||
} |
|||
|
|||
public static Color Green |
|||
{ |
|||
get { return Color.FromUInt32(0xff008000); } |
|||
} |
|||
|
|||
public static Color GreenYellow |
|||
{ |
|||
get { return Color.FromUInt32(0xffadff2f); } |
|||
} |
|||
|
|||
public static Color Honeydew |
|||
{ |
|||
get { return Color.FromUInt32(0xfff0fff0); } |
|||
} |
|||
|
|||
public static Color HotPink |
|||
{ |
|||
get { return Color.FromUInt32(0xffff69b4); } |
|||
} |
|||
|
|||
public static Color IndianRed |
|||
{ |
|||
get { return Color.FromUInt32(0xffcd5c5c); } |
|||
} |
|||
|
|||
public static Color Indigo |
|||
{ |
|||
get { return Color.FromUInt32(0xff4b0082); } |
|||
} |
|||
|
|||
public static Color Ivory |
|||
{ |
|||
get { return Color.FromUInt32(0xfffffff0); } |
|||
} |
|||
|
|||
public static Color Khaki |
|||
{ |
|||
get { return Color.FromUInt32(0xfff0e68c); } |
|||
} |
|||
|
|||
public static Color Lavender |
|||
{ |
|||
get { return Color.FromUInt32(0xffe6e6fa); } |
|||
} |
|||
|
|||
public static Color LavenderBlush |
|||
{ |
|||
get { return Color.FromUInt32(0xfffff0f5); } |
|||
} |
|||
|
|||
public static Color LawnGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff7cfc00); } |
|||
} |
|||
|
|||
public static Color LemonChiffon |
|||
{ |
|||
get { return Color.FromUInt32(0xfffffacd); } |
|||
} |
|||
|
|||
public static Color LightBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xffadd8e6); } |
|||
} |
|||
|
|||
public static Color LightCoral |
|||
{ |
|||
get { return Color.FromUInt32(0xfff08080); } |
|||
} |
|||
|
|||
public static Color LightCyan |
|||
{ |
|||
get { return Color.FromUInt32(0xffe0ffff); } |
|||
} |
|||
|
|||
public static Color LightGoldenrodYellow |
|||
{ |
|||
get { return Color.FromUInt32(0xfffafad2); } |
|||
} |
|||
|
|||
public static Color LightGray |
|||
{ |
|||
get { return Color.FromUInt32(0xffd3d3d3); } |
|||
} |
|||
|
|||
public static Color LightGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff90ee90); } |
|||
} |
|||
|
|||
public static Color LightPink |
|||
{ |
|||
get { return Color.FromUInt32(0xffffb6c1); } |
|||
} |
|||
|
|||
public static Color LightSalmon |
|||
{ |
|||
get { return Color.FromUInt32(0xffffa07a); } |
|||
} |
|||
|
|||
public static Color LightSeaGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff20b2aa); } |
|||
} |
|||
|
|||
public static Color LightSkyBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff87cefa); } |
|||
} |
|||
|
|||
public static Color LightSlateGray |
|||
{ |
|||
get { return Color.FromUInt32(0xff778899); } |
|||
} |
|||
|
|||
public static Color LightSteelBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xffb0c4de); } |
|||
} |
|||
|
|||
public static Color LightYellow |
|||
{ |
|||
get { return Color.FromUInt32(0xffffffe0); } |
|||
} |
|||
|
|||
public static Color Lime |
|||
{ |
|||
get { return Color.FromUInt32(0xff00ff00); } |
|||
} |
|||
|
|||
public static Color LimeGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff32cd32); } |
|||
} |
|||
|
|||
public static Color Linen |
|||
{ |
|||
get { return Color.FromUInt32(0xfffaf0e6); } |
|||
} |
|||
|
|||
public static Color Magenta |
|||
{ |
|||
get { return Color.FromUInt32(0xffff00ff); } |
|||
} |
|||
|
|||
public static Color Maroon |
|||
{ |
|||
get { return Color.FromUInt32(0xff800000); } |
|||
} |
|||
|
|||
public static Color MediumAquamarine |
|||
{ |
|||
get { return Color.FromUInt32(0xff66cdaa); } |
|||
} |
|||
|
|||
public static Color MediumBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff0000cd); } |
|||
} |
|||
|
|||
public static Color MediumOrchid |
|||
{ |
|||
get { return Color.FromUInt32(0xffba55d3); } |
|||
} |
|||
|
|||
public static Color MediumPurple |
|||
{ |
|||
get { return Color.FromUInt32(0xff9370db); } |
|||
} |
|||
|
|||
public static Color MediumSeaGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff3cb371); } |
|||
} |
|||
|
|||
public static Color MediumSlateBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff7b68ee); } |
|||
} |
|||
|
|||
public static Color MediumSpringGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff00fa9a); } |
|||
} |
|||
|
|||
public static Color MediumTurquoise |
|||
{ |
|||
get { return Color.FromUInt32(0xff48d1cc); } |
|||
} |
|||
|
|||
public static Color MediumVioletRed |
|||
{ |
|||
get { return Color.FromUInt32(0xffc71585); } |
|||
} |
|||
|
|||
public static Color MidnightBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff191970); } |
|||
} |
|||
|
|||
public static Color MintCream |
|||
{ |
|||
get { return Color.FromUInt32(0xfff5fffa); } |
|||
} |
|||
|
|||
public static Color MistyRose |
|||
{ |
|||
get { return Color.FromUInt32(0xffffe4e1); } |
|||
} |
|||
|
|||
public static Color Moccasin |
|||
{ |
|||
get { return Color.FromUInt32(0xffffe4b5); } |
|||
} |
|||
|
|||
public static Color NavajoWhite |
|||
{ |
|||
get { return Color.FromUInt32(0xffffdead); } |
|||
} |
|||
|
|||
public static Color Navy |
|||
{ |
|||
get { return Color.FromUInt32(0xff000080); } |
|||
} |
|||
|
|||
public static Color OldLace |
|||
{ |
|||
get { return Color.FromUInt32(0xfffdf5e6); } |
|||
} |
|||
|
|||
public static Color Olive |
|||
{ |
|||
get { return Color.FromUInt32(0xff808000); } |
|||
} |
|||
|
|||
public static Color OliveDrab |
|||
{ |
|||
get { return Color.FromUInt32(0xff6b8e23); } |
|||
} |
|||
|
|||
public static Color Orange |
|||
{ |
|||
get { return Color.FromUInt32(0xffffa500); } |
|||
} |
|||
|
|||
public static Color OrangeRed |
|||
{ |
|||
get { return Color.FromUInt32(0xffff4500); } |
|||
} |
|||
|
|||
public static Color Orchid |
|||
{ |
|||
get { return Color.FromUInt32(0xffda70d6); } |
|||
} |
|||
|
|||
public static Color PaleGoldenrod |
|||
{ |
|||
get { return Color.FromUInt32(0xffeee8aa); } |
|||
} |
|||
|
|||
public static Color PaleGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff98fb98); } |
|||
} |
|||
|
|||
public static Color PaleTurquoise |
|||
{ |
|||
get { return Color.FromUInt32(0xffafeeee); } |
|||
} |
|||
|
|||
public static Color PaleVioletRed |
|||
{ |
|||
get { return Color.FromUInt32(0xffdb7093); } |
|||
} |
|||
|
|||
public static Color PapayaWhip |
|||
{ |
|||
get { return Color.FromUInt32(0xffffefd5); } |
|||
} |
|||
|
|||
public static Color PeachPuff |
|||
{ |
|||
get { return Color.FromUInt32(0xffffdab9); } |
|||
} |
|||
|
|||
public static Color Peru |
|||
{ |
|||
get { return Color.FromUInt32(0xffcd853f); } |
|||
} |
|||
|
|||
public static Color Pink |
|||
{ |
|||
get { return Color.FromUInt32(0xffffc0cb); } |
|||
} |
|||
|
|||
public static Color Plum |
|||
{ |
|||
get { return Color.FromUInt32(0xffdda0dd); } |
|||
} |
|||
|
|||
public static Color PowderBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xffb0e0e6); } |
|||
} |
|||
|
|||
public static Color Purple |
|||
{ |
|||
get { return Color.FromUInt32(0xff800080); } |
|||
} |
|||
|
|||
public static Color Red |
|||
{ |
|||
get { return Color.FromUInt32(0xffff0000); } |
|||
} |
|||
|
|||
public static Color RosyBrown |
|||
{ |
|||
get { return Color.FromUInt32(0xffbc8f8f); } |
|||
} |
|||
|
|||
public static Color RoyalBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff4169e1); } |
|||
} |
|||
|
|||
public static Color SaddleBrown |
|||
{ |
|||
get { return Color.FromUInt32(0xff8b4513); } |
|||
} |
|||
|
|||
public static Color Salmon |
|||
{ |
|||
get { return Color.FromUInt32(0xfffa8072); } |
|||
} |
|||
|
|||
public static Color SandyBrown |
|||
{ |
|||
get { return Color.FromUInt32(0xfff4a460); } |
|||
} |
|||
|
|||
public static Color SeaGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff2e8b57); } |
|||
} |
|||
|
|||
public static Color SeaShell |
|||
{ |
|||
get { return Color.FromUInt32(0xfffff5ee); } |
|||
} |
|||
|
|||
public static Color Sienna |
|||
{ |
|||
get { return Color.FromUInt32(0xffa0522d); } |
|||
} |
|||
|
|||
public static Color Silver |
|||
{ |
|||
get { return Color.FromUInt32(0xffc0c0c0); } |
|||
} |
|||
|
|||
public static Color SkyBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff87ceeb); } |
|||
} |
|||
|
|||
public static Color SlateBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff6a5acd); } |
|||
} |
|||
|
|||
public static Color SlateGray |
|||
{ |
|||
get { return Color.FromUInt32(0xff708090); } |
|||
} |
|||
|
|||
public static Color Snow |
|||
{ |
|||
get { return Color.FromUInt32(0xfffffafa); } |
|||
} |
|||
|
|||
public static Color SpringGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff00ff7f); } |
|||
} |
|||
|
|||
public static Color SteelBlue |
|||
{ |
|||
get { return Color.FromUInt32(0xff4682b4); } |
|||
} |
|||
|
|||
public static Color Tan |
|||
{ |
|||
get { return Color.FromUInt32(0xffd2b48c); } |
|||
} |
|||
|
|||
public static Color Teal |
|||
{ |
|||
get { return Color.FromUInt32(0xff008080); } |
|||
} |
|||
|
|||
public static Color Thistle |
|||
{ |
|||
get { return Color.FromUInt32(0xffd8bfd8); } |
|||
} |
|||
|
|||
public static Color Tomato |
|||
{ |
|||
get { return Color.FromUInt32(0xffff6347); } |
|||
} |
|||
|
|||
public static Color Transparent |
|||
{ |
|||
get { return Color.FromUInt32(0x00ffffff); } |
|||
} |
|||
|
|||
public static Color Turquoise |
|||
{ |
|||
get { return Color.FromUInt32(0xff40e0d0); } |
|||
} |
|||
|
|||
public static Color Violet |
|||
{ |
|||
get { return Color.FromUInt32(0xffee82ee); } |
|||
} |
|||
|
|||
public static Color Wheat |
|||
{ |
|||
get { return Color.FromUInt32(0xfff5deb3); } |
|||
} |
|||
|
|||
public static Color White |
|||
{ |
|||
get { return Color.FromUInt32(0xffffffff); } |
|||
} |
|||
|
|||
public static Color WhiteSmoke |
|||
{ |
|||
get { return Color.FromUInt32(0xfff5f5f5); } |
|||
} |
|||
|
|||
public static Color Yellow |
|||
{ |
|||
get { return Color.FromUInt32(0xffffff00); } |
|||
} |
|||
|
|||
public static Color YellowGreen |
|||
{ |
|||
get { return Color.FromUInt32(0xff9acd32); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="FormattedText.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class FormattedText |
|||
{ |
|||
public string FontFamilyName { get; set; } |
|||
|
|||
public double FontSize { get; set; } |
|||
|
|||
public string Text { get; set; } |
|||
|
|||
public double[] GetLineHeights(Size constraint) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
return factory.TextService.GetLineHeights(this, constraint); |
|||
} |
|||
|
|||
public Size Measure(Size constraint) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
return factory.TextService.Measure(this, constraint); |
|||
} |
|||
} |
|||
} |
|||
@ -1,29 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Geometry.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using Perspex.Platform; |
|||
|
|||
public abstract class Geometry |
|||
{ |
|||
public abstract Rect Bounds |
|||
{ |
|||
get; |
|||
} |
|||
|
|||
public IGeometryImpl PlatformImpl |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
|
|||
public Rect GetRenderBounds(double strokeThickness) |
|||
{ |
|||
return this.PlatformImpl.GetRenderBounds(strokeThickness); |
|||
} |
|||
} |
|||
} |
|||
@ -1,67 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IDrawingContext.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Media.Imaging; |
|||
|
|||
|
|||
/// <summary>
|
|||
/// Defines the interface through which drawing occurs.
|
|||
/// </summary>
|
|||
public interface IDrawingContext : IDisposable |
|||
{ |
|||
Matrix CurrentTransform { get; } |
|||
|
|||
void DrawImage(Bitmap source, double opacity, Rect sourceRect, Rect destRect); |
|||
|
|||
/// <summary>
|
|||
/// Draws a line.
|
|||
/// </summary>
|
|||
/// <param name="pen">The stroke pen.</param>
|
|||
/// <param name="p1">The first point of the line.</param>
|
|||
/// <param name="p1">The second point of the line.</param>
|
|||
void DrawLine(Pen pen, Point p1, Point p2); |
|||
|
|||
/// <summary>
|
|||
/// Draws a geometry.
|
|||
/// </summary>
|
|||
/// <param name="brush">The fill brush.</param>
|
|||
/// <param name="pen">The stroke pen.</param>
|
|||
/// <param name="geometry">The geometry.</param>
|
|||
void DrawGeometry(Brush brush, Pen pen, Geometry geometry); |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of a rectangle.
|
|||
/// </summary>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="rect">The rectangle bounds.</param>
|
|||
void DrawRectange(Pen pen, Rect rect); |
|||
|
|||
/// <summary>
|
|||
/// Draws text.
|
|||
/// </summary>
|
|||
/// <param name="foreground">The foreground brush.</param>
|
|||
/// <param name="rect">The bounding rectangle.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
void DrawText(Brush foreground, Rect rect, FormattedText text); |
|||
|
|||
/// <summary>
|
|||
/// Draws a filled rectangle.
|
|||
/// </summary>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="rect">The rectangle bounds.</param>
|
|||
void FillRectange(Brush brush, Rect rect); |
|||
|
|||
/// <summary>
|
|||
/// Pushes a matrix transformation.
|
|||
/// </summary>
|
|||
/// <param name="matrix">The matrix</param>
|
|||
/// <returns>A disposable used to undo the transformation.</returns>
|
|||
IDisposable PushTransform(Matrix matrix); |
|||
} |
|||
} |
|||
@ -1,52 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Bitmap.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media.Imaging |
|||
{ |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class Bitmap : IBitmap |
|||
{ |
|||
public Bitmap(string fileName) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
this.PlatformImpl = factory.LoadBitmap(fileName); |
|||
} |
|||
|
|||
public Bitmap(int width, int height) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
this.PlatformImpl = factory.CreateBitmap(width, height); |
|||
} |
|||
|
|||
protected Bitmap(IBitmapImpl impl) |
|||
{ |
|||
this.PlatformImpl = impl; |
|||
} |
|||
|
|||
public int PixelWidth |
|||
{ |
|||
get { return this.PlatformImpl.PixelWidth; } |
|||
} |
|||
|
|||
public int PixelHeight |
|||
{ |
|||
get { return this.PlatformImpl.PixelHeight; } |
|||
} |
|||
|
|||
public IBitmapImpl PlatformImpl |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public void Save(string fileName) |
|||
{ |
|||
this.PlatformImpl.Save(fileName); |
|||
} |
|||
} |
|||
} |
|||
@ -1,17 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IBitmap.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media.Imaging |
|||
{ |
|||
public interface IBitmap |
|||
{ |
|||
int PixelHeight { get; } |
|||
|
|||
int PixelWidth { get; } |
|||
|
|||
void Save(string fileName); |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RenderTargetBitmap.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media.Imaging |
|||
{ |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class RenderTargetBitmap : Bitmap |
|||
{ |
|||
public RenderTargetBitmap(int width, int height) |
|||
: base(CreateImpl(width, height)) |
|||
{ |
|||
} |
|||
|
|||
public new IRenderTargetBitmapImpl PlatformImpl |
|||
{ |
|||
get { return (IRenderTargetBitmapImpl)base.PlatformImpl; } |
|||
} |
|||
|
|||
public void Render(IVisual visual) |
|||
{ |
|||
this.PlatformImpl.Render(visual); |
|||
} |
|||
|
|||
private static IBitmapImpl CreateImpl(int width, int height) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
return factory.CreateRenderTargetBitmap(width, height); |
|||
} |
|||
} |
|||
} |
|||
@ -1,182 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Matrix.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
|
|||
public struct Matrix |
|||
{ |
|||
private double m11; |
|||
private double m12; |
|||
private double m21; |
|||
private double m22; |
|||
private double offsetX; |
|||
private double offsetY; |
|||
|
|||
public Matrix( |
|||
double m11, |
|||
double m12, |
|||
double m21, |
|||
double m22, |
|||
double offsetX, |
|||
double offsetY) |
|||
{ |
|||
this.m11 = m11; |
|||
this.m12 = m12; |
|||
this.m21 = m21; |
|||
this.m22 = m22; |
|||
this.offsetX = offsetX; |
|||
this.offsetY = offsetY; |
|||
} |
|||
|
|||
public static Matrix Identity |
|||
{ |
|||
get { return new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); } |
|||
} |
|||
|
|||
public double Determinant |
|||
{ |
|||
get { return (this.m11 * this.m22) - (this.m12 * this.m21); } |
|||
} |
|||
|
|||
public bool HasInverse |
|||
{ |
|||
get { return this.Determinant != 0; } |
|||
} |
|||
|
|||
public bool IsIdentity |
|||
{ |
|||
get { return this.Equals(Matrix.Identity); } |
|||
} |
|||
|
|||
public double M11 |
|||
{ |
|||
get { return this.m11; } |
|||
} |
|||
|
|||
public double M12 |
|||
{ |
|||
get { return this.m12; } |
|||
} |
|||
|
|||
public double M21 |
|||
{ |
|||
get { return this.m21; } |
|||
} |
|||
|
|||
public double M22 |
|||
{ |
|||
get { return this.m22; } |
|||
} |
|||
|
|||
public double OffsetX |
|||
{ |
|||
get { return this.offsetX; } |
|||
} |
|||
|
|||
public double OffsetY |
|||
{ |
|||
get { return this.offsetY; } |
|||
} |
|||
|
|||
public static Matrix operator *(Matrix left, Matrix right) |
|||
{ |
|||
return new Matrix( |
|||
(left.M11 * right.M11) + (left.M12 * right.M21), |
|||
(left.M11 * right.M12) + (left.M12 * right.M22), |
|||
(left.M21 * right.M11) + (left.M22 * right.M21), |
|||
(left.M21 * right.M12) + (left.M22 * right.M22), |
|||
(left.offsetX * right.M11) + (left.offsetY * right.M21) + right.offsetX, |
|||
(left.offsetX * right.M12) + (left.offsetY * right.M22) + right.offsetY); |
|||
} |
|||
|
|||
public static bool Equals(Matrix matrix1, Matrix matrix2) |
|||
{ |
|||
return matrix1.Equals(matrix2); |
|||
} |
|||
|
|||
public static Matrix Rotation(double angle) |
|||
{ |
|||
double cos = Math.Cos(angle); |
|||
double sin = Math.Sin(angle); |
|||
return new Matrix(cos, sin, -sin, cos, 0, 0); |
|||
} |
|||
|
|||
public static Matrix Translation(Vector v) |
|||
{ |
|||
return Translation(v.X, v.Y); |
|||
} |
|||
|
|||
public static Matrix Translation(double x, double y) |
|||
{ |
|||
return new Matrix(1.0, 0.0, 0.0, 1.0, x, y); |
|||
} |
|||
|
|||
public static double ToRadians(double angle) |
|||
{ |
|||
return angle * 0.0174532925; |
|||
} |
|||
|
|||
public static Matrix operator -(Matrix matrix) |
|||
{ |
|||
return matrix.Invert(); |
|||
} |
|||
|
|||
public static bool operator ==(Matrix matrix1, Matrix matrix2) |
|||
{ |
|||
return matrix1.Equals(matrix2); |
|||
} |
|||
|
|||
public static bool operator !=(Matrix matrix1, Matrix matrix2) |
|||
{ |
|||
return !matrix1.Equals(matrix2); |
|||
} |
|||
|
|||
public bool Equals(Matrix value) |
|||
{ |
|||
return this.m11 == value.M11 && |
|||
this.m12 == value.M12 && |
|||
this.m21 == value.M21 && |
|||
this.m22 == value.M22 && |
|||
this.offsetX == value.OffsetX && |
|||
this.offsetY == value.OffsetY; |
|||
} |
|||
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (!(o is Matrix)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this.Equals((Matrix)o); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public Matrix Invert() |
|||
{ |
|||
if (!this.HasInverse) |
|||
{ |
|||
throw new InvalidOperationException("Transform is not invertible."); |
|||
} |
|||
|
|||
double d = this.Determinant; |
|||
|
|||
return new Matrix( |
|||
this.m22 / d, |
|||
-this.m12 / d, |
|||
-this.m21 / d, |
|||
this.m11 / d, |
|||
((this.m21 * this.offsetY) - (this.m22 * this.offsetX)) / d, |
|||
((this.m12 * this.offsetX) - (this.m11 * this.offsetY)) / d); |
|||
} |
|||
} |
|||
} |
|||
@ -1,289 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PathMarkupParser.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Text; |
|||
|
|||
public class PathMarkupParser |
|||
{ |
|||
private static readonly Dictionary<char, Command> Commands = new Dictionary<char, Command> |
|||
{ |
|||
{ 'F', Command.FillRule }, |
|||
{ 'f', Command.FillRule }, |
|||
{ 'M', Command.Move }, |
|||
{ 'm', Command.MoveRelative }, |
|||
{ 'L', Command.Line }, |
|||
{ 'l', Command.LineRelative }, |
|||
{ 'H', Command.HorizontalLine }, |
|||
{ 'h', Command.HorizontalLineRelative }, |
|||
{ 'V', Command.VerticalLine }, |
|||
{ 'v', Command.VerticalLineRelative }, |
|||
{ 'C', Command.CubicBezierCurve }, |
|||
{ 'c', Command.CubicBezierCurveRelative }, |
|||
{ 'Z', Command.Close }, |
|||
{ 'z', Command.Close }, |
|||
}; |
|||
|
|||
private StreamGeometry geometry; |
|||
|
|||
private StreamGeometryContext context; |
|||
|
|||
public PathMarkupParser(StreamGeometry geometry, StreamGeometryContext context) |
|||
{ |
|||
this.geometry = geometry; |
|||
this.context = context; |
|||
} |
|||
|
|||
private enum Command |
|||
{ |
|||
None, |
|||
FillRule, |
|||
Move, |
|||
MoveRelative, |
|||
Line, |
|||
LineRelative, |
|||
HorizontalLine, |
|||
HorizontalLineRelative, |
|||
VerticalLine, |
|||
VerticalLineRelative, |
|||
CubicBezierCurve, |
|||
CubicBezierCurveRelative, |
|||
Close, |
|||
Eof, |
|||
} |
|||
|
|||
public void Parse(string s) |
|||
{ |
|||
bool openFigure = false; |
|||
|
|||
using (StringReader reader = new StringReader(s)) |
|||
{ |
|||
Command lastCommand = Command.None; |
|||
Command command; |
|||
Point point = new Point(); |
|||
|
|||
while ((command = ReadCommand(reader, lastCommand)) != Command.Eof) |
|||
{ |
|||
switch (command) |
|||
{ |
|||
case Command.FillRule: |
|||
// TODO: Implement.
|
|||
reader.Read(); |
|||
break; |
|||
|
|||
case Command.Move: |
|||
case Command.MoveRelative: |
|||
if (openFigure) |
|||
{ |
|||
this.context.EndFigure(false); |
|||
} |
|||
|
|||
point = ReadPoint(reader); |
|||
this.context.BeginFigure(point, true); |
|||
openFigure = true; |
|||
break; |
|||
|
|||
case Command.Line: |
|||
point = ReadPoint(reader); |
|||
this.context.LineTo(point); |
|||
break; |
|||
|
|||
case Command.LineRelative: |
|||
point = ReadRelativePoint(reader, point); |
|||
this.context.LineTo(point); |
|||
break; |
|||
|
|||
////case Command.HorizontalLine:
|
|||
//// point.X = ReadDouble(reader);
|
|||
//// this.context.LineTo(point, true, false);
|
|||
//// break;
|
|||
|
|||
////case Command.HorizontalLineRelative:
|
|||
//// point.X += ReadDouble(reader);
|
|||
//// this.context.LineTo(point, true, false);
|
|||
//// break;
|
|||
|
|||
////case Command.VerticalLine:
|
|||
//// point.Y = ReadDouble(reader);
|
|||
//// this.context.LineTo(point, true, false);
|
|||
//// break;
|
|||
|
|||
////case Command.VerticalLineRelative:
|
|||
//// point.Y += ReadDouble(reader);
|
|||
//// this.context.LineTo(point, true, false);
|
|||
//// break;
|
|||
|
|||
////case Command.CubicBezierCurve:
|
|||
////{
|
|||
//// Point point1 = ReadPoint(reader);
|
|||
//// Point point2 = ReadPoint(reader);
|
|||
//// point = ReadPoint(reader);
|
|||
//// this.context.BezierTo(point1, point2, point, true, false);
|
|||
//// break;
|
|||
////}
|
|||
|
|||
case Command.Close: |
|||
this.context.EndFigure(true); |
|||
openFigure = false; |
|||
break; |
|||
|
|||
default: |
|||
throw new NotSupportedException("Unsupported command"); |
|||
} |
|||
|
|||
lastCommand = command; |
|||
} |
|||
|
|||
if (openFigure) |
|||
{ |
|||
this.context.EndFigure(false); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static Command ReadCommand(StringReader reader, Command lastCommand) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
|
|||
int i = reader.Peek(); |
|||
|
|||
if (i == -1) |
|||
{ |
|||
return Command.Eof; |
|||
} |
|||
else |
|||
{ |
|||
char c = (char)i; |
|||
Command command = Command.None; |
|||
|
|||
if (!Commands.TryGetValue(c, out command)) |
|||
{ |
|||
if ((char.IsDigit(c) || c == '.' || c == '+' || c == '-') && |
|||
(lastCommand != Command.None)) |
|||
{ |
|||
return lastCommand; |
|||
} |
|||
else |
|||
{ |
|||
throw new InvalidDataException("Unexpected path command '" + c + "'."); |
|||
} |
|||
} |
|||
|
|||
reader.Read(); |
|||
return command; |
|||
} |
|||
} |
|||
|
|||
private static double ReadDouble(TextReader reader) |
|||
{ |
|||
// TODO: Handle Infinity, NaN and scientific notation.
|
|||
StringBuilder b = new StringBuilder(); |
|||
bool readSign = false; |
|||
bool readPoint = false; |
|||
bool readExponent = false; |
|||
int i; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = char.ToUpperInvariant((char)i); |
|||
|
|||
if (((c == '+' || c == '-') && !readSign) || |
|||
(c == '.' && !readPoint) || |
|||
(c == 'E' && !readExponent) || |
|||
char.IsDigit(c)) |
|||
{ |
|||
b.Append(c); |
|||
reader.Read(); |
|||
readSign = c == '+' || c == '-'; |
|||
readPoint = c == '.'; |
|||
|
|||
if (c == 'E') |
|||
{ |
|||
readSign = false; |
|||
readExponent = c == 'E'; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return double.Parse(b.ToString()); |
|||
} |
|||
|
|||
private static Point ReadPoint(StringReader reader) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
double x = ReadDouble(reader); |
|||
ReadSeparator(reader); |
|||
double y = ReadDouble(reader); |
|||
return new Point(x, y); |
|||
} |
|||
|
|||
private static Point ReadRelativePoint(StringReader reader, Point lastPoint) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
double x = ReadDouble(reader); |
|||
ReadSeparator(reader); |
|||
double y = ReadDouble(reader); |
|||
return new Point(lastPoint.X + x, lastPoint.Y + y); |
|||
} |
|||
|
|||
private static void ReadSeparator(StringReader reader) |
|||
{ |
|||
int i; |
|||
bool readComma = false; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = (char)i; |
|||
|
|||
if (char.IsWhiteSpace(c)) |
|||
{ |
|||
reader.Read(); |
|||
} |
|||
else if (c == ',') |
|||
{ |
|||
if (readComma) |
|||
{ |
|||
throw new InvalidDataException("Unexpected ','."); |
|||
} |
|||
|
|||
readComma = true; |
|||
reader.Read(); |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void ReadWhitespace(StringReader reader) |
|||
{ |
|||
int i; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = (char)i; |
|||
|
|||
if (char.IsWhiteSpace(c)) |
|||
{ |
|||
reader.Read(); |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,46 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Pen.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Describes how a stroke is drawn.
|
|||
/// </summary>
|
|||
public class Pen |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Pen"/> class.
|
|||
/// </summary>
|
|||
/// <param name="brush">The brush used to draw.</param>
|
|||
/// <param name="thickness">The stroke thickness.</param>
|
|||
public Pen(Brush brush, double thickness) |
|||
{ |
|||
this.Brush = brush; |
|||
this.Thickness = thickness; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Pen"/> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The stroke color.</param>
|
|||
/// <param name="thickness">The stroke thickness.</param>
|
|||
public Pen(uint color, double thickness) |
|||
{ |
|||
this.Brush = new SolidColorBrush(color); |
|||
this.Thickness = thickness; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the brush used to draw the stroke.
|
|||
/// </summary>
|
|||
public Brush Brush { get; private set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the stroke thickness.
|
|||
/// </summary>
|
|||
public double Thickness { get; private set; } |
|||
} |
|||
} |
|||
@ -1,36 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RectangleGeometry.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class RectangleGeometry : Geometry |
|||
{ |
|||
public RectangleGeometry(Rect rect) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
IStreamGeometryImpl impl = factory.CreateStreamGeometry(); |
|||
|
|||
using (IStreamGeometryContextImpl context = impl.Open()) |
|||
{ |
|||
context.BeginFigure(rect.TopLeft, true); |
|||
context.LineTo(rect.TopRight); |
|||
context.LineTo(rect.BottomRight); |
|||
context.LineTo(rect.BottomLeft); |
|||
context.EndFigure(true); |
|||
} |
|||
|
|||
this.PlatformImpl = impl; |
|||
} |
|||
|
|||
public override Rect Bounds |
|||
{ |
|||
get { return this.PlatformImpl.Bounds; } |
|||
} |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RotateTransform.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public class RotateTransform : Transform |
|||
{ |
|||
public static readonly PerspexProperty<double> AngleProperty = |
|||
PerspexProperty.Register<RotateTransform, double>("Angle"); |
|||
|
|||
public RotateTransform() |
|||
{ |
|||
} |
|||
|
|||
public RotateTransform(double angle) |
|||
{ |
|||
this.Angle = angle; |
|||
} |
|||
|
|||
public double Angle |
|||
{ |
|||
get { return this.GetValue(AngleProperty); } |
|||
set { this.SetValue(AngleProperty, value); } |
|||
} |
|||
|
|||
public override Matrix Value |
|||
{ |
|||
get { return Matrix.Rotation(Matrix.ToRadians(this.Angle)); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,46 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="SolidColorBrush.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Fills an area with a solid color.
|
|||
/// </summary>
|
|||
public class SolidColorBrush : Brush |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color to use.</param>
|
|||
public SolidColorBrush(Color color) |
|||
{ |
|||
this.Color = color; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color to use.</param>
|
|||
public SolidColorBrush(uint color) |
|||
: this(Color.FromUInt32(color)) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the color of the brush.
|
|||
/// </summary>
|
|||
public Color Color |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return this.Color.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="StreamGeometry.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class StreamGeometry : Geometry |
|||
{ |
|||
public StreamGeometry() |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
this.PlatformImpl = factory.CreateStreamGeometry(); |
|||
} |
|||
|
|||
public override Rect Bounds |
|||
{ |
|||
get { return this.PlatformImpl.Bounds; } |
|||
} |
|||
|
|||
public static StreamGeometry Parse(string s) |
|||
{ |
|||
StreamGeometry result = new StreamGeometry(); |
|||
|
|||
using (StreamGeometryContext ctx = result.Open()) |
|||
{ |
|||
PathMarkupParser parser = new PathMarkupParser(result, ctx); |
|||
parser.Parse(s); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
public StreamGeometryContext Open() |
|||
{ |
|||
return new StreamGeometryContext(((IStreamGeometryImpl)this.PlatformImpl).Open()); |
|||
} |
|||
} |
|||
} |
|||
@ -1,41 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="StreamGeometryContext.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Platform; |
|||
|
|||
public class StreamGeometryContext : IDisposable |
|||
{ |
|||
private IStreamGeometryContextImpl impl; |
|||
|
|||
public StreamGeometryContext(IStreamGeometryContextImpl impl) |
|||
{ |
|||
this.impl = impl; |
|||
} |
|||
|
|||
public void BeginFigure(Point startPoint, bool isFilled) |
|||
{ |
|||
this.impl.BeginFigure(startPoint, isFilled); |
|||
} |
|||
|
|||
public void LineTo(Point point) |
|||
{ |
|||
this.impl.LineTo(point); |
|||
} |
|||
|
|||
public void EndFigure(bool isClosed) |
|||
{ |
|||
this.impl.EndFigure(isClosed); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
this.impl.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Stretch.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public enum Stretch |
|||
{ |
|||
None, |
|||
Fill, |
|||
Uniform, |
|||
UniformToFill, |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Transform.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public abstract class Transform : PerspexObject |
|||
{ |
|||
public abstract Matrix Value { get; } |
|||
} |
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Origin.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
public enum OriginUnit |
|||
{ |
|||
Percent, |
|||
Pixels, |
|||
} |
|||
|
|||
public struct Origin |
|||
{ |
|||
public static readonly Origin Default = new Origin(0.5, 0.5, OriginUnit.Percent); |
|||
|
|||
private Point point; |
|||
|
|||
private OriginUnit unit; |
|||
|
|||
public Origin(double x, double y, OriginUnit unit) |
|||
: this(new Point(x, y), unit) |
|||
{ |
|||
} |
|||
|
|||
public Origin(Point point, OriginUnit unit) |
|||
{ |
|||
this.point = point; |
|||
this.unit = unit; |
|||
} |
|||
|
|||
public Point Point |
|||
{ |
|||
get { return this.point; } |
|||
} |
|||
|
|||
public OriginUnit Unit |
|||
{ |
|||
get { return this.unit; } |
|||
} |
|||
|
|||
public Point ToPixels(Size size) |
|||
{ |
|||
return this.unit == OriginUnit.Pixels ? |
|||
point : |
|||
new Point(point.X * size.Width, point.Y * size.Height); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue