diff --git a/src/Lumper.UI/App.axaml.cs b/src/Lumper.UI/App.axaml.cs index 22bf68a3..8d111cbe 100644 --- a/src/Lumper.UI/App.axaml.cs +++ b/src/Lumper.UI/App.axaml.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Avalonia.Markup.Xaml; using Lumper.UI.ViewModels; using Lumper.UI.Views; @@ -17,11 +18,22 @@ public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + var vm = new MainWindowViewModel(); desktop.MainWindow = new MainWindow { - DataContext = new MainWindowViewModel() + DataContext = vm, }; + desktop.MainWindow.AddHandler(DragDrop.DragOverEvent, MainWindowViewModel.DragOver); + desktop.MainWindow.AddHandler(DragDrop.DropEvent, vm.Drop); + + if (desktop.Args?.Length > 0) + { + vm.LoadBsp(desktop.Args[0]); + } + } + base.OnFrameworkInitializationCompleted(); } } diff --git a/src/Lumper.UI/ViewModels/MainWindowViewModel.IO.cs b/src/Lumper.UI/ViewModels/MainWindowViewModel.IO.cs index 5f3199a5..96d2c51e 100644 --- a/src/Lumper.UI/ViewModels/MainWindowViewModel.IO.cs +++ b/src/Lumper.UI/ViewModels/MainWindowViewModel.IO.cs @@ -148,13 +148,13 @@ private async void Save(string path) _bspModel.FilePath = path; } - private void LoadBsp(string path) + public void LoadBsp(string path) { var bspFile = new BspFile(path); BspModel = new BspViewModel(this, bspFile); } - private async Task LoadBsp(IStorageFile file) + public async Task LoadBsp(IStorageFile file) { if (!file.CanOpenRead) return; @@ -163,7 +163,7 @@ private async Task LoadBsp(IStorageFile file) if(!file.TryGetUri(out var path)) { throw new Exception("Failed to get file path"); - + } LoadBsp(path.AbsolutePath); } diff --git a/src/Lumper.UI/ViewModels/MainWindowViewModel.cs b/src/Lumper.UI/ViewModels/MainWindowViewModel.cs index c23e767d..72917ff9 100644 --- a/src/Lumper.UI/ViewModels/MainWindowViewModel.cs +++ b/src/Lumper.UI/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,10 @@ using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Lumper.UI.ViewModels.Bsp; using ReactiveUI; @@ -45,4 +49,49 @@ public BspNodeBase? SelectedNode get => _selectedNode; set => this.RaiseAndSetIfChanged(ref _selectedNode, value); } + + internal static void DragOver(object? sender, DragEventArgs e) + { + e.DragEffects = DragDropEffects.Link; + + var names = e.Data.GetFileNames() ?? new List(); + + if (!e.Data.Contains(DataFormats.FileNames) || !names.FirstOrDefault("").ToLower().EndsWith(".bsp")) + e.DragEffects = DragDropEffects.None; + } + + internal void Drop(object? sender, DragEventArgs e) + { + if (!e.Data.Contains(DataFormats.FileNames)) + return; + + var names = e.Data.GetFileNames() ?? new List(); + foreach (string target in names) + { + if (!target.ToLower().EndsWith(".bsp")) + continue; + + if (BspModel == null) + { + // if nothing is open, open it. + LoadBsp(target); + } + else + { + // Otherwise, open a brand new Lumper instance with it. + string? mainModuleFileName = Process.GetCurrentProcess().MainModule?.FileName; + if (mainModuleFileName == null) + return; + + string? executablePath = mainModuleFileName; + ProcessStartInfo startInfo = new ProcessStartInfo() + { + ArgumentList = { $"{target}" }, + FileName = executablePath, + }; + + Process.Start(startInfo); + } + } + } } diff --git a/src/Lumper.UI/Views/MainWindow.axaml b/src/Lumper.UI/Views/MainWindow.axaml index f222b67d..90c5c525 100644 --- a/src/Lumper.UI/Views/MainWindow.axaml +++ b/src/Lumper.UI/Views/MainWindow.axaml @@ -14,6 +14,7 @@ TransparencyLevelHint="AcrylicBlur" ExtendClientAreaToDecorationsHint="True" WindowStartupLocation="CenterScreen" + DragDrop.AllowDrop="True" Background="Transparent">