103 lines
3.1 KiB
C#
103 lines
3.1 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.Shapes;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Media;
|
|
using Avalonia.VisualTree;
|
|
using DelauneyTriangulation.ViewModels;
|
|
|
|
namespace DelauneyTriangulation.Views;
|
|
|
|
public partial class MainWindow : Window
|
|
{
|
|
private bool _isPanning;
|
|
private Point _panStart;
|
|
private Vector _panOffset = new();
|
|
|
|
private double _scale = 1.0;
|
|
private const double MinScale = 0.2;
|
|
private const double MaxScale = 8.0;
|
|
|
|
private readonly TranslateTransform _panTransform = new();
|
|
private readonly ScaleTransform _scaleTransform = new();
|
|
private readonly TransformGroup _transformGroup = new();
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
_transformGroup.Children.Add(_scaleTransform);
|
|
_transformGroup.Children.Add(_panTransform);
|
|
SceneContent.RenderTransform = _transformGroup;
|
|
|
|
if (DataContext is MainWindowViewModel vm) vm.View = this;
|
|
}
|
|
|
|
private void OnTitleBarPointerPressed(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
|
|
BeginMoveDrag(e);
|
|
}
|
|
private void OnTitleBarDoubleTapped(object? sender, RoutedEventArgs e) => WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
|
|
private void Scene_OnPointerPressed(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (!e.GetCurrentPoint(Scene).Properties.IsLeftButtonPressed)
|
|
return;
|
|
|
|
_isPanning = true;
|
|
_panStart = e.GetPosition(this);
|
|
Scene.Cursor = new Cursor(StandardCursorType.SizeAll);
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void Scene_OnPointerMoved(object? sender, PointerEventArgs e)
|
|
{
|
|
if (!_isPanning) return;
|
|
|
|
var pos = e.GetPosition(this);
|
|
var delta = pos - _panStart;
|
|
var current = _panOffset + delta;
|
|
_panTransform.X = current.X;
|
|
_panTransform.Y = current.Y;
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void Scene_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
|
{
|
|
if (!_isPanning) return;
|
|
|
|
var pos = e.GetPosition(this);
|
|
var delta = pos - _panStart;
|
|
_panOffset += delta;
|
|
|
|
_isPanning = false;
|
|
Scene.Cursor = new Cursor(StandardCursorType.Arrow);
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void Scene_OnWheel(object? sender, PointerWheelEventArgs e)
|
|
{
|
|
var mouse = e.GetPosition(Scene);
|
|
|
|
var oldScale = _scale;
|
|
var factor = Math.Pow(1.1, e.Delta.Y);
|
|
var newScale = Math.Clamp(oldScale * factor, MinScale, MaxScale);
|
|
var applied = newScale / oldScale;
|
|
|
|
_scale = newScale;
|
|
_scaleTransform.ScaleX = _scaleTransform.ScaleY = _scale;
|
|
|
|
_panOffset = new Vector(
|
|
mouse.X - applied * (mouse.X - _panOffset.X),
|
|
mouse.Y - applied * (mouse.Y - _panOffset.Y)
|
|
);
|
|
|
|
_panTransform.X = _panOffset.X;
|
|
_panTransform.Y = _panOffset.Y;
|
|
|
|
e.Handled = true;
|
|
}
|
|
} |