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
2 changes: 1 addition & 1 deletion MSURandomizer/MSURandomizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<Version>3.0.0-rc.3</Version>
<Version>3.0.0-rc.3a</Version>
<ApplicationIcon>MSURandomizerIcon.ico</ApplicationIcon>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>MattEqualsCoder.MSURandomizer.Avalonia</PackageId>
Expand Down
4 changes: 2 additions & 2 deletions MSURandomizer/Services/AppInitializationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void Initialize(string[] args)
msuRandomizerInitializationService.Initialize(new MsuRandomizerInitializationRequest()
{
InitializeAppSettings = true,
InitializeMsuTypes = false,
InitializeMsuTypes = true,
InitializeCache = false,
InitializeUserOptions = true,
LookupMsus = false,
Expand Down Expand Up @@ -78,7 +78,7 @@ public void FinishInitialization()
InitializeAppSettings = false,
InitializeMsuTypes = true,
InitializeCache = true,
InitializeUserOptions = true,
InitializeUserOptions = false,
LookupMsus = true
});
msuGameService.InstallLuaScripts();
Expand Down
16 changes: 12 additions & 4 deletions MSURandomizer/Services/MsuDetailsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,18 @@ public MsuDetailsWindowViewModel InitilizeModel(MsuViewModel model)
mapper.Map(_parentModel.Msu.Settings, Model);
_originalMsuTypeName = Model.MsuTypeName;
Model.Msu = _parentModel.Msu;
Model.Tracks =
_parentModel.Msu.MsuType?.Tracks.OrderBy(x => x.Number)
.Select(t => new MsuTrackViewModel(t, _parentModel.Msu.Tracks)).ToList() ??
[];

if (_parentModel.Msu.MsuType != null)
{
Model.Tracks = _parentModel.Msu.MsuType.Tracks.OrderBy(x => x.Number)
.Select(t => new MsuTrackViewModel(t, _parentModel.Msu.Tracks)).ToList();
}
else
{
Model.Tracks = _parentModel.Msu.Tracks.OrderBy(x => x.Number)
.Select(t => new MsuTrackViewModel(t, _parentModel.Msu.Tracks)).ToList();
}

Model.TrackCount = Model.Tracks.Count;
Model.MsuTypeNames = [""];
Model.MsuTypeNames.AddRange(msuTypeService.MsuTypes.Select(x => x.DisplayName).OrderBy(x => x));
Expand Down
27 changes: 1 addition & 26 deletions MSURandomizer/Services/MsuListService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ public void FilterMSUs(MsuType msuType, MsuFilter msuFilter)
{
Model.MsuTypeName = msuType.DisplayName;
Model.MsuType = msuType;
var msuTypePath = Model.HardwareMode ? "" :
userOptions.MsuUserOptions.MsuTypePaths.TryGetValue(msuType, out var path) ? path :
userOptions.MsuUserOptions.DefaultMsuPath;
var rootPath = Model.HardwareMode ? "" : GetMsuTypeBasePath(msuType);
var useAbsolutePath = string.IsNullOrWhiteSpace(rootPath);

// Hardware MSUs are more limited in compatibility
List<string>? compatibleMsuNames = null;
Expand All @@ -94,15 +89,10 @@ public void FilterMSUs(MsuType msuType, MsuFilter msuFilter)
}

var filteredMsus = Model.MsuViewModels
.Where(x => x.Msu.MatchesFilter(msuFilter, msuType, msuTypePath, compatibleMsuNames) &&
.Where(x => x.Msu.MatchesFilter(msuFilter, msuType, compatibleMsuNames) &&
(x.Msu.NumUniqueTracks > x.Msu.MsuType?.RequiredTrackNumbers.Count / 5 || x.Msu.NumUniqueTracks > 10))
.OrderBy(x => x.MsuName)
.ToList();
foreach (var filteredMsu in filteredMsus)
{
filteredMsu.DisplayPath = useAbsolutePath ? filteredMsu.MsuPath : Path.GetRelativePath(rootPath!, filteredMsu.MsuPath);
}

Model.FilteredMsus = filteredMsus;
Model.SelectedMsus = Model.FilteredMsus
.Where(x => Model.SelectedMsus.Select(vm => vm.MsuPath).Contains(x.MsuPath)).ToList();
Expand Down Expand Up @@ -189,19 +179,4 @@ public void PopulateMsuViewModels(List<Msu>? msus)
OnDisplayUnknownMsuWindowRequest?.Invoke(this, EventArgs.Empty);
}
}

private string? GetMsuTypeBasePath(MsuType? msuType)
{
if (msuType == null)
{
return userOptions.MsuUserOptions.DefaultMsuPath;
}

if (userOptions.MsuUserOptions.MsuTypeNamePaths.TryGetValue(msuType.DisplayName, out string? path))
{
return path;
}

return userOptions.MsuUserOptions.DefaultMsuPath;
}
}
65 changes: 37 additions & 28 deletions MSURandomizer/Services/SettingsWindowService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Collections.ObjectModel;
using System.Linq;
using AutoMapper;
using AvaloniaControls.Controls;
Expand All @@ -16,23 +16,23 @@ public class SettingsWindowService(
IMsuUserOptionsService userOptionsService,
IMsuTypeService msuTypeService,
IMsuLookupService msuLookupService,
IMsuCacheService msuCacheService,
IMapper mapper) : ControlService
{
private readonly SettingsWindowViewModel _model = new();
private Dictionary<string, MsuType> _msuTypes = [];
private List<string> _msuTypeList = [];

public SettingsWindowViewModel InitializeModel()
{
mapper.Map(userOptionsService.MsuUserOptions, _model);
_model.DefaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
foreach (var msuType in msuTypeService.MsuTypes.OrderBy(x => x.DisplayName))
{
_model.MsuTypeNamePathsList.Add(new MsuTypePath()
{
MsuType = msuType,
Path = _model.MsuTypeNamePaths.GetValueOrDefault(msuType.DisplayName, ""),
DefaultDirectory = _model.DefaultDirectory
});
}
_msuTypes = msuTypeService.MsuTypes.OrderBy(x => x.DisplayName).ToDictionary(x => x.DisplayName, x => x);
_msuTypeList = _msuTypes.Keys.ToList();
_model.MsuDirectoryList = new ObservableCollection<MsuDirectory>(
userOptionsService.MsuUserOptions.MsuDirectories.Select(x =>
new MsuDirectory(x.Key, x.Value, _msuTypeList)));
_model.DisplayNoMsuDirectoriesMessage = _model.MsuDirectoryList.Count == 0;
return _model;
}

Expand All @@ -41,41 +41,50 @@ public void SaveModel()
var options = userOptionsService.MsuUserOptions;
var hasPathUpdated = HasPathUpdated(options);
mapper.Map(_model, options);
options.MsuTypePaths = _model.MsuTypeNamePathsList
.Where(x => !string.IsNullOrWhiteSpace(x.Path) && Directory.Exists(x.Path) && x.MsuType != null)
.ToDictionary(x => x.MsuType!, x => x.Path);
options.MsuTypeNamePaths = _model.MsuTypeNamePathsList
.Where(x => !string.IsNullOrWhiteSpace(x.Path) && Directory.Exists(x.Path) && x.MsuType != null)
.ToDictionary(x => x.MsuType!.DisplayName, x => x.Path);
options.MsuDirectories = _model.MsuDirectoryList.ToDictionary(x => x.Path, x => x.MsuTypeName);
userOptionsService.Save();
ScalableWindow.GlobalScaleFactor = options.UiScaling;

if (hasPathUpdated)
{
ITaskService.Run(() =>
{
msuCacheService.Clear(false);
msuLookupService.LookupMsus();
});
}
}

private bool HasPathUpdated(MsuUserOptions options)
public bool AddDirectory(string directory)
{
if (_model.DefaultMsuPath != options.DefaultMsuPath)
if (_model.MsuDirectoryList.Any(x => x.Path == directory))
{
return true;
return false;
}

foreach (var msuPath in _model.MsuTypeNamePathsList.Where(x => x.MsuType != null))
_model.MsuDirectoryList.Add(new MsuDirectory(directory, _msuTypeList.FirstOrDefault() ?? "", _msuTypeList));
_model.DisplayNoMsuDirectoriesMessage = false;
return true;
}

public void RemoveDirectory(string directory)
{
var directoryToRemove = _model.MsuDirectoryList.FirstOrDefault(x => x.Path == directory);
if (directoryToRemove != null)
{
var newPath = msuPath.Path.Trim();
var oldPath = options.MsuTypePaths.GetValueOrDefault(msuPath.MsuType!, "").Trim();
if (newPath != oldPath)
{
return true;
}
_model.MsuDirectoryList.Remove(directoryToRemove);
_model.DisplayNoMsuDirectoriesMessage = _model.MsuDirectoryList.Count == 0;
}
}

private bool HasPathUpdated(MsuUserOptions options)
{
if (_model.MsuDirectoryList.Count != options.MsuDirectories.Count)
{
return true;
}

return false;
var currentDirectories = options.MsuDirectories.Select(x => $"{x.Key}={x.Value}");
var newDirectories = _model.MsuDirectoryList.Select(x => $"{x.Path}={x.MsuTypeName}");
return !currentDirectories.SequenceEqual(newDirectories);
}
}
9 changes: 9 additions & 0 deletions MSURandomizer/ViewModels/MsuTrackViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ public MsuTrackViewModel(MsuTypeTrack msuTypeTrack, ICollection<Track> songs)
.Select(x => new MsuSongViewModel(x)).ToList();
Display = Songs.Count != 0;
}

public MsuTrackViewModel(Track msuTrack, ICollection<Track> songs)
{
TrackNumber = msuTrack.Number;
TrackName = msuTrack.TrackName;
Songs = songs.Where(x => x.Number == msuTrack.Number && !x.IsCopied).OrderBy(x => x.IsAlt)
.Select(x => new MsuSongViewModel(x)).ToList();
Display = Songs.Count != 0;
}

public string TrackDisplay => $"{TrackNumber} - {TrackName}";

Expand Down
3 changes: 2 additions & 1 deletion MSURandomizer/ViewModels/MsuViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public MsuViewModel(Msu msu)
Msu = msu;
MsuName = msu.DisplayName;
MsuCreator = msu.DisplayCreator;
MsuPath = DisplayPath = msu.Path;
MsuPath = msu.Path;
DisplayPath = msu.RelativePath;
MsuTypeName = msu.MsuType?.DisplayName ?? msu.MsuTypeName;
MsuTrackCount = $"{msu.ValidTracks.Count} Tracks";
IsFavorite = msu.Settings.IsFavorite;
Expand Down
20 changes: 20 additions & 0 deletions MSURandomizer/ViewModels/SettingsWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using AvaloniaControls;
using AvaloniaControls.Models;
using MSURandomizerLibrary;
Expand Down Expand Up @@ -36,6 +37,10 @@ public class SettingsWindowViewModel : ViewModelBase

public bool LaunchArgumentsEnabled => !string.IsNullOrEmpty(LaunchApplication);

[Reactive] public bool DisplayNoMsuDirectoriesMessage { get; set; }

public ObservableCollection<MsuDirectory> MsuDirectoryList { get; set; } = [];

[Reactive] public string? LaunchArguments { get; set; }

[Reactive]
Expand All @@ -61,6 +66,21 @@ public class MsuTypePath : ViewModelBase
public string MsuTypeName => MsuType?.DisplayName ?? "A Link to the Past";
}

public class MsuDirectory : ViewModelBase
{
public MsuDirectory(string path, string msuTypeName = "", List<string>? msuTypes = null)
{
Path = path;
MsuTypeName = msuTypeName;
MsuTypes = msuTypes ?? [];
}

[Reactive] public string Path { get; set; }
[Reactive] public string MsuTypeName { get; set; }
[Reactive] public List<string> MsuTypes { get; set; }
public string AbbreviatedPath => Path.Length > 40 ? string.Concat("...", Path.AsSpan(Path.Length - 38)) : Path;
}

[MapsTo(typeof(SnesConnectorSettings))]
public class SnesConnectorSettingsViewModel : ViewModelBase
{
Expand Down
49 changes: 26 additions & 23 deletions MSURandomizer/Views/SettingsWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
xmlns:controls="clr-namespace:AvaloniaControls.Controls;assembly=AvaloniaControls"
xmlns:tools="clr-namespace:AvaloniaControls.Converters;assembly=AvaloniaControls"
xmlns:viewModels="clr-namespace:MSURandomizer.ViewModels"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d"
d:DesignWidth="800" d:DesignHeight="450"
Width="800" Height="500"
Expand All @@ -23,6 +24,31 @@
</controls:HeaderFooter>
<ScrollViewer>
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True" Margin="10">
<controls:CardControl HeaderText="MSU Directories" Padding="6" Margin="0 0 0 6">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" IsVisible="{Binding DisplayNoMsuDirectoriesMessage}">
<avalonia:MaterialIcon Kind="Error" Height="20" Width="20" Margin="0 0 5 0" Foreground="IndianRed"></avalonia:MaterialIcon>
<TextBlock FontSize="16" Margin="0 3 0 5" VerticalAlignment="Bottom">
At least one MSU directory must be added.
</TextBlock>
</StackPanel>
<ItemsControl ItemsSource="{Binding MsuDirectoryList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:LabeledControl Text="{Binding AbbreviatedPath}" Margin="3" ToolTip.Tip="{Binding Path}">
<Grid ColumnDefinitions="*, Auto">
<ComboBox Grid.Column="0" ItemsSource="{Binding MsuTypes}" SelectedItem="{Binding MsuTypeName}"></ComboBox>
<Button Grid.Column="1" Margin="3 0 0 0" Tag="{Binding Path}" Click="RemoveDirectoryButton_OnClick">
<avalonia:MaterialIcon Kind="Close" Width="15" Height="15" Background="Transparent"/>
</Button>
</Grid>
</controls:LabeledControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Click="AddDirectoryButton_OnClick">Add Directory</Button>
</StackPanel>
</controls:CardControl>
<controls:CardControl HeaderText="Basic Settings" Padding="6">
<StackPanel Orientation="Vertical">
<controls:LabeledControl Text="Check for Updates" Hint="Shows a popup when first launching when there is a new update on GitHub." DisplayHint="True" Margin="3">
Expand All @@ -34,14 +60,6 @@
></ComboBox>
</controls:LabeledControl>

<controls:LabeledControl Text="Default MSU Directory" Hint="The default directory to look for MSUs if a specific folder isn't set for an MSU type." DisplayHint="True" Margin="3">
<controls:FileControl
FilePath="{Binding DefaultMsuPath, Mode=TwoWay}"
DefaultPath="{Binding DefaultDirectory}"
FileInputType="Folder"
></controls:FileControl>
</controls:LabeledControl>

<controls:LabeledControl Text="Track Display Format" Hint="How currently played tracks will be displayed." DisplayHint="True" Margin="3">
<StackPanel Orientation="Vertical">
<controls:EnumComboBox
Expand Down Expand Up @@ -112,21 +130,6 @@
</StackPanel>
</controls:CardControl>

<controls:CardControl HeaderText="Individual Game Directories" Margin="0 6 0 0" Padding="6">
<ItemsControl ItemsSource="{Binding MsuTypeNamePathsList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:LabeledControl Text="{Binding MsuTypeName}" Margin="3">
<controls:FileControl
FileInputType="Folder"
DefaultPath="{Binding DefaultDirectory}"
FilePath="{Binding Path, Mode=TwoWay}"
></controls:FileControl>
</controls:LabeledControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</controls:CardControl>
</StackPanel>
</ScrollViewer>
</DockPanel>
Expand Down
Loading