mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
133 lines
4.2 KiB
C#
133 lines
4.2 KiB
C#
using System;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.Primitives;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Layout;
|
|
using Avalonia.LogicalTree;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Media;
|
|
using Avalonia.Media.Imaging;
|
|
using Avalonia.ReactiveUI;
|
|
using Avalonia.VisualTree;
|
|
|
|
namespace Artemis.UI.Screens.Sidebar;
|
|
|
|
public partial class SidebarCategoryView : ReactiveUserControl<SidebarCategoryViewModel>
|
|
{
|
|
private static Image? _dragAdorner;
|
|
private Point _dragStartPosition;
|
|
private Point _elementDragOffset;
|
|
|
|
public SidebarCategoryView()
|
|
{
|
|
InitializeComponent();
|
|
AddHandler(DragDrop.DragEnterEvent, HandleDragEnterEvent, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true);
|
|
AddHandler(DragDrop.DragOverEvent, HandleDragOver, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true);
|
|
AddHandler(PointerEnteredEvent, HandlePointerEnter, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true);
|
|
}
|
|
|
|
|
|
private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
|
{
|
|
if (e.InitialPressMouseButton == MouseButton.Left)
|
|
ViewModel?.ToggleCollapsed.Execute().Subscribe();
|
|
}
|
|
|
|
#region Dragging
|
|
|
|
private void HandlePointerEnter(object? sender, PointerEventArgs e)
|
|
{
|
|
DisposeDragAdorner();
|
|
}
|
|
|
|
private void HandleDragEnterEvent(object? sender, DragEventArgs e)
|
|
{
|
|
CreateDragAdorner(e);
|
|
}
|
|
|
|
private void CreateDragAdorner(DragEventArgs e)
|
|
{
|
|
Window? window = this.FindAncestorOfType<Window>();
|
|
if (window == null || _dragAdorner != null)
|
|
return;
|
|
|
|
if (e.Source is not Control c)
|
|
return;
|
|
|
|
// Get the list box item that raised the event
|
|
ListBoxItem? container = c.FindLogicalAncestorOfType<ListBoxItem>();
|
|
if (container == null)
|
|
return;
|
|
|
|
// Take a snapshot of said tree view item and add it as an adorner
|
|
ITransform? originalTransform = container.RenderTransform;
|
|
try
|
|
{
|
|
_dragStartPosition = e.GetPosition(window);
|
|
_elementDragOffset = e.GetPosition(container);
|
|
|
|
RenderTargetBitmap renderTarget = new(new PixelSize((int) container.Bounds.Width, (int) container.Bounds.Height));
|
|
container.RenderTransform = new TranslateTransform(container.Bounds.X * -1, container.Bounds.Y * -1);
|
|
renderTarget.Render(container);
|
|
_dragAdorner = new Image
|
|
{
|
|
Source = renderTarget,
|
|
VerticalAlignment = VerticalAlignment.Top,
|
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|
Stretch = Stretch.None,
|
|
IsHitTestVisible = false
|
|
};
|
|
AdornerLayer.GetAdornerLayer(this)!.Children.Add(_dragAdorner);
|
|
}
|
|
finally
|
|
{
|
|
container.RenderTransform = originalTransform;
|
|
}
|
|
}
|
|
|
|
private void HandleDragOver(object? sender, DragEventArgs e)
|
|
{
|
|
Window? window = this.FindAncestorOfType<Window>();
|
|
if (window != null)
|
|
UpdateDragAdorner(e.GetPosition(window));
|
|
}
|
|
|
|
private void HandleLeaveEvent(object? sender, RoutedEventArgs e)
|
|
{
|
|
// If there is currently an adorner, dispose of it
|
|
DisposeDragAdorner();
|
|
}
|
|
|
|
private void HandleDrop(object? sender, DragEventArgs e)
|
|
{
|
|
// If there is currently an adorner, dispose of it
|
|
DisposeDragAdorner();
|
|
}
|
|
|
|
private void DisposeDragAdorner()
|
|
{
|
|
if (_dragAdorner == null)
|
|
return;
|
|
|
|
AdornerLayer.GetAdornerLayer(this)!.Children.Remove(_dragAdorner);
|
|
(_dragAdorner.Source as RenderTargetBitmap)?.Dispose();
|
|
_dragAdorner = null;
|
|
}
|
|
|
|
private void UpdateDragAdorner(Point position)
|
|
{
|
|
if (_dragAdorner == null)
|
|
return;
|
|
|
|
_dragAdorner.RenderTransform = new TranslateTransform(_dragStartPosition.X - _elementDragOffset.X, position.Y - _elementDragOffset.Y);
|
|
}
|
|
|
|
private void InputElement_OnPointerMoved(object? sender, PointerEventArgs e)
|
|
{
|
|
DisposeDragAdorner();
|
|
}
|
|
|
|
#endregion
|
|
} |