committed by
GitHub
30 changed files with 526 additions and 121 deletions
@ -0,0 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="System.Drawing.Common" Version="4.5.0-preview1-25914-04" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,127 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Specialized; |
|||
using System.Reactive; |
|||
using System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
using System.Reactive.Subjects; |
|||
using Avalonia.Utilities; |
|||
|
|||
namespace Avalonia.Collections |
|||
{ |
|||
public static class NotifyCollectionChangedExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets a weak observable for the CollectionChanged event.
|
|||
/// </summary>
|
|||
/// <param name="collection">The collection.</param>
|
|||
/// <returns>An observable.</returns>
|
|||
public static IObservable<NotifyCollectionChangedEventArgs> GetWeakCollectionChangedObservable( |
|||
this INotifyCollectionChanged collection) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(collection != null); |
|||
|
|||
return new WeakCollectionChangedObservable(new WeakReference<INotifyCollectionChanged>(collection)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Subcribes to the CollectionChanged event using a weak subscription.
|
|||
/// </summary>
|
|||
/// <param name="collection">The collection.</param>
|
|||
/// <param name="handler">
|
|||
/// An action called when the collection event is raised.
|
|||
/// </param>
|
|||
/// <returns>A disposable used to terminate the subscription.</returns>
|
|||
public static IDisposable WeakSubscribe( |
|||
this INotifyCollectionChanged collection, |
|||
NotifyCollectionChangedEventHandler handler) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(collection != null); |
|||
Contract.Requires<ArgumentNullException>(handler != null); |
|||
|
|||
return |
|||
collection.GetWeakCollectionChangedObservable() |
|||
.Subscribe(e => handler.Invoke(collection, e)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Subcribes to the CollectionChanged event using a weak subscription.
|
|||
/// </summary>
|
|||
/// <param name="collection">The collection.</param>
|
|||
/// <param name="handler">
|
|||
/// An action called when the collection event is raised.
|
|||
/// </param>
|
|||
/// <returns>A disposable used to terminate the subscription.</returns>
|
|||
public static IDisposable WeakSubscribe( |
|||
this INotifyCollectionChanged collection, |
|||
Action<NotifyCollectionChangedEventArgs> handler) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(collection != null); |
|||
Contract.Requires<ArgumentNullException>(handler != null); |
|||
|
|||
return |
|||
collection.GetWeakCollectionChangedObservable() |
|||
.Subscribe(handler); |
|||
} |
|||
|
|||
private class WeakCollectionChangedObservable : ObservableBase<NotifyCollectionChangedEventArgs>, |
|||
IWeakSubscriber<NotifyCollectionChangedEventArgs> |
|||
{ |
|||
private WeakReference<INotifyCollectionChanged> _sourceReference; |
|||
private readonly Subject<NotifyCollectionChangedEventArgs> _changed = new Subject<NotifyCollectionChangedEventArgs>(); |
|||
|
|||
private int _count; |
|||
|
|||
public WeakCollectionChangedObservable(WeakReference<INotifyCollectionChanged> source) |
|||
{ |
|||
_sourceReference = source; |
|||
} |
|||
|
|||
public void OnEvent(object sender, NotifyCollectionChangedEventArgs e) |
|||
{ |
|||
_changed.OnNext(e); |
|||
} |
|||
|
|||
protected override IDisposable SubscribeCore(IObserver<NotifyCollectionChangedEventArgs> observer) |
|||
{ |
|||
if (_sourceReference.TryGetTarget(out INotifyCollectionChanged instance)) |
|||
{ |
|||
if (_count++ == 0) |
|||
{ |
|||
WeakSubscriptionManager.Subscribe( |
|||
instance, |
|||
nameof(instance.CollectionChanged), |
|||
this); |
|||
} |
|||
|
|||
return Observable.Using(() => Disposable.Create(DecrementCount), _ => _changed) |
|||
.Subscribe(observer); |
|||
} |
|||
else |
|||
{ |
|||
_changed.OnCompleted(); |
|||
observer.OnCompleted(); |
|||
return Disposable.Empty; |
|||
} |
|||
} |
|||
|
|||
private void DecrementCount() |
|||
{ |
|||
if (--_count == 0) |
|||
{ |
|||
if (_sourceReference.TryGetTarget(out INotifyCollectionChanged instance)) |
|||
{ |
|||
WeakSubscriptionManager.Unsubscribe( |
|||
instance, |
|||
nameof(instance.CollectionChanged), |
|||
this); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
namespace Avalonia.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// Determines the startup location of the window.
|
|||
/// </summary>
|
|||
public enum WindowStartupLocation |
|||
{ |
|||
/// <summary>
|
|||
/// The startup location is defined by the Position property.
|
|||
/// </summary>
|
|||
Manual, |
|||
|
|||
/// <summary>
|
|||
/// The startup location is the center of the screen.
|
|||
/// </summary>
|
|||
CenterScreen, |
|||
|
|||
/// <summary>
|
|||
/// The startup location is the center of the owner window. If the owner window is not specified, the startup location will be <see cref="Manual"/>.
|
|||
/// </summary>
|
|||
CenterOwner |
|||
} |
|||
} |
|||
@ -1,20 +1,38 @@ |
|||
<Style xmlns="https://github.com/avaloniaui" Selector="ProgressBar"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush4}"/> |
|||
<Setter Property="Foreground" Value="{DynamicResource ThemeAccentBrush}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<Grid> |
|||
<Border Name="PART_Track" |
|||
BorderThickness="1" |
|||
BorderBrush="{TemplateBinding Background}"/> |
|||
<Border Name="PART_Indicator" |
|||
BorderThickness="1" |
|||
Background="{TemplateBinding Foreground}"/> |
|||
</Grid> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
<Styles xmlns="https://github.com/avaloniaui"> |
|||
<Style Selector="ProgressBar"> |
|||
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush4}"/> |
|||
<Setter Property="Foreground" Value="{DynamicResource ThemeAccentBrush}"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<Grid> |
|||
<Border Name="PART_Track" |
|||
BorderThickness="1" |
|||
BorderBrush="{TemplateBinding Background}"/> |
|||
<Border Name="PART_Indicator" |
|||
BorderThickness="1" |
|||
Background="{TemplateBinding Foreground}" /> |
|||
</Grid> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="ProgressBar:horizontal /template/ Border#PART_Indicator"> |
|||
<Setter Property="HorizontalAlignment" Value="Left"/> |
|||
<Setter Property="VerticalAlignment" Value="Stretch"/> |
|||
</Style> |
|||
<Style Selector="ProgressBar:vertical /template/ Border#PART_Indicator"> |
|||
<Setter Property="HorizontalAlignment" Value="Stretch"/> |
|||
<Setter Property="VerticalAlignment" Value="Bottom"/> |
|||
</Style> |
|||
<Style Selector="ProgressBar:horizontal"> |
|||
<Setter Property="MinWidth" Value="200"/> |
|||
<Setter Property="MinHeight" Value="14"/> |
|||
</Style> |
|||
<Style Selector="ProgressBar:vertical"> |
|||
<Setter Property="MinWidth" Value="14"/> |
|||
<Setter Property="MinHeight" Value="200"/> |
|||
</Style> |
|||
</Styles> |
|||
Loading…
Reference in new issue