14 changed files with 306 additions and 84 deletions
@ -1,3 +1,32 @@ |
|||||
<Window xmlns="https://github.com/avaloniaui" |
<Window xmlns="https://github.com/avaloniaui" |
||||
Title="Avalonia Render Test"> |
Title="Avalonia Render Test" |
||||
|
xmlns:pages="clr-namespace:RenderTest.Pages;assembly=RenderTest"> |
||||
|
<DockPanel> |
||||
|
<Menu DockPanel.Dock="Top"> |
||||
|
<MenuItem Header="Rendering"> |
||||
|
<MenuItem Header="Draw Dirty Rects" Command="{Binding ToggleDrawDirtyRects}"> |
||||
|
<MenuItem.Icon> |
||||
|
<CheckBox BorderThickness="0" |
||||
|
IsHitTestVisible="False" |
||||
|
IsChecked="{Binding DrawDirtyRects}"/> |
||||
|
</MenuItem.Icon> |
||||
|
</MenuItem> |
||||
|
<MenuItem Header="Draw FPS" Command="{Binding ToggleDrawFps}"> |
||||
|
<MenuItem.Icon> |
||||
|
<CheckBox BorderThickness="0" |
||||
|
IsHitTestVisible="False" |
||||
|
IsChecked="{Binding DrawFps}"/> |
||||
|
</MenuItem.Icon> |
||||
|
</MenuItem> |
||||
|
</MenuItem> |
||||
|
</Menu> |
||||
|
|
||||
|
<TabControl Classes="sidebar"> |
||||
|
<TabControl.Transition> |
||||
|
<CrossFade Duration="0.25"/> |
||||
|
</TabControl.Transition> |
||||
|
<TabItem Header="Animations"><pages:AnimationsPage/></TabItem> |
||||
|
<TabItem Header="Clipping"><pages:ClippingPage/></TabItem> |
||||
|
</TabControl> |
||||
|
</DockPanel> |
||||
</Window> |
</Window> |
||||
@ -0,0 +1,2 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui"> |
||||
|
</UserControl> |
||||
@ -0,0 +1,90 @@ |
|||||
|
using System.Reactive.Linq; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Animation; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.Shapes; |
||||
|
using Avalonia.Data; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using Avalonia.Media; |
||||
|
|
||||
|
namespace RenderTest.Pages |
||||
|
{ |
||||
|
public class AnimationsPage : UserControl |
||||
|
{ |
||||
|
public AnimationsPage() |
||||
|
{ |
||||
|
this.InitializeComponent(); |
||||
|
this.CreateAnimations(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
private void CreateAnimations() |
||||
|
{ |
||||
|
const int Count = 100; |
||||
|
var panel = new WrapPanel(); |
||||
|
|
||||
|
for (var i = 0; i < Count; ++i) |
||||
|
{ |
||||
|
Ellipse ellipse; |
||||
|
var element = new Panel |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(ellipse = new Ellipse |
||||
|
{ |
||||
|
Name = $"ellipse{i}", |
||||
|
Width = 100, |
||||
|
Height = 100, |
||||
|
Fill = Brushes.Blue, |
||||
|
}), |
||||
|
new Path |
||||
|
{ |
||||
|
Data = StreamGeometry.Parse( |
||||
|
"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"), |
||||
|
Fill = Brushes.Green, |
||||
|
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, |
||||
|
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, |
||||
|
RenderTransform = new ScaleTransform(2, 2), |
||||
|
} |
||||
|
}, |
||||
|
Margin = new Thickness(4), |
||||
|
RenderTransform = new ScaleTransform(), |
||||
|
}; |
||||
|
|
||||
|
var start = Animate.Stopwatch.Elapsed; |
||||
|
var index = i % (Count / 2); |
||||
|
var degrees = Animate.Timer |
||||
|
.Select(x => (x - start).TotalSeconds) |
||||
|
.Where(x => (x % Count) >= index && (x % Count) < index + 1) |
||||
|
.Select(x => (x % 1) / 1); |
||||
|
|
||||
|
element.RenderTransform.Bind( |
||||
|
ScaleTransform.ScaleXProperty, |
||||
|
degrees, |
||||
|
BindingPriority.Animation); |
||||
|
|
||||
|
ellipse.PointerEnter += Ellipse_PointerEnter; |
||||
|
ellipse.PointerLeave += Ellipse_PointerLeave; |
||||
|
|
||||
|
panel.Children.Add(element); |
||||
|
} |
||||
|
|
||||
|
Content = panel; |
||||
|
} |
||||
|
|
||||
|
private void Ellipse_PointerEnter(object sender, PointerEventArgs e) |
||||
|
{ |
||||
|
((Ellipse)sender).Fill = Brushes.Red; |
||||
|
} |
||||
|
|
||||
|
private void Ellipse_PointerLeave(object sender, PointerEventArgs e) |
||||
|
{ |
||||
|
((Ellipse)sender).Fill = Brushes.Blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui"> |
||||
|
<Grid ColumnDefinitions="Auto" RowDefinitions="Auto,Auto"> |
||||
|
<Border Name="clipped" |
||||
|
Background="Yellow" |
||||
|
Width="100" |
||||
|
Height="100" |
||||
|
Clip="M 58.625 0.07421875 C 50.305778 0.26687364 42.411858 7.0346526 41.806641 15.595703 C 42.446442 22.063923 39.707425 13.710754 36.982422 12.683594 C 29.348395 6.1821635 16.419398 8.4359222 11.480469 17.195312 C 6.0935256 25.476803 9.8118851 37.71125 18.8125 41.6875 C 9.1554771 40.62945 -0.070876925 49.146842 0.21679688 58.857422 C 0.21545578 60.872512 0.56758794 62.88911 1.2617188 64.78125 C 4.3821886 74.16708 16.298268 78.921772 25.03125 74.326172 C 28.266843 72.062552 26.298191 74.214838 25.414062 76.398438 C 21.407348 85.589198 27.295992 97.294293 37.097656 99.501953 C 46.864883 102.3541 57.82177 94.726518 58.539062 84.580078 C 58.142158 79.498998 59.307538 83.392694 61.207031 85.433594 C 67.532324 93.056874 80.440232 93.192029 86.882812 85.630859 C 93.836392 78.456939 92.396838 65.538666 84.115234 60.009766 C 79.783641 57.904836 83.569793 58.802369 86.375 58.193359 C 96.383335 56.457569 102.87506 44.824101 99.083984 35.394531 C 95.963498 26.008711 84.047451 21.254079 75.314453 25.849609 C 72.078834 28.113269 74.047517 25.960974 74.931641 23.777344 C 78.93827 14.586564 73.049722 2.8815081 63.248047 0.67382812 C 61.721916 0.22817968 60.165597 0.038541919 58.625 0.07421875 z "> |
||||
|
<Border Name="clipChild" Background="{StyleResource ThemeAccentBrush}" Margin="4"> |
||||
|
<!-- Setting opacity puts the TextBox on a new layer --> |
||||
|
<TextBox Text="Avalonia" Opacity="0.9" VerticalAlignment="Center"/> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
<CheckBox Name="useMask" IsChecked="True" Grid.Row="1">Apply Geometry Clip</CheckBox> |
||||
|
</Grid> |
||||
|
</UserControl> |
||||
@ -0,0 +1,48 @@ |
|||||
|
using System; |
||||
|
using System.Reactive.Linq; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Animation; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Data; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using Avalonia.Media; |
||||
|
|
||||
|
namespace RenderTest.Pages |
||||
|
{ |
||||
|
public class ClippingPage : UserControl |
||||
|
{ |
||||
|
private Geometry _clip; |
||||
|
|
||||
|
public ClippingPage() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
CreateAnimations(); |
||||
|
WireUpCheckbox(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
private void CreateAnimations() |
||||
|
{ |
||||
|
var clipped = this.FindControl<Border>("clipChild"); |
||||
|
var degrees = Animate.Timer.Select(x => x.TotalMilliseconds / 5); |
||||
|
clipped.RenderTransform = new RotateTransform(); |
||||
|
clipped.RenderTransform.Bind(RotateTransform.AngleProperty, degrees, BindingPriority.Animation); |
||||
|
clipped.Bind( |
||||
|
Border.BackgroundProperty, |
||||
|
clipped.GetObservable(Control.IsPointerOverProperty) |
||||
|
.Select(x => x ? Brushes.Crimson : AvaloniaProperty.UnsetValue)); |
||||
|
} |
||||
|
|
||||
|
private void WireUpCheckbox() |
||||
|
{ |
||||
|
var useMask = this.FindControl<CheckBox>("useMask"); |
||||
|
var clipped = this.FindControl<Border>("clipped"); |
||||
|
_clip = clipped.Clip; |
||||
|
useMask.Click += (s, e) => clipped.Clip = clipped.Clip == null ? _clip : null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,26 +0,0 @@ |
|||||
<ProjectConfiguration> |
|
||||
<AutoDetectNugetBuildDependencies>true</AutoDetectNugetBuildDependencies> |
|
||||
<BuildPriority>1000</BuildPriority> |
|
||||
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace> |
|
||||
<ConsiderInconclusiveTestsAsPassing>false</ConsiderInconclusiveTestsAsPassing> |
|
||||
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies> |
|
||||
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking> |
|
||||
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking> |
|
||||
<AllowCodeAnalysis>false</AllowCodeAnalysis> |
|
||||
<IgnoreThisComponentCompletely>false</IgnoreThisComponentCompletely> |
|
||||
<RunPreBuildEvents>false</RunPreBuildEvents> |
|
||||
<RunPostBuildEvents>false</RunPostBuildEvents> |
|
||||
<PreviouslyBuiltSuccessfully>true</PreviouslyBuiltSuccessfully> |
|
||||
<InstrumentAssembly>true</InstrumentAssembly> |
|
||||
<PreventSigningOfAssembly>false</PreventSigningOfAssembly> |
|
||||
<AnalyseExecutionTimes>true</AnalyseExecutionTimes> |
|
||||
<DetectStackOverflow>true</DetectStackOverflow> |
|
||||
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace> |
|
||||
<DefaultTestTimeout>60000</DefaultTestTimeout> |
|
||||
<UseBuildConfiguration /> |
|
||||
<UseBuildPlatform /> |
|
||||
<ProxyProcessPath /> |
|
||||
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture> |
|
||||
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState> |
|
||||
<BuildProcessArchitecture>x86</BuildProcessArchitecture> |
|
||||
</ProjectConfiguration> |
|
||||
@ -0,0 +1,40 @@ |
|||||
|
<Styles xmlns="https://github.com/avaloniaui"> |
||||
|
<Style Selector="TabControl.sidebar"> |
||||
|
<Setter Property="Template"> |
||||
|
<ControlTemplate> |
||||
|
<DockPanel> |
||||
|
<ScrollViewer MinWidth="190" Background="{StyleResource ThemeAccentBrush}" DockPanel.Dock="Left"> |
||||
|
<TabStrip Name="PART_TabStrip" |
||||
|
MemberSelector="{Static TabControl.HeaderSelector}" |
||||
|
Items="{TemplateBinding Items}" |
||||
|
SelectedIndex="{TemplateBinding Path=SelectedIndex, Mode=TwoWay}"> |
||||
|
<TabStrip.ItemsPanel> |
||||
|
<ItemsPanelTemplate> |
||||
|
<StackPanel Orientation="Vertical"/> |
||||
|
</ItemsPanelTemplate> |
||||
|
</TabStrip.ItemsPanel> |
||||
|
</TabStrip> |
||||
|
</ScrollViewer> |
||||
|
<Carousel Name="PART_Content" |
||||
|
Margin="8 0 0 0" |
||||
|
MemberSelector="{Static TabControl.ContentSelector}" |
||||
|
Items="{TemplateBinding Items}" |
||||
|
SelectedIndex="{TemplateBinding Path=SelectedIndex}" |
||||
|
Transition="{TemplateBinding Transition}" |
||||
|
Grid.Row="1"/> |
||||
|
</DockPanel> |
||||
|
</ControlTemplate> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="TabControl.sidebar TabStripItem"> |
||||
|
<Setter Property="Foreground" Value="White"/> |
||||
|
<Setter Property="FontSize" Value="14"/> |
||||
|
<Setter Property="Margin" Value="0"/> |
||||
|
<Setter Property="Padding" Value="16"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="TabControl.sidebar TabStripItem:selected"> |
||||
|
<Setter Property="Background" Value="{StyleResource ThemeAccentBrush2}"/> |
||||
|
</Style> |
||||
|
</Styles> |
||||
@ -0,0 +1,34 @@ |
|||||
|
using System; |
||||
|
using ReactiveUI; |
||||
|
|
||||
|
namespace RenderTest.ViewModels |
||||
|
{ |
||||
|
public class MainWindowViewModel : ReactiveObject |
||||
|
{ |
||||
|
private bool drawDirtyRects = true; |
||||
|
private bool drawFps = true; |
||||
|
|
||||
|
public MainWindowViewModel() |
||||
|
{ |
||||
|
ToggleDrawDirtyRects = ReactiveCommand.Create(); |
||||
|
ToggleDrawDirtyRects.Subscribe(_ => DrawDirtyRects = !DrawDirtyRects); |
||||
|
ToggleDrawFps = ReactiveCommand.Create(); |
||||
|
ToggleDrawFps.Subscribe(_ => DrawFps = !DrawFps); |
||||
|
} |
||||
|
|
||||
|
public bool DrawDirtyRects |
||||
|
{ |
||||
|
get { return drawDirtyRects; } |
||||
|
set { this.RaiseAndSetIfChanged(ref drawDirtyRects, value); } |
||||
|
} |
||||
|
|
||||
|
public bool DrawFps |
||||
|
{ |
||||
|
get { return drawFps; } |
||||
|
set { this.RaiseAndSetIfChanged(ref drawFps, value); } |
||||
|
} |
||||
|
|
||||
|
public ReactiveCommand<object> ToggleDrawDirtyRects { get; } |
||||
|
public ReactiveCommand<object> ToggleDrawFps { get; } |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue