184 lines
5.0 KiB
C#
184 lines
5.0 KiB
C#
using Lattice.Core.Docking.Abstractions;
|
|
using Lattice.Core.Docking.Engine;
|
|
using Lattice.Core.Docking.Models;
|
|
using Lattice.UI.Docking.Abstractions;
|
|
using Microsoft.UI.Input;
|
|
using Microsoft.UI.Xaml.Controls;
|
|
using Microsoft.UI.Xaml.Input;
|
|
using Microsoft.UI.Xaml.Media;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace Lattice.UI;
|
|
|
|
public sealed class LatticeSplitter : Control, IDockSplitterControl, IDisposable
|
|
{
|
|
private bool _disposed;
|
|
private IDockElement? _model;
|
|
private LayoutManager? _layoutManager;
|
|
private IDockContextManager? _contextManager;
|
|
private bool _isSelected;
|
|
private bool _isActive;
|
|
private bool _isDragging;
|
|
|
|
public LatticeSplitter()
|
|
{
|
|
this.DefaultStyleKey = typeof(LatticeSplitter);
|
|
this.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
|
|
|
|
this.PointerEntered += (s, e) =>
|
|
this.ProtectedCursor = InputSystemCursor.Create(InputSystemCursorShape.SizeWestEast);
|
|
this.PointerExited += (s, e) =>
|
|
this.ProtectedCursor = InputSystemCursor.Create(InputSystemCursorShape.Arrow);
|
|
|
|
this.ManipulationDelta += OnManipulationDelta;
|
|
this.ManipulationStarted += (s, e) =>
|
|
{
|
|
IsDragging = true;
|
|
DragStarted?.Invoke(this, EventArgs.Empty);
|
|
};
|
|
this.ManipulationCompleted += (s, e) =>
|
|
{
|
|
IsDragging = false;
|
|
DragCompleted?.Invoke(this, EventArgs.Empty);
|
|
};
|
|
}
|
|
|
|
public IDockElement? Model
|
|
{
|
|
get => _model;
|
|
set
|
|
{
|
|
if (_model != value)
|
|
{
|
|
_model = value;
|
|
OnPropertyChanged(nameof(Model));
|
|
}
|
|
}
|
|
}
|
|
|
|
public LayoutManager? LayoutManager
|
|
{
|
|
get => _layoutManager;
|
|
set
|
|
{
|
|
if (_layoutManager != value)
|
|
{
|
|
_layoutManager = value;
|
|
OnPropertyChanged(nameof(LayoutManager));
|
|
}
|
|
}
|
|
}
|
|
|
|
public IDockContextManager? ContextManager
|
|
{
|
|
get => _contextManager;
|
|
set
|
|
{
|
|
if (_contextManager != value)
|
|
{
|
|
_contextManager = value;
|
|
OnPropertyChanged(nameof(ContextManager));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsSelected
|
|
{
|
|
get => _isSelected;
|
|
set
|
|
{
|
|
if (_isSelected != value)
|
|
{
|
|
_isSelected = value;
|
|
OnPropertyChanged(nameof(IsSelected));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsActive
|
|
{
|
|
get => _isActive;
|
|
set
|
|
{
|
|
if (_isActive != value)
|
|
{
|
|
_isActive = value;
|
|
OnPropertyChanged(nameof(IsActive));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool CanDrag => false;
|
|
public bool CanDrop => false;
|
|
|
|
public object? PrepareDragData() => null;
|
|
public bool HandleDrop(object data, DockPosition position) => false;
|
|
|
|
public Core.Docking.Models.SplitDirection Orientation { get; set; }
|
|
|
|
public bool IsDragging
|
|
{
|
|
get => _isDragging;
|
|
set
|
|
{
|
|
if (_isDragging != value)
|
|
{
|
|
_isDragging = value;
|
|
OnPropertyChanged(nameof(IsDragging));
|
|
}
|
|
}
|
|
}
|
|
|
|
public event EventHandler? DragStarted;
|
|
public event EventHandler<SplitterDraggedEventArgs>? DragDelta;
|
|
public event EventHandler? DragCompleted;
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
|
|
{
|
|
if (this.DataContext is not DockGroup group) return;
|
|
|
|
if (VisualTreeHelper.GetParent(this) is not Grid parentGrid ||
|
|
parentGrid.ActualWidth <= 0 || parentGrid.ActualHeight <= 0)
|
|
return;
|
|
|
|
double totalSize = group.Orientation == SplitDirection.Horizontal
|
|
? parentGrid.ActualWidth
|
|
: parentGrid.ActualHeight;
|
|
|
|
if (totalSize <= 0) return;
|
|
|
|
double delta = group.Orientation == SplitDirection.Horizontal
|
|
? e.Delta.Translation.X
|
|
: e.Delta.Translation.Y;
|
|
|
|
double ratioChange = delta / totalSize;
|
|
group.SplitRatio = Math.Clamp(group.SplitRatio + ratioChange, 0.05, 0.95);
|
|
|
|
DragDelta?.Invoke(this, new SplitterDraggedEventArgs(
|
|
group.Orientation == SplitDirection.Horizontal ? delta : 0,
|
|
group.Orientation == SplitDirection.Vertical ? delta : 0));
|
|
}
|
|
|
|
public void Refresh() { }
|
|
|
|
public void ApplyTheme(IDockTheme theme) { }
|
|
|
|
public void OnModelPropertyChanged(string propertyName) { }
|
|
|
|
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (!_disposed)
|
|
{
|
|
_disposed = true;
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
} |