Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Test.MMManaged/obj
Native/.vscode/settings.json
Native/.ionide/symbolCache.db
MMLaunch/obj
MMLaunch/bin
.ionide/symbolCache.db
.rustc_info.json
Native/snaplib/target
Expand Down
48 changes: 45 additions & 3 deletions MMAll.dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,68 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MMManaged.Engine.dotnet", "
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MMTricks.dotnet", "MMTricks\MMTricks.dotnet.fsproj", "{AD894349-DD65-422F-80D1-0ED6F0052352}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MMLaunch", "MMLaunch\MMLaunch.fsproj", "{3F2FB480-E609-4415-96A7-C4BE6DB13570}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|x64.ActiveCfg = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|x64.Build.0 = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|x86.ActiveCfg = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Debug|x86.Build.0 = Debug|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|Any CPU.Build.0 = Release|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|x64.ActiveCfg = Release|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|x64.Build.0 = Release|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|x86.ActiveCfg = Release|Any CPU
{C6097DB3-F08B-4F18-9E9F-F87E4FE3C99B}.Release|x86.Build.0 = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|x64.ActiveCfg = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|x64.Build.0 = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|x86.ActiveCfg = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Debug|x86.Build.0 = Debug|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|Any CPU.Build.0 = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|x64.ActiveCfg = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|x64.Build.0 = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|x86.ActiveCfg = Release|Any CPU
{91E5FD7F-68BC-40F6-BFBE-549F0B82C671}.Release|x86.Build.0 = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|x64.ActiveCfg = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|x64.Build.0 = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|x86.ActiveCfg = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Debug|x86.Build.0 = Debug|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|Any CPU.Build.0 = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|x64.ActiveCfg = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|x64.Build.0 = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|x86.ActiveCfg = Release|Any CPU
{AD894349-DD65-422F-80D1-0ED6F0052352}.Release|x86.Build.0 = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|x64.ActiveCfg = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|x64.Build.0 = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|x86.ActiveCfg = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Debug|x86.Build.0 = Debug|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|Any CPU.Build.0 = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|x64.ActiveCfg = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|x64.Build.0 = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|x86.ActiveCfg = Release|Any CPU
{3F2FB480-E609-4415-96A7-C4BE6DB13570}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
32 changes: 6 additions & 26 deletions MMDotNet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
BlenderScripts\install.py = BlenderScripts\install.py
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfInteropSample", "MMLaunch\WpfInteropSample\WpfInteropSample.csproj", "{B7751FAB-AE42-457F-8D69-51BEE5DC080A}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MMLaunch", "MMLaunch\MMLaunch.fsproj", "{5FC4A84B-A153-4927-B6AA-015C78F6D03D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MMView", "MMView\MMView.fsproj", "{404FA43F-143A-4EB1-AE53-24FC9F65A538}"
EndProject
Global
Expand All @@ -40,34 +36,18 @@ Global
{E87272E6-CE49-4D85-9E55-EAC6117D419A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E87272E6-CE49-4D85-9E55-EAC6117D419A}.Release|Any CPU.Build.0 = Release|Any CPU
{E87272E6-CE49-4D85-9E55-EAC6117D419A}.Release|x86.ActiveCfg = Release|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|x86.ActiveCfg = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|Any CPU.Build.0 = Release|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|x86.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|x86.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|x86.ActiveCfg = Release|Any CPU
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Debug|x86.ActiveCfg = Debug|x86
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Debug|x86.Build.0 = Debug|x86
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Release|Any CPU.Build.0 = Release|Any CPU
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Release|x86.ActiveCfg = Release|x86
{B7751FAB-AE42-457F-8D69-51BEE5DC080A}.Release|x86.Build.0 = Release|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Debug|Any CPU.ActiveCfg = Debug|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Debug|Any CPU.Build.0 = Debug|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Debug|x86.ActiveCfg = Debug|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Debug|x86.Build.0 = Debug|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Release|Any CPU.ActiveCfg = Release|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Release|Any CPU.Build.0 = Release|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Release|x86.ActiveCfg = Release|x86
{5FC4A84B-A153-4927-B6AA-015C78F6D03D}.Release|x86.Build.0 = Release|x86
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Debug|x86.ActiveCfg = Debug|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|Any CPU.Build.0 = Release|Any CPU
{0AAB4CB7-549E-46CF-A3B6-E853C5E381C8}.Release|x86.ActiveCfg = Release|Any CPU
{404FA43F-143A-4EB1-AE53-24FC9F65A538}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{404FA43F-143A-4EB1-AE53-24FC9F65A538}.Debug|Any CPU.Build.0 = Debug|Any CPU
{404FA43F-143A-4EB1-AE53-24FC9F65A538}.Debug|x86.ActiveCfg = Debug|x86
Expand Down
8 changes: 8 additions & 0 deletions MMLaunch/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MMLaunch.App"
RequestedThemeVariant="Default">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
19 changes: 19 additions & 0 deletions MMLaunch/App.axaml.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace MMLaunch

open Avalonia
open Avalonia.Controls.ApplicationLifetimes
open Avalonia.Markup.Xaml

type App() =
inherit Application()

override this.Initialize() =
AvaloniaXamlLoader.Load(this)

override this.OnFrameworkInitializationCompleted() =
match this.ApplicationLifetime with
| :? IClassicDesktopStyleApplicationLifetime as desktop ->
desktop.MainWindow <- MainWindow()
| _ -> ()

base.OnFrameworkInitializationCompleted()
14 changes: 0 additions & 14 deletions MMLaunch/App.config

This file was deleted.

11 changes: 0 additions & 11 deletions MMLaunch/App.fs

This file was deleted.

10 changes: 0 additions & 10 deletions MMLaunch/App.xaml

This file was deleted.

14 changes: 0 additions & 14 deletions MMLaunch/AssemblyInfo.fs

This file was deleted.

11 changes: 8 additions & 3 deletions MMLaunch/BlenderUtil.fs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module BlenderUtil =
if key = null then failwith "can't open reg key"

let bKey = key.OpenSubKey SubKey
if bKey = null then failwith "can't open blender key"
if bKey = null then failwith "can't open blender registry key"

let v = bKey.GetValue(name,defVal)
if v = null then failwith "name not found"
Expand Down Expand Up @@ -163,9 +163,14 @@ module BlenderUtil =
let rawMsg = sprintf "\n\nTried to run: %s\n\nStdout:\n%s\n\nStderr:\n%s" cmd rawOut "<unknown>"
failwithf "No addon paths detected; install script may not be compatible with this version of blender:%s" rawMsg

let isWritable (p:string) =
let isWritable (p:string) =
// Try to write a probe file. Directory.GetAccessControl from
// .NET Framework no longer ships in core; this is a portable
// equivalent.
try
Directory.GetAccessControl(p) |> ignore
let probe = Path.Combine(p, ".mmlaunch_probe_" + System.Guid.NewGuid().ToString("N"))
File.WriteAllText(probe, "")
File.Delete(probe)
true
with
| _ -> false
Expand Down
25 changes: 25 additions & 0 deletions MMLaunch/BlenderWindow.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MMLaunch"
x:Class="MMLaunch.BlenderWindow"
x:DataType="vm:BlenderViewModel"
Title="Blender Setup"
Width="601" Height="273"
CanResize="False">
<Grid Margin="10">
<StackPanel Spacing="6">
<TextBlock Text="Blender Path:" />
<TextBlock Text="{Binding SelectedBlender}" />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Browse" Command="{Binding Browse}" Width="75" />
<Button Content="Detect" Command="{Binding Detect}" Width="75" />
</StackPanel>
<TextBlock Text="Script Status:" Margin="0,16,0,0" />
<TextBlock Text="{Binding ScriptStatus}" />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Check" Command="{Binding Check}" Width="75" />
<Button Content="Install" Command="{Binding Install}" Width="75" />
</StackPanel>
</StackPanel>
</Grid>
</Window>
123 changes: 123 additions & 0 deletions MMLaunch/BlenderWindow.axaml.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
namespace MMLaunch

open System
open System.IO

open Avalonia.Controls
open Avalonia.Markup.Xaml

open ModelMod

type BlenderViewModel() as x =
inherit ViewModelBase()

let mutable detectedBlender = None
let mutable selectedBlender = None
let mutable scriptStatus = ""

let detectBlender () =
match BlenderUtil.detectInstallPath () with
| None -> None
| Some path ->
let exe = Path.Combine(path, BlenderUtil.BlenderExe)
if File.Exists exe then Some exe else None

let getScriptStatus (scriptdir: string option) =
let lastScriptDir =
defaultArg scriptdir (RegConfig.getGlobalValue RegKeys.LastScriptInstallDir "" :?> string)

match lastScriptDir with
| "" -> "Unknown: likely not installed, or was installed manually."
| s when not (Directory.Exists s) -> "Unknown"
| s ->
match BlenderUtil.checkScriptStatus s with
| Err msg -> sprintf "Failed to check status: %s" msg
| Ok BlenderUtil.NotFound -> "Not installed"
| Ok BlenderUtil.UpToDate -> "Up to date"
| Ok BlenderUtil.Diverged -> "Out of date or modified locally"

do
detectedBlender <- detectBlender ()
let lastBlender = RegConfig.getGlobalValue RegKeys.LastSelectedBlender "" :?> string

selectedBlender <-
match lastBlender with
| "" -> detectedBlender
| s when not (File.Exists s) -> detectedBlender
| s -> Some s

scriptStatus <- getScriptStatus None

member _.SelectedBlender
with get () =
match selectedBlender with
| None -> "Not found"
| Some s -> s
and set (value: string) =
if File.Exists value then
RegConfig.setGlobalValue RegKeys.LastSelectedBlender value |> ignore
selectedBlender <- Some value
x.RaisePropertyChanged "SelectedBlender"

member _.ScriptStatus
with get () = scriptStatus
and set value =
scriptStatus <- value
x.RaisePropertyChanged "ScriptStatus"

member _.Detect =
new RelayCommand((fun _ -> true), (fun _ ->
match detectBlender () with
| None -> ViewModelUtil.pushDialog "Blender not found; try using Browse to find it manually"
| Some s ->
match ViewModelUtil.pushOkCancelDialog (sprintf "Found blender:\n%s\nUse this?" s) with
| DialogResult.Yes -> x.SelectedBlender <- s
| _ -> ()))

member _.Browse =
new RelayCommand((fun _ -> true), (fun _ ->
let idir =
match selectedBlender with
| None -> Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
| Some exe -> Path.GetDirectoryName exe

match ViewModelUtil.pushSelectFileDialog (Some idir, "Executable files|*.exe") with
| None -> ()
| Some exe ->
if File.Exists exe then x.SelectedBlender <- exe))

member _.Check =
new RelayCommand((fun _ -> true), (fun _ ->
match selectedBlender with
| None -> ViewModelUtil.pushDialog "Please select a version of blender to use first."
| Some exe ->
match BlenderUtil.getAddonsPath exe with
| Err e -> ViewModelUtil.pushDialog (sprintf "Failed to get addons path: %s" e)
| Ok path ->
let path = Path.Combine(path, BlenderUtil.ModName)
if Directory.Exists path then
RegConfig.setGlobalValue RegKeys.LastScriptInstallDir path |> ignore
x.ScriptStatus <- getScriptStatus (Some path)))

member _.Install =
new RelayCommand((fun _ -> true), (fun _ ->
match selectedBlender with
| None -> ViewModelUtil.pushDialog "Please select a version of blender to use first."
| Some exe ->
match ViewModelUtil.pushOkCancelDialog
"This will install or update the MMObj blender scripts. If you have modified the files locally, your changes will be overwritten. Proceed?" with
| DialogResult.Yes ->
match BlenderUtil.installMMScripts exe with
| Ok dir ->
RegConfig.setGlobalValue RegKeys.LastScriptInstallDir dir |> ignore
ViewModelUtil.pushDialog (sprintf "Blender scripts installed and registered in '%s'" dir)
x.ScriptStatus <- getScriptStatus None
| Err s -> ViewModelUtil.pushDialog s
| _ -> ()))

type BlenderWindow() as this =
inherit Window()

do
AvaloniaXamlLoader.Load(this)
this.DataContext <- BlenderViewModel()
Loading
Loading