committed by
GitHub
788 changed files with 10820 additions and 5385 deletions
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<InstrumentOutputAssembly>False</InstrumentOutputAssembly> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<InstrumentOutputAssembly>False</InstrumentOutputAssembly> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<InstrumentOutputAssembly>False</InstrumentOutputAssembly> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<InstrumentOutputAssembly>False</InstrumentOutputAssembly> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -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,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); |
|||
} |
|||
} |
|||
} |
|||
@ -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
|
|||
} |
|||
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue