added controllers and avalonia integration. Already can render elements

This commit is contained in:
firedef 2022-01-31 17:30:39 +03:00
Родитель db3418d09b
Коммит 624c857c60
19 изменённых файлов: 479 добавлений и 28 удалений

Просмотреть файл

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<attachedFolders>
<Path>../SomeCharts_</Path>
</attachedFolders>
<explicitIncludes />
<explicitExcludes />
</component>

Просмотреть файл

@ -18,6 +18,8 @@
<ItemGroup>
<Folder Include="src\data" />
<Folder Include="src\elements\charts" />
<Folder Include="src\elements\ui" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -10,13 +10,8 @@ namespace SomeChartsUi.backends;
/// all positions and scales are in screen-space transform
/// </summary>
public abstract class ChartsBackendBase {
public ChartsCanvas owner;
public ChartCanvasRenderer renderer;
protected ChartsBackendBase(ChartsCanvas owner, ChartCanvasRenderer renderer) {
this.owner = owner;
this.renderer = renderer;
}
public ChartsCanvas owner = null!;
public ChartCanvasRenderer renderer = null!;
public abstract unsafe void DrawMesh(float2* points, float2* uvs, color* colors, ushort* indexes, int vertexCount, int indexCount);
public abstract void DrawMesh(float2[] points, float2[]? uvs, color[]? colors, ushort[] indexes);
@ -24,4 +19,6 @@ public abstract class ChartsBackendBase {
public abstract void DrawText(string text, float2 pos, color col, FontData font, float scale = 12);
public abstract void DrawRect(rect rectangle, color color);
}

Просмотреть файл

@ -0,0 +1,17 @@
using SomeChartsUi.themes.colors;
using SomeChartsUi.ui.elements;
using SomeChartsUi.utils.rects;
using SomeChartsUi.utils.vectors;
namespace SomeChartsUi.elements.other;
public class TestRenderable : RenderableBase {
protected override void Render() {
rect r = new(-100, -100, 200, 200);
float2[] points = {r.leftBottom, r.leftTop, r.rightTop, r.rightBottom};
color[] colors = {color.red, color.softRed, color.blue, color.softBlue};
ushort[] indexes = {0, 1, 2, 0, 2, 3};
DrawVertices(points, null, colors, indexes);
//Console.WriteLine("render");
}
}

Просмотреть файл

@ -1,12 +1,14 @@
using SomeChartsUi.backends;
using SomeChartsUi.ui.layers;
namespace SomeChartsUi.ui.canvas;
public class ChartCanvasRenderer {
public ChartsCanvas owner;
public ChartsBackendBase backend;
public readonly ChartsBackendBase backend;
public readonly List<CanvasLayer> layers = new();
public readonly Dictionary<string, int> layerNames = new();
public ChartCanvasRenderer(ChartsCanvas owner, ChartsBackendBase backend) {
this.owner = owner;

Просмотреть файл

@ -5,8 +5,8 @@ using SomeChartsUi.utils.vectors;
namespace SomeChartsUi.ui.canvas;
public class ChartCanvasTransform {
public CanvasAnimVariable<float2> position = new(float2.zero);
public CanvasAnimVariable<float2> zoom = new(float2.one);
public CanvasAnimVariable<float2> position = new(float2.zero, animationSpeed: .05f);
public CanvasAnimVariable<float2> zoom = new(float2.one, animationSpeed: .05f);
public CanvasAnimVariable<float> rotation = new(0);
public rect screenBounds;
@ -25,4 +25,10 @@ public class ChartCanvasTransform {
worldBounds = screenBounds.ToWorld(position, zoom);
}
public void SetAnimToCurrent() {
position.OnUpdate(10000);
zoom.OnUpdate(10000);
rotation.OnUpdate(10000);
}
}

Просмотреть файл

@ -1,4 +1,6 @@
using SomeChartsUi.backends;
using SomeChartsUi.ui.canvas.controls;
using SomeChartsUi.ui.layers;
namespace SomeChartsUi.ui.canvas;
@ -6,8 +8,30 @@ public class ChartsCanvas {
public ChartCanvasTransform transform;
public ChartCanvasRenderer renderer;
public ChartCanvasControllerBase? controller;
private List<CanvasLayer> layers => renderer.layers;
private Dictionary<string, int> layerNames => renderer.layerNames;
public ChartsCanvas(ChartsBackendBase backend) {
transform = new();
renderer = new(this, backend);
backend.owner = this;
backend.renderer = renderer;
}
public CanvasLayer AddLayer(string name) {
CanvasLayer l = new(this, name);
renderer.layerNames.Add(name, layers.Count);
layers.Add(l);
return l;
}
public void RemoveLayer(string name) {
if (!layerNames.ContainsKey(name)) return;
layers.RemoveAt(layerNames[name]);
layerNames.Remove(name);
}
public CanvasLayer? GetLayer(string name) => layerNames.TryGetValue(name, out int i) ? layers[i] : null;
public CanvasLayer GetLayer(int i) => layers[i];
}

Просмотреть файл

@ -4,8 +4,25 @@ namespace SomeChartsUi.ui.canvas;
//TODO: method arguments is a subject of change
public interface ICanvasControls {
public void OnMouseMove(float2 pointerPos) {}
public void OnMouseDown(PointerButtons buttons, keymods mods) {}
public void OnMouseUp(PointerButtons buttons, keymods mods) {}
public void OnMouseMove(MouseState state) {}
public void OnMouseDown(MouseState state) {}
public void OnMouseUp(MouseState state) {}
public void OnMouseScroll(MouseState state) {}
public void OnKey(keycode key, keymods mods) {}
}
public class MouseState {
public float2 pos;
public float2 wheel;
public PointerButtons buttons;
public keymods modifiers;
public object? capture;
public MouseState(float2 pos, float2 wheel, PointerButtons buttons, keymods modifiers, object? capture) {
this.pos = pos;
this.wheel = wheel;
this.buttons = buttons;
this.modifiers = modifiers;
this.capture = capture;
}
}

Просмотреть файл

@ -0,0 +1,33 @@
namespace SomeChartsUi.ui.canvas.controls;
public class CanvasCompositeController : ChartCanvasControllerBase {
public List<CanvasCompositeController> controllers = new();
public CanvasCompositeController(ChartsCanvas owner) : base(owner) { }
public override void OnUpdate(float deltatime) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnUpdate(deltatime);
}
public override void OnMouseMove(MouseState state) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnMouseMove(state);
}
public override void OnMouseDown(MouseState state) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnMouseDown(state);
}
public override void OnMouseUp(MouseState state) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnMouseUp(state);
}
public override void OnMouseScroll(MouseState state) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnMouseScroll(state);
}
public override void OnKey(keycode key, keymods mods) {
foreach (CanvasCompositeController ctrl in controllers)
ctrl.OnKey(key, mods);
}
}

Просмотреть файл

@ -0,0 +1,76 @@
using SomeChartsUi.utils.vectors;
namespace SomeChartsUi.ui.canvas.controls;
public class CanvasUiController : ChartCanvasControllerBase {
private float2 _start;
private float2 _origin;
public float zoomSpeed = .2f;
public CanvasUiController(ChartsCanvas owner) : base(owner) { }
public override void OnMouseMove(MouseState state) {
float2 pointerPos = state.pos;
pointerPos.FlipY();
if (state.capture == null) return;
float speed = 1;
if ((state.modifiers & keymods.alt) != 0) speed = 4;
float2 mov = (pointerPos - _start) / owner.transform.zoom.currentValue * speed + _origin;
SetPosition(mov);
//_start = e.GetPosition(this);
//_start.FlipY();
_start = pointerPos;
_origin = mov;
}
public override void OnMouseDown(MouseState state) {
float2 pointerPos = state.pos;
pointerPos.FlipY();
state.capture = this;
_start = pointerPos;
_origin = owner.transform.position.currentValue;
//Cursor = Cursor.Parse("Hand");
}
public override void OnMouseUp(MouseState state) {
state.capture = null;
//Cursor = Cursor.Default;
}
public override void OnMouseScroll(MouseState state) {
float2 pointerPos = state.pos;
pointerPos.FlipY();
bool disableAnim = false;
float2 zoomAdd = zoomSpeed * state.wheel.yy;
if ((state.modifiers & keymods.shift) != 0) zoomAdd.x = 0;
if ((state.modifiers & keymods.ctrl) != 0) zoomAdd.y = 0;
if ((state.modifiers & keymods.alt) != 0) {
zoomAdd.x *= 2;
zoomAdd.y *= 2;
disableAnim = true;
}
float2 oldScale = owner.transform.zoom.currentValue;
float2 newScale = float2.Clamp(oldScale * (1 + zoomAdd), .001f, 1.5f);
// float2 newScale = new(Math.Clamp(oldScale.x * (1 + zoomAdd.x), .001f, 1.5f), Math.Clamp(oldScale.y * (1 + zoomAdd.y), .001f, 1.5f));
zoomAdd = 1 - newScale / oldScale;
SetZoom(newScale);
float2 posOffset = new(pointerPos.x * zoomAdd.x / newScale.x,
(owner.transform.screenBounds.height + pointerPos.y) * zoomAdd.y / newScale.y);
Move(posOffset);
if (disableAnim) owner.transform.SetAnimToCurrent();
}
public override void OnUpdate(float deltatime) { }
}

Просмотреть файл

@ -2,7 +2,7 @@ using SomeChartsUi.utils.vectors;
namespace SomeChartsUi.ui.canvas.controls;
public abstract class ChartCanvasControllerBase : ICanvasUpdate {
public abstract class ChartCanvasControllerBase : ICanvasUpdate, ICanvasControls {
protected ChartsCanvas owner;
protected ChartCanvasControllerBase(ChartsCanvas owner) => this.owner = owner;
@ -30,4 +30,16 @@ public abstract class ChartCanvasControllerBase : ICanvasUpdate {
owner.transform.position.OnUpdate(1000);
owner.transform.zoom.OnUpdate(1000);
}
public virtual void OnMouseMove(MouseState state) {
}
public virtual void OnMouseDown(MouseState state) {
}
public virtual void OnMouseUp(MouseState state) {
}
public virtual void OnMouseScroll(MouseState state) {
}
public virtual void OnKey(keycode key, keymods mods) {
}
}

Просмотреть файл

@ -5,16 +5,23 @@ using SomeChartsUi.ui.elements;
namespace SomeChartsUi.ui.layers;
public class CanvasLayer {
public ChartsCanvas owner;
public readonly string name;
public readonly ChartsCanvas owner;
public color? background;
public List<RenderableBase> elements = new();
public readonly List<RenderableBase> elements = new();
public CanvasLayer(ChartsCanvas owner) => this.owner = owner;
public CanvasLayer(ChartsCanvas owner, string name) {
this.owner = owner;
this.name = name;
}
public void AddElement(RenderableBase r) => elements.Add(r);
public void RemoveElement(RenderableBase r) => elements.Remove(r);
public void Render() {
if (background != null) owner.renderer.backend.DrawRect(owner.transform.screenBounds, background.Value);
foreach (RenderableBase element in elements) {
element.Render(owner);
}
}
}

Просмотреть файл

@ -11,6 +11,11 @@ public struct rect {
public float right => left + width;
public float top => bottom + height;
public float2 leftBottom => new(left, bottom);
public float2 leftTop => new(left, top);
public float2 rightTop => new(right, top);
public float2 rightBottom => new(right, bottom);
public float midX => left + width * .5f;
public float midY => bottom + height * .5f;

Просмотреть файл

@ -28,6 +28,8 @@ public struct float2 {
public void FlipY() => y = -y;
public void FlipX() => x = -x;
public void Flip() => (x, y) = (-x, -y);
public static implicit operator float2(float v) => new(v);
public static implicit operator float2(int v) => new(v);
@ -62,8 +64,14 @@ public struct float2 {
public static float2 SinCos(float rad) => new(MathF.Sin(rad), MathF.Cos(rad));
public static float2 SinCos(float rad, float len) => new(MathF.Sin(rad) * len, MathF.Cos(rad) * len);
public static float2 Min(float2 a, float2 b) => new(math.min(a.x, b.x), math.min(a.y, b.y));
public static float2 Max(float2 a, float2 b) => new(math.max(a.x, b.x), math.max(a.y, b.y));
public static float2 Clamp(float2 v, float2 min, float2 max) => Max(Min(v, max), min);
public bool Equals(float2 other) => x == other.x && y == other.y;
public override bool Equals(object? obj) => obj is float2 other && Equals(other);
public override int GetHashCode() => HashCode.Combine(x, y);
public override string ToString() => $"({x},{y})";
}

Просмотреть файл

@ -2,8 +2,10 @@
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:controls="clr-namespace:SomeChartsUiAvalonia.controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SomeChartsUiAvalonia.MainWindow"
Title="SomeChartsUiAvalonia">
Welcome to Avalonia!
<controls:AvaloniaChartsCanvas/>
</Window>

Просмотреть файл

@ -25,7 +25,6 @@
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.0-preview.187" />
</ItemGroup>
<ItemGroup>
<Folder Include="src\controls" />
<Folder Include="src\ui" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -48,16 +48,21 @@ public class SkiaChartsBackend : ChartsBackendBase, IDisposable {
// skia using flipped y axis, so flip back it
canvas.Scale(1,-1);
canvas.Translate(0, -owner.transform.screenBounds.height);
canvas.Scale((owner.transform.zoom.animatedValue).sk());
canvas.Translate(owner.transform.position.animatedValue.sk());
_canvas?.Dispose();
_canvas = canvas;
_paint ??= new();
_paint.SubpixelText = true;
_paint.Color = SKColors.White;
_paint.StrokeWidth = 2;
//_paint.Typeface = owner.theme.uiFontName;
_paint.IsAntialias = true;
}
public SkiaChartsBackend(ChartsCanvas owner, ChartCanvasRenderer renderer) : base(owner, renderer) { }
public void Dispose() {
_canvas?.Dispose();
_paint?.Dispose();
}
}

Просмотреть файл

@ -0,0 +1,233 @@
using System;
using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Skia;
using SkiaSharp;
using SomeChartsUi.elements.other;
using SomeChartsUi.themes.colors;
using SomeChartsUi.ui;
using SomeChartsUi.ui.canvas;
using SomeChartsUi.ui.canvas.controls;
using SomeChartsUi.ui.elements;
using SomeChartsUi.ui.layers;
using SomeChartsUi.utils.vectors;
using SomeChartsUiAvalonia.backends;
using SomeChartsUiAvalonia.utils;
namespace SomeChartsUiAvalonia.controls;
public class AvaloniaChartsCanvas : Panel {
public ChartsCanvas canvas = CreateCanvas();
public TimeSpan zoomUpdateTime;
public TimeSpan panUpdateTime;
public int updateInterval_hover = 16;
public int updateInterval = 200;
public string chartName = "???";
public bool stopRender;
private Timer? _updateTimer;
private TimeSpan _prevUpdTime;
private static ChartsCanvas CreateCanvas() {
ChartsCanvas canvas = new(new SkiaChartsBackend());
canvas.AddLayer("bg");
canvas.AddLayer("normal");
canvas.AddLayer("top");
return canvas;
}
public AvaloniaChartsCanvas() {
_updateTimer = new(_ => Update(), null, 0, 10);
canvas.controller = new CanvasUiController(canvas);
canvas.GetLayer("bg")!.background = color.purple;
AddElement(new TestRenderable());
}
protected override void OnPointerPressed(PointerPressedEventArgs e) {
PointerPoint currentPoint = e.GetCurrentPoint(this);
PointerButtons buttons = default;
if (currentPoint.Properties.IsLeftButtonPressed) buttons |= PointerButtons.left;
if (currentPoint.Properties.IsRightButtonPressed) buttons |= PointerButtons.right;
if (currentPoint.Properties.IsMiddleButtonPressed) buttons |= PointerButtons.middle;
if (currentPoint.Properties.IsXButton1Pressed) buttons |= PointerButtons.forward;
if (currentPoint.Properties.IsXButton2Pressed) buttons |= PointerButtons.backward;
keymods mods = default;
if ((e.KeyModifiers & KeyModifiers.Shift) != 0) mods |= keymods.shift;
if ((e.KeyModifiers & KeyModifiers.Control) != 0) mods |= keymods.ctrl;
if ((e.KeyModifiers & KeyModifiers.Alt) != 0) mods |= keymods.alt;
if ((e.KeyModifiers & KeyModifiers.Meta) != 0) mods |= keymods.super;
MouseState s = new(currentPoint.Position.ch(), float2.zero, buttons, mods, currentPoint.Pointer.Captured);
canvas.controller?.OnMouseDown(s);
}
protected override void OnPointerMoved(PointerEventArgs e) {
PointerPoint currentPoint = e.GetCurrentPoint(this);
PointerButtons buttons = default;
if (currentPoint.Properties.IsLeftButtonPressed) buttons |= PointerButtons.left;
if (currentPoint.Properties.IsRightButtonPressed) buttons |= PointerButtons.right;
if (currentPoint.Properties.IsMiddleButtonPressed) buttons |= PointerButtons.middle;
if (currentPoint.Properties.IsXButton1Pressed) buttons |= PointerButtons.forward;
if (currentPoint.Properties.IsXButton2Pressed) buttons |= PointerButtons.backward;
keymods mods = default;
if ((e.KeyModifiers & KeyModifiers.Shift) != 0) mods |= keymods.shift;
if ((e.KeyModifiers & KeyModifiers.Control) != 0) mods |= keymods.ctrl;
if ((e.KeyModifiers & KeyModifiers.Alt) != 0) mods |= keymods.alt;
if ((e.KeyModifiers & KeyModifiers.Meta) != 0) mods |= keymods.super;
MouseState s = new(currentPoint.Position.ch(), float2.zero, buttons, mods, currentPoint.Pointer.Captured);
canvas.controller?.OnMouseMove(s);
}
protected override void OnPointerReleased(PointerReleasedEventArgs e) {
PointerPoint currentPoint = e.GetCurrentPoint(this);
PointerButtons buttons = default;
if (currentPoint.Properties.IsLeftButtonPressed) buttons |= PointerButtons.left;
if (currentPoint.Properties.IsRightButtonPressed) buttons |= PointerButtons.right;
if (currentPoint.Properties.IsMiddleButtonPressed) buttons |= PointerButtons.middle;
if (currentPoint.Properties.IsXButton1Pressed) buttons |= PointerButtons.forward;
if (currentPoint.Properties.IsXButton2Pressed) buttons |= PointerButtons.backward;
keymods mods = default;
if ((e.KeyModifiers & KeyModifiers.Shift) != 0) mods |= keymods.shift;
if ((e.KeyModifiers & KeyModifiers.Control) != 0) mods |= keymods.ctrl;
if ((e.KeyModifiers & KeyModifiers.Alt) != 0) mods |= keymods.alt;
if ((e.KeyModifiers & KeyModifiers.Meta) != 0) mods |= keymods.super;
MouseState s = new(currentPoint.Position.ch(), float2.zero, buttons, mods, currentPoint.Pointer.Captured);
canvas.controller?.OnMouseUp(s);
}
protected override void OnPointerWheelChanged(PointerWheelEventArgs e) {
PointerPoint currentPoint = e.GetCurrentPoint(this);
PointerButtons buttons = default;
if (currentPoint.Properties.IsLeftButtonPressed) buttons |= PointerButtons.left;
if (currentPoint.Properties.IsRightButtonPressed) buttons |= PointerButtons.right;
if (currentPoint.Properties.IsMiddleButtonPressed) buttons |= PointerButtons.middle;
if (currentPoint.Properties.IsXButton1Pressed) buttons |= PointerButtons.forward;
if (currentPoint.Properties.IsXButton2Pressed) buttons |= PointerButtons.backward;
keymods mods = default;
if ((e.KeyModifiers & KeyModifiers.Shift) != 0) mods |= keymods.shift;
if ((e.KeyModifiers & KeyModifiers.Control) != 0) mods |= keymods.ctrl;
if ((e.KeyModifiers & KeyModifiers.Alt) != 0) mods |= keymods.alt;
if ((e.KeyModifiers & KeyModifiers.Meta) != 0) mods |= keymods.super;
MouseState s = new(currentPoint.Position.ch(), e.Delta.ch(), buttons, mods, currentPoint.Pointer.Captured);
canvas.controller?.OnMouseScroll(s);
}
protected override void OnKeyUp(KeyEventArgs e) {
// if (e.Key == Key.R) {
// if ((e.KeyModifiers & KeyModifiers.Shift) != 0) ResetTransform();
// else ResetXYZoom();
// }
//
// if (e.Key == Key.T) ToggleTheme();
//
// if (e.Key == Key.P) {
// UpdateTransformAnimation();
// using var img = RenderImage();
// using var data = img.Encode(SKEncodedImageFormat.Png, 100);
//
// using FileStream fs = new(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + $"/SomeChartsSnapshot_{new Random().Next(100_000, 999_999):X}.png", FileMode.Create);
// data.SaveTo(fs);
// Console.WriteLine("aaaa");
// }
//
// if (e.Key == Key.W) positionWithoutAnim.Y -= 100 / scale.Y;
// if (e.Key == Key.S) positionWithoutAnim.Y += 100 / scale.Y;
// if (e.Key == Key.A) positionWithoutAnim.X += 100 / scale.X;
// if (e.Key == Key.D) positionWithoutAnim.X -= 100 / scale.X;
}
public void Rebuild() {
canvas.transform.screenBounds = Bounds.ch();
canvas.transform.Update();
InvalidateVisual();
}
private void Update() {
try {
if (stopRender || !CheckUpdateDelay()) return;
//UpdateAnim();
Rebuild();
_prevUpdTime = DateTime.Now.TimeOfDay;
}
catch (Exception e) {
// ignored
}
}
private bool CheckUpdateDelay() {
if (Environment.HasShutdownStarted) {
_updateTimer = null;
stopRender = true;
return false;
}
var now = DateTime.Now.TimeOfDay;
var maxDiff = TimeSpan.FromMilliseconds(IsPointerOver ? updateInterval_hover : updateInterval);
return now - _prevUpdTime >= maxDiff;
}
public override void Render(DrawingContext context) {
canvas.transform.screenBounds = Bounds.ch();
//renderer!.bounds = Bounds;
//renderer.position = position;
//renderer.scale = scale;
//renderer.theme = theme;
context.Custom(new CustomRender(canvas, Bounds));
}
public SKImage RenderImage() => throw new NotImplementedException();
// SKImageInfo info = new((int)Bounds.Width, (int)Bounds.Height);
//
// using var surf = SKSurface.Create(info);
//
// var canvas = surf.Canvas;
// canvas.Scale(1, -1);
// canvas.Translate(0, (float)-Bounds.Height);
// renderer!.Render();
// canvas.DrawBitmap(renderer.snapshot, renderer.bounds);
// return surf.Snapshot();
public void AddElement(RenderableBase el, string layer = "normal") {
(canvas.GetLayer(layer) ?? canvas.GetLayer(1)).AddElement(el);
}
public void RemoveElement(RenderableBase el, string layer = "normal") {
(canvas.GetLayer(layer) ?? canvas.GetLayer(1)).RemoveElement(el);
}
private class CustomRender : ICustomDrawOperation {
private readonly ChartsCanvas _owner;
public CustomRender(ChartsCanvas owner, Rect bounds) {
_owner = owner;
Bounds = bounds;
}
public Rect Bounds { get; }
public void Dispose() { }
public bool HitTest(Point p) => Bounds.Contains(p);
public bool Equals(ICustomDrawOperation? other) => false;
public void Render(IDrawingContextImpl context) {
((SkiaChartsBackend)_owner.renderer.backend).SetRenderingVariables(context);
//((ISkiaDrawingContextImpl) context).SkCanvas.Clear();
foreach (CanvasLayer layer in _owner.renderer!.layers)
layer.Render();
}
}
}

Просмотреть файл

@ -1,3 +1,4 @@
using Avalonia;
using SkiaSharp;
using SomeChartsUi.themes.colors;
using SomeChartsUi.utils.rects;
@ -6,12 +7,15 @@ using SomeChartsUi.utils.vectors;
namespace SomeChartsUiAvalonia.utils;
public static class SkiaChartsUtils {
public static SKRect sk(this rect v) => new(v.left, v.bottom, v.right, v.top); // skia using inverted y axis, so swap bottom and top
public static rect ch(this SKRect v) => new(v.Left, v.Bottom, v.Right, v.Top); // skia using inverted y axis, so swap bottom and top
public static SKRect sk(this rect v) => new(v.left, v.bottom, v.right, v.top); // skia using inverted y axis, so swap bottom and top
public static rect ch(this SKRect v) => new(v.Left, v.Bottom, v.Right, v.Top); // skia using inverted y axis, so swap bottom and top
public static rect ch(this Rect v) => new((float)v.Left, (float) v.Bottom, (float)v.Right, (float)v.Top);// skia using inverted y axis, so swap bottom and top
public static SKColor sk(this color v) => new(v.raw);
public static color ch(this SKColor v) => new(v.Red, v.Green, v.Blue, v.Alpha);
public static SKPoint sk(this float2 v) => new(v.x, v.y);
public static float2 ch(this SKPoint v) => new(v.X, v.Y);
public static float2 ch(this Point v) => new((float)v.X, (float)v.Y);
public static float2 ch(this Vector v) => new((float)v.X, (float)v.Y);
}