Browse Source
# Conflicts: # native/Avalonia.Native/inc/avalonia-native.h # native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj # native/Avalonia.Native/src/OSX/window.mm # src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs # src/Avalonia.Native/WindowImplBase.cs # src/Avalonia.X11/X11Platform.cs # src/Avalonia.X11/X11Window.cs # src/Windows/Avalonia.Win32/PopupImpl.cspull/3866/head
666 changed files with 48576 additions and 5555 deletions
@ -1,5 +1,5 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Moq" Version="4.7.99" /> |
<PackageReference Include="Moq" Version="4.14.1" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -1,7 +0,0 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Serilog" Version="2.5.0" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Trace" Version="2.1.0" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="1.0.0" /> |
|
||||
</ItemGroup> |
|
||||
</Project> |
|
||||
@ -1,6 +1,6 @@ |
|||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="SkiaSharp" Version="1.68.2" /> |
<PackageReference Include="SkiaSharp" Version="1.68.2.1" /> |
||||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="1.68.2" /> |
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="1.68.2.1" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -0,0 +1,89 @@ |
|||||
|
#include "common.h" |
||||
|
|
||||
|
extern AvnDragDropEffects ConvertDragDropEffects(NSDragOperation nsop) |
||||
|
{ |
||||
|
int effects = 0; |
||||
|
if((nsop & NSDragOperationCopy) != 0) |
||||
|
effects |= (int)AvnDragDropEffects::Copy; |
||||
|
if((nsop & NSDragOperationMove) != 0) |
||||
|
effects |= (int)AvnDragDropEffects::Move; |
||||
|
if((nsop & NSDragOperationLink) != 0) |
||||
|
effects |= (int)AvnDragDropEffects::Link; |
||||
|
return (AvnDragDropEffects)effects; |
||||
|
}; |
||||
|
|
||||
|
extern NSString* GetAvnCustomDataType() |
||||
|
{ |
||||
|
char buffer[256]; |
||||
|
sprintf(buffer, "net.avaloniaui.inproc.uti.n%in", getpid()); |
||||
|
return [NSString stringWithUTF8String:buffer]; |
||||
|
} |
||||
|
|
||||
|
@interface AvnDndSource : NSObject<NSDraggingSource> |
||||
|
|
||||
|
@end |
||||
|
|
||||
|
@implementation AvnDndSource |
||||
|
{ |
||||
|
NSDragOperation _operation; |
||||
|
ComPtr<IAvnDndResultCallback> _cb; |
||||
|
void* _sourceHandle; |
||||
|
}; |
||||
|
|
||||
|
- (NSDragOperation)draggingSession:(nonnull NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context |
||||
|
{ |
||||
|
return NSDragOperationCopy; |
||||
|
} |
||||
|
|
||||
|
- (AvnDndSource*) initWithOperation: (NSDragOperation)operation |
||||
|
andCallback: (IAvnDndResultCallback*) cb |
||||
|
andSourceHandle: (void*) handle |
||||
|
{ |
||||
|
self = [super init]; |
||||
|
_operation = operation; |
||||
|
_cb = cb; |
||||
|
_sourceHandle = handle; |
||||
|
return self; |
||||
|
} |
||||
|
|
||||
|
- (void)draggingSession:(NSDraggingSession *)session |
||||
|
endedAtPoint:(NSPoint)screenPoint |
||||
|
operation:(NSDragOperation)operation |
||||
|
{ |
||||
|
if(_cb != nil) |
||||
|
{ |
||||
|
auto cb = _cb; |
||||
|
_cb = nil; |
||||
|
cb->OnDragAndDropComplete(ConvertDragDropEffects(operation)); |
||||
|
} |
||||
|
if(_sourceHandle != nil) |
||||
|
{ |
||||
|
FreeAvnGCHandle(_sourceHandle); |
||||
|
_sourceHandle = nil; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (void*) gcHandle |
||||
|
{ |
||||
|
return _sourceHandle; |
||||
|
} |
||||
|
|
||||
|
@end |
||||
|
|
||||
|
extern NSObject<NSDraggingSource>* CreateDraggingSource(NSDragOperation op, IAvnDndResultCallback* cb, void* handle) |
||||
|
{ |
||||
|
return [[AvnDndSource alloc] initWithOperation:op andCallback:cb andSourceHandle:handle]; |
||||
|
}; |
||||
|
|
||||
|
extern void* GetAvnDataObjectHandleFromDraggingInfo(NSObject<NSDraggingInfo>* info) |
||||
|
{ |
||||
|
id obj = [info draggingSource]; |
||||
|
if(obj == nil) |
||||
|
return nil; |
||||
|
if([obj isKindOfClass: [AvnDndSource class]]) |
||||
|
{ |
||||
|
auto src = (AvnDndSource*)obj; |
||||
|
return [src gcHandle]; |
||||
|
} |
||||
|
return nil; |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="ControlCatalog.Pages.OpenGlPage" |
||||
|
xmlns:pages="clr-namespace:ControlCatalog.Pages"> |
||||
|
<Grid> |
||||
|
<pages:OpenGlPageControl x:Name="GL"/> |
||||
|
<StackPanel> |
||||
|
<TextBlock Text="{Binding #GL.Info}"/> |
||||
|
</StackPanel> |
||||
|
<Grid ColumnDefinitions="*,Auto" Margin="20"> |
||||
|
<StackPanel Grid.Column="1" MinWidth="300"> |
||||
|
<TextBlock>Yaw</TextBlock> |
||||
|
<Slider Value="{Binding Yaw, Mode=TwoWay, ElementName=GL}" Maximum="10"/> |
||||
|
<TextBlock>Pitch</TextBlock> |
||||
|
<Slider Value="{Binding Pitch, Mode=TwoWay, ElementName=GL}" Maximum="10"/> |
||||
|
<TextBlock>Roll</TextBlock> |
||||
|
<Slider Value="{Binding Roll, Mode=TwoWay, ElementName=GL}" Maximum="10"/> |
||||
|
<StackPanel Orientation="Horizontal"> |
||||
|
<TextBlock FontWeight="Bold" Foreground="#C000C0">D</TextBlock> |
||||
|
<TextBlock FontWeight="Bold" Foreground="#00C090">I</TextBlock> |
||||
|
<TextBlock FontWeight="Bold" Foreground="#90C000">S</TextBlock> |
||||
|
<TextBlock FontWeight="Bold" Foreground="#C09000">C</TextBlock> |
||||
|
<TextBlock FontWeight="Bold" Foreground="#00C090">O</TextBlock> |
||||
|
</StackPanel> |
||||
|
<Slider Value="{Binding Disco, Mode=TwoWay, ElementName=GL}" Maximum="1"/> |
||||
|
</StackPanel> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
</UserControl> |
||||
@ -0,0 +1,401 @@ |
|||||
|
using System; |
||||
|
using System.Diagnostics; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.OpenGL; |
||||
|
using Avalonia.Platform.Interop; |
||||
|
using Avalonia.Threading; |
||||
|
using static Avalonia.OpenGL.GlConsts; |
||||
|
// ReSharper disable StringLiteralTypo
|
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public class OpenGlPage : UserControl |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class OpenGlPageControl : OpenGlControlBase |
||||
|
{ |
||||
|
private float _yaw; |
||||
|
|
||||
|
public static readonly DirectProperty<OpenGlPageControl, float> YawProperty = |
||||
|
AvaloniaProperty.RegisterDirect<OpenGlPageControl, float>("Yaw", o => o.Yaw, (o, v) => o.Yaw = v); |
||||
|
|
||||
|
public float Yaw |
||||
|
{ |
||||
|
get => _yaw; |
||||
|
set => SetAndRaise(YawProperty, ref _yaw, value); |
||||
|
} |
||||
|
|
||||
|
private float _pitch; |
||||
|
|
||||
|
public static readonly DirectProperty<OpenGlPageControl, float> PitchProperty = |
||||
|
AvaloniaProperty.RegisterDirect<OpenGlPageControl, float>("Pitch", o => o.Pitch, (o, v) => o.Pitch = v); |
||||
|
|
||||
|
public float Pitch |
||||
|
{ |
||||
|
get => _pitch; |
||||
|
set => SetAndRaise(PitchProperty, ref _pitch, value); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private float _roll; |
||||
|
|
||||
|
public static readonly DirectProperty<OpenGlPageControl, float> RollProperty = |
||||
|
AvaloniaProperty.RegisterDirect<OpenGlPageControl, float>("Roll", o => o.Roll, (o, v) => o.Roll = v); |
||||
|
|
||||
|
public float Roll |
||||
|
{ |
||||
|
get => _roll; |
||||
|
set => SetAndRaise(RollProperty, ref _roll, value); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private float _disco; |
||||
|
|
||||
|
public static readonly DirectProperty<OpenGlPageControl, float> DiscoProperty = |
||||
|
AvaloniaProperty.RegisterDirect<OpenGlPageControl, float>("Disco", o => o.Disco, (o, v) => o.Disco = v); |
||||
|
|
||||
|
public float Disco |
||||
|
{ |
||||
|
get => _disco; |
||||
|
set => SetAndRaise(DiscoProperty, ref _disco, value); |
||||
|
} |
||||
|
|
||||
|
private string _info; |
||||
|
|
||||
|
public static readonly DirectProperty<OpenGlPageControl, string> InfoProperty = |
||||
|
AvaloniaProperty.RegisterDirect<OpenGlPageControl, string>("Info", o => o.Info, (o, v) => o.Info = v); |
||||
|
|
||||
|
public string Info |
||||
|
{ |
||||
|
get => _info; |
||||
|
private set => SetAndRaise(InfoProperty, ref _info, value); |
||||
|
} |
||||
|
|
||||
|
static OpenGlPageControl() |
||||
|
{ |
||||
|
AffectsRender<OpenGlPageControl>(YawProperty, PitchProperty, RollProperty, DiscoProperty); |
||||
|
} |
||||
|
|
||||
|
private int _vertexShader; |
||||
|
private int _fragmentShader; |
||||
|
private int _shaderProgram; |
||||
|
private int _vertexBufferObject; |
||||
|
private int _indexBufferObject; |
||||
|
private int _vertexArrayObject; |
||||
|
private GlExtrasInterface _glExt; |
||||
|
|
||||
|
private string GetShader(bool fragment, string shader) |
||||
|
{ |
||||
|
var version = (GlVersion.Type == GlProfileType.OpenGL ? |
||||
|
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? 150 : 120 : |
||||
|
100); |
||||
|
var data = "#version " + version + "\n"; |
||||
|
if (GlVersion.Type == GlProfileType.OpenGLES) |
||||
|
data += "precision mediump float;\n"; |
||||
|
if (version >= 150) |
||||
|
{ |
||||
|
shader = shader.Replace("attribute", "in"); |
||||
|
if (fragment) |
||||
|
shader = shader |
||||
|
.Replace("varying", "in") |
||||
|
.Replace("//DECLAREGLFRAG", "out vec4 outFragColor;") |
||||
|
.Replace("gl_FragColor", "outFragColor"); |
||||
|
else |
||||
|
shader = shader.Replace("varying", "out"); |
||||
|
} |
||||
|
|
||||
|
data += shader; |
||||
|
|
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private string VertexShaderSource => GetShader(false, @"
|
||||
|
attribute vec3 aPos; |
||||
|
attribute vec3 aNormal; |
||||
|
uniform mat4 uModel; |
||||
|
uniform mat4 uProjection; |
||||
|
uniform mat4 uView; |
||||
|
|
||||
|
varying vec3 FragPos; |
||||
|
varying vec3 VecPos; |
||||
|
varying vec3 Normal; |
||||
|
uniform float uTime; |
||||
|
uniform float uDisco; |
||||
|
void main() |
||||
|
{ |
||||
|
float discoScale = sin(uTime * 10.0) / 10.0; |
||||
|
float distortionX = 1.0 + uDisco * cos(uTime * 20.0) / 10.0; |
||||
|
|
||||
|
float scale = 1.0 + uDisco * discoScale; |
||||
|
|
||||
|
vec3 scaledPos = aPos; |
||||
|
scaledPos.x = scaledPos.x * distortionX; |
||||
|
|
||||
|
scaledPos *= scale; |
||||
|
gl_Position = uProjection * uView * uModel * vec4(scaledPos, 1.0); |
||||
|
FragPos = vec3(uModel * vec4(aPos, 1.0)); |
||||
|
VecPos = aPos; |
||||
|
Normal = normalize(vec3(uModel * vec4(aNormal, 1.0))); |
||||
|
} |
||||
|
");
|
||||
|
|
||||
|
private string FragmentShaderSource => GetShader(true, @"
|
||||
|
varying vec3 FragPos; |
||||
|
varying vec3 VecPos; |
||||
|
varying vec3 Normal; |
||||
|
uniform float uMaxY; |
||||
|
uniform float uMinY; |
||||
|
uniform float uTime; |
||||
|
uniform float uDisco; |
||||
|
//DECLAREGLFRAG
|
||||
|
|
||||
|
void main() |
||||
|
{ |
||||
|
float y = (VecPos.y - uMinY) / (uMaxY - uMinY); |
||||
|
float c = cos(atan(VecPos.x, VecPos.z) * 20.0 + uTime * 40.0 + y * 50.0); |
||||
|
float s = sin(-atan(VecPos.z, VecPos.x) * 20.0 - uTime * 20.0 - y * 30.0); |
||||
|
|
||||
|
vec3 discoColor = vec3( |
||||
|
0.5 + abs(0.5 - y) * cos(uTime * 10.0), |
||||
|
0.25 + (smoothstep(0.3, 0.8, y) * (0.5 - c / 4.0)), |
||||
|
0.25 + abs((smoothstep(0.1, 0.4, y) * (0.5 - s / 4.0)))); |
||||
|
|
||||
|
vec3 objectColor = vec3((1.0 - y), 0.40 + y / 4.0, y * 0.75 + 0.25); |
||||
|
objectColor = objectColor * (1.0 - uDisco) + discoColor * uDisco; |
||||
|
|
||||
|
float ambientStrength = 0.3; |
||||
|
vec3 lightColor = vec3(1.0, 1.0, 1.0); |
||||
|
vec3 lightPos = vec3(uMaxY * 2.0, uMaxY * 2.0, uMaxY * 2.0); |
||||
|
vec3 ambient = ambientStrength * lightColor; |
||||
|
|
||||
|
|
||||
|
vec3 norm = normalize(Normal); |
||||
|
vec3 lightDir = normalize(lightPos - FragPos); |
||||
|
|
||||
|
float diff = max(dot(norm, lightDir), 0.0); |
||||
|
vec3 diffuse = diff * lightColor; |
||||
|
|
||||
|
vec3 result = (ambient + diffuse) * objectColor; |
||||
|
gl_FragColor = vec4(result, 1.0); |
||||
|
|
||||
|
} |
||||
|
");
|
||||
|
|
||||
|
[StructLayout(LayoutKind.Sequential, Pack = 4)] |
||||
|
private struct Vertex |
||||
|
{ |
||||
|
public Vector3 Position; |
||||
|
public Vector3 Normal; |
||||
|
} |
||||
|
|
||||
|
private readonly Vertex[] _points; |
||||
|
private readonly ushort[] _indices; |
||||
|
private readonly float _minY; |
||||
|
private readonly float _maxY; |
||||
|
|
||||
|
|
||||
|
public OpenGlPageControl() |
||||
|
{ |
||||
|
var name = typeof(OpenGlPage).Assembly.GetManifestResourceNames().First(x => x.Contains("teapot.bin")); |
||||
|
using (var sr = new BinaryReader(typeof(OpenGlPage).Assembly.GetManifestResourceStream(name))) |
||||
|
{ |
||||
|
var buf = new byte[sr.ReadInt32()]; |
||||
|
sr.Read(buf, 0, buf.Length); |
||||
|
var points = new float[buf.Length / 4]; |
||||
|
Buffer.BlockCopy(buf, 0, points, 0, buf.Length); |
||||
|
buf = new byte[sr.ReadInt32()]; |
||||
|
sr.Read(buf, 0, buf.Length); |
||||
|
_indices = new ushort[buf.Length / 2]; |
||||
|
Buffer.BlockCopy(buf, 0, _indices, 0, buf.Length); |
||||
|
_points = new Vertex[points.Length / 3]; |
||||
|
for (var primitive = 0; primitive < points.Length / 3; primitive++) |
||||
|
{ |
||||
|
var srci = primitive * 3; |
||||
|
_points[primitive] = new Vertex |
||||
|
{ |
||||
|
Position = new Vector3(points[srci], points[srci + 1], points[srci + 2]) |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
for (int i = 0; i < _indices.Length; i += 3) |
||||
|
{ |
||||
|
Vector3 a = _points[_indices[i]].Position; |
||||
|
Vector3 b = _points[_indices[i + 1]].Position; |
||||
|
Vector3 c = _points[_indices[i + 2]].Position; |
||||
|
var normal = Vector3.Normalize(Vector3.Cross(c - b, a - b)); |
||||
|
|
||||
|
_points[_indices[i]].Normal += normal; |
||||
|
_points[_indices[i + 1]].Normal += normal; |
||||
|
_points[_indices[i + 2]].Normal += normal; |
||||
|
} |
||||
|
|
||||
|
for (int i = 0; i < _points.Length; i++) |
||||
|
{ |
||||
|
_points[i].Normal = Vector3.Normalize(_points[i].Normal); |
||||
|
_maxY = Math.Max(_maxY, _points[i].Position.Y); |
||||
|
_minY = Math.Min(_minY, _points[i].Position.Y); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void CheckError(GlInterface gl) |
||||
|
{ |
||||
|
int err; |
||||
|
while ((err = gl.GetError()) != GL_NO_ERROR) |
||||
|
Console.WriteLine(err); |
||||
|
} |
||||
|
|
||||
|
protected unsafe override void OnOpenGlInit(GlInterface GL, int fb) |
||||
|
{ |
||||
|
CheckError(GL); |
||||
|
_glExt = new GlExtrasInterface(GL); |
||||
|
|
||||
|
Info = $"Renderer: {GL.GetString(GL_RENDERER)} Version: {GL.GetString(GL_VERSION)}"; |
||||
|
|
||||
|
// Load the source of the vertex shader and compile it.
|
||||
|
_vertexShader = GL.CreateShader(GL_VERTEX_SHADER); |
||||
|
Console.WriteLine(GL.CompileShaderAndGetError(_vertexShader, VertexShaderSource)); |
||||
|
|
||||
|
// Load the source of the fragment shader and compile it.
|
||||
|
_fragmentShader = GL.CreateShader(GL_FRAGMENT_SHADER); |
||||
|
Console.WriteLine(GL.CompileShaderAndGetError(_fragmentShader, FragmentShaderSource)); |
||||
|
|
||||
|
// Create the shader program, attach the vertex and fragment shaders and link the program.
|
||||
|
_shaderProgram = GL.CreateProgram(); |
||||
|
GL.AttachShader(_shaderProgram, _vertexShader); |
||||
|
GL.AttachShader(_shaderProgram, _fragmentShader); |
||||
|
const int positionLocation = 0; |
||||
|
const int normalLocation = 1; |
||||
|
GL.BindAttribLocationString(_shaderProgram, positionLocation, "aPos"); |
||||
|
GL.BindAttribLocationString(_shaderProgram, normalLocation, "aNormal"); |
||||
|
Console.WriteLine(GL.LinkProgramAndGetError(_shaderProgram)); |
||||
|
CheckError(GL); |
||||
|
|
||||
|
// Create the vertex buffer object (VBO) for the vertex data.
|
||||
|
_vertexBufferObject = GL.GenBuffer(); |
||||
|
// Bind the VBO and copy the vertex data into it.
|
||||
|
GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject); |
||||
|
CheckError(GL); |
||||
|
var vertexSize = Marshal.SizeOf<Vertex>(); |
||||
|
fixed (void* pdata = _points) |
||||
|
GL.BufferData(GL_ARRAY_BUFFER, new IntPtr(_points.Length * vertexSize), |
||||
|
new IntPtr(pdata), GL_STATIC_DRAW); |
||||
|
|
||||
|
_indexBufferObject = GL.GenBuffer(); |
||||
|
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); |
||||
|
CheckError(GL); |
||||
|
fixed (void* pdata = _indices) |
||||
|
GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, new IntPtr(_indices.Length * sizeof(ushort)), new IntPtr(pdata), |
||||
|
GL_STATIC_DRAW); |
||||
|
CheckError(GL); |
||||
|
_vertexArrayObject = _glExt.GenVertexArray(); |
||||
|
_glExt.BindVertexArray(_vertexArrayObject); |
||||
|
CheckError(GL); |
||||
|
GL.VertexAttribPointer(positionLocation, 3, GL_FLOAT, |
||||
|
0, vertexSize, IntPtr.Zero); |
||||
|
GL.VertexAttribPointer(normalLocation, 3, GL_FLOAT, |
||||
|
0, vertexSize, new IntPtr(12)); |
||||
|
GL.EnableVertexAttribArray(positionLocation); |
||||
|
GL.EnableVertexAttribArray(normalLocation); |
||||
|
CheckError(GL); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected override void OnOpenGlDeinit(GlInterface GL, int fb) |
||||
|
{ |
||||
|
// Unbind everything
|
||||
|
GL.BindBuffer(GL_ARRAY_BUFFER, 0); |
||||
|
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
||||
|
_glExt.BindVertexArray(0); |
||||
|
GL.UseProgram(0); |
||||
|
|
||||
|
// Delete all resources.
|
||||
|
GL.DeleteBuffers(2, new[] { _vertexBufferObject, _indexBufferObject }); |
||||
|
_glExt.DeleteVertexArrays(1, new[] { _vertexArrayObject }); |
||||
|
GL.DeleteProgram(_shaderProgram); |
||||
|
GL.DeleteShader(_fragmentShader); |
||||
|
GL.DeleteShader(_vertexShader); |
||||
|
} |
||||
|
|
||||
|
static Stopwatch St = Stopwatch.StartNew(); |
||||
|
protected override unsafe void OnOpenGlRender(GlInterface gl, int fb) |
||||
|
{ |
||||
|
gl.ClearColor(0, 0, 0, 0); |
||||
|
gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
||||
|
gl.Enable(GL_DEPTH_TEST); |
||||
|
gl.Viewport(0, 0, (int)Bounds.Width, (int)Bounds.Height); |
||||
|
var GL = gl; |
||||
|
|
||||
|
GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject); |
||||
|
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); |
||||
|
_glExt.BindVertexArray(_vertexArrayObject); |
||||
|
GL.UseProgram(_shaderProgram); |
||||
|
CheckError(GL); |
||||
|
var projection = |
||||
|
Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)(Bounds.Width / Bounds.Height), |
||||
|
0.01f, 1000); |
||||
|
|
||||
|
|
||||
|
var view = Matrix4x4.CreateLookAt(new Vector3(25, 25, 25), new Vector3(), new Vector3(0, -1, 0)); |
||||
|
var model = Matrix4x4.CreateFromYawPitchRoll(_yaw, _pitch, _roll); |
||||
|
var modelLoc = GL.GetUniformLocationString(_shaderProgram, "uModel"); |
||||
|
var viewLoc = GL.GetUniformLocationString(_shaderProgram, "uView"); |
||||
|
var projectionLoc = GL.GetUniformLocationString(_shaderProgram, "uProjection"); |
||||
|
var maxYLoc = GL.GetUniformLocationString(_shaderProgram, "uMaxY"); |
||||
|
var minYLoc = GL.GetUniformLocationString(_shaderProgram, "uMinY"); |
||||
|
var timeLoc = GL.GetUniformLocationString(_shaderProgram, "uTime"); |
||||
|
var discoLoc = GL.GetUniformLocationString(_shaderProgram, "uDisco"); |
||||
|
GL.UniformMatrix4fv(modelLoc, 1, false, &model); |
||||
|
GL.UniformMatrix4fv(viewLoc, 1, false, &view); |
||||
|
GL.UniformMatrix4fv(projectionLoc, 1, false, &projection); |
||||
|
GL.Uniform1f(maxYLoc, _maxY); |
||||
|
GL.Uniform1f(minYLoc, _minY); |
||||
|
GL.Uniform1f(timeLoc, (float)St.Elapsed.TotalSeconds); |
||||
|
GL.Uniform1f(discoLoc, _disco); |
||||
|
CheckError(GL); |
||||
|
GL.DrawElements(GL_TRIANGLES, _indices.Length, GL_UNSIGNED_SHORT, IntPtr.Zero); |
||||
|
|
||||
|
CheckError(GL); |
||||
|
if (_disco > 0.01) |
||||
|
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); |
||||
|
} |
||||
|
|
||||
|
class GlExtrasInterface : GlInterfaceBase<GlInterface.GlContextInfo> |
||||
|
{ |
||||
|
public GlExtrasInterface(GlInterface gl) : base(gl.GetProcAddress, gl.ContextInfo) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public delegate void GlDeleteVertexArrays(int count, int[] buffers); |
||||
|
[GlMinVersionEntryPoint("glDeleteVertexArrays", 3,0)] |
||||
|
[GlExtensionEntryPoint("glDeleteVertexArraysOES", "GL_OES_vertex_array_object")] |
||||
|
public GlDeleteVertexArrays DeleteVertexArrays { get; } |
||||
|
|
||||
|
public delegate void GlBindVertexArray(int array); |
||||
|
[GlMinVersionEntryPoint("glBindVertexArray", 3,0)] |
||||
|
[GlExtensionEntryPoint("glBindVertexArrayOES", "GL_OES_vertex_array_object")] |
||||
|
public GlBindVertexArray BindVertexArray { get; } |
||||
|
public delegate void GlGenVertexArrays(int n, int[] rv); |
||||
|
|
||||
|
[GlMinVersionEntryPoint("glGenVertexArrays",3,0)] |
||||
|
[GlExtensionEntryPoint("glGenVertexArraysOES", "GL_OES_vertex_array_object")] |
||||
|
public GlGenVertexArrays GenVertexArrays { get; } |
||||
|
|
||||
|
public int GenVertexArray() |
||||
|
{ |
||||
|
var rv = new int[1]; |
||||
|
GenVertexArrays(1, rv); |
||||
|
return rv[0]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="ControlCatalog.Pages.ScrollViewerPage"> |
||||
|
<StackPanel Orientation="Vertical" Spacing="4"> |
||||
|
<TextBlock Classes="h1">ScrollViewer</TextBlock> |
||||
|
<TextBlock Classes="h2">Allows for horizontal and vertical content scrolling.</TextBlock> |
||||
|
|
||||
|
<Grid ColumnDefinitions="Auto, *"> |
||||
|
<StackPanel Orientation="Vertical" Spacing="4"> |
||||
|
<ToggleSwitch IsChecked="{Binding AllowAutoHide}" Content="Allow auto hide" /> |
||||
|
|
||||
|
<StackPanel Orientation="Vertical" Spacing="4"> |
||||
|
<TextBlock Text="Horizontal Scroll" /> |
||||
|
<ComboBox Items="{Binding AvailableVisibility}" SelectedItem="{Binding HorizontalScrollVisibility}" /> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<StackPanel Orientation="Vertical" Spacing="4"> |
||||
|
<TextBlock Text="Vertical Scroll" /> |
||||
|
<ComboBox Items="{Binding AvailableVisibility}" SelectedItem="{Binding VerticalScrollVisibility}" /> |
||||
|
</StackPanel> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<ScrollViewer x:Name="ScrollViewer" |
||||
|
Grid.Column="1" |
||||
|
Width="400" Height="400" |
||||
|
AllowAutoHide="{Binding AllowAutoHide}" |
||||
|
HorizontalScrollBarVisibility="{Binding HorizontalScrollVisibility}" |
||||
|
VerticalScrollBarVisibility="{Binding VerticalScrollVisibility}"> |
||||
|
<Image Width="800" Height="800" Stretch="UniformToFill" |
||||
|
Source="/Assets/delicate-arch-896885_640.jpg" /> |
||||
|
</ScrollViewer> |
||||
|
</Grid> |
||||
|
|
||||
|
</StackPanel> |
||||
|
</UserControl> |
||||
@ -0,0 +1,65 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.Primitives; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using ReactiveUI; |
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public class ScrollViewerPageViewModel : ReactiveObject |
||||
|
{ |
||||
|
private bool _allowAutoHide; |
||||
|
private ScrollBarVisibility _horizontalScrollVisibility; |
||||
|
private ScrollBarVisibility _verticalScrollVisibility; |
||||
|
|
||||
|
public ScrollViewerPageViewModel() |
||||
|
{ |
||||
|
AvailableVisibility = new List<ScrollBarVisibility> |
||||
|
{ |
||||
|
ScrollBarVisibility.Auto, |
||||
|
ScrollBarVisibility.Visible, |
||||
|
ScrollBarVisibility.Hidden, |
||||
|
ScrollBarVisibility.Disabled, |
||||
|
}; |
||||
|
|
||||
|
HorizontalScrollVisibility = ScrollBarVisibility.Auto; |
||||
|
VerticalScrollVisibility = ScrollBarVisibility.Auto; |
||||
|
AllowAutoHide = true; |
||||
|
} |
||||
|
|
||||
|
public bool AllowAutoHide |
||||
|
{ |
||||
|
get => _allowAutoHide; |
||||
|
set => this.RaiseAndSetIfChanged(ref _allowAutoHide, value); |
||||
|
} |
||||
|
|
||||
|
public ScrollBarVisibility HorizontalScrollVisibility |
||||
|
{ |
||||
|
get => _horizontalScrollVisibility; |
||||
|
set => this.RaiseAndSetIfChanged(ref _horizontalScrollVisibility, value); |
||||
|
} |
||||
|
|
||||
|
public ScrollBarVisibility VerticalScrollVisibility |
||||
|
{ |
||||
|
get => _verticalScrollVisibility; |
||||
|
set => this.RaiseAndSetIfChanged(ref _verticalScrollVisibility, value); |
||||
|
} |
||||
|
|
||||
|
public List<ScrollBarVisibility> AvailableVisibility { get; } |
||||
|
} |
||||
|
|
||||
|
public class ScrollViewerPage : UserControl |
||||
|
{ |
||||
|
public ScrollViewerPage() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
|
||||
|
DataContext = new ScrollViewerPageViewModel(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="ControlCatalog.Pages.ToggleSwitchPage" Margin="5"> |
||||
|
<StackPanel Width="500" HorizontalAlignment="Center"> |
||||
|
<TextBlock Text="Simple ToggleSwitch" Classes="header"/> |
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Margin="10"/> |
||||
|
<TextBox Text="<ToggleSwitch/>" Classes="CodeBox"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="headered ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="headered" IsChecked="true" Margin="10"/> |
||||
|
<TextBox Classes="CodeBox" |
||||
|
Text="<ToggleSwitch>headered</ToggleSwitch>"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="Custom content ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="Custom" |
||||
|
OnContent="On" |
||||
|
OffContent="Off" |
||||
|
Margin="10"/> |
||||
|
|
||||
|
<TextBox Text="<ToggleSwitch Content="Custom" |
||||
|
ContentOn="On" |
||||
|
ContentOff="Off" />" |
||||
|
Classes="CodeBox"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
|
||||
|
<TextBlock Text="Image content ToggleSwitch" Classes="header"/> |
||||
|
|
||||
|
<Border Classes="Thin"> |
||||
|
<StackPanel> |
||||
|
<ToggleSwitch Content="Just Click!" Margin="10"> |
||||
|
<ToggleSwitch.OnContent> |
||||
|
<Image Source="/Assets/hirsch-899118_640.jpg" Height="32"/> |
||||
|
</ToggleSwitch.OnContent> |
||||
|
|
||||
|
<ToggleSwitch.OffContent> |
||||
|
<Image Source="/Assets/delicate-arch-896885_640.jpg" Height="32"/> |
||||
|
</ToggleSwitch.OffContent> |
||||
|
|
||||
|
</ToggleSwitch> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<UserControl.Styles > |
||||
|
<Style Selector="TextBox.CodeBox" > |
||||
|
<Setter Property="Padding" Value="10"/> |
||||
|
<Setter Property="IsReadOnly" Value="True"/> |
||||
|
<Setter Property="BorderBrush" Value="Transparent"/> |
||||
|
<Setter Property="FontSize" Value="14"/> |
||||
|
<Setter Property="IsEnabled" Value="true"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="TextBlock.header"> |
||||
|
<Setter Property="FontSize" Value="18"/> |
||||
|
<Setter Property="Margin" Value="0 20 0 20"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Thin"> |
||||
|
<Setter Property="BorderBrush" Value="Gray"/> |
||||
|
<Setter Property="BorderThickness" Value="0.5"/> |
||||
|
<Setter Property="CornerRadius" Value="2"/> |
||||
|
</Style> |
||||
|
|
||||
|
</UserControl.Styles> |
||||
|
</UserControl> |
||||
|
|
||||
@ -0,0 +1,19 @@ |
|||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public class ToggleSwitchPage : UserControl |
||||
|
{ |
||||
|
public ToggleSwitchPage() |
||||
|
{ |
||||
|
this.InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Binary file not shown.
@ -0,0 +1,126 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Linq; |
||||
|
using System.Reactive; |
||||
|
using Avalonia.Controls; |
||||
|
using ReactiveUI; |
||||
|
|
||||
|
namespace ControlCatalog.ViewModels |
||||
|
{ |
||||
|
public class TreeViewPageViewModel : ReactiveObject |
||||
|
{ |
||||
|
private readonly Node _root; |
||||
|
private SelectionMode _selectionMode; |
||||
|
|
||||
|
public TreeViewPageViewModel() |
||||
|
{ |
||||
|
_root = new Node(); |
||||
|
|
||||
|
Items = _root.Children; |
||||
|
Selection = new SelectionModel(); |
||||
|
Selection.SelectionChanged += SelectionChanged; |
||||
|
|
||||
|
AddItemCommand = ReactiveCommand.Create(AddItem); |
||||
|
RemoveItemCommand = ReactiveCommand.Create(RemoveItem); |
||||
|
SelectRandomItemCommand = ReactiveCommand.Create(SelectRandomItem); |
||||
|
} |
||||
|
|
||||
|
public ObservableCollection<Node> Items { get; } |
||||
|
public SelectionModel Selection { get; } |
||||
|
public ReactiveCommand<Unit, Unit> AddItemCommand { get; } |
||||
|
public ReactiveCommand<Unit, Unit> RemoveItemCommand { get; } |
||||
|
public ReactiveCommand<Unit, Unit> SelectRandomItemCommand { get; } |
||||
|
|
||||
|
public SelectionMode SelectionMode |
||||
|
{ |
||||
|
get => _selectionMode; |
||||
|
set |
||||
|
{ |
||||
|
Selection.ClearSelection(); |
||||
|
this.RaiseAndSetIfChanged(ref _selectionMode, value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void AddItem() |
||||
|
{ |
||||
|
var parentItem = Selection.SelectedItems.Count > 0 ? (Node)Selection.SelectedItems[0] : _root; |
||||
|
parentItem.AddItem(); |
||||
|
} |
||||
|
|
||||
|
private void RemoveItem() |
||||
|
{ |
||||
|
while (Selection.SelectedItems.Count > 0) |
||||
|
{ |
||||
|
Node lastItem = (Node)Selection.SelectedItems[0]; |
||||
|
RecursiveRemove(Items, lastItem); |
||||
|
Selection.DeselectAt(Selection.SelectedIndices[0]); |
||||
|
} |
||||
|
|
||||
|
bool RecursiveRemove(ObservableCollection<Node> items, Node selectedItem) |
||||
|
{ |
||||
|
if (items.Remove(selectedItem)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
foreach (Node item in items) |
||||
|
{ |
||||
|
if (item.AreChildrenInitialized && RecursiveRemove(item.Children, selectedItem)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void SelectRandomItem() |
||||
|
{ |
||||
|
var random = new Random(); |
||||
|
var depth = random.Next(4); |
||||
|
var indexes = Enumerable.Range(0, 4).Select(x => random.Next(10)); |
||||
|
var path = new IndexPath(indexes); |
||||
|
Selection.SelectedIndex = path; |
||||
|
} |
||||
|
|
||||
|
private void SelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e) |
||||
|
{ |
||||
|
var selected = string.Join(",", e.SelectedIndices); |
||||
|
var deselected = string.Join(",", e.DeselectedIndices); |
||||
|
System.Diagnostics.Debug.WriteLine($"Selected '{selected}', Deselected '{deselected}'"); |
||||
|
} |
||||
|
|
||||
|
public class Node |
||||
|
{ |
||||
|
private ObservableCollection<Node> _children; |
||||
|
private int _childIndex = 10; |
||||
|
|
||||
|
public Node() |
||||
|
{ |
||||
|
Header = "Item"; |
||||
|
} |
||||
|
|
||||
|
public Node(Node parent, int index) |
||||
|
{ |
||||
|
Parent = parent; |
||||
|
Header = parent.Header + ' ' + index; |
||||
|
} |
||||
|
|
||||
|
public Node Parent { get; } |
||||
|
public string Header { get; } |
||||
|
public bool AreChildrenInitialized => _children != null; |
||||
|
public ObservableCollection<Node> Children => _children ??= CreateChildren(); |
||||
|
public void AddItem() => Children.Add(new Node(this, _childIndex++)); |
||||
|
public void RemoveItem(Node child) => Children.Remove(child); |
||||
|
public override string ToString() => Header; |
||||
|
|
||||
|
private ObservableCollection<Node> CreateChildren() |
||||
|
{ |
||||
|
return new ObservableCollection<Node>( |
||||
|
Enumerable.Range(0, 10).Select(i => new Node(this, i))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,7 @@ |
|||||
<Project> |
<Project> |
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<IsPackable>false</IsPackable> |
<IsPackable>false</IsPackable> |
||||
|
<AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
<Import Project="..\build\SharedVersion.props" /> |
<Import Project="..\build\SharedVersion.props" /> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -0,0 +1,53 @@ |
|||||
|
using System; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Media; |
||||
|
using Avalonia.Rendering.SceneGraph; |
||||
|
using Avalonia.Threading; |
||||
|
|
||||
|
namespace RenderDemo.Controls |
||||
|
{ |
||||
|
public class LineBoundsDemoControl : Control |
||||
|
{ |
||||
|
static LineBoundsDemoControl() |
||||
|
{ |
||||
|
AffectsRender<LineBoundsDemoControl>(AngleProperty); |
||||
|
} |
||||
|
|
||||
|
public LineBoundsDemoControl() |
||||
|
{ |
||||
|
var timer = new DispatcherTimer(); |
||||
|
timer.Interval = TimeSpan.FromSeconds(1 / 60.0); |
||||
|
timer.Tick += (sender, e) => Angle += Math.PI / 360; |
||||
|
timer.Start(); |
||||
|
} |
||||
|
|
||||
|
public static readonly StyledProperty<double> AngleProperty = |
||||
|
AvaloniaProperty.Register<LineBoundsDemoControl, double>(nameof(Angle)); |
||||
|
|
||||
|
public double Angle |
||||
|
{ |
||||
|
get => GetValue(AngleProperty); |
||||
|
set => SetValue(AngleProperty, value); |
||||
|
} |
||||
|
|
||||
|
public override void Render(DrawingContext drawingContext) |
||||
|
{ |
||||
|
var lineLength = Math.Sqrt((100 * 100) + (100 * 100)); |
||||
|
|
||||
|
var diffX = LineBoundsHelper.CalculateAdjSide(Angle, lineLength); |
||||
|
var diffY = LineBoundsHelper.CalculateOppSide(Angle, lineLength); |
||||
|
|
||||
|
|
||||
|
var p1 = new Point(200, 200); |
||||
|
var p2 = new Point(p1.X + diffX, p1.Y + diffY); |
||||
|
|
||||
|
var pen = new Pen(Brushes.Green, 20, lineCap: PenLineCap.Square); |
||||
|
var boundPen = new Pen(Brushes.Black); |
||||
|
|
||||
|
drawingContext.DrawLine(pen, p1, p2); |
||||
|
|
||||
|
drawingContext.DrawRectangle(boundPen, LineBoundsHelper.CalculateBounds(p1, p2, pen)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
<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" |
||||
|
xmlns:controls="clr-namespace:RenderDemo.Controls" |
||||
|
x:Class="RenderDemo.Pages.LineBoundsPage"> |
||||
|
<controls:LineBoundsDemoControl /> |
||||
|
</UserControl> |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
|
||||
|
namespace RenderDemo.Pages |
||||
|
{ |
||||
|
public class LineBoundsPage : UserControl |
||||
|
{ |
||||
|
public LineBoundsPage() |
||||
|
{ |
||||
|
this.InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,115 @@ |
|||||
|
<UserControl |
||||
|
xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="RenderDemo.Pages.TransitionsPage"> |
||||
|
<UserControl.Styles> |
||||
|
<Styles> |
||||
|
<Styles.Resources> |
||||
|
<Template x:Key="Acorn"> |
||||
|
<Path Fill="White" Stretch="Uniform" |
||||
|
Data="F1 M 16.6309,18.6563C 17.1309, |
||||
|
8.15625 29.8809,14.1563 29.8809, |
||||
|
14.1563C 30.8809,11.1563 34.1308, |
||||
|
11.4063 34.1308,11.4063C 33.5,12 |
||||
|
34.6309,13.1563 34.6309,13.1563C |
||||
|
32.1309,13.1562 31.1309,14.9062 |
||||
|
31.1309,14.9062C 41.1309,23.9062 |
||||
|
32.6309,27.9063 32.6309,27.9062C |
||||
|
24.6309,24.9063 21.1309,22.1562 |
||||
|
16.6309,18.6563 Z M 16.6309,19.9063C |
||||
|
21.6309,24.1563 25.1309,26.1562 |
||||
|
31.6309,28.6562C 31.6309,28.6562 |
||||
|
26.3809,39.1562 18.3809,36.1563C |
||||
|
18.3809,36.1563 18,38 16.3809,36.9063C |
||||
|
15,36 16.3809,34.9063 16.3809,34.9063C |
||||
|
16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z"/> |
||||
|
</Template> |
||||
|
<Template x:Key="Heart"> |
||||
|
<Path Fill="Red" Stretch="Uniform" Data=" |
||||
|
M 272.70141,238.71731 |
||||
|
C 206.46141,238.71731 152.70146,292.4773 152.70146,358.71731 |
||||
|
C 152.70146,493.47282 288.63461,528.80461 381.26391,662.02535 |
||||
|
C 468.83815,529.62199 609.82641,489.17075 609.82641,358.71731 |
||||
|
C 609.82641,292.47731 556.06651,238.7173 489.82641,238.71731 |
||||
|
C 441.77851,238.71731 400.42481,267.08774 381.26391,307.90481 |
||||
|
C 362.10311,267.08773 320.74941,238.7173 272.70141,238.71731 z "/> |
||||
|
</Template> |
||||
|
</Styles.Resources> |
||||
|
|
||||
|
<Style Selector="Border.Test"> |
||||
|
<Setter Property="Margin" Value="15"/> |
||||
|
<Setter Property="Width" Value="100"/> |
||||
|
<Setter Property="Height" Value="100"/> |
||||
|
<Setter Property="Child" Value="{StaticResource Acorn}"/> |
||||
|
<Setter Property="Transitions"> |
||||
|
<Transitions> |
||||
|
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:1" /> |
||||
|
</Transitions> |
||||
|
</Setter> |
||||
|
<Setter Property="RenderTransform" Value="none" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect1:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="rotate(120deg) scale(1.5)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect2:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="scale(0.8)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect3"> |
||||
|
<Setter Property="Child" Value="{StaticResource Heart}"/> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect3:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="rotate(1turn)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect4:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="translateY(-100px)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect5:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="skewX(-20deg)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect5:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="skewX(-20deg)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect6"> |
||||
|
<Setter Property="Transitions"> |
||||
|
<Transitions> |
||||
|
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.5" Delay="0:0:1"/> |
||||
|
</Transitions> |
||||
|
</Setter> |
||||
|
<Setter Property="RenderTransform" Value="scale(0.8)" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="Border.Rect6:pointerover"> |
||||
|
<Setter Property="RenderTransform" Value="none" /> |
||||
|
</Style> |
||||
|
|
||||
|
</Styles> |
||||
|
</UserControl.Styles> |
||||
|
|
||||
|
<Grid> |
||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="False"> |
||||
|
<StackPanel.Clock> |
||||
|
<Clock /> |
||||
|
</StackPanel.Clock> |
||||
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"> |
||||
|
<TextBlock VerticalAlignment="Center">Hover to activate Transform Keyframe Animations.</TextBlock> |
||||
|
<Button Content="{Binding PlayStateText}" Command="{Binding TogglePlayState}" Click="ToggleClock" /> |
||||
|
</StackPanel> |
||||
|
<WrapPanel ClipToBounds="False"> |
||||
|
<Border Classes="Test Rect1" Background="DarkRed"/> |
||||
|
<Border Classes="Test Rect2" Background="Magenta"/> |
||||
|
<Border Classes="Test Rect3"/> |
||||
|
<Border Classes="Test Rect4" Background="Navy"/> |
||||
|
<Border Classes="Test Rect5" Background="SeaGreen"/> |
||||
|
<Border Classes="Test Rect6" Background="Orange"/> |
||||
|
</WrapPanel> |
||||
|
</StackPanel> |
||||
|
</Grid> |
||||
|
</UserControl> |
||||
@ -0,0 +1,37 @@ |
|||||
|
using Avalonia.Animation; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Interactivity; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using RenderDemo.ViewModels; |
||||
|
|
||||
|
namespace RenderDemo.Pages |
||||
|
{ |
||||
|
public class TransitionsPage : UserControl |
||||
|
{ |
||||
|
public TransitionsPage() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
this.DataContext = new AnimationsPageViewModel(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
private void ToggleClock(object sender, RoutedEventArgs args) |
||||
|
{ |
||||
|
var button = sender as Button; |
||||
|
var clock = button.Clock; |
||||
|
|
||||
|
if (clock.PlayState == PlayState.Run) |
||||
|
{ |
||||
|
clock.PlayState = PlayState.Pause; |
||||
|
} |
||||
|
else if (clock.PlayState == PlayState.Pause) |
||||
|
{ |
||||
|
clock.PlayState = PlayState.Run; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,5 +1,5 @@ |
|||||
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ |
||||
|
|||||
@ -1,5 +1,5 @@ |
|||||
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ |
||||
copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ |
copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue