committed by
GitHub
702 changed files with 12131 additions and 4718 deletions
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,16 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings> |
|||
<EnableTrimAnalyzer>true</EnableTrimAnalyzer> |
|||
<TrimmerSingleWarn>false</TrimmerSingleWarn> |
|||
<IsTrimmable>true</IsTrimmable> |
|||
</PropertyGroup> |
|||
<!-- Remove check for the AOT when we get rid of dependencies with reflection --> |
|||
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(PublishAot)' != 'true'"> |
|||
<ILLinkTreatWarningsAsErrors>true</ILLinkTreatWarningsAsErrors> |
|||
<!-- Trim warnings --> |
|||
<WarningsAsErrors>$(WarningsAsErrors);IL2000;IL2001;IL2002;IL2003;IL2004;IL2005;IL2006;IL2007;IL2008;IL2009;IL2010;IL2011;IL2012;IL2013;IL2014;IL2015;IL2016;IL2017;IL2018;IL2019;IL2020;IL2021;IL2022;IL2023;IL2024;IL2025;IL2026;IL2027;IL2028;IL2029;IL2030;IL2031;IL2032;IL2033;IL2034;IL2035;IL2036;IL2037;IL2038;IL2039;IL2040;IL2041;IL2042;IL2043;IL2044;IL2045;IL2046;IL2047;IL2048;IL2049;IL2050;IL2051;IL2052;IL2053;IL2054;IL2055;IL2056;IL2057;IL2058;IL2059;IL2060;IL2061;IL2062;IL2063;IL2064;IL2065;IL2066;IL2067;IL2068;IL2069;IL2070;IL2071;IL2072;IL2073;IL2074;IL2075;IL2076;IL2077;IL2078;IL2079;IL2080;IL2081;IL2082;IL2083;IL2084;IL2085;IL2086;IL2087;IL2088;IL2089;IL2090;IL2091;IL2092;IL2093;IL2094;IL2095;IL2096;IL2097;IL2098;IL2099;IL2100;IL2101;IL2102;IL2103;IL2104;IL2105;IL2106;IL2107;IL2108;IL2109;IL2110;IL2111;IL2112;IL2113;IL2114;IL2115;IL2116;IL2117;IL2118;IL2119;IL2120;IL2121;IL2122;IL2123;IL2124;IL2125;IL2126;IL2127;IL2128;IL2129;IL2130;IL2131;IL2132;IL2133;IL2134;IL2135;IL2136;IL2137;IL2138;IL2139;IL2140;IL2141;IL2142;IL2143;IL2144;IL2145;IL2146;IL2147;IL2148;IL2149;IL2150;IL2151;IL2152;IL2153;IL2154;IL2155;IL2156;IL2157</WarningsAsErrors> |
|||
<!-- NativeAOT warnings --> |
|||
<WarningsAsErrors>$(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056</WarningsAsErrors> |
|||
</PropertyGroup> |
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"profiles": { |
|||
"ControlCatalog.NetCore": { |
|||
"commandName": "Project" |
|||
}, |
|||
"Dxgi": { |
|||
"commandName": "Project", |
|||
"commandLineArgs": "--dxgi" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Text; |
|||
using Avalonia.Data.Converters; |
|||
|
|||
namespace ControlCatalog.Converter |
|||
{ |
|||
public class DegToRadConverter : IValueConverter |
|||
{ |
|||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) |
|||
{ |
|||
if (value is double rad) |
|||
{ |
|||
return rad * 180.0d / Math.PI; |
|||
} |
|||
return 0.0d; |
|||
} |
|||
|
|||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) |
|||
{ |
|||
if (value is double deg) |
|||
{ |
|||
return deg / 180.0d * Math.PI; |
|||
} |
|||
return 0.0d; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:local="using:ControlCatalog.Pages" |
|||
xmlns:converters="using:ControlCatalog.Converter" |
|||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
|||
x:Class="ControlCatalog.Pages.CustomDrawing"> |
|||
|
|||
<UserControl.Resources> |
|||
<converters:DegToRadConverter x:Key="DegToRadConverter"/> |
|||
</UserControl.Resources> |
|||
|
|||
<Grid> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition/> |
|||
<ColumnDefinition/> |
|||
<ColumnDefinition/> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="Auto"/> |
|||
<RowDefinition/> |
|||
</Grid.RowDefinitions> |
|||
|
|||
<StackPanel Orientation="Vertical"> |
|||
<TextBlock Text="Translation" HorizontalAlignment="Center"/> |
|||
<Grid ColumnDefinitions="*,*" |
|||
RowDefinitions="Auto,Auto" |
|||
> |
|||
<TextBlock Text="Horizontal"/> |
|||
<TextBlock Text="Vertical" Grid.Column="1"/> |
|||
<TextBox IsEnabled="False" |
|||
Text="{Binding ElementName=CustomDrawingControl, |
|||
Path=ViewportCenterX, |
|||
Mode=OneWay, |
|||
StringFormat=\{0:g4\}}" |
|||
Grid.Row="1" |
|||
/> |
|||
<TextBox IsEnabled="False" |
|||
Text="{Binding ElementName=CustomDrawingControl, |
|||
Path=ViewportCenterY, |
|||
Mode=OneWay, |
|||
StringFormat=\{0:g4\}}" |
|||
Grid.Row="1" Grid.Column="1" |
|||
/> |
|||
</Grid> |
|||
</StackPanel> |
|||
|
|||
<StackPanel Orientation="Vertical" Grid.Column="1" |
|||
> |
|||
<TextBlock Text="Rotation" HorizontalAlignment="Center"/> |
|||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" |
|||
> |
|||
<Button Content="➖" Width="40" Height="40" |
|||
VerticalContentAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
Click="RotateMinus" |
|||
/> |
|||
<TextBox IsEnabled="False" |
|||
Text="{Binding ElementName=CustomDrawingControl, |
|||
Path=Rotation, |
|||
Converter={StaticResource DegToRadConverter}, |
|||
Mode=OneWay, |
|||
StringFormat=\{0:g4\}}" |
|||
Grid.Row="1" Grid.Column="1" |
|||
/> |
|||
<Button Content="➕" Width="40" Height="40" |
|||
VerticalContentAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
Click="RotatePlus" |
|||
/> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
|
|||
<StackPanel Orientation="Vertical" Grid.Column="2" |
|||
> |
|||
<TextBlock Text="Scale" HorizontalAlignment="Center"/> |
|||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" |
|||
> |
|||
<Button Content="➖" Width="40" Height="40" |
|||
VerticalContentAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
Click="ZoomOut" |
|||
/> |
|||
<TextBox IsEnabled="False" |
|||
Text="{Binding ElementName=CustomDrawingControl, |
|||
Path=Scale, |
|||
Mode=OneWay, |
|||
StringFormat=\{0:g4\}}" |
|||
Grid.Row="1" Grid.Column="1" |
|||
/> |
|||
<Button Content="➕" Width="40" Height="40" |
|||
VerticalContentAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
Click="ZoomIn" |
|||
/> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
|
|||
<Grid Grid.Row="1" Grid.ColumnSpan="3" ClipToBounds="True"> |
|||
<local:CustomDrawingExampleControl |
|||
x:Name="CustomDrawingControl" |
|||
/> |
|||
</Grid> |
|||
</Grid> |
|||
|
|||
</UserControl> |
|||
@ -0,0 +1,67 @@ |
|||
using System; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Markup.Xaml; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public partial class CustomDrawing : UserControl |
|||
{ |
|||
public CustomDrawing() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
|
|||
private CustomDrawingExampleControl? _customControl; |
|||
public CustomDrawingExampleControl CustomDrawingControl |
|||
{ |
|||
get |
|||
{ |
|||
if (_customControl is not null) |
|||
return _customControl; |
|||
throw new System.Exception("Control did not get initialized"); |
|||
} |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
var cntrl = this.FindControl<CustomDrawingExampleControl>("CustomDrawingControl"); |
|||
if (cntrl != null) |
|||
{ |
|||
_customControl = cntrl; |
|||
} |
|||
else |
|||
{ |
|||
// be sad about it
|
|||
} |
|||
} |
|||
|
|||
private void RotateMinus (object? sender, RoutedEventArgs e) |
|||
{ |
|||
if (_customControl is null) return; |
|||
_customControl.Rotation -= Math.PI / 20.0d; |
|||
} |
|||
|
|||
private void RotatePlus(object? sender, RoutedEventArgs e) |
|||
{ |
|||
if (_customControl is null) |
|||
return; |
|||
_customControl.Rotation += Math.PI / 20.0d; |
|||
} |
|||
|
|||
private void ZoomIn(object? sender, RoutedEventArgs e) |
|||
{ |
|||
if (_customControl is null) |
|||
return; |
|||
_customControl.Scale *= 1.2d; |
|||
} |
|||
|
|||
private void ZoomOut(object? sender, RoutedEventArgs e) |
|||
{ |
|||
if (_customControl is null) |
|||
return; |
|||
_customControl.Scale /= 1.2d; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,215 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Text; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Media; |
|||
using Avalonia.Input; |
|||
using Avalonia.Threading; |
|||
using Avalonia.Controls.Shapes; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class CustomDrawingExampleControl : Control |
|||
{ |
|||
private Point _cursorPoint; |
|||
|
|||
|
|||
public StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Scale), 1.0d); |
|||
public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); } |
|||
|
|||
public StyledProperty<double> RotationProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Rotation)); |
|||
/// <summary>
|
|||
/// Rotation, measured in Radians!
|
|||
/// </summary>
|
|||
public double Rotation |
|||
{ |
|||
get => GetValue(RotationProperty); |
|||
set |
|||
{ |
|||
double valueToUse = value % (Math.PI * 2); |
|||
SetValue(RotationProperty, valueToUse); |
|||
} |
|||
} |
|||
|
|||
public StyledProperty<double> ViewportCenterYProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterY), 0.0d); |
|||
public double ViewportCenterY { get => GetValue(ViewportCenterYProperty); set => SetValue(ViewportCenterYProperty, value); } |
|||
|
|||
public StyledProperty<double> ViewportCenterXProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterX), 0.0d); |
|||
public double ViewportCenterX { get => GetValue(ViewportCenterXProperty); set => SetValue(ViewportCenterXProperty, value); } |
|||
|
|||
private IPen _pen; |
|||
|
|||
private System.Diagnostics.Stopwatch _timeKeeper = System.Diagnostics.Stopwatch.StartNew(); |
|||
|
|||
private bool _isPointerCaptured = false; |
|||
|
|||
public CustomDrawingExampleControl() |
|||
{ |
|||
_pen = new Pen(new SolidColorBrush(Colors.Black), lineCap: PenLineCap.Round); |
|||
|
|||
var _arc = new ArcSegment() |
|||
{ |
|||
IsLargeArc = false, |
|||
Point = new Point(0, 0), |
|||
RotationAngle = 0, |
|||
Size = new Size(25, 25), |
|||
SweepDirection = SweepDirection.Clockwise, |
|||
|
|||
}; |
|||
StreamGeometry sg = new StreamGeometry(); |
|||
var cntx = sg.Open(); |
|||
cntx.BeginFigure(new Point(-25.0d, -10.0d), false); |
|||
cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise); |
|||
cntx.EndFigure(true); |
|||
_smileGeometry = sg.Clone(); |
|||
} |
|||
|
|||
private Geometry _smileGeometry; |
|||
|
|||
protected override void OnPointerMoved(PointerEventArgs e) |
|||
{ |
|||
base.OnPointerMoved(e); |
|||
|
|||
Point previousPoint = _cursorPoint; |
|||
|
|||
_cursorPoint = e.GetPosition(this); |
|||
|
|||
if (_isPointerCaptured) |
|||
{ |
|||
Point oldWorldPoint = UIPointToWorldPoint(previousPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
|||
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
|||
|
|||
Vector diff = newWorldPoint - oldWorldPoint; |
|||
|
|||
ViewportCenterX -= diff.X; |
|||
ViewportCenterY -= diff.Y; |
|||
} |
|||
} |
|||
|
|||
protected override void OnPointerPressed(PointerPressedEventArgs e) |
|||
{ |
|||
e.Handled = true; |
|||
e.Pointer.Capture(this); |
|||
_isPointerCaptured = true; |
|||
base.OnPointerPressed(e); |
|||
} |
|||
|
|||
protected override void OnPointerWheelChanged(PointerWheelEventArgs e) |
|||
{ |
|||
base.OnPointerWheelChanged(e); |
|||
var oldScale = Scale; |
|||
Scale *= (1.0d + e.Delta.Y / 12.0d); |
|||
|
|||
Point oldWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, oldScale, Rotation); |
|||
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
|||
|
|||
Vector diff = newWorldPoint - oldWorldPoint; |
|||
|
|||
ViewportCenterX -= diff.X; |
|||
ViewportCenterY -= diff.Y; |
|||
} |
|||
|
|||
protected override void OnPointerReleased(PointerReleasedEventArgs e) |
|||
{ |
|||
e.Pointer.Capture(null); |
|||
_isPointerCaptured = false; |
|||
base.OnPointerReleased(e); |
|||
} |
|||
|
|||
public override void Render(DrawingContext context) |
|||
{ |
|||
var localBounds = new Rect(new Size(this.Bounds.Width, this.Bounds.Height)); |
|||
var clip = context.PushClip(this.Bounds); |
|||
context.DrawRectangle(Brushes.White, _pen, localBounds, 1.0d); |
|||
|
|||
var halfMax = Math.Max(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) * Math.Sqrt(2.0d); |
|||
var halfMin = Math.Min(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) / 1.3d; |
|||
var halfWidth = this.Bounds.Width / 2.0d; |
|||
var halfHeight = this.Bounds.Height / 2.0d; |
|||
|
|||
// 0,0 refers to the top-left of the control now. It is not prime time to draw gui stuff because it'll be under the world
|
|||
|
|||
var translateModifier = context.PushPreTransform(Avalonia.Matrix.CreateTranslation(new Avalonia.Vector(halfWidth, halfHeight))); |
|||
|
|||
// now 0,0 refers to the ViewportCenter(X,Y).
|
|||
var rotationMatrix = Avalonia.Matrix.CreateRotation(Rotation); |
|||
var rotationModifier = context.PushPreTransform(rotationMatrix); |
|||
|
|||
// everything is rotated but not scaled
|
|||
|
|||
var scaleModifier = context.PushPreTransform(Avalonia.Matrix.CreateScale(Scale, -Scale)); |
|||
|
|||
var mapPositionModifier = context.PushPreTransform(Matrix.CreateTranslation(new Vector(-ViewportCenterX, -ViewportCenterY))); |
|||
|
|||
// now everything is rotated and scaled, and at the right position, now we're drawing strictly in world coordinates
|
|||
|
|||
context.DrawEllipse(Brushes.White, _pen, new Point(0.0d, 0.0d), 50.0d, 50.0d); |
|||
context.DrawLine(_pen, new Point(-25.0d, -5.0d), new Point(-25.0d, 15.0d)); |
|||
context.DrawLine(_pen, new Point(25.0d, -5.0d), new Point(25.0d, 15.0d)); |
|||
context.DrawGeometry(null, _pen, _smileGeometry); |
|||
|
|||
Point cursorInWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
|||
context.DrawEllipse(Brushes.Gray, _pen, cursorInWorldPoint, 20.0d, 20.0d); |
|||
|
|||
|
|||
for (int i = 0; i < 10; i++) |
|||
{ |
|||
double orbitRadius = i * 100 + 200; |
|||
var orbitInput = ((_timeKeeper.Elapsed.TotalMilliseconds + 987654d) / orbitRadius) / 10.0d; |
|||
if (i % 3 == 0) |
|||
orbitInput *= -1; |
|||
Point orbitPosition = new Point(Math.Sin(orbitInput) * orbitRadius, Math.Cos(orbitInput) * orbitRadius); |
|||
context.DrawEllipse(Brushes.Gray, _pen, orbitPosition, 20.0d, 20.0d); |
|||
} |
|||
|
|||
|
|||
// end drawing the world
|
|||
|
|||
mapPositionModifier.Dispose(); |
|||
|
|||
scaleModifier.Dispose(); |
|||
|
|||
rotationModifier.Dispose(); |
|||
translateModifier.Dispose(); |
|||
|
|||
// this is prime time to draw gui stuff
|
|||
|
|||
context.DrawLine(_pen, _cursorPoint + new Vector(-20, 0), _cursorPoint + new Vector(20, 0)); |
|||
context.DrawLine(_pen, _cursorPoint + new Vector(0, -20), _cursorPoint + new Vector(0, 20)); |
|||
|
|||
clip.Dispose(); |
|||
|
|||
// oh and draw again when you can, no rush, right?
|
|||
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); |
|||
} |
|||
|
|||
private Point UIPointToWorldPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation) |
|||
{ |
|||
Point workingPoint = new Point(inPoint.X, -inPoint.Y); |
|||
workingPoint += new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d); |
|||
workingPoint /= scale; |
|||
|
|||
workingPoint = Matrix.CreateRotation(rotation).Transform(workingPoint); |
|||
|
|||
workingPoint += new Vector(viewportCenterX, viewportCenterY); |
|||
|
|||
return workingPoint; |
|||
} |
|||
|
|||
private Point WorldPointToUIPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation) |
|||
{ |
|||
Point workingPoint = new Point(inPoint.X, inPoint.Y); |
|||
|
|||
workingPoint -= new Vector(viewportCenterX, viewportCenterY); |
|||
// undo rotation
|
|||
workingPoint = Matrix.CreateRotation(-rotation).Transform(workingPoint); |
|||
workingPoint *= scale; |
|||
workingPoint -= new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d); |
|||
workingPoint = new Point(workingPoint.X, -workingPoint.Y); |
|||
|
|||
return workingPoint; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:viewModels="using:ControlCatalog.ViewModels" |
|||
mc:Ignorable="d" |
|||
d:DesignWidth="800" |
|||
d:DesignHeight="450" |
|||
x:DataType="viewModels:RefreshContainerViewModel" |
|||
x:Class="ControlCatalog.Pages.RefreshContainerPage"> |
|||
<DockPanel HorizontalAlignment="Stretch" |
|||
Height="600" |
|||
VerticalAlignment="Top"> |
|||
<Label DockPanel.Dock="Top">A control that supports pull to refresh</Label> |
|||
<RefreshContainer Name="Refresh" |
|||
DockPanel.Dock="Bottom" |
|||
HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Stretch" |
|||
PullDirection="TopToBottom" |
|||
RefreshRequested="RefreshContainerPage_RefreshRequested" |
|||
Margin="5"> |
|||
<ListBox HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Top" |
|||
Items="{Binding Items}"/> |
|||
</RefreshContainer> |
|||
</DockPanel> |
|||
</UserControl> |
|||
@ -0,0 +1,36 @@ |
|||
using System.Threading.Tasks; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using ControlCatalog.ViewModels; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class RefreshContainerPage : UserControl |
|||
{ |
|||
private RefreshContainerViewModel _viewModel; |
|||
|
|||
public RefreshContainerPage() |
|||
{ |
|||
this.InitializeComponent(); |
|||
|
|||
_viewModel = new RefreshContainerViewModel(); |
|||
|
|||
DataContext = _viewModel; |
|||
} |
|||
|
|||
private async void RefreshContainerPage_RefreshRequested(object? sender, RefreshRequestedEventArgs e) |
|||
{ |
|||
var deferral = e.GetDeferral(); |
|||
|
|||
await _viewModel.AddToTop(); |
|||
|
|||
deferral.Complete(); |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Reactive; |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Controls.Notifications; |
|||
using ControlCatalog.Pages; |
|||
using MiniMvvm; |
|||
|
|||
namespace ControlCatalog.ViewModels |
|||
{ |
|||
public class RefreshContainerViewModel : ViewModelBase |
|||
{ |
|||
public ObservableCollection<string> Items { get; } |
|||
|
|||
public RefreshContainerViewModel() |
|||
{ |
|||
Items = new ObservableCollection<string>(Enumerable.Range(1, 200).Select(i => $"Item {i}")); |
|||
} |
|||
|
|||
public async Task AddToTop() |
|||
{ |
|||
await Task.Delay(3000); |
|||
Items.Insert(0, $"Item {200 - Items.Count}"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<Application |
|||
xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
x:Class="ReactiveUIDemo.App"> |
|||
<Application.Styles> |
|||
<FluentTheme /> |
|||
</Application.Styles> |
|||
</Application> |
|||
@ -0,0 +1,37 @@ |
|||
using Avalonia; |
|||
using Avalonia.Controls.ApplicationLifetimes; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.ReactiveUI; |
|||
using ReactiveUI; |
|||
using ReactiveUIDemo.ViewModels; |
|||
using ReactiveUIDemo.Views; |
|||
using Splat; |
|||
|
|||
namespace ReactiveUIDemo |
|||
{ |
|||
public class App : Application |
|||
{ |
|||
public override void Initialize() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
Locator.CurrentMutable.Register(() => new FooView(), typeof(IViewFor<FooViewModel>)); |
|||
Locator.CurrentMutable.Register(() => new BarView(), typeof(IViewFor<BarViewModel>)); |
|||
} |
|||
|
|||
public override void OnFrameworkInitializationCompleted() |
|||
{ |
|||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) |
|||
desktop.MainWindow = new MainWindow(); |
|||
base.OnFrameworkInitializationCompleted(); |
|||
} |
|||
|
|||
public static int Main(string[] args) |
|||
=> BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); |
|||
|
|||
public static AppBuilder BuildAvaloniaApp() |
|||
=> AppBuilder.Configure<App>() |
|||
.UsePlatformDetect() |
|||
.UseReactiveUI() |
|||
.LogToTrace(); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<Window xmlns="https://github.com/avaloniaui" |
|||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' |
|||
x:Class="ReactiveUIDemo.MainWindow" |
|||
xmlns:vm="using:ReactiveUIDemo.ViewModels" |
|||
xmlns:rxui="using:Avalonia.ReactiveUI" |
|||
Title="AvaloniaUI ReactiveUI Demo" |
|||
x:DataType="vm:MainWindowViewModel"> |
|||
<TabControl TabStripPlacement="Left"> |
|||
<TabItem Header="RoutedViewHost"> |
|||
<DockPanel DataContext="{Binding RoutedViewHost}"> |
|||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" Spacing="8"> |
|||
<Button Command="{Binding ShowFoo}">Foo</Button> |
|||
<Button Command="{Binding ShowBar}">Bar</Button> |
|||
</StackPanel> |
|||
<rxui:RoutedViewHost Router="{Binding Router}"/> |
|||
</DockPanel> |
|||
</TabItem> |
|||
</TabControl> |
|||
</Window> |
|||
@ -0,0 +1,22 @@ |
|||
using ReactiveUIDemo.ViewModels; |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
|
|||
namespace ReactiveUIDemo |
|||
{ |
|||
public class MainWindow : Window |
|||
{ |
|||
public MainWindow() |
|||
{ |
|||
this.InitializeComponent(); |
|||
this.DataContext = new MainWindowViewModel(); |
|||
this.AttachDevTools(); |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" /> |
|||
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" /> |
|||
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Update="Views\BarView.axaml.cs"> |
|||
<DependentUpon>BarView.axaml</DependentUpon> |
|||
</Compile> |
|||
<Compile Update="Views\FooView.axaml.cs"> |
|||
<DependentUpon>FooView.axaml</DependentUpon> |
|||
</Compile> |
|||
</ItemGroup> |
|||
|
|||
<Import Project="..\..\build\SampleApp.props" /> |
|||
<Import Project="..\..\build\ReferenceCoreLibraries.props" /> |
|||
<Import Project="..\..\build\BuildTargets.targets" /> |
|||
<Import Project="..\..\build\Rx.props" /> |
|||
<Import Project="..\..\build\ReactiveUI.props" /> |
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
using ReactiveUI; |
|||
|
|||
namespace ReactiveUIDemo.ViewModels |
|||
{ |
|||
internal class BarViewModel : ReactiveObject, IRoutableViewModel |
|||
{ |
|||
public BarViewModel(IScreen screen) => HostScreen = screen; |
|||
public string UrlPathSegment => "Bar"; |
|||
public IScreen HostScreen { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using ReactiveUI; |
|||
|
|||
namespace ReactiveUIDemo.ViewModels |
|||
{ |
|||
internal class FooViewModel : ReactiveObject, IRoutableViewModel |
|||
{ |
|||
public FooViewModel(IScreen screen) => HostScreen = screen; |
|||
public string UrlPathSegment => "Foo"; |
|||
public IScreen HostScreen { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using ReactiveUI; |
|||
|
|||
namespace ReactiveUIDemo.ViewModels |
|||
{ |
|||
internal class MainWindowViewModel : ReactiveObject |
|||
{ |
|||
public RoutedViewHostPageViewModel RoutedViewHost { get; } = new(); |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using ReactiveUI; |
|||
|
|||
namespace ReactiveUIDemo.ViewModels |
|||
{ |
|||
internal class RoutedViewHostPageViewModel : ReactiveObject, IScreen |
|||
{ |
|||
public RoutedViewHostPageViewModel() |
|||
{ |
|||
Foo = new(this); |
|||
Bar = new(this); |
|||
Router.Navigate.Execute(Foo); |
|||
} |
|||
|
|||
public RoutingState Router { get; } = new(); |
|||
public FooViewModel Foo { get; } |
|||
public BarViewModel Bar { get; } |
|||
|
|||
public void ShowFoo() => Router.Navigate.Execute(Foo); |
|||
public void ShowBar() => Router.Navigate.Execute(Bar); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
|||
x:Class="ReactiveUIDemo.Views.BarView" |
|||
HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Stretch"> |
|||
<Border Background="Blue"> |
|||
<TextBlock HorizontalAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
FontSize="48"> |
|||
Bar! |
|||
</TextBlock> |
|||
</Border> |
|||
</UserControl> |
|||
@ -0,0 +1,28 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using ReactiveUI; |
|||
using ReactiveUIDemo.ViewModels; |
|||
|
|||
namespace ReactiveUIDemo.Views |
|||
{ |
|||
internal partial class BarView : UserControl, IViewFor<BarViewModel> |
|||
{ |
|||
public BarView() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
|
|||
public BarViewModel? ViewModel { get; set; } |
|||
|
|||
object? IViewFor.ViewModel |
|||
{ |
|||
get => ViewModel; |
|||
set => ViewModel = (BarViewModel?)value; |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
|||
x:Class="ReactiveUIDemo.Views.FooView" |
|||
HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Stretch"> |
|||
<Border Background="Red"> |
|||
<TextBlock HorizontalAlignment="Center" |
|||
VerticalAlignment="Center" |
|||
FontSize="48"> |
|||
Foo! |
|||
</TextBlock> |
|||
</Border> |
|||
</UserControl> |
|||
@ -0,0 +1,28 @@ |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml; |
|||
using ReactiveUI; |
|||
using ReactiveUIDemo.ViewModels; |
|||
|
|||
namespace ReactiveUIDemo.Views |
|||
{ |
|||
internal partial class FooView : UserControl, IViewFor<FooViewModel> |
|||
{ |
|||
public FooView() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
|
|||
public FooViewModel? ViewModel { get; set; } |
|||
|
|||
object? IViewFor.ViewModel |
|||
{ |
|||
get => ViewModel; |
|||
set => ViewModel = (FooViewModel?)value; |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -1,5 +0,0 @@ |
|||
<Application xmlns="https://github.com/avaloniaui"> |
|||
<Application.Styles> |
|||
<SimpleTheme Mode="Light" /> |
|||
</Application.Styles> |
|||
</Application> |
|||
@ -1,21 +0,0 @@ |
|||
using Avalonia; |
|||
using Avalonia.Controls.ApplicationLifetimes; |
|||
using Avalonia.Markup.Xaml; |
|||
|
|||
namespace Direct3DInteropSample |
|||
{ |
|||
public class App : Application |
|||
{ |
|||
public override void Initialize() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
public override void OnFrameworkInitializationCompleted() |
|||
{ |
|||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) |
|||
desktop.MainWindow = new MainWindow(); |
|||
base.OnFrameworkInitializationCompleted(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net461</TargetFramework> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<PackageReference Include="SharpDX.Mathematics" Version="4.0.1" /> |
|||
<PackageReference Include="SharpDX.D3DCompiler" Version="4.0.1" /> |
|||
<Compile Update="**\*.paml.cs"> |
|||
<DependentUpon>%(Filename)</DependentUpon> |
|||
</Compile> |
|||
<EmbeddedResource Include="**\*.paml"> |
|||
<SubType>Designer</SubType> |
|||
</EmbeddedResource> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<None Remove="MiniCube.fx" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<EmbeddedResource Include="MiniCube.fx"> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</EmbeddedResource> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" /> |
|||
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" /> |
|||
<ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" /> |
|||
<ProjectReference Include="..\..\MiniMvvm\MiniMvvm.csproj" /> |
|||
</ItemGroup> |
|||
<Import Project="..\..\..\build\Rx.props" /> |
|||
<Import Project="..\..\..\build\ReferenceCoreLibraries.props" /> |
|||
</Project> |
|||
@ -1,283 +0,0 @@ |
|||
using System; |
|||
|
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Direct2D1; |
|||
using Avalonia.Direct2D1.Media; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering; |
|||
|
|||
using SharpDX; |
|||
using SharpDX.D3DCompiler; |
|||
using SharpDX.Direct2D1; |
|||
using SharpDX.Direct3D; |
|||
using SharpDX.Direct3D11; |
|||
using SharpDX.DXGI; |
|||
|
|||
using AlphaMode = SharpDX.Direct2D1.AlphaMode; |
|||
using Buffer = SharpDX.Direct3D11.Buffer; |
|||
using DeviceContext = SharpDX.Direct2D1.DeviceContext; |
|||
using Factory2 = SharpDX.DXGI.Factory2; |
|||
using InputElement = SharpDX.Direct3D11.InputElement; |
|||
using Matrix = SharpDX.Matrix; |
|||
using PixelFormat = SharpDX.Direct2D1.PixelFormat; |
|||
using Resource = SharpDX.Direct3D11.Resource; |
|||
|
|||
namespace Direct3DInteropSample |
|||
{ |
|||
public class MainWindow : Window |
|||
{ |
|||
Texture2D _backBuffer; |
|||
RenderTargetView _renderView; |
|||
Texture2D _depthBuffer; |
|||
DepthStencilView _depthView; |
|||
private readonly SwapChain _swapChain; |
|||
private SwapChainDescription1 _desc; |
|||
private Matrix _proj = Matrix.Identity; |
|||
private readonly Matrix _view; |
|||
private Buffer _contantBuffer; |
|||
private DeviceContext _deviceContext; |
|||
private readonly MainWindowViewModel _model; |
|||
|
|||
public MainWindow() |
|||
{ |
|||
DataContext = _model = new MainWindowViewModel(); |
|||
|
|||
_desc = new SwapChainDescription1() |
|||
{ |
|||
BufferCount = 1, |
|||
Width = (int)ClientSize.Width, |
|||
Height = (int)ClientSize.Height, |
|||
Format = Format.R8G8B8A8_UNorm, |
|||
SampleDescription = new SampleDescription(1, 0), |
|||
SwapEffect = SwapEffect.Discard, |
|||
Usage = Usage.RenderTargetOutput |
|||
}; |
|||
|
|||
using (var factory = Direct2D1Platform.DxgiDevice.Adapter.GetParent<Factory2>()) |
|||
{ |
|||
_swapChain = new SwapChain1(factory, Direct2D1Platform.DxgiDevice, PlatformImpl?.Handle.Handle ?? IntPtr.Zero, ref _desc); |
|||
} |
|||
|
|||
_deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None) |
|||
{ |
|||
DotsPerInch = new Size2F(96, 96) |
|||
}; |
|||
|
|||
CreateMesh(); |
|||
|
|||
_view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY); |
|||
|
|||
this.GetObservable(ClientSizeProperty).Subscribe(Resize); |
|||
|
|||
Resize(ClientSize); |
|||
|
|||
AvaloniaXamlLoader.Load(this); |
|||
|
|||
Background = Avalonia.Media.Brushes.Transparent; |
|||
} |
|||
|
|||
|
|||
protected override void HandlePaint(Rect rect) |
|||
{ |
|||
var viewProj = Matrix.Multiply(_view, _proj); |
|||
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; |
|||
|
|||
// Clear views
|
|||
context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0); |
|||
context.ClearRenderTargetView(_renderView, Color.White); |
|||
|
|||
// Update WorldViewProj Matrix
|
|||
var worldViewProj = Matrix.RotationX((float)_model.RotationX) * Matrix.RotationY((float)_model.RotationY) |
|||
* Matrix.RotationZ((float)_model.RotationZ) |
|||
* Matrix.Scaling((float)_model.Zoom) |
|||
* viewProj; |
|||
worldViewProj.Transpose(); |
|||
context.UpdateSubresource(ref worldViewProj, _contantBuffer); |
|||
|
|||
// Draw the cube
|
|||
context.Draw(36, 0); |
|||
base.HandlePaint(rect); |
|||
|
|||
// Present!
|
|||
_swapChain.Present(0, PresentFlags.None); |
|||
} |
|||
|
|||
private void CreateMesh() |
|||
{ |
|||
var device = Direct2D1Platform.Direct3D11Device; |
|||
|
|||
// Compile Vertex and Pixel shaders
|
|||
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0"); |
|||
var vertexShader = new VertexShader(device, vertexShaderByteCode); |
|||
|
|||
var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "PS", "ps_4_0"); |
|||
var pixelShader = new PixelShader(device, pixelShaderByteCode); |
|||
|
|||
var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode); |
|||
|
|||
var inputElements = new[] |
|||
{ |
|||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), |
|||
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) |
|||
}; |
|||
|
|||
// Layout from VertexShader input signature
|
|||
var layout = new InputLayout( |
|||
device, |
|||
signature, |
|||
inputElements); |
|||
|
|||
// Instantiate Vertex buffer from vertex data
|
|||
var vertices = Buffer.Create( |
|||
device, |
|||
BindFlags.VertexBuffer, |
|||
new[] |
|||
{ |
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
|
|||
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), |
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), |
|||
|
|||
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
|
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), |
|||
|
|||
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
|
|||
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), |
|||
|
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
|
|||
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), |
|||
|
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
|
|||
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), |
|||
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), |
|||
|
|||
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
|
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), |
|||
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), |
|||
}); |
|||
|
|||
// Create Constant Buffer
|
|||
_contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); |
|||
|
|||
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; |
|||
|
|||
// Prepare All the stages
|
|||
context.InputAssembler.InputLayout = layout; |
|||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; |
|||
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0)); |
|||
context.VertexShader.SetConstantBuffer(0, _contantBuffer); |
|||
context.VertexShader.Set(vertexShader); |
|||
context.PixelShader.Set(pixelShader); |
|||
} |
|||
|
|||
private void Resize(Size size) |
|||
{ |
|||
Utilities.Dispose(ref _deviceContext); |
|||
Utilities.Dispose(ref _backBuffer); |
|||
Utilities.Dispose(ref _renderView); |
|||
Utilities.Dispose(ref _depthBuffer); |
|||
Utilities.Dispose(ref _depthView); |
|||
var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; |
|||
|
|||
// Resize the backbuffer
|
|||
_swapChain.ResizeBuffers(0, 0, 0, Format.Unknown, SwapChainFlags.None); |
|||
|
|||
// Get the backbuffer from the swapchain
|
|||
_backBuffer = Resource.FromSwapChain<Texture2D>(_swapChain, 0); |
|||
|
|||
// Renderview on the backbuffer
|
|||
_renderView = new RenderTargetView(Direct2D1Platform.Direct3D11Device, _backBuffer); |
|||
|
|||
// Create the depth buffer
|
|||
_depthBuffer = new Texture2D( |
|||
Direct2D1Platform.Direct3D11Device, |
|||
new Texture2DDescription() |
|||
{ |
|||
Format = Format.D32_Float_S8X24_UInt, |
|||
ArraySize = 1, |
|||
MipLevels = 1, |
|||
Width = (int)size.Width, |
|||
Height = (int)size.Height, |
|||
SampleDescription = new SampleDescription(1, 0), |
|||
Usage = ResourceUsage.Default, |
|||
BindFlags = BindFlags.DepthStencil, |
|||
CpuAccessFlags = CpuAccessFlags.None, |
|||
OptionFlags = ResourceOptionFlags.None |
|||
}); |
|||
|
|||
// Create the depth buffer view
|
|||
_depthView = new DepthStencilView(Direct2D1Platform.Direct3D11Device, _depthBuffer); |
|||
|
|||
// Setup targets and viewport for rendering
|
|||
context.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f)); |
|||
context.OutputMerger.SetTargets(_depthView, _renderView); |
|||
|
|||
// Setup new projection matrix with correct aspect ratio
|
|||
_proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f); |
|||
|
|||
using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0)) |
|||
{ |
|||
var renderTarget = new SharpDX.Direct2D1.RenderTarget( |
|||
Direct2D1Platform.Direct2D1Factory, |
|||
dxgiBackBuffer, |
|||
new RenderTargetProperties |
|||
{ |
|||
DpiX = 96, |
|||
DpiY = 96, |
|||
Type = RenderTargetType.Default, |
|||
PixelFormat = new PixelFormat( |
|||
Format.Unknown, |
|||
AlphaMode.Premultiplied) |
|||
}); |
|||
|
|||
_deviceContext = renderTarget.QueryInterface<DeviceContext>(); |
|||
|
|||
renderTarget.Dispose(); |
|||
} |
|||
} |
|||
|
|||
private class D3DRenderTarget : IRenderTarget |
|||
{ |
|||
private readonly MainWindow _window; |
|||
|
|||
public D3DRenderTarget(MainWindow window) |
|||
{ |
|||
_window = window; |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer) |
|||
{ |
|||
return new DrawingContextImpl(visualBrushRenderer, null, _window._deviceContext); |
|||
} |
|||
} |
|||
|
|||
|
|||
protected override IRenderTarget CreateRenderTarget() => new D3DRenderTarget(this); |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
<Window xmlns="https://github.com/avaloniaui" Background="White" Title="Avalonia Direct3D Demo"> |
|||
<Grid ColumnDefinitions="*,Auto" Margin="20"> |
|||
<StackPanel Grid.Column="1" MinWidth="200"> |
|||
<TextBlock>Rotation X</TextBlock> |
|||
<Slider Value="{Binding RotationX, Mode=TwoWay}" Maximum="10"/> |
|||
<TextBlock>Rotation Y</TextBlock> |
|||
<Slider Value="{Binding RotationY, Mode=TwoWay}" Maximum="10"/> |
|||
<TextBlock>Rotation Z</TextBlock> |
|||
<Slider Value="{Binding RotationZ, Mode=TwoWay}" Maximum="10"/> |
|||
<TextBlock>Zoom</TextBlock> |
|||
<Slider Value="{Binding Zoom, Mode=TwoWay}" Maximum="3" Minimum="0.5"/> |
|||
</StackPanel> |
|||
</Grid> |
|||
</Window> |
|||
@ -1,45 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using MiniMvvm; |
|||
|
|||
namespace Direct3DInteropSample |
|||
{ |
|||
public class MainWindowViewModel : ViewModelBase |
|||
{ |
|||
private double _rotationX; |
|||
|
|||
public double RotationX |
|||
{ |
|||
get { return _rotationX; } |
|||
set { this.RaiseAndSetIfChanged(ref _rotationX, value); } |
|||
} |
|||
|
|||
private double _rotationY = 1; |
|||
|
|||
public double RotationY |
|||
{ |
|||
get { return _rotationY; } |
|||
set { this.RaiseAndSetIfChanged(ref _rotationY, value); } |
|||
} |
|||
|
|||
private double _rotationZ = 2; |
|||
|
|||
public double RotationZ |
|||
{ |
|||
get { return _rotationZ; } |
|||
set { this.RaiseAndSetIfChanged(ref _rotationZ, value); } |
|||
} |
|||
|
|||
|
|||
private double _zoom = 1; |
|||
|
|||
public double Zoom |
|||
{ |
|||
get { return _zoom; } |
|||
set { this.RaiseAndSetIfChanged(ref _zoom, value); } |
|||
} |
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
struct VS_IN |
|||
{ |
|||
float4 pos : POSITION; |
|||
float4 col : COLOR; |
|||
}; |
|||
|
|||
struct PS_IN |
|||
{ |
|||
float4 pos : SV_POSITION; |
|||
float4 col : COLOR; |
|||
}; |
|||
|
|||
float4x4 worldViewProj; |
|||
|
|||
PS_IN VS( VS_IN input ) |
|||
{ |
|||
PS_IN output = (PS_IN)0; |
|||
|
|||
output.pos = mul(input.pos, worldViewProj); |
|||
output.col = input.col; |
|||
|
|||
return output; |
|||
} |
|||
|
|||
float4 PS( PS_IN input ) : SV_Target |
|||
{ |
|||
return input.col; |
|||
} |
|||
@ -1,16 +0,0 @@ |
|||
using Avalonia; |
|||
|
|||
namespace Direct3DInteropSample |
|||
{ |
|||
class Program |
|||
{ |
|||
public static AppBuilder BuildAvaloniaApp() |
|||
=> AppBuilder.Configure<App>() |
|||
.With(new Win32PlatformOptions { UseDeferredRendering = false }) |
|||
.UseWin32() |
|||
.UseDirect2D1(); |
|||
|
|||
public static int Main(string[] args) |
|||
=> BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
using Avalonia.OpenGL; |
|||
using Avalonia.OpenGL.Egl; |
|||
using Avalonia.OpenGL.Surfaces; |
|||
|
|||
namespace Avalonia.Android.OpenGL |
|||
{ |
|||
internal sealed class GlPlatformSurface : EglGlPlatformSurfaceBase |
|||
{ |
|||
private readonly EglPlatformOpenGlInterface _egl; |
|||
private readonly IEglWindowGlPlatformSurfaceInfo _info; |
|||
|
|||
private GlPlatformSurface(EglPlatformOpenGlInterface egl, IEglWindowGlPlatformSurfaceInfo info) |
|||
{ |
|||
_egl = egl; |
|||
_info = info; |
|||
} |
|||
|
|||
public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() => |
|||
new GlRenderTarget(_egl, _info, _egl.CreateWindowSurface(_info.Handle), _info.Handle); |
|||
|
|||
public static GlPlatformSurface TryCreate(IEglWindowGlPlatformSurfaceInfo info) |
|||
{ |
|||
var feature = AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>(); |
|||
if (feature is EglPlatformOpenGlInterface egl) |
|||
{ |
|||
return new GlPlatformSurface(egl, info); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
using System; |
|||
|
|||
using Avalonia.OpenGL.Egl; |
|||
using Avalonia.OpenGL.Surfaces; |
|||
|
|||
namespace Avalonia.Android.OpenGL |
|||
{ |
|||
internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase, IGlPlatformSurfaceRenderTargetWithCorruptionInfo |
|||
{ |
|||
private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; |
|||
private readonly EglSurface _surface; |
|||
private readonly IntPtr _handle; |
|||
|
|||
public GlRenderTarget( |
|||
EglPlatformOpenGlInterface egl, |
|||
EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, |
|||
EglSurface surface, |
|||
IntPtr handle) |
|||
: base(egl) |
|||
{ |
|||
_info = info; |
|||
_surface = surface; |
|||
_handle = handle; |
|||
} |
|||
|
|||
public bool IsCorrupted => _handle != _info.Handle; |
|||
|
|||
public override IGlPlatformSurfaceRenderingSession BeginDraw() => BeginDraw(_surface, _info); |
|||
} |
|||
} |
|||
@ -0,0 +1,121 @@ |
|||
#pragma warning disable MA0048 // File name must match type name
|
|||
// https://github.com/dotnet/runtime/tree/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis
|
|||
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
|||
// See the LICENSE file in the project root for more information.
|
|||
|
|||
namespace System.Diagnostics.CodeAnalysis |
|||
{ |
|||
#nullable enable |
|||
#if !NET6_0_OR_GREATER
|
|||
[AttributeUsage( |
|||
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter | |
|||
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | |
|||
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct, |
|||
Inherited = false)] |
|||
internal sealed class DynamicallyAccessedMembersAttribute : Attribute |
|||
{ |
|||
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) |
|||
{ |
|||
MemberTypes = memberTypes; |
|||
} |
|||
|
|||
public DynamicallyAccessedMemberTypes MemberTypes { get; } |
|||
} |
|||
|
|||
[Flags] |
|||
internal enum DynamicallyAccessedMemberTypes |
|||
{ |
|||
None = 0, |
|||
PublicParameterlessConstructor = 0x0001, |
|||
PublicConstructors = 0x0002 | PublicParameterlessConstructor, |
|||
NonPublicConstructors = 0x0004, |
|||
PublicMethods = 0x0008, |
|||
NonPublicMethods = 0x0010, |
|||
PublicFields = 0x0020, |
|||
NonPublicFields = 0x0040, |
|||
PublicNestedTypes = 0x0080, |
|||
NonPublicNestedTypes = 0x0100, |
|||
PublicProperties = 0x0200, |
|||
NonPublicProperties = 0x0400, |
|||
PublicEvents = 0x0800, |
|||
NonPublicEvents = 0x1000, |
|||
Interfaces = 0x2000, |
|||
All = ~None |
|||
} |
|||
|
|||
[AttributeUsage( |
|||
AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method, |
|||
AllowMultiple = true, Inherited = false)] |
|||
internal sealed class DynamicDependencyAttribute : Attribute |
|||
{ |
|||
public DynamicDependencyAttribute(string memberSignature) |
|||
{ |
|||
MemberSignature = memberSignature; |
|||
} |
|||
|
|||
public DynamicDependencyAttribute(string memberSignature, Type type) |
|||
{ |
|||
MemberSignature = memberSignature; |
|||
Type = type; |
|||
} |
|||
|
|||
public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName) |
|||
{ |
|||
MemberSignature = memberSignature; |
|||
TypeName = typeName; |
|||
AssemblyName = assemblyName; |
|||
} |
|||
|
|||
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type) |
|||
{ |
|||
MemberTypes = memberTypes; |
|||
Type = type; |
|||
} |
|||
|
|||
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName) |
|||
{ |
|||
MemberTypes = memberTypes; |
|||
TypeName = typeName; |
|||
AssemblyName = assemblyName; |
|||
} |
|||
|
|||
public string? MemberSignature { get; } |
|||
public DynamicallyAccessedMemberTypes MemberTypes { get; } |
|||
public Type? Type { get; } |
|||
public string? TypeName { get; } |
|||
public string? AssemblyName { get; } |
|||
public string? Condition { get; set; } |
|||
} |
|||
|
|||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)] |
|||
internal sealed class RequiresUnreferencedCodeAttribute : Attribute |
|||
{ |
|||
public RequiresUnreferencedCodeAttribute(string message) |
|||
{ |
|||
Message = message; |
|||
} |
|||
|
|||
public string Message { get; } |
|||
public string? Url { get; set; } |
|||
} |
|||
|
|||
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] |
|||
internal sealed class UnconditionalSuppressMessageAttribute : Attribute |
|||
{ |
|||
public UnconditionalSuppressMessageAttribute(string category, string checkId) |
|||
{ |
|||
Category = category; |
|||
CheckId = checkId; |
|||
} |
|||
public string Category { get; } |
|||
public string CheckId { get; } |
|||
public string? Scope { get; set; } |
|||
public string? Target { get; set; } |
|||
public string? MessageId { get; set; } |
|||
public string? Justification { get; set; } |
|||
} |
|||
#endif
|
|||
} |
|||
|
|||
@ -0,0 +1,30 @@ |
|||
namespace Avalonia; |
|||
|
|||
internal static class TrimmingMessages |
|||
{ |
|||
public const string ImplicitTypeConvertionSupressWarningMessage = "Implicit convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible."; |
|||
public const string ImplicitTypeConvertionRequiresUnreferencedCodeMessage = "Implicit convertion methods are required for type conversion."; |
|||
|
|||
public const string TypeConvertionSupressWarningMessage = "Convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible."; |
|||
public const string TypeConvertionRequiresUnreferencedCodeMessage = "Convertion methods are required for type conversion, including op_Implicit, op_Explicit, Parse and TypeConverter."; |
|||
|
|||
public const string ReflectionBindingRequiresUnreferencedCodeMessage = "BindingExpression and ReflectionBinding heavily use reflection. Consider using CompiledBindings instead."; |
|||
public const string ReflectionBindingSupressWarningMessage = "BindingExpression and ReflectionBinding internal heavily use reflection."; |
|||
|
|||
public const string CompiledBindingSafeSupressWarningMessage = "CompiledBinding preserves members used in the expression tree."; |
|||
|
|||
public const string ExpressionNodeRequiresUnreferencedCodeMessage = "ExpressionNode might require unreferenced code."; |
|||
public const string ExpressionSafeSupressWarningMessage = "Typed Expressions preserves members used in the expression tree."; |
|||
|
|||
public const string SelectorsParseRequiresUnreferencedCodeMessage = "Selectors runtime parser might require unreferenced code. Consider using stronly typed selectors factory with 'new Style(s => s.OfType<Button>())' syntax."; |
|||
|
|||
public const string PropertyAccessorsRequiresUnreferencedCodeMessage = "PropertyAccessors might require unreferenced code."; |
|||
public const string DataValidationPluginRequiresUnreferencedCodeMessage = "DataValidationPlugin might require unreferenced code."; |
|||
public const string StreamPluginRequiresUnreferencedCodeMessage = "StreamPlugin might require unreferenced code."; |
|||
|
|||
public const string StyleResourceIncludeRequiresUnreferenceCodeMessage = "StyleInclude and ResourceInclude use AvaloniaXamlLoader.Load which dynamically loads referenced assembly with Avalonia resources. Note, StyleInclude and ResourceInclude defined in XAML are resolved compile time and are safe with trimming and AOT."; |
|||
public const string AvaloniaXamlLoaderRequiresUnreferenceCodeMessage = "AvaloniaXamlLoader.Load(uri, baseUri) dynamically loads referenced assembly with Avalonia resources."; |
|||
public const string XamlTypeResolvedRequiresUnreferenceCodeMessage = "XamlTypeResolver might require unreferenced code."; |
|||
|
|||
public const string IgnoreNativeAotSupressWarningMessage = "This method is not supported by NativeAOT."; |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue