diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b983c9cb5..fbf15e1f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,9 +12,8 @@ jobs: strategy: matrix: platform: [ - {netversion: 6.x, targetframework: net6.0, aot: false, singleFile: true, aotString: ""}, - {netversion: 8.x, targetframework: net8.0, aot: false, singleFile: true, aotString: ""}, - {netversion: 8.x, targetframework: net8.0, aot: true, singleFile: false, aotString: " - AoT"} + {netversion: 10.x, targetframework: net10.0, aot: false, singleFile: true, aotString: ""}, + {netversion: 10.x, targetframework: net10.0, aot: true, singleFile: false, aotString: " - AoT"} ] fail-fast: false runs-on: windows-2025-vs2026 @@ -84,7 +83,7 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.x + dotnet-version: 10.x - name: Install dependencies run: | @@ -130,7 +129,7 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.x + dotnet-version: 10.x - name: Install dependencies run: | @@ -181,7 +180,7 @@ jobs: - name: Install .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.x + dotnet-version: 10.x - name: Install dependencies run: | diff --git a/.github/workflows/dotnet-format-check.yml b/.github/workflows/dotnet-format-check.yml index 1235609c1..03e0e98cb 100644 --- a/.github/workflows/dotnet-format-check.yml +++ b/.github/workflows/dotnet-format-check.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.0.x + dotnet-version: 10.0.x - name: Restore dependencies run: dotnet restore - name: Format diff --git a/COMPILING.md b/COMPILING.md index ec0a4b41a..58754f46e 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -1,6 +1,6 @@ ## Windows -1) Open the solution in Visual Studio 2022 +1) Open the solution in Visual Studio (2022 or 2026) 2) Compile as `Release`/`x64` 3) Set the startup project to the `UI` project and run @@ -8,15 +8,15 @@ To build under Linux you need a version of Clang or GCC that supports C++17. -Additionally, SDL2 and the [.NET 8 SDK](https://learn.microsoft.com/en-us/dotnet/core/install/linux) must also be installed. +Additionally, SDL2 and the [.NET 10 SDK](https://learn.microsoft.com/en-us/dotnet/core/install/linux) must also be installed. -Once SDL2 and the .NET 8 SDK are installed, run `make` to compile with Clang. +Once SDL2 and the .NET 10 SDK are installed, run `make` to compile with Clang. To compile with GCC instead, use `USE_GCC=true make`. **Note:** Mesen usually runs faster when built with Clang instead of GCC. ## macOS -To build macOS, install SDL2 (i.e via Homebrew) and the [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0). +To build macOS, install SDL2 (i.e via Homebrew) and the [.NET 10 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/10.0). -Once SDL2 and the .NET 8 SDK are installed, run `make`. \ No newline at end of file +Once SDL2 and the .NET 10 SDK are installed, run `make`. \ No newline at end of file diff --git a/Linux/appimage/appimage-arm64.sh b/Linux/appimage/appimage-arm64.sh index 6046980de..f9eb12a46 100755 --- a/Linux/appimage/appimage-arm64.sh +++ b/Linux/appimage/appimage-arm64.sh @@ -1,6 +1,6 @@ #!/bin/bash -export PUBLISHFLAGS="-r linux-arm64 --no-self-contained false -p:PublishSingleFile=true -p:PublishReadyToRun=true" +export PUBLISHFLAGS="-r linux-arm64 -p:PublishSingleFile=true -p:PublishReadyToRun=true" make -j$(nproc) -O LTO=true STATICLINK=true SYSTEM_LIBEVDEV=false curl -SL https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-aarch64.AppImage -o appimagetool diff --git a/Linux/appimage/appimage.sh b/Linux/appimage/appimage.sh index a98979e4f..afec510e6 100755 --- a/Linux/appimage/appimage.sh +++ b/Linux/appimage/appimage.sh @@ -1,6 +1,6 @@ #!/bin/bash -export PUBLISHFLAGS="-r linux-x64 --no-self-contained false -p:PublishSingleFile=true -p:PublishReadyToRun=true" +export PUBLISHFLAGS="-r linux-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=true" make -j$(nproc) -O LTO=true STATICLINK=true SYSTEM_LIBEVDEV=false curl -SL https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -o appimagetool diff --git a/README.md b/README.md index 802834bfd..3e5c78315 100644 --- a/README.md +++ b/README.md @@ -12,27 +12,20 @@ We are currently just doing development builds. When we launch stable releases, [![Mesen](https://github.com/nesdev-org/MesenCE/actions/workflows/build.yml/badge.svg)](https://github.com/nesdev-org/MesenCE/actions/workflows/build.yml) -#### Native builds (recommended) #### +#### Recommended -These builds don't require .NET to be installed. They load more quickly and are recommended over the .NET builds. - -* [Windows 10 / 11](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Windows%20-%20net8.0%20-%20AoT%29.zip) +* [Windows 10 / 11](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Windows%20-%20net10.0%20-%20AoT%29.zip) * [Linux x64](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Linux%20-%20ubuntu-22.04%20-%20clang_aot%29.zip) (requires **SDL2**) * [Linux ARM64](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Linux%20-%20ubuntu-22.04-arm%20-%20clang_aot%29.zip) (requires **SDL2**) * [macOS - Intel](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28macOS%20-%20macos-15-intel%20-%20clang_aot%29.zip) (requires **SDL2**) * [macOS - Apple Silicon](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28macOS%20-%20macos-15%20-%20clang_aot%29.zip) (requires **SDL2**) -#### .NET builds #### - -These builds use .NET, which for some builds comes bundled and for others must be installed. -They all require **.NET 8** except the Windows 7 / 8 build, which requires **.NET 6**. -For Linux and macOS, **SDL2** must also be installed. For AppImage builds, **FUSE** (such as libfuse2) must be installed. +#### AppImages (Linux) -* [Windows 7 / 8](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Windows%20-%20net6.0%29.zip) (requires **.NET 6**) -* [Linux x64 - AppImage](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20(Linux%20x64%20-%20AppImage).zip) (requires **FUSE** and **SDL2**) -* [Linux ARM64](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20%28Linux%20-%20ubuntu-22.04-arm%20-%20clang%29.zip) (requires **.NET 8** and **SDL2**) -* [Linux ARM64 - AppImage](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20(Linux%20ARM64%20-%20AppImage).zip) (requires **FUSE** and **SDL2**) +For AppImage builds, **FUSE** (such as libfuse2) and **SDL2** must be installed. +* [Linux x64 (AppImage)](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20(Linux%20x64%20-%20AppImage).zip) +* [Linux ARM64 (AppImage)](https://nightly.link/nesdev-org/MesenCE/workflows/build/master/Mesen%20(Linux%20ARM64%20-%20AppImage).zip) #### Notes #### @@ -53,7 +46,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) Mesen is available under the GPL V3 license. Full text here: -Copyright (C) 2014-2025 Sour, 2026 contributors +Copyright (C) 2014-2026 Sour, 2026 contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/UI/.filenesting.json b/UI/.filenesting.json new file mode 100644 index 000000000..a35a825fb --- /dev/null +++ b/UI/.filenesting.json @@ -0,0 +1,19 @@ +{ + "help": "https://go.microsoft.com/fwlink/?linkid=866610", + "root": true, + + "dependentFileProviders": { + "add": { + "extensionToExtension": { + "add": { + ".cs": [ + ".axaml.cs" + ], + ".designer.cs": [ + ".resx" + ] + } + } + } + } +} diff --git a/UI/App.axaml b/UI/App.axaml index 8e02f3e93..deecfcc36 100644 --- a/UI/App.axaml +++ b/UI/App.axaml @@ -32,6 +32,7 @@ + diff --git a/UI/App.axaml.cs b/UI/App.axaml.cs index 10dcb4829..26a5fc091 100644 --- a/UI/App.axaml.cs +++ b/UI/App.axaml.cs @@ -34,6 +34,9 @@ public override void Initialize() e.Handled = true; }; +#if DEBUG + this.AttachDeveloperTools(); +#endif AvaloniaXamlLoader.Load(this); ResourceHelper.LoadResources(); } diff --git a/UI/Config/AudioConfig.cs b/UI/Config/AudioConfig.cs index 63aaa27e6..9f18cf3cd 100644 --- a/UI/Config/AudioConfig.cs +++ b/UI/Config/AudioConfig.cs @@ -1,6 +1,5 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using System; using System.Collections.Generic; using System.Linq; @@ -10,54 +9,54 @@ namespace Mesen.Config { - public class AudioConfig : BaseConfig + public partial class AudioConfig : BaseConfig { - [Reactive] public string AudioDevice { get; set; } = ""; - [Reactive] public bool EnableAudio { get; set; } = true; - [Reactive] public bool DisableDynamicSampleRate { get; set; } = false; - - [Reactive][MinMax(0, 100)] public UInt32 MasterVolume { get; set; } = 100; - [Reactive] public AudioSampleRate SampleRate { get; set; } = AudioSampleRate._48000; - [Reactive][MinMax(15, 300)] public UInt32 AudioLatency { get; set; } = 60; - - [Reactive] public bool MuteSoundInBackground { get; set; } = false; - [Reactive] public bool ReduceSoundInBackground { get; set; } = true; - [Reactive] public bool ReduceSoundInFastForward { get; set; } = false; - [Reactive][MinMax(0, 100)] public int VolumeReduction { get; set; } = 75; - - [Reactive] public bool ReverbEnabled { get; set; } = false; - [Reactive][MinMax(1, 10)] public UInt32 ReverbStrength { get; set; } = 5; - [Reactive][MinMax(1, 30)] public UInt32 ReverbDelay { get; set; } = 10; - - [Reactive] public bool CrossFeedEnabled { get; set; } = false; - [Reactive][MinMax(0, 100)] public UInt32 CrossFeedRatio { get; set; } = 0; - - [Reactive] public bool EnableEqualizer { get; set; } = false; - [Reactive][MinMax(-20.0, 20.0)] public double Band1Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band2Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band3Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band4Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band5Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band6Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band7Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band8Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band9Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band10Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band11Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band12Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band13Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band14Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band15Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band16Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band17Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band18Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band19Gain { get; set; } = 0; - [Reactive][MinMax(-20.0, 20.0)] public double Band20Gain { get; set; } = 0; - - [Reactive] public bool AudioPlayerEnableTrackLength { get; set; } = true; - [Reactive][MinMax(0, 9999)] public UInt32 AudioPlayerTrackLength { get; set; } = 120; - [Reactive] public bool AudioPlayerAutoDetectSilence { get; set; } = true; - [Reactive][MinMax(0, 999999)] public UInt32 AudioPlayerSilenceDelay { get; set; } = 3; + [ObservableProperty] public partial string AudioDevice { get; set; } = ""; + [ObservableProperty] public partial bool EnableAudio { get; set; } = true; + [ObservableProperty] public partial bool DisableDynamicSampleRate { get; set; } = false; + + [ObservableProperty][MinMax(0, 100)] public partial UInt32 MasterVolume { get; set; } = 100; + [ObservableProperty] public partial AudioSampleRate SampleRate { get; set; } = AudioSampleRate._48000; + [ObservableProperty][MinMax(15, 300)] public partial UInt32 AudioLatency { get; set; } = 60; + + [ObservableProperty] public partial bool MuteSoundInBackground { get; set; } = false; + [ObservableProperty] public partial bool ReduceSoundInBackground { get; set; } = true; + [ObservableProperty] public partial bool ReduceSoundInFastForward { get; set; } = false; + [ObservableProperty][MinMax(0, 100)] public partial int VolumeReduction { get; set; } = 75; + + [ObservableProperty] public partial bool ReverbEnabled { get; set; } = false; + [ObservableProperty][MinMax(1, 10)] public partial UInt32 ReverbStrength { get; set; } = 5; + [ObservableProperty][MinMax(1, 30)] public partial UInt32 ReverbDelay { get; set; } = 10; + + [ObservableProperty] public partial bool CrossFeedEnabled { get; set; } = false; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 CrossFeedRatio { get; set; } = 0; + + [ObservableProperty] public partial bool EnableEqualizer { get; set; } = false; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band1Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band2Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band3Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band4Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band5Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band6Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band7Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band8Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band9Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band10Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band11Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band12Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band13Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band14Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band15Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band16Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band17Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band18Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band19Gain { get; set; } = 0; + [ObservableProperty][MinMax(-20.0, 20.0)] public partial double Band20Gain { get; set; } = 0; + + [ObservableProperty] public partial bool AudioPlayerEnableTrackLength { get; set; } = true; + [ObservableProperty][MinMax(0, 9999)] public partial UInt32 AudioPlayerTrackLength { get; set; } = 120; + [ObservableProperty] public partial bool AudioPlayerAutoDetectSilence { get; set; } = true; + [ObservableProperty][MinMax(0, 999999)] public partial UInt32 AudioPlayerSilenceDelay { get; set; } = 3; public void ApplyConfig() { diff --git a/UI/Config/AudioPlayerConfig.cs b/UI/Config/AudioPlayerConfig.cs index 2b79fff9e..9ca2eb527 100644 --- a/UI/Config/AudioPlayerConfig.cs +++ b/UI/Config/AudioPlayerConfig.cs @@ -1,6 +1,5 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using System; using System.Collections.Generic; using System.Linq; @@ -10,11 +9,11 @@ namespace Mesen.Config { - public class AudioPlayerConfig : BaseConfig + public partial class AudioPlayerConfig : BaseConfig { - [Reactive] public UInt32 Volume { get; set; } = 100; - [Reactive] public bool Repeat { get; set; } = false; - [Reactive] public bool Shuffle { get; set; } = false; + [ObservableProperty] public partial UInt32 Volume { get; set; } = 100; + [ObservableProperty] public partial bool Repeat { get; set; } = false; + [ObservableProperty] public partial bool Shuffle { get; set; } = false; public void ApplyConfig() { diff --git a/UI/Config/BaseConfig.cs b/UI/Config/BaseConfig.cs index 38efe7a7e..e668c392d 100644 --- a/UI/Config/BaseConfig.cs +++ b/UI/Config/BaseConfig.cs @@ -1,11 +1,11 @@ -using Mesen.Utilities; -using ReactiveUI; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Utilities; using System; using System.Text.Json; namespace Mesen.Config { - public class BaseConfig : ReactiveObject where T : class + public partial class BaseConfig : ObservableObject where T : class { public T Clone() { diff --git a/UI/Config/BaseWindowConfig.cs b/UI/Config/BaseWindowConfig.cs index a040906f7..780b39eb2 100644 --- a/UI/Config/BaseWindowConfig.cs +++ b/UI/Config/BaseWindowConfig.cs @@ -5,7 +5,7 @@ namespace Mesen.Config { - public class BaseWindowConfig : BaseConfig where T : class + public partial class BaseWindowConfig : BaseConfig where T : class { public MesenSize WindowSize { get; set; } = new PixelSize(0, 0); public MesenPoint WindowLocation { get; set; } = new PixelPoint(0, 0); @@ -30,7 +30,7 @@ public void SaveWindowSettings(Window wnd) public void LoadWindowSettings(Window wnd) { //Update _restoreBounds when size/position changes - wnd.GetPropertyChangedObservable(Window.ClientSizeProperty).Subscribe(x => UpdateRestoreBounds(wnd)); + wnd.SizeChanged += (s, e) => UpdateRestoreBounds(wnd); wnd.PositionChanged += (s, e) => UpdateRestoreBounds(wnd); if(WindowSize.Width != 0 && WindowSize.Height != 0) { diff --git a/UI/Config/CheatCodes.cs b/UI/Config/CheatCodes.cs index c54191170..c20f3f452 100644 --- a/UI/Config/CheatCodes.cs +++ b/UI/Config/CheatCodes.cs @@ -1,7 +1,7 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.IO; @@ -70,12 +70,12 @@ public static void ApplyCheats(IEnumerable cheats) } } - public class CheatCode : ViewModelBase + public partial class CheatCode : ViewModelBase { - [Reactive] public string Description { get; set; } = ""; - [Reactive] public CheatType Type { get; set; } - [Reactive] public bool Enabled { get; set; } = true; - [Reactive] public string Codes { get; set; } = ""; + [ObservableProperty] public partial string Description { get; set; } = ""; + [ObservableProperty] public partial CheatType Type { get; set; } + [ObservableProperty] public partial bool Enabled { get; set; } = true; + [ObservableProperty] public partial string Codes { get; set; } = ""; public List ToInteropCheats() { diff --git a/UI/Config/CheatWindowConfig.cs b/UI/Config/CheatWindowConfig.cs index 70ac41072..0c1a0c05e 100644 --- a/UI/Config/CheatWindowConfig.cs +++ b/UI/Config/CheatWindowConfig.cs @@ -1,5 +1,5 @@ using Avalonia; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -8,7 +8,7 @@ namespace Mesen.Config { - public class CheatWindowConfig : BaseWindowConfig + public partial class CheatWindowConfig : BaseWindowConfig { public bool DisableAllCheats { get; set; } = false; public List ColumnWidths { get; set; } = new(); diff --git a/UI/Config/ConfigManager.cs b/UI/Config/ConfigManager.cs index 44c307438..7a602954f 100644 --- a/UI/Config/ConfigManager.cs +++ b/UI/Config/ConfigManager.cs @@ -159,7 +159,9 @@ public static bool ProcessSwitch(string switchArg) object? cfg = ConfigManager.Config; PropertyInfo? property; for(int i = 0; i < switchPath.Length; i++) { +#pragma warning disable IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. property = cfg.GetType().GetProperty(switchPath[i], BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); +#pragma warning restore IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. if(property == null) { //Invalid switch name return false; diff --git a/UI/Config/Configuration.cs b/UI/Config/Configuration.cs index f8010c5e8..51084d39b 100644 --- a/UI/Config/Configuration.cs +++ b/UI/Config/Configuration.cs @@ -1,11 +1,10 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config.Shortcuts; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -16,7 +15,7 @@ namespace Mesen.Config { - public partial class Configuration : ReactiveObject + public partial class Configuration : ObservableObject { private string _fileData = ""; @@ -24,29 +23,29 @@ public partial class Configuration : ReactiveObject public int ConfigUpgrade { get; set; } = 0; public bool EnableTestMode { get; set; } = false; - [Reactive] public VideoConfig Video { get; set; } = new(); - [Reactive] public AudioConfig Audio { get; set; } = new(); - [Reactive] public InputConfig Input { get; set; } = new(); - [Reactive] public EmulationConfig Emulation { get; set; } = new(); - [Reactive] public SnesConfig Snes { get; set; } = new(); - [Reactive] public NesConfig Nes { get; set; } = new(); - [Reactive] public GameboyConfig Gameboy { get; set; } = new(); - [Reactive] public PcEngineConfig PcEngine { get; set; } = new(); - [Reactive] public SmsConfig Sms { get; set; } = new(); - [Reactive] public CvConfig Cv { get; set; } = new(); - [Reactive] public GbaConfig Gba { get; set; } = new(); - [Reactive] public WsConfig Ws { get; set; } = new(); - [Reactive] public PreferencesConfig Preferences { get; set; } = new(); - [Reactive] public AudioPlayerConfig AudioPlayer { get; set; } = new(); - [Reactive] public DebugConfig Debug { get; set; } = new(); - [Reactive] public RecentItems RecentFiles { get; set; } = new(); - [Reactive] public VideoRecordConfig VideoRecord { get; set; } = new(); - [Reactive] public MovieRecordConfig MovieRecord { get; set; } = new(); - [Reactive] public HdPackBuilderConfig HdPackBuilder { get; set; } = new(); - [Reactive] public CheatWindowConfig Cheats { get; set; } = new(); - [Reactive] public NetplayConfig Netplay { get; set; } = new(); - [Reactive] public HistoryViewerConfig HistoryViewer { get; set; } = new(); - [Reactive] public MainWindowConfig MainWindow { get; set; } = new(); + [ObservableProperty] public partial VideoConfig Video { get; set; } = new(); + [ObservableProperty] public partial AudioConfig Audio { get; set; } = new(); + [ObservableProperty] public partial InputConfig Input { get; set; } = new(); + [ObservableProperty] public partial EmulationConfig Emulation { get; set; } = new(); + [ObservableProperty] public partial SnesConfig Snes { get; set; } = new(); + [ObservableProperty] public partial NesConfig Nes { get; set; } = new(); + [ObservableProperty] public partial GameboyConfig Gameboy { get; set; } = new(); + [ObservableProperty] public partial PcEngineConfig PcEngine { get; set; } = new(); + [ObservableProperty] public partial SmsConfig Sms { get; set; } = new(); + [ObservableProperty] public partial CvConfig Cv { get; set; } = new(); + [ObservableProperty] public partial GbaConfig Gba { get; set; } = new(); + [ObservableProperty] public partial WsConfig Ws { get; set; } = new(); + [ObservableProperty] public partial PreferencesConfig Preferences { get; set; } = new(); + [ObservableProperty] public partial AudioPlayerConfig AudioPlayer { get; set; } = new(); + [ObservableProperty] public partial DebugConfig Debug { get; set; } = new(); + [ObservableProperty] public partial RecentItems RecentFiles { get; set; } = new(); + [ObservableProperty] public partial VideoRecordConfig VideoRecord { get; set; } = new(); + [ObservableProperty] public partial MovieRecordConfig MovieRecord { get; set; } = new(); + [ObservableProperty] public partial HdPackBuilderConfig HdPackBuilder { get; set; } = new(); + [ObservableProperty] public partial CheatWindowConfig Cheats { get; set; } = new(); + [ObservableProperty] public partial NetplayConfig Netplay { get; set; } = new(); + [ObservableProperty] public partial HistoryViewerConfig HistoryViewer { get; set; } = new(); + [ObservableProperty] public partial MainWindowConfig MainWindow { get; set; } = new(); public DefaultKeyMappingType DefaultKeyMappings { get; set; } = DefaultKeyMappingType.Xbox | DefaultKeyMappingType.ArrowKeys; diff --git a/UI/Config/ConsoleOverrideConfig.cs b/UI/Config/ConsoleOverrideConfig.cs index 049da6196..f360f0a92 100644 --- a/UI/Config/ConsoleOverrideConfig.cs +++ b/UI/Config/ConsoleOverrideConfig.cs @@ -1,6 +1,6 @@ using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,14 +9,14 @@ namespace Mesen.Config; -public class ConsoleOverrideConfig : BaseConfig +public partial class ConsoleOverrideConfig : BaseConfig { - [Reactive] public bool OverrideVideoFilter { get; set; } = false; - [Reactive] public VideoFilterType VideoFilter { get; set; } = VideoFilterType.None; + [ObservableProperty] public partial bool OverrideVideoFilter { get; set; } = false; + [ObservableProperty] public partial VideoFilterType VideoFilter { get; set; } = VideoFilterType.None; - [Reactive] public bool OverrideAspectRatio { get; set; } = false; - [Reactive] public VideoAspectRatio AspectRatio { get; set; } = VideoAspectRatio.NoStretching; - [Reactive][MinMax(0.1, 5.0)] public double CustomAspectRatio { get; set; } = 1.0; + [ObservableProperty] public partial bool OverrideAspectRatio { get; set; } = false; + [ObservableProperty] public partial VideoAspectRatio AspectRatio { get; set; } = VideoAspectRatio.NoStretching; + [ObservableProperty][MinMax(0.1, 5.0)] public partial double CustomAspectRatio { get; set; } = 1.0; public static ConsoleOverrideConfig? GetActiveOverride() { diff --git a/UI/Config/CvConfig.cs b/UI/Config/CvConfig.cs index 6e9ce475e..c53752e3f 100644 --- a/UI/Config/CvConfig.cs +++ b/UI/Config/CvConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,26 +9,26 @@ namespace Mesen.Config; -public class CvConfig : BaseConfig +public partial class CvConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - [Reactive] public CvControllerConfig Port1 { get; set; } = new(); - [Reactive] public CvControllerConfig Port2 { get; set; } = new(); + [ObservableProperty] public partial CvControllerConfig Port1 { get; set; } = new(); + [ObservableProperty] public partial CvControllerConfig Port2 { get; set; } = new(); [ValidValues(ConsoleRegion.Auto, ConsoleRegion.Ntsc, ConsoleRegion.Pal)] - [Reactive] public ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; + [ObservableProperty] public partial ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.AllZeros; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.AllZeros; - [Reactive] public bool RemoveSpriteLimit { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; - [Reactive] public bool DisableBackground { get; set; } = false; + [ObservableProperty] public partial bool RemoveSpriteLimit { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool DisableBackground { get; set; } = false; - [Reactive][MinMax(0, 100)] public UInt32 Tone1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Tone2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Tone3Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 NoiseVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone3Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 NoiseVol { get; set; } = 100; public void ApplyConfig() { diff --git a/UI/Config/Debugger/AssemblerConfig.cs b/UI/Config/Debugger/AssemblerConfig.cs index 1a14b4d9b..db1b9d73b 100644 --- a/UI/Config/Debugger/AssemblerConfig.cs +++ b/UI/Config/Debugger/AssemblerConfig.cs @@ -3,7 +3,7 @@ namespace Mesen.Config { - public class AssemblerConfig : BaseWindowConfig + public partial class AssemblerConfig : BaseWindowConfig { } } diff --git a/UI/Config/Debugger/DebugLogConfig.cs b/UI/Config/Debugger/DebugLogConfig.cs index 823c432c4..e761116ed 100644 --- a/UI/Config/Debugger/DebugLogConfig.cs +++ b/UI/Config/Debugger/DebugLogConfig.cs @@ -2,7 +2,7 @@ namespace Mesen.Config { - public class DebugLogConfig : BaseWindowConfig + public partial class DebugLogConfig : BaseWindowConfig { } } diff --git a/UI/Config/Debugger/DebuggerConfig.cs b/UI/Config/Debugger/DebuggerConfig.cs index 3746e6cbe..a10aaa304 100644 --- a/UI/Config/Debugger/DebuggerConfig.cs +++ b/UI/Config/Debugger/DebuggerConfig.cs @@ -1,108 +1,105 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Config { - public class DebuggerConfig : BaseWindowConfig + public partial class DebuggerConfig : BaseWindowConfig { public DockEntryDefinition? SavedDockLayout { get; set; } = null; - [Reactive] public bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; - [Reactive] public bool ShowByteCode { get; set; } = false; - [Reactive] public bool ShowMemoryValues { get; set; } = true; - [Reactive] public bool UseLowerCaseDisassembly { get; set; } = false; + [ObservableProperty] public partial bool ShowByteCode { get; set; } = false; + [ObservableProperty] public partial bool ShowMemoryValues { get; set; } = true; + [ObservableProperty] public partial bool UseLowerCaseDisassembly { get; set; } = false; - [Reactive] public bool ShowJumpLabels { get; set; } = false; - [Reactive] public AddressDisplayType AddressDisplayType { get; set; } = AddressDisplayType.CpuAddress; + [ObservableProperty] public partial bool ShowJumpLabels { get; set; } = false; + [ObservableProperty] public partial AddressDisplayType AddressDisplayType { get; set; } = AddressDisplayType.CpuAddress; - [Reactive] public bool DrawPartialFrame { get; set; } = false; + [ObservableProperty] public partial bool DrawPartialFrame { get; set; } = false; - [Reactive] public SnesDebuggerConfig Snes { get; set; } = new(); - [Reactive] public NesDebuggerConfig Nes { get; set; } = new(); - [Reactive] public GbDebuggerConfig Gameboy { get; set; } = new(); - [Reactive] public GbaDebuggerConfig Gba { get; set; } = new(); - [Reactive] public PceDebuggerConfig Pce { get; set; } = new(); - [Reactive] public SmsDebuggerConfig Sms { get; set; } = new(); - [Reactive] public WsDebuggerConfig Ws { get; set; } = new(); + [ObservableProperty] public partial SnesDebuggerConfig Snes { get; set; } = new(); + [ObservableProperty] public partial NesDebuggerConfig Nes { get; set; } = new(); + [ObservableProperty] public partial GbDebuggerConfig Gameboy { get; set; } = new(); + [ObservableProperty] public partial GbaDebuggerConfig Gba { get; set; } = new(); + [ObservableProperty] public partial PceDebuggerConfig Pce { get; set; } = new(); + [ObservableProperty] public partial SmsDebuggerConfig Sms { get; set; } = new(); + [ObservableProperty] public partial WsDebuggerConfig Ws { get; set; } = new(); - [Reactive] public bool BreakOnUninitRead { get; set; } = false; - [Reactive] public bool BreakOnOpen { get; set; } = true; - [Reactive] public bool BreakOnPowerCycleReset { get; set; } = true; + [ObservableProperty] public partial bool BreakOnUninitRead { get; set; } = false; + [ObservableProperty] public partial bool BreakOnOpen { get; set; } = true; + [ObservableProperty] public partial bool BreakOnPowerCycleReset { get; set; } = true; - [Reactive] public bool AutoResetCdl { get; set; } = true; - [Reactive] public bool DisableDefaultLabels { get; set; } = false; + [ObservableProperty] public partial bool AutoResetCdl { get; set; } = true; + [ObservableProperty] public partial bool DisableDefaultLabels { get; set; } = false; - [Reactive] public bool UsePredictiveBreakpoints { get; set; } = true; - [Reactive] public bool SingleBreakpointPerInstruction { get; set; } = true; + [ObservableProperty] public partial bool UsePredictiveBreakpoints { get; set; } = true; + [ObservableProperty] public partial bool SingleBreakpointPerInstruction { get; set; } = true; - [Reactive] public bool CopyAddresses { get; set; } = true; - [Reactive] public bool CopyByteCode { get; set; } = true; - [Reactive] public bool CopyComments { get; set; } = true; - [Reactive] public bool CopyBlockHeaders { get; set; } = true; + [ObservableProperty] public partial bool CopyAddresses { get; set; } = true; + [ObservableProperty] public partial bool CopyByteCode { get; set; } = true; + [ObservableProperty] public partial bool CopyComments { get; set; } = true; + [ObservableProperty] public partial bool CopyBlockHeaders { get; set; } = true; - [Reactive] public bool KeepActiveStatementInCenter { get; set; } = false; + [ObservableProperty] public partial bool KeepActiveStatementInCenter { get; set; } = false; - [Reactive] public bool ShowMemoryMappings { get; set; } = true; + [ObservableProperty] public partial bool ShowMemoryMappings { get; set; } = true; - [Reactive] public bool RefreshWhileRunning { get; set; } = false; + [ObservableProperty] public partial bool RefreshWhileRunning { get; set; } = false; - [Reactive] public bool BringToFrontOnBreak { get; set; } = true; - [Reactive] public bool BringToFrontOnPause { get; set; } = false; - [Reactive] public bool FocusGameOnResume { get; set; } = false; + [ObservableProperty] public partial bool BringToFrontOnBreak { get; set; } = true; + [ObservableProperty] public partial bool BringToFrontOnPause { get; set; } = false; + [ObservableProperty] public partial bool FocusGameOnResume { get; set; } = false; - [Reactive] public CodeDisplayMode UnidentifiedBlockDisplay { get; set; } = CodeDisplayMode.Hide; - [Reactive] public CodeDisplayMode VerifiedDataDisplay { get; set; } = CodeDisplayMode.Hide; + [ObservableProperty] public partial CodeDisplayMode UnidentifiedBlockDisplay { get; set; } = CodeDisplayMode.Hide; + [ObservableProperty] public partial CodeDisplayMode VerifiedDataDisplay { get; set; } = CodeDisplayMode.Hide; - [Reactive] public int BreakOnValue { get; set; } = 0; - [Reactive] public int BreakInCount { get; set; } = 1; - [Reactive] public BreakInMetric BreakInMetric { get; set; } = BreakInMetric.CpuInstructions; + [ObservableProperty] public partial int BreakOnValue { get; set; } = 0; + [ObservableProperty] public partial int BreakInCount { get; set; } = 1; + [ObservableProperty] public partial BreakInMetric BreakInMetric { get; set; } = BreakInMetric.CpuInstructions; - [Reactive] public bool ShowSelectionLength { get; set; } = false; - [Reactive] public WatchFormatStyle WatchFormat { get; set; } = WatchFormatStyle.Hex; + [ObservableProperty] public partial bool ShowSelectionLength { get; set; } = false; + [ObservableProperty] public partial WatchFormatStyle WatchFormat { get; set; } = WatchFormatStyle.Hex; - [Reactive] public UInt32 CodeOpcodeColor { get; set; } = Color.FromRgb(22, 37, 37).ToUInt32(); - [Reactive] public UInt32 CodeLabelDefinitionColor { get; set; } = Colors.Blue.ToUInt32(); - [Reactive] public UInt32 CodeImmediateColor { get; set; } = Colors.Chocolate.ToUInt32(); - [Reactive] public UInt32 CodeAddressColor { get; set; } = Colors.DarkRed.ToUInt32(); - [Reactive] public UInt32 CodeCommentColor { get; set; } = Colors.Green.ToUInt32(); - [Reactive] public UInt32 CodeEffectiveAddressColor { get; set; } = Colors.SteelBlue.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeOpcodeColor { get; set; } = Color.FromRgb(22, 37, 37).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeLabelDefinitionColor { get; set; } = Colors.Blue.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeImmediateColor { get; set; } = Colors.Chocolate.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeAddressColor { get; set; } = Colors.DarkRed.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeCommentColor { get; set; } = Colors.Green.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeEffectiveAddressColor { get; set; } = Colors.SteelBlue.ToUInt32(); - [Reactive] public UInt32 CodeVerifiedDataColor { get; set; } = Color.FromRgb(255, 252, 236).ToUInt32(); - [Reactive] public UInt32 CodeUnidentifiedDataColor { get; set; } = Color.FromRgb(255, 242, 242).ToUInt32(); - [Reactive] public UInt32 CodeUnexecutedCodeColor { get; set; } = Color.FromRgb(225, 244, 228).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeVerifiedDataColor { get; set; } = Color.FromRgb(255, 252, 236).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeUnidentifiedDataColor { get; set; } = Color.FromRgb(255, 242, 242).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeUnexecutedCodeColor { get; set; } = Color.FromRgb(225, 244, 228).ToUInt32(); - [Reactive] public UInt32 CodeExecBreakpointColor { get; set; } = Color.FromRgb(140, 40, 40).ToUInt32(); - [Reactive] public UInt32 CodeWriteBreakpointColor { get; set; } = Color.FromRgb(40, 120, 80).ToUInt32(); - [Reactive] public UInt32 CodeReadBreakpointColor { get; set; } = Color.FromRgb(40, 40, 200).ToUInt32(); - [Reactive] public UInt32 ForbidBreakpointColor { get; set; } = Color.FromRgb(115, 115, 115).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeExecBreakpointColor { get; set; } = Color.FromRgb(140, 40, 40).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeWriteBreakpointColor { get; set; } = Color.FromRgb(40, 120, 80).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeReadBreakpointColor { get; set; } = Color.FromRgb(40, 40, 200).ToUInt32(); + [ObservableProperty] public partial UInt32 ForbidBreakpointColor { get; set; } = Color.FromRgb(115, 115, 115).ToUInt32(); - [Reactive] public UInt32 CodeActiveStatementColor { get; set; } = Colors.Yellow.ToUInt32(); - [Reactive] public UInt32 CodeActiveMidInstructionColor { get; set; } = Color.FromRgb(255, 220, 40).ToUInt32(); + [ObservableProperty] public partial UInt32 CodeActiveStatementColor { get; set; } = Colors.Yellow.ToUInt32(); + [ObservableProperty] public partial UInt32 CodeActiveMidInstructionColor { get; set; } = Color.FromRgb(255, 220, 40).ToUInt32(); - [Reactive] public List LabelListColumnWidths { get; set; } = new(); - [Reactive] public List FunctionListColumnWidths { get; set; } = new(); - [Reactive] public List BreakpointListColumnWidths { get; set; } = new(); - [Reactive] public List WatchListColumnWidths { get; set; } = new(); - [Reactive] public List CallStackColumnWidths { get; set; } = new(); - [Reactive] public List FindResultColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List LabelListColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List FunctionListColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List BreakpointListColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List WatchListColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List CallStackColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List FindResultColumnWidths { get; set; } = new(); public DebuggerConfig() { } } - public class CfgColor : ReactiveObject + public partial class CfgColor : ObservableObject { - [Reactive] public UInt32 ColorCode { get; set; } + [ObservableProperty] public partial UInt32 ColorCode { get; set; } } public enum BreakInMetric diff --git a/UI/Config/Debugger/DebuggerFontConfig.cs b/UI/Config/Debugger/DebuggerFontConfig.cs index 1392c9b91..2ee7d88e7 100644 --- a/UI/Config/Debugger/DebuggerFontConfig.cs +++ b/UI/Config/Debugger/DebuggerFontConfig.cs @@ -1,17 +1,17 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; -using ReactiveUI.Fody.Helpers; namespace Mesen.Config { - public class DebuggerFontConfig : BaseConfig + public partial class DebuggerFontConfig : BaseConfig { - [Reactive] public FontConfig DisassemblyFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; - [Reactive] public FontConfig MemoryViewerFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; - [Reactive] public FontConfig AssemblerFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; - [Reactive] public FontConfig ScriptWindowFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; - [Reactive] public FontConfig OtherMonoFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 12 }; + [ObservableProperty] public partial FontConfig DisassemblyFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; + [ObservableProperty] public partial FontConfig MemoryViewerFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; + [ObservableProperty] public partial FontConfig AssemblerFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; + [ObservableProperty] public partial FontConfig ScriptWindowFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 14 }; + [ObservableProperty] public partial FontConfig OtherMonoFont { get; set; } = new() { FontFamily = "Consolas", FontSize = 12 }; public void ApplyConfig() { diff --git a/UI/Config/Debugger/DebuggerShortcutsConfig.cs b/UI/Config/Debugger/DebuggerShortcutsConfig.cs index 22b32b31f..dbe819b24 100644 --- a/UI/Config/Debugger/DebuggerShortcutsConfig.cs +++ b/UI/Config/Debugger/DebuggerShortcutsConfig.cs @@ -1,6 +1,6 @@ using Avalonia.Input; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Text.Json.Serialization; @@ -8,7 +8,7 @@ namespace Mesen.Config { - public class DebuggerShortcutsConfig : BaseConfig, IJsonOnDeserialized + public partial class DebuggerShortcutsConfig : BaseConfig, IJsonOnDeserialized { private List _shortcuts = new(); private Dictionary _lookup = new(); @@ -473,10 +473,10 @@ public enum DebuggerShortcut TileEditor_TranslateDown, } - public class DebuggerShortcutInfo : ViewModelBase + public partial class DebuggerShortcutInfo : ViewModelBase { - [Reactive] public DebuggerShortcut Shortcut { get; set; } - [Reactive] public DbgShortKeys KeyBinding { get; set; } = new(); + [ObservableProperty] public partial DebuggerShortcut Shortcut { get; set; } + [ObservableProperty] public partial DbgShortKeys KeyBinding { get; set; } = new(); } public class DbgShortKeys diff --git a/UI/Config/Debugger/EventViewerCategoryCfg.cs b/UI/Config/Debugger/EventViewerCategoryCfg.cs index 66314ff41..f420b3e29 100644 --- a/UI/Config/Debugger/EventViewerCategoryCfg.cs +++ b/UI/Config/Debugger/EventViewerCategoryCfg.cs @@ -1,15 +1,15 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Config { - public class EventViewerCategoryCfg : ViewModelBase + public partial class EventViewerCategoryCfg : ViewModelBase { - [Reactive] public bool Visible { get; set; } = true; - [Reactive] public UInt32 Color { get; set; } + [ObservableProperty] public partial bool Visible { get; set; } = true; + [ObservableProperty] public partial UInt32 Color { get; set; } public EventViewerCategoryCfg() { } diff --git a/UI/Config/Debugger/EventViewerConfig.cs b/UI/Config/Debugger/EventViewerConfig.cs index 4d944ab67..1935f5d93 100644 --- a/UI/Config/Debugger/EventViewerConfig.cs +++ b/UI/Config/Debugger/EventViewerConfig.cs @@ -1,31 +1,31 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class EventViewerConfig : BaseWindowConfig + public partial class EventViewerConfig : BaseWindowConfig { - [Reactive] public bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; - [Reactive] public double ImageScale { get; set; } = 1; + [ObservableProperty] public partial double ImageScale { get; set; } = 1; - [Reactive] public bool RefreshOnBreakPause { get; set; } = true; - [Reactive] public bool AutoRefresh { get; set; } = true; - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial bool RefreshOnBreakPause { get; set; } = true; + [ObservableProperty] public partial bool AutoRefresh { get; set; } = true; + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); - [Reactive] public List ColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List ColumnWidths { get; set; } = new(); - [Reactive] public bool ShowToolbar { get; set; } = true; + [ObservableProperty] public partial bool ShowToolbar { get; set; } = true; - [Reactive] public bool ShowListView { get; set; } = true; - [Reactive] public double ListViewHeight { get; set; } = 200; + [ObservableProperty] public partial bool ShowListView { get; set; } = true; + [ObservableProperty] public partial double ListViewHeight { get; set; } = 200; - [Reactive] public SnesEventViewerConfig SnesConfig { get; set; } = new SnesEventViewerConfig(); - [Reactive] public NesEventViewerConfig NesConfig { get; set; } = new NesEventViewerConfig(); - [Reactive] public GbEventViewerConfig GbConfig { get; set; } = new GbEventViewerConfig(); - [Reactive] public GbaEventViewerConfig GbaConfig { get; set; } = new GbaEventViewerConfig(); - [Reactive] public PceEventViewerConfig PceConfig { get; set; } = new PceEventViewerConfig(); - [Reactive] public SmsEventViewerConfig SmsConfig { get; set; } = new SmsEventViewerConfig(); - [Reactive] public WsEventViewerConfig WsConfig { get; set; } = new WsEventViewerConfig(); + [ObservableProperty] public partial SnesEventViewerConfig SnesConfig { get; set; } = new SnesEventViewerConfig(); + [ObservableProperty] public partial NesEventViewerConfig NesConfig { get; set; } = new NesEventViewerConfig(); + [ObservableProperty] public partial GbEventViewerConfig GbConfig { get; set; } = new GbEventViewerConfig(); + [ObservableProperty] public partial GbaEventViewerConfig GbaConfig { get; set; } = new GbaEventViewerConfig(); + [ObservableProperty] public partial PceEventViewerConfig PceConfig { get; set; } = new PceEventViewerConfig(); + [ObservableProperty] public partial SmsEventViewerConfig SmsConfig { get; set; } = new SmsEventViewerConfig(); + [ObservableProperty] public partial WsEventViewerConfig WsConfig { get; set; } = new WsEventViewerConfig(); } } diff --git a/UI/Config/Debugger/FontConfig.cs b/UI/Config/Debugger/FontConfig.cs index ba0bbbe87..419eaa290 100644 --- a/UI/Config/Debugger/FontConfig.cs +++ b/UI/Config/Debugger/FontConfig.cs @@ -1,14 +1,13 @@ using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; namespace Mesen.Config { - public class FontConfig : BaseConfig + public partial class FontConfig : BaseConfig { - [Reactive] public string FontFamily { get; set; } = ""; - [Reactive] public double FontSize { get; set; } = 12; + [ObservableProperty] public partial string FontFamily { get; set; } = ""; + [ObservableProperty] public partial double FontSize { get; set; } = 12; } } diff --git a/UI/Config/Debugger/GbDebuggerConfig.cs b/UI/Config/Debugger/GbDebuggerConfig.cs index d18e52a21..6b81a5354 100644 --- a/UI/Config/Debugger/GbDebuggerConfig.cs +++ b/UI/Config/Debugger/GbDebuggerConfig.cs @@ -1,21 +1,19 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Config { - public class GbDebuggerConfig : ViewModelBase + public partial class GbDebuggerConfig : ViewModelBase { - [Reactive] public bool GbBreakOnInvalidOamAccess { get; set; } = false; - [Reactive] public bool GbBreakOnInvalidVramAccess { get; set; } = false; - [Reactive] public bool GbBreakOnDisableLcdOutsideVblank { get; set; } = false; - [Reactive] public bool GbBreakOnInvalidOpCode { get; set; } = false; - [Reactive] public bool GbBreakOnNopLoad { get; set; } = false; - [Reactive] public bool GbBreakOnOamCorruption { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnInvalidOamAccess { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnInvalidVramAccess { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnDisableLcdOutsideVblank { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnInvalidOpCode { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnNopLoad { get; set; } = false; + [ObservableProperty] public partial bool GbBreakOnOamCorruption { get; set; } = false; } } diff --git a/UI/Config/Debugger/GbEventViewerConfig.cs b/UI/Config/Debugger/GbEventViewerConfig.cs index f40932dc4..7b2a298b6 100644 --- a/UI/Config/Debugger/GbEventViewerConfig.cs +++ b/UI/Config/Debugger/GbEventViewerConfig.cs @@ -1,46 +1,46 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class GbEventViewerConfig : ViewModelBase + public partial class GbEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg PpuRegisterCgramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); - [Reactive] public EventViewerCategoryCfg PpuRegisterVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); - [Reactive] public EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterCgramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); - [Reactive] public EventViewerCategoryCfg PpuRegisterCgramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); - [Reactive] public EventViewerCategoryCfg PpuRegisterVramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOamReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgScrollReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD9, 0x4A, 0x7C)); - [Reactive] public EventViewerCategoryCfg PpuRegisterWindowReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF7, 0xE2, 0x51)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOtherReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x42, 0xD1, 0xDD)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterCgramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterVramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOamReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgScrollReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD9, 0x4A, 0x7C)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterWindowReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF7, 0xE2, 0x51)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOtherReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x42, 0xD1, 0xDD)); - [Reactive] public EventViewerCategoryCfg SerialWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0x7C, 0x29)); - [Reactive] public EventViewerCategoryCfg SerialReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg SerialWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0x7C, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg SerialReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0x29)); - [Reactive] public EventViewerCategoryCfg InputWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x42, 0x44)); - [Reactive] public EventViewerCategoryCfg InputReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x51, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg InputWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x42, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg InputReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x51, 0xE4)); - [Reactive] public EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xFF, 0x44)); - [Reactive] public EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xFF, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg OtherRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x98, 0x5E, 0xFF)); - [Reactive] public EventViewerCategoryCfg OtherRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg OtherRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x98, 0x5E, 0xFF)); + [ObservableProperty] public partial EventViewerCategoryCfg OtherRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); - [Reactive] public EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; public InteropGbEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/GbaDebuggerConfig.cs b/UI/Config/Debugger/GbaDebuggerConfig.cs index 82937adff..b864ee34c 100644 --- a/UI/Config/Debugger/GbaDebuggerConfig.cs +++ b/UI/Config/Debugger/GbaDebuggerConfig.cs @@ -1,15 +1,15 @@ using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config; -public class GbaDebuggerConfig : ViewModelBase +public partial class GbaDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnInvalidOpCode { get; set; } = false; - [Reactive] public bool BreakOnNopLoad { get; set; } = false; - [Reactive] public bool BreakOnUnalignedMemAccess { get; set; } = false; + [ObservableProperty] public partial bool BreakOnInvalidOpCode { get; set; } = false; + [ObservableProperty] public partial bool BreakOnNopLoad { get; set; } = false; + [ObservableProperty] public partial bool BreakOnUnalignedMemAccess { get; set; } = false; - [Reactive] public GbaDisassemblyMode DisassemblyMode { get; set; } = GbaDisassemblyMode.Default; + [ObservableProperty] public partial GbaDisassemblyMode DisassemblyMode { get; set; } = GbaDisassemblyMode.Default; } public enum GbaDisassemblyMode : byte diff --git a/UI/Config/Debugger/GbaEventViewerConfig.cs b/UI/Config/Debugger/GbaEventViewerConfig.cs index 4d6e5af29..15a1e509a 100644 --- a/UI/Config/Debugger/GbaEventViewerConfig.cs +++ b/UI/Config/Debugger/GbaEventViewerConfig.cs @@ -1,49 +1,49 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class GbaEventViewerConfig : ViewModelBase + public partial class GbaEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg PaletteReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); - [Reactive] public EventViewerCategoryCfg PaletteWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); - [Reactive] public EventViewerCategoryCfg VramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); - [Reactive] public EventViewerCategoryCfg VramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg OamReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); - [Reactive] public EventViewerCategoryCfg OamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg PaletteReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg PaletteWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg VramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg VramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg OamReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); + [ObservableProperty] public partial EventViewerCategoryCfg OamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgScrollReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD9, 0x4A, 0x7C)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); - [Reactive] public EventViewerCategoryCfg PpuRegisterWindowReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF7, 0xE2, 0x51)); - [Reactive] public EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOtherReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x42, 0xD1, 0xDD)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgScrollReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD9, 0x4A, 0x7C)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterWindowReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF7, 0xE2, 0x51)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOtherReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x42, 0xD1, 0xDD)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); - [Reactive] public EventViewerCategoryCfg SerialWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0x7C, 0x29)); - [Reactive] public EventViewerCategoryCfg SerialReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg SerialWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0x7C, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg SerialReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0x29)); - [Reactive] public EventViewerCategoryCfg InputWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x42, 0x44)); - [Reactive] public EventViewerCategoryCfg InputReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x51, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg InputWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x42, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg InputReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x51, 0xE4)); - [Reactive] public EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xFF, 0x44)); - [Reactive] public EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xFF, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg OtherRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x98, 0x5E, 0xFF)); - [Reactive] public EventViewerCategoryCfg OtherRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg OtherRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x98, 0x5E, 0xFF)); + [ObservableProperty] public partial EventViewerCategoryCfg OtherRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); - [Reactive] public EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg DmaRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xDA, 0x4A)); - [Reactive] public EventViewerCategoryCfg DmaRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0xB4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg DmaRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x51, 0xDA, 0x4A)); + [ObservableProperty] public partial EventViewerCategoryCfg DmaRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0xB4, 0x7A)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; public InteropGbaEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/HexEditorConfig.cs b/UI/Config/Debugger/HexEditorConfig.cs index 029b1c280..2471f3704 100644 --- a/UI/Config/Debugger/HexEditorConfig.cs +++ b/UI/Config/Debugger/HexEditorConfig.cs @@ -1,9 +1,8 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; @@ -16,41 +15,41 @@ namespace Mesen.Config { - public class HexEditorConfig : BaseWindowConfig + public partial class HexEditorConfig : BaseWindowConfig { - [Reactive] public bool ShowOptionPanel { get; set; } = true; - [Reactive] public bool AutoRefresh { get; set; } = true; - [Reactive] public bool IgnoreRedundantWrites { get; set; } = false; + [ObservableProperty] public partial bool ShowOptionPanel { get; set; } = true; + [ObservableProperty] public partial bool AutoRefresh { get; set; } = true; + [ObservableProperty] public partial bool IgnoreRedundantWrites { get; set; } = false; - [Reactive] public int BytesPerRow { get; set; } = 16; + [ObservableProperty] public partial int BytesPerRow { get; set; } = 16; - [Reactive] public bool HighDensityTextMode { get; set; } = false; + [ObservableProperty] public partial bool HighDensityTextMode { get; set; } = false; - [Reactive] public bool ShowCharacters { get; set; } = true; - [Reactive] public bool ShowTooltips { get; set; } = true; + [ObservableProperty] public partial bool ShowCharacters { get; set; } = true; + [ObservableProperty] public partial bool ShowTooltips { get; set; } = true; - [Reactive] public bool HideUnusedBytes { get; set; } = false; - [Reactive] public bool HideReadBytes { get; set; } = false; - [Reactive] public bool HideWrittenBytes { get; set; } = false; - [Reactive] public bool HideExecutedBytes { get; set; } = false; + [ObservableProperty] public partial bool HideUnusedBytes { get; set; } = false; + [ObservableProperty] public partial bool HideReadBytes { get; set; } = false; + [ObservableProperty] public partial bool HideWrittenBytes { get; set; } = false; + [ObservableProperty] public partial bool HideExecutedBytes { get; set; } = false; - [Reactive] public HighlightFadeSpeed FadeSpeed { get; set; } = HighlightFadeSpeed.Normal; - [Reactive] public HighlightConfig ReadHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Blue.ToUInt32() }; - [Reactive] public HighlightConfig WriteHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Red.ToUInt32() }; - [Reactive] public HighlightConfig ExecHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Green.ToUInt32() }; + [ObservableProperty] public partial HighlightFadeSpeed FadeSpeed { get; set; } = HighlightFadeSpeed.Normal; + [ObservableProperty] public partial HighlightConfig ReadHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Blue.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig WriteHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Red.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig ExecHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Green.ToUInt32() }; - [Reactive] public HighlightConfig LabelHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.LightPink.ToUInt32() }; - [Reactive] public HighlightConfig CodeHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.DarkSeaGreen.ToUInt32() }; - [Reactive] public HighlightConfig DataHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.LightSteelBlue.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig LabelHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.LightPink.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig CodeHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.DarkSeaGreen.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig DataHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.LightSteelBlue.ToUInt32() }; - [Reactive] public HighlightConfig FrozenHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Magenta.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig FrozenHighlight { get; set; } = new() { Highlight = true, ColorCode = Colors.Magenta.ToUInt32() }; - [Reactive] public HighlightConfig NesPcmDataHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.Khaki.ToUInt32() }; - [Reactive] public HighlightConfig NesDrawnChrRomHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.Thistle.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig NesPcmDataHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.Khaki.ToUInt32() }; + [ObservableProperty] public partial HighlightConfig NesDrawnChrRomHighlight { get; set; } = new() { Highlight = false, ColorCode = Colors.Thistle.ToUInt32() }; - [Reactive] public bool HighlightBreakpoints { get; set; } = false; + [ObservableProperty] public partial bool HighlightBreakpoints { get; set; } = false; - [Reactive] public MemoryType MemoryType { get; set; } = MemoryType.SnesMemory; + [ObservableProperty] public partial MemoryType MemoryType { get; set; } = MemoryType.SnesMemory; public HexEditorConfig() { @@ -79,10 +78,10 @@ public static int ToFrameCount(this HighlightFadeSpeed speed) } } - public class HighlightConfig : ReactiveObject + public partial class HighlightConfig : ObservableObject { - [Reactive] public bool Highlight { get; set; } - [Reactive] public UInt32 ColorCode { get; set; } + [ObservableProperty] public partial bool Highlight { get; set; } + [ObservableProperty] public partial UInt32 ColorCode { get; set; } [JsonIgnore] public Color Color diff --git a/UI/Config/Debugger/MemorySearchConfig.cs b/UI/Config/Debugger/MemorySearchConfig.cs index 502182253..b0444010b 100644 --- a/UI/Config/Debugger/MemorySearchConfig.cs +++ b/UI/Config/Debugger/MemorySearchConfig.cs @@ -1,11 +1,11 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class MemorySearchConfig : BaseWindowConfig + public partial class MemorySearchConfig : BaseWindowConfig { - [Reactive] public List ColumnWidths { get; set; } = new(); + [ObservableProperty] public partial List ColumnWidths { get; set; } = new(); } } diff --git a/UI/Config/Debugger/NesDebuggerConfig.cs b/UI/Config/Debugger/NesDebuggerConfig.cs index 6e15d74aa..c981ea3d6 100644 --- a/UI/Config/Debugger/NesDebuggerConfig.cs +++ b/UI/Config/Debugger/NesDebuggerConfig.cs @@ -1,23 +1,21 @@ -using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using System.Reactive; -using System.Reactive.Linq; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.ViewModels; namespace Mesen.Config { - public class NesDebuggerConfig : ViewModelBase + public partial class NesDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnBrk { get; set; } = false; - [Reactive] public bool BreakOnUnofficialOpCode { get; set; } = false; - [Reactive] public bool BreakOnUnstableOpCode { get; set; } = true; - [Reactive] public bool BreakOnCpuCrash { get; set; } = true; + [ObservableProperty] public partial bool BreakOnBrk { get; set; } = false; + [ObservableProperty] public partial bool BreakOnUnofficialOpCode { get; set; } = false; + [ObservableProperty] public partial bool BreakOnUnstableOpCode { get; set; } = true; + [ObservableProperty] public partial bool BreakOnCpuCrash { get; set; } = true; - [Reactive] public bool BreakOnBusConflict { get; set; } = false; - [Reactive] public bool BreakOnDecayedOamRead { get; set; } = false; - [Reactive] public bool BreakOnPpuScrollGlitch { get; set; } = false; - [Reactive] public bool BreakOnExtOutputMode { get; set; } = true; - [Reactive] public bool BreakOnInvalidVramAccess { get; set; } = false; - [Reactive] public bool BreakOnInvalidOamWrite { get; set; } = false; - [Reactive] public bool BreakOnDmaInputRead { get; set; } = false; + [ObservableProperty] public partial bool BreakOnBusConflict { get; set; } = false; + [ObservableProperty] public partial bool BreakOnDecayedOamRead { get; set; } = false; + [ObservableProperty] public partial bool BreakOnPpuScrollGlitch { get; set; } = false; + [ObservableProperty] public partial bool BreakOnExtOutputMode { get; set; } = true; + [ObservableProperty] public partial bool BreakOnInvalidVramAccess { get; set; } = false; + [ObservableProperty] public partial bool BreakOnInvalidOamWrite { get; set; } = false; + [ObservableProperty] public partial bool BreakOnDmaInputRead { get; set; } = false; } } diff --git a/UI/Config/Debugger/NesEventViewerConfig.cs b/UI/Config/Debugger/NesEventViewerConfig.cs index 7fadeb28f..98fa4c93e 100644 --- a/UI/Config/Debugger/NesEventViewerConfig.cs +++ b/UI/Config/Debugger/NesEventViewerConfig.cs @@ -1,44 +1,44 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class NesEventViewerConfig : ViewModelBase + public partial class NesEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg MapperRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x6E, 0x8E)); - [Reactive] public EventViewerCategoryCfg MapperRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x78, 0xA5, 0xB2)); + [ObservableProperty] public partial EventViewerCategoryCfg MapperRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x6E, 0x8E)); + [ObservableProperty] public partial EventViewerCategoryCfg MapperRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x78, 0xA5, 0xB2)); - [Reactive] public EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x97, 0x75, 0x00)); - [Reactive] public EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB7, 0xAA, 0x7B)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x97, 0x75, 0x00)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB7, 0xAA, 0x7B)); - [Reactive] public EventViewerCategoryCfg ControlRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x06, 0xDA, 0xDF)); - [Reactive] public EventViewerCategoryCfg ControlRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9B, 0xFF, 0xDE)); + [ObservableProperty] public partial EventViewerCategoryCfg ControlRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x06, 0xDA, 0xDF)); + [ObservableProperty] public partial EventViewerCategoryCfg ControlRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9B, 0xFF, 0xDE)); - [Reactive] public EventViewerCategoryCfg Ppu2000Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x96, 0x45, 0x45)); - [Reactive] public EventViewerCategoryCfg Ppu2001Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x8E, 0x33, 0xFF)); - [Reactive] public EventViewerCategoryCfg Ppu2003Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x84, 0xE0)); - [Reactive] public EventViewerCategoryCfg Ppu2004Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFA, 0xFF, 0x39)); - [Reactive] public EventViewerCategoryCfg Ppu2005Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x2E, 0xFF, 0x28)); - [Reactive] public EventViewerCategoryCfg Ppu2006Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x3D, 0x2D, 0xFF)); - [Reactive] public EventViewerCategoryCfg Ppu2007Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x06, 0x0D)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2000Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x96, 0x45, 0x45)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2001Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x8E, 0x33, 0xFF)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2003Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x84, 0xE0)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2004Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFA, 0xFF, 0x39)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2005Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x2E, 0xFF, 0x28)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2006Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x3D, 0x2D, 0xFF)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2007Write { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x06, 0x0D)); - [Reactive] public EventViewerCategoryCfg Ppu2002Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x74, 0x0A)); - [Reactive] public EventViewerCategoryCfg Ppu2004Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFD, 0xFF, 0xB3)); - [Reactive] public EventViewerCategoryCfg Ppu2007Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x7D, 0x7D)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2002Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x74, 0x0A)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2004Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFD, 0xFF, 0xB3)); + [ObservableProperty] public partial EventViewerCategoryCfg Ppu2007Read { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x7D, 0x7D)); - [Reactive] public EventViewerCategoryCfg DmcDmaReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0xFF, 0xFD)); - [Reactive] public EventViewerCategoryCfg OtherDmaReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0xC9, 0xFD)); - [Reactive] public EventViewerCategoryCfg SpriteZeroHit { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x84, 0x73, 0xC0)); + [ObservableProperty] public partial EventViewerCategoryCfg DmcDmaReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0xFF, 0xFD)); + [ObservableProperty] public partial EventViewerCategoryCfg OtherDmaReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0xC9, 0xFD)); + [ObservableProperty] public partial EventViewerCategoryCfg SpriteZeroHit { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x84, 0x73, 0xC0)); - [Reactive] public EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAB, 0xAD, 0xAC)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAB, 0xAD, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; - [Reactive] public bool ShowNtscBorders { get; set; } = false; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowNtscBorders { get; set; } = false; public InteropNesEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/PaletteViewerConfig.cs b/UI/Config/Debugger/PaletteViewerConfig.cs index 6b13f1688..fef6d5916 100644 --- a/UI/Config/Debugger/PaletteViewerConfig.cs +++ b/UI/Config/Debugger/PaletteViewerConfig.cs @@ -1,15 +1,15 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class PaletteViewerConfig : BaseWindowConfig + public partial class PaletteViewerConfig : BaseWindowConfig { - [Reactive] public bool ShowSettingsPanel { get; set; } = true; - [Reactive] public bool ShowPaletteIndexes { get; set; } = false; - [Reactive] public int Zoom { get; set; } = 3; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowPaletteIndexes { get; set; } = false; + [ObservableProperty] public partial int Zoom { get; set; } = 3; - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); public PaletteViewerConfig() { diff --git a/UI/Config/Debugger/PceDebuggerConfig.cs b/UI/Config/Debugger/PceDebuggerConfig.cs index 0b1e78221..402899ff2 100644 --- a/UI/Config/Debugger/PceDebuggerConfig.cs +++ b/UI/Config/Debugger/PceDebuggerConfig.cs @@ -1,18 +1,16 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Config { - public class PceDebuggerConfig : ViewModelBase + public partial class PceDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnBrk { get; set; } = false; - [Reactive] public bool BreakOnUnofficialOpCode { get; set; } = false; - [Reactive] public bool BreakOnInvalidVramAddress { get; set; } = false; + [ObservableProperty] public partial bool BreakOnBrk { get; set; } = false; + [ObservableProperty] public partial bool BreakOnUnofficialOpCode { get; set; } = false; + [ObservableProperty] public partial bool BreakOnInvalidVramAddress { get; set; } = false; } } diff --git a/UI/Config/Debugger/PceEventViewerConfig.cs b/UI/Config/Debugger/PceEventViewerConfig.cs index b8a49e2f5..40500ffb1 100644 --- a/UI/Config/Debugger/PceEventViewerConfig.cs +++ b/UI/Config/Debugger/PceEventViewerConfig.cs @@ -1,49 +1,49 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class PceEventViewerConfig : ViewModelBase + public partial class PceEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg VdcStatusReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0xC9)); - [Reactive] public EventViewerCategoryCfg VdcVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); - [Reactive] public EventViewerCategoryCfg VdcVramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); - [Reactive] public EventViewerCategoryCfg VdcRegSelectWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0x29, 0xC9)); - [Reactive] public EventViewerCategoryCfg VdcControlWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC6, 0x93)); - [Reactive] public EventViewerCategoryCfg VdcRcrWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0x9F, 0x93)); - [Reactive] public EventViewerCategoryCfg VdcHvConfigWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x93, 0xC6, 0x9F)); - [Reactive] public EventViewerCategoryCfg VdcMemoryWidthWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0x29, 0xC6)); - [Reactive] public EventViewerCategoryCfg VdcScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0xC6, 0x29)); - [Reactive] public EventViewerCategoryCfg VdcDmaWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x93, 0x29, 0xC9)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcStatusReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0xC9)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcVramReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC9, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcRegSelectWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0x29, 0xC9)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcControlWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x29, 0xC6, 0x93)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcRcrWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0x9F, 0x93)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcHvConfigWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x93, 0xC6, 0x9F)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcMemoryWidthWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0x29, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC6, 0xC6, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg VdcDmaWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x93, 0x29, 0xC9)); - [Reactive] public EventViewerCategoryCfg CdRomWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); - [Reactive] public EventViewerCategoryCfg CdRomReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); - [Reactive] public EventViewerCategoryCfg AdpcmWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD7, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg AdpcmReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x53, 0x44)); - [Reactive] public EventViewerCategoryCfg ArcadeCardWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0xDA, 0xD7)); - [Reactive] public EventViewerCategoryCfg ArcadeCardReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0xB4, 0x53)); + [ObservableProperty] public partial EventViewerCategoryCfg CdRomWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xDA, 0xB4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg CdRomReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0x53, 0xD7)); + [ObservableProperty] public partial EventViewerCategoryCfg AdpcmWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD7, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg AdpcmReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x53, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg ArcadeCardWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x7A, 0xDA, 0xD7)); + [ObservableProperty] public partial EventViewerCategoryCfg ArcadeCardReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x44, 0xB4, 0x53)); - [Reactive] public EventViewerCategoryCfg VceWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg VceReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg VceWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg VceReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); - [Reactive] public EventViewerCategoryCfg PsgWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); - [Reactive] public EventViewerCategoryCfg PsgReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg PsgWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); + [ObservableProperty] public partial EventViewerCategoryCfg PsgReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); - [Reactive] public EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); + [ObservableProperty] public partial EventViewerCategoryCfg TimerReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); - [Reactive] public EventViewerCategoryCfg IoWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); - [Reactive] public EventViewerCategoryCfg IoReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg IrqControlWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0xDD)); - [Reactive] public EventViewerCategoryCfg IrqControlReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg IoWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); + [ObservableProperty] public partial EventViewerCategoryCfg IoReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg IrqControlWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0xDD)); + [ObservableProperty] public partial EventViewerCategoryCfg IrqControlReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; public InteropPceEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/ProfilerConfig.cs b/UI/Config/Debugger/ProfilerConfig.cs index 08ffc96e0..dddbe6bbb 100644 --- a/UI/Config/Debugger/ProfilerConfig.cs +++ b/UI/Config/Debugger/ProfilerConfig.cs @@ -1,12 +1,12 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class ProfilerConfig : BaseWindowConfig + public partial class ProfilerConfig : BaseWindowConfig { - [Reactive] public List ColumnWidths { get; set; } = new(); - [Reactive] public bool AutoRefresh { get; set; } = true; - [Reactive] public bool RefreshOnBreakPause { get; set; } = true; + [ObservableProperty] public partial List ColumnWidths { get; set; } = new(); + [ObservableProperty] public partial bool AutoRefresh { get; set; } = true; + [ObservableProperty] public partial bool RefreshOnBreakPause { get; set; } = true; } } diff --git a/UI/Config/Debugger/RefreshTimingConfig.cs b/UI/Config/Debugger/RefreshTimingConfig.cs index ac00f5253..0d2fc4a48 100644 --- a/UI/Config/Debugger/RefreshTimingConfig.cs +++ b/UI/Config/Debugger/RefreshTimingConfig.cs @@ -1,14 +1,14 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class RefreshTimingConfig : BaseConfig + public partial class RefreshTimingConfig : BaseConfig { - [Reactive] public Dictionary ConsoleConfig { get; set; } = new(); - [Reactive] public bool RefreshOnBreakPause { get; set; } = true; - [Reactive] public bool AutoRefresh { get; set; } = true; + [ObservableProperty] public partial Dictionary ConsoleConfig { get; set; } = new(); + [ObservableProperty] public partial bool RefreshOnBreakPause { get; set; } = true; + [ObservableProperty] public partial bool AutoRefresh { get; set; } = true; public RefreshTimingConfig() { @@ -24,10 +24,10 @@ public RefreshTimingConsoleConfig GetConsoleConfig(CpuType cpuType) } } - public class RefreshTimingConsoleConfig : BaseConfig + public partial class RefreshTimingConsoleConfig : BaseConfig { - [Reactive] public int RefreshScanline { get; set; } = 240; - [Reactive] public int RefreshCycle { get; set; } = 0; + [ObservableProperty] public partial int RefreshScanline { get; set; } = 240; + [ObservableProperty] public partial int RefreshCycle { get; set; } = 0; public RefreshTimingConsoleConfig() { diff --git a/UI/Config/Debugger/RegisterViewerConfig.cs b/UI/Config/Debugger/RegisterViewerConfig.cs index 38cfd4312..4eee3fef7 100644 --- a/UI/Config/Debugger/RegisterViewerConfig.cs +++ b/UI/Config/Debugger/RegisterViewerConfig.cs @@ -1,11 +1,11 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class RegisterViewerConfig : BaseWindowConfig + public partial class RegisterViewerConfig : BaseWindowConfig { - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); - [Reactive] public List ColumnWidths { get; set; } = new(); + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial List ColumnWidths { get; set; } = new(); } } diff --git a/UI/Config/Debugger/ScriptWindowConfig.cs b/UI/Config/Debugger/ScriptWindowConfig.cs index 304ebaa30..1aa7a19bf 100644 --- a/UI/Config/Debugger/ScriptWindowConfig.cs +++ b/UI/Config/Debugger/ScriptWindowConfig.cs @@ -1,7 +1,7 @@ using Avalonia; using Avalonia.Media; using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -10,28 +10,28 @@ namespace Mesen.Config { - public class ScriptWindowConfig : BaseWindowConfig + public partial class ScriptWindowConfig : BaseWindowConfig { private const int MaxRecentScripts = 10; - [Reactive] public List RecentScripts { get; set; } = new List(); + [ObservableProperty] public partial List RecentScripts { get; set; } = new List(); - [Reactive] public int Zoom { get; set; } = 100; + [ObservableProperty] public partial int Zoom { get; set; } = 100; - [Reactive] public double LogWindowHeight { get; set; } = 100; + [ObservableProperty] public partial double LogWindowHeight { get; set; } = 100; - [Reactive] public ScriptStartupBehavior ScriptStartupBehavior { get; set; } = ScriptStartupBehavior.ShowTutorial; - [Reactive] public bool SaveScriptBeforeRun { get; set; } = true; - [Reactive] public bool AutoStartScriptOnLoad { get; set; } = true; - [Reactive] public bool AutoReloadScriptWhenFileChanges { get; set; } = true; - [Reactive] public bool AutoRestartScriptAfterPowerCycle { get; set; } = true; + [ObservableProperty] public partial ScriptStartupBehavior ScriptStartupBehavior { get; set; } = ScriptStartupBehavior.ShowTutorial; + [ObservableProperty] public partial bool SaveScriptBeforeRun { get; set; } = true; + [ObservableProperty] public partial bool AutoStartScriptOnLoad { get; set; } = true; + [ObservableProperty] public partial bool AutoReloadScriptWhenFileChanges { get; set; } = true; + [ObservableProperty] public partial bool AutoRestartScriptAfterPowerCycle { get; set; } = true; - [Reactive] public bool AllowIoOsAccess { get; set; } = false; - [Reactive] public bool AllowNetworkAccess { get; set; } = false; + [ObservableProperty] public partial bool AllowIoOsAccess { get; set; } = false; + [ObservableProperty] public partial bool AllowNetworkAccess { get; set; } = false; - [Reactive] public bool ShowLineNumbers { get; set; } = false; + [ObservableProperty] public partial bool ShowLineNumbers { get; set; } = false; - [Reactive] public UInt32 ScriptTimeout { get; set; } = 1; + [ObservableProperty] public partial UInt32 ScriptTimeout { get; set; } = 1; public void AddRecentScript(string scriptFile) { diff --git a/UI/Config/Debugger/SmsDebuggerConfig.cs b/UI/Config/Debugger/SmsDebuggerConfig.cs index 9f49e3026..fd986b881 100644 --- a/UI/Config/Debugger/SmsDebuggerConfig.cs +++ b/UI/Config/Debugger/SmsDebuggerConfig.cs @@ -1,16 +1,14 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Config { - public class SmsDebuggerConfig : ViewModelBase + public partial class SmsDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnNopLoad { get; set; } = false; + [ObservableProperty] public partial bool BreakOnNopLoad { get; set; } = false; } } diff --git a/UI/Config/Debugger/SmsEventViewerConfig.cs b/UI/Config/Debugger/SmsEventViewerConfig.cs index af443e4cd..c642cbdb9 100644 --- a/UI/Config/Debugger/SmsEventViewerConfig.cs +++ b/UI/Config/Debugger/SmsEventViewerConfig.cs @@ -1,35 +1,35 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class SmsEventViewerConfig : ViewModelBase + public partial class SmsEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg VdpPaletteWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); - [Reactive] public EventViewerCategoryCfg VdpVramWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg VdpVCounterRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); - [Reactive] public EventViewerCategoryCfg VdpHCounterRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); - [Reactive] public EventViewerCategoryCfg VdpVramRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); - [Reactive] public EventViewerCategoryCfg VdpControlPortRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); - [Reactive] public EventViewerCategoryCfg VdpControlPortWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpPaletteWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpVramWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpVCounterRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpHCounterRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpVramRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpControlPortRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); + [ObservableProperty] public partial EventViewerCategoryCfg VdpControlPortWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); - [Reactive] public EventViewerCategoryCfg PsgWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); - [Reactive] public EventViewerCategoryCfg IoWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg IoRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg PsgWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); + [ObservableProperty] public partial EventViewerCategoryCfg IoWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg IoRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); - [Reactive] public EventViewerCategoryCfg MemoryControlWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg MemoryControlWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg GameGearPortWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg GameGearPortRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAC, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg GameGearPortWrite { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg GameGearPortRead { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAC, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; public InteropSmsEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/SnesDebuggerConfig.cs b/UI/Config/Debugger/SnesDebuggerConfig.cs index 5ee4ab58a..5484027a9 100644 --- a/UI/Config/Debugger/SnesDebuggerConfig.cs +++ b/UI/Config/Debugger/SnesDebuggerConfig.cs @@ -1,21 +1,21 @@ using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class SnesDebuggerConfig : ViewModelBase + public partial class SnesDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnBrk { get; set; } = false; - [Reactive] public bool BreakOnCop { get; set; } = false; - [Reactive] public bool BreakOnWdm { get; set; } = false; - [Reactive] public bool BreakOnStp { get; set; } = false; - [Reactive] public bool BreakOnInvalidPpuAccess { get; set; } = false; - [Reactive] public bool BreakOnReadDuringAutoJoy { get; set; } = false; + [ObservableProperty] public partial bool BreakOnBrk { get; set; } = false; + [ObservableProperty] public partial bool BreakOnCop { get; set; } = false; + [ObservableProperty] public partial bool BreakOnWdm { get; set; } = false; + [ObservableProperty] public partial bool BreakOnStp { get; set; } = false; + [ObservableProperty] public partial bool BreakOnInvalidPpuAccess { get; set; } = false; + [ObservableProperty] public partial bool BreakOnReadDuringAutoJoy { get; set; } = false; - [Reactive] public bool SpcBreakOnBrk { get; set; } = false; - [Reactive] public bool SpcBreakOnStpSleep { get; set; } = false; + [ObservableProperty] public partial bool SpcBreakOnBrk { get; set; } = false; + [ObservableProperty] public partial bool SpcBreakOnStpSleep { get; set; } = false; - [Reactive] public bool UseAltSpcOpNames { get; set; } = false; - [Reactive] public bool IgnoreDspReadWrites { get; set; } = true; + [ObservableProperty] public partial bool UseAltSpcOpNames { get; set; } = false; + [ObservableProperty] public partial bool IgnoreDspReadWrites { get; set; } = true; } } diff --git a/UI/Config/Debugger/SnesEventViewerConfig.cs b/UI/Config/Debugger/SnesEventViewerConfig.cs index eaf1d7fea..c5a5b94ee 100644 --- a/UI/Config/Debugger/SnesEventViewerConfig.cs +++ b/UI/Config/Debugger/SnesEventViewerConfig.cs @@ -1,46 +1,46 @@ using Avalonia.Media; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class SnesEventViewerConfig : ViewModelBase + public partial class SnesEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg PpuRegisterCgramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); - [Reactive] public EventViewerCategoryCfg PpuRegisterVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); - [Reactive] public EventViewerCategoryCfg PpuRegisterMode7Writes { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFE, 0x78, 0x7B)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgOptionWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xBF, 0x80, 0x20)); - [Reactive] public EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); - [Reactive] public EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); - [Reactive] public EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); - [Reactive] public EventViewerCategoryCfg PpuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterCgramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC9, 0x29, 0x29)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterVramWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xB4, 0x7A, 0xDA)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOamWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x53, 0xD7, 0x44)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterMode7Writes { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFE, 0x78, 0x7B)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgOptionWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xBF, 0x80, 0x20)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterBgScrollWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x4A, 0x7C, 0xD9)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterWindowWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xE2, 0x51, 0xF7)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterOtherWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xD1, 0xDD, 0x42)); + [ObservableProperty] public partial EventViewerCategoryCfg PpuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x00, 0x75, 0x97)); - [Reactive] public EventViewerCategoryCfg CpuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); - [Reactive] public EventViewerCategoryCfg CpuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg CpuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xFF, 0x5E, 0x5E)); + [ObservableProperty] public partial EventViewerCategoryCfg CpuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); - [Reactive] public EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x9F, 0x93, 0xC6)); + [ObservableProperty] public partial EventViewerCategoryCfg ApuRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xF9, 0xFE, 0xAC)); - [Reactive] public EventViewerCategoryCfg WorkRamRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x2E, 0xFF, 0x28)); - [Reactive] public EventViewerCategoryCfg WorkRamRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x8E, 0x33, 0xFF)); + [ObservableProperty] public partial EventViewerCategoryCfg WorkRamRegisterWrites { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x2E, 0xFF, 0x28)); + [ObservableProperty] public partial EventViewerCategoryCfg WorkRamRegisterReads { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x8E, 0x33, 0xFF)); - [Reactive] public EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAB, 0xAD, 0xAC)); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); + [ObservableProperty] public partial EventViewerCategoryCfg Nmi { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xAB, 0xAD, 0xAC)); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0xC4, 0xF4, 0x7A)); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(Color.FromRgb(0x18, 0x98, 0xE4)); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; - [Reactive] public bool ShowDmaChannel0 { get; set; } = true; - [Reactive] public bool ShowDmaChannel1 { get; set; } = true; - [Reactive] public bool ShowDmaChannel2 { get; set; } = true; - [Reactive] public bool ShowDmaChannel3 { get; set; } = true; - [Reactive] public bool ShowDmaChannel4 { get; set; } = true; - [Reactive] public bool ShowDmaChannel5 { get; set; } = true; - [Reactive] public bool ShowDmaChannel6 { get; set; } = true; - [Reactive] public bool ShowDmaChannel7 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel0 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel1 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel2 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel3 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel4 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel5 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel6 { get; set; } = true; + [ObservableProperty] public partial bool ShowDmaChannel7 { get; set; } = true; public InteropSnesEventViewerConfig ToInterop() { diff --git a/UI/Config/Debugger/SpriteViewerConfig.cs b/UI/Config/Debugger/SpriteViewerConfig.cs index 95f26015f..8bcd271c3 100644 --- a/UI/Config/Debugger/SpriteViewerConfig.cs +++ b/UI/Config/Debugger/SpriteViewerConfig.cs @@ -1,27 +1,27 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System.Collections.Generic; namespace Mesen.Config { - public class SpriteViewerConfig : BaseWindowConfig + public partial class SpriteViewerConfig : BaseWindowConfig { - [Reactive] public bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; - [Reactive] public bool ShowOutline { get; set; } = false; - [Reactive] public bool ShowOffscreenRegions { get; set; } = false; - [Reactive] public SpriteBackground Background { get; set; } = SpriteBackground.Gray; + [ObservableProperty] public partial bool ShowOutline { get; set; } = false; + [ObservableProperty] public partial bool ShowOffscreenRegions { get; set; } = false; + [ObservableProperty] public partial SpriteBackground Background { get; set; } = SpriteBackground.Gray; - [Reactive] public SpriteViewerSource Source { get; set; } = SpriteViewerSource.SpriteRam; - [Reactive] public int SourceOffset { get; set; } = 0; + [ObservableProperty] public partial SpriteViewerSource Source { get; set; } = SpriteViewerSource.SpriteRam; + [ObservableProperty] public partial int SourceOffset { get; set; } = 0; - [Reactive] public bool DimOffscreenSprites { get; set; } = true; - [Reactive] public bool ShowListView { get; set; } = false; - [Reactive] public double ListViewHeight { get; set; } = 100; - [Reactive] public List ColumnWidths { get; set; } = new(); + [ObservableProperty] public partial bool DimOffscreenSprites { get; set; } = true; + [ObservableProperty] public partial bool ShowListView { get; set; } = false; + [ObservableProperty] public partial double ListViewHeight { get; set; } = 100; + [ObservableProperty] public partial List ColumnWidths { get; set; } = new(); - [Reactive] public double ImageScale { get; set; } = 2; - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial double ImageScale { get; set; } = 2; + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); public SpriteViewerConfig() { diff --git a/UI/Config/Debugger/TileEditorConfig.cs b/UI/Config/Debugger/TileEditorConfig.cs index 856fea24b..9b9f8c343 100644 --- a/UI/Config/Debugger/TileEditorConfig.cs +++ b/UI/Config/Debugger/TileEditorConfig.cs @@ -1,12 +1,12 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class TileEditorConfig : BaseWindowConfig + public partial class TileEditorConfig : BaseWindowConfig { - [Reactive] public double ImageScale { get; set; } = 8; - [Reactive] public bool ShowGrid { get; set; } = false; - [Reactive] public TileBackground Background { get; set; } = TileBackground.Transparent; + [ObservableProperty] public partial double ImageScale { get; set; } = 8; + [ObservableProperty] public partial bool ShowGrid { get; set; } = false; + [ObservableProperty] public partial TileBackground Background { get; set; } = TileBackground.Transparent; } } diff --git a/UI/Config/Debugger/TileViewerConfig.cs b/UI/Config/Debugger/TileViewerConfig.cs index 33c4ebb8f..8c1b89727 100644 --- a/UI/Config/Debugger/TileViewerConfig.cs +++ b/UI/Config/Debugger/TileViewerConfig.cs @@ -1,28 +1,28 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class TileViewerConfig : BaseWindowConfig + public partial class TileViewerConfig : BaseWindowConfig { - [Reactive] public bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; - [Reactive] public double ImageScale { get; set; } = 3; - [Reactive] public bool ShowTileGrid { get; set; } = false; + [ObservableProperty] public partial double ImageScale { get; set; } = 3; + [ObservableProperty] public partial bool ShowTileGrid { get; set; } = false; - [Reactive] public string SelectedPreset { get; set; } = "PPU"; + [ObservableProperty] public partial string SelectedPreset { get; set; } = "PPU"; - [Reactive] public MemoryType Source { get; set; } - [Reactive] public TileFormat Format { get; set; } = TileFormat.Bpp4; - [Reactive] public TileLayout Layout { get; set; } = TileLayout.Normal; - [Reactive] public TileFilter Filter { get; set; } = TileFilter.None; - [Reactive] public TileBackground Background { get; set; } = TileBackground.Default; - [Reactive] public int RowCount { get; set; } = 64; - [Reactive] public int ColumnCount { get; set; } = 32; - [Reactive] public int StartAddress { get; set; } = 0; - [Reactive] public bool UseGrayscalePalette { get; set; } = false; + [ObservableProperty] public partial MemoryType Source { get; set; } + [ObservableProperty] public partial TileFormat Format { get; set; } = TileFormat.Bpp4; + [ObservableProperty] public partial TileLayout Layout { get; set; } = TileLayout.Normal; + [ObservableProperty] public partial TileFilter Filter { get; set; } = TileFilter.None; + [ObservableProperty] public partial TileBackground Background { get; set; } = TileBackground.Default; + [ObservableProperty] public partial int RowCount { get; set; } = 64; + [ObservableProperty] public partial int ColumnCount { get; set; } = 32; + [ObservableProperty] public partial int StartAddress { get; set; } = 0; + [ObservableProperty] public partial bool UseGrayscalePalette { get; set; } = false; - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); public TileViewerConfig() { diff --git a/UI/Config/Debugger/TilemapViewerConfig.cs b/UI/Config/Debugger/TilemapViewerConfig.cs index bf13803d7..6f550bca0 100644 --- a/UI/Config/Debugger/TilemapViewerConfig.cs +++ b/UI/Config/Debugger/TilemapViewerConfig.cs @@ -1,26 +1,26 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class TilemapViewerConfig : BaseWindowConfig + public partial class TilemapViewerConfig : BaseWindowConfig { - [Reactive] public bool ShowSettingsPanel { get; set; } = true; + [ObservableProperty] public partial bool ShowSettingsPanel { get; set; } = true; - [Reactive] public double ImageScale { get; set; } = 1; + [ObservableProperty] public partial double ImageScale { get; set; } = 1; - [Reactive] public bool ShowGrid { get; set; } - [Reactive] public bool ShowScrollOverlay { get; set; } + [ObservableProperty] public partial bool ShowGrid { get; set; } + [ObservableProperty] public partial bool ShowScrollOverlay { get; set; } - [Reactive] public bool NesShowAttributeGrid { get; set; } - [Reactive] public bool NesShowAttributeByteGrid { get; set; } - [Reactive] public bool NesShowTilemapGrid { get; set; } + [ObservableProperty] public partial bool NesShowAttributeGrid { get; set; } + [ObservableProperty] public partial bool NesShowAttributeByteGrid { get; set; } + [ObservableProperty] public partial bool NesShowTilemapGrid { get; set; } - [Reactive] public TilemapHighlightMode TileHighlightMode { get; set; } = TilemapHighlightMode.None; - [Reactive] public TilemapHighlightMode AttributeHighlightMode { get; set; } = TilemapHighlightMode.None; - [Reactive] public TilemapDisplayMode DisplayMode { get; set; } = TilemapDisplayMode.Default; + [ObservableProperty] public partial TilemapHighlightMode TileHighlightMode { get; set; } = TilemapHighlightMode.None; + [ObservableProperty] public partial TilemapHighlightMode AttributeHighlightMode { get; set; } = TilemapHighlightMode.None; + [ObservableProperty] public partial TilemapDisplayMode DisplayMode { get; set; } = TilemapDisplayMode.Default; - [Reactive] public RefreshTimingConfig RefreshTiming { get; set; } = new(); + [ObservableProperty] public partial RefreshTimingConfig RefreshTiming { get; set; } = new(); public TilemapViewerConfig() { diff --git a/UI/Config/Debugger/TraceLoggerConfig.cs b/UI/Config/Debugger/TraceLoggerConfig.cs index a98578dd5..c5c94620e 100644 --- a/UI/Config/Debugger/TraceLoggerConfig.cs +++ b/UI/Config/Debugger/TraceLoggerConfig.cs @@ -3,7 +3,7 @@ using Mesen.Debugger; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.IO; @@ -15,25 +15,25 @@ namespace Mesen.Config { - public class TraceLoggerConfig : BaseWindowConfig + public partial class TraceLoggerConfig : BaseWindowConfig { - [Reactive] public bool AutoRefresh { get; set; } = true; - [Reactive] public bool RefreshOnBreakPause { get; set; } = true; - [Reactive] public bool ShowToolbar { get; set; } = true; + [ObservableProperty] public partial bool AutoRefresh { get; set; } = true; + [ObservableProperty] public partial bool RefreshOnBreakPause { get; set; } = true; + [ObservableProperty] public partial bool ShowToolbar { get; set; } = true; - [Reactive] public TraceLoggerCpuConfig SnesConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig SpcConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig NecDspConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig Sa1Config { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig GsuConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig Cx4Config { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig St018Config { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig GbConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig NesConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig PceConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig SmsConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig GbaConfig { get; set; } = new(); - [Reactive] public TraceLoggerCpuConfig WsConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig SnesConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig SpcConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig NecDspConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig Sa1Config { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig GsuConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig Cx4Config { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig St018Config { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig GbConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig NesConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig PceConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig SmsConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig GbaConfig { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerCpuConfig WsConfig { get; set; } = new(); public TraceLoggerConfig() { diff --git a/UI/Config/Debugger/TraceLoggerCpuConfig.cs b/UI/Config/Debugger/TraceLoggerCpuConfig.cs index 0de119ac9..10b963e91 100644 --- a/UI/Config/Debugger/TraceLoggerCpuConfig.cs +++ b/UI/Config/Debugger/TraceLoggerCpuConfig.cs @@ -1,29 +1,29 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class TraceLoggerCpuConfig : BaseConfig + public partial class TraceLoggerCpuConfig : BaseConfig { - [Reactive] public bool Enabled { get; set; } = true; + [ObservableProperty] public partial bool Enabled { get; set; } = true; - [Reactive] public bool ShowRegisters { get; set; } = true; - [Reactive] public bool ShowStatusFlags { get; set; } = true; - [Reactive] public StatusFlagFormat StatusFormat { get; set; } = StatusFlagFormat.Text; + [ObservableProperty] public partial bool ShowRegisters { get; set; } = true; + [ObservableProperty] public partial bool ShowStatusFlags { get; set; } = true; + [ObservableProperty] public partial StatusFlagFormat StatusFormat { get; set; } = StatusFlagFormat.Text; - [Reactive] public bool ShowEffectiveAddresses { get; set; } = true; - [Reactive] public bool ShowMemoryValues { get; set; } = true; - [Reactive] public bool ShowByteCode { get; set; } = false; + [ObservableProperty] public partial bool ShowEffectiveAddresses { get; set; } = true; + [ObservableProperty] public partial bool ShowMemoryValues { get; set; } = true; + [ObservableProperty] public partial bool ShowByteCode { get; set; } = false; - [Reactive] public bool ShowClockCounter { get; set; } = false; - [Reactive] public bool ShowFrameCounter { get; set; } = false; - [Reactive] public bool ShowFramePosition { get; set; } = true; + [ObservableProperty] public partial bool ShowClockCounter { get; set; } = false; + [ObservableProperty] public partial bool ShowFrameCounter { get; set; } = false; + [ObservableProperty] public partial bool ShowFramePosition { get; set; } = true; - [Reactive] public bool UseLabels { get; set; } = true; - [Reactive] public bool IndentCode { get; set; } = false; + [ObservableProperty] public partial bool UseLabels { get; set; } = true; + [ObservableProperty] public partial bool IndentCode { get; set; } = false; - [Reactive] public bool UseCustomFormat { get; set; } = false; - [Reactive] public string Format { get; set; } = ""; - [Reactive] public string Condition { get; set; } = ""; + [ObservableProperty] public partial bool UseCustomFormat { get; set; } = false; + [ObservableProperty] public partial string Format { get; set; } = ""; + [ObservableProperty] public partial string Condition { get; set; } = ""; } public enum StatusFlagFormat diff --git a/UI/Config/Debugger/WatchWindowConfig.cs b/UI/Config/Debugger/WatchWindowConfig.cs index eb9315549..5e32a4ee2 100644 --- a/UI/Config/Debugger/WatchWindowConfig.cs +++ b/UI/Config/Debugger/WatchWindowConfig.cs @@ -1,6 +1,6 @@ namespace Mesen.Config { - public class WatchWindowConfig : BaseWindowConfig + public partial class WatchWindowConfig : BaseWindowConfig { } } diff --git a/UI/Config/Debugger/WsDebuggerConfig.cs b/UI/Config/Debugger/WsDebuggerConfig.cs index ca636c478..5e88aec6c 100644 --- a/UI/Config/Debugger/WsDebuggerConfig.cs +++ b/UI/Config/Debugger/WsDebuggerConfig.cs @@ -1,16 +1,14 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Config { - public class WsDebuggerConfig : ViewModelBase + public partial class WsDebuggerConfig : ViewModelBase { - [Reactive] public bool BreakOnUndefinedOpCode { get; set; } = false; + [ObservableProperty] public partial bool BreakOnUndefinedOpCode { get; set; } = false; } } diff --git a/UI/Config/Debugger/WsEventViewerConfig.cs b/UI/Config/Debugger/WsEventViewerConfig.cs index cba2cc358..9892ce002 100644 --- a/UI/Config/Debugger/WsEventViewerConfig.cs +++ b/UI/Config/Debugger/WsEventViewerConfig.cs @@ -1,58 +1,58 @@ using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config; -public class WsEventViewerConfig : ViewModelBase +public partial class WsEventViewerConfig : ViewModelBase { - [Reactive] public EventViewerCategoryCfg PpuPaletteRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[0]); - [Reactive] public EventViewerCategoryCfg PpuPaletteWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[1]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuPaletteRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[0]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuPaletteWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[1]); - [Reactive] public EventViewerCategoryCfg PpuVramRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[2]); - [Reactive] public EventViewerCategoryCfg PpuVramWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[3]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuVramRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[2]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuVramWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[3]); - [Reactive] public EventViewerCategoryCfg PpuScrollRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[4]); - [Reactive] public EventViewerCategoryCfg PpuScrollWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[5]); - [Reactive] public EventViewerCategoryCfg PpuWindowRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[6]); - [Reactive] public EventViewerCategoryCfg PpuWindowWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[7]); - [Reactive] public EventViewerCategoryCfg PpuOtherRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[8]); - [Reactive] public EventViewerCategoryCfg PpuOtherWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[9]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuScrollRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[4]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuScrollWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[5]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuWindowRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[6]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuWindowWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[7]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuOtherRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[8]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuOtherWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[9]); - [Reactive] public EventViewerCategoryCfg AudioRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[10]); - [Reactive] public EventViewerCategoryCfg AudioWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[11]); + [ObservableProperty] public partial EventViewerCategoryCfg AudioRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[10]); + [ObservableProperty] public partial EventViewerCategoryCfg AudioWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[11]); - [Reactive] public EventViewerCategoryCfg SerialRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[12]); - [Reactive] public EventViewerCategoryCfg SerialWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[13]); + [ObservableProperty] public partial EventViewerCategoryCfg SerialRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[12]); + [ObservableProperty] public partial EventViewerCategoryCfg SerialWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[13]); - [Reactive] public EventViewerCategoryCfg DmaRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[14]); - [Reactive] public EventViewerCategoryCfg DmaWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[15]); + [ObservableProperty] public partial EventViewerCategoryCfg DmaRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[14]); + [ObservableProperty] public partial EventViewerCategoryCfg DmaWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[15]); - [Reactive] public EventViewerCategoryCfg InputRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[16]); - [Reactive] public EventViewerCategoryCfg InputWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[17]); + [ObservableProperty] public partial EventViewerCategoryCfg InputRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[16]); + [ObservableProperty] public partial EventViewerCategoryCfg InputWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[17]); - [Reactive] public EventViewerCategoryCfg IrqRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[18]); - [Reactive] public EventViewerCategoryCfg IrqWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[19]); + [ObservableProperty] public partial EventViewerCategoryCfg IrqRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[18]); + [ObservableProperty] public partial EventViewerCategoryCfg IrqWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[19]); - [Reactive] public EventViewerCategoryCfg TimerRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[20]); - [Reactive] public EventViewerCategoryCfg TimerWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[21]); + [ObservableProperty] public partial EventViewerCategoryCfg TimerRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[20]); + [ObservableProperty] public partial EventViewerCategoryCfg TimerWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[21]); - [Reactive] public EventViewerCategoryCfg EepromRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[22]); - [Reactive] public EventViewerCategoryCfg EepromWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[23]); + [ObservableProperty] public partial EventViewerCategoryCfg EepromRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[22]); + [ObservableProperty] public partial EventViewerCategoryCfg EepromWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[23]); - [Reactive] public EventViewerCategoryCfg CartRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[24]); - [Reactive] public EventViewerCategoryCfg CartWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[25]); + [ObservableProperty] public partial EventViewerCategoryCfg CartRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[24]); + [ObservableProperty] public partial EventViewerCategoryCfg CartWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[25]); - [Reactive] public EventViewerCategoryCfg OtherRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[26]); - [Reactive] public EventViewerCategoryCfg OtherWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[27]); + [ObservableProperty] public partial EventViewerCategoryCfg OtherRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[26]); + [ObservableProperty] public partial EventViewerCategoryCfg OtherWrite { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[27]); - [Reactive] public EventViewerCategoryCfg PpuVCounterRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[28]); + [ObservableProperty] public partial EventViewerCategoryCfg PpuVCounterRead { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[28]); - [Reactive] public EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[29]); + [ObservableProperty] public partial EventViewerCategoryCfg Irq { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[29]); - [Reactive] public EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[30]); + [ObservableProperty] public partial EventViewerCategoryCfg MarkedBreakpoints { get; set; } = new EventViewerCategoryCfg(EventViewerColors.Colors[30]); - [Reactive] public bool ShowPreviousFrameEvents { get; set; } = true; + [ObservableProperty] public partial bool ShowPreviousFrameEvents { get; set; } = true; public InteropWsEventViewerConfig ToInterop() { diff --git a/UI/Config/EmulationConfig.cs b/UI/Config/EmulationConfig.cs index 3487c419b..64f8954bc 100644 --- a/UI/Config/EmulationConfig.cs +++ b/UI/Config/EmulationConfig.cs @@ -1,6 +1,5 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using System; using System.Collections.Generic; using System.Linq; @@ -10,13 +9,13 @@ namespace Mesen.Config { - public class EmulationConfig : BaseConfig + public partial class EmulationConfig : BaseConfig { - [Reactive][MinMax(0, 5000)] public UInt32 EmulationSpeed { get; set; } = 100; - [Reactive][MinMax(0, 5000)] public UInt32 TurboSpeed { get; set; } = 300; - [Reactive][MinMax(0, 5000)] public UInt32 RewindSpeed { get; set; } = 100; + [ObservableProperty][MinMax(0, 5000)] public partial UInt32 EmulationSpeed { get; set; } = 100; + [ObservableProperty][MinMax(0, 5000)] public partial UInt32 TurboSpeed { get; set; } = 300; + [ObservableProperty][MinMax(0, 5000)] public partial UInt32 RewindSpeed { get; set; } = 100; - [Reactive][MinMax(0, 10)] public UInt32 RunAheadFrames { get; set; } = 0; + [ObservableProperty][MinMax(0, 10)] public partial UInt32 RunAheadFrames { get; set; } = 0; public void ApplyConfig() { diff --git a/UI/Config/GameConfig.cs b/UI/Config/GameConfig.cs index 5a7c714ee..16c9310e1 100644 --- a/UI/Config/GameConfig.cs +++ b/UI/Config/GameConfig.cs @@ -1,8 +1,7 @@ -using Mesen.Interop; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; @@ -14,12 +13,12 @@ namespace Mesen.Config { - public class GameConfig : BaseConfig + public partial class GameConfig : BaseConfig { - [Reactive] public UInt32 DipSwitches { get; set; } = 0; + [ObservableProperty] public partial UInt32 DipSwitches { get; set; } = 0; - [Reactive] public bool OverrideOverscan { get; set; } = false; - [Reactive] public OverscanConfig Overscan { get; set; } = new(); + [ObservableProperty] public partial bool OverrideOverscan { get; set; } = false; + [ObservableProperty] public partial OverscanConfig Overscan { get; set; } = new(); public void ApplyConfig() { diff --git a/UI/Config/GameboyConfig.cs b/UI/Config/GameboyConfig.cs index 867fc4e98..25ef0534a 100644 --- a/UI/Config/GameboyConfig.cs +++ b/UI/Config/GameboyConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,38 +9,38 @@ namespace Mesen.Config { - public class GameboyConfig : BaseConfig + public partial class GameboyConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - [Reactive] public ControllerConfig Controller { get; set; } = new(); - [Reactive] public ControllerConfig LinkedController { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Controller { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig LinkedController { get; set; } = new(); - [Reactive] public GameboyModel Model { get; set; } = GameboyModel.AutoFavorBest; - [Reactive] public bool UseSgb2 { get; set; } = true; + [ObservableProperty] public partial GameboyModel Model { get; set; } = GameboyModel.AutoFavorBest; + [ObservableProperty] public partial bool UseSgb2 { get; set; } = true; - [Reactive] public bool UseLocalLinkCable { get; set; } = false; - [Reactive] public GbLocalLinkOutputOption LocalLinkCableVideoOutput { get; set; } = GbLocalLinkOutputOption.Both; - [Reactive] public GbLocalLinkOutputOption LocalLinkCableAudioOutput { get; set; } = GbLocalLinkOutputOption.Both; + [ObservableProperty] public partial bool UseLocalLinkCable { get; set; } = false; + [ObservableProperty] public partial GbLocalLinkOutputOption LocalLinkCableVideoOutput { get; set; } = GbLocalLinkOutputOption.Both; + [ObservableProperty] public partial GbLocalLinkOutputOption LocalLinkCableAudioOutput { get; set; } = GbLocalLinkOutputOption.Both; - [Reactive] public bool BlendFrames { get; set; } = true; - [Reactive] public bool GbcAdjustColors { get; set; } = true; + [ObservableProperty] public partial bool BlendFrames { get; set; } = true; + [ObservableProperty] public partial bool GbcAdjustColors { get; set; } = true; - [Reactive] public bool DisableBackground { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; - [Reactive] public bool HideSgbBorders { get; set; } = false; + [ObservableProperty] public partial bool DisableBackground { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool HideSgbBorders { get; set; } = false; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.Random; - [Reactive] public bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.Random; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; - [Reactive] public UInt32[] BgColors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; - [Reactive] public UInt32[] Obj0Colors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; - [Reactive] public UInt32[] Obj1Colors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; + [ObservableProperty] public partial UInt32[] BgColors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; + [ObservableProperty] public partial UInt32[] Obj0Colors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; + [ObservableProperty] public partial UInt32[] Obj1Colors { get; set; } = new UInt32[] { 0xFFFFFFFF, 0xFFB0B0B0, 0xFF686868, 0xFF000000 }; - [Reactive][MinMax(0, 100)] public UInt32 Square1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Square2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 NoiseVol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 WaveVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 NoiseVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 WaveVol { get; set; } = 100; public void ApplyConfig() { diff --git a/UI/Config/GbaConfig.cs b/UI/Config/GbaConfig.cs index 406d3584b..f1cb8d492 100644 --- a/UI/Config/GbaConfig.cs +++ b/UI/Config/GbaConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,36 +9,36 @@ namespace Mesen.Config { - public class GbaConfig : BaseConfig + public partial class GbaConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - - [Reactive] public ControllerConfig Controller { get; set; } = new(); - - [Reactive] public bool SkipBootScreen { get; set; } = false; - [Reactive] public bool DisableFrameSkipping { get; set; } = false; - [Reactive] public bool BlendFrames { get; set; } = true; - [Reactive] public bool GbaAdjustColors { get; set; } = true; - - [Reactive] public bool HideBgLayer1 { get; set; } = false; - [Reactive] public bool HideBgLayer2 { get; set; } = false; - [Reactive] public bool HideBgLayer3 { get; set; } = false; - [Reactive] public bool HideBgLayer4 { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; - - [Reactive][MinMax(0, 1000)] public UInt32 OverclockScanlineCount { get; set; } = 0; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.AllZeros; - [Reactive] public GbaSaveType SaveType { get; set; } = GbaSaveType.AutoDetect; - [Reactive] public GbaRtcType RtcType { get; set; } = GbaRtcType.AutoDetect; - [Reactive] public bool AllowInvalidInput { get; set; } = false; - [Reactive] public bool EnableMgbaLogApi { get; set; } = false; - - [Reactive][MinMax(0, 100)] public UInt32 Square1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Square2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 NoiseVol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 WaveVol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 ChannelAVol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 ChannelBVol { get; set; } = 100; + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + + [ObservableProperty] public partial ControllerConfig Controller { get; set; } = new(); + + [ObservableProperty] public partial bool SkipBootScreen { get; set; } = false; + [ObservableProperty] public partial bool DisableFrameSkipping { get; set; } = false; + [ObservableProperty] public partial bool BlendFrames { get; set; } = true; + [ObservableProperty] public partial bool GbaAdjustColors { get; set; } = true; + + [ObservableProperty] public partial bool HideBgLayer1 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer2 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer3 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer4 { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + + [ObservableProperty][MinMax(0, 1000)] public partial UInt32 OverclockScanlineCount { get; set; } = 0; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.AllZeros; + [ObservableProperty] public partial GbaSaveType SaveType { get; set; } = GbaSaveType.AutoDetect; + [ObservableProperty] public partial GbaRtcType RtcType { get; set; } = GbaRtcType.AutoDetect; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial bool EnableMgbaLogApi { get; set; } = false; + + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 NoiseVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 WaveVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 ChannelAVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 ChannelBVol { get; set; } = 100; public void ApplyConfig() { diff --git a/UI/Config/HdPackBuilderConfig.cs b/UI/Config/HdPackBuilderConfig.cs index 77a0a6a7c..e3949b5df 100644 --- a/UI/Config/HdPackBuilderConfig.cs +++ b/UI/Config/HdPackBuilderConfig.cs @@ -1,11 +1,11 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Runtime.InteropServices; namespace Mesen.Config { - public class HdPackBuilderConfig : BaseConfig + public partial class HdPackBuilderConfig : BaseConfig { public ScaleFilterType FilterType { get; set; } = ScaleFilterType.Prescale; public UInt32 Scale { get; set; } = 1; diff --git a/UI/Config/HistoryViewerConfig.cs b/UI/Config/HistoryViewerConfig.cs index f77d657d3..8a75c4fbe 100644 --- a/UI/Config/HistoryViewerConfig.cs +++ b/UI/Config/HistoryViewerConfig.cs @@ -1,10 +1,10 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Config { - public class HistoryViewerConfig : BaseWindowConfig + public partial class HistoryViewerConfig : BaseWindowConfig { - [Reactive] public int Volume { get; set; } = 100; + [ObservableProperty] public partial int Volume { get; set; } = 100; } } diff --git a/UI/Config/InputConfig.cs b/UI/Config/InputConfig.cs index 3865e807f..5b6c9d92c 100644 --- a/UI/Config/InputConfig.cs +++ b/UI/Config/InputConfig.cs @@ -1,7 +1,6 @@ -using Mesen.Interop; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -11,23 +10,23 @@ namespace Mesen.Config { - public class InputConfig : BaseConfig + public partial class InputConfig : BaseConfig { - [Reactive][MinMax(0, 4)] public UInt32 ControllerDeadzoneSize { get; set; } = 2; - [Reactive][MinMax(0, 9)] public UInt32 MouseSensitivity { get; set; } = 5; - [Reactive] public bool HidePointerForLightGuns { get; set; } = false; - [Reactive][MinMax(0, 10)] public UInt32 ForceFeedbackIntensity { get; set; } = 5; - - [Reactive] public InputDisplayPosition DisplayInputPosition { get; set; } = InputDisplayPosition.BottomRight; - [Reactive] public bool DisplayInputPort1 { get; set; } = false; - [Reactive] public bool DisplayInputPort2 { get; set; } = false; - [Reactive] public bool DisplayInputPort3 { get; set; } = false; - [Reactive] public bool DisplayInputPort4 { get; set; } = false; - [Reactive] public bool DisplayInputPort5 { get; set; } = false; - [Reactive] public bool DisplayInputPort6 { get; set; } = false; - [Reactive] public bool DisplayInputPort7 { get; set; } = false; - [Reactive] public bool DisplayInputPort8 { get; set; } = false; - [Reactive] public bool DisplayInputHorizontally { get; set; } = true; + [ObservableProperty][MinMax(0, 4)] public partial UInt32 ControllerDeadzoneSize { get; set; } = 2; + [ObservableProperty][MinMax(0, 9)] public partial UInt32 MouseSensitivity { get; set; } = 5; + [ObservableProperty] public partial bool HidePointerForLightGuns { get; set; } = false; + [ObservableProperty][MinMax(0, 10)] public partial UInt32 ForceFeedbackIntensity { get; set; } = 5; + + [ObservableProperty] public partial InputDisplayPosition DisplayInputPosition { get; set; } = InputDisplayPosition.BottomRight; + [ObservableProperty] public partial bool DisplayInputPort1 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort2 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort3 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort4 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort5 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort6 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort7 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputPort8 { get; set; } = false; + [ObservableProperty] public partial bool DisplayInputHorizontally { get; set; } = true; public InputConfig() { @@ -53,33 +52,33 @@ public void ApplyConfig() } } - public class KeyMapping : ReactiveObject + public partial class KeyMapping : ObservableObject { - [Reactive] public UInt16 A { get; set; } - [Reactive] public UInt16 B { get; set; } - [Reactive] public UInt16 X { get; set; } - [Reactive] public UInt16 Y { get; set; } - [Reactive] public UInt16 L { get; set; } - [Reactive] public UInt16 R { get; set; } - [Reactive] public UInt16 Up { get; set; } - [Reactive] public UInt16 Down { get; set; } - [Reactive] public UInt16 Left { get; set; } - [Reactive] public UInt16 Right { get; set; } - [Reactive] public UInt16 Start { get; set; } - [Reactive] public UInt16 Select { get; set; } - [Reactive] public UInt16 U { get; set; } - [Reactive] public UInt16 D { get; set; } - - [Reactive] public UInt16 TurboA { get; set; } - [Reactive] public UInt16 TurboB { get; set; } - [Reactive] public UInt16 TurboX { get; set; } - [Reactive] public UInt16 TurboY { get; set; } - [Reactive] public UInt16 TurboL { get; set; } - [Reactive] public UInt16 TurboR { get; set; } - [Reactive] public UInt16 TurboSelect { get; set; } - [Reactive] public UInt16 TurboStart { get; set; } - - [Reactive] public UInt16 GenericKey1 { get; set; } + [ObservableProperty] public partial UInt16 A { get; set; } + [ObservableProperty] public partial UInt16 B { get; set; } + [ObservableProperty] public partial UInt16 X { get; set; } + [ObservableProperty] public partial UInt16 Y { get; set; } + [ObservableProperty] public partial UInt16 L { get; set; } + [ObservableProperty] public partial UInt16 R { get; set; } + [ObservableProperty] public partial UInt16 Up { get; set; } + [ObservableProperty] public partial UInt16 Down { get; set; } + [ObservableProperty] public partial UInt16 Left { get; set; } + [ObservableProperty] public partial UInt16 Right { get; set; } + [ObservableProperty] public partial UInt16 Start { get; set; } + [ObservableProperty] public partial UInt16 Select { get; set; } + [ObservableProperty] public partial UInt16 U { get; set; } + [ObservableProperty] public partial UInt16 D { get; set; } + + [ObservableProperty] public partial UInt16 TurboA { get; set; } + [ObservableProperty] public partial UInt16 TurboB { get; set; } + [ObservableProperty] public partial UInt16 TurboX { get; set; } + [ObservableProperty] public partial UInt16 TurboY { get; set; } + [ObservableProperty] public partial UInt16 TurboL { get; set; } + [ObservableProperty] public partial UInt16 TurboR { get; set; } + [ObservableProperty] public partial UInt16 TurboSelect { get; set; } + [ObservableProperty] public partial UInt16 TurboStart { get; set; } + + [ObservableProperty] public partial UInt16 GenericKey1 { get; set; } public virtual InteropKeyMapping ToInterop(ControllerType type, int mappingIndex) { @@ -199,7 +198,7 @@ public enum KeyPresetType ArrowKeys } - public class ControllerConfig : BaseConfig + public partial class ControllerConfig : BaseConfig { protected KeyMapping _mapping1 = new(); protected KeyMapping _mapping2 = new(); @@ -210,8 +209,8 @@ public class ControllerConfig : BaseConfig public KeyMapping Mapping2 { get => _mapping2; set => _mapping2 = value; } public KeyMapping Mapping3 { get => _mapping3; set => _mapping3 = value; } public KeyMapping Mapping4 { get => _mapping4; set => _mapping4 = value; } - [Reactive] public UInt32 TurboSpeed { get; set; } = 0; - [Reactive] public ControllerType Type { get; set; } = ControllerType.None; + [ObservableProperty] public partial UInt32 TurboSpeed { get; set; } = 0; + [ObservableProperty] public partial ControllerType Type { get; set; } = ControllerType.None; public void InitDefaults(DefaultKeyMappingType defaultMappings, ControllerType type) { diff --git a/UI/Config/IntegrationConfig.cs b/UI/Config/IntegrationConfig.cs index 4e4964863..f53b6b108 100644 --- a/UI/Config/IntegrationConfig.cs +++ b/UI/Config/IntegrationConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,25 +9,25 @@ namespace Mesen.Config { - public class IntegrationConfig : BaseConfig + public partial class IntegrationConfig : BaseConfig { - [Reactive] public bool AutoLoadDbgFiles { get; set; } = true; - [Reactive] public bool AutoLoadMlbFiles { get; set; } = true; - [Reactive] public bool AutoLoadCdlFiles { get; set; } = false; - [Reactive] public bool AutoLoadSymFiles { get; set; } = true; - [Reactive] public bool AutoLoadCdbFiles { get; set; } = true; - [Reactive] public bool AutoLoadElfFiles { get; set; } = true; - [Reactive] public bool AutoLoadFnsFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadDbgFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadMlbFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadCdlFiles { get; set; } = false; + [ObservableProperty] public partial bool AutoLoadSymFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadCdbFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadElfFiles { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadFnsFiles { get; set; } = true; - [Reactive] public bool ResetLabelsOnImport { get; set; } = true; + [ObservableProperty] public partial bool ResetLabelsOnImport { get; set; } = true; - [Reactive] public bool ImportPrgRomLabels { get; set; } = true; - [Reactive] public bool ImportWorkRamLabels { get; set; } = true; - [Reactive] public bool ImportSaveRamLabels { get; set; } = true; - [Reactive] public bool ImportOtherLabels { get; set; } = true; - [Reactive] public bool ImportComments { get; set; } = true; + [ObservableProperty] public partial bool ImportPrgRomLabels { get; set; } = true; + [ObservableProperty] public partial bool ImportWorkRamLabels { get; set; } = true; + [ObservableProperty] public partial bool ImportSaveRamLabels { get; set; } = true; + [ObservableProperty] public partial bool ImportOtherLabels { get; set; } = true; + [ObservableProperty] public partial bool ImportComments { get; set; } = true; - [Reactive] public int TabSize { get; set; } = 4; + [ObservableProperty] public partial int TabSize { get; set; } = 4; public bool IsMemoryTypeImportEnabled(MemoryType memType) { diff --git a/UI/Config/MainWindowConfig.cs b/UI/Config/MainWindowConfig.cs index 5f0b2866d..a998471f6 100644 --- a/UI/Config/MainWindowConfig.cs +++ b/UI/Config/MainWindowConfig.cs @@ -1,9 +1,9 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Config { - public class MainWindowConfig : BaseWindowConfig + public partial class MainWindowConfig : BaseWindowConfig { } } diff --git a/UI/Config/MovieRecordConfig.cs b/UI/Config/MovieRecordConfig.cs index a1c49de39..7f90537e5 100644 --- a/UI/Config/MovieRecordConfig.cs +++ b/UI/Config/MovieRecordConfig.cs @@ -1,12 +1,12 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.Config { - public class MovieRecordConfig : BaseConfig + public partial class MovieRecordConfig : BaseConfig { - [Reactive] public RecordMovieFrom RecordFrom { get; set; } = RecordMovieFrom.CurrentState; - [Reactive] public string Author { get; set; } = ""; - [Reactive] public string Description { get; set; } = ""; + [ObservableProperty] public partial RecordMovieFrom RecordFrom { get; set; } = RecordMovieFrom.CurrentState; + [ObservableProperty] public partial string Author { get; set; } = ""; + [ObservableProperty] public partial string Description { get; set; } = ""; } } diff --git a/UI/Config/NesConfig.cs b/UI/Config/NesConfig.cs index b33bad67e..0f2802ce9 100644 --- a/UI/Config/NesConfig.cs +++ b/UI/Config/NesConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,126 +10,126 @@ namespace Mesen.Config { - public class NesConfig : BaseConfig + public partial class NesConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); //Input - [Reactive] public NesControllerConfig Port1 { get; set; } = new(); - [Reactive] public NesControllerConfig Port2 { get; set; } = new(); - [Reactive] public NesControllerConfig ExpPort { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port1 { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port2 { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig ExpPort { get; set; } = new(); - [Reactive] public NesControllerConfig Port1A { get; set; } = new(); - [Reactive] public NesControllerConfig Port1B { get; set; } = new(); - [Reactive] public NesControllerConfig Port1C { get; set; } = new(); - [Reactive] public NesControllerConfig Port1D { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port1A { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port1B { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port1C { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig Port1D { get; set; } = new(); - [Reactive] public NesControllerConfig ExpPortA { get; set; } = new(); - [Reactive] public NesControllerConfig ExpPortB { get; set; } = new(); - [Reactive] public NesControllerConfig ExpPortC { get; set; } = new(); - [Reactive] public NesControllerConfig ExpPortD { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig ExpPortA { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig ExpPortB { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig ExpPortC { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig ExpPortD { get; set; } = new(); - [Reactive] public NesControllerConfig MapperInput { get; set; } = new(); + [ObservableProperty] public partial NesControllerConfig MapperInput { get; set; } = new(); - [Reactive][MinMax(0, 3)] public UInt32 LightDetectionRadius { get; set; } = 0; - [Reactive] public bool AutoConfigureInput { get; set; } = true; + [ObservableProperty][MinMax(0, 3)] public partial UInt32 LightDetectionRadius { get; set; } = 0; + [ObservableProperty] public partial bool AutoConfigureInput { get; set; } = true; //General [ValidValues(ConsoleRegion.Auto, ConsoleRegion.Ntsc, ConsoleRegion.Pal, ConsoleRegion.Dendy)] - [Reactive] public ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; + [ObservableProperty] public partial ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; - [Reactive] public bool EnableHdPacks { get; set; } = true; - [Reactive] public bool DisableGameDatabase { get; set; } = false; - [Reactive] public bool FdsAutoLoadDisk { get; set; } = true; - [Reactive] public bool FdsFastForwardOnLoad { get; set; } = false; - [Reactive] public bool FdsAutoInsertDisk { get; set; } = false; - [Reactive] public VsDualOutputOption VsDualVideoOutput { get; set; } = VsDualOutputOption.Both; - [Reactive] public VsDualOutputOption VsDualAudioOutput { get; set; } = VsDualOutputOption.Both; + [ObservableProperty] public partial bool EnableHdPacks { get; set; } = true; + [ObservableProperty] public partial bool DisableGameDatabase { get; set; } = false; + [ObservableProperty] public partial bool FdsAutoLoadDisk { get; set; } = true; + [ObservableProperty] public partial bool FdsFastForwardOnLoad { get; set; } = false; + [ObservableProperty] public partial bool FdsAutoInsertDisk { get; set; } = false; + [ObservableProperty] public partial VsDualOutputOption VsDualVideoOutput { get; set; } = VsDualOutputOption.Both; + [ObservableProperty] public partial VsDualOutputOption VsDualAudioOutput { get; set; } = VsDualOutputOption.Both; //Video - [Reactive] public bool DisableSprites { get; set; } = false; - [Reactive] public bool DisableBackground { get; set; } = false; - [Reactive] public bool ForceBackgroundFirstColumn { get; set; } = false; - [Reactive] public bool ForceSpritesFirstColumn { get; set; } = false; - [Reactive] public bool RemoveSpriteLimit { get; set; } = false; - [Reactive] public bool AdaptiveSpriteLimit { get; set; } = false; - [Reactive] public bool EnablePalBorders { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool DisableBackground { get; set; } = false; + [ObservableProperty] public partial bool ForceBackgroundFirstColumn { get; set; } = false; + [ObservableProperty] public partial bool ForceSpritesFirstColumn { get; set; } = false; + [ObservableProperty] public partial bool RemoveSpriteLimit { get; set; } = false; + [ObservableProperty] public partial bool AdaptiveSpriteLimit { get; set; } = false; + [ObservableProperty] public partial bool EnablePalBorders { get; set; } = false; - [Reactive] public bool UseCustomVsPalette { get; set; } = false; + [ObservableProperty] public partial bool UseCustomVsPalette { get; set; } = false; - [Reactive] public OverscanConfig NtscOverscan { get; set; } = new(); - [Reactive] public OverscanConfig PalOverscan { get; set; } = new(); + [ObservableProperty] public partial OverscanConfig NtscOverscan { get; set; } = new(); + [ObservableProperty] public partial OverscanConfig PalOverscan { get; set; } = new(); //Emulation - [Reactive] public bool EnableOamDecay { get; set; } = false; - [Reactive] public bool EnablePpuOamRowCorruption { get; set; } = false; - [Reactive] public bool EnablePpuSpriteEvalBug { get; set; } = false; - [Reactive] public bool DisableOamAddrBug { get; set; } = false; - [Reactive] public bool DisablePaletteRead { get; set; } = false; - [Reactive] public bool DisablePpu2004Reads { get; set; } = false; - [Reactive] public bool EnablePpu2000ScrollGlitch { get; set; } = false; - [Reactive] public bool EnablePpu2006ScrollGlitch { get; set; } = false; - [Reactive] public bool RestrictPpuAccessOnFirstFrame { get; set; } = false; - [Reactive] public bool EnableDmcSampleDuplicationGlitch { get; set; } = false; - [Reactive] public bool EnableCpuTestMode { get; set; } = false; - - [Reactive] public NesConsoleType ConsoleType { get; set; } = NesConsoleType.Nes001; - [Reactive] public bool DisablePpuReset { get; set; } = false; - [Reactive] public bool AllowInvalidInput { get; set; } = false; - [Reactive] public bool DisableGameGenieBusConflicts { get; set; } = false; - [Reactive] public bool DisableFlashSaves { get; set; } = false; - [Reactive] public bool OverwriteOriginalRom { get; set; } = false; - - [Reactive] public bool RandomizeMapperPowerOnState { get; set; } = false; - [Reactive] public bool RandomizeCpuPpuAlignment { get; set; } = false; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.AllZeros; - - [Reactive][MinMax(0, 1000)] public UInt32 PpuExtraScanlinesBeforeNmi { get; set; } = 0; - [Reactive][MinMax(0, 1000)] public UInt32 PpuExtraScanlinesAfterNmi { get; set; } = 0; + [ObservableProperty] public partial bool EnableOamDecay { get; set; } = false; + [ObservableProperty] public partial bool EnablePpuOamRowCorruption { get; set; } = false; + [ObservableProperty] public partial bool EnablePpuSpriteEvalBug { get; set; } = false; + [ObservableProperty] public partial bool DisableOamAddrBug { get; set; } = false; + [ObservableProperty] public partial bool DisablePaletteRead { get; set; } = false; + [ObservableProperty] public partial bool DisablePpu2004Reads { get; set; } = false; + [ObservableProperty] public partial bool EnablePpu2000ScrollGlitch { get; set; } = false; + [ObservableProperty] public partial bool EnablePpu2006ScrollGlitch { get; set; } = false; + [ObservableProperty] public partial bool RestrictPpuAccessOnFirstFrame { get; set; } = false; + [ObservableProperty] public partial bool EnableDmcSampleDuplicationGlitch { get; set; } = false; + [ObservableProperty] public partial bool EnableCpuTestMode { get; set; } = false; + + [ObservableProperty] public partial NesConsoleType ConsoleType { get; set; } = NesConsoleType.Nes001; + [ObservableProperty] public partial bool DisablePpuReset { get; set; } = false; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial bool DisableGameGenieBusConflicts { get; set; } = false; + [ObservableProperty] public partial bool DisableFlashSaves { get; set; } = false; + [ObservableProperty] public partial bool OverwriteOriginalRom { get; set; } = false; + + [ObservableProperty] public partial bool RandomizeMapperPowerOnState { get; set; } = false; + [ObservableProperty] public partial bool RandomizeCpuPpuAlignment { get; set; } = false; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.AllZeros; + + [ObservableProperty][MinMax(0, 1000)] public partial UInt32 PpuExtraScanlinesBeforeNmi { get; set; } = 0; + [ObservableProperty][MinMax(0, 1000)] public partial UInt32 PpuExtraScanlinesAfterNmi { get; set; } = 0; //Audio - [Reactive] public bool DisableNoiseModeFlag { get; set; } = false; - [Reactive] public bool ReduceDmcPopping { get; set; } = false; - [Reactive] public bool SilenceTriangleHighFreq { get; set; } = false; - [Reactive] public bool SwapDutyCycles { get; set; } = false; - [Reactive] public bool ReverseDpcmBitOrder { get; set; } = false; - - [Reactive][MinMax(0, 100)] public UInt32 Square1Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Square2Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 TriangleVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 NoiseVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 DmcVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 FdsVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Mmc5Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Vrc6Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Vrc7Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Namco163Volume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Sunsoft5bVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 EpsmVolume { get; set; } = 100; - - [Reactive][MinMax(-100, 100)] public Int32 Square1Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Square2Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 TrianglePanning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 NoisePanning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 DmcPanning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 FdsPanning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Mmc5Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Vrc6Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Vrc7Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Namco163Panning { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public Int32 Sunsoft5bPanning { get; set; } = 0; - - [Reactive] public StereoFilter StereoFilter { get; set; } = StereoFilter.None; - [Reactive][MinMax(0, 100)] public Int32 StereoDelay { get; set; } = 15; - [Reactive][MinMax(-180, 180)] public Int32 StereoPanningAngle { get; set; } = 15; - [Reactive][MinMax(1, 100)] public Int32 StereoCombFilterDelay { get; set; } = 5; - [Reactive][MinMax(1, 200)] public Int32 StereoCombFilterStrength { get; set; } = 100; + [ObservableProperty] public partial bool DisableNoiseModeFlag { get; set; } = false; + [ObservableProperty] public partial bool ReduceDmcPopping { get; set; } = false; + [ObservableProperty] public partial bool SilenceTriangleHighFreq { get; set; } = false; + [ObservableProperty] public partial bool SwapDutyCycles { get; set; } = false; + [ObservableProperty] public partial bool ReverseDpcmBitOrder { get; set; } = false; + + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square1Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Square2Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 TriangleVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 NoiseVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 DmcVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 FdsVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Mmc5Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Vrc6Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Vrc7Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Namco163Volume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Sunsoft5bVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 EpsmVolume { get; set; } = 100; + + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Square1Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Square2Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 TrianglePanning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 NoisePanning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 DmcPanning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 FdsPanning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Mmc5Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Vrc6Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Vrc7Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Namco163Panning { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial Int32 Sunsoft5bPanning { get; set; } = 0; + + [ObservableProperty] public partial StereoFilter StereoFilter { get; set; } = StereoFilter.None; + [ObservableProperty][MinMax(0, 100)] public partial Int32 StereoDelay { get; set; } = 15; + [ObservableProperty][MinMax(-180, 180)] public partial Int32 StereoPanningAngle { get; set; } = 15; + [ObservableProperty][MinMax(1, 100)] public partial Int32 StereoCombFilterDelay { get; set; } = 5; + [ObservableProperty][MinMax(1, 200)] public partial Int32 StereoCombFilterStrength { get; set; } = 100; //Misc - [Reactive] public bool BreakOnCrash { get; set; } = false; + [ObservableProperty] public partial bool BreakOnCrash { get; set; } = false; - [Reactive] public Int32 InputScanline { get; set; } = 241; - [Reactive] public UInt32[] UserPalette { get; set; } = new UInt32[64] { 0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E, 0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800, 0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE, 0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00, 0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF, 0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22, 0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE, 0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF, 0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5, 0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC, 0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000 }; + [ObservableProperty] public partial Int32 InputScanline { get; set; } = 241; + [ObservableProperty] public partial UInt32[] UserPalette { get; set; } = new UInt32[64] { 0xFF666666, 0xFF002A88, 0xFF1412A7, 0xFF3B00A4, 0xFF5C007E, 0xFF6E0040, 0xFF6C0600, 0xFF561D00, 0xFF333500, 0xFF0B4800, 0xFF005200, 0xFF004F08, 0xFF00404D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFADADAD, 0xFF155FD9, 0xFF4240FF, 0xFF7527FE, 0xFFA01ACC, 0xFFB71E7B, 0xFFB53120, 0xFF994E00, 0xFF6B6D00, 0xFF388700, 0xFF0C9300, 0xFF008F32, 0xFF007C8D, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFF64B0FF, 0xFF9290FF, 0xFFC676FF, 0xFFF36AFF, 0xFFFE6ECC, 0xFFFE8170, 0xFFEA9E22, 0xFFBCBE00, 0xFF88D800, 0xFF5CE430, 0xFF45E082, 0xFF48CDDE, 0xFF4F4F4F, 0xFF000000, 0xFF000000, 0xFFFFFEFF, 0xFFC0DFFF, 0xFFD3D2FF, 0xFFE8C8FF, 0xFFFBC2FF, 0xFFFEC4EA, 0xFFFECCC5, 0xFFF7D8A5, 0xFFE4E594, 0xFFCFEF96, 0xFFBDF4AB, 0xFFB3F3CC, 0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000 }; public void ApplyConfig() { diff --git a/UI/Config/NetplayConfig.cs b/UI/Config/NetplayConfig.cs index 109068bac..b239df277 100644 --- a/UI/Config/NetplayConfig.cs +++ b/UI/Config/NetplayConfig.cs @@ -1,15 +1,15 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Config { - public class NetplayConfig : BaseConfig + public partial class NetplayConfig : BaseConfig { - [Reactive] public string Host { get; set; } = "localhost"; - [Reactive] public UInt16 Port { get; set; } = 8888; - [Reactive] public string Password { get; set; } = ""; + [ObservableProperty] public partial string Host { get; set; } = "localhost"; + [ObservableProperty] public partial UInt16 Port { get; set; } = 8888; + [ObservableProperty] public partial string Password { get; set; } = ""; - [Reactive] public UInt16 ServerPort { get; set; } = 8888; - [Reactive] public string ServerPassword { get; set; } = ""; + [ObservableProperty] public partial UInt16 ServerPort { get; set; } = 8888; + [ObservableProperty] public partial string ServerPassword { get; set; } = ""; } } diff --git a/UI/Config/OverscanConfig.cs b/UI/Config/OverscanConfig.cs index a0412c8b7..d33216f07 100644 --- a/UI/Config/OverscanConfig.cs +++ b/UI/Config/OverscanConfig.cs @@ -1,8 +1,7 @@ -using Mesen.Interop; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; @@ -14,12 +13,12 @@ namespace Mesen.Config { - public class OverscanConfig : BaseConfig + public partial class OverscanConfig : BaseConfig { - [Reactive][MinMax(0, 100)] public UInt32 Left { get; set; } = 0; - [Reactive][MinMax(0, 100)] public UInt32 Right { get; set; } = 0; - [Reactive][MinMax(0, 95)] public UInt32 Top { get; set; } = 0; - [Reactive][MinMax(0, 95)] public UInt32 Bottom { get; set; } = 0; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Left { get; set; } = 0; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Right { get; set; } = 0; + [ObservableProperty][MinMax(0, 95)] public partial UInt32 Top { get; set; } = 0; + [ObservableProperty][MinMax(0, 95)] public partial UInt32 Bottom { get; set; } = 0; public InteropOverscanDimensions ToInterop() { diff --git a/UI/Config/PcEngineConfig.cs b/UI/Config/PcEngineConfig.cs index d9f6aee86..7046ce5c4 100644 --- a/UI/Config/PcEngineConfig.cs +++ b/UI/Config/PcEngineConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -10,52 +10,52 @@ namespace Mesen.Config { - public class PcEngineConfig : BaseConfig + public partial class PcEngineConfig : BaseConfig { public static readonly ReadOnlyCollection DefaultPalette = Array.AsReadOnly(new UInt32[512] { 0xFF000000, 0xFF000016, 0xFF040235, 0xFF01004B, 0xFF07046A, 0xFF050180, 0xFF0B069F, 0xFF0903B5, 0xFF1A0003, 0xFF200521, 0xFF1E0237, 0xFF240756, 0xFF22046C, 0xFF28098B, 0xFF2506A1, 0xFF2B0BC0, 0xFF3D080D, 0xFF3B0524, 0xFF400A42, 0xFF3E0759, 0xFF440C77, 0xFF42098D, 0xFF480EAC, 0xFF450BC2, 0xFF570910, 0xFF550526, 0xFF5B0A45, 0xFF59075B, 0xFF5E0C7A, 0xFF5C0990, 0xFF620EAF, 0xFF600BC5, 0xFF720913, 0xFF770E31, 0xFF750B48, 0xFF7B1066, 0xFF790C7C, 0xFF7F119B, 0xFF7C0EB1, 0xFF8213D0, 0xFF94111E, 0xFF920E34, 0xFF981352, 0xFF951069, 0xFF9B1587, 0xFF99129E, 0xFF9F17BC, 0xFF9D13D2, 0xFFAE1120, 0xFFAC0E36, 0xFFB21355, 0xFFB0106B, 0xFFB6158A, 0xFFB312A0, 0xFFB917BF, 0xFFB714D5, 0xFFC91123, 0xFFCF1641, 0xFFCC1358, 0xFFD21876, 0xFFD0158C, 0xFFD61AAB, 0xFFD417C1, 0xFFDA1CE0, 0xFF092408, 0xFF07211E, 0xFF0D263D, 0xFF0A2353, 0xFF102872, 0xFF0E2588, 0xFF142AA7, 0xFF1127BD, 0xFF23240B, 0xFF212121, 0xFF27263F, 0xFF252356, 0xFF2A2874, 0xFF28258B, 0xFF2E2AA9, 0xFF2C27BF, 0xFF3E240D, 0xFF43292C, 0xFF412642, 0xFF472B61, 0xFF452877, 0xFF4B2D95, 0xFF482AAC, 0xFF4E2FCA, 0xFF602C18, 0xFF5E292E, 0xFF642E4D, 0xFF612B63, 0xFF673082, 0xFF652D98, 0xFF6B32B7, 0xFF692FCD, 0xFF7A2D1B, 0xFF782931, 0xFF7E2E50, 0xFF7C2B66, 0xFF823084, 0xFF7F2D9B, 0xFF8532B9, 0xFF832FD0, 0xFF952D1D, 0xFF9B323C, 0xFF982F52, 0xFF9E3471, 0xFF9C3087, 0xFFA236A6, 0xFFA032BC, 0xFFA637DA, 0xFFB73528, 0xFFB5323E, 0xFFBB375D, 0xFFB93473, 0xFFBF3992, 0xFFBC36A8, 0xFFC23BC7, 0xFFC038DD, 0xFFD2352B, 0xFFCF3241, 0xFFD53760, 0xFFD33476, 0xFFD93994, 0xFFD736AB, 0xFFDC3BC9, 0xFFDA38E0, 0xFF0A4008, 0xFF0F4526, 0xFF0D423D, 0xFF13475B, 0xFF114471, 0xFF174990, 0xFF1445A6, 0xFF1A4AC5, 0xFF2C4813, 0xFF2A4529, 0xFF304A47, 0xFF2D475E, 0xFF334C7C, 0xFF314993, 0xFF2F46A9, 0xFF354BC7, 0xFF464815, 0xFF44452B, 0xFF4A4A4A, 0xFF484760, 0xFF4E4C7F, 0xFF4B4995, 0xFF514EB4, 0xFF4F4BCA, 0xFF614818, 0xFF674D36, 0xFF644A4D, 0xFF6A4F6B, 0xFF684C81, 0xFF6E51A0, 0xFF6C4EB6, 0xFF7253D5, 0xFF835123, 0xFF814D39, 0xFF875257, 0xFF854F6E, 0xFF8B548C, 0xFF8851A3, 0xFF864EB9, 0xFF8C53D7, 0xFF9E5125, 0xFF9B4D3C, 0xFFA1535A, 0xFF9F4F70, 0xFFA5548F, 0xFFA351A5, 0xFFA856C4, 0xFFA653DA, 0xFFB85128, 0xFFBE5646, 0xFFBC535D, 0xFFC1587B, 0xFFBF5592, 0xFFC55AB0, 0xFFC356C6, 0xFFC95CE5, 0xFFDA5933, 0xFFD85649, 0xFFDE5B68, 0xFFDC587E, 0xFFD95594, 0xFFDF5AB3, 0xFFDD57C9, 0xFFE35CE8, 0xFF126410, 0xFF106126, 0xFF166645, 0xFF14625B, 0xFF1A6779, 0xFF176490, 0xFF1D69AE, 0xFF1B66C5, 0xFF2D6412, 0xFF336931, 0xFF306647, 0xFF366B66, 0xFF34687C, 0xFF3A6D9B, 0xFF3869B1, 0xFF3E6FCF, 0xFF476415, 0xFF4D6933, 0xFF4B664A, 0xFF516B68, 0xFF4E687F, 0xFF546D9D, 0xFF526AB3, 0xFF586FD2, 0xFF6A6C20, 0xFF676936, 0xFF6D6E55, 0xFF6B6B6B, 0xFF717089, 0xFF6F6DA0, 0xFF7472BE, 0xFF726FD5, 0xFF846C22, 0xFF8A7141, 0xFF886E57, 0xFF8D7376, 0xFF8B708C, 0xFF9175AB, 0xFF8F72C1, 0xFF9577DF, 0xFF9E6C25, 0xFFA47144, 0xFFA26E5A, 0xFFA87378, 0xFFA6708F, 0xFFAB75AD, 0xFFA972C4, 0xFFAF77E2, 0xFFC17530, 0xFFBE7246, 0xFFC47765, 0xFFC2737B, 0xFFC8799A, 0xFFC675B0, 0xFFCC7ACE, 0xFFC977E5, 0xFFDB7532, 0xFFE17A51, 0xFFDF7767, 0xFFE57C86, 0xFFE2799C, 0xFFE87EBB, 0xFFE67BD1, 0xFFEC80F0, 0xFF137F0F, 0xFF19842E, 0xFF178144, 0xFF1D8663, 0xFF1A8379, 0xFF208898, 0xFF1E85AE, 0xFF248ACD, 0xFF36881A, 0xFF338531, 0xFF398A4F, 0xFF378665, 0xFF3D8C84, 0xFF3B889A, 0xFF418DB9, 0xFF3E8ACF, 0xFF50881D, 0xFF568D3B, 0xFF548A52, 0xFF598F70, 0xFF578C87, 0xFF5D91A5, 0xFF5B8EBB, 0xFF6193DA, 0xFF6A8820, 0xFF708D3E, 0xFF6E8A54, 0xFF748F73, 0xFF728C89, 0xFF7791A8, 0xFF758EBE, 0xFF7B93DD, 0xFF8D902A, 0xFF8B8D41, 0xFF90925F, 0xFF8E8F76, 0xFF949494, 0xFF9291AA, 0xFF9896C9, 0xFF9593DF, 0xFFA7902D, 0xFFAD954C, 0xFFAB9262, 0xFFB19780, 0xFFAE9497, 0xFFB499B5, 0xFFB296CC, 0xFFB89BEA, 0xFFC19030, 0xFFC7964E, 0xFFC59264, 0xFFCB9783, 0xFFC99499, 0xFFCF99B8, 0xFFCC96CE, 0xFFD29BED, 0xFFE4993A, 0xFFE29651, 0xFFE89B6F, 0xFFE59886, 0xFFEB9DA4, 0xFFE999BA, 0xFFEF9ED9, 0xFFED9BEF, 0xFF1CA317, 0xFF22A836, 0xFF20A54C, 0xFF26AA6B, 0xFF23A781, 0xFF29ACA0, 0xFF27A9B6, 0xFF25A6CC, 0xFF36A31A, 0xFF3CA939, 0xFF3AA54F, 0xFF40AA6D, 0xFF3EA784, 0xFF43ACA2, 0xFF41A9B9, 0xFF47AED7, 0xFF59AC25, 0xFF57A93B, 0xFF5CAE5A, 0xFF5AAB70, 0xFF60B08F, 0xFF5EACA5, 0xFF64B2C3, 0xFF61AEDA, 0xFF73AC28, 0xFF79B146, 0xFF77AE5C, 0xFF7DB37B, 0xFF7AB091, 0xFF78ADA8, 0xFF7EB2C6, 0xFF7CAEDC, 0xFF8DAC2A, 0xFF93B149, 0xFF91AE5F, 0xFF97B37E, 0xFF95B094, 0xFF9BB5B2, 0xFF98B2C9, 0xFF9EB7E7, 0xFFB0B435, 0xFFAEB14B, 0xFFB4B66A, 0xFFB1B380, 0xFFB7B89F, 0xFFB5B5B5, 0xFFBBBAD4, 0xFFB9B7EA, 0xFFCAB438, 0xFFD0B956, 0xFFCEB66C, 0xFFD4BB8B, 0xFFD2B8A1, 0xFFCFB5B8, 0xFFD5BAD6, 0xFFD3B7EC, 0xFFE5B53A, 0xFFEBBA59, 0xFFE8B66F, 0xFFEEBB8E, 0xFFECB8A4, 0xFFF2BDC2, 0xFFF0BAD9, 0xFFF5BFF7, 0xFF25C71F, 0xFF23C436, 0xFF28C954, 0xFF26C66B, 0xFF2CCB89, 0xFF2AC89F, 0xFF30CDBE, 0xFF2DCAD4, 0xFF3FC722, 0xFF3DC438, 0xFF43C957, 0xFF40C66D, 0xFF46CB8C, 0xFF44C8A2, 0xFF4ACDC1, 0xFF48CAD7, 0xFF59C825, 0xFF5FCD43, 0xFF5DC959, 0xFF63CF78, 0xFF61CB8E, 0xFF67D0AD, 0xFF64CDC3, 0xFF6AD2E2, 0xFF7CD02F, 0xFF7ACD46, 0xFF80D264, 0xFF7DCF7B, 0xFF83D499, 0xFF81D1AF, 0xFF87D6CE, 0xFF85D2E4, 0xFF96D032, 0xFF94CD48, 0xFF9AD267, 0xFF98CF7D, 0xFF9ED49C, 0xFF9BD1B2, 0xFFA1D6D1, 0xFF9FD3E7, 0xFFB1D035, 0xFFB7D553, 0xFFB4D26A, 0xFFBAD788, 0xFFB8D49E, 0xFFBED9BD, 0xFFBCD6D3, 0xFFC1DBF2, 0xFFD3D840, 0xFFD1D556, 0xFFD7DA74, 0xFFD5D78B, 0xFFDADCA9, 0xFFD8D9C0, 0xFFDEDEDE, 0xFFDCDBF4, 0xFFEED842, 0xFFEBD558, 0xFFF1DA77, 0xFFEFD78D, 0xFFF5DCAC, 0xFFF2D9C2, 0xFFF8DEE1, 0xFFF6DBF7, 0xFF25E31F, 0xFF2BE83E, 0xFF29E554, 0xFF2FEA73, 0xFF2DE789, 0xFF33ECA7, 0xFF30E9BE, 0xFF36EEDC, 0xFF48EB2A, 0xFF46E840, 0xFF4CED5F, 0xFF49EA75, 0xFF4FEF94, 0xFF4DECAA, 0xFF53F1C9, 0xFF51EEDF, 0xFF62EC2D, 0xFF60E843, 0xFF66ED61, 0xFF64EA78, 0xFF6AEF96, 0xFF67ECAD, 0xFF6DF1CB, 0xFF6BEEE1, 0xFF7DEC2F, 0xFF83F14E, 0xFF80EE64, 0xFF86F383, 0xFF84EF99, 0xFF8AF4B7, 0xFF88F1CE, 0xFF8DF6EC, 0xFF9FF43A, 0xFF9DF150, 0xFFA3F66F, 0xFFA1F385, 0xFFA6F8A4, 0xFFA4F5BA, 0xFFAAFAD9, 0xFFA8F6EF, 0xFFBAF43D, 0xFFB7F153, 0xFFBDF672, 0xFFBBF388, 0xFFC1F8A6, 0xFFBFF5BD, 0xFFC4FADB, 0xFFC2F7F2, 0xFFD4F43F, 0xFFDAF95E, 0xFFD7F674, 0xFFDDFB93, 0xFFDBF8A9, 0xFFE1FDC8, 0xFFDFFADE, 0xFFE5FFFC, 0xFFF6FC4A, 0xFFF4F960, 0xFFFAFE7F, 0xFFF8FB95, 0xFFFEFFB4, 0xFFFBFDCA, 0xFFFFFFE9, 0xFFFFFFFF }); - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - [Reactive] public ControllerConfig Port1 { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1 { get; set; } = new(); - [Reactive] public ControllerConfig Port1A { get; set; } = new(); - [Reactive] public ControllerConfig Port1B { get; set; } = new(); - [Reactive] public ControllerConfig Port1C { get; set; } = new(); - [Reactive] public ControllerConfig Port1D { get; set; } = new(); - [Reactive] public ControllerConfig Port1E { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1A { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1B { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1C { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1D { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig Port1E { get; set; } = new(); - [Reactive] public bool AllowInvalidInput { get; set; } = false; - [Reactive] public bool PreventSelectRunReset { get; set; } = true; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial bool PreventSelectRunReset { get; set; } = true; - [Reactive] public PceConsoleType ConsoleType { get; set; } = PceConsoleType.Auto; - [Reactive] public PceCdRomType CdRomType { get; set; } = PceCdRomType.Arcade; - [Reactive] public bool EnableCdRomForHuCardGames { get; set; } = false; - [Reactive] public bool DisableCdRomSaveRamForHuCardGames { get; set; } = false; + [ObservableProperty] public partial PceConsoleType ConsoleType { get; set; } = PceConsoleType.Auto; + [ObservableProperty] public partial PceCdRomType CdRomType { get; set; } = PceCdRomType.Arcade; + [ObservableProperty] public partial bool EnableCdRomForHuCardGames { get; set; } = false; + [ObservableProperty] public partial bool DisableCdRomSaveRamForHuCardGames { get; set; } = false; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.Random; - [Reactive] public bool EnableRandomPowerOnState { get; set; } = false; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.Random; + [ObservableProperty] public partial bool EnableRandomPowerOnState { get; set; } = false; - [Reactive][MinMax(0, 100)] public UInt32 Channel1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel3Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel4Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel5Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel6Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 CdAudioVolume { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 AdpcmVolume { get; set; } = 100; - [Reactive] public bool UseHuC6280aAudio { get; set; } = true; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel3Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel4Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel5Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel6Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 CdAudioVolume { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 AdpcmVolume { get; set; } = 100; + [ObservableProperty] public partial bool UseHuC6280aAudio { get; set; } = true; - [Reactive] public bool RemoveSpriteLimit { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; - [Reactive] public bool DisableSpritesVdc2 { get; set; } = false; - [Reactive] public bool DisableBackground { get; set; } = false; - [Reactive] public bool DisableBackgroundVdc2 { get; set; } = false; - [Reactive] public bool DisableFrameSkipping { get; set; } = false; - [Reactive] public bool ForceFixedResolution { get; set; } = false; + [ObservableProperty] public partial bool RemoveSpriteLimit { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool DisableSpritesVdc2 { get; set; } = false; + [ObservableProperty] public partial bool DisableBackground { get; set; } = false; + [ObservableProperty] public partial bool DisableBackgroundVdc2 { get; set; } = false; + [ObservableProperty] public partial bool DisableFrameSkipping { get; set; } = false; + [ObservableProperty] public partial bool ForceFixedResolution { get; set; } = false; - [Reactive] public OverscanConfig Overscan { get; set; } = new() { Top = 3, Left = 18, Right = 18 }; + [ObservableProperty] public partial OverscanConfig Overscan { get; set; } = new() { Top = 3, Left = 18, Right = 18 }; - [Reactive] public UInt32[] Palette { get; set; } = PcEngineConfig.DefaultPalette.ToArray(); + [ObservableProperty] public partial UInt32[] Palette { get; set; } = PcEngineConfig.DefaultPalette.ToArray(); public void ApplyConfig() { diff --git a/UI/Config/PreferencesConfig.cs b/UI/Config/PreferencesConfig.cs index 67476acc3..2a3c7deb3 100644 --- a/UI/Config/PreferencesConfig.cs +++ b/UI/Config/PreferencesConfig.cs @@ -8,7 +8,7 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -19,77 +19,77 @@ namespace Mesen.Config { - public class PreferencesConfig : BaseConfig + public partial class PreferencesConfig : BaseConfig { - [Reactive] public MesenTheme Theme { get; set; } = MesenTheme.Light; - [Reactive] public bool AutomaticallyCheckForUpdates { get; set; } = true; - [Reactive] public bool SingleInstance { get; set; } = true; - [Reactive] public bool AutoLoadPatches { get; set; } = true; - - [Reactive] public bool PauseWhenInBackground { get; set; } = false; - [Reactive] public bool PauseWhenInMenusAndConfig { get; set; } = false; - [Reactive] public bool AllowBackgroundInput { get; set; } = false; - [Reactive] public bool PauseOnMovieEnd { get; set; } = true; - [Reactive] public bool ShowMovieIcons { get; set; } = true; - [Reactive] public bool ShowTurboRewindIcons { get; set; } = true; - [Reactive] public bool ConfirmExitResetPower { get; set; } = false; - - [Reactive] public bool AssociateSnesRomFiles { get; set; } = false; - [Reactive] public bool AssociateSnesMusicFiles { get; set; } = false; - [Reactive] public bool AssociateNesRomFiles { get; set; } = false; - [Reactive] public bool AssociateNesMusicFiles { get; set; } = false; - [Reactive] public bool AssociateGbRomFiles { get; set; } = false; - [Reactive] public bool AssociateGbMusicFiles { get; set; } = false; - [Reactive] public bool AssociateGbaRomFiles { get; set; } = false; - [Reactive] public bool AssociatePceRomFiles { get; set; } = false; - [Reactive] public bool AssociatePceMusicFiles { get; set; } = false; - [Reactive] public bool AssociateSmsRomFiles { get; set; } = false; - [Reactive] public bool AssociateGameGearRomFiles { get; set; } = false; - [Reactive] public bool AssociateSgRomFiles { get; set; } = false; - [Reactive] public bool AssociateCvRomFiles { get; set; } = false; - [Reactive] public bool AssociateWsRomFiles { get; set; } = false; - - [Reactive] public bool EnableAutoSaveState { get; set; } = true; - [Reactive] public UInt32 AutoSaveStateDelay { get; set; } = 5; - - [Reactive] public bool EnableRewind { get; set; } = true; - [Reactive] public UInt32 RewindBufferSize { get; set; } = 300; - - [Reactive] public bool AlwaysOnTop { get; set; } = false; - - [Reactive] public bool AutoHideMenu { get; set; } = false; - - [Reactive] public bool ShowFps { get; set; } = false; - [Reactive] public bool ShowFrameCounter { get; set; } = false; - [Reactive] public bool ShowGameTimer { get; set; } = false; - [Reactive] public bool ShowLagCounter { get; set; } = false; - [Reactive] public bool ShowTitleBarInfo { get; set; } = false; - [Reactive] public bool ShowDebugInfo { get; set; } = false; - [Reactive] public bool DisableOsd { get; set; } = false; - [Reactive] public HudDisplaySize HudSize { get; set; } = HudDisplaySize.Fixed; - [Reactive] public GameSelectionMode GameSelectionScreenMode { get; set; } = GameSelectionMode.ResumeState; - - [Reactive] public FontAntialiasing FontAntialiasing { get; set; } = FontAntialiasing.SubPixelAntialias; - [Reactive] public FontConfig MesenFont { get; set; } = new FontConfig() { FontFamily = "Microsoft Sans Serif", FontSize = 11 }; - [Reactive] public FontConfig MesenMenuFont { get; set; } = new FontConfig() { FontFamily = "Segoe UI", FontSize = 12 }; - - [Reactive] public List ShortcutKeys { get; set; } = new List(); - - [Reactive] public bool OverrideGameFolder { get; set; } = false; - [Reactive] public bool OverrideAviFolder { get; set; } = false; - [Reactive] public bool OverrideMovieFolder { get; set; } = false; - [Reactive] public bool OverrideSaveDataFolder { get; set; } = false; - [Reactive] public bool OverrideSaveStateFolder { get; set; } = false; - [Reactive] public bool OverrideScreenshotFolder { get; set; } = false; - [Reactive] public bool OverrideWaveFolder { get; set; } = false; - - [Reactive] public string GameFolder { get; set; } = ""; - [Reactive] public string AviFolder { get; set; } = ""; - [Reactive] public string MovieFolder { get; set; } = ""; - [Reactive] public string SaveDataFolder { get; set; } = ""; - [Reactive] public string SaveStateFolder { get; set; } = ""; - [Reactive] public string ScreenshotFolder { get; set; } = ""; - [Reactive] public string WaveFolder { get; set; } = ""; + [ObservableProperty] public partial MesenTheme Theme { get; set; } = MesenTheme.Light; + [ObservableProperty] public partial bool AutomaticallyCheckForUpdates { get; set; } = true; + [ObservableProperty] public partial bool SingleInstance { get; set; } = true; + [ObservableProperty] public partial bool AutoLoadPatches { get; set; } = true; + + [ObservableProperty] public partial bool PauseWhenInBackground { get; set; } = false; + [ObservableProperty] public partial bool PauseWhenInMenusAndConfig { get; set; } = false; + [ObservableProperty] public partial bool AllowBackgroundInput { get; set; } = false; + [ObservableProperty] public partial bool PauseOnMovieEnd { get; set; } = true; + [ObservableProperty] public partial bool ShowMovieIcons { get; set; } = true; + [ObservableProperty] public partial bool ShowTurboRewindIcons { get; set; } = true; + [ObservableProperty] public partial bool ConfirmExitResetPower { get; set; } = false; + + [ObservableProperty] public partial bool AssociateSnesRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateSnesMusicFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateNesRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateNesMusicFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateGbRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateGbMusicFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateGbaRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociatePceRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociatePceMusicFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateSmsRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateGameGearRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateSgRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateCvRomFiles { get; set; } = false; + [ObservableProperty] public partial bool AssociateWsRomFiles { get; set; } = false; + + [ObservableProperty] public partial bool EnableAutoSaveState { get; set; } = true; + [ObservableProperty] public partial UInt32 AutoSaveStateDelay { get; set; } = 5; + + [ObservableProperty] public partial bool EnableRewind { get; set; } = true; + [ObservableProperty] public partial UInt32 RewindBufferSize { get; set; } = 300; + + [ObservableProperty] public partial bool AlwaysOnTop { get; set; } = false; + + [ObservableProperty] public partial bool AutoHideMenu { get; set; } = false; + + [ObservableProperty] public partial bool ShowFps { get; set; } = false; + [ObservableProperty] public partial bool ShowFrameCounter { get; set; } = false; + [ObservableProperty] public partial bool ShowGameTimer { get; set; } = false; + [ObservableProperty] public partial bool ShowLagCounter { get; set; } = false; + [ObservableProperty] public partial bool ShowTitleBarInfo { get; set; } = false; + [ObservableProperty] public partial bool ShowDebugInfo { get; set; } = false; + [ObservableProperty] public partial bool DisableOsd { get; set; } = false; + [ObservableProperty] public partial HudDisplaySize HudSize { get; set; } = HudDisplaySize.Fixed; + [ObservableProperty] public partial GameSelectionMode GameSelectionScreenMode { get; set; } = GameSelectionMode.ResumeState; + + [ObservableProperty] public partial FontAntialiasing FontAntialiasing { get; set; } = FontAntialiasing.SubPixelAntialias; + [ObservableProperty] public partial FontConfig MesenFont { get; set; } = new FontConfig() { FontFamily = "Microsoft Sans Serif", FontSize = 11 }; + [ObservableProperty] public partial FontConfig MesenMenuFont { get; set; } = new FontConfig() { FontFamily = "Segoe UI", FontSize = 12 }; + + [ObservableProperty] public partial List ShortcutKeys { get; set; } = new List(); + + [ObservableProperty] public partial bool OverrideGameFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideAviFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideMovieFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideSaveDataFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideSaveStateFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideScreenshotFolder { get; set; } = false; + [ObservableProperty] public partial bool OverrideWaveFolder { get; set; } = false; + + [ObservableProperty] public partial string GameFolder { get; set; } = ""; + [ObservableProperty] public partial string AviFolder { get; set; } = ""; + [ObservableProperty] public partial string MovieFolder { get; set; } = ""; + [ObservableProperty] public partial string SaveDataFolder { get; set; } = ""; + [ObservableProperty] public partial string SaveStateFolder { get; set; } = ""; + [ObservableProperty] public partial string ScreenshotFolder { get; set; } = ""; + [ObservableProperty] public partial string WaveFolder { get; set; } = ""; public PreferencesConfig() { diff --git a/UI/Config/Shortcuts/ShortcutKeyInfo.cs b/UI/Config/Shortcuts/ShortcutKeyInfo.cs index 933083ae5..75526b1d0 100644 --- a/UI/Config/Shortcuts/ShortcutKeyInfo.cs +++ b/UI/Config/Shortcuts/ShortcutKeyInfo.cs @@ -1,5 +1,4 @@ -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,10 +8,10 @@ namespace Mesen.Config.Shortcuts { - public class ShortcutKeyInfo : ReactiveObject + public partial class ShortcutKeyInfo : ObservableObject { - [Reactive] public EmulatorShortcut Shortcut { get; set; } - [Reactive] public KeyCombination KeyCombination { get; set; } = new KeyCombination(); - [Reactive] public KeyCombination KeyCombination2 { get; set; } = new KeyCombination(); + [ObservableProperty] public partial EmulatorShortcut Shortcut { get; set; } + [ObservableProperty] public partial KeyCombination KeyCombination { get; set; } = new KeyCombination(); + [ObservableProperty] public partial KeyCombination KeyCombination2 { get; set; } = new KeyCombination(); } } diff --git a/UI/Config/SmsConfig.cs b/UI/Config/SmsConfig.cs index 4f7ebfaec..790422c36 100644 --- a/UI/Config/SmsConfig.cs +++ b/UI/Config/SmsConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -11,42 +11,42 @@ namespace Mesen.Config; -public class SmsConfig : BaseConfig +public partial class SmsConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - [Reactive] public ConsoleOverrideConfig GgConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig GgConfigOverrides { get; set; } = new(); - [Reactive] public SmsControllerConfig Port1 { get; set; } = new(); - [Reactive] public SmsControllerConfig Port2 { get; set; } = new(); + [ObservableProperty] public partial SmsControllerConfig Port1 { get; set; } = new(); + [ObservableProperty] public partial SmsControllerConfig Port2 { get; set; } = new(); - [Reactive] public bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; [ValidValues(ConsoleRegion.Auto, ConsoleRegion.Ntsc, ConsoleRegion.Pal)] - [Reactive] public ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; + [ObservableProperty] public partial ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; [ValidValues(ConsoleRegion.Auto, ConsoleRegion.Ntsc, ConsoleRegion.NtscJapan, ConsoleRegion.Pal)] - [Reactive] public ConsoleRegion GameGearRegion { get; set; } = ConsoleRegion.Auto; + [ObservableProperty] public partial ConsoleRegion GameGearRegion { get; set; } = ConsoleRegion.Auto; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.Random; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.Random; - [Reactive] public SmsRevision Revision { get; set; } = SmsRevision.Compatibility; + [ObservableProperty] public partial SmsRevision Revision { get; set; } = SmsRevision.Compatibility; - [Reactive] public bool UseSgPalette { get; set; } = true; - [Reactive] public bool GgBlendFrames { get; set; } = true; - [Reactive] public bool RemoveSpriteLimit { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; - [Reactive] public bool DisableBackground { get; set; } = false; + [ObservableProperty] public partial bool UseSgPalette { get; set; } = true; + [ObservableProperty] public partial bool GgBlendFrames { get; set; } = true; + [ObservableProperty] public partial bool RemoveSpriteLimit { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool DisableBackground { get; set; } = false; - [Reactive][MinMax(0, 100)] public UInt32 Tone1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Tone2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Tone3Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 NoiseVol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 FmAudioVolume { get; set; } = 100; - [Reactive] public bool EnableFmAudio { get; set; } = true; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Tone3Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 NoiseVol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 FmAudioVolume { get; set; } = 100; + [ObservableProperty] public partial bool EnableFmAudio { get; set; } = true; - [Reactive] public OverscanConfig NtscOverscan { get; set; } = new() { Top = 24, Bottom = 24 }; - [Reactive] public OverscanConfig PalOverscan { get; set; } = new() { Top = 24, Bottom = 24 }; - [Reactive] public OverscanConfig GameGearOverscan { get; set; } = new() { Top = 48, Bottom = 48, Left = 48, Right = 48 }; + [ObservableProperty] public partial OverscanConfig NtscOverscan { get; set; } = new() { Top = 24, Bottom = 24 }; + [ObservableProperty] public partial OverscanConfig PalOverscan { get; set; } = new() { Top = 24, Bottom = 24 }; + [ObservableProperty] public partial OverscanConfig GameGearOverscan { get; set; } = new() { Top = 48, Bottom = 48, Left = 48, Right = 48 }; public void ApplyConfig() { diff --git a/UI/Config/SnesConfig.cs b/UI/Config/SnesConfig.cs index 5c471e44e..7b07e597d 100644 --- a/UI/Config/SnesConfig.cs +++ b/UI/Config/SnesConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,67 +9,67 @@ namespace Mesen.Config { - public class SnesConfig : BaseConfig + public partial class SnesConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); //Input - [Reactive] public SnesControllerConfig Port1 { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port2 { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port1 { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port2 { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port1A { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port1B { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port1C { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port1D { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port1A { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port1B { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port1C { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port1D { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port2A { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port2B { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port2C { get; set; } = new SnesControllerConfig(); - [Reactive] public SnesControllerConfig Port2D { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port2A { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port2B { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port2C { get; set; } = new SnesControllerConfig(); + [ObservableProperty] public partial SnesControllerConfig Port2D { get; set; } = new SnesControllerConfig(); - [Reactive] public bool AllowInvalidInput { get; set; } = false; + [ObservableProperty] public partial bool AllowInvalidInput { get; set; } = false; [ValidValues(ConsoleRegion.Auto, ConsoleRegion.Ntsc, ConsoleRegion.Pal)] - [Reactive] public ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; + [ObservableProperty] public partial ConsoleRegion Region { get; set; } = ConsoleRegion.Auto; //Video - [Reactive] public SnesHighResBlendMode HighResBlendMode { get; set; } = SnesHighResBlendMode.None; - [Reactive] public bool HideBgLayer1 { get; set; } = false; - [Reactive] public bool HideBgLayer2 { get; set; } = false; - [Reactive] public bool HideBgLayer3 { get; set; } = false; - [Reactive] public bool HideBgLayer4 { get; set; } = false; - [Reactive] public bool HideSprites { get; set; } = false; - [Reactive] public bool DisableFrameSkipping { get; set; } = false; - [Reactive] public bool ForceFixedResolution { get; set; } = false; + [ObservableProperty] public partial SnesHighResBlendMode HighResBlendMode { get; set; } = SnesHighResBlendMode.None; + [ObservableProperty] public partial bool HideBgLayer1 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer2 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer3 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer4 { get; set; } = false; + [ObservableProperty] public partial bool HideSprites { get; set; } = false; + [ObservableProperty] public partial bool DisableFrameSkipping { get; set; } = false; + [ObservableProperty] public partial bool ForceFixedResolution { get; set; } = false; - [Reactive] public OverscanConfig Overscan { get; set; } = new() { Top = 7, Bottom = 8 }; + [ObservableProperty] public partial OverscanConfig Overscan { get; set; } = new() { Top = 7, Bottom = 8 }; //Audio - [Reactive] public DspInterpolationType InterpolationType { get; set; } = DspInterpolationType.Gauss; - [Reactive][MinMax(0, 100)] public UInt32 Channel1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel3Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel4Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel5Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel6Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel7Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel8Vol { get; set; } = 100; + [ObservableProperty] public partial DspInterpolationType InterpolationType { get; set; } = DspInterpolationType.Gauss; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel3Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel4Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel5Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel6Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel7Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel8Vol { get; set; } = 100; //Emulation - [Reactive] public bool EnableRandomPowerOnState { get; set; } = false; - [Reactive] public bool EnableStrictBoardMappings { get; set; } = false; - [Reactive] public RamState RamPowerOnState { get; set; } = RamState.Random; - [Reactive][MinMax(-999, 999)] public Int32 SpcClockSpeedAdjustment { get; set; } = 40; + [ObservableProperty] public partial bool EnableRandomPowerOnState { get; set; } = false; + [ObservableProperty] public partial bool EnableStrictBoardMappings { get; set; } = false; + [ObservableProperty] public partial RamState RamPowerOnState { get; set; } = RamState.Random; + [ObservableProperty][MinMax(-999, 999)] public partial Int32 SpcClockSpeedAdjustment { get; set; } = 40; //Overclocking - [Reactive][MinMax(0, 1000)] public UInt32 PpuExtraScanlinesBeforeNmi { get; set; } = 0; - [Reactive][MinMax(0, 1000)] public UInt32 PpuExtraScanlinesAfterNmi { get; set; } = 0; - [Reactive][MinMax(100, 1000)] public UInt32 GsuClockSpeed { get; set; } = 100; + [ObservableProperty][MinMax(0, 1000)] public partial UInt32 PpuExtraScanlinesBeforeNmi { get; set; } = 0; + [ObservableProperty][MinMax(0, 1000)] public partial UInt32 PpuExtraScanlinesAfterNmi { get; set; } = 0; + [ObservableProperty][MinMax(100, 1000)] public partial UInt32 GsuClockSpeed { get; set; } = 100; //BSX - [Reactive] public bool BsxUseCustomTime { get; set; } = false; - [Reactive] public DateTimeOffset BsxCustomDate { get; set; } = new DateTimeOffset(1995, 1, 1, 0, 0, 0, TimeSpan.Zero); - [Reactive] public TimeSpan BsxCustomTime { get; set; } = TimeSpan.Zero; + [ObservableProperty] public partial bool BsxUseCustomTime { get; set; } = false; + [ObservableProperty] public partial DateTimeOffset BsxCustomDate { get; set; } = new DateTimeOffset(1995, 1, 1, 0, 0, 0, TimeSpan.Zero); + [ObservableProperty] public partial TimeSpan BsxCustomTime { get; set; } = TimeSpan.Zero; public void ApplyConfig() { diff --git a/UI/Config/VideoConfig.cs b/UI/Config/VideoConfig.cs index d8326afbf..3cdf48dac 100644 --- a/UI/Config/VideoConfig.cs +++ b/UI/Config/VideoConfig.cs @@ -1,7 +1,6 @@ -using Mesen.Interop; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -11,49 +10,49 @@ namespace Mesen.Config { - public class VideoConfig : BaseConfig + public partial class VideoConfig : BaseConfig { - [Reactive][MinMax(0.1, 5.0)] public double CustomAspectRatio { get; set; } = 1.0; - [Reactive] public VideoFilterType VideoFilter { get; set; } = VideoFilterType.None; - [Reactive] public VideoAspectRatio AspectRatio { get; set; } = VideoAspectRatio.NoStretching; - - [Reactive] public bool UseBilinearInterpolation { get; set; } = false; - [Reactive] public bool UseSoftwareRenderer { get; set; } = false; - [Reactive] public bool UseSrgbTextureFormat { get; set; } = false; - [Reactive] public bool VerticalSync { get; set; } = false; - [Reactive] public bool IntegerFpsMode { get; set; } = false; - - [Reactive][MinMax(-100, 100)] public int Brightness { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int Contrast { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int Hue { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int Saturation { get; set; } = 0; - [Reactive][MinMax(0, 100)] public int ScanlineIntensity { get; set; } = 0; - - [Reactive][MinMax(0, 100)] public int LcdGridTopLeftBrightness { get; set; } = 100; - [Reactive][MinMax(0, 100)] public int LcdGridTopRightBrightness { get; set; } = 85; - [Reactive][MinMax(0, 100)] public int LcdGridBottomLeftBrightness { get; set; } = 85; - [Reactive][MinMax(0, 100)] public int LcdGridBottomRightBrightness { get; set; } = 85; - - [Reactive][MinMax(-100, 100)] public int NtscArtifacts { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int NtscBleed { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int NtscFringing { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int NtscGamma { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int NtscResolution { get; set; } = 0; - [Reactive][MinMax(-100, 100)] public int NtscSharpness { get; set; } = 0; - [Reactive] public bool NtscMergeFields { get; set; } = false; - - [Reactive] public NtscBisqwitFilterScale NtscScale { get; set; } = NtscBisqwitFilterScale._2x; - [Reactive][MinMax(-50, 400)] public Int32 NtscYFilterLength { get; set; } = 0; - [Reactive][MinMax(0, 400)] public Int32 NtscIFilterLength { get; set; } = 50; - [Reactive][MinMax(0, 400)] public Int32 NtscQFilterLength { get; set; } = 50; - - [Reactive] public bool FullscreenForceIntegerScale { get; set; } = false; - [Reactive] public bool UseExclusiveFullscreen { get; set; } = false; - [Reactive] public UInt32 ExclusiveFullscreenRefreshRateNtsc { get; set; } = 60; - [Reactive] public UInt32 ExclusiveFullscreenRefreshRatePal { get; set; } = 50; - [Reactive] public FullscreenResolution ExclusiveFullscreenResolution { get; set; } = 0; - - [Reactive] public ScreenRotation ScreenRotation { get; set; } = ScreenRotation.None; + [ObservableProperty][MinMax(0.1, 5.0)] public partial double CustomAspectRatio { get; set; } = 1.0; + [ObservableProperty] public partial VideoFilterType VideoFilter { get; set; } = VideoFilterType.None; + [ObservableProperty] public partial VideoAspectRatio AspectRatio { get; set; } = VideoAspectRatio.NoStretching; + + [ObservableProperty] public partial bool UseBilinearInterpolation { get; set; } = false; + [ObservableProperty] public partial bool UseSoftwareRenderer { get; set; } = false; + [ObservableProperty] public partial bool UseSrgbTextureFormat { get; set; } = false; + [ObservableProperty] public partial bool VerticalSync { get; set; } = false; + [ObservableProperty] public partial bool IntegerFpsMode { get; set; } = false; + + [ObservableProperty][MinMax(-100, 100)] public partial int Brightness { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int Contrast { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int Hue { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int Saturation { get; set; } = 0; + [ObservableProperty][MinMax(0, 100)] public partial int ScanlineIntensity { get; set; } = 0; + + [ObservableProperty][MinMax(0, 100)] public partial int LcdGridTopLeftBrightness { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial int LcdGridTopRightBrightness { get; set; } = 85; + [ObservableProperty][MinMax(0, 100)] public partial int LcdGridBottomLeftBrightness { get; set; } = 85; + [ObservableProperty][MinMax(0, 100)] public partial int LcdGridBottomRightBrightness { get; set; } = 85; + + [ObservableProperty][MinMax(-100, 100)] public partial int NtscArtifacts { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int NtscBleed { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int NtscFringing { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int NtscGamma { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int NtscResolution { get; set; } = 0; + [ObservableProperty][MinMax(-100, 100)] public partial int NtscSharpness { get; set; } = 0; + [ObservableProperty] public partial bool NtscMergeFields { get; set; } = false; + + [ObservableProperty] public partial NtscBisqwitFilterScale NtscScale { get; set; } = NtscBisqwitFilterScale._2x; + [ObservableProperty][MinMax(-50, 400)] public partial Int32 NtscYFilterLength { get; set; } = 0; + [ObservableProperty][MinMax(0, 400)] public partial Int32 NtscIFilterLength { get; set; } = 50; + [ObservableProperty][MinMax(0, 400)] public partial Int32 NtscQFilterLength { get; set; } = 50; + + [ObservableProperty] public partial bool FullscreenForceIntegerScale { get; set; } = false; + [ObservableProperty] public partial bool UseExclusiveFullscreen { get; set; } = false; + [ObservableProperty] public partial UInt32 ExclusiveFullscreenRefreshRateNtsc { get; set; } = 60; + [ObservableProperty] public partial UInt32 ExclusiveFullscreenRefreshRatePal { get; set; } = 50; + [ObservableProperty] public partial FullscreenResolution ExclusiveFullscreenResolution { get; set; } = 0; + + [ObservableProperty] public partial ScreenRotation ScreenRotation { get; set; } = ScreenRotation.None; public VideoConfig() { diff --git a/UI/Config/VideoRecordConfig.cs b/UI/Config/VideoRecordConfig.cs index 79b73ec78..92a7168f5 100644 --- a/UI/Config/VideoRecordConfig.cs +++ b/UI/Config/VideoRecordConfig.cs @@ -1,4 +1,4 @@ -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -7,12 +7,12 @@ namespace Mesen.Config { - public class VideoRecordConfig : BaseConfig + public partial class VideoRecordConfig : BaseConfig { - [Reactive] public VideoCodec Codec { get; set; } = VideoCodec.CSCD; - [Reactive] public UInt32 CompressionLevel { get; set; } = 6; - [Reactive] public bool RecordSystemHud { get; set; } = false; - [Reactive] public bool RecordInputHud { get; set; } = false; + [ObservableProperty] public partial VideoCodec Codec { get; set; } = VideoCodec.CSCD; + [ObservableProperty] public partial UInt32 CompressionLevel { get; set; } = 6; + [ObservableProperty] public partial bool RecordSystemHud { get; set; } = false; + [ObservableProperty] public partial bool RecordInputHud { get; set; } = false; } public enum VideoCodec diff --git a/UI/Config/WsConfig.cs b/UI/Config/WsConfig.cs index f51a9ae2c..6245d5c53 100644 --- a/UI/Config/WsConfig.cs +++ b/UI/Config/WsConfig.cs @@ -1,5 +1,5 @@ using Mesen.Interop; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; @@ -9,33 +9,33 @@ namespace Mesen.Config; -public class WsConfig : BaseConfig +public partial class WsConfig : BaseConfig { - [Reactive] public ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); + [ObservableProperty] public partial ConsoleOverrideConfig ConfigOverrides { get; set; } = new(); - [Reactive] public ControllerConfig ControllerHorizontal { get; set; } = new(); - [Reactive] public ControllerConfig ControllerVertical { get; set; } = new(); - [Reactive] public ControllerConfig ControllerPcv2 { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig ControllerHorizontal { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig ControllerVertical { get; set; } = new(); + [ObservableProperty] public partial ControllerConfig ControllerPcv2 { get; set; } = new(); - [Reactive] public WsModel Model { get; set; } = WsModel.Auto; - [Reactive] public bool UseBootRom { get; set; } = false; + [ObservableProperty] public partial WsModel Model { get; set; } = WsModel.Auto; + [ObservableProperty] public partial bool UseBootRom { get; set; } = false; - [Reactive] public bool AutoRotate { get; set; } = true; + [ObservableProperty] public partial bool AutoRotate { get; set; } = true; - [Reactive] public bool BlendFrames { get; set; } = true; - [Reactive] public bool LcdAdjustColors { get; set; } = true; - [Reactive] public bool LcdShowIcons { get; set; } = true; + [ObservableProperty] public partial bool BlendFrames { get; set; } = true; + [ObservableProperty] public partial bool LcdAdjustColors { get; set; } = true; + [ObservableProperty] public partial bool LcdShowIcons { get; set; } = true; - [Reactive] public bool HideBgLayer1 { get; set; } = false; - [Reactive] public bool HideBgLayer2 { get; set; } = false; - [Reactive] public bool DisableSprites { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer1 { get; set; } = false; + [ObservableProperty] public partial bool HideBgLayer2 { get; set; } = false; + [ObservableProperty] public partial bool DisableSprites { get; set; } = false; - [Reactive] public WsAudioMode AudioMode { get; set; } = WsAudioMode.Headphones; - [Reactive][MinMax(0, 100)] public UInt32 Channel1Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel2Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel3Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel4Vol { get; set; } = 100; - [Reactive][MinMax(0, 100)] public UInt32 Channel5Vol { get; set; } = 100; + [ObservableProperty] public partial WsAudioMode AudioMode { get; set; } = WsAudioMode.Headphones; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel1Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel2Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel3Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel4Vol { get; set; } = 100; + [ObservableProperty][MinMax(0, 100)] public partial UInt32 Channel5Vol { get; set; } = 100; public void ApplyConfig() { diff --git a/UI/Controls/FirmwareSelect.axaml.cs b/UI/Controls/FirmwareSelect.axaml.cs index 8e92e801c..9a4241c23 100644 --- a/UI/Controls/FirmwareSelect.axaml.cs +++ b/UI/Controls/FirmwareSelect.axaml.cs @@ -4,6 +4,7 @@ using Avalonia.Markup.Xaml; using Avalonia.Metadata; using Mesen.Config; +using Mesen.Debugger.Windows; using Mesen.Interop; using Mesen.Localization; using Mesen.Utilities; @@ -91,9 +92,9 @@ private void ValidateFirmware() private async void BtnBrowse_OnClick(object sender, RoutedEventArgs e) { while(true) { - string? selectedFile = await FileDialogHelper.OpenFile(null, VisualRoot, FileDialogHelper.FirmwareExt); + string? selectedFile = await FileDialogHelper.OpenFile(null, this.GetWindow(), FileDialogHelper.FirmwareExt); if(selectedFile?.Length > 0 && File.Exists(selectedFile)) { - if(await FirmwareHelper.SelectFirmwareFile(FirmwareType, selectedFile, VisualRoot)) { + if(await FirmwareHelper.SelectFirmwareFile(FirmwareType, selectedFile, this.GetWindow())) { break; } } else { @@ -107,7 +108,7 @@ public async void DeleteFirmware(object parameter) { string path = Path.Combine(ConfigManager.FirmwareFolder, Filename); if(File.Exists(path)) { - DialogResult result = await MesenMsgBox.Show(VisualRoot, "PromptDeleteFirmware", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, path); + DialogResult result = await MesenMsgBox.Show(this.GetWindow(), "PromptDeleteFirmware", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, path); if(result == DialogResult.OK) { File.Delete(path); } diff --git a/UI/Controls/InputComboBox.axaml.cs b/UI/Controls/InputComboBox.axaml.cs index d12917296..512a93da7 100644 --- a/UI/Controls/InputComboBox.axaml.cs +++ b/UI/Controls/InputComboBox.axaml.cs @@ -78,7 +78,7 @@ private async void BtnSetup_Click(object sender, RoutedEventArgs e) ControllerConfig cfg = Config.Clone(); wnd.DataContext = new ControllerConfigViewModel(ControllerType, cfg, Config, Port); - if(await wnd.ShowDialogAtPosition(btn.GetVisualRoot() as Visual, startPosition)) { + if(await wnd.ShowDialogAtPosition(btn.GetWindow(), startPosition)) { Config = cfg; } } diff --git a/UI/Controls/KeyBindingButton.axaml.cs b/UI/Controls/KeyBindingButton.axaml.cs index 292c7eb5d..78846d7e5 100644 --- a/UI/Controls/KeyBindingButton.axaml.cs +++ b/UI/Controls/KeyBindingButton.axaml.cs @@ -58,7 +58,7 @@ protected override async void OnClick() GetKeyWindow wnd = new GetKeyWindow(false); wnd.SingleKeyMode = true; wnd.WindowStartupLocation = WindowStartupLocation.CenterOwner; - await wnd.ShowCenteredDialog(this.GetVisualRoot() as Visual); + await wnd.ShowCenteredDialog(this.GetWindow()); this.KeyBinding = wnd.ShortcutKey.Key1; } diff --git a/UI/Controls/MesenNumericTextBox.cs b/UI/Controls/MesenNumericTextBox.cs index ba44bc951..89ec3da40 100644 --- a/UI/Controls/MesenNumericTextBox.cs +++ b/UI/Controls/MesenNumericTextBox.cs @@ -269,13 +269,13 @@ private void UpdateText(bool force = false) } } - protected override void OnGotFocus(GotFocusEventArgs e) + protected override void OnGotFocus(FocusChangedEventArgs e) { base.OnGotFocus(e); this.SelectAll(); } - protected override void OnLostFocus(RoutedEventArgs e) + protected override void OnLostFocus(FocusChangedEventArgs e) { base.OnLostFocus(e); UpdateValueFromText(); diff --git a/UI/Controls/MultiKeyBindingButton.axaml.cs b/UI/Controls/MultiKeyBindingButton.axaml.cs index 3a941ffe0..bf037bf75 100644 --- a/UI/Controls/MultiKeyBindingButton.axaml.cs +++ b/UI/Controls/MultiKeyBindingButton.axaml.cs @@ -51,7 +51,7 @@ protected override async void OnClick() GetKeyWindow wnd = new GetKeyWindow(false); wnd.SingleKeyMode = false; wnd.WindowStartupLocation = WindowStartupLocation.CenterOwner; - await wnd.ShowCenteredDialog(this.GetVisualRoot() as Visual); + await wnd.ShowCenteredDialog(this.GetWindow()); this.KeyBinding = wnd.ShortcutKey; } diff --git a/UI/Controls/PaletteConfig.axaml.cs b/UI/Controls/PaletteConfig.axaml.cs index 3f99ecb34..21c978ffc 100644 --- a/UI/Controls/PaletteConfig.axaml.cs +++ b/UI/Controls/PaletteConfig.axaml.cs @@ -10,12 +10,10 @@ using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; -using ReactiveUI; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reactive; using System.Reflection; namespace Mesen.Controls @@ -92,7 +90,7 @@ private async void PaletteColor_OnClick(object sender, PaletteSelector.ColorClic ColorPickerViewModel model = new ColorPickerViewModel() { Color = e.Color }; ColorPickerWindow wnd = new ColorPickerWindow() { DataContext = model }; - bool success = await wnd.ShowCenteredDialog(this.GetVisualRoot() as Visual); + bool success = await wnd.ShowCenteredDialog(this.GetWindow()); if(success) { UInt32[] colors = (UInt32[])Palette.Clone(); colors[e.ColorIndex] = model.Color.ToUInt32(); @@ -102,7 +100,7 @@ private async void PaletteColor_OnClick(object sender, PaletteSelector.ColorClic private async void BtnLoadPalFile_OnClick(object sender, RoutedEventArgs e) { - string? filename = await FileDialogHelper.OpenFile(null, this.GetVisualRoot(), FileDialogHelper.PaletteExt); + string? filename = await FileDialogHelper.OpenFile(null, this.GetWindow(), FileDialogHelper.PaletteExt); if(filename != null) { LoadPaletteFile(filename); } @@ -110,7 +108,7 @@ private async void BtnLoadPalFile_OnClick(object sender, RoutedEventArgs e) private async void BtnExportPalette_OnClick(object sender, RoutedEventArgs e) { - string? filename = await FileDialogHelper.SaveFile(null, null, this.GetVisualRoot(), FileDialogHelper.PaletteExt); + string? filename = await FileDialogHelper.SaveFile(null, null, this.GetWindow(), FileDialogHelper.PaletteExt); if(filename != null) { ExportPalette(filename); } @@ -137,7 +135,7 @@ public void LoadPaletteFile(string filename) } Palette = paletteData; } else { - MesenMsgBox.Show(VisualRoot, "InvalidPaletteFile", MessageBoxButtons.OK, MessageBoxIcon.Error); + MesenMsgBox.Show(this.GetWindow(), "InvalidPaletteFile", MessageBoxButtons.OK, MessageBoxIcon.Error); } paletteFile.Close(); } diff --git a/UI/Controls/PathSelector.axaml.cs b/UI/Controls/PathSelector.axaml.cs index f2092b81c..57846345d 100644 --- a/UI/Controls/PathSelector.axaml.cs +++ b/UI/Controls/PathSelector.axaml.cs @@ -43,7 +43,7 @@ private void InitializeComponent() private async void BtnBrowse_OnClick(object sender, RoutedEventArgs e) { - string? folderName = await FileDialogHelper.OpenFolder(VisualRoot); + string? folderName = await FileDialogHelper.OpenFolder(this.GetWindow()); if(folderName?.Length > 0) { this.Path = folderName; } diff --git a/UI/Controls/SimpleImageViewer.cs b/UI/Controls/SimpleImageViewer.cs index 3586511ad..3533e9a8e 100644 --- a/UI/Controls/SimpleImageViewer.cs +++ b/UI/Controls/SimpleImageViewer.cs @@ -2,7 +2,6 @@ using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Imaging; -using Avalonia.Media.TextFormatting; using Avalonia.Platform; using Avalonia.Rendering.SceneGraph; using Avalonia.Skia; @@ -93,14 +92,13 @@ public void Render(ImmediateDrawingContext context) using SKPaint paint = new(); paint.Color = new SKColor(255, 255, 255, 255); - paint.FilterQuality = _interpolationMode.ToSKFilterQuality(); using(_source.Lock(true)) { - canvas.DrawBitmap(_bitmap, - new SKRect(0, 0, (int)_source.Size.Width, (int)_source.Size.Height), - new SKRect(0, 0, (float)Bounds.Width, (float)Bounds.Height), - paint - ); + SKRect rcImage = new SKRect(0, 0, (int)_source.Size.Width, (int)_source.Size.Height); + SKRect rcTarget = new SKRect(0, 0, (float)Bounds.Width, (float)Bounds.Height); + var sampling = _interpolationMode.ToSKSamplingOptions(); + var resizedBitmap = _bitmap.Resize(new SKImageInfo((int)rcTarget.Width, (int)rcTarget.Height), sampling); + canvas.DrawBitmap(resizedBitmap, rcTarget, paint); } } } diff --git a/UI/Controls/SoftwareRendererView.axaml b/UI/Controls/SoftwareRendererView.axaml index 2fb269c2b..f62d0d76e 100644 --- a/UI/Controls/SoftwareRendererView.axaml +++ b/UI/Controls/SoftwareRendererView.axaml @@ -30,14 +30,14 @@ Source="{Binding EmuHudSurface}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - RenderOptions.TextRenderingMode="Alias" + TextOptions.TextRenderingMode="Alias" /> \ No newline at end of file diff --git a/UI/Controls/SoftwareRendererView.axaml.cs b/UI/Controls/SoftwareRendererView.axaml.cs index aeb70f319..f5c770b3f 100644 --- a/UI/Controls/SoftwareRendererView.axaml.cs +++ b/UI/Controls/SoftwareRendererView.axaml.cs @@ -7,13 +7,12 @@ using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; -using Splat.ModeDetection; using System; using System.Collections.Generic; using System.Linq; @@ -85,12 +84,12 @@ public unsafe void UpdateSoftwareRenderer(SoftwareRendererFrame frameInfo) } } - public class SoftwareRendererViewModel : ViewModelBase + public partial class SoftwareRendererViewModel : ViewModelBase { - [Reactive] public DynamicBitmap? FrameSurface { get; set; } - [Reactive] public DynamicBitmap? EmuHudSurface { get; set; } - [Reactive] public DynamicBitmap? ScriptHudSurface { get; set; } - [Reactive] public double Width { get; set; } - [Reactive] public double Height { get; set; } + [ObservableProperty] public partial DynamicBitmap? FrameSurface { get; set; } + [ObservableProperty] public partial DynamicBitmap? EmuHudSurface { get; set; } + [ObservableProperty] public partial DynamicBitmap? ScriptHudSurface { get; set; } + [ObservableProperty] public partial double Width { get; set; } + [ObservableProperty] public partial double Height { get; set; } } } diff --git a/UI/Controls/StateGrid.axaml.cs b/UI/Controls/StateGrid.axaml.cs index 9e9abbc36..a3ff18f65 100644 --- a/UI/Controls/StateGrid.axaml.cs +++ b/UI/Controls/StateGrid.axaml.cs @@ -6,7 +6,7 @@ using Mesen.Config; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Linq; diff --git a/UI/Controls/SystemSpecificSettings.axaml.cs b/UI/Controls/SystemSpecificSettings.axaml.cs index ef5b4d04b..6b9a1f6e7 100644 --- a/UI/Controls/SystemSpecificSettings.axaml.cs +++ b/UI/Controls/SystemSpecificSettings.axaml.cs @@ -5,6 +5,7 @@ using Avalonia.Markup.Xaml; using Mesen.Config; using Mesen.Localization; +using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; using System; @@ -71,7 +72,7 @@ private void OnClickWs(object sender, RoutedEventArgs e) private void NavigateTo(ConfigWindowTab console) { - if(VisualRoot is ConfigWindow wnd && wnd.DataContext is ConfigViewModel cfg) { + if(this.GetWindow()?.DataContext is ConfigViewModel cfg) { cfg.SelectTab(console); switch(console) { diff --git a/UI/Debugger/Breakpoints/Breakpoint.cs b/UI/Debugger/Breakpoints/Breakpoint.cs index 951e2f60b..c727fa286 100644 --- a/UI/Debugger/Breakpoints/Breakpoint.cs +++ b/UI/Debugger/Breakpoints/Breakpoint.cs @@ -1,33 +1,31 @@ using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Labels; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive.Linq; using System.Text; namespace Mesen.Debugger { - public class Breakpoint : ReactiveObject + public partial class Breakpoint : ObservableObject { - [Reactive] public bool BreakOnRead { get; set; } - [Reactive] public bool BreakOnWrite { get; set; } - [Reactive] public bool BreakOnExec { get; set; } - [Reactive] public bool Forbid { get; set; } - - [Reactive] public bool Enabled { get; set; } = true; - [Reactive] public bool MarkEvent { get; set; } - [Reactive] public bool IgnoreDummyOperations { get; set; } = true; - [Reactive] public MemoryType MemoryType { get; set; } - [Reactive] public UInt32 StartAddress { get; set; } - [Reactive] public UInt32 EndAddress { get; set; } - [Reactive] public CpuType CpuType { get; set; } - [Reactive] public bool AnyAddress { get; set; } = false; - [Reactive] public bool IsAssert { get; set; } = false; - [Reactive] public string Condition { get; set; } = ""; + [ObservableProperty] public partial bool BreakOnRead { get; set; } + [ObservableProperty] public partial bool BreakOnWrite { get; set; } + [ObservableProperty] public partial bool BreakOnExec { get; set; } + [ObservableProperty] public partial bool Forbid { get; set; } + + [ObservableProperty] public partial bool Enabled { get; set; } = true; + [ObservableProperty] public partial bool MarkEvent { get; set; } + [ObservableProperty] public partial bool IgnoreDummyOperations { get; set; } = true; + [ObservableProperty] public partial MemoryType MemoryType { get; set; } + [ObservableProperty] public partial UInt32 StartAddress { get; set; } + [ObservableProperty] public partial UInt32 EndAddress { get; set; } + [ObservableProperty] public partial CpuType CpuType { get; set; } + [ObservableProperty] public partial bool AnyAddress { get; set; } = false; + [ObservableProperty] public partial bool IsAssert { get; set; } = false; + [ObservableProperty] public partial string Condition { get; set; } = ""; public Breakpoint() { diff --git a/UI/Debugger/Controls/ActionToolbar.axaml.cs b/UI/Debugger/Controls/ActionToolbar.axaml.cs index 1c866c110..4625aee52 100644 --- a/UI/Debugger/Controls/ActionToolbar.axaml.cs +++ b/UI/Debugger/Controls/ActionToolbar.axaml.cs @@ -1,6 +1,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Data; +using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.Threading; diff --git a/UI/Debugger/Controls/DebuggerKeyBindingButton.cs b/UI/Debugger/Controls/DebuggerKeyBindingButton.cs index 61979e945..bb811b4c9 100644 --- a/UI/Debugger/Controls/DebuggerKeyBindingButton.cs +++ b/UI/Debugger/Controls/DebuggerKeyBindingButton.cs @@ -45,7 +45,7 @@ protected override async void OnClick() GetKeyWindow wnd = new GetKeyWindow(true); wnd.SingleKeyMode = false; wnd.WindowStartupLocation = WindowStartupLocation.CenterOwner; - await wnd.ShowCenteredDialog(this.GetVisualRoot() as Visual); + await wnd.ShowCenteredDialog(this.GetWindow()); this.KeyBinding = wnd.DbgShortcutKey; } diff --git a/UI/Debugger/Controls/DisassemblyViewer.cs b/UI/Debugger/Controls/DisassemblyViewer.cs index f715dea89..3e3f4f02b 100644 --- a/UI/Debugger/Controls/DisassemblyViewer.cs +++ b/UI/Debugger/Controls/DisassemblyViewer.cs @@ -11,7 +11,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Reactive.Disposables; namespace Mesen.Debugger.Controls { @@ -116,7 +115,7 @@ public AddressDisplayType AddressDisplayType private Dictionary> _textFragments = new(); private Point _previousPointerPos; private CodeSegmentInfo? _prevPointerOverSegment = null; - private CompositeDisposable _disposables = new(); + private List _disposables = new(); static DisassemblyViewer() { @@ -138,14 +137,19 @@ public DisassemblyViewer() protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); - _disposables.Add(FontSizeProperty.Changed.Subscribe(_ => InitFontAndLetterSize())); - _disposables.Add(FontFamilyProperty.Changed.Subscribe(_ => InitFontAndLetterSize())); - _disposables.Add(BoundsProperty.Changed.Subscribe(_ => InitFontAndLetterSize())); + this.ObserveProp(FontSizeProperty, _ => InitFontAndLetterSize()); + this.ObserveProp(FontFamilyProperty, _ => InitFontAndLetterSize()); + this.ObserveProp(BoundsProperty, _ => InitFontAndLetterSize()); + + InitFontAndLetterSize(); } protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { - _disposables.Dispose(); + foreach(IDisposable disposable in _disposables) { + disposable.Dispose(); + } + _disposables.Clear(); base.OnDetachedFromVisualTree(e); } diff --git a/UI/Debugger/Controls/DynamicTooltip.axaml.cs b/UI/Debugger/Controls/DynamicTooltip.axaml.cs index cdb4b50fc..2618d6226 100644 --- a/UI/Debugger/Controls/DynamicTooltip.axaml.cs +++ b/UI/Debugger/Controls/DynamicTooltip.axaml.cs @@ -5,12 +5,11 @@ using Avalonia.Layout; using Avalonia.Markup.Xaml; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Localization; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -91,11 +90,11 @@ private void TextBox_LostFocus(object? sender, RoutedEventArgs e) } } - public class TooltipEntry : ReactiveObject + public partial class TooltipEntry : ObservableObject { - [Reactive] public string Name { get; set; } = ""; - [Reactive] public object Value { get; set; } = ""; - [Reactive] public bool UseMonoFont { get; set; } = false; + [ObservableProperty] public partial string Name { get; set; } = ""; + [ObservableProperty] public partial object Value { get; set; } = ""; + [ObservableProperty] public partial bool UseMonoFont { get; set; } = false; public virtual VerticalAlignment VerticalAlignment => Value is bool ? VerticalAlignment.Center : VerticalAlignment.Top; @@ -114,9 +113,9 @@ public CustomTooltipEntry(string name, object value, bool useMonoFont = false) : } } - public class TooltipSeparator : TooltipEntry + public partial class TooltipSeparator : TooltipEntry { - [Reactive] public bool Hidden { get; set; } = false; + [ObservableProperty] public partial bool Hidden { get; set; } = false; public TooltipSeparator(string name) : base(name, false, false) { @@ -243,11 +242,11 @@ public void EndUpdate() } } - public class TooltipPictureEntry : ReactiveObject + public partial class TooltipPictureEntry : ObservableObject { - [Reactive] public IImage Source { get; set; } - [Reactive] public double Zoom { get; set; } - [Reactive] public PixelRect? CropRect { get; set; } + [ObservableProperty] public partial IImage Source { get; set; } + [ObservableProperty] public partial double Zoom { get; set; } + [ObservableProperty] public partial PixelRect? CropRect { get; set; } public IImage OriginalSource { get; } public TooltipPictureEntry(IImage src, double zoom, PixelRect? cropRect) @@ -263,9 +262,9 @@ public TooltipPictureEntry(IImage src, double zoom, PixelRect? cropRect) } } - public class TooltipColorEntry : ReactiveObject + public partial class TooltipColorEntry : ObservableObject { - [Reactive] public UInt32[] Color { get; set; } + [ObservableProperty] public partial UInt32[] Color { get; set; } public TooltipColorEntry(UInt32 color) { @@ -274,11 +273,11 @@ public TooltipColorEntry(UInt32 color) } } - public class TooltipPaletteEntry : ReactiveObject + public partial class TooltipPaletteEntry : ObservableObject { - [Reactive] public UInt32[] RgbPalette { get; set; } - [Reactive] public UInt32[] RawPalette { get; set; } - [Reactive] public RawPaletteFormat RawFormat { get; set; } + [ObservableProperty] public partial UInt32[] RgbPalette { get; set; } + [ObservableProperty] public partial UInt32[] RawPalette { get; set; } + [ObservableProperty] public partial RawPaletteFormat RawFormat { get; set; } public TooltipPaletteEntry(UInt32[] rgbPalette, UInt32[] rawPalette, RawPaletteFormat rawFormat) { diff --git a/UI/Debugger/Controls/HexEditor.HexViewDrawOperation.cs b/UI/Debugger/Controls/HexEditor.HexViewDrawOperation.cs index 9e5dcc66e..742c399d7 100644 --- a/UI/Debugger/Controls/HexEditor.HexViewDrawOperation.cs +++ b/UI/Debugger/Controls/HexEditor.HexViewDrawOperation.cs @@ -153,7 +153,7 @@ private void DrawHexView(SKCanvas canvas, Color color) string rowText = sb.ToString(); int count = font.CountGlyphs(rowText); var buffer = builder.AllocateRun(font, count, 0, (float)(row * _rowHeight + drawOffsetY)); - font.GetGlyphs(rowText, buffer.GetGlyphSpan()); + font.GetGlyphs(rowText, buffer.Glyphs); row++; sb.Clear(); } @@ -201,9 +201,9 @@ private void PrepareStringView() if(codepoint > 0x024F) { SKRunBuffer measureBuffer = measureText.AllocateRun(altFont, altFont.CountGlyphs(str), 0, 0); byteInfo.UseAltFont = true; - altFont.GetGlyphs(str, measureBuffer.GetGlyphSpan()); + altFont.GetGlyphs(str, measureBuffer.Glyphs); startPositionByByte[index] = (float)xPos; - xPos += altFont.MeasureText(measureBuffer.GetGlyphSpan()); + xPos += altFont.MeasureText(measureBuffer.Glyphs); endPositionByByte[index] = (float)xPos; } else { startPositionByByte[index] = (float)xPos; @@ -282,7 +282,7 @@ private void DrawStringView(SKCanvas canvas, Color color) int count = currentFont.CountGlyphs(byteInfo.StringValue); var buffer = builder.AllocateRun(currentFont, count, _he._startPositionByByte[pos + i], (float)(row * _rowHeight + drawOffsetY)); - currentFont.GetGlyphs(byteInfo.StringValue, buffer.GetGlyphSpan()); + currentFont.GetGlyphs(byteInfo.StringValue, buffer.Glyphs); } i += (byteInfo.StringValueKeyLength - 1); @@ -498,7 +498,7 @@ public void Render(ImmediateDrawingContext context) string rowText = headerByte.ToString("X" + _headerCharLength); int count = font.CountGlyphs(rowText); var buffer = builder.AllocateRun(font, count, (float)xOffset, (float)(row * _rowHeight + drawOffsetY)); - font.GetGlyphs(rowText, buffer.GetGlyphSpan()); + font.GetGlyphs(rowText, buffer.Glyphs); row++; y += _rowHeight; headerByte += bytesPerRow; diff --git a/UI/Debugger/Controls/PaletteSelector.cs b/UI/Debugger/Controls/PaletteSelector.cs index 3f8a9ef27..cbba3204a 100644 --- a/UI/Debugger/Controls/PaletteSelector.cs +++ b/UI/Debugger/Controls/PaletteSelector.cs @@ -14,6 +14,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -110,18 +111,18 @@ static PaletteSelector() { AffectsRender(IsEnabledProperty, SelectionModeProperty, SelectedPaletteProperty, PaletteColorsProperty, ColumnCountProperty, ShowIndexesProperty, PaletteIndexValuesProperty); AffectsMeasure(ColumnCountProperty, BlockSizeProperty, PaletteColorsProperty); - } - public PaletteSelector() - { - this.GetObservable(SelectionModeProperty).Subscribe((mode) => { - this.CoerceValue(SelectedPaletteProperty); + SelectionModeProperty.Changed.AddClassHandler((x, e) => { + x.CoerceValue(SelectedPaletteProperty); }); - this.GetObservable(PaletteColorsProperty).Subscribe((mode) => { - this.CoerceValue(SelectedPaletteProperty); + PaletteColorsProperty.Changed.AddClassHandler((x, e) => { + x.CoerceValue(SelectedPaletteProperty); }); + } + public PaletteSelector() + { Focusable = true; ClipToBounds = true; } diff --git a/UI/Debugger/Controls/PictureViewer.cs b/UI/Debugger/Controls/PictureViewer.cs index a99e58f2f..8e12f6a74 100644 --- a/UI/Debugger/Controls/PictureViewer.cs +++ b/UI/Debugger/Controls/PictureViewer.cs @@ -271,7 +271,7 @@ public void ZoomOut() public async void ExportToPng() { if(Source is Bitmap bitmap) { - string? filename = await FileDialogHelper.SaveFile(null, null, this.VisualRoot, FileDialogHelper.PngExt); + string? filename = await FileDialogHelper.SaveFile(null, null, this.GetWindow(), FileDialogHelper.PngExt); if(filename != null) { bitmap.Save(filename); } diff --git a/UI/Debugger/Controls/SpritePreviewPanel.axaml.cs b/UI/Debugger/Controls/SpritePreviewPanel.axaml.cs index abc3ef101..48b177a3d 100644 --- a/UI/Debugger/Controls/SpritePreviewPanel.axaml.cs +++ b/UI/Debugger/Controls/SpritePreviewPanel.axaml.cs @@ -2,12 +2,11 @@ using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Markup.Xaml; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.ViewModels; using Mesen.Utilities; -using ReactiveUI; using System; -using System.Reactive.Linq; namespace Mesen.Debugger.Controls { @@ -55,9 +54,13 @@ public SpritePreviewPanel(SpritePreviewModel model, SpriteViewerConfig config) Model = model; Config = config; - AddDisposable(this.WhenAnyValue(x => x.Model.FadePreview, x => x.Config.DimOffscreenSprites).Subscribe(x => { - FadePreview = Model.FadePreview == true && Config.DimOffscreenSprites == true; - })); + AddDisposable(Model.ObserveProp(nameof(Model.FadePreview), UpdateFadePreviewFlag)); + AddDisposable(Config.ObserveProp(nameof(Config.DimOffscreenSprites), UpdateFadePreviewFlag)); + } + + private void UpdateFadePreviewFlag() + { + FadePreview = Model.FadePreview == true && Config.DimOffscreenSprites == true; } protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) diff --git a/UI/Debugger/DebuggerDockFactory.cs b/UI/Debugger/DebuggerDockFactory.cs index 77835036a..6c099720a 100644 --- a/UI/Debugger/DebuggerDockFactory.cs +++ b/UI/Debugger/DebuggerDockFactory.cs @@ -267,4 +267,6 @@ public class DockEntryDefinition public class MesenProportionalDockSplitter : DockBase, IProportionalDockSplitter { //The regular ProportionalDockSplitter in Dock.Model.Mvvm.Controls inherits from DockableBase, which causes an exception when styles are applied + public bool CanResize { get; set; } = true; + public bool ResizePreview { get; set; } = false; } diff --git a/UI/Debugger/Labels/CodeLabel.cs b/UI/Debugger/Labels/CodeLabel.cs index b28d4db6a..336f366aa 100644 --- a/UI/Debugger/Labels/CodeLabel.cs +++ b/UI/Debugger/Labels/CodeLabel.cs @@ -1,7 +1,6 @@ -using Mesen.Interop; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Globalization; using System.Text; diff --git a/UI/Debugger/StatusViews/BaseConsoleStatusViewModel.cs b/UI/Debugger/StatusViews/BaseConsoleStatusViewModel.cs index 2e0e02768..6867c5ada 100644 --- a/UI/Debugger/StatusViews/BaseConsoleStatusViewModel.cs +++ b/UI/Debugger/StatusViews/BaseConsoleStatusViewModel.cs @@ -1,15 +1,15 @@ -using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.ViewModels; using System; using System.ComponentModel; namespace Mesen.Debugger.StatusViews { - public abstract class BaseConsoleStatusViewModel : ViewModelBase + public abstract partial class BaseConsoleStatusViewModel : ViewModelBase { - [Reactive] public bool EditAllowed { get; set; } - [Reactive] public UInt64 ElapsedCycles { get; set; } - [Reactive] public UInt64 CycleCount { get; set; } + [ObservableProperty] public partial bool EditAllowed { get; set; } + [ObservableProperty] public partial UInt64 ElapsedCycles { get; set; } + [ObservableProperty] public partial UInt64 CycleCount { get; set; } private bool _isUpdatingUi = false; private bool _needUpdate = false; diff --git a/UI/Debugger/StatusViews/Cx4StatusViewModel.cs b/UI/Debugger/StatusViews/Cx4StatusViewModel.cs index d21f39ce4..b1594e557 100644 --- a/UI/Debugger/StatusViews/Cx4StatusViewModel.cs +++ b/UI/Debugger/StatusViews/Cx4StatusViewModel.cs @@ -1,51 +1,50 @@ using Avalonia.Collections; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class Cx4StatusViewModel : BaseConsoleStatusViewModel + public partial class Cx4StatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt32 Reg0 { get; set; } - [Reactive] public UInt32 Reg1 { get; set; } - [Reactive] public UInt32 Reg2 { get; set; } - [Reactive] public UInt32 Reg3 { get; set; } - [Reactive] public UInt32 Reg4 { get; set; } - [Reactive] public UInt32 Reg5 { get; set; } - [Reactive] public UInt32 Reg6 { get; set; } - [Reactive] public UInt32 Reg7 { get; set; } - [Reactive] public UInt32 Reg8 { get; set; } - [Reactive] public UInt32 Reg9 { get; set; } - [Reactive] public UInt32 Reg10 { get; set; } - [Reactive] public UInt32 Reg11 { get; set; } - [Reactive] public UInt32 Reg12 { get; set; } - [Reactive] public UInt32 Reg13 { get; set; } - [Reactive] public UInt32 Reg14 { get; set; } - [Reactive] public UInt32 Reg15 { get; set; } - - [Reactive] public UInt16 RegPb { get; set; } - [Reactive] public UInt16 RegP { get; set; } - [Reactive] public byte RegPc { get; set; } - [Reactive] public byte RegSp { get; set; } - - [Reactive] public UInt32 RegMdr { get; set; } - [Reactive] public UInt32 RegMar { get; set; } - [Reactive] public UInt32 RegDpr { get; set; } - - [Reactive] public UInt32 RegA { get; set; } - [Reactive] public UInt64 RegMult { get; set; } - - [Reactive] public UInt32 RomBuffer { get; set; } - [Reactive] public UInt32 RamBuffer { get; set; } - - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagNegative { get; set; } - [Reactive] public bool FlagOverflow { get; set; } - [Reactive] public bool FlagIrq { get; set; } + [ObservableProperty] public partial UInt32 Reg0 { get; set; } + [ObservableProperty] public partial UInt32 Reg1 { get; set; } + [ObservableProperty] public partial UInt32 Reg2 { get; set; } + [ObservableProperty] public partial UInt32 Reg3 { get; set; } + [ObservableProperty] public partial UInt32 Reg4 { get; set; } + [ObservableProperty] public partial UInt32 Reg5 { get; set; } + [ObservableProperty] public partial UInt32 Reg6 { get; set; } + [ObservableProperty] public partial UInt32 Reg7 { get; set; } + [ObservableProperty] public partial UInt32 Reg8 { get; set; } + [ObservableProperty] public partial UInt32 Reg9 { get; set; } + [ObservableProperty] public partial UInt32 Reg10 { get; set; } + [ObservableProperty] public partial UInt32 Reg11 { get; set; } + [ObservableProperty] public partial UInt32 Reg12 { get; set; } + [ObservableProperty] public partial UInt32 Reg13 { get; set; } + [ObservableProperty] public partial UInt32 Reg14 { get; set; } + [ObservableProperty] public partial UInt32 Reg15 { get; set; } + + [ObservableProperty] public partial UInt16 RegPb { get; set; } + [ObservableProperty] public partial UInt16 RegP { get; set; } + [ObservableProperty] public partial byte RegPc { get; set; } + [ObservableProperty] public partial byte RegSp { get; set; } + + [ObservableProperty] public partial UInt32 RegMdr { get; set; } + [ObservableProperty] public partial UInt32 RegMar { get; set; } + [ObservableProperty] public partial UInt32 RegDpr { get; set; } + + [ObservableProperty] public partial UInt32 RegA { get; set; } + [ObservableProperty] public partial UInt64 RegMult { get; set; } + + [ObservableProperty] public partial UInt32 RomBuffer { get; set; } + [ObservableProperty] public partial UInt32 RamBuffer { get; set; } + + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagNegative { get; set; } + [ObservableProperty] public partial bool FlagOverflow { get; set; } + [ObservableProperty] public partial bool FlagIrq { get; set; } public Cx4StatusViewModel() { diff --git a/UI/Debugger/StatusViews/GbStatusViewModel.cs b/UI/Debugger/StatusViews/GbStatusViewModel.cs index 8ed26dac9..cd0991a0a 100644 --- a/UI/Debugger/StatusViews/GbStatusViewModel.cs +++ b/UI/Debugger/StatusViews/GbStatusViewModel.cs @@ -1,50 +1,57 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class GbStatusViewModel : BaseConsoleStatusViewModel + public partial class GbStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public byte RegA { get; set; } - [Reactive] public byte RegB { get; set; } - [Reactive] public byte RegC { get; set; } - [Reactive] public byte RegD { get; set; } - [Reactive] public byte RegE { get; set; } - [Reactive] public byte RegFlags { get; set; } + [ObservableProperty] public partial byte RegA { get; set; } + [ObservableProperty] public partial byte RegB { get; set; } + [ObservableProperty] public partial byte RegC { get; set; } + [ObservableProperty] public partial byte RegD { get; set; } + [ObservableProperty] public partial byte RegE { get; set; } + [ObservableProperty] public partial byte RegFlags { get; set; } - [Reactive] public byte RegH { get; set; } - [Reactive] public byte RegL { get; set; } + [ObservableProperty] public partial byte RegH { get; set; } + [ObservableProperty] public partial byte RegL { get; set; } - [Reactive] public UInt16 RegSP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } + [ObservableProperty] public partial UInt16 RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } - [Reactive] public UInt16 Scanline { get; set; } - [Reactive] public UInt16 Cycle { get; set; } + [ObservableProperty] public partial UInt16 Scanline { get; set; } + [ObservableProperty] public partial UInt16 Cycle { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagHalf { get; set; } - [Reactive] public bool FlagAddSub { get; set; } - [Reactive] public bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagHalf { get; set; } + [ObservableProperty] public partial bool FlagAddSub { get; set; } + [ObservableProperty] public partial bool FlagZero { get; set; } - [Reactive] public bool FlagHalted { get; set; } - [Reactive] public bool FlagEiPending { get; set; } - [Reactive] public bool FlagIme { get; set; } + [ObservableProperty] public partial bool FlagHalted { get; set; } + [ObservableProperty] public partial bool FlagEiPending { get; set; } + [ObservableProperty] public partial bool FlagIme { get; set; } - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public GbStatusViewModel() { - this.WhenAnyValue(x => x.FlagCarry, x => x.FlagHalf, x => x.FlagAddSub, x => x.FlagZero).Subscribe(x => UpdateFlagsValue()); - - this.WhenAnyValue(x => x.RegFlags).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate RegFlags while updating the flags - FlagCarry = (x & (byte)GameboyFlags.Carry) != 0; - FlagHalf = (x & (byte)GameboyFlags.HalfCarry) != 0; - FlagAddSub = (x & (byte)GameboyFlags.AddSub) != 0; - FlagZero = (x & (byte)GameboyFlags.Zero) != 0; + bool preventUpdate = false; + + this.ObserveProp([nameof(FlagCarry), nameof(FlagHalf), nameof(FlagAddSub), nameof(FlagZero)], () => { + if(!preventUpdate) { + UpdateFlagsValue(); + } + }); + + this.ObserveProp(nameof(RegFlags), () => { + preventUpdate = true; + FlagCarry = (RegFlags & (byte)GameboyFlags.Carry) != 0; + FlagHalf = (RegFlags & (byte)GameboyFlags.HalfCarry) != 0; + FlagAddSub = (RegFlags & (byte)GameboyFlags.AddSub) != 0; + FlagZero = (RegFlags & (byte)GameboyFlags.Zero) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/GbaStatusViewModel.cs b/UI/Debugger/StatusViews/GbaStatusViewModel.cs index a3d21cf52..abb967e23 100644 --- a/UI/Debugger/StatusViews/GbaStatusViewModel.cs +++ b/UI/Debugger/StatusViews/GbaStatusViewModel.cs @@ -1,54 +1,63 @@ using Avalonia.Collections; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using Mesen.Utilities; using System; +using System.ComponentModel; using System.Text; namespace Mesen.Debugger.StatusViews { - public class GbaStatusViewModel : BaseConsoleStatusViewModel + public partial class GbaStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt32 Reg0 { get; set; } - [Reactive] public UInt32 Reg1 { get; set; } - [Reactive] public UInt32 Reg2 { get; set; } - [Reactive] public UInt32 Reg3 { get; set; } - [Reactive] public UInt32 Reg4 { get; set; } - [Reactive] public UInt32 Reg5 { get; set; } - [Reactive] public UInt32 Reg6 { get; set; } - [Reactive] public UInt32 Reg7 { get; set; } - [Reactive] public UInt32 Reg8 { get; set; } - [Reactive] public UInt32 Reg9 { get; set; } - [Reactive] public UInt32 Reg10 { get; set; } - [Reactive] public UInt32 Reg11 { get; set; } - [Reactive] public UInt32 Reg12 { get; set; } - [Reactive] public UInt32 Reg13 { get; set; } - [Reactive] public UInt32 Reg14 { get; set; } - [Reactive] public UInt32 Reg15 { get; set; } - - [Reactive] public UInt32 RegCpsr { get; set; } - - [Reactive] public GbaCpuMode Mode { get; set; } - [Reactive] public string ModeString { get; set; } = GbaCpuMode.User.ToString(); - - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagNegative { get; set; } - [Reactive] public bool FlagOverflow { get; set; } - - [Reactive] public bool FlagThumb { get; set; } - [Reactive] public bool FlagIrqDisable { get; set; } - [Reactive] public bool FlagFiqDisable { get; set; } - - [Reactive] public string StackPreview { get; set; } = ""; - - [Reactive] public UInt16 Scanline { get; set; } - [Reactive] public UInt16 Cycle { get; set; } + [ObservableProperty] public partial UInt32 Reg0 { get; set; } + [ObservableProperty] public partial UInt32 Reg1 { get; set; } + [ObservableProperty] public partial UInt32 Reg2 { get; set; } + [ObservableProperty] public partial UInt32 Reg3 { get; set; } + [ObservableProperty] public partial UInt32 Reg4 { get; set; } + [ObservableProperty] public partial UInt32 Reg5 { get; set; } + [ObservableProperty] public partial UInt32 Reg6 { get; set; } + [ObservableProperty] public partial UInt32 Reg7 { get; set; } + [ObservableProperty] public partial UInt32 Reg8 { get; set; } + [ObservableProperty] public partial UInt32 Reg9 { get; set; } + [ObservableProperty] public partial UInt32 Reg10 { get; set; } + [ObservableProperty] public partial UInt32 Reg11 { get; set; } + [ObservableProperty] public partial UInt32 Reg12 { get; set; } + [ObservableProperty] public partial UInt32 Reg13 { get; set; } + [ObservableProperty] public partial UInt32 Reg14 { get; set; } + [ObservableProperty] public partial UInt32 Reg15 { get; set; } + + [ObservableProperty] public partial UInt32 RegCpsr { get; set; } + + [ObservableProperty] public partial GbaCpuMode Mode { get; set; } + [ObservableProperty] public partial string ModeString { get; set; } = GbaCpuMode.User.ToString(); + + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagNegative { get; set; } + [ObservableProperty] public partial bool FlagOverflow { get; set; } + + [ObservableProperty] public partial bool FlagThumb { get; set; } + [ObservableProperty] public partial bool FlagIrqDisable { get; set; } + [ObservableProperty] public partial bool FlagFiqDisable { get; set; } + + [ObservableProperty] public partial string StackPreview { get; set; } = ""; + + [ObservableProperty] public partial UInt16 Scanline { get; set; } + [ObservableProperty] public partial UInt16 Cycle { get; set; } public GbaStatusViewModel() { - this.WhenAnyValue(x => x.FlagZero, x => x.FlagCarry, x => x.FlagNegative, x => x.FlagOverflow).Subscribe(x => UpdateFlags()); - this.WhenAnyValue(x => x.FlagThumb, x => x.FlagIrqDisable, x => x.FlagFiqDisable, x => x.Mode).Subscribe(x => UpdateFlags()); + this.ObserveProp([ + nameof(FlagZero), + nameof(FlagCarry), + nameof(FlagNegative), + nameof(FlagOverflow), + nameof(FlagThumb), + nameof(FlagIrqDisable), + nameof(FlagFiqDisable), + nameof(Mode) + ], () => UpdateFlags()); } private void UpdateFlags() diff --git a/UI/Debugger/StatusViews/GsuStatusViewModel.cs b/UI/Debugger/StatusViews/GsuStatusViewModel.cs index f76a4288c..6309a41c3 100644 --- a/UI/Debugger/StatusViews/GsuStatusViewModel.cs +++ b/UI/Debugger/StatusViews/GsuStatusViewModel.cs @@ -1,72 +1,76 @@ using Avalonia.Collections; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class GsuStatusViewModel : BaseConsoleStatusViewModel + public partial class GsuStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt16 Reg0 { get; set; } - [Reactive] public UInt16 Reg1 { get; set; } - [Reactive] public UInt16 Reg2 { get; set; } - [Reactive] public UInt16 Reg3 { get; set; } - [Reactive] public UInt16 Reg4 { get; set; } - [Reactive] public UInt16 Reg5 { get; set; } - [Reactive] public UInt16 Reg6 { get; set; } - [Reactive] public UInt16 Reg7 { get; set; } - [Reactive] public UInt16 Reg8 { get; set; } - [Reactive] public UInt16 Reg9 { get; set; } - [Reactive] public UInt16 Reg10 { get; set; } - [Reactive] public UInt16 Reg11 { get; set; } - [Reactive] public UInt16 Reg12 { get; set; } - [Reactive] public UInt16 Reg13 { get; set; } - [Reactive] public UInt16 Reg14 { get; set; } - [Reactive] public UInt16 Reg15 { get; set; } - - [Reactive] public UInt16 RegSfr { get; set; } - [Reactive] public UInt16 RamAddrCache { get; set; } - - [Reactive] public byte RegSrc { get; set; } - [Reactive] public byte RegDst { get; set; } - [Reactive] public byte RegColor { get; set; } - [Reactive] public byte RegPor { get; set; } - - [Reactive] public byte RegPbr { get; set; } - [Reactive] public byte RomBank { get; set; } - [Reactive] public byte RamBank { get; set; } - - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagSign { get; set; } - [Reactive] public bool FlagOverflow { get; set; } - - [Reactive] public bool FlagAlt1 { get; set; } - [Reactive] public bool FlagAlt2 { get; set; } - [Reactive] public bool FlagIrq { get; set; } - [Reactive] public bool FlagRomReadPending { get; set; } - - [Reactive] public bool FlagRunning { get; set; } - [Reactive] public bool FlagImmLow { get; set; } - [Reactive] public bool FlagImmHigh { get; set; } - [Reactive] public bool FlagPrefix { get; set; } - - [Reactive] public bool FlagPlotTransparent { get; set; } - [Reactive] public bool FlagPlotDither { get; set; } - [Reactive] public bool FlagColorHighNibble { get; set; } - [Reactive] public bool FlagColorFreezeHigh { get; set; } - [Reactive] public bool FlagObjMode { get; set; } + [ObservableProperty] public partial UInt16 Reg0 { get; set; } + [ObservableProperty] public partial UInt16 Reg1 { get; set; } + [ObservableProperty] public partial UInt16 Reg2 { get; set; } + [ObservableProperty] public partial UInt16 Reg3 { get; set; } + [ObservableProperty] public partial UInt16 Reg4 { get; set; } + [ObservableProperty] public partial UInt16 Reg5 { get; set; } + [ObservableProperty] public partial UInt16 Reg6 { get; set; } + [ObservableProperty] public partial UInt16 Reg7 { get; set; } + [ObservableProperty] public partial UInt16 Reg8 { get; set; } + [ObservableProperty] public partial UInt16 Reg9 { get; set; } + [ObservableProperty] public partial UInt16 Reg10 { get; set; } + [ObservableProperty] public partial UInt16 Reg11 { get; set; } + [ObservableProperty] public partial UInt16 Reg12 { get; set; } + [ObservableProperty] public partial UInt16 Reg13 { get; set; } + [ObservableProperty] public partial UInt16 Reg14 { get; set; } + [ObservableProperty] public partial UInt16 Reg15 { get; set; } + + [ObservableProperty] public partial UInt16 RegSfr { get; set; } + [ObservableProperty] public partial UInt16 RamAddrCache { get; set; } + + [ObservableProperty] public partial byte RegSrc { get; set; } + [ObservableProperty] public partial byte RegDst { get; set; } + [ObservableProperty] public partial byte RegColor { get; set; } + [ObservableProperty] public partial byte RegPor { get; set; } + + [ObservableProperty] public partial byte RegPbr { get; set; } + [ObservableProperty] public partial byte RomBank { get; set; } + [ObservableProperty] public partial byte RamBank { get; set; } + + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagSign { get; set; } + [ObservableProperty] public partial bool FlagOverflow { get; set; } + + [ObservableProperty] public partial bool FlagAlt1 { get; set; } + [ObservableProperty] public partial bool FlagAlt2 { get; set; } + [ObservableProperty] public partial bool FlagIrq { get; set; } + [ObservableProperty] public partial bool FlagRomReadPending { get; set; } + + [ObservableProperty] public partial bool FlagRunning { get; set; } + [ObservableProperty] public partial bool FlagImmLow { get; set; } + [ObservableProperty] public partial bool FlagImmHigh { get; set; } + [ObservableProperty] public partial bool FlagPrefix { get; set; } + + [ObservableProperty] public partial bool FlagPlotTransparent { get; set; } + [ObservableProperty] public partial bool FlagPlotDither { get; set; } + [ObservableProperty] public partial bool FlagColorHighNibble { get; set; } + [ObservableProperty] public partial bool FlagColorFreezeHigh { get; set; } + [ObservableProperty] public partial bool FlagObjMode { get; set; } public GsuStatusViewModel() { - this.WhenAnyValue(x => x.FlagZero, x => x.FlagCarry, x => x.FlagSign, x => x.FlagOverflow).Subscribe(x => UpdateSfrValue()); - this.WhenAnyValue(x => x.FlagAlt1, x => x.FlagAlt2, x => x.FlagIrq, x => x.FlagRomReadPending).Subscribe(x => UpdateSfrValue()); - this.WhenAnyValue(x => x.FlagRunning, x => x.FlagImmLow, x => x.FlagImmHigh, x => x.FlagPrefix).Subscribe(x => UpdateSfrValue()); - - this.WhenAnyValue(x => x.FlagPlotTransparent, x => x.FlagPlotDither, x => x.FlagColorHighNibble).Subscribe(x => UpdatePorValue()); - this.WhenAnyValue(x => x.FlagColorFreezeHigh, x => x.FlagObjMode).Subscribe(x => UpdatePorValue()); + this.ObserveProp([ + nameof(FlagZero), nameof(FlagCarry), nameof(FlagSign), nameof(FlagOverflow), + nameof(FlagAlt1), nameof(FlagAlt2), nameof(FlagIrq), nameof(FlagRomReadPending), + nameof(FlagRunning), nameof(FlagImmLow), nameof(FlagImmHigh), nameof(FlagPrefix) + ], UpdateSfrValue); + + this.ObserveProp([ + nameof(FlagPlotTransparent), nameof(FlagPlotDither), nameof(FlagColorHighNibble), + nameof(FlagColorFreezeHigh), nameof(FlagObjMode) + ], UpdatePorValue); } private void UpdateSfrValue() diff --git a/UI/Debugger/StatusViews/NecDspStatusViewModel.cs b/UI/Debugger/StatusViews/NecDspStatusViewModel.cs index 8299f2d0e..efce85b22 100644 --- a/UI/Debugger/StatusViews/NecDspStatusViewModel.cs +++ b/UI/Debugger/StatusViews/NecDspStatusViewModel.cs @@ -1,42 +1,41 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class NecDspStatusViewModel : BaseConsoleStatusViewModel + public partial class NecDspStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt16 RegTR { get; set; } - [Reactive] public UInt16 RegTRB { get; set; } - [Reactive] public UInt16 RegRP { get; set; } - [Reactive] public UInt16 RegDP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } - [Reactive] public byte RegSP { get; set; } - - [Reactive] public UInt16 RegDR { get; set; } - [Reactive] public UInt16 RegSR { get; set; } - [Reactive] public UInt16 RegK { get; set; } - [Reactive] public UInt16 RegL { get; set; } - [Reactive] public UInt16 RegM { get; set; } - [Reactive] public UInt16 RegN { get; set; } - [Reactive] public UInt16 RegA { get; set; } - [Reactive] public UInt16 RegB { get; set; } - - [Reactive] public bool RegA_C { get; set; } - [Reactive] public bool RegA_Z { get; set; } - [Reactive] public bool RegA_V0 { get; set; } - [Reactive] public bool RegA_V1 { get; set; } - [Reactive] public bool RegA_S0 { get; set; } - [Reactive] public bool RegA_S1 { get; set; } - - [Reactive] public bool RegB_C { get; set; } - [Reactive] public bool RegB_Z { get; set; } - [Reactive] public bool RegB_V0 { get; set; } - [Reactive] public bool RegB_V1 { get; set; } - [Reactive] public bool RegB_S0 { get; set; } - [Reactive] public bool RegB_S1 { get; set; } + [ObservableProperty] public partial UInt16 RegTR { get; set; } + [ObservableProperty] public partial UInt16 RegTRB { get; set; } + [ObservableProperty] public partial UInt16 RegRP { get; set; } + [ObservableProperty] public partial UInt16 RegDP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } + [ObservableProperty] public partial byte RegSP { get; set; } + + [ObservableProperty] public partial UInt16 RegDR { get; set; } + [ObservableProperty] public partial UInt16 RegSR { get; set; } + [ObservableProperty] public partial UInt16 RegK { get; set; } + [ObservableProperty] public partial UInt16 RegL { get; set; } + [ObservableProperty] public partial UInt16 RegM { get; set; } + [ObservableProperty] public partial UInt16 RegN { get; set; } + [ObservableProperty] public partial UInt16 RegA { get; set; } + [ObservableProperty] public partial UInt16 RegB { get; set; } + + [ObservableProperty] public partial bool RegA_C { get; set; } + [ObservableProperty] public partial bool RegA_Z { get; set; } + [ObservableProperty] public partial bool RegA_V0 { get; set; } + [ObservableProperty] public partial bool RegA_V1 { get; set; } + [ObservableProperty] public partial bool RegA_S0 { get; set; } + [ObservableProperty] public partial bool RegA_S1 { get; set; } + + [ObservableProperty] public partial bool RegB_C { get; set; } + [ObservableProperty] public partial bool RegB_Z { get; set; } + [ObservableProperty] public partial bool RegB_V0 { get; set; } + [ObservableProperty] public partial bool RegB_V1 { get; set; } + [ObservableProperty] public partial bool RegB_S0 { get; set; } + [ObservableProperty] public partial bool RegB_S1 { get; set; } public NecDspStatusViewModel() { diff --git a/UI/Debugger/StatusViews/NesStatusViewModel.cs b/UI/Debugger/StatusViews/NesStatusViewModel.cs index e7a05eb72..03a9740c2 100644 --- a/UI/Debugger/StatusViews/NesStatusViewModel.cs +++ b/UI/Debugger/StatusViews/NesStatusViewModel.cs @@ -1,86 +1,91 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class NesStatusViewModel : BaseConsoleStatusViewModel + public partial class NesStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public byte RegA { get; set; } - [Reactive] public byte RegX { get; set; } - [Reactive] public byte RegY { get; set; } - [Reactive] public byte RegSP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } - [Reactive] public byte RegPS { get; set; } - - [Reactive] public bool FlagN { get; set; } - [Reactive] public bool FlagV { get; set; } - [Reactive] public bool FlagD { get; set; } - [Reactive] public bool FlagI { get; set; } - [Reactive] public bool FlagZ { get; set; } - [Reactive] public bool FlagC { get; set; } - - [Reactive] public bool FlagNmi { get; set; } - - [Reactive] public bool FlagIrqExternal { get; set; } - [Reactive] public bool FlagIrqFrameCount { get; set; } - [Reactive] public bool FlagIrqDmc { get; set; } - [Reactive] public bool FlagIrqFdsDisk { get; set; } - - [Reactive] public uint Cycle { get; private set; } - [Reactive] public int Scanline { get; private set; } - [Reactive] public UInt32 FrameCount { get; private set; } - [Reactive] public UInt16 VramAddr { get; set; } - [Reactive] public UInt16 TmpVramAddr { get; set; } - [Reactive] public UInt16 BusAddr { get; set; } - [Reactive] public byte ScrollX { get; set; } - [Reactive] public bool Sprite0Hit { get; set; } - [Reactive] public bool SpriteOverflow { get; set; } - [Reactive] public bool VerticalBlank { get; set; } - [Reactive] public bool WriteToggle { get; set; } + [ObservableProperty] public partial byte RegA { get; set; } + [ObservableProperty] public partial byte RegX { get; set; } + [ObservableProperty] public partial byte RegY { get; set; } + [ObservableProperty] public partial byte RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } + [ObservableProperty] public partial byte RegPS { get; set; } + + [ObservableProperty] public partial bool FlagN { get; set; } + [ObservableProperty] public partial bool FlagV { get; set; } + [ObservableProperty] public partial bool FlagD { get; set; } + [ObservableProperty] public partial bool FlagI { get; set; } + [ObservableProperty] public partial bool FlagZ { get; set; } + [ObservableProperty] public partial bool FlagC { get; set; } + + [ObservableProperty] public partial bool FlagNmi { get; set; } + + [ObservableProperty] public partial bool FlagIrqExternal { get; set; } + [ObservableProperty] public partial bool FlagIrqFrameCount { get; set; } + [ObservableProperty] public partial bool FlagIrqDmc { get; set; } + [ObservableProperty] public partial bool FlagIrqFdsDisk { get; set; } + + [ObservableProperty] public partial uint Cycle { get; private set; } + [ObservableProperty] public partial int Scanline { get; private set; } + [ObservableProperty] public partial UInt32 FrameCount { get; private set; } + [ObservableProperty] public partial UInt16 VramAddr { get; set; } + [ObservableProperty] public partial UInt16 TmpVramAddr { get; set; } + [ObservableProperty] public partial UInt16 BusAddr { get; set; } + [ObservableProperty] public partial byte ScrollX { get; set; } + [ObservableProperty] public partial bool Sprite0Hit { get; set; } + [ObservableProperty] public partial bool SpriteOverflow { get; set; } + [ObservableProperty] public partial bool VerticalBlank { get; set; } + [ObservableProperty] public partial bool WriteToggle { get; set; } //Mask - [Reactive] public bool BgEnabled { get; set; } - [Reactive] public bool SpritesEnabled { get; set; } - [Reactive] public bool BgMaskLeft { get; set; } - [Reactive] public bool SpriteMaskLeft { get; set; } - [Reactive] public bool Grayscale { get; set; } - [Reactive] public bool IntensifyRed { get; set; } - [Reactive] public bool IntensifyGreen { get; set; } - [Reactive] public bool IntensifyBlue { get; set; } + [ObservableProperty] public partial bool BgEnabled { get; set; } + [ObservableProperty] public partial bool SpritesEnabled { get; set; } + [ObservableProperty] public partial bool BgMaskLeft { get; set; } + [ObservableProperty] public partial bool SpriteMaskLeft { get; set; } + [ObservableProperty] public partial bool Grayscale { get; set; } + [ObservableProperty] public partial bool IntensifyRed { get; set; } + [ObservableProperty] public partial bool IntensifyGreen { get; set; } + [ObservableProperty] public partial bool IntensifyBlue { get; set; } //Control - [Reactive] public bool LargeSprites { get; set; } - [Reactive] public bool NmiOnVBlank { get; set; } - [Reactive] public bool VerticalWrite { get; set; } - [Reactive] public bool BgAt1000 { get; set; } - [Reactive] public bool SpritesAt1000 { get; set; } + [ObservableProperty] public partial bool LargeSprites { get; set; } + [ObservableProperty] public partial bool NmiOnVBlank { get; set; } + [ObservableProperty] public partial bool VerticalWrite { get; set; } + [ObservableProperty] public partial bool BgAt1000 { get; set; } + [ObservableProperty] public partial bool SpritesAt1000 { get; set; } - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public NesStatusViewModel() { - this.WhenAnyValue(x => x.FlagC, x => x.FlagD, x => x.FlagI, x => x.FlagN, x => x.FlagV, x => x.FlagZ).Subscribe(x => { - RegPS = (byte)( - (FlagN ? (byte)NesCpuFlags.Negative : 0) | - (FlagV ? (byte)NesCpuFlags.Overflow : 0) | - (FlagD ? (byte)NesCpuFlags.Decimal : 0) | - (FlagI ? (byte)NesCpuFlags.IrqDisable : 0) | - (FlagZ ? (byte)NesCpuFlags.Zero : 0) | - (FlagC ? (byte)NesCpuFlags.Carry : 0) - ); + bool preventUpdate = false; + + this.ObserveProp([nameof(FlagC), nameof(FlagD), nameof(FlagI), nameof(FlagN), nameof(FlagV), nameof(FlagZ)], () => { + if(!preventUpdate) { + RegPS = (byte)( + (FlagN ? (byte)NesCpuFlags.Negative : 0) | + (FlagV ? (byte)NesCpuFlags.Overflow : 0) | + (FlagD ? (byte)NesCpuFlags.Decimal : 0) | + (FlagI ? (byte)NesCpuFlags.IrqDisable : 0) | + (FlagZ ? (byte)NesCpuFlags.Zero : 0) | + (FlagC ? (byte)NesCpuFlags.Carry : 0) + ); + } }); - this.WhenAnyValue(x => x.RegPS).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate PS while updating the flags - FlagN = (x & (byte)NesCpuFlags.Negative) != 0; - FlagV = (x & (byte)NesCpuFlags.Overflow) != 0; - FlagD = (x & (byte)NesCpuFlags.Decimal) != 0; - FlagI = (x & (byte)NesCpuFlags.IrqDisable) != 0; - FlagZ = (x & (byte)NesCpuFlags.Zero) != 0; - FlagC = (x & (byte)NesCpuFlags.Carry) != 0; + this.ObserveProp(nameof(RegPS), () => { + preventUpdate = true; + FlagN = (RegPS & (byte)NesCpuFlags.Negative) != 0; + FlagV = (RegPS & (byte)NesCpuFlags.Overflow) != 0; + FlagD = (RegPS & (byte)NesCpuFlags.Decimal) != 0; + FlagI = (RegPS & (byte)NesCpuFlags.IrqDisable) != 0; + FlagZ = (RegPS & (byte)NesCpuFlags.Zero) != 0; + FlagC = (RegPS & (byte)NesCpuFlags.Carry) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/PceStatusViewModel.cs b/UI/Debugger/StatusViews/PceStatusViewModel.cs index 877ed925a..0677bcd53 100644 --- a/UI/Debugger/StatusViews/PceStatusViewModel.cs +++ b/UI/Debugger/StatusViews/PceStatusViewModel.cs @@ -1,57 +1,62 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class PceStatusViewModel : BaseConsoleStatusViewModel + public partial class PceStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public byte RegA { get; set; } - [Reactive] public byte RegX { get; set; } - [Reactive] public byte RegY { get; set; } - [Reactive] public byte RegSP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } - [Reactive] public byte RegPS { get; set; } + [ObservableProperty] public partial byte RegA { get; set; } + [ObservableProperty] public partial byte RegX { get; set; } + [ObservableProperty] public partial byte RegY { get; set; } + [ObservableProperty] public partial byte RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } + [ObservableProperty] public partial byte RegPS { get; set; } - [Reactive] public bool FlagN { get; set; } - [Reactive] public bool FlagV { get; set; } - [Reactive] public bool FlagD { get; set; } - [Reactive] public bool FlagI { get; set; } - [Reactive] public bool FlagZ { get; set; } - [Reactive] public bool FlagC { get; set; } - [Reactive] public bool FlagT { get; set; } + [ObservableProperty] public partial bool FlagN { get; set; } + [ObservableProperty] public partial bool FlagV { get; set; } + [ObservableProperty] public partial bool FlagD { get; set; } + [ObservableProperty] public partial bool FlagI { get; set; } + [ObservableProperty] public partial bool FlagZ { get; set; } + [ObservableProperty] public partial bool FlagC { get; set; } + [ObservableProperty] public partial bool FlagT { get; set; } - [Reactive] public UInt16 Cycle { get; private set; } - [Reactive] public UInt16 Scanline { get; private set; } - [Reactive] public UInt32 FrameCount { get; private set; } + [ObservableProperty] public partial UInt16 Cycle { get; private set; } + [ObservableProperty] public partial UInt16 Scanline { get; private set; } + [ObservableProperty] public partial UInt32 FrameCount { get; private set; } - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public PceStatusViewModel() { - this.WhenAnyValue(x => x.FlagC, x => x.FlagD, x => x.FlagI, x => x.FlagN, x => x.FlagV, x => x.FlagZ, x => x.FlagT).Subscribe(x => { - RegPS = (byte)( - (FlagN ? (byte)PceCpuFlags.Negative : 0) | - (FlagV ? (byte)PceCpuFlags.Overflow : 0) | - (FlagT ? (byte)PceCpuFlags.Memory : 0) | - (FlagD ? (byte)PceCpuFlags.Decimal : 0) | - (FlagI ? (byte)PceCpuFlags.IrqDisable : 0) | - (FlagZ ? (byte)PceCpuFlags.Zero : 0) | - (FlagC ? (byte)PceCpuFlags.Carry : 0) - ); + bool preventUpdate = false; + + this.ObserveProp([nameof(FlagC), nameof(FlagD), nameof(FlagI), nameof(FlagN), nameof(FlagV), nameof(FlagZ), nameof(FlagT)], () => { + if(!preventUpdate) { + RegPS = (byte)( + (FlagN ? (byte)PceCpuFlags.Negative : 0) | + (FlagV ? (byte)PceCpuFlags.Overflow : 0) | + (FlagT ? (byte)PceCpuFlags.Memory : 0) | + (FlagD ? (byte)PceCpuFlags.Decimal : 0) | + (FlagI ? (byte)PceCpuFlags.IrqDisable : 0) | + (FlagZ ? (byte)PceCpuFlags.Zero : 0) | + (FlagC ? (byte)PceCpuFlags.Carry : 0) + ); + } }); - this.WhenAnyValue(x => x.RegPS).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate PS while updating the flags - FlagN = (x & (byte)PceCpuFlags.Negative) != 0; - FlagV = (x & (byte)PceCpuFlags.Overflow) != 0; - FlagT = (x & (byte)PceCpuFlags.Memory) != 0; - FlagD = (x & (byte)PceCpuFlags.Decimal) != 0; - FlagI = (x & (byte)PceCpuFlags.IrqDisable) != 0; - FlagZ = (x & (byte)PceCpuFlags.Zero) != 0; - FlagC = (x & (byte)PceCpuFlags.Carry) != 0; + this.ObserveProp(nameof(RegPS), () => { + preventUpdate = true; + FlagN = (RegPS & (byte)PceCpuFlags.Negative) != 0; + FlagV = (RegPS & (byte)PceCpuFlags.Overflow) != 0; + FlagT = (RegPS & (byte)PceCpuFlags.Memory) != 0; + FlagD = (RegPS & (byte)PceCpuFlags.Decimal) != 0; + FlagI = (RegPS & (byte)PceCpuFlags.IrqDisable) != 0; + FlagZ = (RegPS & (byte)PceCpuFlags.Zero) != 0; + FlagC = (RegPS & (byte)PceCpuFlags.Carry) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/SmsStatusViewModel.cs b/UI/Debugger/StatusViews/SmsStatusViewModel.cs index 87815b5f1..cc137491a 100644 --- a/UI/Debugger/StatusViews/SmsStatusViewModel.cs +++ b/UI/Debugger/StatusViews/SmsStatusViewModel.cs @@ -1,74 +1,85 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class SmsStatusViewModel : BaseConsoleStatusViewModel + public partial class SmsStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public byte RegA { get; set; } - [Reactive] public byte RegB { get; set; } - [Reactive] public byte RegC { get; set; } - [Reactive] public byte RegD { get; set; } - [Reactive] public byte RegE { get; set; } - [Reactive] public byte RegFlags { get; set; } - - [Reactive] public byte RegH { get; set; } - [Reactive] public byte RegL { get; set; } - - [Reactive] public UInt16 RegIX { get; set; } - [Reactive] public UInt16 RegIY { get; set; } - - [Reactive] public byte RegR { get; set; } - [Reactive] public byte RegI { get; set; } - - [Reactive] public byte RegAltA { get; set; } - [Reactive] public byte RegAltFlags { get; set; } - [Reactive] public byte RegAltB { get; set; } - [Reactive] public byte RegAltC { get; set; } - [Reactive] public byte RegAltD { get; set; } - [Reactive] public byte RegAltE { get; set; } - [Reactive] public byte RegAltH { get; set; } - [Reactive] public byte RegAltL { get; set; } - - [Reactive] public UInt16 RegSP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } - - [Reactive] public UInt16 Scanline { get; set; } - [Reactive] public UInt16 Cycle { get; set; } - - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagAddSub { get; set; } - [Reactive] public bool FlagParity { get; set; } - [Reactive] public bool FlagF3 { get; set; } - [Reactive] public bool FlagHalf { get; set; } - [Reactive] public bool FlagF5 { get; set; } - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagSign { get; set; } - - [Reactive] public bool FlagIFF1 { get; set; } - [Reactive] public bool FlagIFF2 { get; set; } - [Reactive] public bool FlagHalted { get; set; } - [Reactive] public byte IM { get; set; } - - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial byte RegA { get; set; } + [ObservableProperty] public partial byte RegB { get; set; } + [ObservableProperty] public partial byte RegC { get; set; } + [ObservableProperty] public partial byte RegD { get; set; } + [ObservableProperty] public partial byte RegE { get; set; } + [ObservableProperty] public partial byte RegFlags { get; set; } + + [ObservableProperty] public partial byte RegH { get; set; } + [ObservableProperty] public partial byte RegL { get; set; } + + [ObservableProperty] public partial UInt16 RegIX { get; set; } + [ObservableProperty] public partial UInt16 RegIY { get; set; } + + [ObservableProperty] public partial byte RegR { get; set; } + [ObservableProperty] public partial byte RegI { get; set; } + + [ObservableProperty] public partial byte RegAltA { get; set; } + [ObservableProperty] public partial byte RegAltFlags { get; set; } + [ObservableProperty] public partial byte RegAltB { get; set; } + [ObservableProperty] public partial byte RegAltC { get; set; } + [ObservableProperty] public partial byte RegAltD { get; set; } + [ObservableProperty] public partial byte RegAltE { get; set; } + [ObservableProperty] public partial byte RegAltH { get; set; } + [ObservableProperty] public partial byte RegAltL { get; set; } + + [ObservableProperty] public partial UInt16 RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } + + [ObservableProperty] public partial UInt16 Scanline { get; set; } + [ObservableProperty] public partial UInt16 Cycle { get; set; } + + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagAddSub { get; set; } + [ObservableProperty] public partial bool FlagParity { get; set; } + [ObservableProperty] public partial bool FlagF3 { get; set; } + [ObservableProperty] public partial bool FlagHalf { get; set; } + [ObservableProperty] public partial bool FlagF5 { get; set; } + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagSign { get; set; } + + [ObservableProperty] public partial bool FlagIFF1 { get; set; } + [ObservableProperty] public partial bool FlagIFF2 { get; set; } + [ObservableProperty] public partial bool FlagHalted { get; set; } + [ObservableProperty] public partial byte IM { get; set; } + + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public SmsStatusViewModel() { - this.WhenAnyValue(x => x.FlagCarry, x => x.FlagHalf, x => x.FlagAddSub, x => x.FlagZero).Subscribe(x => UpdateFlagsValue()); - - this.WhenAnyValue(x => x.RegFlags).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate RegFlags while updating the flags - FlagCarry = (x & (byte)SmsCpuFlags.Carry) != 0; - FlagAddSub = (x & (byte)SmsCpuFlags.AddSub) != 0; - FlagParity = (x & (byte)SmsCpuFlags.Parity) != 0; - FlagF3 = (x & (byte)SmsCpuFlags.F3) != 0; - FlagHalf = (x & (byte)SmsCpuFlags.HalfCarry) != 0; - FlagF5 = (x & (byte)SmsCpuFlags.F5) != 0; - FlagZero = (x & (byte)SmsCpuFlags.Zero) != 0; - FlagSign = (x & (byte)SmsCpuFlags.Sign) != 0; + bool preventUpdate = false; + + this.ObserveProp([ + nameof(FlagCarry), nameof(FlagAddSub), nameof(FlagParity), nameof(FlagF3), + nameof(FlagHalf), nameof(FlagF5), nameof(FlagZero), nameof(FlagSign), + + ], () => { + if(!preventUpdate) { + UpdateFlagsValue(); + } + }); + + this.ObserveProp(nameof(RegFlags), () => { + preventUpdate = true; + FlagCarry = (RegFlags & (byte)SmsCpuFlags.Carry) != 0; + FlagAddSub = (RegFlags & (byte)SmsCpuFlags.AddSub) != 0; + FlagParity = (RegFlags & (byte)SmsCpuFlags.Parity) != 0; + FlagF3 = (RegFlags & (byte)SmsCpuFlags.F3) != 0; + FlagHalf = (RegFlags & (byte)SmsCpuFlags.HalfCarry) != 0; + FlagF5 = (RegFlags & (byte)SmsCpuFlags.F5) != 0; + FlagZero = (RegFlags & (byte)SmsCpuFlags.Zero) != 0; + FlagSign = (RegFlags & (byte)SmsCpuFlags.Sign) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/SnesStatusViewModel.cs b/UI/Debugger/StatusViews/SnesStatusViewModel.cs index a595814bd..a8ad53a6b 100644 --- a/UI/Debugger/StatusViews/SnesStatusViewModel.cs +++ b/UI/Debugger/StatusViews/SnesStatusViewModel.cs @@ -1,49 +1,48 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Interop; +using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive.Linq; using System.Text; namespace Mesen.Debugger.StatusViews { - public class SnesStatusViewModel : BaseConsoleStatusViewModel + public partial class SnesStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt16 RegA { get; set; } - [Reactive] public UInt16 RegX { get; set; } - [Reactive] public UInt16 RegY { get; set; } - [Reactive] public UInt16 RegSP { get; set; } - [Reactive] public UInt16 RegD { get; set; } - [Reactive] public UInt32 RegPC { get; set; } - [Reactive] public byte RegDBR { get; set; } - [Reactive] public byte RegPS { get; set; } - - [Reactive] public bool FlagN { get; set; } - [Reactive] public bool FlagV { get; set; } - [Reactive] public bool FlagM { get; set; } - [Reactive] public bool FlagX { get; set; } - [Reactive] public bool FlagD { get; set; } - [Reactive] public bool FlagI { get; set; } - [Reactive] public bool FlagZ { get; set; } - [Reactive] public bool FlagC { get; set; } - - [Reactive] public bool FlagE { get; set; } - - [Reactive] public bool FlagNmi { get; set; } - [Reactive] public bool FlagIrqHvCounters { get; set; } - [Reactive] public bool FlagIrqCoprocessor { get; set; } - - [Reactive] public int Cycle { get; private set; } - [Reactive] public int Scanline { get; private set; } - [Reactive] public int HClock { get; private set; } - - [Reactive] public int VramAddress { get; private set; } - [Reactive] public int OamAddress { get; private set; } - [Reactive] public int CgRamAddress { get; private set; } - - [Reactive] public string StackPreview { get; set; } = ""; + [ObservableProperty] public partial UInt16 RegA { get; set; } + [ObservableProperty] public partial UInt16 RegX { get; set; } + [ObservableProperty] public partial UInt16 RegY { get; set; } + [ObservableProperty] public partial UInt16 RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegD { get; set; } + [ObservableProperty] public partial UInt32 RegPC { get; set; } + [ObservableProperty] public partial byte RegDBR { get; set; } + [ObservableProperty] public partial byte RegPS { get; set; } + + [ObservableProperty] public partial bool FlagN { get; set; } + [ObservableProperty] public partial bool FlagV { get; set; } + [ObservableProperty] public partial bool FlagM { get; set; } + [ObservableProperty] public partial bool FlagX { get; set; } + [ObservableProperty] public partial bool FlagD { get; set; } + [ObservableProperty] public partial bool FlagI { get; set; } + [ObservableProperty] public partial bool FlagZ { get; set; } + [ObservableProperty] public partial bool FlagC { get; set; } + + [ObservableProperty] public partial bool FlagE { get; set; } + + [ObservableProperty] public partial bool FlagNmi { get; set; } + [ObservableProperty] public partial bool FlagIrqHvCounters { get; set; } + [ObservableProperty] public partial bool FlagIrqCoprocessor { get; set; } + + [ObservableProperty] public partial int Cycle { get; private set; } + [ObservableProperty] public partial int Scanline { get; private set; } + [ObservableProperty] public partial int HClock { get; private set; } + + [ObservableProperty] public partial int VramAddress { get; private set; } + [ObservableProperty] public partial int OamAddress { get; private set; } + [ObservableProperty] public partial int CgRamAddress { get; private set; } + + [ObservableProperty] public partial string StackPreview { get; set; } = ""; private CpuType _cpuType; @@ -54,19 +53,25 @@ public SnesStatusViewModel(CpuType cpuType) { _cpuType = cpuType; - this.WhenAnyValue(x => x.FlagC, x => x.FlagD, x => x.FlagI, x => x.FlagN).Subscribe(x => UpdatePsValue()); - this.WhenAnyValue(x => x.FlagV, x => x.FlagZ, x => x.FlagM, x => x.FlagX).Subscribe(x => UpdatePsValue()); - - this.WhenAnyValue(x => x.RegPS).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate PS while updating the flags - FlagN = (x & (byte)SnesCpuFlags.Negative) != 0; - FlagV = (x & (byte)SnesCpuFlags.Overflow) != 0; - FlagD = (x & (byte)SnesCpuFlags.Decimal) != 0; - FlagI = (x & (byte)SnesCpuFlags.IrqDisable) != 0; - FlagZ = (x & (byte)SnesCpuFlags.Zero) != 0; - FlagC = (x & (byte)SnesCpuFlags.Carry) != 0; - FlagX = (x & (byte)SnesCpuFlags.IndexMode8) != 0; - FlagM = (x & (byte)SnesCpuFlags.MemoryMode8) != 0; + bool preventUpdate = false; + + this.ObserveProp([nameof(FlagC), nameof(FlagD), nameof(FlagI), nameof(FlagN), nameof(FlagV), nameof(FlagZ), nameof(FlagM), nameof(FlagX)], () => { + if(!preventUpdate) { + UpdatePsValue(); + } + }); + + this.ObserveProp(nameof(RegPS), () => { + preventUpdate = true; + FlagN = (RegPS & (byte)SnesCpuFlags.Negative) != 0; + FlagV = (RegPS & (byte)SnesCpuFlags.Overflow) != 0; + FlagD = (RegPS & (byte)SnesCpuFlags.Decimal) != 0; + FlagI = (RegPS & (byte)SnesCpuFlags.IrqDisable) != 0; + FlagZ = (RegPS & (byte)SnesCpuFlags.Zero) != 0; + FlagC = (RegPS & (byte)SnesCpuFlags.Carry) != 0; + FlagX = (RegPS & (byte)SnesCpuFlags.IndexMode8) != 0; + FlagM = (RegPS & (byte)SnesCpuFlags.MemoryMode8) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/SpcStatusViewModel.cs b/UI/Debugger/StatusViews/SpcStatusViewModel.cs index d69f2512e..3f72379ee 100644 --- a/UI/Debugger/StatusViews/SpcStatusViewModel.cs +++ b/UI/Debugger/StatusViews/SpcStatusViewModel.cs @@ -1,46 +1,52 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews { - public class SpcStatusViewModel : BaseConsoleStatusViewModel + public partial class SpcStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public byte RegA { get; set; } - [Reactive] public byte RegX { get; set; } - [Reactive] public byte RegY { get; set; } - [Reactive] public byte RegSP { get; set; } - [Reactive] public UInt16 RegPC { get; set; } - [Reactive] public byte RegPS { get; set; } + [ObservableProperty] public partial byte RegA { get; set; } + [ObservableProperty] public partial byte RegX { get; set; } + [ObservableProperty] public partial byte RegY { get; set; } + [ObservableProperty] public partial byte RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegPC { get; set; } + [ObservableProperty] public partial byte RegPS { get; set; } - [Reactive] public bool FlagN { get; set; } - [Reactive] public bool FlagV { get; set; } - [Reactive] public bool FlagP { get; set; } - [Reactive] public bool FlagB { get; set; } - [Reactive] public bool FlagH { get; set; } - [Reactive] public bool FlagI { get; set; } - [Reactive] public bool FlagZ { get; set; } - [Reactive] public bool FlagC { get; set; } + [ObservableProperty] public partial bool FlagN { get; set; } + [ObservableProperty] public partial bool FlagV { get; set; } + [ObservableProperty] public partial bool FlagP { get; set; } + [ObservableProperty] public partial bool FlagB { get; set; } + [ObservableProperty] public partial bool FlagH { get; set; } + [ObservableProperty] public partial bool FlagI { get; set; } + [ObservableProperty] public partial bool FlagZ { get; set; } + [ObservableProperty] public partial bool FlagC { get; set; } - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public SpcStatusViewModel() { - this.WhenAnyValue(x => x.FlagC, x => x.FlagP, x => x.FlagB, x => x.FlagH).Subscribe(x => UpdatePsValue()); - this.WhenAnyValue(x => x.FlagI, x => x.FlagN, x => x.FlagV, x => x.FlagZ).Subscribe(x => UpdatePsValue()); + bool preventUpdate = false; - this.WhenAnyValue(x => x.RegPS).Subscribe(x => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate PS while updating the flags - FlagN = (x & (byte)SpcFlags.Negative) != 0; - FlagV = (x & (byte)SpcFlags.Overflow) != 0; - FlagP = (x & (byte)SpcFlags.DirectPage) != 0; - FlagB = (x & (byte)SpcFlags.Break) != 0; - FlagH = (x & (byte)SpcFlags.HalfCarry) != 0; - FlagI = (x & (byte)SpcFlags.IrqEnable) != 0; - FlagZ = (x & (byte)SpcFlags.Zero) != 0; - FlagC = (x & (byte)SpcFlags.Carry) != 0; + this.ObserveProp([nameof(FlagC), nameof(FlagP), nameof(FlagB), nameof(FlagH), nameof(FlagI), nameof(FlagN), nameof(FlagV), nameof(FlagZ)], () => { + if(!preventUpdate) { + UpdatePsValue(); + } + }); + + this.ObserveProp(nameof(RegPS), () => { + preventUpdate = true; + FlagN = (RegPS & (byte)SpcFlags.Negative) != 0; + FlagV = (RegPS & (byte)SpcFlags.Overflow) != 0; + FlagP = (RegPS & (byte)SpcFlags.DirectPage) != 0; + FlagB = (RegPS & (byte)SpcFlags.Break) != 0; + FlagH = (RegPS & (byte)SpcFlags.HalfCarry) != 0; + FlagI = (RegPS & (byte)SpcFlags.IrqEnable) != 0; + FlagZ = (RegPS & (byte)SpcFlags.Zero) != 0; + FlagC = (RegPS & (byte)SpcFlags.Carry) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/StatusViews/St018StatusViewModel.cs b/UI/Debugger/StatusViews/St018StatusViewModel.cs index 4c485e71d..57d543efa 100644 --- a/UI/Debugger/StatusViews/St018StatusViewModel.cs +++ b/UI/Debugger/StatusViews/St018StatusViewModel.cs @@ -1,50 +1,55 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; namespace Mesen.Debugger.StatusViews; -public class St018StatusViewModel : BaseConsoleStatusViewModel +public partial class St018StatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt32 Reg0 { get; set; } - [Reactive] public UInt32 Reg1 { get; set; } - [Reactive] public UInt32 Reg2 { get; set; } - [Reactive] public UInt32 Reg3 { get; set; } - [Reactive] public UInt32 Reg4 { get; set; } - [Reactive] public UInt32 Reg5 { get; set; } - [Reactive] public UInt32 Reg6 { get; set; } - [Reactive] public UInt32 Reg7 { get; set; } - [Reactive] public UInt32 Reg8 { get; set; } - [Reactive] public UInt32 Reg9 { get; set; } - [Reactive] public UInt32 Reg10 { get; set; } - [Reactive] public UInt32 Reg11 { get; set; } - [Reactive] public UInt32 Reg12 { get; set; } - [Reactive] public UInt32 Reg13 { get; set; } - [Reactive] public UInt32 Reg14 { get; set; } - [Reactive] public UInt32 Reg15 { get; set; } - - [Reactive] public UInt32 RegCpsr { get; set; } - - [Reactive] public ArmV3CpuMode Mode { get; set; } - [Reactive] public string ModeString { get; set; } = ArmV3CpuMode.User.ToString(); - - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagNegative { get; set; } - [Reactive] public bool FlagOverflow { get; set; } - - [Reactive] public bool FlagThumb { get; set; } - [Reactive] public bool FlagIrqDisable { get; set; } - [Reactive] public bool FlagFiqDisable { get; set; } - - [Reactive] public string StackPreview { get; set; } = ""; + [ObservableProperty] public partial UInt32 Reg0 { get; set; } + [ObservableProperty] public partial UInt32 Reg1 { get; set; } + [ObservableProperty] public partial UInt32 Reg2 { get; set; } + [ObservableProperty] public partial UInt32 Reg3 { get; set; } + [ObservableProperty] public partial UInt32 Reg4 { get; set; } + [ObservableProperty] public partial UInt32 Reg5 { get; set; } + [ObservableProperty] public partial UInt32 Reg6 { get; set; } + [ObservableProperty] public partial UInt32 Reg7 { get; set; } + [ObservableProperty] public partial UInt32 Reg8 { get; set; } + [ObservableProperty] public partial UInt32 Reg9 { get; set; } + [ObservableProperty] public partial UInt32 Reg10 { get; set; } + [ObservableProperty] public partial UInt32 Reg11 { get; set; } + [ObservableProperty] public partial UInt32 Reg12 { get; set; } + [ObservableProperty] public partial UInt32 Reg13 { get; set; } + [ObservableProperty] public partial UInt32 Reg14 { get; set; } + [ObservableProperty] public partial UInt32 Reg15 { get; set; } + + [ObservableProperty] public partial UInt32 RegCpsr { get; set; } + + [ObservableProperty] public partial ArmV3CpuMode Mode { get; set; } + [ObservableProperty] public partial string ModeString { get; set; } = ArmV3CpuMode.User.ToString(); + + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagNegative { get; set; } + [ObservableProperty] public partial bool FlagOverflow { get; set; } + + [ObservableProperty] public partial bool FlagIrqDisable { get; set; } + [ObservableProperty] public partial bool FlagFiqDisable { get; set; } + + [ObservableProperty] public partial string StackPreview { get; set; } = ""; public St018StatusViewModel() { - this.WhenAnyValue(x => x.FlagZero, x => x.FlagCarry, x => x.FlagNegative, x => x.FlagOverflow).Subscribe(x => UpdateFlags()); - this.WhenAnyValue(x => x.FlagIrqDisable, x => x.FlagFiqDisable).Subscribe(x => UpdateFlags()); + this.ObserveProp([ + nameof(FlagZero), + nameof(FlagCarry), + nameof(FlagNegative), + nameof(FlagOverflow), + nameof(FlagIrqDisable), + nameof(FlagFiqDisable) + ], () => UpdateFlags()); } private void UpdateFlags() diff --git a/UI/Debugger/StatusViews/WsStatusViewModel.cs b/UI/Debugger/StatusViews/WsStatusViewModel.cs index 4bd9cea87..e26216b94 100644 --- a/UI/Debugger/StatusViews/WsStatusViewModel.cs +++ b/UI/Debugger/StatusViews/WsStatusViewModel.cs @@ -1,69 +1,77 @@ -using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Interop; +using Mesen.Utilities; using System; using System.Text; using System.Text.RegularExpressions; namespace Mesen.Debugger.StatusViews; -public class WsStatusViewModel : BaseConsoleStatusViewModel +public partial class WsStatusViewModel : BaseConsoleStatusViewModel { - [Reactive] public UInt16 RegAX { get; set; } - [Reactive] public UInt16 RegBX { get; set; } - [Reactive] public UInt16 RegCX { get; set; } - [Reactive] public UInt16 RegDX { get; set; } - [Reactive] public UInt16 RegFlags { get; set; } + [ObservableProperty] public partial UInt16 RegAX { get; set; } + [ObservableProperty] public partial UInt16 RegBX { get; set; } + [ObservableProperty] public partial UInt16 RegCX { get; set; } + [ObservableProperty] public partial UInt16 RegDX { get; set; } + [ObservableProperty] public partial UInt16 RegFlags { get; set; } - [Reactive] public UInt16 RegSS { get; set; } - [Reactive] public UInt16 RegDS { get; set; } - [Reactive] public UInt16 RegES { get; set; } + [ObservableProperty] public partial UInt16 RegSS { get; set; } + [ObservableProperty] public partial UInt16 RegDS { get; set; } + [ObservableProperty] public partial UInt16 RegES { get; set; } - [Reactive] public UInt16 RegCS { get; set; } - [Reactive] public UInt16 RegIP { get; set; } + [ObservableProperty] public partial UInt16 RegCS { get; set; } + [ObservableProperty] public partial UInt16 RegIP { get; set; } - [Reactive] public UInt16 RegDI { get; set; } - [Reactive] public UInt16 RegSI { get; set; } + [ObservableProperty] public partial UInt16 RegDI { get; set; } + [ObservableProperty] public partial UInt16 RegSI { get; set; } - [Reactive] public UInt16 RegSP { get; set; } - [Reactive] public UInt16 RegBP { get; set; } + [ObservableProperty] public partial UInt16 RegSP { get; set; } + [ObservableProperty] public partial UInt16 RegBP { get; set; } - [Reactive] public UInt16 Scanline { get; set; } - [Reactive] public UInt16 Cycle { get; set; } + [ObservableProperty] public partial UInt16 Scanline { get; set; } + [ObservableProperty] public partial UInt16 Cycle { get; set; } - [Reactive] public bool FlagCarry { get; set; } - [Reactive] public bool FlagAuxCarry { get; set; } - [Reactive] public bool FlagParity { get; set; } - [Reactive] public bool FlagSign { get; set; } - [Reactive] public bool FlagZero { get; set; } - [Reactive] public bool FlagOverflow { get; set; } - [Reactive] public bool FlagTrap { get; set; } - [Reactive] public bool FlagIrq { get; set; } - [Reactive] public bool FlagDirection { get; set; } - [Reactive] public bool FlagMode { get; set; } + [ObservableProperty] public partial bool FlagCarry { get; set; } + [ObservableProperty] public partial bool FlagAuxCarry { get; set; } + [ObservableProperty] public partial bool FlagParity { get; set; } + [ObservableProperty] public partial bool FlagSign { get; set; } + [ObservableProperty] public partial bool FlagZero { get; set; } + [ObservableProperty] public partial bool FlagOverflow { get; set; } + [ObservableProperty] public partial bool FlagTrap { get; set; } + [ObservableProperty] public partial bool FlagIrq { get; set; } + [ObservableProperty] public partial bool FlagDirection { get; set; } + [ObservableProperty] public partial bool FlagMode { get; set; } - [Reactive] public bool FlagHalted { get; set; } + [ObservableProperty] public partial bool FlagHalted { get; set; } - [Reactive] public string StackPreview { get; private set; } = ""; + [ObservableProperty] public partial string StackPreview { get; private set; } = ""; public WsStatusViewModel() { - this.WhenAnyValue(x => x.FlagZero, x => x.FlagCarry, x => x.FlagSign, x => x.FlagOverflow).Subscribe(x => UpdateFlags()); - this.WhenAnyValue(x => x.FlagParity, x => x.FlagIrq, x => x.FlagTrap, x => x.FlagMode).Subscribe(x => UpdateFlags()); - this.WhenAnyValue(x => x.FlagAuxCarry, x => x.FlagDirection).Subscribe(x => UpdateFlags()); - - this.WhenAnyValue(x => x.RegFlags).Subscribe(f => { - using var delayNotifs = DelayChangeNotifications(); //don't reupdate RegFlags while updating the flags - FlagCarry = (f & 0x01) != 0; - FlagParity = (f & 0x04) != 0; - FlagAuxCarry = (f & 0x10) != 0; - FlagZero = (f & 0x40) != 0; - FlagSign = (f & 0x80) != 0; - FlagTrap = (f & 0x100) != 0; - FlagIrq = (f & 0x200) != 0; - FlagDirection = (f & 0x400) != 0; - FlagOverflow = (f & 0x800) != 0; - FlagMode = (f & 0x8000) != 0; + bool preventUpdate = false; + + this.ObserveProp([ + nameof(FlagZero), nameof(FlagCarry), nameof(FlagSign), nameof(FlagOverflow), nameof(FlagParity), + nameof(FlagIrq), nameof(FlagTrap), nameof(FlagMode), nameof(FlagAuxCarry), nameof(FlagDirection) + ], () => { + if(!preventUpdate) { + UpdateFlags(); + } + }); + + this.ObserveProp(nameof(RegFlags), () => { + preventUpdate = true; + FlagCarry = (RegFlags & 0x01) != 0; + FlagParity = (RegFlags & 0x04) != 0; + FlagAuxCarry = (RegFlags & 0x10) != 0; + FlagZero = (RegFlags & 0x40) != 0; + FlagSign = (RegFlags & 0x80) != 0; + FlagTrap = (RegFlags & 0x100) != 0; + FlagIrq = (RegFlags & 0x200) != 0; + FlagDirection = (RegFlags & 0x400) != 0; + FlagOverflow = (RegFlags & 0x800) != 0; + FlagMode = (RegFlags & 0x8000) != 0; + preventUpdate = false; }); } diff --git a/UI/Debugger/Utilities/ContextMenuAction.cs b/UI/Debugger/Utilities/ContextMenuAction.cs index 261c8c201..cdc7d55ac 100644 --- a/UI/Debugger/Utilities/ContextMenuAction.cs +++ b/UI/Debugger/Utilities/ContextMenuAction.cs @@ -2,6 +2,7 @@ using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Config.Shortcuts; using Mesen.Controls; @@ -9,17 +10,15 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; -using System.Reactive; +using System.Reflection; using System.Threading.Tasks; using System.Windows.Input; namespace Mesen.Debugger.Utilities { - public abstract class BaseMenuAction : ViewModelBase, IDisposable + public abstract partial class BaseMenuAction : ViewModelBase, IDisposable { private static Dictionary _iconCache = new(); @@ -31,7 +30,7 @@ public abstract class BaseMenuAction : ViewModelBase, IDisposable static BaseMenuAction() { foreach(ActionType value in Enum.GetValues()) { - _iconCache[value] = value.GetAttribute()?.Icon; + _iconCache[value] = typeof(ActionType).GetMember(value.ToString())[0].GetCustomAttribute()?.Icon; } } @@ -80,15 +79,13 @@ public virtual string Name return null; } - List? _subActions; + private List? _subActions; public List? SubActions { get => _subActions; set { - _subActions = value; - - if(_subActions != null) { + if(value != null) { Func? isEnabled = IsEnabled; IsEnabled = () => { @@ -96,7 +93,7 @@ public List? SubActions return false; } - foreach(object subAction in _subActions) { + foreach(object subAction in value) { if(subAction is BaseMenuAction act) { if(act.IsEnabled == null || act.IsEnabled()) { return true; @@ -106,7 +103,7 @@ public List? SubActions return false; }; } - this.RaiseAndSetIfChanged(ref _subActions, value); + SetProperty(ref _subActions, value); } } @@ -121,13 +118,13 @@ public List? SubActions protected abstract string InternalShortcutText { get; } - [Reactive] public string ShortcutText { get; set; } = ""; - [Reactive] public string ActionName { get; set; } = ""; - [Reactive] public Image? ActionIcon { get; set; } - [Reactive] public bool Enabled { get; set; } - [Reactive] public bool Visible { get; set; } + [ObservableProperty] public partial string ShortcutText { get; set; } = ""; + [ObservableProperty] public partial string ActionName { get; set; } = ""; + [ObservableProperty] public partial Image? ActionIcon { get; set; } + [ObservableProperty] public partial bool Enabled { get; set; } + [ObservableProperty] public partial bool Visible { get; set; } - [Reactive] public string TooltipText { get; set; } = ""; + [ObservableProperty] public partial string TooltipText { get; set; } = ""; private static SimpleCommand _emptyCommand = new SimpleCommand(() => { }); diff --git a/UI/Debugger/Utilities/HdPackCopyHelper.cs b/UI/Debugger/Utilities/HdPackCopyHelper.cs index 167438525..20c3c6544 100644 --- a/UI/Debugger/Utilities/HdPackCopyHelper.cs +++ b/UI/Debugger/Utilities/HdPackCopyHelper.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Input.Platform; using Mesen.Interop; using Mesen.Utilities; using System; diff --git a/UI/Debugger/ViewModels/AssemblerWindowViewModel.cs b/UI/Debugger/ViewModels/AssemblerWindowViewModel.cs index 79c8f9386..6bb0fb097 100644 --- a/UI/Debugger/ViewModels/AssemblerWindowViewModel.cs +++ b/UI/Debugger/ViewModels/AssemblerWindowViewModel.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Utilities; using Mesen.Debugger.Windows; @@ -7,36 +8,33 @@ using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; -using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; namespace Mesen.Debugger.ViewModels { - public class AssemblerWindowViewModel : DisposableViewModel + public partial class AssemblerWindowViewModel : DisposableViewModel { public AssemblerConfig Config { get; } - [Reactive] public string Code { get; set; } = ""; - [Reactive] public string ByteCodeView { get; set; } = ""; - [Reactive] public int StartAddress { get; set; } - [Reactive] public int BytesUsed { get; set; } + [ObservableProperty] public partial string Code { get; set; } = ""; + [ObservableProperty] public partial string ByteCodeView { get; set; } = ""; + [ObservableProperty] public partial int StartAddress { get; set; } + [ObservableProperty] public partial int BytesUsed { get; set; } - [Reactive] public bool HasWarning { get; set; } - [Reactive] public bool IsIdentical { get; set; } - [Reactive] public bool OriginalSizeExceeded { get; set; } - [Reactive] public bool MaxSizeExceeded { get; set; } + [ObservableProperty] public partial bool HasWarning { get; set; } + [ObservableProperty] public partial bool IsIdentical { get; set; } + [ObservableProperty] public partial bool OriginalSizeExceeded { get; set; } + [ObservableProperty] public partial bool MaxSizeExceeded { get; set; } - [Reactive] public bool OkEnabled { get; set; } = false; - [Reactive] public List Errors { get; set; } = new List(); + [ObservableProperty] public partial bool OkEnabled { get; set; } = false; + [ObservableProperty] public partial List Errors { get; set; } = new List(); - [Reactive] public List FileMenuActions { get; private set; } = new(); - [Reactive] public List OptionsMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List OptionsMenuActions { get; private set; } = new(); public CpuType CpuType { get; } private List _bytes = new(); @@ -45,12 +43,12 @@ public class AssemblerWindowViewModel : DisposableViewModel private int _originalAddress = -1; private byte[] _originalCode = Array.Empty(); - [Reactive] public int OriginalByteCount { get; private set; } = 0; + [ObservableProperty] public partial int OriginalByteCount { get; private set; } = 0; [Obsolete("For designer only")] public AssemblerWindowViewModel() : this(CpuType.Snes) { } - public AssemblerWindowViewModel(CpuType cpuType) + public AssemblerWindowViewModel(CpuType cpuType, int address = -1, string code = "", int byteCount = -1) { Config = ConfigManager.Config.Debug.Assembler; CpuType = cpuType; @@ -59,9 +57,21 @@ public AssemblerWindowViewModel(CpuType cpuType) return; } + if(address >= 0) { + OriginalByteCount = byteCount; + _originalAddress = address; + + StartAddress = address; + Code = code; + + if(OriginalByteCount > 0) { + _originalCode = DebugApi.GetMemoryValues(CpuType.ToMemoryType(), (uint)StartAddress, (uint)(StartAddress + OriginalByteCount - 1)); + } + } + MaxAddress = DebugApi.GetMemorySize(CpuType.ToMemoryType()) - 1; - AddDisposable(this.WhenAnyValue(x => x.Code, x => x.StartAddress).Subscribe(_ => { + AddDisposable(this.ObserveProp([nameof(Code), nameof(StartAddress)], () => { UpdateAssembly(Code); })); } @@ -88,20 +98,6 @@ public void InitMenu(Window wnd) }); } - public void InitEditCode(int address, string code, int byteCount) - { - OriginalByteCount = byteCount; - _originalAddress = address; - - using var delayNotifs = DelayChangeNotifications(); - StartAddress = address; - Code = code; - - if(OriginalByteCount > 0) { - _originalCode = DebugApi.GetMemoryValues(CpuType.ToMemoryType(), (uint)StartAddress, (uint)(StartAddress + OriginalByteCount - 1)); - } - } - private void UpdateAssembly(string code) { string[] codeLines = code.Replace("\r", "").Split('\n').Select(x => x.Trim()).ToArray(); diff --git a/UI/Debugger/ViewModels/BreakpointEditViewModel.cs b/UI/Debugger/ViewModels/BreakpointEditViewModel.cs index 4824ff7ef..5680f9e8f 100644 --- a/UI/Debugger/ViewModels/BreakpointEditViewModel.cs +++ b/UI/Debugger/ViewModels/BreakpointEditViewModel.cs @@ -1,31 +1,30 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger.Labels; using Mesen.Debugger.Utilities; using Mesen.Debugger.Windows; using Mesen.Interop; using Mesen.Localization; +using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels { - public class BreakpointEditViewModel : DisposableViewModel + public partial class BreakpointEditViewModel : DisposableViewModel { - [Reactive] public Breakpoint Breakpoint { get; set; } + [ObservableProperty] public partial Breakpoint Breakpoint { get; set; } public Control? HelpTooltip { get; } = null; public string WindowTitle { get; } = ""; - [Reactive] public bool IsConditionValid { get; private set; } - [Reactive] public bool OkEnabled { get; private set; } - [Reactive] public string MaxAddress { get; private set; } = ""; - [Reactive] public bool CanExec { get; private set; } = false; - [Reactive] public bool HasDummyOperations { get; private set; } = false; + [ObservableProperty] public partial bool IsConditionValid { get; private set; } + [ObservableProperty] public partial bool OkEnabled { get; private set; } + [ObservableProperty] public partial string MaxAddress { get; private set; } = ""; + [ObservableProperty] public partial bool CanExec { get; private set; } = false; + [ObservableProperty] public partial bool HasDummyOperations { get; private set; } = false; public Enum[] AvailableMemoryTypes { get; private set; } = Array.Empty(); @@ -54,22 +53,18 @@ public BreakpointEditViewModel(Breakpoint bp) Breakpoint.MemoryType = (MemoryType)AvailableMemoryTypes[0]; } - AddDisposable(this.WhenAnyValue(x => x.Breakpoint.StartAddress) - .Buffer(2, 1) - .Select(b => (Previous: b[0], Current: b[1])) - .Subscribe(t => { - if(t.Previous == Breakpoint.EndAddress) { - Breakpoint.EndAddress = t.Current; - } + UInt32 prevStart = Breakpoint.StartAddress; + AddDisposable(Breakpoint.ObserveProp(nameof(Breakpoint.StartAddress), () => { + if(prevStart == Breakpoint.EndAddress) { + Breakpoint.EndAddress = Breakpoint.StartAddress; } - )); - - AddDisposable(this.WhenAnyValue(x => x.Breakpoint.MemoryType).Subscribe(memoryType => { - CanExec = memoryType.SupportsExecBreakpoints(); + prevStart = Breakpoint.StartAddress; })); - AddDisposable(this.WhenAnyValue(x => x.Breakpoint.MemoryType).Subscribe(memoryType => { - int maxAddress = DebugApi.GetMemorySize(memoryType) - 1; + AddDisposable(Breakpoint.ObserveProp(nameof(Breakpoint.MemoryType), () => { + CanExec = Breakpoint.MemoryType.SupportsExecBreakpoints(); + + int maxAddress = DebugApi.GetMemorySize(Breakpoint.MemoryType) - 1; if(maxAddress <= 0) { MaxAddress = "(unavailable)"; } else { @@ -77,38 +72,43 @@ public BreakpointEditViewModel(Breakpoint bp) } })); - AddDisposable(this.WhenAnyValue(x => x.Breakpoint.Condition).Subscribe(condition => { - if(!string.IsNullOrWhiteSpace(condition)) { + AddDisposable(Breakpoint.ObserveProp(nameof(Breakpoint.Condition), () => { + if(!string.IsNullOrWhiteSpace(Breakpoint.Condition)) { EvalResultType resultType; - DebugApi.EvaluateExpression(condition.Replace(Environment.NewLine, " "), Breakpoint.CpuType, out resultType, false); + DebugApi.EvaluateExpression(Breakpoint.Condition.Replace(Environment.NewLine, " "), Breakpoint.CpuType, out resultType, false); if(resultType == EvalResultType.Invalid) { IsConditionValid = false; return; } } IsConditionValid = true; + UpdateButtonState(); })); - AddDisposable(this.WhenAnyValue( - x => x.Breakpoint.BreakOnExec, - x => x.Breakpoint.BreakOnRead, - x => x.Breakpoint.BreakOnWrite, - x => x.Breakpoint.MemoryType, - x => x.Breakpoint.StartAddress, - x => x.Breakpoint.EndAddress, - x => x.IsConditionValid - ).Subscribe(_ => { - bool enabled = true; - if(Breakpoint.Type == BreakpointTypeFlags.None || !IsConditionValid) { + AddDisposable(Breakpoint.ObserveProp([ + nameof(Breakpoint.BreakOnExec), + nameof(Breakpoint.BreakOnRead), + nameof(Breakpoint.BreakOnWrite), + nameof(Breakpoint.MemoryType), + nameof(Breakpoint.StartAddress), + nameof(Breakpoint.EndAddress) + ], () => { + UpdateButtonState(); + })); + } + + private void UpdateButtonState() + { + bool enabled = true; + if(Breakpoint.Type == BreakpointTypeFlags.None || !IsConditionValid) { + enabled = false; + } else { + int maxAddress = DebugApi.GetMemorySize(Breakpoint.MemoryType) - 1; + if(Breakpoint.StartAddress > maxAddress || Breakpoint.EndAddress > maxAddress || Breakpoint.StartAddress > Breakpoint.EndAddress) { enabled = false; - } else { - int maxAddress = DebugApi.GetMemorySize(Breakpoint.MemoryType) - 1; - if(Breakpoint.StartAddress > maxAddress || Breakpoint.EndAddress > maxAddress || Breakpoint.StartAddress > Breakpoint.EndAddress) { - enabled = false; - } } - OkEnabled = enabled; - })); + } + OkEnabled = enabled; } } } diff --git a/UI/Debugger/ViewModels/BreakpointListViewModel.cs b/UI/Debugger/ViewModels/BreakpointListViewModel.cs index 748e14d8c..166981076 100644 --- a/UI/Debugger/ViewModels/BreakpointListViewModel.cs +++ b/UI/Debugger/ViewModels/BreakpointListViewModel.cs @@ -1,6 +1,7 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Selection; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Mesen.Config; using Mesen.Debugger.Utilities; @@ -8,22 +9,20 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels { - public class BreakpointListViewModel : DisposableViewModel + public partial class BreakpointListViewModel : DisposableViewModel { - [Reactive] public MesenList Breakpoints { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new() { SingleSelect = false }; - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial MesenList Breakpoints { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new() { SingleSelect = false }; + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.BreakpointListColumnWidths; public CpuType CpuType { get; } diff --git a/UI/Debugger/ViewModels/CallStackViewModel.cs b/UI/Debugger/ViewModels/CallStackViewModel.cs index 9ca3b9296..45195dbbe 100644 --- a/UI/Debugger/ViewModels/CallStackViewModel.cs +++ b/UI/Debugger/ViewModels/CallStackViewModel.cs @@ -10,20 +10,20 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Mesen.Debugger.ViewModels { - public class CallStackViewModel : DisposableViewModel + public partial class CallStackViewModel : DisposableViewModel { public CpuType CpuType { get; } public DebuggerWindowViewModel Debugger { get; } - [Reactive] public MesenList CallStackContent { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new(); + [ObservableProperty] public partial MesenList CallStackContent { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.CallStackColumnWidths; private StackFrameInfo[] _stackFrames = Array.Empty(); diff --git a/UI/Debugger/ViewModels/CommentEditViewModel.cs b/UI/Debugger/ViewModels/CommentEditViewModel.cs index 1fe502dac..7101cf0b3 100644 --- a/UI/Debugger/ViewModels/CommentEditViewModel.cs +++ b/UI/Debugger/ViewModels/CommentEditViewModel.cs @@ -5,7 +5,7 @@ namespace Mesen.Debugger.ViewModels { - public class CommentEditViewModel : ViewModelBase + public partial class CommentEditViewModel : ViewModelBase { public ReactiveCodeLabel Label { get; set; } diff --git a/UI/Debugger/ViewModels/ControllerInputViewModel.cs b/UI/Debugger/ViewModels/ControllerInputViewModel.cs index b8faf02ce..233f54b06 100644 --- a/UI/Debugger/ViewModels/ControllerInputViewModel.cs +++ b/UI/Debugger/ViewModels/ControllerInputViewModel.cs @@ -3,29 +3,29 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.ViewModels { - public class ControllerInputViewModel : ViewModelBase + public partial class ControllerInputViewModel : ViewModelBase { - [Reactive] public int ViewHeight { get; set; } + [ObservableProperty] public partial int ViewHeight { get; set; } - [Reactive] public bool ButtonA { get; set; } - [Reactive] public bool ButtonB { get; set; } - [Reactive] public bool ButtonX { get; set; } - [Reactive] public bool ButtonY { get; set; } - [Reactive] public bool ButtonL { get; set; } - [Reactive] public bool ButtonR { get; set; } - [Reactive] public bool ButtonU { get; set; } - [Reactive] public bool ButtonD { get; set; } - [Reactive] public bool ButtonUp { get; set; } - [Reactive] public bool ButtonDown { get; set; } - [Reactive] public bool ButtonLeft { get; set; } - [Reactive] public bool ButtonRight { get; set; } - [Reactive] public bool ButtonSelect { get; set; } - [Reactive] public bool ButtonStart { get; set; } + [ObservableProperty] public partial bool ButtonA { get; set; } + [ObservableProperty] public partial bool ButtonB { get; set; } + [ObservableProperty] public partial bool ButtonX { get; set; } + [ObservableProperty] public partial bool ButtonY { get; set; } + [ObservableProperty] public partial bool ButtonL { get; set; } + [ObservableProperty] public partial bool ButtonR { get; set; } + [ObservableProperty] public partial bool ButtonU { get; set; } + [ObservableProperty] public partial bool ButtonD { get; set; } + [ObservableProperty] public partial bool ButtonUp { get; set; } + [ObservableProperty] public partial bool ButtonDown { get; set; } + [ObservableProperty] public partial bool ButtonLeft { get; set; } + [ObservableProperty] public partial bool ButtonRight { get; set; } + [ObservableProperty] public partial bool ButtonSelect { get; set; } + [ObservableProperty] public partial bool ButtonStart { get; set; } public int ControllerIndex { get; } public bool IsSnes { get; } diff --git a/UI/Debugger/ViewModels/ControllerListViewModel.cs b/UI/Debugger/ViewModels/ControllerListViewModel.cs index 84fa34618..6aa96c442 100644 --- a/UI/Debugger/ViewModels/ControllerListViewModel.cs +++ b/UI/Debugger/ViewModels/ControllerListViewModel.cs @@ -1,15 +1,15 @@ using Avalonia.Controls; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; namespace Mesen.Debugger.ViewModels { - public class ControllerListViewModel : ViewModelBase + public partial class ControllerListViewModel : ViewModelBase { - [Reactive] public List Controllers { get; set; } = new(); + [ObservableProperty] public partial List Controllers { get; set; } = new(); [Obsolete("For designer only")] public ControllerListViewModel() : this(ConsoleType.Snes) { } diff --git a/UI/Debugger/ViewModels/DebuggerConfigWindowViewModel.cs b/UI/Debugger/ViewModels/DebuggerConfigWindowViewModel.cs index e911c5a34..a9bf49a60 100644 --- a/UI/Debugger/ViewModels/DebuggerConfigWindowViewModel.cs +++ b/UI/Debugger/ViewModels/DebuggerConfigWindowViewModel.cs @@ -1,10 +1,9 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -14,7 +13,7 @@ namespace Mesen.Debugger.ViewModels { - public class DebuggerConfigWindowViewModel : DisposableViewModel + public partial class DebuggerConfigWindowViewModel : DisposableViewModel { public DebuggerFontConfig Fonts { get; set; } public DebuggerConfig Debugger { get; set; } @@ -23,7 +22,7 @@ public class DebuggerConfigWindowViewModel : DisposableViewModel public List CpuTypeList { get; set; } = new(); - [Reactive] public DebugConfigWindowTab SelectedIndex { get; set; } + [ObservableProperty] public partial DebugConfigWindowTab SelectedIndex { get; set; } public List SharedShortcuts { get; set; } = new(); public List MemoryToolsShortcuts { get; set; } = new(); @@ -104,7 +103,7 @@ public bool IsDirty() ); } - private void RevertChanges<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T current, T original) where T : ReactiveObject + private void RevertChanges<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T current, T original) where T : ObservableObject { if(_changes.TryGetValue(current, out HashSet? changes)) { foreach(string propertyName in changes) { diff --git a/UI/Debugger/ViewModels/DebuggerDock/ToolContainerViewModel.cs b/UI/Debugger/ViewModels/DebuggerDock/ToolContainerViewModel.cs index e3afa5823..60e131bc5 100644 --- a/UI/Debugger/ViewModels/DebuggerDock/ToolContainerViewModel.cs +++ b/UI/Debugger/ViewModels/DebuggerDock/ToolContainerViewModel.cs @@ -1,14 +1,16 @@ -using Dock.Model.Mvvm.Controls; +using Dock.Controls.DeferredContentControl; +using Dock.Model.Mvvm.Controls; using Mesen.Debugger.Utilities; -using ReactiveUI.Fody.Helpers; using System; namespace Mesen.Debugger.ViewModels.DebuggerDock { - public class BaseToolContainerViewModel : Tool + public class BaseToolContainerViewModel : Tool, IDeferredContentPresentation { public virtual object? HelpContent { get; } = null; + public bool DeferContentPresentation => false; + public event EventHandler? Selected; public override void OnSelected() diff --git a/UI/Debugger/ViewModels/DebuggerOptionsViewModel.cs b/UI/Debugger/ViewModels/DebuggerOptionsViewModel.cs index e77b40bd8..efcf9f5f6 100644 --- a/UI/Debugger/ViewModels/DebuggerOptionsViewModel.cs +++ b/UI/Debugger/ViewModels/DebuggerOptionsViewModel.cs @@ -4,7 +4,7 @@ namespace Mesen.Debugger.ViewModels { - public class DebuggerOptionsViewModel : ViewModelBase + public partial class DebuggerOptionsViewModel : ViewModelBase { public DebuggerConfig Config { get; } diff --git a/UI/Debugger/ViewModels/DebuggerWindowViewModel.cs b/UI/Debugger/ViewModels/DebuggerWindowViewModel.cs index d2dd3ac79..5a685a058 100644 --- a/UI/Debugger/ViewModels/DebuggerWindowViewModel.cs +++ b/UI/Debugger/ViewModels/DebuggerWindowViewModel.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Dock.Model.Controls; using Dock.Model.Core; using Dock.Model.Mvvm.Controls; @@ -16,7 +17,6 @@ using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -25,42 +25,42 @@ namespace Mesen.Debugger.ViewModels { - public class DebuggerWindowViewModel : DisposableViewModel + public partial class DebuggerWindowViewModel : DisposableViewModel { - [Reactive] public string Title { get; private set; } = "Debugger"; - [Reactive] public WindowIcon? Icon { get; private set; } = null; - [Reactive] public bool IsMainCpuDebugger { get; private set; } = true; - - [Reactive] public DebuggerConfig Config { get; private set; } - - [Reactive] public DebuggerOptionsViewModel Options { get; private set; } - - [Reactive] public DisassemblyViewModel Disassembly { get; private set; } - [Reactive] public BreakpointListViewModel BreakpointList { get; private set; } - [Reactive] public WatchListViewModel WatchList { get; private set; } - [Reactive] public BaseConsoleStatusViewModel? ConsoleStatus { get; private set; } - [Reactive] public LabelListViewModel LabelList { get; private set; } - [Reactive] public FunctionListViewModel? FunctionList { get; private set; } - [Reactive] public CallStackViewModel CallStack { get; private set; } - [Reactive] public SourceViewViewModel? SourceView { get; private set; } - [Reactive] public MemoryMappingViewModel? MemoryMappings { get; private set; } - [Reactive] public FindResultListViewModel FindResultList { get; private set; } - [Reactive] public ControllerListViewModel ControllerList { get; private set; } - - [Reactive] public DebuggerDockFactory DockFactory { get; private set; } - [Reactive] public IRootDock DockLayout { get; private set; } - - [Reactive] public string BreakReason { get; private set; } = ""; - [Reactive] public string BreakElapsedCycles { get; private set; } = ""; - [Reactive] public string BreakElapsedCyclesTooltip { get; private set; } = ""; - [Reactive] public string CdlStats { get; private set; } = ""; - - [Reactive] public List ToolbarItems { get; private set; } = new(); - - [Reactive] public List FileMenuItems { get; private set; } = new(); - [Reactive] public List DebugMenuItems { get; private set; } = new(); - [Reactive] public List SearchMenuItems { get; private set; } = new(); - [Reactive] public List OptionMenuItems { get; private set; } = new(); + [ObservableProperty] public partial string Title { get; private set; } = "Debugger"; + [ObservableProperty] public partial WindowIcon? Icon { get; private set; } = null; + [ObservableProperty] public partial bool IsMainCpuDebugger { get; private set; } = true; + + [ObservableProperty] public partial DebuggerConfig Config { get; private set; } + + [ObservableProperty] public partial DebuggerOptionsViewModel Options { get; private set; } + + [ObservableProperty] public partial DisassemblyViewModel Disassembly { get; private set; } + [ObservableProperty] public partial BreakpointListViewModel BreakpointList { get; private set; } + [ObservableProperty] public partial WatchListViewModel WatchList { get; private set; } + [ObservableProperty] public partial BaseConsoleStatusViewModel? ConsoleStatus { get; private set; } + [ObservableProperty] public partial LabelListViewModel LabelList { get; private set; } + [ObservableProperty] public partial FunctionListViewModel? FunctionList { get; private set; } + [ObservableProperty] public partial CallStackViewModel CallStack { get; private set; } + [ObservableProperty] public partial SourceViewViewModel? SourceView { get; private set; } + [ObservableProperty] public partial MemoryMappingViewModel? MemoryMappings { get; private set; } + [ObservableProperty] public partial FindResultListViewModel FindResultList { get; private set; } + [ObservableProperty] public partial ControllerListViewModel ControllerList { get; private set; } + + [ObservableProperty] public partial DebuggerDockFactory DockFactory { get; private set; } + [ObservableProperty] public partial IRootDock DockLayout { get; private set; } + + [ObservableProperty] public partial string BreakReason { get; private set; } = ""; + [ObservableProperty] public partial string BreakElapsedCycles { get; private set; } = ""; + [ObservableProperty] public partial string BreakElapsedCyclesTooltip { get; private set; } = ""; + [ObservableProperty] public partial string CdlStats { get; private set; } = ""; + + [ObservableProperty] public partial List ToolbarItems { get; private set; } = new(); + + [ObservableProperty] public partial List FileMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List DebugMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List SearchMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List OptionMenuItems { get; private set; } = new(); public CpuType CpuType { get; private set; } private UInt64 _masterClock = 0; diff --git a/UI/Debugger/ViewModels/DisassemblyViewModel.cs b/UI/Debugger/ViewModels/DisassemblyViewModel.cs index 3a96b3bc2..05dcebe3f 100644 --- a/UI/Debugger/ViewModels/DisassemblyViewModel.cs +++ b/UI/Debugger/ViewModels/DisassemblyViewModel.cs @@ -1,6 +1,8 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Input.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Disassembly; @@ -9,31 +11,29 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Linq; using System.Text; namespace Mesen.Debugger.ViewModels { - public class DisassemblyViewModel : DisposableViewModel, ISelectableModel + public partial class DisassemblyViewModel : DisposableViewModel, ISelectableModel { public ICodeDataProvider DataProvider { get; } public CpuType CpuType { get; } public DebuggerWindowViewModel Debugger { get; } public DisassemblyViewStyleProvider StyleProvider { get; } - [Reactive] public int ScrollPosition { get; set; } = 0; - [Reactive] public int MaxScrollPosition { get; private set; } = 1000000000; - [Reactive] public int TopAddress { get; private set; } = 0; - [Reactive] public CodeLineData[] Lines { get; private set; } = Array.Empty(); + [ObservableProperty] public partial int ScrollPosition { get; set; } = 0; + [ObservableProperty] public partial int MaxScrollPosition { get; private set; } = 1000000000; + [ObservableProperty] public partial int TopAddress { get; private set; } = 0; + [ObservableProperty] public partial CodeLineData[] Lines { get; private set; } = Array.Empty(); - [Reactive] public int? ActiveAddress { get; set; } - [Reactive] public int SelectedRowAddress { get; set; } - [Reactive] public int SelectionAnchor { get; set; } - [Reactive] public int SelectionStart { get; set; } - [Reactive] public int SelectionEnd { get; set; } + [ObservableProperty] public partial int? ActiveAddress { get; set; } + [ObservableProperty] public partial int SelectedRowAddress { get; set; } + [ObservableProperty] public partial int SelectionAnchor { get; set; } + [ObservableProperty] public partial int SelectionStart { get; set; } + [ObservableProperty] public partial int SelectionEnd { get; set; } public QuickSearchViewModel QuickSearch { get; } = new QuickSearchViewModel(); public NavigationHistory History { get; } = new(); @@ -65,16 +65,17 @@ public DisassemblyViewModel(DebuggerWindowViewModel debugger, DebugConfig config QuickSearch.OnFind += QuickSearch_OnFind; - AddDisposable(this.WhenAnyValue(x => x.TopAddress).Subscribe(x => Refresh())); + AddDisposable(this.ObserveProp(nameof(TopAddress), Refresh)); - AddDisposable(this.WhenAnyValue(x => x.QuickSearch.IsSearchBoxVisible).Subscribe(x => { + AddDisposable(QuickSearch.ObserveProp(nameof(QuickSearch.IsSearchBoxVisible), () => { if(!QuickSearch.IsSearchBoxVisible) { _viewer?.Focus(); } })); int lastValue = ScrollPosition; - AddDisposable(this.WhenAnyValue(x => x.ScrollPosition).Subscribe(scrollPos => { + AddDisposable(this.ObserveProp(nameof(ScrollPosition), () => { + int scrollPos = ScrollPosition; if(_viewer == null) { ScrollPosition = lastValue; return; diff --git a/UI/Debugger/ViewModels/EventViewerListViewModel.cs b/UI/Debugger/ViewModels/EventViewerListViewModel.cs index 47901c345..04855bd73 100644 --- a/UI/Debugger/ViewModels/EventViewerListViewModel.cs +++ b/UI/Debugger/ViewModels/EventViewerListViewModel.cs @@ -1,22 +1,21 @@ using Avalonia.Collections; using Avalonia.Controls.Selection; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using DataBoxControl; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; using System.Windows.Input; namespace Mesen.Debugger.ViewModels { - public class EventViewerListViewModel : DisposableViewModel + public partial class EventViewerListViewModel : DisposableViewModel { public DebugEventInfo[] RawDebugEvents => _debugEvents; private DebugEventInfo[] _debugEvents = new DebugEventInfo[0]; @@ -25,7 +24,7 @@ public class EventViewerListViewModel : DisposableViewModel public SelectionModel Selection { get; set; } = new(); public EventViewerViewModel EventViewer { get; } - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.EventViewer.ColumnWidths; public ICommand SortCommand { get; } @@ -38,7 +37,7 @@ public EventViewerListViewModel(EventViewerViewModel eventViewer) SortState.SetColumnSort("Scanline", ListSortDirection.Ascending, false); SortState.SetColumnSort("Cycle", ListSortDirection.Ascending, false); - SortCommand = ReactiveCommand.Create(sortMemberPath => { + SortCommand = new RelayCommand(() => { RefreshList(); }); } diff --git a/UI/Debugger/ViewModels/EventViewerViewModel.cs b/UI/Debugger/ViewModels/EventViewerViewModel.cs index 46d7b0e88..84f02672b 100644 --- a/UI/Debugger/ViewModels/EventViewerViewModel.cs +++ b/UI/Debugger/ViewModels/EventViewerViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Mesen.Config; using Mesen.Debugger.Controls; @@ -13,44 +14,41 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.Reactive.Linq; using System.Reflection; namespace Mesen.Debugger.ViewModels { - public class EventViewerViewModel : DisposableViewModel + public partial class EventViewerViewModel : DisposableViewModel { public const int HdmaChannelFlag = 0x40; - [Reactive] public CpuType CpuType { get; set; } - [Reactive] public DynamicBitmap ViewerBitmap { get; private set; } + [ObservableProperty] public partial CpuType CpuType { get; set; } + [ObservableProperty] public partial DynamicBitmap ViewerBitmap { get; private set; } - [Reactive] public ViewModelBase ConsoleConfig { get; set; } - [Reactive] public GridRowColumn? GridHighlightPoint { get; set; } + [ObservableProperty] public partial ViewModelBase ConsoleConfig { get; set; } + [ObservableProperty] public partial GridRowColumn? GridHighlightPoint { get; set; } - [Reactive] public bool ShowListView { get; set; } - [Reactive] public double MinListViewHeight { get; set; } - [Reactive] public double ListViewHeight { get; set; } + [ObservableProperty] public partial bool ShowListView { get; set; } + [ObservableProperty] public partial double MinListViewHeight { get; set; } + [ObservableProperty] public partial double ListViewHeight { get; set; } private DateTime _lastListRefresh = DateTime.MinValue; - [Reactive] public DebugEventInfo? SelectedEvent { get; set; } - [Reactive] public Rect SelectionRect { get; set; } + [ObservableProperty] public partial DebugEventInfo? SelectedEvent { get; set; } + [ObservableProperty] public partial Rect SelectionRect { get; set; } public EventViewerListViewModel ListView { get; } public EventViewerConfig Config { get; } - [Reactive] public List FileMenuItems { get; private set; } = new(); - [Reactive] public List DebugMenuItems { get; private set; } = new(); - [Reactive] public List ViewMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List DebugMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List ViewMenuItems { get; private set; } = new(); - [Reactive] public List ToolbarItems { get; private set; } = new(); + [ObservableProperty] public partial List ToolbarItems { get; private set; } = new(); private PictureViewer _picViewer; private bool _refreshPending; @@ -139,27 +137,27 @@ public EventViewerViewModel(CpuType cpuType, PictureViewer picViewer, DataBox li DebugMenuItems = AddDisposables(DebugSharedActions.GetStepActions(wnd, () => CpuType)); ToolbarItems = AddDisposables(DebugSharedActions.GetStepActions(wnd, () => CpuType)); - AddDisposable(this.WhenAnyValue(x => x.CpuType).Subscribe(_ => { - InitForCpuType(); + AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => { UpdateConfig(); - RefreshData(); + RefreshUi(false); })); - AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => { + AddDisposable(this.ObserveProp(nameof(CpuType), () => { + InitForCpuType(); UpdateConfig(); - RefreshUi(false); + RefreshData(); })); - AddDisposable(this.WhenAnyValue(x => x.ShowListView).Subscribe(showListView => { - Config.ShowListView = showListView; - ListViewHeight = showListView ? Config.ListViewHeight : 0; - MinListViewHeight = showListView ? 100 : 0; + AddDisposable(this.ObserveProp(nameof(ShowListView), () => { + Config.ShowListView = ShowListView; + ListViewHeight = ShowListView ? Config.ListViewHeight : 0; + MinListViewHeight = ShowListView ? 100 : 0; RefreshUi(false); })); - AddDisposable(this.WhenAnyValue(x => x.ListViewHeight).Subscribe(height => { + AddDisposable(this.ObserveProp(nameof(ListViewHeight), () => { if(ShowListView) { - Config.ListViewHeight = height; + Config.ListViewHeight = ListViewHeight; } else { ListViewHeight = 0; } @@ -401,9 +399,16 @@ public void UpdateConfig() } } + private static PropertyInfo[] GetPublicProperties(ViewModelBase target) + { +#pragma warning disable IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. + return target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); +#pragma warning restore IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. + } + public void EnableAllEventTypes() { - foreach(PropertyInfo prop in ConsoleConfig.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { + foreach(PropertyInfo prop in GetPublicProperties(ConsoleConfig)) { if(prop.PropertyType == typeof(EventViewerCategoryCfg)) { ((EventViewerCategoryCfg)prop.GetValue(ConsoleConfig)!).Visible = true; } @@ -412,7 +417,7 @@ public void EnableAllEventTypes() public void DisableAllEventTypes() { - foreach(PropertyInfo prop in ConsoleConfig.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { + foreach(PropertyInfo prop in GetPublicProperties(ConsoleConfig)) { if(prop.PropertyType == typeof(EventViewerCategoryCfg)) { ((EventViewerCategoryCfg)prop.GetValue(ConsoleConfig)!).Visible = false; } diff --git a/UI/Debugger/ViewModels/FindResultListViewModel.cs b/UI/Debugger/ViewModels/FindResultListViewModel.cs index 6fb63d9ac..cb5f82495 100644 --- a/UI/Debugger/ViewModels/FindResultListViewModel.cs +++ b/UI/Debugger/ViewModels/FindResultListViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Controls.Selection; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Dock.Model.Core; using Mesen.Config; @@ -13,22 +14,20 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels; -public class FindResultListViewModel : DisposableViewModel +public partial class FindResultListViewModel : DisposableViewModel { - [Reactive] public MesenList FindResults { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new() { SingleSelect = false }; - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial MesenList FindResults { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new() { SingleSelect = false }; + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.FindResultColumnWidths; public DebuggerWindowViewModel Debugger { get; } diff --git a/UI/Debugger/ViewModels/FunctionListViewModel.cs b/UI/Debugger/ViewModels/FunctionListViewModel.cs index 7756be527..a4697fb84 100644 --- a/UI/Debugger/ViewModels/FunctionListViewModel.cs +++ b/UI/Debugger/ViewModels/FunctionListViewModel.cs @@ -11,7 +11,7 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections; using System.Collections.Generic; @@ -21,11 +21,11 @@ namespace Mesen.Debugger.ViewModels { - public class FunctionListViewModel : DisposableViewModel + public partial class FunctionListViewModel : DisposableViewModel { - [Reactive] public MesenList Functions { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new() { SingleSelect = false }; - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial MesenList Functions { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new() { SingleSelect = false }; + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.FunctionListColumnWidths; public CpuType CpuType { get; } diff --git a/UI/Debugger/ViewModels/GoToAllViewModel.cs b/UI/Debugger/ViewModels/GoToAllViewModel.cs index 56e2fed32..ffaffe3ef 100644 --- a/UI/Debugger/ViewModels/GoToAllViewModel.cs +++ b/UI/Debugger/ViewModels/GoToAllViewModel.cs @@ -1,10 +1,11 @@ -using Avalonia.Controls.Selection; +using Avalonia.Controls; +using Avalonia.Controls.Selection; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger.Integration; using Mesen.Debugger.Utilities; using Mesen.Interop; +using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -12,28 +13,29 @@ namespace Mesen.Debugger.ViewModels; -public class GoToAllViewModel : DisposableViewModel +public partial class GoToAllViewModel : DisposableViewModel { - [Reactive] public string SearchString { get; set; } = ""; - [Reactive] public List SearchResults { get; set; } = new(); - [Reactive] public SelectionModel SelectionModel { get; set; } = new(); - [Reactive] public SearchResultInfo? SelectedItem { get; set; } = null; - [Reactive] public bool CanSelect { get; set; } = false; + [ObservableProperty] public partial string SearchString { get; set; } = ""; + [ObservableProperty] public partial List SearchResults { get; set; } = new(); + [ObservableProperty] public partial SearchResultInfo? SelectedItem { get; set; } = null; + [ObservableProperty] public partial bool CanSelect { get; set; } = false; + + public SelectionModel SelectionModel { get; private set; } = new(); [Obsolete("For designer only")] public GoToAllViewModel() : this(CpuType.Snes, GoToAllOptions.None) { } public GoToAllViewModel(CpuType cpuType, GoToAllOptions options, ISymbolProvider? symbolProvider = null) { - AddDisposable(this.WhenAnyValue(x => x.SearchString).Subscribe(x => { + AddDisposable(this.ObserveProp(nameof(SearchString), () => { SearchResults = SearchHelper.GetGoToAllResults(cpuType, SearchString, options, symbolProvider); if(SearchResults.Count > 0) { SelectionModel.SelectedIndex = 0; } })); - AddDisposable(this.WhenAnyValue(x => x.SelectionModel.SelectedItem).Subscribe(item => { - CanSelect = item?.Disabled == false; + AddDisposable(SelectionModel.ObserveProp(nameof(SelectionModel.SelectedItem), () => { + CanSelect = SelectionModel.SelectedItem?.Disabled == false; })); } } diff --git a/UI/Debugger/ViewModels/LabelEditViewModel.cs b/UI/Debugger/ViewModels/LabelEditViewModel.cs index f5c53299b..dd9cf90ce 100644 --- a/UI/Debugger/ViewModels/LabelEditViewModel.cs +++ b/UI/Debugger/ViewModels/LabelEditViewModel.cs @@ -1,25 +1,24 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger.Labels; using Mesen.Interop; using Mesen.Localization; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels { - public class LabelEditViewModel : DisposableViewModel + public partial class LabelEditViewModel : DisposableViewModel { - [Reactive] public ReactiveCodeLabel Label { get; set; } + [ObservableProperty] public partial ReactiveCodeLabel Label { get; set; } - [ObservableAsProperty] public bool OkEnabled { get; } - [ObservableAsProperty] public string MaxAddress { get; } = ""; - [Reactive] public string ErrorMessage { get; private set; } = ""; + [ObservableProperty] public partial bool OkEnabled { get; private set; } = false; + [ObservableProperty] public partial string MaxAddress { get; private set; } = ""; + [ObservableProperty] public partial string ErrorMessage { get; private set; } = ""; public bool AllowDelete { get; } = false; @@ -48,58 +47,63 @@ public LabelEditViewModel(CpuType cpuType, CodeLabel label, CodeLabel? originalL Label.MemoryType = (MemoryType)AvailableMemoryTypes[0]; } - AddDisposable(this.WhenAnyValue(x => x.Label.MemoryType, (memoryType) => { - int maxAddress = DebugApi.GetMemorySize(memoryType) - 1; - if(maxAddress <= 0) { - return "(unavailable)"; - } else { - return "(Max: $" + maxAddress.ToString("X4") + ")"; + Label.PropertyChanged += (s, e) => { + int maxAddress = DebugApi.GetMemorySize(Label.MemoryType) - 1; + + if(e.PropertyName == nameof(Label.MemoryType)) { + if(maxAddress <= 0) { + MaxAddress = "(unavailable)"; + } else { + MaxAddress = "(Max: $" + maxAddress.ToString("X4") + ")"; + } } - }).ToPropertyEx(this, x => x.MaxAddress)); - AddDisposable(this.WhenAnyValue(x => x.Label.Label, x => x.Label.Comment, x => x.Label.Length, x => x.Label.MemoryType, x => x.Label.Address, (label, comment, length, memoryType, address) => { - CodeLabel? sameLabel = LabelManager.GetLabel(label); - int maxAddress = DebugApi.GetMemorySize(memoryType) - 1; + CodeLabel? sameLabel = LabelManager.GetLabel(Label.Label); - for(UInt32 i = 0; i < length; i++) { - CodeLabel? sameAddress = LabelManager.GetLabel(address + i, memoryType); + for(UInt32 i = 0; i < Label.Length; i++) { + CodeLabel? sameAddress = LabelManager.GetLabel(Label.Address + i, Label.MemoryType); if(sameAddress != null) { if(originalLabel == null || (sameAddress.Label != originalLabel.Label && !sameAddress.Label.StartsWith(originalLabel.Label + "+"))) { //A label already exists, we're trying to edit an existing label, but the existing label //and the label we're editing aren't the same label. Can't override an existing label with a different one. ErrorMessage = ResourceHelper.GetMessage("AddressHasOtherLabel", sameAddress.Label.Length > 0 ? sameAddress.Label : sameAddress.Comment); - return false; + OkEnabled = false; } } } - if(address + (length - 1) > maxAddress) { + if(Label.Address + (Label.Length - 1) > maxAddress) { ErrorMessage = ResourceHelper.GetMessage("AddressOutOfRange"); - return false; + OkEnabled = false; + return; } - if(label.Length == 0 && comment.Length == 0) { + if(label.Length == 0 && Label.Comment.Length == 0) { ErrorMessage = ResourceHelper.GetMessage("LabelOrCommentRequired"); - return false; + OkEnabled = false; + return; } - if(label.Length > 0 && !LabelManager.LabelRegex.IsMatch(label)) { + if(label.Length > 0 && !LabelManager.LabelRegex.IsMatch(Label.Label)) { ErrorMessage = ResourceHelper.GetMessage("InvalidLabel"); - return false; + OkEnabled = false; + return; } if(sameLabel != null && sameLabel != originalLabel) { ErrorMessage = ResourceHelper.GetMessage("LabelNameInUse"); - return false; + OkEnabled = false; + return; } - if(length >= 1 && length <= 65536 && !comment.Contains('\x1')) { + if(Label.Length >= 1 && Label.Length <= 65536 && !Label.Comment.Contains('\x1')) { ErrorMessage = ""; - return true; + OkEnabled = false; + return; } - return false; - }).ToPropertyEx(this, x => x.OkEnabled)); + OkEnabled = true; + }; } public void DeleteLabel() @@ -114,7 +118,7 @@ public void Commit() Label.Commit(); } - public class ReactiveCodeLabel : ReactiveObject + public partial class ReactiveCodeLabel : ObservableObject { private CodeLabel _originalLabel; @@ -140,12 +144,17 @@ public void Commit() _originalLabel.Length = Length; } - [Reactive] public UInt32 Address { get; set; } - [Reactive] public MemoryType MemoryType { get; set; } - [Reactive] public string Label { get; set; } = ""; - [Reactive] public string Comment { get; set; } = ""; - [Reactive] public CodeLabelFlags Flags { get; set; } - [Reactive] public UInt32 Length { get; set; } = 1; + [ObservableProperty] public partial UInt32 Address { get; set; } + [ObservableProperty] public partial MemoryType MemoryType { get; set; } + [ObservableProperty] public partial string Label { get; set; } = ""; + [ObservableProperty] public partial string Comment { get; set; } = ""; + [ObservableProperty] public partial CodeLabelFlags Flags { get; set; } + [ObservableProperty] public partial UInt32 Length { get; set; } = 1; + + protected override void OnPropertyChanged(PropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + } } } } diff --git a/UI/Debugger/ViewModels/LabelListViewModel.cs b/UI/Debugger/ViewModels/LabelListViewModel.cs index 70c0dd7f7..4b3777cf0 100644 --- a/UI/Debugger/ViewModels/LabelListViewModel.cs +++ b/UI/Debugger/ViewModels/LabelListViewModel.cs @@ -11,7 +11,7 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections; using System.Collections.Generic; @@ -20,11 +20,11 @@ namespace Mesen.Debugger.ViewModels { - public class LabelListViewModel : DisposableViewModel + public partial class LabelListViewModel : DisposableViewModel { - [Reactive] public MesenList Labels { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new() { SingleSelect = false }; - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial MesenList Labels { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new() { SingleSelect = false }; + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.LabelListColumnWidths; public CpuType CpuType { get; } diff --git a/UI/Debugger/ViewModels/MemoryMappingViewModel.cs b/UI/Debugger/ViewModels/MemoryMappingViewModel.cs index 002167395..664007470 100644 --- a/UI/Debugger/ViewModels/MemoryMappingViewModel.cs +++ b/UI/Debugger/ViewModels/MemoryMappingViewModel.cs @@ -3,18 +3,18 @@ using Mesen.Debugger.Controls; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; namespace Mesen.Debugger.ViewModels { - public class MemoryMappingViewModel : ViewModelBase + public partial class MemoryMappingViewModel : ViewModelBase { private CpuType _cpuType; - [Reactive] public List CpuMappings { get; private set; } = new(); - [Reactive] public List? PpuMappings { get; private set; } = null; + [ObservableProperty] public partial List CpuMappings { get; private set; } = new(); + [ObservableProperty] public partial List? PpuMappings { get; private set; } = null; public MemoryType CpuMemType { get; } public MemoryType PpuMemType { get; } diff --git a/UI/Debugger/ViewModels/MemorySearchViewModel.cs b/UI/Debugger/ViewModels/MemorySearchViewModel.cs index 45cd571a4..d0127a7d1 100644 --- a/UI/Debugger/ViewModels/MemorySearchViewModel.cs +++ b/UI/Debugger/ViewModels/MemorySearchViewModel.cs @@ -1,57 +1,54 @@ using Avalonia.Controls; using Avalonia.Controls.Selection; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; -using DynamicData; using Mesen.Config; using Mesen.Debugger.Utilities; using Mesen.Interop; using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace Mesen.Debugger.ViewModels; -public class MemorySearchViewModel : DisposableViewModel +public partial class MemorySearchViewModel : DisposableViewModel { public MemorySearchConfig Config { get; } - [Reactive] public Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); + [ObservableProperty] public partial Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); - [Reactive] public MemoryType MemoryType { get; set; } = MemoryType.SnesMemory; - [Reactive] public MemorySearchFormat Format { get; set; } = MemorySearchFormat.Hex; - [Reactive] public MemorySearchValueSize ValueSize { get; set; } = MemorySearchValueSize.Byte; + [ObservableProperty] public partial MemoryType MemoryType { get; set; } = MemoryType.SnesMemory; + [ObservableProperty] public partial MemorySearchFormat Format { get; set; } = MemorySearchFormat.Hex; + [ObservableProperty] public partial MemorySearchValueSize ValueSize { get; set; } = MemorySearchValueSize.Byte; - [Reactive] public MemorySearchCompareTo CompareTo { get; set; } = MemorySearchCompareTo.PreviousRefreshValue; - [Reactive] public MemorySearchOperator Operator { get; set; } = MemorySearchOperator.Equal; + [ObservableProperty] public partial MemorySearchCompareTo CompareTo { get; set; } = MemorySearchCompareTo.PreviousRefreshValue; + [ObservableProperty] public partial MemorySearchOperator Operator { get; set; } = MemorySearchOperator.Equal; - [Reactive] public MesenList ListData { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new(); - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial MesenList ListData { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new(); + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public List ColumnWidths { get; } = ConfigManager.Config.Debug.MemorySearch.ColumnWidths; - [Reactive] public int SpecificAddress { get; set; } = 0; - [Reactive] public int SpecificValue { get; set; } = 0; + [ObservableProperty] public partial int SpecificAddress { get; set; } = 0; + [ObservableProperty] public partial int SpecificValue { get; set; } = 0; - [Reactive] public bool IsValueHex { get; set; } + [ObservableProperty] public partial bool IsValueHex { get; set; } - [Reactive] public string MinValue { get; set; } = ""; - [Reactive] public string MaxValue { get; set; } = ""; + [ObservableProperty] public partial string MinValue { get; set; } = ""; + [ObservableProperty] public partial string MaxValue { get; set; } = ""; - [Reactive] public int MaxAddress { get; set; } = 0; + [ObservableProperty] public partial int MaxAddress { get; set; } = 0; - [Reactive] public bool IsUndoEnabled { get; set; } = false; - [Reactive] public bool IsSpecificValueEnabled { get; set; } = false; - [Reactive] public bool IsSpecificAddressEnabled { get; set; } = false; + [ObservableProperty] public partial bool IsUndoEnabled { get; set; } = false; + [ObservableProperty] public partial bool IsSpecificValueEnabled { get; set; } = false; + [ObservableProperty] public partial bool IsSpecificAddressEnabled { get; set; } = false; public int[] AddressLookup => _addressLookup; public byte[] MemoryState => _memoryState; @@ -82,11 +79,7 @@ public MemorySearchViewModel() OnGameLoaded(); SortState.SetColumnSort("Address", ListSortDirection.Ascending, false); - AddDisposable(this.WhenAnyValue(x => x.MemoryType).Subscribe(x => { - ResetSearch(); - })); - - AddDisposable(this.WhenAnyValue(x => x.Operator, x => x.CompareTo, x => x.ValueSize, x => x.Format).Subscribe(x => { + AddDisposable(this.ObserveProp([nameof(Operator), nameof(CompareTo), nameof(ValueSize), nameof(Format)], () => { IsSpecificValueEnabled = CompareTo == MemorySearchCompareTo.SpecificValue; IsSpecificAddressEnabled = CompareTo == MemorySearchCompareTo.SpecificAddress; @@ -111,11 +104,16 @@ public MemorySearchViewModel() RefreshList(true); })); - AddDisposable(this.WhenAnyValue(x => x.SpecificValue, x => x.SpecificAddress).Subscribe(x => { + AddDisposable(this.ObserveProp([nameof(SpecificValue), nameof(SpecificAddress)], () => { RefreshList(false); })); } + partial void OnMemoryTypeChanged(MemoryType value) + { + ResetSearch(); + } + public void SortCommand() { RefreshList(true); diff --git a/UI/Debugger/ViewModels/MemoryToolsDisplayOptionsViewModel.cs b/UI/Debugger/ViewModels/MemoryToolsDisplayOptionsViewModel.cs index 98c9b4da5..e1a59f836 100644 --- a/UI/Debugger/ViewModels/MemoryToolsDisplayOptionsViewModel.cs +++ b/UI/Debugger/ViewModels/MemoryToolsDisplayOptionsViewModel.cs @@ -1,32 +1,30 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Utilities; using Mesen.Interop; using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; namespace Mesen.Debugger.ViewModels { - public class MemoryToolsDisplayOptionsViewModel : DisposableViewModel + public partial class MemoryToolsDisplayOptionsViewModel : DisposableViewModel { public HexEditorConfig Config { get; } public MemoryToolsViewModel MemoryTools { get; } public int[] AvailableWidths => new int[] { 4, 8, 16, 32, 48, 64, 80, 96, 112, 128 }; - [Reactive] public bool ShowFrozenAddressesOption { get; set; } - [Reactive] public bool ShowNesPcmDataOption { get; set; } - [Reactive] public bool ShowNesDrawnChrRomOption { get; set; } + [ObservableProperty] public partial bool ShowFrozenAddressesOption { get; set; } + [ObservableProperty] public partial bool ShowNesPcmDataOption { get; set; } + [ObservableProperty] public partial bool ShowNesDrawnChrRomOption { get; set; } [Obsolete("For designer only")] public MemoryToolsDisplayOptionsViewModel() : this(new()) { } @@ -40,7 +38,7 @@ public MemoryToolsDisplayOptionsViewModel(MemoryToolsViewModel memoryTools) return; } - AddDisposable(this.WhenAnyValue(x => x.Config.MemoryType).Subscribe(x => UpdateAvailableOptions())); + AddDisposable(Config.ObserveProp(nameof(Config.MemoryType), () => UpdateAvailableOptions())); } public void UpdateAvailableOptions() diff --git a/UI/Debugger/ViewModels/MemoryToolsViewModel.cs b/UI/Debugger/ViewModels/MemoryToolsViewModel.cs index 075eec3ec..813f1c5e2 100644 --- a/UI/Debugger/ViewModels/MemoryToolsViewModel.cs +++ b/UI/Debugger/ViewModels/MemoryToolsViewModel.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Labels; @@ -7,39 +8,36 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; namespace Mesen.Debugger.ViewModels { - public class MemoryToolsViewModel : DisposableViewModel + public partial class MemoryToolsViewModel : DisposableViewModel { - [Reactive] public HexEditorConfig Config { get; set; } - [Reactive] public int ScrollPosition { get; set; } - [Reactive] public HexEditorDataProvider? DataProvider { get; set; } - [Reactive] public TblByteCharConverter? TblConverter { get; set; } + [ObservableProperty] public partial HexEditorConfig Config { get; set; } + [ObservableProperty] public partial int ScrollPosition { get; set; } + [ObservableProperty] public partial HexEditorDataProvider? DataProvider { get; set; } + [ObservableProperty] public partial TblByteCharConverter? TblConverter { get; set; } - [Reactive] public Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); + [ObservableProperty] public partial Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); - [Reactive] public int SelectionStart { get; set; } - [Reactive] public int SelectionLength { get; set; } + [ObservableProperty] public partial int SelectionStart { get; set; } + [ObservableProperty] public partial int SelectionLength { get; set; } - [Reactive] public string LocationText { get; private set; } = ""; - [Reactive] public string LengthText { get; private set; } = ""; + [ObservableProperty] public partial string LocationText { get; private set; } = ""; + [ObservableProperty] public partial string LengthText { get; private set; } = ""; - [Reactive] public List FileMenuItems { get; set; } = new(); - [Reactive] public List ViewMenuItems { get; set; } = new(); - [Reactive] public List SearchMenuItems { get; set; } = new(); - [Reactive] public List ToolbarItems { get; set; } = new(); + [ObservableProperty] public partial List FileMenuItems { get; set; } = new(); + [ObservableProperty] public partial List ViewMenuItems { get; set; } = new(); + [ObservableProperty] public partial List SearchMenuItems { get; set; } = new(); + [ObservableProperty] public partial List ToolbarItems { get; set; } = new(); - [Reactive] public int MaxScrollValue { get; private set; } + [ObservableProperty] public partial int MaxScrollValue { get; private set; } private HexEditor _editor; public MemoryToolsDisplayOptionsViewModel Options { get; } @@ -68,7 +66,8 @@ public MemoryToolsViewModel(HexEditor editor) UpdateAvailableMemoryTypes(); - AddDisposable(this.WhenAnyValue(x => x.SelectionStart, x => x.SelectionLength).Subscribe(((int start, int length) o) => { + AddDisposable(this.ObserveProp([nameof(SelectionStart), nameof(SelectionLength)], () => { + (int start, int length) o = (SelectionStart, SelectionLength); string location; string length = ""; if(o.length <= 1) { @@ -96,13 +95,11 @@ public MemoryToolsViewModel(HexEditor editor) })); AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => UpdateDataProvider())); - AddDisposable(this.WhenAnyValue(x => x.TblConverter).Subscribe(x => UpdateDataProvider())); - AddDisposable(this.WhenAnyValue( - x => x.Config.MemoryType, - x => x.Config.BytesPerRow - ).Subscribe(((MemoryType memType, int bytesPerRow) o) => { - MaxScrollValue = (DebugApi.GetMemorySize(o.memType) / o.bytesPerRow) - 1; + AddDisposable(this.ObserveProp(nameof(TblConverter), () => UpdateDataProvider())); + + AddDisposable(Config.ObserveProp([nameof(Config.MemoryType), nameof(Config.BytesPerRow)], () => { + MaxScrollValue = (DebugApi.GetMemorySize(Config.MemoryType) / Config.BytesPerRow) - 1; _editor.SetCursorPosition(0, false, true); })); } diff --git a/UI/Debugger/ViewModels/MemoryViewerFindViewModel.cs b/UI/Debugger/ViewModels/MemoryViewerFindViewModel.cs index 883751c53..0c47e8f9f 100644 --- a/UI/Debugger/ViewModels/MemoryViewerFindViewModel.cs +++ b/UI/Debugger/ViewModels/MemoryViewerFindViewModel.cs @@ -1,10 +1,10 @@ using Avalonia.Controls; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Utilities; +using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -13,29 +13,29 @@ namespace Mesen.Debugger.ViewModels; -public class MemoryViewerFindViewModel : DisposableViewModel +public partial class MemoryViewerFindViewModel : DisposableViewModel { - [Reactive] public SearchDataType DataType { get; set; } - [Reactive] public SearchIntType IntType { get; set; } - [Reactive] public bool CaseSensitive { get; set; } - [Reactive] public bool UseTblMappings { get; set; } - - [Reactive] public bool FilterNotAccessed { get; set; } - [Reactive] public bool FilterRead { get; set; } - [Reactive] public bool FilterWrite { get; set; } - [Reactive] public bool FilterExec { get; set; } - [Reactive] public bool FilterTimeSpanEnabled { get; set; } - [Reactive] public int FilterTimeSpan { get; set; } - - [Reactive] public bool FilterCode { get; set; } - [Reactive] public bool FilterData { get; set; } - [Reactive] public bool FilterUnidentified { get; set; } - - [Reactive] public bool IsInteger { get; private set; } - [Reactive] public bool IsString { get; private set; } - [Reactive] public bool IsValid { get; private set; } = false; - [Reactive] public bool ShowNotFoundError { get; set; } - [Reactive] public string SearchString { get; set; } = ""; + [ObservableProperty] public partial SearchDataType DataType { get; set; } + [ObservableProperty] public partial SearchIntType IntType { get; set; } + [ObservableProperty] public partial bool CaseSensitive { get; set; } + [ObservableProperty] public partial bool UseTblMappings { get; set; } + + [ObservableProperty] public partial bool FilterNotAccessed { get; set; } + [ObservableProperty] public partial bool FilterRead { get; set; } + [ObservableProperty] public partial bool FilterWrite { get; set; } + [ObservableProperty] public partial bool FilterExec { get; set; } + [ObservableProperty] public partial bool FilterTimeSpanEnabled { get; set; } + [ObservableProperty] public partial int FilterTimeSpan { get; set; } + + [ObservableProperty] public partial bool FilterCode { get; set; } + [ObservableProperty] public partial bool FilterData { get; set; } + [ObservableProperty] public partial bool FilterUnidentified { get; set; } + + [ObservableProperty] public partial bool IsInteger { get; private set; } + [ObservableProperty] public partial bool IsString { get; private set; } + [ObservableProperty] public partial bool IsValid { get; private set; } = false; + [ObservableProperty] public partial bool ShowNotFoundError { get; set; } + [ObservableProperty] public partial string SearchString { get; set; } = ""; private MemoryToolsViewModel _memToolsModel; @@ -46,12 +46,12 @@ public MemoryViewerFindViewModel(MemoryToolsViewModel memToolsModel) { _memToolsModel = memToolsModel; - AddDisposable(this.WhenAnyValue(x => x.DataType).Subscribe(x => { + AddDisposable(this.ObserveProp(nameof(DataType), () => { IsInteger = DataType == SearchDataType.Integer; IsString = DataType == SearchDataType.String; })); - AddDisposable(this.WhenAnyValue(x => x.SearchString).Subscribe(x => { + AddDisposable(this.ObserveProp(nameof(SearchString), () => { if(SearchString.Contains(Environment.NewLine)) { //Run asynchronously to allow the textbox to update its content correctly Dispatcher.UIThread.Post(() => { @@ -60,7 +60,7 @@ public MemoryViewerFindViewModel(MemoryToolsViewModel memToolsModel) } })); - AddDisposable(this.WhenAnyValue(x => x.DataType, x => x.IntType, x => x.SearchString).Subscribe(x => { + AddDisposable(this.ObserveProp([nameof(DataType), nameof(IntType), nameof(SearchString)], () => { SearchData? searchData = GetSearchData(); IsValid = searchData != null && searchData.Data.Length > 0; })); diff --git a/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs b/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs index 54b8ec5f1..222752599 100644 --- a/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs +++ b/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs @@ -1,10 +1,9 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Debugger.Utilities; using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; @@ -14,19 +13,19 @@ namespace Mesen.Debugger.ViewModels; -public class NesHeaderEditViewModel : DisposableViewModel +public partial class NesHeaderEditViewModel : DisposableViewModel { public NesHeader Header { get; } - [Reactive] public bool IsBatteryCheckboxEnabled { get; private set; } - [Reactive] public bool IsVsSystemVisible { get; private set; } - [Reactive] public bool IsNes20 { get; private set; } + [ObservableProperty] public partial bool IsBatteryCheckboxEnabled { get; private set; } + [ObservableProperty] public partial bool IsVsSystemVisible { get; private set; } + [ObservableProperty] public partial bool IsNes20 { get; private set; } - [Reactive] public Enum[]? AvailableSystemTypes { get; private set; } = null; - [Reactive] public Enum[]? AvailableTimings { get; private set; } = null; + [ObservableProperty] public partial Enum[]? AvailableSystemTypes { get; private set; } = null; + [ObservableProperty] public partial Enum[]? AvailableTimings { get; private set; } = null; - [Reactive] public string HeaderBytes { get; private set; } = ""; - [Reactive] public string ErrorMessage { get; private set; } = ""; + [ObservableProperty] public partial string HeaderBytes { get; private set; } = ""; + [ObservableProperty] public partial string ErrorMessage { get; private set; } = ""; private RomInfo _romInfo; private byte[] _prgRom; @@ -54,14 +53,14 @@ public NesHeaderEditViewModel() _romInfo = EmuApi.GetRomInfo(); Header = NesHeader.FromBytes(headerBytes); - AddDisposable(this.WhenAnyValue(x => x.Header.SaveRam, x => x.Header.ChrRamBattery).Subscribe(x => { + AddDisposable(Header.ObserveProp([nameof(Header.SaveRam), nameof(Header.ChrRamBattery)], () => { IsBatteryCheckboxEnabled = Header.SaveRam == MemorySizes.None && Header.ChrRamBattery == MemorySizes.None; if(!IsBatteryCheckboxEnabled) { Header.HasBattery = true; } })); - AddDisposable(this.WhenAnyValue(x => x.Header.System, x => x.Header.FileType).Subscribe(x => { + AddDisposable(Header.ObserveProp([nameof(Header.System), nameof(Header.FileType)], () => { bool isVsSystem = Header.System == TvSystem.VsSystem; IsVsSystemVisible = isVsSystem && Header.FileType == NesFileType.Nes2_0; if(!IsVsSystemVisible) { @@ -70,7 +69,7 @@ public NesHeaderEditViewModel() } })); - AddDisposable(this.WhenAnyValue(x => x.Header.FileType).Subscribe(x => { + AddDisposable(Header.ObserveProp(nameof(Header.FileType), () => { IsNes20 = Header.FileType == NesFileType.Nes2_0; if(IsNes20) { @@ -175,34 +174,34 @@ public enum RomSizeUnit MB } - public class NesHeader : ViewModelBase + public partial class NesHeader : ViewModelBase { private static Dictionary _validSizeValues = new Dictionary(); - [Reactive] public NesFileType FileType { get; set; } + [ObservableProperty] public partial NesFileType FileType { get; set; } - [Reactive] public uint MapperId { get; set; } - [Reactive] public uint SubmapperId { get; set; } + [ObservableProperty] public partial uint MapperId { get; set; } + [ObservableProperty] public partial uint SubmapperId { get; set; } - [Reactive] public UInt64 PrgRom { get; set; } - [Reactive] public RomSizeUnit PrgRomUnit { get; set; } - [Reactive] public UInt64 ChrRom { get; set; } - [Reactive] public RomSizeUnit ChrRomUnit { get; set; } + [ObservableProperty] public partial UInt64 PrgRom { get; set; } + [ObservableProperty] public partial RomSizeUnit PrgRomUnit { get; set; } + [ObservableProperty] public partial UInt64 ChrRom { get; set; } + [ObservableProperty] public partial RomSizeUnit ChrRomUnit { get; set; } - [Reactive] public MirroringType Mirroring { get; set; } + [ObservableProperty] public partial MirroringType Mirroring { get; set; } - [Reactive] public FrameTiming Timing { get; set; } - [Reactive] public TvSystem System { get; set; } - [Reactive] public bool HasTrainer { get; set; } - [Reactive] public bool HasBattery { get; set; } - [Reactive] public VsPpuType VsPpu { get; set; } - [Reactive] public VsSystemType VsSystem { get; set; } - [Reactive] public GameInputType InputType { get; set; } + [ObservableProperty] public partial FrameTiming Timing { get; set; } + [ObservableProperty] public partial TvSystem System { get; set; } + [ObservableProperty] public partial bool HasTrainer { get; set; } + [ObservableProperty] public partial bool HasBattery { get; set; } + [ObservableProperty] public partial VsPpuType VsPpu { get; set; } + [ObservableProperty] public partial VsSystemType VsSystem { get; set; } + [ObservableProperty] public partial GameInputType InputType { get; set; } - [Reactive] public MemorySizes WorkRam { get; set; } = MemorySizes.None; - [Reactive] public MemorySizes SaveRam { get; set; } = MemorySizes.None; - [Reactive] public MemorySizes ChrRam { get; set; } = MemorySizes.None; - [Reactive] public MemorySizes ChrRamBattery { get; set; } = MemorySizes.None; + [ObservableProperty] public partial MemorySizes WorkRam { get; set; } = MemorySizes.None; + [ObservableProperty] public partial MemorySizes SaveRam { get; set; } = MemorySizes.None; + [ObservableProperty] public partial MemorySizes ChrRam { get; set; } = MemorySizes.None; + [ObservableProperty] public partial MemorySizes ChrRamBattery { get; set; } = MemorySizes.None; static NesHeader() { diff --git a/UI/Debugger/ViewModels/PaletteViewerViewModel.cs b/UI/Debugger/ViewModels/PaletteViewerViewModel.cs index 23bb1ba18..50c8f4ae9 100644 --- a/UI/Debugger/ViewModels/PaletteViewerViewModel.cs +++ b/UI/Debugger/ViewModels/PaletteViewerViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Media; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Utilities; @@ -10,33 +11,31 @@ using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace Mesen.Debugger.ViewModels { - public class PaletteViewerViewModel : DisposableViewModel, ICpuTypeModel + public partial class PaletteViewerViewModel : DisposableViewModel, ICpuTypeModel { public CpuType CpuType { get; set; } public PaletteViewerConfig Config { get; } - [Reactive] public RefreshTimingViewModel RefreshTiming { get; private set; } + [ObservableProperty] public partial RefreshTimingViewModel RefreshTiming { get; private set; } - [Reactive] public UInt32[] PaletteColors { get; set; } = Array.Empty(); - [Reactive] public UInt32[]? PaletteValues { get; set; } = null; - [Reactive] public int PaletteColumnCount { get; private set; } = 16; + [ObservableProperty] public partial UInt32[] PaletteColors { get; set; } = Array.Empty(); + [ObservableProperty] public partial UInt32[]? PaletteValues { get; set; } = null; + [ObservableProperty] public partial int PaletteColumnCount { get; private set; } = 16; - [Reactive] public DynamicTooltip? PreviewPanel { get; private set; } - [Reactive] public int SelectedPalette { get; set; } = 0; - [Reactive] public int BlockSize { get; set; } = 8; + [ObservableProperty] public partial DynamicTooltip? PreviewPanel { get; private set; } + [ObservableProperty] public partial int SelectedPalette { get; set; } = 0; + [ObservableProperty] public partial int BlockSize { get; set; } = 8; - [Reactive] public DynamicTooltip? ViewerTooltip { get; set; } - [Reactive] public int ViewerMouseOverPalette { get; set; } = -1; + [ObservableProperty] public partial DynamicTooltip? ViewerTooltip { get; set; } + [ObservableProperty] public partial int ViewerMouseOverPalette { get; set; } = -1; - [Reactive] public List FileMenuActions { get; private set; } = new(); - [Reactive] public List ViewMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List ViewMenuActions { get; private set; } = new(); private RefStruct? _palette = null; @@ -53,8 +52,13 @@ public PaletteViewerViewModel(CpuType cpuType) return; } - AddDisposable(this.WhenAnyValue(x => x.Config.Zoom).Subscribe(x => BlockSize = Math.Max(16, 16 + (x - 1) * 4))); - AddDisposable(this.WhenAnyValue(x => x.SelectedPalette).Subscribe(x => UpdatePreviewPanel())); + AddDisposable(Config.ObserveProp(nameof(Config.Zoom), () => BlockSize = Math.Max(16, 16 + (Config.Zoom - 1) * 4))); + UpdatePreviewPanel(); + } + + partial void OnSelectedPaletteChanged(int value) + { + UpdatePreviewPanel(); } public void InitActions(Window wnd, PaletteSelector palSelector, Border selectorBorder) diff --git a/UI/Debugger/ViewModels/ProfilerWindowViewModel.cs b/UI/Debugger/ViewModels/ProfilerWindowViewModel.cs index 2dfc9f918..d44e883c4 100644 --- a/UI/Debugger/ViewModels/ProfilerWindowViewModel.cs +++ b/UI/Debugger/ViewModels/ProfilerWindowViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Controls.Selection; using Avalonia.Threading; using Avalonia.VisualTree; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Mesen.Config; using Mesen.Debugger.Labels; @@ -11,8 +12,6 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -21,10 +20,10 @@ namespace Mesen.Debugger.ViewModels { - public class ProfilerWindowViewModel : DisposableViewModel + public partial class ProfilerWindowViewModel : DisposableViewModel { - [Reactive] public List ProfilerTabs { get; set; } = new List(); - [Reactive] public ProfilerTab? SelectedTab { get; set; } = null; + [ObservableProperty] public partial List ProfilerTabs { get; set; } = new List(); + [ObservableProperty] public partial ProfilerTab? SelectedTab { get; set; } = null; public List FileMenuActions { get; } = new(); public List ViewMenuActions { get; } = new(); @@ -41,7 +40,7 @@ public ProfilerWindowViewModel(Window? wnd) UpdateAvailableTabs(); - AddDisposable(this.WhenAnyValue(x => x.SelectedTab).Subscribe(x => { + AddDisposable(this.ObserveProp(nameof(SelectedTab), () => { if(SelectedTab != null && EmuApi.IsPaused()) { RefreshData(); } @@ -132,13 +131,13 @@ public void RefreshData() } } - public class ProfilerTab : ReactiveObject + public partial class ProfilerTab : ObservableObject { - [Reactive] public string TabName { get; set; } = ""; - [Reactive] public CpuType CpuType { get; set; } = CpuType.Snes; - [Reactive] public MesenList GridData { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new(); - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial string TabName { get; set; } = ""; + [ObservableProperty] public partial CpuType CpuType { get; set; } = CpuType.Snes; + [ObservableProperty] public partial MesenList GridData { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new(); + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public ProfilerConfig Config => ConfigManager.Config.Debug.Profiler; public List ColumnWidths { get; } = ConfigManager.Config.Debug.Profiler.ColumnWidths; diff --git a/UI/Debugger/ViewModels/QuickSearchViewModel.cs b/UI/Debugger/ViewModels/QuickSearchViewModel.cs index 5bd484746..850c08324 100644 --- a/UI/Debugger/ViewModels/QuickSearchViewModel.cs +++ b/UI/Debugger/ViewModels/QuickSearchViewModel.cs @@ -2,10 +2,9 @@ using Avalonia.Controls; using Avalonia.Media; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -15,11 +14,11 @@ namespace Mesen.Debugger.ViewModels; -public class QuickSearchViewModel : ViewModelBase +public partial class QuickSearchViewModel : ViewModelBase { - [Reactive] public bool IsSearchBoxVisible { get; set; } - [Reactive] public string SearchString { get; set; } = ""; - [Reactive] public bool IsErrorVisible { get; set; } = false; + [ObservableProperty] public partial bool IsSearchBoxVisible { get; set; } + [ObservableProperty] public partial string SearchString { get; set; } = ""; + [ObservableProperty] public partial bool IsErrorVisible { get; set; } = false; public delegate void OnFindEventHandler(OnFindEventArgs e); public event OnFindEventHandler? OnFind; @@ -32,16 +31,18 @@ public class QuickSearchViewModel : ViewModelBase public QuickSearchViewModel() { - this.WhenAnyValue(x => x.SearchString).Subscribe(x => { - if(!string.IsNullOrWhiteSpace(x)) { - if(!string.IsNullOrEmpty(_noMatchSearch) && x.StartsWith(_noMatchSearch)) { - //Previous search gave no result, current search starts with the same string, so can't give results either, don't search - return; - } + } - Find(SearchDirection.Forward, false); + partial void OnSearchStringChanged(string value) + { + if(!string.IsNullOrWhiteSpace(value)) { + if(!string.IsNullOrEmpty(_noMatchSearch) && value.StartsWith(_noMatchSearch)) { + //Previous search gave no result, current search starts with the same string, so can't give results either, don't search + return; } - }); + + Find(SearchDirection.Forward, false); + } } public void Open() diff --git a/UI/Debugger/ViewModels/RefreshTimingViewModel.cs b/UI/Debugger/ViewModels/RefreshTimingViewModel.cs index ac8b19c89..ec48143a9 100644 --- a/UI/Debugger/ViewModels/RefreshTimingViewModel.cs +++ b/UI/Debugger/ViewModels/RefreshTimingViewModel.cs @@ -1,22 +1,25 @@ -using Mesen.Config; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Mesen.Config; using Mesen.Interop; +using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive; namespace Mesen.Debugger.ViewModels { - public class RefreshTimingViewModel : ViewModelBase + public partial class RefreshTimingViewModel : ViewModelBase { public RefreshTimingConfig Config { get; } public RefreshTimingConsoleConfig ConsoleConfig { get; } - [Reactive] public int MinScanline { get; private set; } - [Reactive] public int MaxScanline { get; private set; } - [Reactive] public int MaxCycle { get; private set; } + [ObservableProperty] public partial int RefreshCycle { get; private set; } + [ObservableProperty] public partial int RefreshScanline { get; private set; } - public ReactiveCommand ResetCommand { get; } + [ObservableProperty] public partial int MinScanline { get; private set; } + [ObservableProperty] public partial int MaxScanline { get; private set; } + [ObservableProperty] public partial int MaxCycle { get; private set; } + + public IRelayCommand ResetCommand { get; } private CpuType _cpuType; @@ -30,9 +33,21 @@ public RefreshTimingViewModel(RefreshTimingConfig config, CpuType cpuType) _cpuType = cpuType; UpdateMinMaxValues(_cpuType); - ResetCommand = ReactiveCommand.Create(Reset); + ResetCommand = new RelayCommand(Reset); + UpdateMinMax(); + + RefreshCycle = ConsoleConfig.RefreshCycle; + RefreshScanline = ConsoleConfig.RefreshScanline; + } + + partial void OnRefreshCycleChanged(int value) + { + UpdateMinMax(); + } - ConsoleConfig.WhenAnyValue(x => x.RefreshScanline, x => x.RefreshCycle).Subscribe(x => UpdateMinMax()); + partial void OnRefreshScanlineChanged(int value) + { + UpdateMinMax(); } private void UpdateMinMax() @@ -40,13 +55,16 @@ private void UpdateMinMax() //Manually enforce min/max to avoid issues when switching from one console type to another where the UI //could end up setting the new console's scanline value to the max scanline value of the previous console //(presumably due to the order in which the property bindings were processed) - ConsoleConfig.RefreshScanline = Math.Max(MinScanline, Math.Min(MaxScanline, ConsoleConfig.RefreshScanline)); - ConsoleConfig.RefreshCycle = Math.Max(0, Math.Min(MaxCycle, ConsoleConfig.RefreshCycle)); + RefreshScanline = Math.Max(MinScanline, Math.Min(MaxScanline, RefreshScanline)); + RefreshCycle = Math.Max(0, Math.Min(MaxCycle, RefreshCycle)); + + ConsoleConfig.RefreshCycle = RefreshCycle; + ConsoleConfig.RefreshScanline = RefreshScanline; } public void Reset() { - ConsoleConfig.RefreshScanline = _cpuType.GetConsoleType() switch { + RefreshScanline = _cpuType.GetConsoleType() switch { ConsoleType.Snes => 240, ConsoleType.Nes => 241, ConsoleType.Gameboy => 144, @@ -57,7 +75,7 @@ public void Reset() _ => throw new Exception("Invalid console type") }; - ConsoleConfig.RefreshCycle = 0; + RefreshCycle = 0; } private void UpdateMinMaxValues(CpuType cpuType) diff --git a/UI/Debugger/ViewModels/RegisterViewerWindowViewModel.cs b/UI/Debugger/ViewModels/RegisterViewerWindowViewModel.cs index 12f3909bb..2ad6885fe 100644 --- a/UI/Debugger/ViewModels/RegisterViewerWindowViewModel.cs +++ b/UI/Debugger/ViewModels/RegisterViewerWindowViewModel.cs @@ -2,13 +2,12 @@ using Avalonia.Controls.Selection; using Avalonia.Media; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.RegisterViewer; using Mesen.Debugger.Utilities; using Mesen.Interop; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -16,15 +15,15 @@ namespace Mesen.Debugger.ViewModels { - public class RegisterViewerWindowViewModel : DisposableViewModel, ICpuTypeModel + public partial class RegisterViewerWindowViewModel : DisposableViewModel, ICpuTypeModel { - [Reactive] public List Tabs { get; set; } = new List(); + [ObservableProperty] public partial List Tabs { get; set; } = new List(); public RegisterViewerConfig Config { get; } - [Reactive] public RefreshTimingViewModel RefreshTiming { get; private set; } + [ObservableProperty] public partial RefreshTimingViewModel RefreshTiming { get; private set; } - [Reactive] public List FileMenuActions { get; private set; } = new(); - [Reactive] public List ViewMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List ViewMenuActions { get; private set; } = new(); private BaseState? _state = null; @@ -162,13 +161,10 @@ public void OnGameLoaded() } } - public class RegisterViewerTab : ReactiveObject + public partial class RegisterViewerTab : ObservableObject { - private string _name; - private List _data; - - public string TabName { get => _name; set => this.RaiseAndSetIfChanged(ref _name, value); } - public List Data { get => _data; set => this.RaiseAndSetIfChanged(ref _data, value); } + [ObservableProperty] public partial string TabName { get; set; } + [ObservableProperty] public partial List Data { get; set; } public SelectionModel Selection { get; set; } = new(); public List ColumnWidths { get; set; } = new(); @@ -177,8 +173,8 @@ public class RegisterViewerTab : ReactiveObject public RegisterViewerTab(string name, List data, CpuType? cpuType = null, MemoryType? memoryType = null) { - _name = name; - _data = data; + TabName = name; + Data = data; CpuType = cpuType; MemoryType = memoryType; } diff --git a/UI/Debugger/ViewModels/ScriptWindowViewModel.cs b/UI/Debugger/ViewModels/ScriptWindowViewModel.cs index 75c116aaf..6a07bcf38 100644 --- a/UI/Debugger/ViewModels/ScriptWindowViewModel.cs +++ b/UI/Debugger/ViewModels/ScriptWindowViewModel.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Utilities; using Mesen.Debugger.Windows; @@ -8,55 +9,51 @@ using Mesen.Utilities; using Mesen.ViewModels; using Mesen.Windows; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using System.Reactive.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Mesen.Debugger.ViewModels { - public class ScriptWindowViewModel : ViewModelBase + public partial class ScriptWindowViewModel : ViewModelBase { public ScriptWindowConfig Config { get; } = ConfigManager.Config.Debug.ScriptWindow; - [Reactive] public string Code { get; set; } = ""; - [Reactive] public string FilePath { get; set; } = ""; - [Reactive] public int ScriptId { get; set; } = -1; - [Reactive] public string Log { get; set; } = ""; - [Reactive] public string ScriptName { get; set; } = ""; + [ObservableProperty] public partial string Code { get; set; } = ""; + [ObservableProperty] public partial string FilePath { get; set; } = ""; + [ObservableProperty] public partial int ScriptId { get; set; } = -1; + [ObservableProperty] public partial string Log { get; set; } = ""; + [ObservableProperty] public partial string ScriptName { get; set; } = ""; - [ObservableAsProperty] public string WindowTitle { get; } = ""; + [ObservableProperty] public partial string WindowTitle { get; private set; } = ""; private string _originalText = ""; private ScriptWindow? _wnd = null; private FileSystemWatcher _fileWatcher = new(); - private ContextMenuAction _recentScriptsAction = new(); - - [Reactive] public List FileMenuActions { get; private set; } = new(); - [Reactive] public List ScriptMenuActions { get; private set; } = new(); - [Reactive] public List HelpMenuActions { get; private set; } = new(); - [Reactive] public List ToolbarActions { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List ScriptMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List HelpMenuActions { get; private set; } = new(); + [ObservableProperty] public partial List ToolbarActions { get; private set; } = new(); [Obsolete("For designer only")] public ScriptWindowViewModel() : this(null) { } public ScriptWindowViewModel(ScriptStartupBehavior? behavior) { - this.WhenAnyValue(x => x.ScriptName).Select(x => { + this.ObserveProp(nameof(ScriptName), () => { string wndTitle = ResourceHelper.GetViewLabel(nameof(ScriptWindow), "wndTitle"); - if(!string.IsNullOrWhiteSpace(x)) { - return wndTitle + " - " + x; + if(!string.IsNullOrWhiteSpace(ScriptName)) { + WindowTitle = wndTitle + " - " + ScriptName; + } else { + WindowTitle = wndTitle; } - return wndTitle; - }).ToPropertyEx(this, x => x.WindowTitle); + }); switch(behavior ?? Config.ScriptStartupBehavior) { case ScriptStartupBehavior.ShowBlankWindow: break; diff --git a/UI/Debugger/ViewModels/SourceViewViewModel.cs b/UI/Debugger/ViewModels/SourceViewViewModel.cs index 701dc4789..3b24fb9f7 100644 --- a/UI/Debugger/ViewModels/SourceViewViewModel.cs +++ b/UI/Debugger/ViewModels/SourceViewViewModel.cs @@ -1,5 +1,7 @@ using Avalonia; +using Avalonia.Input.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Disassembly; @@ -8,8 +10,6 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -18,7 +18,7 @@ namespace Mesen.Debugger.ViewModels; -public class SourceViewViewModel : DisposableViewModel, ISelectableModel +public partial class SourceViewViewModel : DisposableViewModel, ISelectableModel { public ISymbolProvider SymbolProvider { get; set; } public DebugConfig Config { get; } @@ -29,18 +29,18 @@ public class SourceViewViewModel : DisposableViewModel, ISelectableModel public QuickSearchViewModel QuickSearch { get; } = new(); - [Reactive] public SourceFileInfo? SelectedFile { get; set; } - [Reactive] public int MaxScrollPosition { get; private set; } - [Reactive] public int ScrollPosition { get; set; } - [Reactive] public CodeLineData[] Lines { get; private set; } = Array.Empty(); + [ObservableProperty] public partial SourceFileInfo? SelectedFile { get; set; } + [ObservableProperty] public partial int MaxScrollPosition { get; private set; } + [ObservableProperty] public partial int ScrollPosition { get; set; } + [ObservableProperty] public partial CodeLineData[] Lines { get; private set; } = Array.Empty(); - [Reactive] public int? ActiveAddress { get; set; } - [Reactive] public int SelectedRow { get; set; } - [Reactive] public int SelectionAnchor { get; set; } - [Reactive] public int SelectionStart { get; set; } - [Reactive] public int SelectionEnd { get; set; } + [ObservableProperty] public partial int? ActiveAddress { get; set; } + [ObservableProperty] public partial int SelectedRow { get; set; } + [ObservableProperty] public partial int SelectionAnchor { get; set; } + [ObservableProperty] public partial int SelectionStart { get; set; } + [ObservableProperty] public partial int SelectionEnd { get; set; } - [Reactive] public int VisibleRowCount { get; set; } = 100; + [ObservableProperty] public partial int VisibleRowCount { get; set; } = 100; public DebuggerWindowViewModel Debugger { get; } public NavigationHistory History { get; } = new(); @@ -72,21 +72,21 @@ public SourceViewViewModel(DebuggerWindowViewModel debugger, ISymbolProvider sym QuickSearch.OnFind += QuickSearch_OnFind; - AddDisposable(this.WhenAnyValue(x => x.QuickSearch.IsSearchBoxVisible).Subscribe(x => { + AddDisposable(QuickSearch.ObserveProp(nameof(QuickSearch.IsSearchBoxVisible), () => { if(!QuickSearch.IsSearchBoxVisible) { _viewer?.Focus(); } })); - AddDisposable(this.WhenAnyValue(x => x.SelectedFile).Subscribe(x => { - MaxScrollPosition = (x?.Data.Length ?? 1) - 1; + AddDisposable(this.ObserveProp(nameof(SelectedFile), () => { + MaxScrollPosition = (SelectedFile?.Data.Length ?? 1) - 1; ScrollPosition = 0; UpdateCodeLines(); })); int lastValue = ScrollPosition; - AddDisposable(this.WhenAnyValue(x => x.ScrollPosition).Subscribe(x => { - if(_viewer == null && x == 0) { + AddDisposable(this.ObserveProp(nameof(ScrollPosition), () => { + if(_viewer == null && ScrollPosition == 0) { ScrollPosition = lastValue; return; } diff --git a/UI/Debugger/ViewModels/SpritePreviewModel.cs b/UI/Debugger/ViewModels/SpritePreviewModel.cs index 01737605f..c9e4a6292 100644 --- a/UI/Debugger/ViewModels/SpritePreviewModel.cs +++ b/UI/Debugger/ViewModels/SpritePreviewModel.cs @@ -4,41 +4,41 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.ViewModels { - public class SpritePreviewModel : ViewModelBase + public partial class SpritePreviewModel : ViewModelBase { - [Reactive] public int SpriteIndex { get; set; } - [Reactive] public int X { get; set; } - [Reactive] public int Y { get; set; } - [Reactive] public int RawX { get; set; } - [Reactive] public int RawY { get; set; } - [Reactive] public int PreviewX { get; set; } - [Reactive] public int PreviewY { get; set; } - [Reactive] public int Width { get; set; } - [Reactive] public int Height { get; set; } - [Reactive] public int TileIndex { get; set; } - [Reactive] public int TileAddress { get; set; } - [Reactive] public DebugSpritePriority Priority { get; set; } - [Reactive] public DebugSpriteMode Mode { get; set; } - [Reactive] public int Bpp { get; set; } - [Reactive] public TileFormat Format { get; set; } - [Reactive] public int Palette { get; set; } - [Reactive] public int PaletteAddress { get; set; } - [Reactive] public SpriteVisibility Visibility { get; set; } - [Reactive] public string? Flags { get; set; } - - [Reactive] public NullableBoolean HorizontalMirror { get; set; } - [Reactive] public NullableBoolean VerticalMirror { get; set; } - [Reactive] public NullableBoolean MosaicEnabled { get; set; } - [Reactive] public NullableBoolean TransformEnabled { get; set; } - [Reactive] public NullableBoolean DoubleSize { get; set; } - [Reactive] public sbyte TransformParamIndex { get; set; } - [Reactive] public bool UseExtendedVram { get; set; } - [Reactive] public NullableBoolean UseSecondTable { get; set; } + [ObservableProperty] public partial int SpriteIndex { get; set; } + [ObservableProperty] public partial int X { get; set; } + [ObservableProperty] public partial int Y { get; set; } + [ObservableProperty] public partial int RawX { get; set; } + [ObservableProperty] public partial int RawY { get; set; } + [ObservableProperty] public partial int PreviewX { get; set; } + [ObservableProperty] public partial int PreviewY { get; set; } + [ObservableProperty] public partial int Width { get; set; } + [ObservableProperty] public partial int Height { get; set; } + [ObservableProperty] public partial int TileIndex { get; set; } + [ObservableProperty] public partial int TileAddress { get; set; } + [ObservableProperty] public partial DebugSpritePriority Priority { get; set; } + [ObservableProperty] public partial DebugSpriteMode Mode { get; set; } + [ObservableProperty] public partial int Bpp { get; set; } + [ObservableProperty] public partial TileFormat Format { get; set; } + [ObservableProperty] public partial int Palette { get; set; } + [ObservableProperty] public partial int PaletteAddress { get; set; } + [ObservableProperty] public partial SpriteVisibility Visibility { get; set; } + [ObservableProperty] public partial string? Flags { get; set; } + + [ObservableProperty] public partial NullableBoolean HorizontalMirror { get; set; } + [ObservableProperty] public partial NullableBoolean VerticalMirror { get; set; } + [ObservableProperty] public partial NullableBoolean MosaicEnabled { get; set; } + [ObservableProperty] public partial NullableBoolean TransformEnabled { get; set; } + [ObservableProperty] public partial NullableBoolean DoubleSize { get; set; } + [ObservableProperty] public partial sbyte TransformParamIndex { get; set; } + [ObservableProperty] public partial bool UseExtendedVram { get; set; } + [ObservableProperty] public partial NullableBoolean UseSecondTable { get; set; } public UInt32 TileCount { get; set; } public UInt32 WrapWidth { get; set; } @@ -47,9 +47,9 @@ public class SpritePreviewModel : ViewModelBase private UInt32[] _rawPreview = new UInt32[128 * 128]; - [Reactive] public DynamicBitmap? SpritePreview { get; set; } - [Reactive] public double SpritePreviewZoom { get; set; } - [Reactive] public bool FadePreview { get; set; } + [ObservableProperty] public partial DynamicBitmap? SpritePreview { get; set; } + [ObservableProperty] public partial double SpritePreviewZoom { get; set; } + [ObservableProperty] public partial bool FadePreview { get; set; } public int RealWidth => Width / (DoubleSize == NullableBoolean.True ? 2 : 1); public int RealHeight => Height / (DoubleSize == NullableBoolean.True ? 2 : 1); diff --git a/UI/Debugger/ViewModels/SpriteViewerListViewModel.cs b/UI/Debugger/ViewModels/SpriteViewerListViewModel.cs index 06ff9ba95..4eb546fe4 100644 --- a/UI/Debugger/ViewModels/SpriteViewerListViewModel.cs +++ b/UI/Debugger/ViewModels/SpriteViewerListViewModel.cs @@ -1,10 +1,10 @@ using Avalonia.Controls.Selection; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using DataBoxControl; using Mesen.Config; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -13,14 +13,14 @@ namespace Mesen.Debugger.ViewModels { - public class SpriteViewerListViewModel : DisposableViewModel + public partial class SpriteViewerListViewModel : DisposableViewModel { - [Reactive] public bool ShowListView { get; set; } - [Reactive] public double MinListViewHeight { get; set; } - [Reactive] public double ListViewHeight { get; set; } - [Reactive] public List? SpritePreviews { get; set; } = null; - [Reactive] public SelectionModel Selection { get; set; } = new(); - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial bool ShowListView { get; set; } + [ObservableProperty] public partial double MinListViewHeight { get; set; } + [ObservableProperty] public partial double ListViewHeight { get; set; } + [ObservableProperty] public partial List? SpritePreviews { get; set; } = null; + public SelectionModel Selection { get; private set; } = new(); + public SortState SortState { get; private set; } = new(); public List ColumnWidths => SpriteViewer.Config.ColumnWidths; public ICommand SortCommand { get; } @@ -38,13 +38,13 @@ public SpriteViewerListViewModel(SpriteViewerViewModel viewer) SortState.SetColumnSort("SpriteIndex", ListSortDirection.Ascending, false); - SortCommand = ReactiveCommand.Create(sortMemberPath => { + SortCommand = new RelayCommand(() => { RefreshList(true); }); - AddDisposable(this.WhenAnyValue(x => x.Selection.SelectedItem).Subscribe(x => { - if(x != null) { - SpriteViewer.SelectSprite(x.SpriteIndex); + AddDisposable(Selection.ObserveProp(nameof(Selection.SelectedItem), () => { + if(Selection.SelectedItem != null) { + SpriteViewer.SelectSprite(Selection.SelectedItem.SpriteIndex); } })); } @@ -108,27 +108,21 @@ public void RefreshList(bool force = false) } } - public void InitListViewObservers() + partial void OnShowListViewChanged(bool value) { - //Update list view height based on show list view flag - AddDisposable(this.WhenAnyValue(x => x.ShowListView).Subscribe(showListView => { - Config.ShowListView = showListView; - ListViewHeight = showListView ? Config.ListViewHeight : 0; - MinListViewHeight = showListView ? 100 : 0; - RefreshList(true); - })); - - AddDisposable(this.WhenAnyValue(x => x.SpriteViewer.SpritePreviews).Subscribe(x => { - RefreshList(true); - })); + Config.ShowListView = value; + ListViewHeight = value ? Config.ListViewHeight : 0; + MinListViewHeight = value ? 100 : 0; + RefreshList(true); + } - AddDisposable(this.WhenAnyValue(x => x.ListViewHeight).Subscribe(height => { - if(ShowListView) { - Config.ListViewHeight = height; - } else { - ListViewHeight = 0; - } - })); + partial void OnListViewHeightChanged(double value) + { + if(ShowListView) { + Config.ListViewHeight = value; + } else { + ListViewHeight = 0; + } } } } diff --git a/UI/Debugger/ViewModels/SpriteViewerViewModel.cs b/UI/Debugger/ViewModels/SpriteViewerViewModel.cs index b3e94d4f3..d57bbd8a9 100644 --- a/UI/Debugger/ViewModels/SpriteViewerViewModel.cs +++ b/UI/Debugger/ViewModels/SpriteViewerViewModel.cs @@ -5,6 +5,7 @@ using Avalonia.Media; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Utilities; @@ -13,8 +14,6 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -23,36 +22,36 @@ namespace Mesen.Debugger.ViewModels { - public class SpriteViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel + public partial class SpriteViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel { public SpriteViewerConfig Config { get; } - [Reactive] public RefreshTimingViewModel RefreshTiming { get; private set; } + [ObservableProperty] public partial RefreshTimingViewModel RefreshTiming { get; private set; } public CpuType CpuType { get; set; } - [Reactive] public SpritePreviewModel? SelectedSprite { get; set; } - [Reactive] public DynamicTooltip? SelectedPreviewPanel { get; set; } + [ObservableProperty] public partial SpritePreviewModel? SelectedSprite { get; set; } + [ObservableProperty] public partial DynamicTooltip? SelectedPreviewPanel { get; set; } - [Reactive] public DynamicTooltip? PreviewPanelTooltip { get; set; } - [Reactive] public SpritePreviewModel? PreviewPanelSprite { get; set; } + [ObservableProperty] public partial DynamicTooltip? PreviewPanelTooltip { get; set; } + [ObservableProperty] public partial SpritePreviewModel? PreviewPanelSprite { get; set; } - [Reactive] public DynamicTooltip? ViewerTooltip { get; set; } - [Reactive] public PixelPoint? ViewerMousePos { get; set; } + [ObservableProperty] public partial DynamicTooltip? ViewerTooltip { get; set; } + [ObservableProperty] public partial PixelPoint? ViewerMousePos { get; set; } - [Reactive] public DynamicBitmap ViewerBitmap { get; private set; } - [Reactive] public Rect SelectionRect { get; set; } - [Reactive] public Rect? MouseOverRect { get; set; } + [ObservableProperty] public partial DynamicBitmap ViewerBitmap { get; private set; } + [ObservableProperty] public partial Rect SelectionRect { get; set; } + [ObservableProperty] public partial Rect? MouseOverRect { get; set; } - [Reactive] public int TopClipSize { get; set; } - [Reactive] public int BottomClipSize { get; set; } - [Reactive] public int LeftClipSize { get; set; } - [Reactive] public int RightClipSize { get; set; } + [ObservableProperty] public partial int TopClipSize { get; set; } + [ObservableProperty] public partial int BottomClipSize { get; set; } + [ObservableProperty] public partial int LeftClipSize { get; set; } + [ObservableProperty] public partial int RightClipSize { get; set; } - [Reactive] public List SpritePreviews { get; set; } = new(); + [ObservableProperty] public partial List SpritePreviews { get; set; } = new(); public SpriteViewerListViewModel ListView { get; } - [Reactive] public int MaxSourceOffset { get; set; } = 0; + [ObservableProperty] public partial int MaxSourceOffset { get; set; } = 0; public List FileMenuActions { get; } = new(); public List ViewMenuActions { get; } = new(); @@ -171,27 +170,28 @@ public SpriteViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPic GetCopyHdPackFormatAction() })); - AddDisposable(this.WhenAnyValue(x => x.SelectedSprite).Subscribe(x => { - UpdateSelectionPreview(); - if(x != null) { - ListView.SelectSprite(x.SpriteIndex); - } - })); - - AddDisposable(this.WhenAnyValue(x => x.ViewerMousePos, x => x.PreviewPanelSprite).Subscribe(x => UpdateMouseOverRect())); - - AddDisposable(this.WhenAnyValue(x => x.Config.Source, x => x.Config.SourceOffset).Subscribe(x => RefreshData())); - - AddDisposable(this.WhenAnyValue(x => x.Config.ShowOffscreenRegions).Subscribe(x => RefreshTab())); - - ListView.InitListViewObservers(); - + AddDisposable(this.ObserveProp([nameof(ViewerMousePos), nameof(PreviewPanelSprite)], UpdateMouseOverRect)); + AddDisposable(Config.ObserveProp([nameof(Config.Source), nameof(Config.SourceOffset)], RefreshData)); + AddDisposable(Config.ObserveProp(nameof(Config.ShowOffscreenRegions), RefreshTab)); AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, Config_PropertyChanged)); DebugShortcutManager.RegisterActions(wnd, FileMenuActions); DebugShortcutManager.RegisterActions(wnd, ViewMenuActions); } + partial void OnSelectedSpriteChanged(SpritePreviewModel? value) + { + UpdateSelectionPreview(); + if(value != null) { + ListView.SelectSprite(value.SpriteIndex); + } + } + + partial void OnSpritePreviewsChanged(List value) + { + ListView.RefreshList(true); + } + private ContextMenuAction GetEditTileAction(Window wnd) { return new ContextMenuAction() { diff --git a/UI/Debugger/ViewModels/TileEditorViewModel.cs b/UI/Debugger/ViewModels/TileEditorViewModel.cs index b89a9a93f..36a8201be 100644 --- a/UI/Debugger/ViewModels/TileEditorViewModel.cs +++ b/UI/Debugger/ViewModels/TileEditorViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Media; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Utilities; @@ -10,26 +11,22 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels; -public class TileEditorViewModel : DisposableViewModel +public partial class TileEditorViewModel : DisposableViewModel { - [Reactive] public DynamicBitmap ViewerBitmap { get; private set; } + [ObservableProperty] public partial DynamicBitmap ViewerBitmap { get; private set; } - [Reactive] public UInt32[] PaletteColors { get; set; } = Array.Empty(); - [Reactive] public UInt32[] RawPalette { get; set; } = Array.Empty(); - [Reactive] public RawPaletteFormat RawFormat { get; set; } - [Reactive] public int PaletteColumnCount { get; private set; } = 16; - [Reactive] public int SelectedColor { get; set; } = 0; - [Reactive] public List? CustomGrids { get; set; } = null; + [ObservableProperty] public partial UInt32[] PaletteColors { get; set; } = Array.Empty(); + [ObservableProperty] public partial UInt32[] RawPalette { get; set; } = Array.Empty(); + [ObservableProperty] public partial RawPaletteFormat RawFormat { get; set; } + [ObservableProperty] public partial int PaletteColumnCount { get; private set; } = 16; + [ObservableProperty] public partial int SelectedColor { get; set; } = 0; + [ObservableProperty] public partial List? CustomGrids { get; set; } = null; public TileEditorConfig Config { get; } @@ -66,9 +63,9 @@ public TileEditorViewModel(List tileAddresses, int columnCount, return; } - AddDisposable(this.WhenAnyValue(x => x.Config.Background).Subscribe(x => RefreshViewer())); - AddDisposable(this.WhenAnyValue(x => x.SelectedColor).Subscribe(x => RefreshViewer())); - AddDisposable(this.WhenAnyValue(x => x.Config.ShowGrid).Subscribe(x => { + AddDisposable(Config.ObserveProp(nameof(Config.Background), RefreshViewer)); + AddDisposable(this.ObserveProp(nameof(SelectedColor), RefreshViewer)); + AddDisposable(Config.ObserveProp(nameof(Config.ShowGrid), () => { if(Config.ShowGrid) { PixelSize tileSize = _tileFormat.GetTileSize(); CustomGrids = new List() { new GridDefinition() { @@ -80,7 +77,7 @@ public TileEditorViewModel(List tileAddresses, int columnCount, CustomGrids = null; } })); - AddDisposable(this.WhenAnyValue(x => x.Config.ImageScale).Subscribe(x => { + AddDisposable(Config.ObserveProp(nameof(Config.ImageScale), () => { if(Config.ImageScale < 4) { Config.ImageScale = 4; } diff --git a/UI/Debugger/ViewModels/TileViewerViewModel.cs b/UI/Debugger/ViewModels/TileViewerViewModel.cs index 56efbb6f5..c3a1f49d1 100644 --- a/UI/Debugger/ViewModels/TileViewerViewModel.cs +++ b/UI/Debugger/ViewModels/TileViewerViewModel.cs @@ -3,6 +3,8 @@ using Avalonia.Media; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Utilities; @@ -10,56 +12,52 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reactive; -using System.Reactive.Linq; namespace Mesen.Debugger.ViewModels { - public class TileViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel + public partial class TileViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel { public CpuType CpuType { get; set; } public TileViewerConfig Config { get; } - [Reactive] public RefreshTimingViewModel RefreshTiming { get; private set; } + [ObservableProperty] public partial RefreshTimingViewModel RefreshTiming { get; private set; } - [Reactive] public DynamicBitmap ViewerBitmap { get; private set; } + [ObservableProperty] public partial DynamicBitmap ViewerBitmap { get; private set; } - [Reactive] public DynamicTooltip? PreviewPanel { get; private set; } + [ObservableProperty] public partial DynamicTooltip? PreviewPanel { get; private set; } - [Reactive] public DynamicTooltip? ViewerTooltip { get; set; } - [Reactive] public PixelPoint? ViewerMousePos { get; set; } + [ObservableProperty] public partial DynamicTooltip? ViewerTooltip { get; set; } + [ObservableProperty] public partial PixelPoint? ViewerMousePos { get; set; } - [Reactive] public UInt32[] PaletteColors { get; set; } = Array.Empty(); - [Reactive] public UInt32[] RawPalette { get; set; } = Array.Empty(); - [Reactive] public RawPaletteFormat RawFormat { get; set; } - [Reactive] public PaletteSelectionMode PaletteSelectionMode { get; private set; } - [Reactive] public int PaletteColumnCount { get; private set; } = 16; - [Reactive] public int SelectedPalette { get; set; } = 0; + [ObservableProperty] public partial UInt32[] PaletteColors { get; set; } = Array.Empty(); + [ObservableProperty] public partial UInt32[] RawPalette { get; set; } = Array.Empty(); + [ObservableProperty] public partial RawPaletteFormat RawFormat { get; set; } + [ObservableProperty] public partial PaletteSelectionMode PaletteSelectionMode { get; private set; } + [ObservableProperty] public partial int PaletteColumnCount { get; private set; } = 16; + [ObservableProperty] public partial int SelectedPalette { get; set; } = 0; - [Reactive] public int AddressIncrement { get; private set; } - [Reactive] public int MaximumAddress { get; private set; } = int.MaxValue; + [ObservableProperty] public partial int AddressIncrement { get; private set; } + [ObservableProperty] public partial int MaximumAddress { get; private set; } = int.MaxValue; - [Reactive] public int GridSizeX { get; set; } = 8; - [Reactive] public int GridSizeY { get; set; } = 8; + [ObservableProperty] public partial int GridSizeX { get; set; } = 8; + [ObservableProperty] public partial int GridSizeY { get; set; } = 8; - [Reactive] public Rect SelectionRect { get; set; } + [ObservableProperty] public partial Rect SelectionRect { get; set; } - [Reactive] public List? PageDelimiters { get; set; } + [ObservableProperty] public partial List? PageDelimiters { get; set; } - [Reactive] public Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); - [Reactive] public Enum[] AvailableFormats { get; set; } = Array.Empty(); - [Reactive] public bool ShowFormatDropdown { get; set; } - [Reactive] public bool ShowFilterDropdown { get; set; } + [ObservableProperty] public partial Enum[] AvailableMemoryTypes { get; set; } = Array.Empty(); + [ObservableProperty] public partial Enum[] AvailableFormats { get; set; } = Array.Empty(); + [ObservableProperty] public partial bool ShowFormatDropdown { get; set; } + [ObservableProperty] public partial bool ShowFilterDropdown { get; set; } - [Reactive] public List> ConfigPresetRows { get; set; } = new() { new(), new(), new() }; - [Reactive] public List ConfigPresets { get; set; } = new List(); + [ObservableProperty] public partial List> ConfigPresetRows { get; set; } = new() { new(), new(), new() }; + [ObservableProperty] public partial List ConfigPresets { get; set; } = new List(); public List FileMenuActions { get; } = new(); public List ViewMenuActions { get; } = new(); @@ -189,40 +187,23 @@ public TileViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPictu InitForCpuType(); - AddDisposable(this.WhenAnyValue(x => x.Config.Format, x => x.RawPalette).Subscribe(x => { - PaletteSelectionMode selMode = PaletteSelectionMode; - selMode = x.Item1.GetBitsPerPixel() switch { - 1 => PaletteSelectionMode.TwoColors, - 2 => PaletteSelectionMode.FourColors, - 4 => PaletteSelectionMode.SixteenColors, - 8 => RawPalette.Length >= 512 ? PaletteSelectionMode._256Colors : PaletteSelectionMode.None, - _ => PaletteSelectionMode.None - }; - - if(selMode != PaletteSelectionMode) { - PaletteSelectionMode = selMode; - - PixelSize tileSize = x.Item1.GetTileSize(); - if(GridSizeX != tileSize.Width || GridSizeY != tileSize.Height) { - GridSizeX = tileSize.Width; - GridSizeY = tileSize.Height; - SelectionRect = default; - PreviewPanel = null; - } + AddDisposable(Config.ObserveProp(nameof(Config.Format), () => { + UpdatePaletteSelectionMode(); + })); - RefreshPalette(); - } + AddDisposable(this.ObserveProp(nameof(RawPalette), () => { + UpdatePaletteSelectionMode(); })); - AddDisposable(this.WhenAnyValue(x => x.Config.Layout).Subscribe(x => { + AddDisposable(Config.ObserveProp(nameof(Config.Layout), () => { ApplyColumnRowCountRestrictions(); })); - AddDisposable(this.WhenAnyValue(x => x.Config.StartAddress).Subscribe(x => { + AddDisposable(Config.ObserveProp(nameof(Config.StartAddress), () => { RefreshData(); })); - AddDisposable(this.WhenAnyValue(x => x.Config.ColumnCount, x => x.Config.RowCount, x => x.Config.Format).Subscribe(x => { + AddDisposable(Config.ObserveProp([nameof(Config.ColumnCount), nameof(Config.RowCount), nameof(Config.Format)], () => { //Enforce min/max values for column/row counts Config.ColumnCount = ColumnCount; Config.RowCount = RowCount; @@ -233,28 +214,57 @@ public TileViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPictu RefreshData(); })); - AddDisposable(this.WhenAnyValue(x => x.Config.Source).Subscribe(memType => { - MaximumAddress = Math.Max(0, DebugApi.GetMemorySize(memType) - 1); + + AddDisposable(Config.ObserveProp(nameof(Config.Source), () => { + MaximumAddress = Math.Max(0, DebugApi.GetMemorySize(Config.Source) - 1); if(Config.StartAddress > MaximumAddress) { Config.StartAddress = 0; } - ShowFilterDropdown = memType.SupportsCdl(); + ShowFilterDropdown = Config.Source.SupportsCdl(); RefreshData(); })); - AddDisposable(this.WhenAnyValue(x => x.SelectedPalette).Subscribe(x => RefreshTab())); - AddDisposable(this.WhenAnyValue(x => x.SelectionRect).Subscribe(x => UpdatePreviewPanel())); + AddDisposable(this.ObserveProp(nameof(SelectedPalette), () => RefreshTab())); + AddDisposable(this.ObserveProp(nameof(SelectionRect), () => UpdatePreviewPanel())); LoadSelectedPreset(false); - AddDisposable(this.WhenAnyValue( - x => x.Config.Source, x => x.Config.StartAddress, x => x.Config.ColumnCount, - x => x.Config.RowCount, x => x.Config.Format - ).Skip(1).Subscribe(x => ClearPresetSelection())); + Config.ObserveProp([ + nameof(Config.Source), + nameof(Config.StartAddress), + nameof(Config.ColumnCount), + nameof(Config.RowCount), + nameof(Config.Format) + ], () => ClearPresetSelection()); AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, Config_PropertyChanged)); } + private void UpdatePaletteSelectionMode() + { + PaletteSelectionMode selMode = Config.Format.GetBitsPerPixel() switch { + 1 => PaletteSelectionMode.TwoColors, + 2 => PaletteSelectionMode.FourColors, + 4 => PaletteSelectionMode.SixteenColors, + 8 => RawPalette.Length >= 512 ? PaletteSelectionMode._256Colors : PaletteSelectionMode.None, + _ => PaletteSelectionMode.None + }; + + if(selMode != PaletteSelectionMode) { + PaletteSelectionMode = selMode; + + PixelSize tileSize = Config.Format.GetTileSize(); + if(GridSizeX != tileSize.Width || GridSizeY != tileSize.Height) { + GridSizeX = tileSize.Width; + GridSizeY = tileSize.Height; + SelectionRect = default; + PreviewPanel = null; + } + + RefreshPalette(); + } + } + private void ApplyColumnRowCountRestrictions() { if(Config.Layout != TileLayout.Normal || Config.Format == TileFormat.PceSpriteBpp4) { @@ -1158,21 +1168,21 @@ private List GetConfigPresets() } } - public class ConfigPreset : ViewModelBase + public partial class ConfigPreset : ViewModelBase { public string Name { get; } public Func GetPresetValues { get; } - public ReactiveCommand ClickCommand { get; } + public IRelayCommand ClickCommand { get; } public Action ApplyPreset { get; } - [Reactive] public bool Selected { get; set; } + [ObservableProperty] public partial bool Selected { get; set; } public ConfigPreset(string name, Func getPresetValues, Action applyPreset) { Name = name; GetPresetValues = getPresetValues; ApplyPreset = applyPreset; - ClickCommand = ReactiveCommand.Create(ApplyPreset); + ClickCommand = new RelayCommand(ApplyPreset); } } diff --git a/UI/Debugger/ViewModels/TilemapViewerViewModel.cs b/UI/Debugger/ViewModels/TilemapViewerViewModel.cs index f68a7a2dd..b0ae82349 100644 --- a/UI/Debugger/ViewModels/TilemapViewerViewModel.cs +++ b/UI/Debugger/ViewModels/TilemapViewerViewModel.cs @@ -4,6 +4,7 @@ using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Utilities; @@ -11,8 +12,6 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -20,37 +19,37 @@ namespace Mesen.Debugger.ViewModels { - public class TilemapViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel + public partial class TilemapViewerViewModel : DisposableViewModel, ICpuTypeModel, IMouseOverViewerModel { - [Reactive] public CpuType CpuType { get; set; } - [Reactive] public bool IsNes { get; private set; } + [ObservableProperty] public partial CpuType CpuType { get; set; } + [ObservableProperty] public partial bool IsNes { get; private set; } public TilemapViewerConfig Config { get; } - [Reactive] public RefreshTimingViewModel RefreshTiming { get; private set; } + [ObservableProperty] public partial RefreshTimingViewModel RefreshTiming { get; private set; } - [Reactive] public Rect SelectionRect { get; set; } - [Reactive] public int GridSizeX { get; set; } = 8; - [Reactive] public int GridSizeY { get; set; } = 8; + [ObservableProperty] public partial Rect SelectionRect { get; set; } + [ObservableProperty] public partial int GridSizeX { get; set; } = 8; + [ObservableProperty] public partial int GridSizeY { get; set; } = 8; - [Reactive] public List? CustomGrids { get; set; } = null; + [ObservableProperty] public partial List? CustomGrids { get; set; } = null; - [Reactive] public DynamicBitmap ViewerBitmap { get; private set; } + [ObservableProperty] public partial DynamicBitmap ViewerBitmap { get; private set; } - [Reactive] public DynamicTooltip TilemapInfoPanel { get; private set; } = new DynamicTooltip(); - [Reactive] public bool IsTilemapInfoVisible { get; private set; } + [ObservableProperty] public partial DynamicTooltip TilemapInfoPanel { get; private set; } = new DynamicTooltip(); + [ObservableProperty] public partial bool IsTilemapInfoVisible { get; private set; } - [Reactive] public DynamicTooltip? PreviewPanel { get; private set; } - [Reactive] public DynamicTooltip? ViewerTooltip { get; set; } - [Reactive] public PixelPoint? ViewerMousePos { get; set; } + [ObservableProperty] public partial DynamicTooltip? PreviewPanel { get; private set; } + [ObservableProperty] public partial DynamicTooltip? ViewerTooltip { get; set; } + [ObservableProperty] public partial PixelPoint? ViewerMousePos { get; set; } - [Reactive] public List Tabs { get; private set; } = new List(); - [Reactive] public bool ShowTabs { get; private set; } - [Reactive] public TilemapViewerTab SelectedTab { get; set; } + [ObservableProperty] public partial List Tabs { get; private set; } = new List(); + [ObservableProperty] public partial bool ShowTabs { get; private set; } + [ObservableProperty] public partial TilemapViewerTab SelectedTab { get; set; } - [Reactive] public Rect ScrollOverlayRect { get; private set; } - [Reactive] public List? OverlayLines { get; private set; } = null; + [ObservableProperty] public partial Rect ScrollOverlayRect { get; private set; } + [ObservableProperty] public partial List? OverlayLines { get; private set; } = null; - [Reactive] public Enum[] AvailableDisplayModes { get; set; } = Array.Empty(); + [ObservableProperty] public partial Enum[] AvailableDisplayModes { get; set; } = Array.Empty(); public List FileMenuActions { get; } = new(); public List ViewMenuActions { get; } = new(); @@ -218,8 +217,10 @@ public TilemapViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPi } })); - AddDisposable(this.WhenAnyValue(x => x.Tabs).Subscribe(x => ShowTabs = x.Count > 1)); - AddDisposable(this.WhenAnyValue(x => x.SelectedTab).Subscribe(x => { + + AddDisposable(this.ObserveProp(nameof(Tabs), () => ShowTabs = Tabs.Count > 1)); + AddDisposable(this.ObserveProp(nameof(SelectionRect), () => UpdatePreviewPanel())); + AddDisposable(this.ObserveProp(nameof(SelectedTab), () => { if(_inGameLoaded) { //Skip refresh data/tab if this is triggered while processing a gameloaded event //Otherwise RefreshTab will be called on the old game's data, causing a crash. @@ -232,7 +233,7 @@ public TilemapViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPi RefreshTab(); } })); - AddDisposable(this.WhenAnyValue(x => x.SelectionRect).Subscribe(x => UpdatePreviewPanel())); + AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, Config_PropertyChanged)); InitNesGridOptions(); @@ -243,23 +244,28 @@ public TilemapViewerViewModel(CpuType cpuType, PictureViewer picViewer, ScrollPi private void InitNesGridOptions() { - AddDisposable(this.WhenAnyValue(x => x.Config.NesShowAttributeGrid, x => x.Config.NesShowAttributeByteGrid, x => x.Config.NesShowTilemapGrid, x => x.CpuType).Subscribe(x => { - if(CpuType == CpuType.Nes) { - List grids = new(); - if(Config.NesShowAttributeGrid) { - grids.Add(new() { SizeX = 16, SizeY = 16, Color = Colors.Red }); - } - if(Config.NesShowAttributeByteGrid) { - grids.Add(new() { SizeX = 32, SizeY = 32, Color = Colors.LightGreen, RestartY = 240 }); - } - if(Config.NesShowTilemapGrid) { - grids.Add(new() { SizeX = 256, SizeY = 240, Color = Colors.LightGray }); - } - CustomGrids = grids; - } else { - CustomGrids = null; + AddDisposable(Config.ObserveProp([nameof(Config.NesShowAttributeGrid), nameof(Config.NesShowAttributeByteGrid), nameof(Config.NesShowTilemapGrid)], UpdateCustomGrid)); + AddDisposable(this.ObserveProp(nameof(CpuType), UpdateCustomGrid)); + } + + private void UpdateCustomGrid() + { + if(CpuType == CpuType.Nes) { + List grids = new(); + if(Config.NesShowAttributeGrid) { + grids.Add(new() { SizeX = 16, SizeY = 16, Color = Colors.Red }); } - })); + if(Config.NesShowAttributeByteGrid) { + grids.Add(new() { SizeX = 32, SizeY = 32, Color = Colors.LightGreen, RestartY = 240 }); + } + if(Config.NesShowTilemapGrid) { + grids.Add(new() { SizeX = 256, SizeY = 240, Color = Colors.LightGray }); + } + CustomGrids = grids; + } else { + CustomGrids = null; + } + } private async void EditBreakpoint(Window wnd, int address) @@ -839,12 +845,12 @@ public void OnGameLoaded() } } - public class TilemapViewerTab : ViewModelBase + public partial class TilemapViewerTab : ViewModelBase { - [Reactive] public string Title { get; set; } = ""; - [Reactive] public int Layer { get; set; } = 0; - [Reactive] public MemoryType? VramMemoryType { get; set; } - [Reactive] public bool Enabled { get; set; } = true; + [ObservableProperty] public partial string Title { get; set; } = ""; + [ObservableProperty] public partial int Layer { get; set; } = 0; + [ObservableProperty] public partial MemoryType? VramMemoryType { get; set; } + [ObservableProperty] public partial bool Enabled { get; set; } = true; } public class TilemapViewerData diff --git a/UI/Debugger/ViewModels/TraceLoggerViewModel.cs b/UI/Debugger/ViewModels/TraceLoggerViewModel.cs index 367a9fcdb..5c34fb01d 100644 --- a/UI/Debugger/ViewModels/TraceLoggerViewModel.cs +++ b/UI/Debugger/ViewModels/TraceLoggerViewModel.cs @@ -1,7 +1,9 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Input.Platform; using Avalonia.Media; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Disassembly; @@ -11,8 +13,6 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -22,37 +22,37 @@ namespace Mesen.Debugger.ViewModels { - public class TraceLoggerViewModel : DisposableViewModel, ISelectableModel + public partial class TraceLoggerViewModel : DisposableViewModel, ISelectableModel { public TraceLoggerConfig Config { get; } - [Reactive] public TraceLoggerStyleProvider StyleProvider { get; set; } - [Reactive] public CodeLineData[] TraceLogLines { get; set; } = Array.Empty(); - [Reactive] public int VisibleRowCount { get; set; } = 100; - [Reactive] public int ScrollPosition { get; set; } = 0; - [Reactive] public int MinScrollPosition { get; set; } = 0; - [Reactive] public int MaxScrollPosition { get; set; } = DebugApi.TraceLogBufferSize; - [Reactive] public bool IsLoggingToFile { get; set; } = false; + [ObservableProperty] public partial TraceLoggerStyleProvider StyleProvider { get; set; } + [ObservableProperty] public partial CodeLineData[] TraceLogLines { get; set; } = Array.Empty(); + [ObservableProperty] public partial int VisibleRowCount { get; set; } = 100; + [ObservableProperty] public partial int ScrollPosition { get; set; } = 0; + [ObservableProperty] public partial int MinScrollPosition { get; set; } = 0; + [ObservableProperty] public partial int MaxScrollPosition { get; set; } = DebugApi.TraceLogBufferSize; + [ObservableProperty] public partial bool IsLoggingToFile { get; set; } = false; - [Reactive] public List Tabs { get; set; } = new(); - [Reactive] public TraceLoggerOptionTab SelectedTab { get; set; } = null!; + [ObservableProperty] public partial List Tabs { get; set; } = new(); + [ObservableProperty] public partial TraceLoggerOptionTab SelectedTab { get; set; } = null!; - [Reactive] public string? TraceFile { get; set; } = null; - [Reactive] public bool AllowOpenTraceFile { get; private set; } = false; - [Reactive] public bool IsStartLoggingEnabled { get; set; } + [ObservableProperty] public partial string? TraceFile { get; set; } = null; + [ObservableProperty] public partial bool AllowOpenTraceFile { get; private set; } = false; + [ObservableProperty] public partial bool IsStartLoggingEnabled { get; set; } - [Reactive] public bool ShowByteCode { get; private set; } + [ObservableProperty] public partial bool ShowByteCode { get; private set; } - [Reactive] public int SelectionStart { get; private set; } - [Reactive] public int SelectionEnd { get; private set; } - [Reactive] public int SelectionAnchor { get; private set; } - [Reactive] public int SelectedRow { get; private set; } + [ObservableProperty] public partial int SelectionStart { get; private set; } + [ObservableProperty] public partial int SelectionEnd { get; private set; } + [ObservableProperty] public partial int SelectionAnchor { get; private set; } + [ObservableProperty] public partial int SelectedRow { get; private set; } - [Reactive] public List ToolbarItems { get; private set; } = new(); + [ObservableProperty] public partial List ToolbarItems { get; private set; } = new(); - [Reactive] public List FileMenuItems { get; private set; } = new(); - [Reactive] public List DebugMenuItems { get; private set; } = new(); - [Reactive] public List SearchMenuItems { get; private set; } = new(); - [Reactive] public List ViewMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List FileMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List DebugMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List SearchMenuItems { get; private set; } = new(); + [ObservableProperty] public partial List ViewMenuItems { get; private set; } = new(); public QuickSearchViewModel QuickSearch { get; } = new(); @@ -71,7 +71,7 @@ public TraceLoggerViewModel() QuickSearch.OnFind += QuickSearch_OnFind; - AddDisposable(this.WhenAnyValue(x => x.QuickSearch.IsSearchBoxVisible).Subscribe(x => { + AddDisposable(QuickSearch.ObserveProp(nameof(QuickSearch.IsSearchBoxVisible), () => { if(!QuickSearch.IsSearchBoxVisible) { _viewer?.Focus(); } @@ -79,24 +79,15 @@ public TraceLoggerViewModel() UpdateAvailableTabs(); - AddDisposable(this.WhenAnyValue(x => x.ScrollPosition).Subscribe(x => { - ScrollPosition = Math.Max(MinScrollPosition, Math.Min(x, MaxScrollPosition)); - UpdateLog(); - })); - - AddDisposable(this.WhenAnyValue(x => x.MinScrollPosition).Subscribe(x => { - ScrollPosition = Math.Max(MinScrollPosition, Math.Min(x, MaxScrollPosition)); - })); - - AddDisposable(this.WhenAnyValue(x => x.MaxScrollPosition).Subscribe(x => { - ScrollPosition = Math.Max(MinScrollPosition, Math.Min(x, MaxScrollPosition)); - })); + AddDisposable(this.ObserveProp(nameof(ScrollPosition), UpdateScrollPosition)); + AddDisposable(this.ObserveProp(nameof(MinScrollPosition), UpdateScrollPosition)); + AddDisposable(this.ObserveProp(nameof(MaxScrollPosition), UpdateScrollPosition)); - AddDisposable(this.WhenAnyValue(x => x.IsLoggingToFile).Subscribe(x => { + AddDisposable(this.ObserveProp(nameof(IsLoggingToFile), () => { AllowOpenTraceFile = !IsLoggingToFile && TraceFile != null; })); - AddDisposable(this.WhenAnyValue(x => x.SelectionStart, x => x.SelectionEnd, x => x.SelectedRow, x => x.SelectionAnchor).Subscribe(x => { + AddDisposable(this.ObserveProp([nameof(SelectionStart), nameof(SelectionEnd), nameof(SelectedRow), nameof(SelectionAnchor)], () => { SelectionStart = Math.Max(MinScrollPosition, Math.Min(DebugApi.TraceLogBufferSize - 1, SelectionStart)); SelectionEnd = Math.Max(MinScrollPosition, Math.Min(DebugApi.TraceLogBufferSize - 1, SelectionEnd)); SelectedRow = Math.Max(MinScrollPosition, Math.Min(DebugApi.TraceLogBufferSize - 1, SelectedRow)); @@ -104,6 +95,11 @@ public TraceLoggerViewModel() })); } + private void UpdateScrollPosition() + { + ScrollPosition = Math.Max(MinScrollPosition, Math.Min(ScrollPosition, MaxScrollPosition)); + } + public void SetViewer(DisassemblyViewer viewer) { _viewer = viewer; @@ -445,7 +441,7 @@ private CodeLineData[] GetCodeLines(int startIndex, int rowCount) } } - public class TraceLoggerOptionTab : DisposableViewModel + public partial class TraceLoggerOptionTab : DisposableViewModel { public string TabName { get; set; } = ""; public Control HelpTooltip => ExpressionTooltipHelper.GetHelpTooltip(CpuType, false); @@ -459,8 +455,8 @@ public class TraceLoggerOptionTab : DisposableViewModel public bool ShowIndentCode { get; } public TraceLoggerCpuConfig Options { get; } - [Reactive] public string Format { get; set; } = ""; - [Reactive] public bool IsConditionValid { get; set; } = true; + [ObservableProperty] public partial string Format { get; set; } = ""; + [ObservableProperty] public partial bool IsConditionValid { get; set; } = true; private TraceLoggerViewModel _traceLogger; diff --git a/UI/Debugger/ViewModels/WatchListViewModel.cs b/UI/Debugger/ViewModels/WatchListViewModel.cs index be527c749..ed73b51b3 100644 --- a/UI/Debugger/ViewModels/WatchListViewModel.cs +++ b/UI/Debugger/ViewModels/WatchListViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Controls.Selection; using Avalonia.Interactivity; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Disassembly; using Mesen.Debugger.Labels; @@ -10,22 +11,20 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Reactive.Linq; using System.Text.RegularExpressions; namespace Mesen.Debugger.ViewModels { - public class WatchListViewModel : DisposableViewModel, IToolHelpTooltip + public partial class WatchListViewModel : DisposableViewModel, IToolHelpTooltip { private static Regex _watchAddressOrLabel = new Regex(@"^(\[|{)(\s*((\$[0-9A-Fa-f]+)|(\d+)|([@_a-zA-Z0-9]+)))\s*[,]{0,1}\d*\s*(\]|})$", RegexOptions.Compiled); - [Reactive] public MesenList WatchEntries { get; private set; } = new(); - [Reactive] public SelectionModel Selection { get; set; } = new() { SingleSelect = false }; + [ObservableProperty] public partial MesenList WatchEntries { get; private set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new() { SingleSelect = false }; public List ColumnWidths { get; } = ConfigManager.Config.Debug.Debugger.WatchListColumnWidths; public WatchManager Manager { get; } diff --git a/UI/Debugger/ViewModels/WatchWindowViewModel.cs b/UI/Debugger/ViewModels/WatchWindowViewModel.cs index 4dba8f8cc..a28e2bee5 100644 --- a/UI/Debugger/ViewModels/WatchWindowViewModel.cs +++ b/UI/Debugger/ViewModels/WatchWindowViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Controls.Selection; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Mesen.Config; using Mesen.Debugger.Labels; @@ -9,8 +10,6 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -18,10 +17,10 @@ namespace Mesen.Debugger.ViewModels { - public class WatchWindowViewModel : ViewModelBase + public partial class WatchWindowViewModel : ViewModelBase { - [Reactive] public List WatchTabs { get; set; } = new List(); - [Reactive] public WatchTab SelectedTab { get; set; } = null!; + [ObservableProperty] public partial List WatchTabs { get; set; } = new List(); + [ObservableProperty] public partial WatchTab SelectedTab { get; set; } = null!; public WatchWindowConfig Config { get; } @@ -64,7 +63,7 @@ public void RefreshData() } } - public class WatchTab : DisposableViewModel + public partial class WatchTab : DisposableViewModel { public string TabName { get; } public CpuType CpuType { get; } diff --git a/UI/Debugger/Views/DisassemblyView.axaml.cs b/UI/Debugger/Views/DisassemblyView.axaml.cs index 28fa9c585..a33926436 100644 --- a/UI/Debugger/Views/DisassemblyView.axaml.cs +++ b/UI/Debugger/Views/DisassemblyView.axaml.cs @@ -37,7 +37,8 @@ public DisassemblyView() InitializeComponent(); _viewer = this.GetControl("disViewer"); - _viewer.GetPropertyChangedObservable(DisassemblyViewer.VisibleRowCountProperty).Subscribe(x => { + + AddDisposable(_viewer.ObserveProp(DisassemblyViewer.VisibleRowCountProperty, x => { int rowCount = _viewer.VisibleRowCount; int prevCount = Model.VisibleRowCount; if(prevCount != rowCount) { @@ -46,7 +47,7 @@ public DisassemblyView() Model.Refresh(); } } - }); + })); InitContextMenu(); } diff --git a/UI/Debugger/Views/SourceViewView.axaml.cs b/UI/Debugger/Views/SourceViewView.axaml.cs index 0265a2427..d03acdc2a 100644 --- a/UI/Debugger/Views/SourceViewView.axaml.cs +++ b/UI/Debugger/Views/SourceViewView.axaml.cs @@ -39,7 +39,8 @@ public SourceViewView() { InitializeComponent(); _viewer = this.GetControl("disViewer"); - _viewer.GetPropertyChangedObservable(DisassemblyViewer.VisibleRowCountProperty).Subscribe(x => { + + AddDisposable(_viewer.ObserveProp(DisassemblyViewer.VisibleRowCountProperty, x => { SourceViewViewModel? model = Model; if(model == null) { return; @@ -53,7 +54,7 @@ public SourceViewView() model.ScrollToRowNumber(pos); model.Refresh(); } - }); + })); InitContextMenu(); } diff --git a/UI/Debugger/Views/WatchListView.axaml b/UI/Debugger/Views/WatchListView.axaml index b667beaa7..3fbc35703 100644 --- a/UI/Debugger/Views/WatchListView.axaml +++ b/UI/Debugger/Views/WatchListView.axaml @@ -71,7 +71,7 @@ Text="{Binding Expression, DataType={x:Type md:WatchValueInfo}}" LostFocus="OnEntryLostFocus" KeyDown="OnEntryKeyDown" - Watermark="Click to add..." + PlaceholderText="Click to add..." /> diff --git a/UI/Debugger/Views/WatchListView.axaml.cs b/UI/Debugger/Views/WatchListView.axaml.cs index 09df5a2f9..103ffcecd 100644 --- a/UI/Debugger/Views/WatchListView.axaml.cs +++ b/UI/Debugger/Views/WatchListView.axaml.cs @@ -147,7 +147,7 @@ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) _listView = this.FindLogicalAncestorOfType(); } - protected override void OnGotFocus(GotFocusEventArgs e) + protected override void OnGotFocus(FocusChangedEventArgs e) { base.OnGotFocus(e); diff --git a/UI/Debugger/WatchManager.cs b/UI/Debugger/WatchManager.cs index 172afdf59..354d69cdd 100644 --- a/UI/Debugger/WatchManager.cs +++ b/UI/Debugger/WatchManager.cs @@ -1,10 +1,9 @@ using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Debugger.Labels; using Mesen.Debugger.Utilities; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; @@ -307,11 +306,11 @@ private void SetSelectionFormat(string formatString, int[] indexes) } } - public class WatchValueInfo : ReactiveObject + public partial class WatchValueInfo : ObservableObject { - [Reactive] public string Value { get; set; } = ""; - [Reactive] public string Expression { get; set; } = ""; - [Reactive] public bool IsChanged { get; set; } = false; + [ObservableProperty] public partial string Value { get; set; } = ""; + [ObservableProperty] public partial string Expression { get; set; } = ""; + [ObservableProperty] public partial bool IsChanged { get; set; } = false; public Int64 NumericValue { get; set; } = -1; } diff --git a/UI/Debugger/Windows/AssemblerWindow.axaml.cs b/UI/Debugger/Windows/AssemblerWindow.axaml.cs index fe9e67445..13c40c461 100644 --- a/UI/Debugger/Windows/AssemblerWindow.axaml.cs +++ b/UI/Debugger/Windows/AssemblerWindow.axaml.cs @@ -41,9 +41,6 @@ public AssemblerWindow() : this(new()) { } public AssemblerWindow(AssemblerWindowViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif UpdateSyntaxDef(); _highlighting = HighlightingLoader.Load(_syntaxDef, HighlightingManager.Instance); @@ -77,8 +74,7 @@ private void UpdateSyntaxDef() public static void EditCode(CpuType cpuType, int address, string code, int byteCount) { - AssemblerWindowViewModel model = new AssemblerWindowViewModel(cpuType); - model.InitEditCode(address, code, byteCount); + AssemblerWindowViewModel model = new AssemblerWindowViewModel(cpuType, address, code, byteCount); DebugWindowManager.OpenDebugWindow(() => new AssemblerWindow(model)); } diff --git a/UI/Debugger/Windows/BreakInWindow.axaml.cs b/UI/Debugger/Windows/BreakInWindow.axaml.cs index 8bd0d4b74..9fbf25418 100644 --- a/UI/Debugger/Windows/BreakInWindow.axaml.cs +++ b/UI/Debugger/Windows/BreakInWindow.axaml.cs @@ -5,7 +5,7 @@ using Mesen.Controls; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.Windows @@ -51,9 +51,6 @@ public BreakInWindow(CpuType cpuType) } InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/BreakOnWindow.axaml.cs b/UI/Debugger/Windows/BreakOnWindow.axaml.cs index 0403c6619..ecee3a1ac 100644 --- a/UI/Debugger/Windows/BreakOnWindow.axaml.cs +++ b/UI/Debugger/Windows/BreakOnWindow.axaml.cs @@ -5,7 +5,7 @@ using Mesen.Controls; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.Windows @@ -53,9 +53,6 @@ public BreakOnWindow(CpuType cpuType) } InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/BreakpointEditWindow.axaml.cs b/UI/Debugger/Windows/BreakpointEditWindow.axaml.cs index d7c071747..1d6c67fa4 100644 --- a/UI/Debugger/Windows/BreakpointEditWindow.axaml.cs +++ b/UI/Debugger/Windows/BreakpointEditWindow.axaml.cs @@ -20,9 +20,6 @@ public BreakpointEditWindow(BreakpointEditViewModel model) { DataContext = model; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/ColorIndexPickerWindow.axaml.cs b/UI/Debugger/Windows/ColorIndexPickerWindow.axaml.cs index 9ba4206a5..6c57c855b 100644 --- a/UI/Debugger/Windows/ColorIndexPickerWindow.axaml.cs +++ b/UI/Debugger/Windows/ColorIndexPickerWindow.axaml.cs @@ -7,7 +7,7 @@ using Mesen.Debugger.Controls; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.Windows @@ -61,9 +61,6 @@ public ColorIndexPickerWindow(CpuType cpuType, int selectedPalette) } InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private static UInt32[] GenerateWsPalette() diff --git a/UI/Debugger/Windows/CommentEditWindow.axaml.cs b/UI/Debugger/Windows/CommentEditWindow.axaml.cs index b266baa3a..ab08cee30 100644 --- a/UI/Debugger/Windows/CommentEditWindow.axaml.cs +++ b/UI/Debugger/Windows/CommentEditWindow.axaml.cs @@ -27,9 +27,6 @@ public CommentEditWindow(CommentEditViewModel model) AddHandler(CommentEditWindow.KeyDownEvent, this.KeyDownHandler, RoutingStrategies.Tunnel); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/DebuggerConfigWindow.axaml.cs b/UI/Debugger/Windows/DebuggerConfigWindow.axaml.cs index 5594cac00..eca88fd5a 100644 --- a/UI/Debugger/Windows/DebuggerConfigWindow.axaml.cs +++ b/UI/Debugger/Windows/DebuggerConfigWindow.axaml.cs @@ -28,17 +28,14 @@ public DebuggerConfigWindow() : this(new()) public DebuggerConfigWindow(DebuggerConfigWindowViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = model; DataContext = model; } - public static void Open(DebugConfigWindowTab tab, IRenderRoot? parent) + public static void Open(DebugConfigWindowTab tab, Window? parent) { - new DebuggerConfigWindow(new DebuggerConfigWindowViewModel(tab)).ShowCenteredDialog(parent as Visual); + new DebuggerConfigWindow(new DebuggerConfigWindowViewModel(tab)).ShowCenteredDialog(parent); } private void InitializeComponent() diff --git a/UI/Debugger/Windows/DebuggerWindow.axaml.cs b/UI/Debugger/Windows/DebuggerWindow.axaml.cs index 779d13b81..c37bc5d1d 100644 --- a/UI/Debugger/Windows/DebuggerWindow.axaml.cs +++ b/UI/Debugger/Windows/DebuggerWindow.axaml.cs @@ -36,9 +36,6 @@ public DebuggerWindow() : this(null, null) { } public DebuggerWindow(CpuType? cpuType, int? scrollToAddress = null) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = new DebuggerWindowViewModel(cpuType); _scrollToAddress = scrollToAddress; diff --git a/UI/Debugger/Windows/EventViewerWindow.axaml.cs b/UI/Debugger/Windows/EventViewerWindow.axaml.cs index 385a2b014..58953f20a 100644 --- a/UI/Debugger/Windows/EventViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/EventViewerWindow.axaml.cs @@ -5,7 +5,6 @@ using Avalonia.Markup.Xaml; using Avalonia.Threading; using DataBoxControl; -using DynamicData; using Mesen.Config; using Mesen.Debugger.Controls; using Mesen.Debugger.Labels; @@ -31,9 +30,6 @@ public EventViewerWindow() : this(CpuType.Snes) { } public EventViewerWindow(CpuType cpuType) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif PictureViewer viewer = this.GetControl("picViewer").InnerViewer; DataBox listView = this.GetControl("lstEvents"); diff --git a/UI/Debugger/Windows/FindAllOccurrencesWindow.axaml.cs b/UI/Debugger/Windows/FindAllOccurrencesWindow.axaml.cs index b6ac45610..45562ca67 100644 --- a/UI/Debugger/Windows/FindAllOccurrencesWindow.axaml.cs +++ b/UI/Debugger/Windows/FindAllOccurrencesWindow.axaml.cs @@ -4,7 +4,7 @@ using Avalonia.Markup.Xaml; using Mesen.Controls; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.Windows @@ -26,9 +26,6 @@ public FindAllOccurrencesWindow() MatchWholeWord = _lastMatchWholeWord; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/GoToAllWindow.axaml.cs b/UI/Debugger/Windows/GoToAllWindow.axaml.cs index a55a34751..1b4b7635e 100644 --- a/UI/Debugger/Windows/GoToAllWindow.axaml.cs +++ b/UI/Debugger/Windows/GoToAllWindow.axaml.cs @@ -11,7 +11,7 @@ using Mesen.Debugger.ViewModels; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; using System.ComponentModel; @@ -32,9 +32,6 @@ public GoToAllWindow(GoToAllViewModel model) DataContext = model; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/GoToWindow.axaml.cs b/UI/Debugger/Windows/GoToWindow.axaml.cs index 2a6f51387..0e78c151f 100644 --- a/UI/Debugger/Windows/GoToWindow.axaml.cs +++ b/UI/Debugger/Windows/GoToWindow.axaml.cs @@ -9,7 +9,7 @@ using Mesen.Localization; using Mesen.Utilities; using Mesen.Views; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Globalization; @@ -43,9 +43,6 @@ public GoToWindow(CpuType cpuType, MemoryType memType, int maximum) _memType = memType; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/LabelEditWindow.axaml.cs b/UI/Debugger/Windows/LabelEditWindow.axaml.cs index e875cb7d6..7f337bbdf 100644 --- a/UI/Debugger/Windows/LabelEditWindow.axaml.cs +++ b/UI/Debugger/Windows/LabelEditWindow.axaml.cs @@ -25,9 +25,6 @@ public LabelEditWindow(LabelEditViewModel model) DataContext = model; _model = model; -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/MemorySearchWindow.axaml.cs b/UI/Debugger/Windows/MemorySearchWindow.axaml.cs index 1fb52506a..93317e2d3 100644 --- a/UI/Debugger/Windows/MemorySearchWindow.axaml.cs +++ b/UI/Debugger/Windows/MemorySearchWindow.axaml.cs @@ -24,9 +24,6 @@ public MemorySearchWindow() DataContext = _model; InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif if(Design.IsDesignMode) { return; diff --git a/UI/Debugger/Windows/MemoryToolsWindow.axaml.cs b/UI/Debugger/Windows/MemoryToolsWindow.axaml.cs index d3dbe4df8..6dc5a9624 100644 --- a/UI/Debugger/Windows/MemoryToolsWindow.axaml.cs +++ b/UI/Debugger/Windows/MemoryToolsWindow.axaml.cs @@ -33,9 +33,6 @@ public class MemoryToolsWindow : MesenWindow, INotificationHandler public MemoryToolsWindow() { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _editor = this.GetControl("Hex"); _model = new MemoryToolsViewModel(_editor); @@ -79,7 +76,7 @@ protected override void OnOpened(EventArgs e) _editor.Focus(); } - protected override void OnGotFocus(GotFocusEventArgs e) + protected override void OnGotFocus(FocusChangedEventArgs e) { base.OnGotFocus(e); if(FocusManager?.GetFocusedElement() == this) { diff --git a/UI/Debugger/Windows/MemoryViewerFindWindow.axaml.cs b/UI/Debugger/Windows/MemoryViewerFindWindow.axaml.cs index c95e0118d..4799cc20b 100644 --- a/UI/Debugger/Windows/MemoryViewerFindWindow.axaml.cs +++ b/UI/Debugger/Windows/MemoryViewerFindWindow.axaml.cs @@ -9,7 +9,7 @@ using Mesen.Debugger.ViewModels; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections.Generic; @@ -34,9 +34,6 @@ public MemoryViewerFindWindow(MemoryViewerFindViewModel model, MemoryToolsViewMo AddHandler(InputElement.KeyDownEvent, OnPreviewKeyDown, RoutingStrategies.Tunnel, true); InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/NesHeaderEditWindow.axaml.cs b/UI/Debugger/Windows/NesHeaderEditWindow.axaml.cs index e595fb439..c1aafad50 100644 --- a/UI/Debugger/Windows/NesHeaderEditWindow.axaml.cs +++ b/UI/Debugger/Windows/NesHeaderEditWindow.axaml.cs @@ -7,7 +7,7 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.ViewModels; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; using System; namespace Mesen.Debugger.Windows @@ -23,9 +23,6 @@ public NesHeaderEditWindow() InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif } private void InitializeComponent() diff --git a/UI/Debugger/Windows/PaletteViewerWindow.axaml.cs b/UI/Debugger/Windows/PaletteViewerWindow.axaml.cs index 969fe4f17..fba270e5e 100644 --- a/UI/Debugger/Windows/PaletteViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/PaletteViewerWindow.axaml.cs @@ -25,9 +25,6 @@ public PaletteViewerWindow() : this(CpuType.Snes) { } public PaletteViewerWindow(CpuType cpuType) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif PaletteSelector palSelector = this.GetControl("palSelector"); Border border = this.GetControl("selectorBorder"); diff --git a/UI/Debugger/Windows/ProfilerWindow.axaml.cs b/UI/Debugger/Windows/ProfilerWindow.axaml.cs index a4a5dd208..37ef126d2 100644 --- a/UI/Debugger/Windows/ProfilerWindow.axaml.cs +++ b/UI/Debugger/Windows/ProfilerWindow.axaml.cs @@ -21,9 +21,6 @@ public class ProfilerWindow : MesenWindow, INotificationHandler public ProfilerWindow() { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = new ProfilerWindowViewModel(this); DataContext = _model; diff --git a/UI/Debugger/Windows/RegisterViewerWindow.axaml.cs b/UI/Debugger/Windows/RegisterViewerWindow.axaml.cs index 0e41beba8..bc8365aa6 100644 --- a/UI/Debugger/Windows/RegisterViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/RegisterViewerWindow.axaml.cs @@ -21,9 +21,6 @@ public RegisterViewerWindow() : this(new()) { } public RegisterViewerWindow(RegisterViewerWindowViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = model; DataContext = model; diff --git a/UI/Debugger/Windows/ScriptWindow.axaml.cs b/UI/Debugger/Windows/ScriptWindow.axaml.cs index ed56e7c2b..50ab04908 100644 --- a/UI/Debugger/Windows/ScriptWindow.axaml.cs +++ b/UI/Debugger/Windows/ScriptWindow.axaml.cs @@ -52,9 +52,6 @@ public ScriptWindow() : this(new(null)) { } public ScriptWindow(ScriptWindowViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif UpdateSyntaxDef(); _highlighting = HighlightingLoader.Load(_syntaxDef, HighlightingManager.Instance); diff --git a/UI/Debugger/Windows/SpriteViewerWindow.axaml.cs b/UI/Debugger/Windows/SpriteViewerWindow.axaml.cs index e4e6e7843..d71ea6160 100644 --- a/UI/Debugger/Windows/SpriteViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/SpriteViewerWindow.axaml.cs @@ -23,9 +23,6 @@ public SpriteViewerWindow() : this(CpuType.Snes) { } public SpriteViewerWindow(CpuType cpuType) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif ScrollPictureViewer scrollViewer = this.GetControl("picViewer"); PictureViewer picViewer = scrollViewer.InnerViewer; diff --git a/UI/Debugger/Windows/TileEditorWindow.axaml.cs b/UI/Debugger/Windows/TileEditorWindow.axaml.cs index f1041fb75..52d87e425 100644 --- a/UI/Debugger/Windows/TileEditorWindow.axaml.cs +++ b/UI/Debugger/Windows/TileEditorWindow.axaml.cs @@ -30,9 +30,6 @@ public TileEditorWindow() : this(new()) { } public TileEditorWindow(TileEditorViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _picViewer = this.GetControl("picViewer").InnerViewer; _picViewer.PositionClicked += PicViewer_PositionClicked; diff --git a/UI/Debugger/Windows/TileViewerWindow.axaml.cs b/UI/Debugger/Windows/TileViewerWindow.axaml.cs index b64dab868..2cd404218 100644 --- a/UI/Debugger/Windows/TileViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/TileViewerWindow.axaml.cs @@ -22,9 +22,6 @@ public TileViewerWindow() : this(CpuType.Snes) { } public TileViewerWindow(CpuType cpuType) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif ScrollPictureViewer scrollViewer = this.GetControl("picViewer"); PictureViewer picViewer = scrollViewer.InnerViewer; diff --git a/UI/Debugger/Windows/TilemapViewerWindow.axaml.cs b/UI/Debugger/Windows/TilemapViewerWindow.axaml.cs index 337e083d5..0c3e12a61 100644 --- a/UI/Debugger/Windows/TilemapViewerWindow.axaml.cs +++ b/UI/Debugger/Windows/TilemapViewerWindow.axaml.cs @@ -24,9 +24,6 @@ public TilemapViewerWindow() : this(CpuType.Snes) { } public TilemapViewerWindow(CpuType cpuType) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif ScrollPictureViewer scrollViewer = this.GetControl("picViewer"); _picViewer = scrollViewer.InnerViewer; diff --git a/UI/Debugger/Windows/TraceLoggerWindow.axaml.cs b/UI/Debugger/Windows/TraceLoggerWindow.axaml.cs index 792e0d253..adb0f42c4 100644 --- a/UI/Debugger/Windows/TraceLoggerWindow.axaml.cs +++ b/UI/Debugger/Windows/TraceLoggerWindow.axaml.cs @@ -29,9 +29,6 @@ public TraceLoggerWindow() : this(new()) { } public TraceLoggerWindow(TraceLoggerViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = model; _model.InitializeMenu(this); @@ -41,10 +38,10 @@ public TraceLoggerWindow(TraceLoggerViewModel model) InitContextMenu(viewer); _selectionHandler = new CodeViewerSelectionHandler(viewer, _model, (rowIndex, rowAddress) => rowIndex, false); - viewer.GetPropertyChangedObservable(DisassemblyViewer.VisibleRowCountProperty).Subscribe(x => { + _model.AddDisposable(viewer.ObserveProp(DisassemblyViewer.VisibleRowCountProperty, x => { _model.VisibleRowCount = Math.Max(1, viewer.VisibleRowCount - 1); _model.MaxScrollPosition = DebugApi.TraceLogBufferSize - _model.VisibleRowCount; - }); + })); DataContext = model; @@ -193,7 +190,7 @@ public void ProcessNotification(NotificationEventArgs e) private async void OnStartLoggingClick(object sender, RoutedEventArgs e) { - string? filename = await FileDialogHelper.SaveFile(ConfigManager.DebuggerFolder, EmuApi.GetRomInfo().GetRomName() + ".txt", VisualRoot, FileDialogHelper.TraceExt); + string? filename = await FileDialogHelper.SaveFile(ConfigManager.DebuggerFolder, EmuApi.GetRomInfo().GetRomName() + ".txt", this.GetWindow(), FileDialogHelper.TraceExt); if(filename != null) { _model.TraceFile = filename; _model.IsLoggingToFile = true; diff --git a/UI/Debugger/Windows/WatchWindow.axaml.cs b/UI/Debugger/Windows/WatchWindow.axaml.cs index 3f8b1bee3..7bd2dcb93 100644 --- a/UI/Debugger/Windows/WatchWindow.axaml.cs +++ b/UI/Debugger/Windows/WatchWindow.axaml.cs @@ -24,9 +24,6 @@ public WatchWindow() : this(new WatchWindowViewModel()) { } public WatchWindow(WatchWindowViewModel model) { InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif _model = model; DataContext = model; diff --git a/UI/FodyWeavers.xml b/UI/FodyWeavers.xml deleted file mode 100644 index 63fc14848..000000000 --- a/UI/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/UI/FodyWeavers.xsd b/UI/FodyWeavers.xsd deleted file mode 100644 index f3ac47620..000000000 --- a/UI/FodyWeavers.xsd +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/UI/MesenWindow.cs b/UI/MesenWindow.cs index 7884aaab5..f454e2ea2 100644 --- a/UI/MesenWindow.cs +++ b/UI/MesenWindow.cs @@ -30,16 +30,16 @@ private static void SetTextRenderingMode(Visual v) { switch(ConfigManager.Config.Preferences.FontAntialiasing) { case FontAntialiasing.Disabled: - RenderOptions.SetTextRenderingMode(v, TextRenderingMode.Alias); + TextOptions.SetTextRenderingMode(v, TextRenderingMode.Alias); break; case FontAntialiasing.Antialias: - RenderOptions.SetTextRenderingMode(v, TextRenderingMode.Antialias); + TextOptions.SetTextRenderingMode(v, TextRenderingMode.Antialias); break; default: case FontAntialiasing.SubPixelAntialias: - RenderOptions.SetTextRenderingMode(v, TextRenderingMode.SubpixelAntialias); + TextOptions.SetTextRenderingMode(v, TextRenderingMode.SubpixelAntialias); break; } } diff --git a/UI/Program.cs b/UI/Program.cs index 503377876..b183edb21 100644 --- a/UI/Program.cs +++ b/UI/Program.cs @@ -2,7 +2,6 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Media; -using Avalonia.ReactiveUI; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; @@ -113,7 +112,6 @@ private static IntPtr DllImportResolver(string libraryName, Assembly assembly, D // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() - .UseReactiveUI() .UsePlatformDetect() .With(new Win32PlatformOptions { }) .With(new X11PlatformOptions { diff --git a/UI/Properties/PublishProfiles/Release.pubxml b/UI/Properties/PublishProfiles/Release.pubxml index 5e6b1eef5..326e38fd6 100644 --- a/UI/Properties/PublishProfiles/Release.pubxml +++ b/UI/Properties/PublishProfiles/Release.pubxml @@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. x64 ../build/TmpReleaseBuild FileSystem - net8.0 + net10.0 win-x64 true true diff --git a/UI/Styles/AvaloniaMenuItemStyles.xaml b/UI/Styles/AvaloniaMenuItemStyles.xaml index 1a4151559..eb3157c09 100644 --- a/UI/Styles/AvaloniaMenuItemStyles.xaml +++ b/UI/Styles/AvaloniaMenuItemStyles.xaml @@ -137,7 +137,7 @@ Placement="BottomEdgeAlignedLeft" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" IsLightDismissEnabled="True" - RenderOptions.TextRenderingMode="Alias" + TextOptions.TextRenderingMode="Alias" IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}" OverlayInputPassThroughElement="{Binding $parent[Menu]}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UI/Styles/DockStyles.xaml b/UI/Styles/DockStyles.xaml index 530419743..fb1d837e2 100644 --- a/UI/Styles/DockStyles.xaml +++ b/UI/Styles/DockStyles.xaml @@ -7,6 +7,14 @@ xmlns:controls="using:Dock.Model.Controls" xmlns:core="using:Dock.Model.Core" > + + + + + + + + @@ -32,134 +40,7 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/UI/Styles/MesenStyles.xaml b/UI/Styles/MesenStyles.xaml index b56073ba5..b30636daa 100644 --- a/UI/Styles/MesenStyles.xaml +++ b/UI/Styles/MesenStyles.xaml @@ -8,7 +8,7 @@ - + diff --git a/UI/Styles/StartupStyles.xaml b/UI/Styles/StartupStyles.xaml index 54271fa0f..30c5b2165 100644 --- a/UI/Styles/StartupStyles.xaml +++ b/UI/Styles/StartupStyles.xaml @@ -19,9 +19,6 @@ - - - = 0) { + if(cell.Column is DataBoxCheckBoxColumn && Selection.SelectedItems.Contains(cell.DataContext)) { //Prevent selection change when clicking checkbox column when multiple items are selected e.Handled = true; } @@ -356,10 +353,10 @@ private bool SearchColumn(DataBoxColumn column) return false; } - if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBindingExtension columnBinding) { -#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code - Binding binding = new Binding(columnBinding.Path.ToString(), BindingMode.OneTime); -#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code + if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBinding columnBinding) { +#pragma warning disable IL2026, IL3050 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code + Binding binding = new Binding(columnBinding.Path?.ToString() ?? ""); +#pragma warning restore IL2026, IL3050 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code int i = 0; foreach(object item in Items) { binding.Source = item; @@ -391,10 +388,10 @@ private string ConvertToText() List bindings = new(); for(int i = 0; i < Columns.Count; i++) { DataBoxColumn column = Columns[i]; - if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBindingExtension columnBinding) { -#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code - bindings.Add(new Binding(columnBinding.Path.ToString(), BindingMode.OneTime)); -#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code + if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBinding columnBinding) { +#pragma warning disable IL2026, IL3050 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code + bindings.Add(new Binding(columnBinding.Path?.ToString() ?? "")); +#pragma warning restore IL2026, IL3050 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code sb.Append(textColumn.Header); if(i < Columns.Count - 1) { @@ -409,7 +406,7 @@ private string ConvertToText() foreach(object item in Items) { for(int i = 0; i < Columns.Count; i++) { DataBoxColumn column = Columns[i]; - if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBindingExtension columnBinding) { + if(column is DataBoxTextColumn textColumn && textColumn.Binding is CompiledBinding columnBinding) { Binding? binding = bindings[i]; if(binding == null) { continue; diff --git a/UI/ThirdParty/DataBox/DataBoxBoundColumn.cs b/UI/ThirdParty/DataBox/DataBoxBoundColumn.cs index 6fe2f7980..fd36f8bcf 100644 --- a/UI/ThirdParty/DataBox/DataBoxBoundColumn.cs +++ b/UI/ThirdParty/DataBox/DataBoxBoundColumn.cs @@ -5,21 +5,21 @@ namespace DataBoxControl; public abstract class DataBoxBoundColumn : DataBoxColumn { - public static readonly StyledProperty BindingProperty = - AvaloniaProperty.Register(nameof(Binding)); + public static readonly StyledProperty BindingProperty = + AvaloniaProperty.Register(nameof(Binding)); - public static readonly StyledProperty IsVisibleProperty = - AvaloniaProperty.Register(nameof(IsVisible)); + public static readonly StyledProperty IsVisibleProperty = + AvaloniaProperty.Register(nameof(IsVisible)); [AssignBinding] - public IBinding? Binding + public BindingBase? Binding { get => GetValue(BindingProperty); set => SetValue(BindingProperty, value); } [AssignBinding] - public IBinding? IsVisible + public BindingBase? IsVisible { get => GetValue(IsVisibleProperty); set => SetValue(IsVisibleProperty, value); diff --git a/UI/ThirdParty/DataBox/Primitives/DataBoxColumnHeadersPresenter.cs b/UI/ThirdParty/DataBox/Primitives/DataBoxColumnHeadersPresenter.cs index 3f4e6bf56..76d27a93c 100644 --- a/UI/ThirdParty/DataBox/Primitives/DataBoxColumnHeadersPresenter.cs +++ b/UI/ThirdParty/DataBox/Primitives/DataBoxColumnHeadersPresenter.cs @@ -3,6 +3,7 @@ using Avalonia.Layout; using Avalonia.Styling; using DataBoxControl.Primitives.Layout; +using Mesen.Utilities; using System; using System.Collections.Generic; @@ -48,7 +49,7 @@ internal void Attach() Children.Add(columnHeader); _columnHeaders.Add(columnHeader); - var disposable = column.GetObservable(DataBoxColumn.MeasureWidthProperty).Subscribe(_ => { + var disposable = column.ObserveProp(DataBoxColumn.MeasureWidthProperty, x => { InvalidateMeasure(); InvalidateVisual(); }); diff --git a/UI/UI.csproj b/UI/UI.csproj index e8c784c8c..beb75bd34 100644 --- a/UI/UI.csproj +++ b/UI/UI.csproj @@ -1,7 +1,7 @@  WinExe - net8.0 + net10.0 win-x64 enable true @@ -13,6 +13,9 @@ (C) 2014-2026 Sour + + false + false false Assets\Icon.ico @@ -22,14 +25,12 @@ app.manifest false false - false - true - true false false - - true + + true + IL2026;IL2070;IL2075;IL2104;IL3050;IL3053 .. @@ -103,6 +104,13 @@ https://nuget-feed-nightly.avaloniaui.net/v3/index.json;https://api.nuget.org/v3/index.json + + true + NoMatchFilter + NoMatchFilter + False + False + @@ -112,18 +120,18 @@ - - - - - - - - - + + + + + + + + + + - @@ -608,6 +616,9 @@ MSBuild:Compile + + MSBuild:Compile + MSBuild:Compile diff --git a/UI/Utilities/ControlExtensions.cs b/UI/Utilities/ControlExtensions.cs index c6d4bf6e3..f436c5999 100644 --- a/UI/Utilities/ControlExtensions.cs +++ b/UI/Utilities/ControlExtensions.cs @@ -12,7 +12,15 @@ static class ControlExtensions { public static bool IsParentWindowFocused(this Control ctrl) { - return (ctrl.GetVisualRoot() as WindowBase)?.IsKeyboardFocusWithin == true; + return ctrl.GetWindow()?.IsKeyboardFocusWithin == true; + } + + public static Window? GetWindow(this Control ctrl) + { + if(ctrl.GetPresentationSource()?.RootVisual?.Parent is Window wnd) { + return wnd; + } + return null; } } } diff --git a/UI/Utilities/EnumExtensions.cs b/UI/Utilities/EnumExtensions.cs deleted file mode 100644 index 411602e99..000000000 --- a/UI/Utilities/EnumExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace Mesen.Utilities -{ - public static class EnumExtensions - { - public static T? GetAttribute(this Enum val) where T : Attribute - { - return val.GetType().GetMember(val.ToString())[0].GetCustomAttribute(); - } - } -} diff --git a/UI/Utilities/FileDialogHelper.cs b/UI/Utilities/FileDialogHelper.cs index 1408173f6..ce6926c4e 100644 --- a/UI/Utilities/FileDialogHelper.cs +++ b/UI/Utilities/FileDialogHelper.cs @@ -38,7 +38,7 @@ public class FileDialogHelper public const string SufamiTurboExt = "st"; public const string SpcExt = "spc"; - public static async Task OpenFile(string? initialFolder, IRenderRoot? parent, params string[] extensions) + public static async Task OpenFile(string? initialFolder, Window? parent, params string[] extensions) { if(!((parent ?? ApplicationHelper.GetMainWindow()) is Window wnd)) { throw new Exception("Invalid parent window"); @@ -96,7 +96,7 @@ public class FileDialogHelper return null; } - public static async Task SaveFile(string? initialFolder, string? initialFile, IRenderRoot? parent, params string[] extensions) + public static async Task SaveFile(string? initialFolder, string? initialFile, Window? parent, params string[] extensions) { if(!((parent ?? ApplicationHelper.GetMainWindow()) is Window wnd)) { throw new Exception("Invalid parent window"); @@ -132,7 +132,7 @@ public class FileDialogHelper return null; } - public static async Task OpenFolder(IRenderRoot? parent) + public static async Task OpenFolder(Window? parent) { if(!((parent ?? ApplicationHelper.GetMainWindow()) is Window wnd)) { throw new Exception("Invalid parent window"); diff --git a/UI/Utilities/FirmwareHelper.cs b/UI/Utilities/FirmwareHelper.cs index c6c4890f4..e81639ad7 100644 --- a/UI/Utilities/FirmwareHelper.cs +++ b/UI/Utilities/FirmwareHelper.cs @@ -58,7 +58,7 @@ public static async Task RequestFirmwareFile(MissingFirmwareMessage msg) } } - public static async Task SelectFirmwareFile(FirmwareType type, string selectedFile, IRenderRoot? wnd) + public static async Task SelectFirmwareFile(FirmwareType type, string selectedFile, Window? wnd) { FirmwareFiles knownFirmwares = type.GetFirmwareInfo(); diff --git a/UI/Utilities/LoadRomHelper.cs b/UI/Utilities/LoadRomHelper.cs index f4c80221b..5a3e9b2a1 100644 --- a/UI/Utilities/LoadRomHelper.cs +++ b/UI/Utilities/LoadRomHelper.cs @@ -124,7 +124,7 @@ private static bool IsPatchFile(string filename) using(FileStream? stream = FileHelper.OpenRead(filename)) { if(stream != null) { byte[] header = new byte[5]; - stream.Read(header, 0, 5); + stream.ReadExactly(header, 0, 5); if(header[0] == 'P' && header[1] == 'A' && header[2] == 'T' && header[3] == 'C' && header[4] == 'H') { return true; } else if((header[0] == 'U' || header[0] == 'B') && header[1] == 'P' && header[2] == 'S' && header[3] == '1') { diff --git a/UI/Utilities/MenuHelper.cs b/UI/Utilities/MenuHelper.cs index 7e7df79d2..96c739a9a 100644 --- a/UI/Utilities/MenuHelper.cs +++ b/UI/Utilities/MenuHelper.cs @@ -22,7 +22,7 @@ private static bool IsPointerInItem(MenuItem item) if(IsPointerInItem(subItem)) { return true; } else if(checkPopup) { - if(subItem.GetVisualRoot() is PopupRoot root) { + if(subItem.GetPresentationSource()?.RootVisual?.Parent is PopupRoot root) { if(root.IsPointerOver) { return true; } @@ -64,7 +64,7 @@ private static bool IsFocusInItem(MenuItem item) if(IsFocusInItem(subItem)) { return true; } else if(checkPopup) { - if(subItem.GetVisualRoot() is PopupRoot root) { + if(subItem.GetPresentationSource()?.RootVisual?.Parent is PopupRoot root) { if(root.IsKeyboardFocusWithin) { return true; } diff --git a/UI/Utilities/MesenMsgBox.cs b/UI/Utilities/MesenMsgBox.cs index a84bba9fa..d9f3f23c2 100644 --- a/UI/Utilities/MesenMsgBox.cs +++ b/UI/Utilities/MesenMsgBox.cs @@ -17,7 +17,7 @@ public static Task ShowException(Exception ex) return MesenMsgBox.Show(null, "UnexpectedError", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.Message + Environment.NewLine + ex.StackTrace); } - public static Task Show(IRenderRoot? parent, string text, MessageBoxButtons buttons, MessageBoxIcon icon, params string[] args) + public static Task Show(Window? parent, string text, MessageBoxButtons buttons, MessageBoxIcon icon, params string[] args) { Window? wnd = parent as Window; if(parent != null && wnd == null) { diff --git a/UI/Utilities/ReactiveHelper.cs b/UI/Utilities/ReactiveHelper.cs index 9f87ab782..03d62b35c 100644 --- a/UI/Utilities/ReactiveHelper.cs +++ b/UI/Utilities/ReactiveHelper.cs @@ -1,5 +1,6 @@ -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using Avalonia; +using Avalonia.Reactive; +using CommunityToolkit.Mvvm.ComponentModel; using System; using System.Collections; using System.Collections.Generic; @@ -10,22 +11,96 @@ namespace Mesen.Utilities { public static class ReactiveHelper { - public static IDisposable RegisterRecursiveObserver(ReactiveObject target, PropertyChangedEventHandler handler) + public static IDisposable RegisterObserver(T target, string propertyName, Action action) where T : INotifyPropertyChanged { - Dictionary observableObjects = new(); + return RegisterObserver([target], [propertyName], action); + } + + public static IDisposable RegisterObserver(T[] targets, string propertyName, Action action) where T : INotifyPropertyChanged + { + return RegisterObserver(targets, [propertyName], action); + } + + public static IDisposable RegisterObserver(T target, string[] properties, Action action) where T : INotifyPropertyChanged + { + return RegisterObserver([target], properties, action); + } + + public static IDisposable RegisterObserver(T[] targets, string[] properties, Action action) where T : INotifyPropertyChanged + { + HashSet props = new(properties); + PropertyChangedEventHandler handler = (s, e) => { + if(e.PropertyName != null && props.Contains(e.PropertyName)) { + action(); + } + }; + foreach(T target in targets) { + target.PropertyChanged += handler; + } + action(); + + return new DisposableObserver(() => { + foreach(INotifyPropertyChanged target in targets) { + target.PropertyChanged -= handler; + } + }); + } + + public static IDisposable RegisterForeignObserver((Func, string)[] targets, Action action) + { + List elementsToDispose = new(); + Action dispose = () => { + foreach(Action disposeAction in elementsToDispose) { + disposeAction(); + } + }; + + Action? initObserver = null; + + initObserver = () => { + foreach((Func targetFunc, string prop) in targets) { + PropertyChangedEventHandler handler = (s, e) => { + if(e.PropertyName == prop) { + action(); + dispose(); + initObserver?.Invoke(); + } + }; + ObservableObject target = targetFunc(); + target.PropertyChanged += handler; + elementsToDispose.Add(() => { target.PropertyChanged -= handler; }); + } + }; + + initObserver(); + action(); + + return new DisposableObserver(dispose); + } + + private static PropertyInfo[] GetProperties(ObservableObject target) + { +#pragma warning disable IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. + return target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); +#pragma warning restore IL2075 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations. + } + + public static IDisposable RegisterRecursiveObserver(ObservableObject target, PropertyChangedEventHandler handler) + { + Dictionary observableObjects = new(); Dictionary props = new(); - foreach(PropertyInfo prop in target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { - if(prop.GetCustomAttribute() != null) { + foreach(PropertyInfo prop in GetProperties(target)) { + if(prop.GetCustomAttribute() != null) { object? value = prop.GetValue(target); - if(value is ReactiveObject propValue) { + if(value is ObservableObject propValue) { observableObjects[prop.Name] = propValue; props[prop.Name] = prop; ReactiveHelper.RegisterRecursiveObserver(propValue, handler); } else if(value is IList list) { foreach(object listValue in list) { - if(listValue is ReactiveObject) { - ReactiveHelper.RegisterRecursiveObserver((ReactiveObject)listValue, handler); + if(listValue is ObservableObject) { + ReactiveHelper.RegisterRecursiveObserver((ObservableObject)listValue, handler); } } } @@ -36,13 +111,13 @@ public static IDisposable RegisterRecursiveObserver(ReactiveObject target, Prope handler(s, e); //Reset change handlers if an object is replaced with another object - if(e.PropertyName != null && observableObjects.TryGetValue(e.PropertyName, out ReactiveObject? obj)) { + if(e.PropertyName != null && observableObjects.TryGetValue(e.PropertyName, out ObservableObject? obj)) { //Remove handlers on the old object ReactiveHelper.UnregisterRecursiveObserver(obj, handler); if(props.TryGetValue(e.PropertyName, out PropertyInfo? prop)) { object? value = prop.GetValue(target); - if(value is ReactiveObject propValue) { + if(value is ObservableObject propValue) { observableObjects[prop.Name] = propValue; //Register change handlers on the new object @@ -55,17 +130,17 @@ public static IDisposable RegisterRecursiveObserver(ReactiveObject target, Prope return new RecursiveObserver(target, handler); } - public static void UnregisterRecursiveObserver(ReactiveObject target, PropertyChangedEventHandler handler) + public static void UnregisterRecursiveObserver(ObservableObject target, PropertyChangedEventHandler handler) { - foreach(PropertyInfo prop in target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { - if(prop.GetCustomAttribute() != null) { + foreach(PropertyInfo prop in GetProperties(target)) { + if(prop.GetCustomAttribute() != null) { object? value = prop.GetValue(target); - if(value is ReactiveObject propValue) { + if(value is ObservableObject propValue) { ReactiveHelper.UnregisterRecursiveObserver(propValue, handler); } else if(value is IList list) { foreach(object listValue in list) { - if(listValue is ReactiveObject) { - ReactiveHelper.UnregisterRecursiveObserver((ReactiveObject)listValue, handler); + if(listValue is ObservableObject) { + ReactiveHelper.UnregisterRecursiveObserver((ObservableObject)listValue, handler); } } } @@ -78,10 +153,10 @@ public static void UnregisterRecursiveObserver(ReactiveObject target, PropertyCh public class RecursiveObserver : IDisposable { - private ReactiveObject _target; + private ObservableObject _target; private PropertyChangedEventHandler _handler; - public RecursiveObserver(ReactiveObject target, PropertyChangedEventHandler handler) + public RecursiveObserver(ObservableObject target, PropertyChangedEventHandler handler) { _target = target; _handler = handler; @@ -92,4 +167,37 @@ public void Dispose() ReactiveHelper.UnregisterRecursiveObserver(_target, _handler); } } + + public class DisposableObserver : IDisposable + { + private Action DisposeCallback { get; } + + public DisposableObserver(Action dispose) + { + DisposeCallback = dispose; + } + + public void Dispose() + { + DisposeCallback(); + } + } + + public static class ReactiveExtensions + { + public static IDisposable ObserveProp(this AvaloniaObject obj, AvaloniaProperty prop, Action action) + { + return obj.GetPropertyChangedObservable(prop).Subscribe(new AnonymousObserver(action)); + } + + public static IDisposable ObserveProp(this INotifyPropertyChanged obj, string property, Action action) + { + return ReactiveHelper.RegisterObserver(obj, property, action); + } + + public static IDisposable ObserveProp(this INotifyPropertyChanged obj, string[] properties, Action action) + { + return ReactiveHelper.RegisterObserver(obj, properties, action); + } + } } diff --git a/UI/Utilities/WindowExtensions.cs b/UI/Utilities/WindowExtensions.cs index 9d3feee52..e5526bec0 100644 --- a/UI/Utilities/WindowExtensions.cs +++ b/UI/Utilities/WindowExtensions.cs @@ -14,14 +14,14 @@ namespace Mesen.Utilities { static class WindowExtensions { - public static void CenterWindow(Window child, Visual parent) + public static void CenterWindow(Window child, Control parent) { EventHandler? handler = null; handler = (s, e) => { //This logic is inside the Opened event because running it immediately //before showing the window appears to break some things in some configurations (multi-monitor+high DPI) - WindowBase? parentWnd = parent.GetVisualRoot() as WindowBase; + WindowBase? parentWnd = parent.GetWindow(); Screen? screen = null; double scale = 1; if(parentWnd != null) { @@ -67,7 +67,7 @@ private static PixelPoint FitToScreenBounds(Screen? screen, int childWidth, int return startPosition; } - public static void ShowCentered(this Window child, Visual? parent) + public static void ShowCentered(this Window child, Control? parent) { if(parent != null) { CenterWindow(child, parent); @@ -81,12 +81,12 @@ public static void ShowCenteredWithParent(this Window child, Window parent) child.Show(parent); } - public static Task ShowCenteredDialog(this Window child, Visual? parent) + public static Task ShowCenteredDialog(this Window child, Control? parent) { return ShowCenteredDialog(child, parent); } - public static Task ShowCenteredDialog(this Window child, Visual? parent) + public static Task ShowCenteredDialog(this Window child, Control? parent) { if(parent != null) { CenterWindow(child, parent); @@ -94,14 +94,14 @@ public static Task ShowCenteredDialog(this Window child, Visua return InternalShowDialog(child, parent); } - public static Task ShowDialogAtPosition(this Window child, Visual? parent, PixelPoint startPosition) + public static Task ShowDialogAtPosition(this Window child, Control? parent, PixelPoint startPosition) { child.WindowStartupLocation = WindowStartupLocation.Manual; child.Position = startPosition; EventHandler? handler = null; handler = (s, e) => { - WindowBase? parentWnd = parent?.GetVisualRoot() as WindowBase; + WindowBase? parentWnd = parent?.GetWindow(); if(parentWnd != null && parent != null) { Screen? screen = parentWnd.Screens.ScreenFromVisual(parent); double scale = LayoutHelper.GetLayoutScale(parentWnd); diff --git a/UI/ViewModels/AudioConfigViewModel.cs b/UI/ViewModels/AudioConfigViewModel.cs index df8c9cc10..706a3e97a 100644 --- a/UI/ViewModels/AudioConfigViewModel.cs +++ b/UI/ViewModels/AudioConfigViewModel.cs @@ -1,21 +1,19 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; -using System.Reactive.Linq; namespace Mesen.ViewModels { - public class AudioConfigViewModel : DisposableViewModel + public partial class AudioConfigViewModel : DisposableViewModel { - [Reactive] public AudioConfig Config { get; set; } - [Reactive] public AudioConfig OriginalConfig { get; set; } - [Reactive] public List AudioDevices { get; set; } = new(); - [Reactive] public bool ShowLatencyWarning { get; set; } = false; + [ObservableProperty] public partial AudioConfig Config { get; set; } + [ObservableProperty] public partial AudioConfig OriginalConfig { get; set; } + [ObservableProperty] public partial List AudioDevices { get; set; } = new(); + [ObservableProperty] public partial bool ShowLatencyWarning { get; set; } = false; public AudioConfigViewModel() { @@ -31,7 +29,7 @@ public AudioConfigViewModel() Config.AudioDevice = AudioDevices[0]; } - AddDisposable(this.WhenAnyValue(x => x.Config.AudioLatency).Subscribe(x => { + AddDisposable(Config.ObserveProp(nameof(Config.AudioLatency), () => { ShowLatencyWarning = Config.AudioLatency <= 55; })); diff --git a/UI/ViewModels/AudioPlayerViewModel.cs b/UI/ViewModels/AudioPlayerViewModel.cs index 7a98deffe..7e9349d26 100644 --- a/UI/ViewModels/AudioPlayerViewModel.cs +++ b/UI/ViewModels/AudioPlayerViewModel.cs @@ -1,7 +1,7 @@ -using Mesen.Config; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Config; using Mesen.Interop; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using Mesen.Utilities; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -11,18 +11,18 @@ namespace Mesen.ViewModels { - public class AudioPlayerViewModel : ViewModelBase + public partial class AudioPlayerViewModel : DisposableViewModel { - [Reactive] public AudioPlayerConfig Config { get; set; } - [Reactive] public bool IsPaused { get; set; } + [ObservableProperty] public partial AudioPlayerConfig Config { get; set; } + [ObservableProperty] public partial bool IsPaused { get; set; } public AudioPlayerViewModel() { Config = ConfigManager.Config.AudioPlayer; - this.WhenAnyValue(x => x.Config.Volume).Subscribe((vol) => { + AddDisposable(Config.ObserveProp(nameof(Config.Volume), () => { Config.ApplyConfig(); - }); + })); } public void UpdatePauseFlag() diff --git a/UI/ViewModels/CheatDatabaseViewModel.cs b/UI/ViewModels/CheatDatabaseViewModel.cs index f840b89e0..f02444c3e 100644 --- a/UI/ViewModels/CheatDatabaseViewModel.cs +++ b/UI/ViewModels/CheatDatabaseViewModel.cs @@ -1,29 +1,27 @@ using Avalonia.Controls; using Avalonia.Controls.Selection; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; -using System.Reactive.Linq; using System.Reflection; using System.Text.Json; using System.Xml.Serialization; namespace Mesen.ViewModels { - public class CheatDatabaseViewModel : DisposableViewModel + public partial class CheatDatabaseViewModel : DisposableViewModel { private List _entries; - [Reactive] public IEnumerable FilteredEntries { get; set; } - [Reactive] public SelectionModel SelectionModel { get; set; } = new(); - [Reactive] public string SearchString { get; set; } = ""; + [ObservableProperty] public partial IEnumerable FilteredEntries { get; set; } + [ObservableProperty] public partial SelectionModel SelectionModel { get; set; } = new(); + [ObservableProperty] public partial string SearchString { get; set; } = ""; [Obsolete("For designer only")] public CheatDatabaseViewModel() : this(ConsoleType.Snes) { } @@ -40,20 +38,22 @@ public CheatDatabaseViewModel(ConsoleType consoleType) _entries = cheatDb.Games; FilteredEntries = _entries; - AddDisposable(this.WhenAnyValue(x => x.SearchString).Subscribe(x => { - if(string.IsNullOrWhiteSpace(x)) { - FilteredEntries = _entries; - } else { - FilteredEntries = _entries.Where(e => e.Name.Contains(x, StringComparison.OrdinalIgnoreCase)); - } - - SelectionModel.SelectedItem = FilteredEntries.FirstOrDefault(); - })); if(!Design.IsDesignMode) { string sha1 = EmuApi.GetRomHash(HashType.Sha1Cheat); SelectionModel.SelectedItem = _entries.Find(e => e.Sha1 == sha1); } } + + partial void OnSearchStringChanged(string value) + { + if(string.IsNullOrWhiteSpace(value)) { + FilteredEntries = _entries; + } else { + FilteredEntries = _entries.Where(e => e.Name.Contains(value, StringComparison.OrdinalIgnoreCase)); + } + + SelectionModel.SelectedItem = FilteredEntries.FirstOrDefault(); + } } } diff --git a/UI/ViewModels/CheatEditWindowViewModel.cs b/UI/ViewModels/CheatEditWindowViewModel.cs index 7e02ae0b0..6d6b528d8 100644 --- a/UI/ViewModels/CheatEditWindowViewModel.cs +++ b/UI/ViewModels/CheatEditWindowViewModel.cs @@ -1,27 +1,25 @@ using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Interop; using Mesen.Utilities; using Mesen.Windows; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; -using System.Reactive.Linq; using System.Text; namespace Mesen.ViewModels { - public class CheatEditWindowViewModel : DisposableViewModel + public partial class CheatEditWindowViewModel : DisposableViewModel { public CheatCode Cheat { get; } - [ObservableAsProperty] public string ConvertedCodes { get; } = ""; - [Reactive] public bool ShowInvalidCodeHint { get; private set; } = false; - [Reactive] public bool OkButtonEnabled { get; private set; } = false; + [ObservableProperty] public partial string ConvertedCodes { get; private set; } = ""; + [ObservableProperty] public partial bool ShowInvalidCodeHint { get; private set; } = false; + [ObservableProperty] public partial bool OkButtonEnabled { get; private set; } = false; - [Reactive] public Enum[] AvailableCheatTypes { get; private set; } = Array.Empty(); + [ObservableProperty] public partial Enum[] AvailableCheatTypes { get; private set; } = Array.Empty(); private MainWindowViewModel MainWndModel { get; } @@ -33,7 +31,11 @@ public CheatEditWindowViewModel(CheatCode cheat) Cheat = cheat; MainWndModel = MainWindowViewModel.Instance; - AddDisposable(this.WhenAnyValue(x => x.Cheat.Codes, x => x.Cheat.Type).Select(x => { + Cheat.PropertyChanged += (s, e) => { + if(e.PropertyName != nameof(CheatCode.Codes) && e.PropertyName != nameof(CheatCode.Type)) { + return; + } + string[] codes = cheat.Codes.Split(Environment.NewLine); StringBuilder sb = new StringBuilder(); bool hasInvalidCode = false; @@ -66,19 +68,22 @@ public CheatEditWindowViewModel(CheatCode cheat) ShowInvalidCodeHint = hasInvalidCode; OkButtonEnabled = hasValidCode && !hasInvalidCode; - return sb.ToString(); - }).ToPropertyEx(this, x => x.ConvertedCodes)); + ConvertedCodes = sb.ToString(); + }; if(Design.IsDesignMode) { return; } - AddDisposable(this.WhenAnyValue(x => x.MainWndModel.RomInfo).Subscribe(romInfo => { - AvailableCheatTypes = Enum.GetValues().Where(e => romInfo.CpuTypes.Contains(e.ToCpuType())).Cast().ToArray(); - if(!AvailableCheatTypes.Contains(Cheat.Type)) { - Cheat.Type = (CheatType)AvailableCheatTypes[0]; + + MainWndModel.PropertyChanged += (s, e) => { + if(e.PropertyName == nameof(MainWindowViewModel.RomInfo)) { + AvailableCheatTypes = Enum.GetValues().Where(e => MainWndModel.RomInfo.CpuTypes.Contains(e.ToCpuType())).Cast().ToArray(); + if(!AvailableCheatTypes.Contains(Cheat.Type)) { + Cheat.Type = (CheatType)AvailableCheatTypes[0]; + } } - })); + }; } } } diff --git a/UI/ViewModels/CheatListWindowViewModel.cs b/UI/ViewModels/CheatListWindowViewModel.cs index 0f7cd5187..00e643819 100644 --- a/UI/ViewModels/CheatListWindowViewModel.cs +++ b/UI/ViewModels/CheatListWindowViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Controls.Selection; using Avalonia.Input; using Avalonia.VisualTree; +using CommunityToolkit.Mvvm.ComponentModel; using DataBoxControl; using Mesen.Config; using Mesen.Debugger; @@ -10,23 +11,21 @@ using Mesen.Interop; using Mesen.Utilities; using Mesen.Windows; -using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using System.Reactive.Linq; namespace Mesen.ViewModels { - public class CheatListWindowViewModel : DisposableViewModel + public partial class CheatListWindowViewModel : DisposableViewModel { - [Reactive] public MesenList Cheats { get; private set; } = new(); - [Reactive] public List ToolbarActions { get; private set; } = new(); - [Reactive] public bool DisableAllCheats { get; set; } = false; + [ObservableProperty] public partial MesenList Cheats { get; private set; } = new(); + [ObservableProperty] public partial List ToolbarActions { get; private set; } = new(); + [ObservableProperty] public partial bool DisableAllCheats { get; set; } = false; - [Reactive] public SelectionModel Selection { get; set; } = new(); - [Reactive] public SortState SortState { get; set; } = new(); + [ObservableProperty] public partial SelectionModel Selection { get; set; } = new(); + [ObservableProperty] public partial SortState SortState { get; set; } = new(); public CheatWindowConfig Config { get; } diff --git a/UI/ViewModels/ColorPickerViewModel.cs b/UI/ViewModels/ColorPickerViewModel.cs index bdb265b31..2fa13d89a 100644 --- a/UI/ViewModels/ColorPickerViewModel.cs +++ b/UI/ViewModels/ColorPickerViewModel.cs @@ -1,10 +1,10 @@ using Avalonia.Media; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.ViewModels { - public class ColorPickerViewModel : ViewModelBase + public partial class ColorPickerViewModel : ViewModelBase { - [Reactive] public Color Color { get; set; } + [ObservableProperty] public partial Color Color { get; set; } } } diff --git a/UI/ViewModels/ConfigViewModel.cs b/UI/ViewModels/ConfigViewModel.cs index a3b51e364..0ac849652 100644 --- a/UI/ViewModels/ConfigViewModel.cs +++ b/UI/ViewModels/ConfigViewModel.cs @@ -1,30 +1,29 @@ -using Mesen.Config; +using CommunityToolkit.Mvvm.ComponentModel; +using HarfBuzzSharp; +using Mesen.Config; using Mesen.Utilities; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive.Linq; namespace Mesen.ViewModels { - public class ConfigViewModel : DisposableViewModel + public partial class ConfigViewModel : DisposableViewModel { - [Reactive] public AudioConfigViewModel? Audio { get; set; } - [Reactive] public InputConfigViewModel? Input { get; set; } - [Reactive] public VideoConfigViewModel? Video { get; set; } - [Reactive] public PreferencesConfigViewModel? Preferences { get; set; } - [Reactive] public EmulationConfigViewModel? Emulation { get; set; } + [ObservableProperty] public partial AudioConfigViewModel? Audio { get; set; } + [ObservableProperty] public partial InputConfigViewModel? Input { get; set; } + [ObservableProperty] public partial VideoConfigViewModel? Video { get; set; } + [ObservableProperty] public partial PreferencesConfigViewModel? Preferences { get; set; } + [ObservableProperty] public partial EmulationConfigViewModel? Emulation { get; set; } - [Reactive] public SnesConfigViewModel? Snes { get; set; } - [Reactive] public NesConfigViewModel? Nes { get; set; } - [Reactive] public GameboyConfigViewModel? Gameboy { get; set; } - [Reactive] public GbaConfigViewModel? Gba { get; set; } - [Reactive] public PceConfigViewModel? PcEngine { get; set; } - [Reactive] public SmsConfigViewModel? Sms { get; set; } - [Reactive] public WsConfigViewModel? Ws { get; set; } - [Reactive] public OtherConsolesConfigViewModel? OtherConsoles { get; set; } + [ObservableProperty] public partial SnesConfigViewModel? Snes { get; set; } + [ObservableProperty] public partial NesConfigViewModel? Nes { get; set; } + [ObservableProperty] public partial GameboyConfigViewModel? Gameboy { get; set; } + [ObservableProperty] public partial GbaConfigViewModel? Gba { get; set; } + [ObservableProperty] public partial PceConfigViewModel? PcEngine { get; set; } + [ObservableProperty] public partial SmsConfigViewModel? Sms { get; set; } + [ObservableProperty] public partial WsConfigViewModel? Ws { get; set; } + [ObservableProperty] public partial OtherConsolesConfigViewModel? OtherConsoles { get; set; } - [Reactive] public ConfigWindowTab SelectedIndex { get; set; } + [ObservableProperty] public partial ConfigWindowTab SelectedIndex { get; set; } public bool AlwaysOnTop { get; } [Obsolete("For designer only")] @@ -33,11 +32,12 @@ public ConfigViewModel() : this(ConfigWindowTab.Audio) { } public ConfigViewModel(ConfigWindowTab selectedTab) { AlwaysOnTop = ConfigManager.Config.Preferences.AlwaysOnTop; - SelectedIndex = selectedTab; + SelectTab(selectedTab); + } - AddDisposable(this.WhenAnyValue(x => x.SelectedIndex).Subscribe((tab) => { - this.SelectTab(tab); - })); + partial void OnSelectedIndexChanged(ConfigWindowTab value) + { + SelectTab(value); } public void SelectTab(ConfigWindowTab tab) diff --git a/UI/ViewModels/ControllerConfigViewModel.cs b/UI/ViewModels/ControllerConfigViewModel.cs index 5e5f9b066..fd5305686 100644 --- a/UI/ViewModels/ControllerConfigViewModel.cs +++ b/UI/ViewModels/ControllerConfigViewModel.cs @@ -1,29 +1,27 @@ -using Mesen.Config; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; +using Mesen.Config; using System; using System.Collections.Generic; using System.Linq; -using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; namespace Mesen.ViewModels { - public class ControllerConfigViewModel : ViewModelBase + public partial class ControllerConfigViewModel : ViewModelBase { public ControllerConfig Config { get; } public ControllerConfig OriginalConfig { get; } public ControllerType Type { get; } - [Reactive] public KeyMappingViewModel KeyMapping1 { get; set; } - [Reactive] public KeyMappingViewModel KeyMapping2 { get; set; } - [Reactive] public KeyMappingViewModel KeyMapping3 { get; set; } - [Reactive] public KeyMappingViewModel KeyMapping4 { get; set; } + [ObservableProperty] public partial KeyMappingViewModel KeyMapping1 { get; set; } + [ObservableProperty] public partial KeyMappingViewModel KeyMapping2 { get; set; } + [ObservableProperty] public partial KeyMappingViewModel KeyMapping3 { get; set; } + [ObservableProperty] public partial KeyMappingViewModel KeyMapping4 { get; set; } - [Reactive] public bool ShowPresets { get; set; } = false; - [Reactive] public bool IsTwoButtonController { get; set; } = false; - [Reactive] public bool ShowTurbo { get; set; } = false; + [ObservableProperty] public partial bool ShowPresets { get; set; } = false; + [ObservableProperty] public partial bool IsTwoButtonController { get; set; } = false; + [ObservableProperty] public partial bool ShowTurbo { get; set; } = false; [Obsolete("For designer only")] public ControllerConfigViewModel() : this(ControllerType.SnesController, new ControllerConfig(), new ControllerConfig(), 0) { } @@ -45,12 +43,12 @@ public ControllerConfigViewModel(ControllerType type, ControllerConfig config, C } } - public class KeyMappingViewModel : ViewModelBase + public partial class KeyMappingViewModel : ViewModelBase { - [Reactive] public ControllerType Type { get; set; } - [Reactive] public KeyMapping Mapping { get; set; } - [Reactive] public int Port { get; set; } - [Reactive] public List CustomKeys { get; set; } = new(); + [ObservableProperty] public partial ControllerType Type { get; set; } + [ObservableProperty] public partial KeyMapping Mapping { get; set; } + [ObservableProperty] public partial int Port { get; set; } + [ObservableProperty] public partial List CustomKeys { get; set; } = new(); private int _mappingIndex = 0; @@ -73,12 +71,12 @@ public void RefreshCustomKeys() } } - public class CustomKeyMapping : ViewModelBase + public partial class CustomKeyMapping : ViewModelBase { public string Name { get; set; } public UInt16[] Mappings { get; set; } public int Index { get; set; } - [Reactive] public UInt16 KeyMapping { get; set; } + [ObservableProperty] public partial UInt16 KeyMapping { get; set; } public CustomKeyMapping(string name, UInt16[] mappings, int index) { @@ -86,10 +84,11 @@ public CustomKeyMapping(string name, UInt16[] mappings, int index) Mappings = mappings; Index = index; KeyMapping = mappings[index]; + } - this.WhenAnyValue(x => x.KeyMapping).Subscribe(x => { - mappings[index] = x; - }); + partial void OnKeyMappingChanged(ushort value) + { + Mappings[Index] = value; } } } diff --git a/UI/ViewModels/CvInputConfigViewModel.cs b/UI/ViewModels/CvInputConfigViewModel.cs index b7bb2f45e..000d86de2 100644 --- a/UI/ViewModels/CvInputConfigViewModel.cs +++ b/UI/ViewModels/CvInputConfigViewModel.cs @@ -1,15 +1,13 @@ using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive.Linq; namespace Mesen.ViewModels { - public class CvInputConfigViewModel : DisposableViewModel + public partial class CvInputConfigViewModel : DisposableViewModel { - [Reactive] public CvConfig Config { get; set; } + [ObservableProperty] public partial CvConfig Config { get; set; } public Enum[] AvailableControllerTypesP12 => new Enum[] { ControllerType.None, diff --git a/UI/ViewModels/EmulationConfigViewModel.cs b/UI/ViewModels/EmulationConfigViewModel.cs index d0f373323..0dcdbf894 100644 --- a/UI/ViewModels/EmulationConfigViewModel.cs +++ b/UI/ViewModels/EmulationConfigViewModel.cs @@ -1,14 +1,14 @@ using Avalonia.Controls; using Mesen.Config; using Mesen.Utilities; -using ReactiveUI.Fody.Helpers; +using CommunityToolkit.Mvvm.ComponentModel; namespace Mesen.ViewModels { - public class EmulationConfigViewModel : DisposableViewModel + public partial class EmulationConfigViewModel : DisposableViewModel { - [Reactive] public EmulationConfig Config { get; set; } - [Reactive] public EmulationConfig OriginalConfig { get; set; } + [ObservableProperty] public partial EmulationConfig Config { get; set; } + [ObservableProperty] public partial EmulationConfig OriginalConfig { get; set; } public EmulationConfigViewModel() { diff --git a/UI/ViewModels/GameConfigViewModel.cs b/UI/ViewModels/GameConfigViewModel.cs index 49bf52b38..b9d6f1333 100644 --- a/UI/ViewModels/GameConfigViewModel.cs +++ b/UI/ViewModels/GameConfigViewModel.cs @@ -1,17 +1,16 @@ using Avalonia.Controls; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Mesen.Config; using Mesen.Utilities; using Microsoft.VisualBasic; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; namespace Mesen.ViewModels { - public class GameConfigViewModel : DisposableViewModel + public partial class GameConfigViewModel : DisposableViewModel { - [Reactive] public GameConfig Config { get; set; } + [ObservableProperty] public partial GameConfig Config { get; set; } public GameDipSwitches DipSwitches { get; } public GameConfigViewModel() diff --git a/UI/ViewModels/GameboyConfigViewModel.cs b/UI/ViewModels/GameboyConfigViewModel.cs index 4a8c51e3b..16824d822 100644 --- a/UI/ViewModels/GameboyConfigViewModel.cs +++ b/UI/ViewModels/GameboyConfigViewModel.cs @@ -1,33 +1,31 @@ using Avalonia; using Avalonia.Controls; using Avalonia.VisualTree; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using Mesen.Config; using Mesen.Utilities; using Mesen.Windows; -using ReactiveUI; -using ReactiveUI.Fody.Helpers; using System; -using System.Reactive; namespace Mesen.ViewModels { - public class GameboyConfigViewModel : DisposableViewModel + public partial class GameboyConfigViewModel : DisposableViewModel { - [Reactive] public GameboyConfig Config { get; set; } - [Reactive] public GameboyConfig OriginalConfig { get; set; } - [Reactive] public GameboyConfigTab SelectedTab { get; set; } = 0; + [ObservableProperty] public partial GameboyConfig Config { get; set; } + [ObservableProperty] public partial GameboyConfig OriginalConfig { get; set; } + [ObservableProperty] public partial GameboyConfigTab SelectedTab { get; set; } = 0; - public ReactiveCommand SetupPlayer { get; } - public ReactiveCommand SetupPlayer2 { get; } + public RelayCommand