CVR Manager 1.0.0

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Exterrata
2026-10-25 02:46:35 -04:00
commit 9bb4f85802
59 changed files with 7913 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Platform.Storage;
using Avalonia.VisualTree;
using CVRManager.ViewModels;
namespace CVRManager.Views;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new MainViewModel
{
PickFolder = async () =>
{
var r = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions { AllowMultiple = false });
return r.Count > 0 ? r[0].TryGetLocalPath() : null;
},
PickFiles = async () =>
{
var r = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
AllowMultiple = true,
FileTypeFilter = new[] { new FilePickerFileType("Mod files") { Patterns = new[] { "*.dll", "*.zip" } } },
});
return (IReadOnlyList<string>)r.Select(f => f.TryGetLocalPath()).Where(p => p != null).Select(p => p!).ToList();
},
Confirm = ConfirmAsync,
CopyImage = async path =>
{
if (Clipboard == null) return;
using var bmp = new Avalonia.Media.Imaging.Bitmap(path);
await Clipboard.SetBitmapAsync(bmp);
},
};
DataContext = vm;
Opened += (_, _) => WindowIcons.Apply(this);
HookInstallDrag(vm);
}
InstallVM? dragItem;
Point dragStart;
bool dragging;
void HookInstallDrag(MainViewModel vm)
{
var list = InstallList;
list.AddHandler(PointerPressedEvent, (_, e) =>
{
if (!e.GetCurrentPoint(list).Properties.IsLeftButtonPressed) return;
if ((e.Source as Visual)?.FindAncestorOfType<Button>(true) != null) return;
if ((e.Source as StyledElement)?.DataContext is not InstallVM item) return;
dragItem = item;
dragStart = e.GetPosition(list);
dragging = false;
}, RoutingStrategies.Bubble, true);
list.AddHandler(PointerMovedEvent, (_, e) =>
{
if (dragItem == null) return;
var p = e.GetPosition(list);
if (!dragging)
{
if (Math.Abs(p.Y - dragStart.Y) < 6) return;
dragging = true;
e.Pointer.Capture(list);
list.Cursor = new Cursor(StandardCursorType.SizeNorthSouth);
}
var from = vm.Installs.IndexOf(dragItem);
for (var i = 0; i < list.ItemCount; i++)
{
if (i == from || list.ContainerFromIndex(i) is not Control c || c.TranslatePoint(default, list) is not { } top) continue;
var mid = top.Y + c.Bounds.Height / 2;
if ((i > from && p.Y > mid && p.Y < top.Y + c.Bounds.Height) || (i < from && p.Y < mid && p.Y > top.Y))
{
vm.MoveInstall(dragItem, i);
break;
}
}
MarkDragged(list);
}, RoutingStrategies.Bubble, true);
void End()
{
if (dragItem == null) return;
var moved = dragging;
dragItem = null;
dragging = false;
list.Cursor = null;
MarkDragged(list);
if (moved) vm.Save();
}
list.AddHandler(PointerReleasedEvent, (_, e) => { if (dragging) e.Pointer.Capture(null); End(); }, RoutingStrategies.Bubble, true);
list.AddHandler(PointerCaptureLostEvent, (_, _) => End(), RoutingStrategies.Bubble, true);
}
void MarkDragged(ListBox list)
{
for (var i = 0; i < list.ItemCount; i++)
if (list.ContainerFromIndex(i) is Control c)
c.Opacity = dragging && c.DataContext == dragItem ? 0.6 : 1;
}
void OnTableSelection(object? sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && e.AddedItems[0] is GroupHeader header)
header.ToggleCommand.Execute(null);
}
async Task<bool> ConfirmAsync(string message)
{
var dlg = new Window
{
Title = "Confirm",
Width = 460,
SizeToContent = SizeToContent.Height,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
CanResize = false,
};
var ok = new Button { Content = "OK", Padding = new Thickness(18, 6) };
var cancel = new Button { Content = "Cancel", Padding = new Thickness(18, 6) };
ok.Click += (_, _) => dlg.Close(true);
cancel.Click += (_, _) => dlg.Close(false);
dlg.Content = new StackPanel
{
Margin = new Thickness(20),
Spacing = 16,
Children =
{
new TextBlock { Text = message, TextWrapping = Avalonia.Media.TextWrapping.Wrap },
new StackPanel
{
Orientation = Orientation.Horizontal,
Spacing = 8,
HorizontalAlignment = HorizontalAlignment.Right,
Children = { ok, cancel },
},
},
};
return await dlg.ShowDialog<bool>(this);
}
}