14 changed files with 306 additions and 84 deletions
@ -1,3 +1,32 @@ |
|||
<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> |
|||
@ -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