Browse Source

Merge remote-tracking branch 'origin/master' into deck

pull/58/head
Steven Kirk 11 years ago
parent
commit
40459f30f2
  1. 16
      Perspex.Base/Binding.cs
  2. 13
      Perspex.Base/IObservableDescription.cs
  3. 2
      Perspex.Base/Perspex.Base.csproj
  4. 36
      Perspex.Base/PerspexObject.cs
  5. 3
      Perspex.Base/PriorityBindingEntry.cs
  6. 35
      Perspex.Base/Reactive/PerspexObservable.cs
  7. 13
      Perspex.Controls/Primitives/ScrollBar.cs
  8. 13
      Perspex.Diagnostics/DevTools.cs
  9. 33
      Perspex.Input/KeyboardDevice.cs
  10. 6
      Perspex.Styling/StyleBinding.cs
  11. 2
      Perspex.Themes.Default/ScrollBarStyle.cs
  12. 16
      Perspex.Themes.Default/ScrollViewerStyle.cs
  13. 2
      Perspex.Themes.Default/TextBoxStyle.cs

16
Perspex.Base/Binding.cs

@ -7,7 +7,7 @@
namespace Perspex
{
using System;
using System.Reactive.Linq;
using System.Reactive;
public enum BindingMode
{
@ -18,7 +18,7 @@ namespace Perspex
OneWayToSource,
}
public class Binding : IObservable<object>
public class Binding : ObservableBase<object>, IDescription
{
public BindingMode Mode
{
@ -44,6 +44,8 @@ namespace Perspex
set;
}
public string Description => string.Format("{0}.{1}", this.Source?.GetType().Name, this.Property.Name);
public static Binding operator !(Binding binding)
{
return binding.WithMode(BindingMode.TwoWay);
@ -54,11 +56,6 @@ namespace Perspex
return binding.WithMode(BindingMode.TwoWay);
}
public IDisposable Subscribe(IObserver<object> observer)
{
return this.Source.GetObservable(this.Property).Subscribe(observer);
}
public Binding WithMode(BindingMode mode)
{
this.Mode = mode;
@ -70,5 +67,10 @@ namespace Perspex
this.Priority = priority;
return this;
}
protected override IDisposable SubscribeCore(IObserver<object> observer)
{
return this.Source.GetObservable(this.Property).Subscribe(observer);
}
}
}

13
Perspex.Base/IObservableDescription.cs

@ -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; }
}
}

2
Perspex.Base/Perspex.Base.csproj

@ -46,7 +46,6 @@
<Compile Include="Diagnostics\PerspexPropertyValue.cs" />
<Compile Include="IDescription.cs" />
<Compile Include="Collections\PerspexListExtensions.cs" />
<Compile Include="IObservableDescription.cs" />
<Compile Include="Collections\IPerspexReadOnlyList.cs" />
<Compile Include="PerspexObject.cs" />
<Compile Include="PerspexProperty.cs" />
@ -57,6 +56,7 @@
<Compile Include="PriorityLevel.cs" />
<Compile Include="PriorityValue.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Reactive\PerspexObservable.cs" />
<Compile Include="Threading\Dispatcher.cs" />
<Compile Include="Threading\DispatcherPriority.cs" />
<Compile Include="Threading\DispatcherTimer.cs" />

36
Perspex.Base/PerspexObject.cs

@ -15,7 +15,7 @@ namespace Perspex
using Perspex.Diagnostics;
using Splat;
using System.Reactive.Disposables;
using Perspex.Reactive;
/// <summary>
/// The priority of a binding.
@ -306,7 +306,7 @@ namespace Perspex
{
Contract.Requires<NullReferenceException>(property != null);
return Observable.Create<object>(observer =>
return new PerspexObservable<object>(observer =>
{
EventHandler<PerspexPropertyChangedEventArgs> handler = (s, e) =>
{
@ -316,21 +316,23 @@ namespace Perspex
}
};
observer.OnNext(this.GetValue(property));
this.PropertyChanged += handler;
return () =>
return Disposable.Create(() =>
{
this.PropertyChanged -= handler;
};
}).StartWith(this.GetValue(property));
});
}, this.GetObservableDescription(property));
}
/// <summary>
/// Gets an observable for a <see cref="PerspexProperty"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="property"></param>
/// <returns></returns>
/// <typeparam name="T">The property type.</typeparam>
/// <param name="property">The property.</param>
/// <returns>An observable.</returns>
public IObservable<T> GetObservable<T>(PerspexProperty<T> property)
{
Contract.Requires<NullReferenceException>(property != null);
@ -346,7 +348,7 @@ namespace Perspex
/// <returns></returns>
public IObservable<Tuple<T, T>> GetObservableWithHistory<T>(PerspexProperty<T> property)
{
return Observable.Create<Tuple<T, T>>(observer =>
return new PerspexObservable<Tuple<T, T>>(observer =>
{
EventHandler<PerspexPropertyChangedEventArgs> handler = (s, e) =>
{
@ -358,11 +360,11 @@ namespace Perspex
this.PropertyChanged += handler;
return () =>
return Disposable.Create(() =>
{
this.PropertyChanged -= handler;
};
});
});
}, this.GetObservableDescription(property));
}
/// <summary>
@ -759,6 +761,16 @@ namespace Perspex
}
}
/// <summary>
/// Gets a description of a property that van be used in observables.
/// </summary>
/// <param name="property">The property</param>
/// <returns>The description.</returns>
private string GetObservableDescription(PerspexProperty property)
{
return string.Format("{0}.{1}", this.GetType().Name, property.Name);
}
/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>

3
Perspex.Base/PriorityBindingEntry.cs

@ -24,6 +24,8 @@ namespace Perspex
this.Index = index;
}
public IObservable<object> Observable { get; private set; }
/// <summary>
/// Gets a description of the binding.
/// </summary>
@ -67,6 +69,7 @@ namespace Perspex
throw new Exception("PriorityValue.Entry.Start() called more than once.");
}
this.Observable = binding;
this.Value = PerspexProperty.UnsetValue;
if (binding is IDescription)

35
Perspex.Base/Reactive/PerspexObservable.cs

@ -0,0 +1,35 @@
// -----------------------------------------------------------------------
// <copyright file="PerspexObject.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Reactive
{
using System;
using System.Reactive;
using System.Reactive.Disposables;
public sealed class PerspexObservable<T> : ObservableBase<T>, IDescription
{
private readonly Func<IObserver<T>, IDisposable> subscribe;
public string Description { get; }
public PerspexObservable(Func<IObserver<T>, IDisposable> subscribe, string description)
{
if (subscribe == null)
{
throw new ArgumentNullException("subscribe");
}
this.subscribe = subscribe;
this.Description = description;
}
protected override IDisposable SubscribeCore(IObserver<T> observer)
{
return this.subscribe(observer) ?? Disposable.Empty;
}
}
}

13
Perspex.Controls/Primitives/ScrollBar.cs

@ -9,6 +9,7 @@ namespace Perspex.Controls.Primitives
using System;
using System.Reactive;
using System.Reactive.Linq;
using Perspex.Controls.Templates;
public class ScrollBar : TemplatedControl
{
@ -88,6 +89,18 @@ namespace Perspex.Controls.Primitives
return base.MeasureOverride(availableSize);
}
protected override void OnTemplateApplied()
{
base.OnTemplateApplied();
// Binding between this.Value and track.Value must be done explicitly like this rather
// than using standard bindings as it shouldn't be able to to be overridden by binding
// e.g. ScrollBar.Value.
var track = this.GetTemplateChild<Track>("track");
track.GetObservable(ValueProperty).Subscribe(x => this.Value = x);
this.GetObservable(ValueProperty).Subscribe(x => track.Value = x);
}
private bool CalculateIsVisible()
{
switch (this.Visibility)

13
Perspex.Diagnostics/DevTools.cs

@ -70,16 +70,19 @@ namespace Perspex.Diagnostics
}
};
var detailsView = new ContentControl
var detailsView = new ScrollViewer
{
DataTemplates = new DataTemplates
Content = new ContentControl
{
new DataTemplate<ControlDetails>(CreateDetailsView),
},
[!ContentControl.ContentProperty] = treeView[!TreeView.SelectedItemProperty]
DataTemplates = new DataTemplates
{
new DataTemplate<ControlDetails>(CreateDetailsView),
},
[!ContentControl.ContentProperty] = treeView[!TreeView.SelectedItemProperty]
.Where(x => x != null)
.Cast<TreeNode>()
.Select(x => new ControlDetails(x.Control)),
},
[Grid.ColumnProperty] = 2,
};

33
Perspex.Input/KeyboardDevice.cs

@ -48,26 +48,29 @@ namespace Perspex.Input
public void SetFocusedElement(IInputElement element, bool keyboardNavigated)
{
var interactive = this.FocusedElement as IInteractive;
if (interactive != null)
if (element != this.FocusedElement)
{
interactive.RaiseEvent(new RoutedEventArgs
var interactive = this.FocusedElement as IInteractive;
if (interactive != null)
{
RoutedEvent = InputElement.LostFocusEvent,
});
}
interactive.RaiseEvent(new RoutedEventArgs
{
RoutedEvent = InputElement.LostFocusEvent,
});
}
this.FocusedElement = element;
interactive = element as IInteractive;
this.FocusedElement = element;
interactive = element as IInteractive;
if (interactive != null)
{
interactive.RaiseEvent(new GotFocusEventArgs
if (interactive != null)
{
RoutedEvent = InputElement.GotFocusEvent,
KeyboardNavigated = keyboardNavigated,
});
interactive.RaiseEvent(new GotFocusEventArgs
{
RoutedEvent = InputElement.GotFocusEvent,
KeyboardNavigated = keyboardNavigated,
});
}
}
}

6
Perspex.Styling/StyleBinding.cs

@ -7,7 +7,7 @@
namespace Perspex.Styling
{
using System;
using System.Reactive.Subjects;
using System.Reactive;
/// <summary>
/// Provides an observable for a style.
@ -17,7 +17,7 @@ namespace Perspex.Styling
/// a bool. When the activator produces true, this observable will produce <see cref="Value"/>.
/// When the activator produces false it will produce <see cref="PerspexProperty.UnsetValue"/>.
/// </remarks>
internal class StyleBinding : IObservable<object>, IObservableDescription
internal class StyleBinding : ObservableBase<object>, IDescription
{
/// <summary>
/// The activator.
@ -63,7 +63,7 @@ namespace Perspex.Styling
/// </summary>
/// <param name="observer">The observer.</param>
/// <returns>IDisposable object used to unsubscribe from the observable sequence.</returns>
public IDisposable Subscribe(IObserver<object> observer)
protected override IDisposable SubscribeCore(IObserver<object> observer)
{
Contract.Requires<NullReferenceException>(observer != null);
return this.activator.Subscribe(

2
Perspex.Themes.Default/ScrollBarStyle.cs

@ -66,9 +66,9 @@ namespace Perspex.Themes.Default
Background = Brushes.Silver,
Content = new Track
{
Id = "track",
[~Track.MinimumProperty] = control[~ScrollBar.MinimumProperty],
[~Track.MaximumProperty] = control[~ScrollBar.MaximumProperty],
[~~Track.ValueProperty] = control[~ScrollBar.ValueProperty],
[~Track.ViewportSizeProperty] = control[~ScrollBar.ViewportSizeProperty],
[~Track.OrientationProperty] = control[~ScrollBar.OrientationProperty],
Thumb = new Thumb

16
Perspex.Themes.Default/ScrollViewerStyle.cs

@ -31,7 +31,9 @@ namespace Perspex.Themes.Default
private Control Template(ScrollViewer control)
{
return new Grid
ScrollBar vert;
var result = new Grid
{
ColumnDefinitions = new ColumnDefinitions
{
@ -59,23 +61,27 @@ namespace Perspex.Themes.Default
Id = "horizontalScrollBar",
Orientation = Orientation.Horizontal,
[~ScrollBar.MaximumProperty] = control[~ScrollViewer.HorizontalScrollBarMaximumProperty],
[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.HorizontalScrollBarValueProperty],
//[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.HorizontalScrollBarValueProperty],
[~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.HorizontalScrollBarViewportSizeProperty],
[~ScrollBar.VisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty],
[Grid.RowProperty] = 1,
},
new ScrollBar
(vert = new ScrollBar
{
Id = "verticalScrollBar",
Orientation = Orientation.Vertical,
[~ScrollBar.MaximumProperty] = control[~ScrollViewer.VerticalScrollBarMaximumProperty],
[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.VerticalScrollBarValueProperty],
//[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.VerticalScrollBarValueProperty],
[~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.VerticalScrollBarViewportSizeProperty],
[~ScrollBar.VisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty],
[Grid.ColumnProperty] = 1,
},
}),
},
};
vert[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.VerticalScrollBarValueProperty];
return result;
}
}
}

2
Perspex.Themes.Default/TextBoxStyle.cs

@ -60,7 +60,7 @@ namespace Perspex.Themes.Default
[~TextPresenter.CaretIndexProperty] = control[~TextBox.CaretIndexProperty],
[~TextPresenter.SelectionStartProperty] = control[~TextBox.SelectionStartProperty],
[~TextPresenter.SelectionEndProperty] = control[~TextBox.SelectionEndProperty],
[~~TextPresenter.TextProperty] = control[~~TextBox.TextProperty],
[~TextPresenter.TextProperty] = control[~TextBox.TextProperty],
[~TextPresenter.TextWrappingProperty] = control[~TextBox.TextWrappingProperty],
}
}

Loading…
Cancel
Save