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