Browse Source
# Conflicts: # src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cspull/4043/head
172 changed files with 5639 additions and 1364 deletions
@ -1,5 +1,5 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Moq" Version="4.7.99" /> |
<PackageReference Include="Moq" Version="4.14.1" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,7 +0,0 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Serilog" Version="2.5.0" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Trace" Version="2.1.0" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="1.0.0" /> |
|
||||
</ItemGroup> |
|
||||
</Project> |
|
||||
@ -0,0 +1,79 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="ControlCatalog.Pages.ToggleSwitchPage" Margin="5"> |
||||
|
<StackPanel Width="500" HorizontalAlignment="Center"> |
||||
|
<TextBlock Text="Simple ToggleSwitch" Classes="header"/> |
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Margin="10"/> |
||||
|
<TextBox Text="<ToggleSwitch/>" Classes="CodeBox"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="headered ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="headered" IsChecked="true" Margin="10"/> |
||||
|
<TextBox Classes="CodeBox" |
||||
|
Text="<ToggleSwitch>headered</ToggleSwitch>"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="Custom content ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="Custom" |
||||
|
OnContent="On" |
||||
|
OffContent="Off" |
||||
|
Margin="10"/> |
||||
|
|
||||
|
<TextBox Text="<ToggleSwitch Content="Custom" |
||||
|
ContentOn="On" |
||||
|
ContentOff="Off" />" |
||||
|
Classes="CodeBox"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="Image content ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="Just Click!" Margin="10"> |
||||
|
<ToggleSwitch.OnContent> |
||||
|
<Image Source="/Assets/hirsch-899118_640.jpg" Height="32"/> |
||||
|
</ToggleSwitch.OnContent> |
||||
|
|
||||
|
<ToggleSwitch.OffContent> |
||||
|
<Image Source="/Assets/delicate-arch-896885_640.jpg" Height="32"/> |
||||
|
</ToggleSwitch.OffContent> |
||||
|
|
||||
|
</ToggleSwitch> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<UserControl.Styles > |
||||
|
<Style Selector="TextBox.CodeBox" > |
||||
|
<Setter Property="Padding" Value="10"/> |
||||
|
<Setter Property="IsReadOnly" Value="True"/> |
||||
|
<Setter Property="BorderBrush" Value="Transparent"/> |
||||
|
<Setter Property="FontSize" Value="14"/> |
||||
|
<Setter Property="IsEnabled" Value="true"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="TextBlock.header"> |
||||
|
<Setter Property="FontSize" Value="18"/> |
||||
|
<Setter Property="Margin" Value="0 20 0 20"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Thin"> |
||||
|
<Setter Property="BorderBrush" Value="Gray"/> |
||||
|
<Setter Property="BorderThickness" Value="0.5"/> |
||||
|
<Setter Property="CornerRadius" Value="2"/> |
||||
|
</Style> |
||||
|
|
||||
|
</UserControl.Styles> |
||||
|
</UserControl> |
||||
|
|
||||
@ -0,0 +1,19 @@ |
|||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public class ToggleSwitchPage : UserControl |
||||
|
{ |
||||
|
public ToggleSwitchPage() |
||||
|
{ |
||||
|
this.InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,115 @@ |
|||||
|
<UserControl |
||||
|
xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="RenderDemo.Pages.TransitionsPage"> |
||||
|
<UserControl.Styles> |
||||
|
<Styles> |
||||
|
<Styles.Resources> |
||||
|
<Template x:Key="Acorn"> |
||||
|
<Path Fill="White" Stretch="Uniform" |
||||
|
Data="F1 M 16.6309,18.6563C 17.1309, |
||||
|
8.15625 29.8809,14.1563 29.8809, |
||||
|
14.1563C 30.8809,11.1563 34.1308, |
||||
|
11.4063 34.1308,11.4063C 33.5,12 |
||||
|
34.6309,13.1563 34.6309,13.1563C |
||||
|
32.1309,13.1562 31.1309,14.9062 |
||||
|
31.1309,14.9062C 41.1309,23.9062 |
||||
|
32.6309,27.9063 32.6309,27.9062C |
||||
|
24.6309,24.9063 21.1309,22.1562 |
||||
|
16.6309,18.6563 Z M 16.6309,19.9063C |
||||
|
21.6309,24.1563 25.1309,26.1562 |
||||
|
31.6309,28.6562C 31.6309,28.6562 |
||||
|
26.3809,39.1562 18.3809,36.1563C |
||||
|
18.3809,36.1563 18,38 16.3809,36.9063C |
||||
|
15,36 16.3809,34.9063 16.3809,34.9063C |
||||
|
16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z"/> |
||||
|
</Template> |
||||
|
<Template x:Key="Heart"> |
||||
|
<Path Fill="Red" Stretch="Uniform" Data=" |
||||
|
M 272.70141,238.71731 |
||||
|
C 206.46141,238.71731 152.70146,292.4773 152.70146,358.71731 |
||||
|
C 152.70146,493.47282 288.63461,528.80461 381.26391,662.02535 |
||||
|
C 468.83815,529.62199 609.82641,489.17075 609.82641,358.71731 |
||||
|
C 609.82641,292.47731 556.06651,238.7173 489.82641,238.71731 |
||||
|
C 441.77851,238.71731 400.42481,267.08774 381.26391,307.90481 |
||||
|
C 362.10311,267.08773 320.74941,238.7173 272.70141,238.71731 z "/> |
||||
|
</Template> |
||||
|
</Styles.Resources> |
||||
|
|
||||
|
<Style Selector="Border.Test"> |
||||
|
<Setter Property="Margin" Value="15"/> |
||||
|
<Setter Property="Width" Value="100"/> |
||||
|
<Setter Property="Height" Value="100"/> |
||||
|
<Setter Property="Child" Value="{StaticResource Acorn}"/> |
||||
|
<Setter Property="Transitions"> |
||||
|
<Transitions> |
||||
|
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:1" /> |
||||
|
</Transitions> |
||||
|
</Setter> |
||||
|
<Setter Property="RenderTransform" Value="none" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect1:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="rotate(120deg) scale(1.5)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect2:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="scale(0.8)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect3"> |
||||
|
<Setter Property="Child" Value="{StaticResource Heart}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect3:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="rotate(1turn)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect4:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="translateY(-100px)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect5:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="skewX(-20deg)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect5:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="skewX(-20deg)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect6"> |
||||
|
<Setter Property="Transitions"> |
||||
|
<Transitions> |
||||
|
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.5" Delay="0:0:1"/> |
||||
|
</Transitions> |
||||
|
</Setter> |
||||
|
<Setter Property="RenderTransform" Value="scale(0.8)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect6:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="none" /> |
||||
|
</Style> |
||||
|
|
||||
|
</Styles> |
||||
|
</UserControl.Styles> |
||||
|
|
||||
|
<Grid> |
||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="False"> |
||||
|
<StackPanel.Clock> |
||||
|
<Clock /> |
||||
|
</StackPanel.Clock> |
||||
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"> |
||||
|
<TextBlock VerticalAlignment="Center">Hover to activate Transform Keyframe Animations.</TextBlock> |
||||
|
<Button Content="{Binding PlayStateText}" Command="{Binding TogglePlayState}" Click="ToggleClock" /> |
||||
|
</StackPanel> |
||||
|
<WrapPanel ClipToBounds="False"> |
||||
|
<Border Classes="Test Rect1" Background="DarkRed"/> |
||||
|
<Border Classes="Test Rect2" Background="Magenta"/> |
||||
|
<Border Classes="Test Rect3"/> |
||||
|
<Border Classes="Test Rect4" Background="Navy"/> |
||||
|
<Border Classes="Test Rect5" Background="SeaGreen"/> |
||||
|
<Border Classes="Test Rect6" Background="Orange"/> |
||||
|
</WrapPanel> |
||||
|
</StackPanel> |
||||
|
</Grid> |
||||
|
</UserControl> |
||||
@ -0,0 +1,37 @@ |
|||||
|
using Avalonia.Animation; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Interactivity; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using RenderDemo.ViewModels; |
||||
|
|
||||
|
namespace RenderDemo.Pages |
||||
|
{ |
||||
|
public class TransitionsPage : UserControl |
||||
|
{ |
||||
|
public TransitionsPage() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
this.DataContext = new AnimationsPageViewModel(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
private void ToggleClock(object sender, RoutedEventArgs args) |
||||
|
{ |
||||
|
var button = sender as Button; |
||||
|
var clock = button.Clock; |
||||
|
|
||||
|
if (clock.PlayState == PlayState.Run) |
||||
|
{ |
||||
|
clock.PlayState = PlayState.Pause; |
||||
|
} |
||||
|
else if (clock.PlayState == PlayState.Pause) |
||||
|
{ |
||||
|
clock.PlayState = PlayState.Run; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,179 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using System.Text; |
||||
|
using Avalonia.Utilities; |
||||
|
|
||||
|
namespace Avalonia.Logging |
||||
|
{ |
||||
|
public class DebugLogSink : ILogSink |
||||
|
{ |
||||
|
private readonly LogEventLevel _level; |
||||
|
private readonly IList<string> _areas; |
||||
|
|
||||
|
public DebugLogSink( |
||||
|
LogEventLevel minimumLevel, |
||||
|
IList<string> areas = null) |
||||
|
{ |
||||
|
_level = minimumLevel; |
||||
|
_areas = areas?.Count > 0 ? areas : null; |
||||
|
} |
||||
|
|
||||
|
public bool IsEnabled(LogEventLevel level, string area) |
||||
|
{ |
||||
|
return level >= _level && (_areas?.Contains(area) ?? true); |
||||
|
} |
||||
|
|
||||
|
public void Log(LogEventLevel level, string area, object source, string messageTemplate) |
||||
|
{ |
||||
|
if (IsEnabled(level, area)) |
||||
|
{ |
||||
|
Debug.WriteLine(Format<object, object, object>(area, messageTemplate, source)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Log<T0>(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0) |
||||
|
{ |
||||
|
if (IsEnabled(level, area)) |
||||
|
{ |
||||
|
Debug.WriteLine(Format<T0, object, object>(area, messageTemplate, source, propertyValue0)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Log<T0, T1>(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1) |
||||
|
{ |
||||
|
if (IsEnabled(level, area)) |
||||
|
{ |
||||
|
Debug.WriteLine(Format<T0, T1, object>(area, messageTemplate, source, propertyValue0, propertyValue1)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Log<T0, T1, T2>(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) |
||||
|
{ |
||||
|
if (IsEnabled(level, area)) |
||||
|
{ |
||||
|
Debug.WriteLine(Format(area, messageTemplate, source, propertyValue0, propertyValue1, propertyValue2)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Log(LogEventLevel level, string area, object source, string messageTemplate, params object[] propertyValues) |
||||
|
{ |
||||
|
if (IsEnabled(level, area)) |
||||
|
{ |
||||
|
Debug.WriteLine(Format(area, messageTemplate, source, propertyValues)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static string Format<T0, T1, T2>( |
||||
|
string area, |
||||
|
string template, |
||||
|
object source, |
||||
|
T0 v0 = default, |
||||
|
T1 v1 = default, |
||||
|
T2 v2 = default) |
||||
|
{ |
||||
|
var result = new StringBuilder(template.Length); |
||||
|
var r = new CharacterReader(template.AsSpan()); |
||||
|
var i = 0; |
||||
|
|
||||
|
result.Append('['); |
||||
|
result.Append(area); |
||||
|
result.Append("] "); |
||||
|
|
||||
|
while (!r.End) |
||||
|
{ |
||||
|
var c = r.Take(); |
||||
|
|
||||
|
if (c != '{') |
||||
|
{ |
||||
|
result.Append(c); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (r.Peek != '{') |
||||
|
{ |
||||
|
result.Append('\''); |
||||
|
result.Append(i++ switch |
||||
|
{ |
||||
|
0 => v0, |
||||
|
1 => v1, |
||||
|
2 => v2, |
||||
|
_ => null |
||||
|
}); |
||||
|
result.Append('\''); |
||||
|
r.TakeUntil('}'); |
||||
|
r.Take(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result.Append('{'); |
||||
|
r.Take(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (source is object) |
||||
|
{ |
||||
|
result.Append(" ("); |
||||
|
result.Append(source.GetType().Name); |
||||
|
result.Append(" #"); |
||||
|
result.Append(source.GetHashCode()); |
||||
|
result.Append(')'); |
||||
|
} |
||||
|
|
||||
|
return result.ToString(); |
||||
|
} |
||||
|
|
||||
|
private static string Format( |
||||
|
string area, |
||||
|
string template, |
||||
|
object source, |
||||
|
object[] v) |
||||
|
{ |
||||
|
var result = new StringBuilder(template.Length); |
||||
|
var r = new CharacterReader(template.AsSpan()); |
||||
|
var i = 0; |
||||
|
|
||||
|
result.Append('['); |
||||
|
result.Append(area); |
||||
|
result.Append(']'); |
||||
|
|
||||
|
while (!r.End) |
||||
|
{ |
||||
|
var c = r.Take(); |
||||
|
|
||||
|
if (c != '{') |
||||
|
{ |
||||
|
result.Append(c); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (r.Peek != '{') |
||||
|
{ |
||||
|
result.Append('\''); |
||||
|
result.Append(i < v.Length ? v[i++] : null); |
||||
|
result.Append('\''); |
||||
|
r.TakeUntil('}'); |
||||
|
r.Take(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
result.Append('{'); |
||||
|
r.Take(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (source is object) |
||||
|
{ |
||||
|
result.Append('('); |
||||
|
result.Append(source.GetType().Name); |
||||
|
result.Append(" #"); |
||||
|
result.Append(source.GetHashCode()); |
||||
|
result.Append(')'); |
||||
|
} |
||||
|
|
||||
|
return result.ToString(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,136 +0,0 @@ |
|||||
// (c) Copyright Microsoft Corporation.
|
|
||||
// This source is subject to the Microsoft Public License (Ms-PL).
|
|
||||
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
|
|
||||
// All other rights reserved.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
namespace Avalonia.Controls.Utils |
|
||||
{ |
|
||||
internal static class DoubleUtil |
|
||||
{ |
|
||||
internal const double DBL_EPSILON = 1e-6; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// AreClose - Returns whether or not two doubles are "close". That is, whether or
|
|
||||
/// not they are within epsilon of each other. Note that this epsilon is proportional
|
|
||||
/// to the numbers themselves to that AreClose survives scalar multiplication.
|
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
|
||||
/// returns false. This is important enough to repeat:
|
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
|
||||
/// used for optimizations *only*.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the AreClose comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value1"> The first double to compare. </param>
|
|
||||
/// <param name="value2"> The second double to compare. </param>
|
|
||||
public static bool AreClose(double value1, double value2) |
|
||||
{ |
|
||||
//in case they are Infinities (then epsilon check does not work)
|
|
||||
if (value1 == value2) return true; |
|
||||
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
|
|
||||
double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON; |
|
||||
double delta = value1 - value2; |
|
||||
return (-eps < delta) && (eps > delta); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// GreaterThan - Returns whether or not the first double is greater than the second double.
|
|
||||
/// That is, whether or not the first is strictly greater than *and* not within epsilon of
|
|
||||
/// the other number. Note that this epsilon is proportional to the numbers themselves
|
|
||||
/// to that AreClose survives scalar multiplication. Note,
|
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
|
||||
/// returns false. This is important enough to repeat:
|
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
|
||||
/// used for optimizations *only*.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the GreaterThan comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value1"> The first double to compare. </param>
|
|
||||
/// <param name="value2"> The second double to compare. </param>
|
|
||||
public static bool GreaterThan(double value1, double value2) |
|
||||
{ |
|
||||
return (value1 > value2) && !AreClose(value1, value2); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// GreaterThanOrClose - Returns whether or not the first double is greater than or close to
|
|
||||
/// the second double. That is, whether or not the first is strictly greater than or within
|
|
||||
/// epsilon of the other number. Note that this epsilon is proportional to the numbers
|
|
||||
/// themselves to that AreClose survives scalar multiplication. Note,
|
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
|
||||
/// returns false. This is important enough to repeat:
|
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
|
||||
/// used for optimizations *only*.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the GreaterThanOrClose comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value1"> The first double to compare. </param>
|
|
||||
/// <param name="value2"> The second double to compare. </param>
|
|
||||
public static bool GreaterThanOrClose(double value1, double value2) |
|
||||
{ |
|
||||
return (value1 > value2) || AreClose(value1, value2); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0),
|
|
||||
/// but this is faster.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the IsZero comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value"> The double to compare to 0. </param>
|
|
||||
public static bool IsZero(double value) |
|
||||
{ |
|
||||
return Math.Abs(value) < 10.0 * DBL_EPSILON; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// LessThan - Returns whether or not the first double is less than the second double.
|
|
||||
/// That is, whether or not the first is strictly less than *and* not within epsilon of
|
|
||||
/// the other number. Note that this epsilon is proportional to the numbers themselves
|
|
||||
/// to that AreClose survives scalar multiplication. Note,
|
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
|
||||
/// returns false. This is important enough to repeat:
|
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
|
||||
/// used for optimizations *only*.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the LessThan comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value1"> The first double to compare. </param>
|
|
||||
/// <param name="value2"> The second double to compare. </param>
|
|
||||
public static bool LessThan(double value1, double value2) |
|
||||
{ |
|
||||
return (value1 < value2) && !AreClose(value1, value2); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// LessThanOrClose - Returns whether or not the first double is less than or close to
|
|
||||
/// the second double. That is, whether or not the first is strictly less than or within
|
|
||||
/// epsilon of the other number. Note that this epsilon is proportional to the numbers
|
|
||||
/// themselves to that AreClose survives scalar multiplication. Note,
|
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
|
||||
/// returns false. This is important enough to repeat:
|
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
|
||||
/// used for optimizations *only*.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// bool - the result of the LessThanOrClose comparison.
|
|
||||
/// </returns>
|
|
||||
/// <param name="value1"> The first double to compare. </param>
|
|
||||
/// <param name="value2"> The second double to compare. </param>
|
|
||||
public static bool LessThanOrClose(double value1, double value2) |
|
||||
{ |
|
||||
return (value1 < value2) || AreClose(value1, value2); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,64 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using Avalonia.Controls.Primitives; |
||||
|
using Avalonia.Data.Converters; |
||||
|
using Avalonia.Utilities; |
||||
|
|
||||
|
namespace Avalonia.Controls.Converters |
||||
|
{ |
||||
|
public class MenuScrollingVisibilityConverter : IMultiValueConverter |
||||
|
{ |
||||
|
public static readonly MenuScrollingVisibilityConverter Instance = new MenuScrollingVisibilityConverter(); |
||||
|
|
||||
|
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture) |
||||
|
{ |
||||
|
if (parameter == null || |
||||
|
values == null || |
||||
|
values.Count != 4 || |
||||
|
!(values[0] is ScrollBarVisibility visiblity) || |
||||
|
!(values[1] is double offset) || |
||||
|
!(values[2] is double extent) || |
||||
|
!(values[3] is double viewport)) |
||||
|
{ |
||||
|
return AvaloniaProperty.UnsetValue; |
||||
|
} |
||||
|
|
||||
|
if (visiblity == ScrollBarVisibility.Auto) |
||||
|
{ |
||||
|
if (extent == viewport) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
double target; |
||||
|
|
||||
|
if (parameter is double d) |
||||
|
{ |
||||
|
target = d; |
||||
|
} |
||||
|
else if (parameter is string s) |
||||
|
{ |
||||
|
target = double.Parse(s, NumberFormatInfo.InvariantInfo); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return AvaloniaProperty.UnsetValue; |
||||
|
} |
||||
|
|
||||
|
// Calculate the percent so that we can see if we are near the edge of the range
|
||||
|
double percent = MathUtilities.Clamp(offset * 100.0 / (extent - viewport), 0, 100); |
||||
|
|
||||
|
if (MathUtilities.AreClose(percent, target)) |
||||
|
{ |
||||
|
// We are at the end of the range, so no need for this button to be shown
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Logging; |
||||
|
|
||||
|
namespace Avalonia |
||||
|
{ |
||||
|
public static class LoggingExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Logs Avalonia events to the <see cref="System.Diagnostics.Debug"/> sink.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The application class type.</typeparam>
|
||||
|
/// <param name="builder">The app builder instance.</param>
|
||||
|
/// <param name="level">The minimum level to log.</param>
|
||||
|
/// <param name="areas">The areas to log. Valid values are listed in <see cref="LogArea"/>.</param>
|
||||
|
/// <returns>The app builder instance.</returns>
|
||||
|
public static T LogToDebug<T>( |
||||
|
this T builder, |
||||
|
LogEventLevel level = LogEventLevel.Warning, |
||||
|
params string[] areas) |
||||
|
where T : AppBuilderBase<T>, new() |
||||
|
{ |
||||
|
Logger.Sink = new DebugLogSink(level, areas); |
||||
|
return builder; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,136 @@ |
|||||
|
using Avalonia.Controls.Presenters; |
||||
|
using Avalonia.Controls.Primitives; |
||||
|
using Avalonia.Controls.Templates; |
||||
|
using Avalonia.LogicalTree; |
||||
|
|
||||
|
namespace Avalonia.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A Toggle Switch control.
|
||||
|
/// </summary>
|
||||
|
public class ToggleSwitch : ToggleButton |
||||
|
{ |
||||
|
static ToggleSwitch() |
||||
|
{ |
||||
|
OffContentProperty.Changed.AddClassHandler<ToggleSwitch>((x, e) => x.OffContentChanged(e)); |
||||
|
OnContentProperty.Changed.AddClassHandler<ToggleSwitch>((x, e) => x.OnContentChanged(e)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="OffContent"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<object> OffContentProperty = |
||||
|
AvaloniaProperty.Register<ToggleSwitch, object>(nameof(OffContent), defaultValue: "Off"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="OffContentTemplate"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<IDataTemplate> OffContentTemplateProperty = |
||||
|
AvaloniaProperty.Register<ToggleSwitch, IDataTemplate>(nameof(OffContentTemplate)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="OnContent"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<object> OnContentProperty = |
||||
|
AvaloniaProperty.Register<ToggleSwitch, object>(nameof(OnContent), defaultValue: "On"); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="OnContentTemplate"/> property.
|
||||
|
/// </summary>
|
||||
|
public static readonly StyledProperty<IDataTemplate> OnContentTemplateProperty = |
||||
|
AvaloniaProperty.Register<ToggleSwitch, IDataTemplate>(nameof(OnContentTemplate)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or Sets the Content that is displayed when in the On State.
|
||||
|
/// </summary>
|
||||
|
public object OnContent |
||||
|
{ |
||||
|
get { return GetValue(OnContentProperty); } |
||||
|
set { SetValue(OnContentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or Sets the Content that is displayed when in the Off State.
|
||||
|
/// </summary>
|
||||
|
public object OffContent |
||||
|
{ |
||||
|
get { return GetValue(OffContentProperty); } |
||||
|
set { SetValue(OffContentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public IContentPresenter OffContentPresenter |
||||
|
{ |
||||
|
get; |
||||
|
private set; |
||||
|
} |
||||
|
|
||||
|
public IContentPresenter OnContentPresenter |
||||
|
{ |
||||
|
get; |
||||
|
private set; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or Sets the <see cref="IDataTemplate"/> used to display the <see cref="OffContent"/>.
|
||||
|
/// </summary>
|
||||
|
public IDataTemplate OffContentTemplate |
||||
|
{ |
||||
|
get { return GetValue(OffContentTemplateProperty); } |
||||
|
set { SetValue(OffContentTemplateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or Sets the <see cref="IDataTemplate"/> used to display the <see cref="OnContent"/>.
|
||||
|
/// </summary>
|
||||
|
public IDataTemplate OnContentTemplate |
||||
|
{ |
||||
|
get { return GetValue(OnContentTemplateProperty); } |
||||
|
set { SetValue(OnContentTemplateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private void OffContentChanged(AvaloniaPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
if (e.OldValue is ILogical oldChild) |
||||
|
{ |
||||
|
LogicalChildren.Remove(oldChild); |
||||
|
} |
||||
|
|
||||
|
if (e.NewValue is ILogical newChild) |
||||
|
{ |
||||
|
LogicalChildren.Add(newChild); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void OnContentChanged(AvaloniaPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
if (e.OldValue is ILogical oldChild) |
||||
|
{ |
||||
|
LogicalChildren.Remove(oldChild); |
||||
|
} |
||||
|
|
||||
|
if (e.NewValue is ILogical newChild) |
||||
|
{ |
||||
|
LogicalChildren.Add(newChild); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override bool RegisterContentPresenter(IContentPresenter presenter) |
||||
|
{ |
||||
|
var result = base.RegisterContentPresenter(presenter); |
||||
|
|
||||
|
if (presenter.Name == "Part_OnContentPresenter") |
||||
|
{ |
||||
|
OnContentPresenter = presenter; |
||||
|
result = true; |
||||
|
} |
||||
|
else if (presenter.Name == "PART_OffContentPresenter") |
||||
|
{ |
||||
|
OffContentPresenter = presenter; |
||||
|
result = true; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -1,10 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
</PropertyGroup> |
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" /> |
|
||||
<ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" /> |
|
||||
</ItemGroup> |
|
||||
<Import Project="..\..\build\Serilog.props" /> |
|
||||
</Project> |
|
||||
@ -1,103 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Controls; |
|
||||
using Serilog; |
|
||||
using Serilog.Configuration; |
|
||||
using Serilog.Filters; |
|
||||
using SerilogLevel = Serilog.Events.LogEventLevel; |
|
||||
|
|
||||
namespace Avalonia.Logging.Serilog |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Extension methods for Serilog logging.
|
|
||||
/// </summary>
|
|
||||
public static class SerilogExtensions |
|
||||
{ |
|
||||
private const string DefaultTemplate = "[{Area}] {Message} ({SourceType} #{SourceHash})"; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Logs Avalonia events to the <see cref="System.Diagnostics.Debug"/> sink.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The application class type.</typeparam>
|
|
||||
/// <param name="builder">The app builder instance.</param>
|
|
||||
/// <param name="level">The minimum level to log.</param>
|
|
||||
/// <returns>The app builder instance.</returns>
|
|
||||
public static T LogToDebug<T>( |
|
||||
this T builder, |
|
||||
LogEventLevel level = LogEventLevel.Warning) |
|
||||
where T : AppBuilderBase<T>, new() |
|
||||
{ |
|
||||
SerilogLogger.Initialize(new LoggerConfiguration() |
|
||||
.MinimumLevel.Is((SerilogLevel)level) |
|
||||
.Enrich.FromLogContext() |
|
||||
.WriteTo.Debug(outputTemplate: DefaultTemplate) |
|
||||
.CreateLogger()); |
|
||||
return builder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Logs Avalonia events to the <see cref="System.Diagnostics.Debug"/> sink.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The application class type.</typeparam>
|
|
||||
/// <param name="builder">The app builder instance.</param>
|
|
||||
/// <param name="area">The area to log. Valid values are listed in <see cref="LogArea"/>.</param>
|
|
||||
/// <param name="level">The minimum level to log.</param>
|
|
||||
/// <returns>The app builder instance.</returns>
|
|
||||
public static T LogToDebug<T>( |
|
||||
this T builder, |
|
||||
string area, |
|
||||
LogEventLevel level = LogEventLevel.Warning) |
|
||||
where T : AppBuilderBase<T>, new() |
|
||||
{ |
|
||||
SerilogLogger.Initialize(new LoggerConfiguration() |
|
||||
.MinimumLevel.Is((SerilogLevel)level) |
|
||||
.Filter.ByIncludingOnly(Matching.WithProperty("Area", area)) |
|
||||
.Enrich.FromLogContext() |
|
||||
.WriteTo.Debug(outputTemplate: DefaultTemplate) |
|
||||
.CreateLogger()); |
|
||||
return builder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Logs Avalonia events to the <see cref="System.Diagnostics.Trace"/> sink.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The application class type.</typeparam>
|
|
||||
/// <param name="builder">The app builder instance.</param>
|
|
||||
/// <param name="level">The minimum level to log.</param>
|
|
||||
/// <returns>The app builder instance.</returns>
|
|
||||
public static T LogToTrace<T>( |
|
||||
this T builder, |
|
||||
LogEventLevel level = LogEventLevel.Warning) |
|
||||
where T : AppBuilderBase<T>, new() |
|
||||
{ |
|
||||
SerilogLogger.Initialize(new LoggerConfiguration() |
|
||||
.MinimumLevel.Is((SerilogLevel)level) |
|
||||
.Enrich.FromLogContext() |
|
||||
.WriteTo.Trace(outputTemplate: DefaultTemplate) |
|
||||
.CreateLogger()); |
|
||||
return builder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Logs Avalonia events to the <see cref="System.Diagnostics.Trace"/> sink.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The application class type.</typeparam>
|
|
||||
/// <param name="builder">The app builder instance.</param>
|
|
||||
/// <param name="area">The area to log. Valid values are listed in <see cref="LogArea"/>.</param>
|
|
||||
/// <param name="level">The minimum level to log.</param>
|
|
||||
/// <returns>The app builder instance.</returns>
|
|
||||
public static T LogToTrace<T>( |
|
||||
this T builder, |
|
||||
string area, |
|
||||
LogEventLevel level = LogEventLevel.Warning) |
|
||||
where T : AppBuilderBase<T>, new() |
|
||||
{ |
|
||||
SerilogLogger.Initialize(new LoggerConfiguration() |
|
||||
.MinimumLevel.Is((SerilogLevel)level) |
|
||||
.Filter.ByIncludingOnly(Matching.WithProperty("Area", area)) |
|
||||
.Enrich.FromLogContext() |
|
||||
.WriteTo.Trace(outputTemplate: DefaultTemplate) |
|
||||
.CreateLogger()); |
|
||||
return builder; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,151 +0,0 @@ |
|||||
using System; |
|
||||
using Serilog; |
|
||||
using Serilog.Context; |
|
||||
using AvaloniaLogEventLevel = Avalonia.Logging.LogEventLevel; |
|
||||
using SerilogLogEventLevel = Serilog.Events.LogEventLevel; |
|
||||
|
|
||||
namespace Avalonia.Logging.Serilog |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Sends log output to serilog.
|
|
||||
/// </summary>
|
|
||||
public class SerilogLogger : ILogSink |
|
||||
{ |
|
||||
private readonly ILogger _output; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="SerilogLogger"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="output">The serilog logger to use.</param>
|
|
||||
public SerilogLogger(ILogger output) |
|
||||
{ |
|
||||
_output = output; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes the Avalonia logging with a new instance of a <see cref="SerilogLogger"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="output">The serilog logger to use.</param>
|
|
||||
public static void Initialize(ILogger output) |
|
||||
{ |
|
||||
Logger.Sink = new SerilogLogger(output); |
|
||||
} |
|
||||
|
|
||||
public bool IsEnabled(LogEventLevel level) |
|
||||
{ |
|
||||
return _output.IsEnabled((SerilogLogEventLevel)level); |
|
||||
} |
|
||||
|
|
||||
public void Log( |
|
||||
LogEventLevel level, |
|
||||
string area, |
|
||||
object source, |
|
||||
string messageTemplate) |
|
||||
{ |
|
||||
Contract.Requires<ArgumentNullException>(area != null); |
|
||||
Contract.Requires<ArgumentNullException>(messageTemplate != null); |
|
||||
|
|
||||
using (PushLogContextProperties(area, source)) |
|
||||
{ |
|
||||
_output.Write((SerilogLogEventLevel)level, messageTemplate); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public void Log<T0>( |
|
||||
LogEventLevel level, |
|
||||
string area, object source, |
|
||||
string messageTemplate, |
|
||||
T0 propertyValue0) |
|
||||
{ |
|
||||
Contract.Requires<ArgumentNullException>(area != null); |
|
||||
Contract.Requires<ArgumentNullException>(messageTemplate != null); |
|
||||
|
|
||||
using (PushLogContextProperties(area, source)) |
|
||||
{ |
|
||||
_output.Write((SerilogLogEventLevel)level, messageTemplate, propertyValue0); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public void Log<T0, T1>( |
|
||||
LogEventLevel level, |
|
||||
string area, |
|
||||
object source, |
|
||||
string messageTemplate, |
|
||||
T0 propertyValue0, |
|
||||
T1 propertyValue1) |
|
||||
{ |
|
||||
Contract.Requires<ArgumentNullException>(area != null); |
|
||||
Contract.Requires<ArgumentNullException>(messageTemplate != null); |
|
||||
|
|
||||
using (PushLogContextProperties(area, source)) |
|
||||
{ |
|
||||
_output.Write((SerilogLogEventLevel)level, messageTemplate, propertyValue0, propertyValue1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public void Log<T0, T1, T2>( |
|
||||
LogEventLevel level, |
|
||||
string area, |
|
||||
object source, |
|
||||
string messageTemplate, |
|
||||
T0 propertyValue0, |
|
||||
T1 propertyValue1, |
|
||||
T2 propertyValue2) |
|
||||
{ |
|
||||
Contract.Requires<ArgumentNullException>(area != null); |
|
||||
Contract.Requires<ArgumentNullException>(messageTemplate != null); |
|
||||
|
|
||||
using (PushLogContextProperties(area, source)) |
|
||||
{ |
|
||||
_output.Write((SerilogLogEventLevel)level, messageTemplate, propertyValue0, propertyValue1, propertyValue2); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public void Log( |
|
||||
AvaloniaLogEventLevel level, |
|
||||
string area, |
|
||||
object source, |
|
||||
string messageTemplate, |
|
||||
params object[] propertyValues) |
|
||||
{ |
|
||||
Contract.Requires<ArgumentNullException>(area != null); |
|
||||
Contract.Requires<ArgumentNullException>(messageTemplate != null); |
|
||||
|
|
||||
using (PushLogContextProperties(area, source)) |
|
||||
{ |
|
||||
_output.Write((SerilogLogEventLevel)level, messageTemplate, propertyValues); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static LogContextDisposable PushLogContextProperties(string area, object source) |
|
||||
{ |
|
||||
return new LogContextDisposable( |
|
||||
LogContext.PushProperty("Area", area), |
|
||||
LogContext.PushProperty("SourceType", source?.GetType()), |
|
||||
LogContext.PushProperty("SourceHash", source?.GetHashCode()) |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
private readonly struct LogContextDisposable : IDisposable |
|
||||
{ |
|
||||
private readonly IDisposable _areaDisposable; |
|
||||
private readonly IDisposable _sourceTypeDisposable; |
|
||||
private readonly IDisposable _sourceHashDisposable; |
|
||||
|
|
||||
public LogContextDisposable(IDisposable areaDisposable, IDisposable sourceTypeDisposable, IDisposable sourceHashDisposable) |
|
||||
{ |
|
||||
_areaDisposable = areaDisposable; |
|
||||
_sourceTypeDisposable = sourceTypeDisposable; |
|
||||
_sourceHashDisposable = sourceHashDisposable; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
_areaDisposable.Dispose(); |
|
||||
_sourceTypeDisposable.Dispose(); |
|
||||
_sourceHashDisposable.Dispose(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,47 +1,105 @@ |
|||||
<Style xmlns="https://github.com/avaloniaui" Selector="ScrollViewer"> |
<Styles xmlns="https://github.com/avaloniaui" |
||||
<Setter Property="Background" |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
Value="Transparent" /> |
xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"> |
||||
<Setter Property="Template"> |
<Style Selector="ScrollViewer"> |
||||
<ControlTemplate> |
<Setter Property="Background" |
||||
<Grid ColumnDefinitions="*,Auto" RowDefinitions="*,Auto"> |
Value="Transparent" /> |
||||
<ScrollContentPresenter Name="PART_ContentPresenter" |
<Setter Property="Template"> |
||||
Background="{TemplateBinding Background}" |
<ControlTemplate> |
||||
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}" |
<Grid ColumnDefinitions="*,Auto" RowDefinitions="*,Auto"> |
||||
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}" |
<ScrollContentPresenter Name="PART_ContentPresenter" |
||||
Content="{TemplateBinding Content}" |
Background="{TemplateBinding Background}" |
||||
Extent="{TemplateBinding Extent, Mode=TwoWay}" |
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}" |
||||
Margin="{TemplateBinding Padding}" |
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}" |
||||
Offset="{TemplateBinding Offset, Mode=TwoWay}" |
Content="{TemplateBinding Content}" |
||||
Viewport="{TemplateBinding Viewport, Mode=TwoWay}"> |
Extent="{TemplateBinding Extent, Mode=TwoWay}" |
||||
<ScrollContentPresenter.GestureRecognizers> |
Margin="{TemplateBinding Padding}" |
||||
<ScrollGestureRecognizer |
Offset="{TemplateBinding Offset, Mode=TwoWay}" |
||||
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}" |
Viewport="{TemplateBinding Viewport, Mode=TwoWay}"> |
||||
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}" |
<ScrollContentPresenter.GestureRecognizers> |
||||
|
<ScrollGestureRecognizer |
||||
|
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}" |
||||
|
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}" |
||||
/> |
/> |
||||
</ScrollContentPresenter.GestureRecognizers> |
</ScrollContentPresenter.GestureRecognizers> |
||||
</ScrollContentPresenter> |
</ScrollContentPresenter> |
||||
<ScrollBar Name="horizontalScrollBar" |
<ScrollBar Name="horizontalScrollBar" |
||||
Orientation="Horizontal" |
Orientation="Horizontal" |
||||
LargeChange="{Binding LargeChange.Width, RelativeSource={RelativeSource TemplatedParent}}" |
LargeChange="{Binding LargeChange.Width, RelativeSource={RelativeSource TemplatedParent}}" |
||||
SmallChange="{Binding SmallChange.Width, RelativeSource={RelativeSource TemplatedParent}}" |
SmallChange="{Binding SmallChange.Width, RelativeSource={RelativeSource TemplatedParent}}" |
||||
Maximum="{TemplateBinding HorizontalScrollBarMaximum}" |
Maximum="{TemplateBinding HorizontalScrollBarMaximum}" |
||||
Value="{TemplateBinding HorizontalScrollBarValue, Mode=TwoWay}" |
Value="{TemplateBinding HorizontalScrollBarValue, Mode=TwoWay}" |
||||
ViewportSize="{TemplateBinding HorizontalScrollBarViewportSize}" |
ViewportSize="{TemplateBinding HorizontalScrollBarViewportSize}" |
||||
Visibility="{TemplateBinding HorizontalScrollBarVisibility}" |
Visibility="{TemplateBinding HorizontalScrollBarVisibility}" |
||||
Grid.Row="1" |
Grid.Row="1" |
||||
Focusable="False"/> |
Focusable="False"/> |
||||
<ScrollBar Name="verticalScrollBar" |
<ScrollBar Name="verticalScrollBar" |
||||
Orientation="Vertical" |
Orientation="Vertical" |
||||
LargeChange="{Binding LargeChange.Height, RelativeSource={RelativeSource TemplatedParent}}" |
LargeChange="{Binding LargeChange.Height, RelativeSource={RelativeSource TemplatedParent}}" |
||||
SmallChange="{Binding SmallChange.Height, RelativeSource={RelativeSource TemplatedParent}}" |
SmallChange="{Binding SmallChange.Height, RelativeSource={RelativeSource TemplatedParent}}" |
||||
Maximum="{TemplateBinding VerticalScrollBarMaximum}" |
Maximum="{TemplateBinding VerticalScrollBarMaximum}" |
||||
Value="{TemplateBinding VerticalScrollBarValue, Mode=TwoWay}" |
Value="{TemplateBinding VerticalScrollBarValue, Mode=TwoWay}" |
||||
ViewportSize="{TemplateBinding VerticalScrollBarViewportSize}" |
ViewportSize="{TemplateBinding VerticalScrollBarViewportSize}" |
||||
Visibility="{TemplateBinding VerticalScrollBarVisibility}" |
Visibility="{TemplateBinding VerticalScrollBarVisibility}" |
||||
Grid.Column="1" |
Grid.Column="1" |
||||
Focusable="False"/> |
Focusable="False"/> |
||||
<Panel Grid.Row="1" Grid.Column="1" Background="{DynamicResource ThemeControlMidBrush}"/> |
<Panel Grid.Row="1" Grid.Column="1" Background="{DynamicResource ThemeControlMidBrush}"/> |
||||
</Grid> |
</Grid> |
||||
</ControlTemplate> |
</ControlTemplate> |
||||
</Setter> |
</Setter> |
||||
</Style> |
</Style> |
||||
|
|
||||
|
<Style Selector="ScrollViewer.menuscroller"> |
||||
|
<Setter Property="Template"> |
||||
|
<ControlTemplate> |
||||
|
<DockPanel> |
||||
|
<RepeatButton DockPanel.Dock="Top" |
||||
|
BorderThickness="0" |
||||
|
Background="Transparent" |
||||
|
Command="{Binding LineUp, RelativeSource={RelativeSource TemplatedParent}}"> |
||||
|
<RepeatButton.IsVisible> |
||||
|
<MultiBinding Converter="{x:Static converters:MenuScrollingVisibilityConverter.Instance}" |
||||
|
ConverterParameter="0"> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="VerticalScrollBarVisibility"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Offset.Y"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Extent.Height"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Viewport.Height"/> |
||||
|
</MultiBinding> |
||||
|
</RepeatButton.IsVisible> |
||||
|
<Path Data="M 0 4 L 8 4 L 4 0 Z"/> |
||||
|
</RepeatButton> |
||||
|
<RepeatButton DockPanel.Dock="Bottom" |
||||
|
BorderThickness="0" |
||||
|
Background="Transparent" |
||||
|
Command="{Binding LineDown, RelativeSource={RelativeSource TemplatedParent}}"> |
||||
|
<RepeatButton.IsVisible> |
||||
|
<MultiBinding Converter="{x:Static converters:MenuScrollingVisibilityConverter.Instance}" |
||||
|
ConverterParameter="100"> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="VerticalScrollBarVisibility"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Offset.Y"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Extent.Height"/> |
||||
|
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Viewport.Height"/> |
||||
|
</MultiBinding> |
||||
|
</RepeatButton.IsVisible> |
||||
|
<Path Data="M 0 0 L 4 4 L 8 0 Z"/> |
||||
|
</RepeatButton> |
||||
|
<ScrollContentPresenter Name="PART_ContentPresenter" |
||||
|
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}" |
||||
|
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}" |
||||
|
Content="{TemplateBinding Content}" |
||||
|
Extent="{TemplateBinding Extent, Mode=TwoWay}" |
||||
|
Margin="{TemplateBinding Padding}" |
||||
|
Offset="{TemplateBinding Offset, Mode=TwoWay}" |
||||
|
Viewport="{TemplateBinding Viewport, Mode=TwoWay}"/> |
||||
|
</DockPanel> |
||||
|
</ControlTemplate> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
<Style Selector="ScrollViewer.menuscroller /template/ RepeatButton > Path"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ThemeForegroundLowBrush}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ScrollViewer.menuscroller /template/ RepeatButton:pointerover > Path"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ThemeAccentBrush}" /> |
||||
|
</Style> |
||||
|
</Styles> |
||||
|
|||||
@ -0,0 +1,294 @@ |
|||||
|
<Styles xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:sys="clr-namespace:System;assembly=netstandard"> |
||||
|
<Styles.Resources> |
||||
|
<Thickness x:Key="ToggleSwitchTopHeaderMargin">0,0,0,6</Thickness> |
||||
|
<x:Double x:Key="ToggleSwitchPreContentMargin">6</x:Double> |
||||
|
<x:Double x:Key="ToggleSwitchPostContentMargin">6</x:Double> |
||||
|
<x:Double x:Key="ToggleSwitchThemeMinWidth">154</x:Double> |
||||
|
<x:Double x:Key="KnobOnPosition">20</x:Double> |
||||
|
<x:Double x:Key="KnobOffPosition">0</x:Double> |
||||
|
</Styles.Resources> |
||||
|
<Design.PreviewWith> |
||||
|
<StackPanel Margin="20" Width="250" Spacing="24" > |
||||
|
<StackPanel Spacing="12" > |
||||
|
<TextBlock |
||||
|
Text="Automatic updates" |
||||
|
Classes="h1"/> |
||||
|
<TextBlock |
||||
|
Text="Updates will be automaticly Downloaded and installed shile the computer is shutting down or restarting" |
||||
|
TextWrapping="Wrap"/> |
||||
|
<ToggleSwitch HorizontalContentAlignment="Left" |
||||
|
Content="Enable automatic Updates?" |
||||
|
OffContent="Uit" |
||||
|
OnContent="Aan" |
||||
|
VerticalAlignment="Bottom"/> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<StackPanel Spacing="12"> |
||||
|
<TextBlock |
||||
|
Text="Previewer" |
||||
|
Classes="h1"/> |
||||
|
<TextBlock |
||||
|
Text="The previewer Shows a preview off your code, this could slow down your system" |
||||
|
TextWrapping="Wrap"/> |
||||
|
<ToggleSwitch |
||||
|
Content="Previewer" |
||||
|
IsChecked="True" /> |
||||
|
</StackPanel> |
||||
|
</StackPanel> |
||||
|
</Design.PreviewWith> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch"> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource ToggleSwitchContentForeground}" /> |
||||
|
<Setter Property="HorizontalAlignment" Value="Left" /> |
||||
|
<Setter Property="VerticalAlignment" Value="Center" /> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
||||
|
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" /> |
||||
|
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<ControlTemplate> |
||||
|
<Grid Background="{TemplateBinding Background}" |
||||
|
RowDefinitions="Auto,*"> |
||||
|
|
||||
|
<ContentPresenter x:Name="PART_ContentPresenter" |
||||
|
Grid.Row="0" |
||||
|
Content="{TemplateBinding Content}" |
||||
|
ContentTemplate="{TemplateBinding ContentTemplate}" |
||||
|
Margin="{DynamicResource ToggleSwitchTopHeaderMargin}" |
||||
|
VerticalAlignment="Top"/> |
||||
|
|
||||
|
<Grid Grid.Row="1" |
||||
|
MinWidth="{StaticResource ToggleSwitchThemeMinWidth}" |
||||
|
HorizontalAlignment="Left" |
||||
|
VerticalAlignment="Top"> |
||||
|
|
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="{DynamicResource ToggleSwitchPreContentMargin}" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="{DynamicResource ToggleSwitchPostContentMargin}" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="Auto" /> |
||||
|
<ColumnDefinition Width="12" MaxWidth="12" /> |
||||
|
<ColumnDefinition Width="Auto" /> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<Grid x:Name="SwitchAreaGrid" |
||||
|
Grid.RowSpan="3" |
||||
|
Grid.ColumnSpan="3" |
||||
|
TemplatedControl.IsTemplateFocusTarget="True" |
||||
|
Margin="0,5" /> |
||||
|
|
||||
|
<ContentPresenter x:Name="PART_OffContentPresenter" |
||||
|
Grid.RowSpan="3" |
||||
|
Grid.Column="2" |
||||
|
Content="{TemplateBinding OffContent}" |
||||
|
ContentTemplate="{TemplateBinding OffContentTemplate}" |
||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> |
||||
|
|
||||
|
<ContentPresenter x:Name="PART_OnContentPresenter" |
||||
|
Grid.RowSpan="3" |
||||
|
Grid.Column="2" |
||||
|
Content="{TemplateBinding OnContent}" |
||||
|
ContentTemplate="{TemplateBinding OnContentTemplate}" |
||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> |
||||
|
|
||||
|
<Border x:Name="OuterBorder" |
||||
|
Grid.Row="1" |
||||
|
Height="20" |
||||
|
Width="40" |
||||
|
CornerRadius="10" |
||||
|
BorderThickness="{DynamicResource ToggleSwitchOuterBorderStrokeThickness}" /> |
||||
|
|
||||
|
<Border x:Name="SwitchKnobBounds" |
||||
|
Grid.Row="1" |
||||
|
Height="20" |
||||
|
Width="40" |
||||
|
CornerRadius="10" |
||||
|
BorderThickness="{DynamicResource ToggleSwitchOnStrokeThickness}"/> |
||||
|
|
||||
|
<Canvas x:Name="SwitchKnob" Grid.Row="1" |
||||
|
HorizontalAlignment="Left" |
||||
|
Width="20" Height="20"> |
||||
|
|
||||
|
<Grid x:Name="MovingKnobs" |
||||
|
Width="20" Height="20"> |
||||
|
|
||||
|
<Ellipse x:Name="SwitchKnobOn" |
||||
|
Width="10" Height="10" /> |
||||
|
|
||||
|
<Ellipse x:Name="SwitchKnobOff" |
||||
|
Width="10" Height="10" /> |
||||
|
</Grid> |
||||
|
</Canvas> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- NormalState --> |
||||
|
<Style Selector="ToggleSwitch /template/ Grid#SwitchAreaGrid"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchContainerBackground}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch /template/ Border#OuterBorder"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOff}"/> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOff}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOn}"/> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOn}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOn}"/> |
||||
|
<Setter Property="Stroke" Value="{DynamicResource ToggleSwitchKnobStrokeOn}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOff}"/> |
||||
|
<Setter Property="Stroke" Value="{DynamicResource ToggleSwitchKnobStrokeOff}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch /template/ Grid#MovingKnobs"> |
||||
|
<Setter Property="Canvas.Left" Value="{DynamicResource KnobOffPosition}"/> |
||||
|
<Setter Property="Transitions"> |
||||
|
<Transitions> |
||||
|
<DoubleTransition Property="Canvas.Left" Duration="0:0:0.2" Easing="CubicEaseOut"/> |
||||
|
</Transitions> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- PointerOverState --> |
||||
|
<Style Selector="ToggleSwitch:pointerover /template/ Border#OuterBorder"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOffPointerOver}"/> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOffPointerOver}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pointerover /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOffPointerOver}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pointerover /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOnPointerOver}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pointerover /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOnPointerOver}"/> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOnPointerOver}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pointerover /template/ Grid#SwitchAreaGrid"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchContainerBackgroundPointerOver}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- PressedState --> |
||||
|
<Style Selector="ToggleSwitch:pressed /template/ Border#OuterBorder"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOffPressed}"/> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOffPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pressed /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOnPressed}"/> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOnPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pressed /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOffPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pressed /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOnPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:pressed /template/ Grid#SwitchAreaGrid"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchContainerBackgroundPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- DisabledState --> |
||||
|
<Style Selector="ToggleSwitch:disabled"> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource ToggleSwitchHeaderForegroundDisabled}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:disabled /template/ Border#OuterBorder"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOffDisabled}"/> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOffPressed}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:disabled /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOffDisabled}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:disabled /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource ToggleSwitchKnobFillOnDisabled}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:disabled /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Background" Value="{DynamicResource ToggleSwitchFillOnDisabled}"/> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ToggleSwitchStrokeOnDisabled}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- CheckedState --> |
||||
|
<Style Selector="ToggleSwitch:checked /template/ Grid#MovingKnobs"> |
||||
|
<Setter Property="Canvas.Left" Value="{DynamicResource KnobOnPosition}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ Border#OuterBorder"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ ContentPresenter#PART_OffContentPresenter"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:checked /template/ ContentPresenter#PART_OnContentPresenter"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<!--UncheckedState --> |
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ Grid#MovingKnobs"> |
||||
|
<Setter Property="Canvas.Left" Value="{DynamicResource KnobOffPosition}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ Border#OuterBorder"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ Ellipse#SwitchKnobOff"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ Ellipse#SwitchKnobOn"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ Border#SwitchKnobBounds"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ ContentPresenter#PART_OffContentPresenter"> |
||||
|
<Setter Property="Opacity" Value="1"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="ToggleSwitch:unchecked /template/ ContentPresenter#PART_OnContentPresenter"> |
||||
|
<Setter Property="Opacity" Value="0"/> |
||||
|
</Style> |
||||
|
</Styles> |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue