Anpassung am Sitzplan
This commit is contained in:
@@ -10,6 +10,9 @@ namespace LehrerApp.Desktop.Views.Groups;
|
||||
|
||||
public partial class SeatingPlanTabView : UserControl
|
||||
{
|
||||
private const double AutoScrollEdgeSize = 72;
|
||||
private const double AutoScrollStep = 14;
|
||||
|
||||
private object? _dragCandidate;
|
||||
private PointerPressedEventArgs? _dragTrigger;
|
||||
private Avalonia.Point _pressPosition;
|
||||
@@ -18,8 +21,15 @@ public partial class SeatingPlanTabView : UserControl
|
||||
private SeatCellViewModel? _pendingDropTarget;
|
||||
private bool _pendingClearSeat;
|
||||
private DateTime _ignoreTapUntil;
|
||||
private readonly DispatcherTimer _autoScrollTimer;
|
||||
private Avalonia.Vector _autoScrollDirection;
|
||||
|
||||
public SeatingPlanTabView() => InitializeComponent();
|
||||
public SeatingPlanTabView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_autoScrollTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(30) };
|
||||
_autoScrollTimer.Tick += OnAutoScrollTick;
|
||||
}
|
||||
|
||||
protected override void OnDataContextChanged(EventArgs e)
|
||||
{
|
||||
@@ -69,6 +79,7 @@ public partial class SeatingPlanTabView : UserControl
|
||||
_draggedStudent = null;
|
||||
_pendingDropTarget = null;
|
||||
_pendingClearSeat = false;
|
||||
StopAutoScroll();
|
||||
_ignoreTapUntil = DateTime.UtcNow.AddMilliseconds(250);
|
||||
|
||||
// Never mutate an ItemsControl while Avalonia is still processing its native
|
||||
@@ -107,6 +118,7 @@ public partial class SeatingPlanTabView : UserControl
|
||||
|
||||
private void OnSeatDrop(object? sender, DragEventArgs e)
|
||||
{
|
||||
StopAutoScroll();
|
||||
if (sender is not Border { DataContext: SeatCellViewModel target }) return;
|
||||
target.IsDropTarget = false;
|
||||
if (!CanDropOn(target))
|
||||
@@ -128,6 +140,7 @@ public partial class SeatingPlanTabView : UserControl
|
||||
|
||||
private void OnUnassignedDrop(object? sender, DragEventArgs e)
|
||||
{
|
||||
StopAutoScroll();
|
||||
if (_draggedSeat is not null)
|
||||
{
|
||||
_pendingDropTarget = null;
|
||||
@@ -136,6 +149,50 @@ public partial class SeatingPlanTabView : UserControl
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomDragOver(object? sender, DragEventArgs e)
|
||||
{
|
||||
if (_draggedSeat is null && _draggedStudent is null)
|
||||
{
|
||||
StopAutoScroll();
|
||||
return;
|
||||
}
|
||||
|
||||
var position = e.GetPosition(RoomScrollViewer);
|
||||
_autoScrollDirection = new Avalonia.Vector(
|
||||
GetAutoScrollDirection(position.X, RoomScrollViewer.Bounds.Width),
|
||||
GetAutoScrollDirection(position.Y, RoomScrollViewer.Bounds.Height));
|
||||
|
||||
if (_autoScrollDirection == default)
|
||||
StopAutoScroll();
|
||||
else if (!_autoScrollTimer.IsEnabled)
|
||||
_autoScrollTimer.Start();
|
||||
}
|
||||
|
||||
private void OnRoomDragLeave(object? sender, DragEventArgs e) => StopAutoScroll();
|
||||
|
||||
private void OnAutoScrollTick(object? sender, EventArgs e)
|
||||
{
|
||||
var maxX = Math.Max(0, RoomScrollViewer.Extent.Width - RoomScrollViewer.Viewport.Width);
|
||||
var maxY = Math.Max(0, RoomScrollViewer.Extent.Height - RoomScrollViewer.Viewport.Height);
|
||||
var offset = RoomScrollViewer.Offset;
|
||||
RoomScrollViewer.Offset = new Avalonia.Vector(
|
||||
Math.Clamp(offset.X + _autoScrollDirection.X * AutoScrollStep, 0, maxX),
|
||||
Math.Clamp(offset.Y + _autoScrollDirection.Y * AutoScrollStep, 0, maxY));
|
||||
}
|
||||
|
||||
private static double GetAutoScrollDirection(double position, double viewportSize)
|
||||
{
|
||||
if (position < AutoScrollEdgeSize) return -1;
|
||||
if (position > viewportSize - AutoScrollEdgeSize) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void StopAutoScroll()
|
||||
{
|
||||
_autoScrollDirection = default;
|
||||
_autoScrollTimer.Stop();
|
||||
}
|
||||
|
||||
private async void OnSeatTapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
if (DateTime.UtcNow < _ignoreTapUntil || sender is not Border { DataContext: SeatCellViewModel seat }
|
||||
|
||||
Reference in New Issue
Block a user