From 6ceccb3018973ff121ba90a0efde749d432fd59f Mon Sep 17 00:00:00 2001 From: Pete Brown Date: Fri, 14 Feb 2025 00:41:16 -0500 Subject: [PATCH 1/3] Settings app updates (in progress) --- build/staging/version/BundleInfo.wxi | 2 +- .../version/WindowsMidiServicesVersion.cs | 4 +- .../version/WindowsMidiServicesVersion.h | 4 +- .../basics/client-basics-cpp.vcxproj | 2 +- samples/cpp-winrt/basics/packages.config | 2 +- .../loopback-endpoints-cpp.vcxproj | 2 +- .../loopback-endpoints/packages.config | 2 +- samples/cpp-winrt/send-speed/packages.config | 2 +- .../send-speed/send-speed-cpp.vcxproj | 2 +- .../simple-app-to-app-midi/packages.config | 2 +- .../simple-app-to-app-cpp.vcxproj | 2 +- .../static-enum-endpoints/packages.config | 2 +- .../static-enum-endpoints-cpp.vcxproj | 2 +- .../cpp-winrt/watch-endpoints/packages.config | 2 +- .../watch-endpoints-cpp.vcxproj | 2 +- src/app-sdk/mididiag/mididiag.vcxproj | 2 +- src/app-sdk/mididiag/packages.config | 2 +- src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj | 2 +- src/app-sdk/midimdnsinfo/packages.config | 2 +- src/app-sdk/midiusbinfo/midiusbinfo.vcxproj | 2 +- src/app-sdk/midiusbinfo/packages.config | 2 +- .../winrt/MidiLoopbackEndpointManager.cpp | 91 ++++++++++++++ .../winrt/MidiLoopbackEndpointManager.h | 11 ++ .../winrt/MidiLoopbackEndpointManager.idl | 12 ++ .../Microsoft.Midi.Settings/App.xaml.cs | 7 ++ .../Services/IMidiConfigFileService.cs | 14 +++ .../Microsoft.Midi.Settings.csproj | 4 + .../FirstRunExperiencePage.xaml | 103 ++++++++++++++++ .../FirstRunExperiencePage.xaml.cs | 60 ++++++++++ .../FirstRunExperienceViewModel.cs | 92 +++++++++++++++ .../Services/MidiConfigFileService.cs | 111 ++++++++++++++++++ .../Services/PageService.cs | 3 + .../Styles/TextBlock.xaml | 17 ++- .../ViewModels/HomeViewModel.cs | 38 ++++++ .../Views/HomePage.xaml | 28 +++++ 35 files changed, 613 insertions(+), 24 deletions(-) create mode 100644 src/user-tools/midi-settings/Microsoft.Midi.Settings/Contracts/Services/IMidiConfigFileService.cs create mode 100644 src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml create mode 100644 src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml.cs create mode 100644 src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperienceViewModel.cs create mode 100644 src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/MidiConfigFileService.cs diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi index d20880a59..530615462 100644 --- a/build/staging/version/BundleInfo.wxi +++ b/build/staging/version/BundleInfo.wxi @@ -1,4 +1,4 @@ - + diff --git a/build/staging/version/WindowsMidiServicesVersion.cs b/build/staging/version/WindowsMidiServicesVersion.cs index fc657e903..40eb6b432 100644 --- a/build/staging/version/WindowsMidiServicesVersion.cs +++ b/build/staging/version/WindowsMidiServicesVersion.cs @@ -6,12 +6,12 @@ public static class MidiBuildInformation { public const string Source = "GitHub Preview"; public const string Name = "Customer Preview 2"; - public const string BuildFullVersion = "1.0.3-preview-11.250213-52"; + public const string BuildFullVersion = "1.0.3-preview-11.250213-2017"; public const string VersionMajor = "1"; public const string VersionMinor = "0"; public const string VersionRevision = "3"; public const string VersionDateNumber = "250213"; - public const string VersionTimeNumber = "52"; + public const string VersionTimeNumber = "2017"; } } diff --git a/build/staging/version/WindowsMidiServicesVersion.h b/build/staging/version/WindowsMidiServicesVersion.h index a79945daf..c0ef7c1d7 100644 --- a/build/staging/version/WindowsMidiServicesVersion.h +++ b/build/staging/version/WindowsMidiServicesVersion.h @@ -5,12 +5,12 @@ #define WINDOWS_MIDI_SERVICES_BUILD_SOURCE L"GitHub Preview" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_NAME L"Customer Preview 2" -#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.3-preview-11.250213-52" +#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.3-preview-11.250213-2017" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MAJOR L"1" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MINOR L"0" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_REVISION L"3" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_DATE_NUMBER L"250213" -#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"52" +#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"2017" #endif diff --git a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj index 1276e2a45..ec75ccd15 100644 --- a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj +++ b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true false diff --git a/samples/cpp-winrt/basics/packages.config b/samples/cpp-winrt/basics/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/basics/packages.config +++ b/samples/cpp-winrt/basics/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj index feca9dfa5..1961c29cc 100644 --- a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/samples/cpp-winrt/loopback-endpoints/packages.config b/samples/cpp-winrt/loopback-endpoints/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/loopback-endpoints/packages.config +++ b/samples/cpp-winrt/loopback-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/send-speed/packages.config b/samples/cpp-winrt/send-speed/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/send-speed/packages.config +++ b/samples/cpp-winrt/send-speed/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj index 69024004a..d6d1c7490 100644 --- a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj +++ b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/samples/cpp-winrt/simple-app-to-app-midi/packages.config b/samples/cpp-winrt/simple-app-to-app-midi/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/simple-app-to-app-midi/packages.config +++ b/samples/cpp-winrt/simple-app-to-app-midi/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj index 722d32cab..89351f1b1 100644 --- a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj +++ b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/samples/cpp-winrt/static-enum-endpoints/packages.config b/samples/cpp-winrt/static-enum-endpoints/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/static-enum-endpoints/packages.config +++ b/samples/cpp-winrt/static-enum-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj index d33d45eb7..f15f2ffd9 100644 --- a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/samples/cpp-winrt/watch-endpoints/packages.config b/samples/cpp-winrt/watch-endpoints/packages.config index 29bfea9f4..2aa14b3e8 100644 --- a/samples/cpp-winrt/watch-endpoints/packages.config +++ b/samples/cpp-winrt/watch-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj index 01344d9e6..7d1199490 100644 --- a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/src/app-sdk/mididiag/mididiag.vcxproj b/src/app-sdk/mididiag/mididiag.vcxproj index 96c5aeb7b..6ac175893 100644 --- a/src/app-sdk/mididiag/mididiag.vcxproj +++ b/src/app-sdk/mididiag/mididiag.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/src/app-sdk/mididiag/packages.config b/src/app-sdk/mididiag/packages.config index d50f79bbc..ee7b132fa 100644 --- a/src/app-sdk/mididiag/packages.config +++ b/src/app-sdk/mididiag/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj index 02ced8544..3e886622d 100644 --- a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj +++ b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/src/app-sdk/midimdnsinfo/packages.config b/src/app-sdk/midimdnsinfo/packages.config index d50f79bbc..ee7b132fa 100644 --- a/src/app-sdk/midimdnsinfo/packages.config +++ b/src/app-sdk/midimdnsinfo/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj b/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj index ed6d716f2..01e1fb4a1 100644 --- a/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj +++ b/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-52 + Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250213-2017 true true true diff --git a/src/app-sdk/midiusbinfo/packages.config b/src/app-sdk/midiusbinfo/packages.config index d50f79bbc..ee7b132fa 100644 --- a/src/app-sdk/midiusbinfo/packages.config +++ b/src/app-sdk/midiusbinfo/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/winrt/MidiLoopbackEndpointManager.cpp b/src/app-sdk/winrt/MidiLoopbackEndpointManager.cpp index d2d541a88..2c8c8d3a5 100644 --- a/src/app-sdk/winrt/MidiLoopbackEndpointManager.cpp +++ b/src/app-sdk/winrt/MidiLoopbackEndpointManager.cpp @@ -111,4 +111,95 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Loopback::implem return result; } + + _Use_decl_annotations_ + midi2::MidiEndpointDeviceInformation MidiLoopbackEndpointManager::GetAssociatedLoopbackEndpoint( + midi2::MidiEndpointDeviceInformation const& loopbackEndpoint + ) + { + auto domain = midi2::MidiEndpointDeviceInformation::FindAll(); + + return GetAssociatedLoopbackEndpoint(loopbackEndpoint, domain); + } + + + _Use_decl_annotations_ + midi2::MidiEndpointDeviceInformation MidiLoopbackEndpointManager::GetAssociatedLoopbackEndpointForId( + winrt::hstring loopbackEndpointId + ) + { + auto cleanId = internal::NormalizeEndpointInterfaceIdHStringCopy(loopbackEndpointId); + + auto info = midi2::MidiEndpointDeviceInformation::CreateFromEndpointDeviceId(cleanId); + + return GetAssociatedLoopbackEndpoint(info); + } + + + _Use_decl_annotations_ + midi2::MidiEndpointDeviceInformation MidiLoopbackEndpointManager::GetAssociatedLoopbackEndpoint( + midi2::MidiEndpointDeviceInformation const& loopbackEndpoint, + collections::IIterable endpointsToSearch) + { + if (loopbackEndpoint == nullptr) + { + return nullptr; + } + + if (endpointsToSearch == nullptr) + { + return nullptr; + } + + auto transportId = loopbackEndpoint.GetTransportSuppliedInfo().TransportId; + + if (transportId != TransportId()) + { + // not a loopback endpoint + return nullptr; + } + + // get the endpoint's association id + + if (loopbackEndpoint.Properties().HasKey(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator) && + loopbackEndpoint.Properties().Lookup(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator) != nullptr) + { + auto associator = winrt::unbox_value(loopbackEndpoint.Properties().Lookup(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator)); + + // find the other endpoint that has this associator + // this is wasteful to get everything and then iterate, but there's + // no AQS way to search using our custom DEVPKEY properties + + winrt::hstring query{ MIDI_ENDPOINT_DEVICE_AQS_FILTER }; + + for (auto const& ep : endpointsToSearch) + { + auto id = internal::NormalizeEndpointInterfaceIdHStringCopy(ep.EndpointDeviceId()); + + // don't process the endpoint that was passed in, of course + if (id != loopbackEndpoint.EndpointDeviceId()) + { + if (ep.Properties().HasKey(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator) && + ep.Properties().Lookup(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator) != nullptr) + { + auto thisAssociator = winrt::unbox_value(loopbackEndpoint.Properties().Lookup(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator)); + + if (!thisAssociator.empty()) + { + // return the endpoint if it has the matching association id + if (thisAssociator == associator) + { + // create the endpoint + return MidiEndpointDeviceInformation::CreateFromEndpointDeviceId(id); + } + } + } + } + } + } + + return nullptr; + + } + } diff --git a/src/app-sdk/winrt/MidiLoopbackEndpointManager.h b/src/app-sdk/winrt/MidiLoopbackEndpointManager.h index 5f658a3a5..52ee7299e 100644 --- a/src/app-sdk/winrt/MidiLoopbackEndpointManager.h +++ b/src/app-sdk/winrt/MidiLoopbackEndpointManager.h @@ -25,6 +25,17 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Loopback::implem static bool RemoveTransientLoopbackEndpoints( _In_ loop::MidiLoopbackEndpointRemovalConfig deletionConfig); + + static midi2::MidiEndpointDeviceInformation GetAssociatedLoopbackEndpointForId( + _In_ winrt::hstring loopbackEndpointId); + + static midi2::MidiEndpointDeviceInformation GetAssociatedLoopbackEndpoint( + _In_ midi2::MidiEndpointDeviceInformation const& loopbackEndpoint, + _In_ collections::IIterable endpointsToSearch); + + static midi2::MidiEndpointDeviceInformation GetAssociatedLoopbackEndpoint( + _In_ midi2::MidiEndpointDeviceInformation const& loopbackEndpoint); + }; } namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Loopback::factory_implementation diff --git a/src/app-sdk/winrt/MidiLoopbackEndpointManager.idl b/src/app-sdk/winrt/MidiLoopbackEndpointManager.idl index 8c0d62adc..5eed7d532 100644 --- a/src/app-sdk/winrt/MidiLoopbackEndpointManager.idl +++ b/src/app-sdk/winrt/MidiLoopbackEndpointManager.idl @@ -11,6 +11,8 @@ import "MidiLoopbackEndpointCreationResult.idl"; import "MidiLoopbackEndpointCreationConfig.idl"; import "MidiLoopbackEndpointRemovalConfig.idl"; +import "MidiEndpointDeviceInformation.idl"; + namespace Microsoft.Windows.Devices.Midi2.Endpoints.Loopback { static runtimeclass MidiLoopbackEndpointManager @@ -24,6 +26,16 @@ namespace Microsoft.Windows.Devices.Midi2.Endpoints.Loopback static Boolean RemoveTransientLoopbackEndpoints( MidiLoopbackEndpointRemovalConfig removalConfig); + + static Microsoft.Windows.Devices.Midi2.MidiEndpointDeviceInformation GetAssociatedLoopbackEndpointForId( + String loopbackEndpointId); + + static Microsoft.Windows.Devices.Midi2.MidiEndpointDeviceInformation GetAssociatedLoopbackEndpoint( + Microsoft.Windows.Devices.Midi2.MidiEndpointDeviceInformation loopbackEndpoint, + IIterable endpointsToSearch); + + static Microsoft.Windows.Devices.Midi2.MidiEndpointDeviceInformation GetAssociatedLoopbackEndpoint( + Microsoft.Windows.Devices.Midi2.MidiEndpointDeviceInformation loopbackEndpoint); } } diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/App.xaml.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/App.xaml.cs index 5abdbc997..8d9491c00 100644 --- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/App.xaml.cs +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/App.xaml.cs @@ -71,6 +71,10 @@ public App() services.AddSingleton(); services.AddSingleton(); + // MIDI Services + services.AddSingleton(); + + // Views and ViewModels services.AddTransient(); services.AddTransient(); @@ -147,6 +151,9 @@ public App() services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + // Configuration services.Configure(context.Configuration.GetSection(nameof(LocalSettingsOptions))); }). diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Contracts/Services/IMidiConfigFileService.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Contracts/Services/IMidiConfigFileService.cs new file mode 100644 index 000000000..4f5d1a5d4 --- /dev/null +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Contracts/Services/IMidiConfigFileService.cs @@ -0,0 +1,14 @@ +namespace Microsoft.Midi.Settings.Contracts.Services; + +public interface IMidiConfigFileService +{ + string GetDefaultConfigName(); + string CleanupConfigName(string configName); + string BuildConfigFileName(string configName); + string GetConfigFilePath(); + + bool ConfigExists(string configName); + + bool CreateNewConfigFile(string configName); + bool SetCurrentConfig(string configName); +} diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj index c4bcae7d2..ce748254a 100644 --- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj @@ -69,6 +69,7 @@ + @@ -167,6 +168,9 @@ Never + + MSBuild:Compile + MSBuild:Compile diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml new file mode 100644 index 000000000..935cdf637 --- /dev/null +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml.cs new file mode 100644 index 000000000..ba398456c --- /dev/null +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperiencePage.xaml.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using Microsoft.Midi.Settings.Contracts.ViewModels; +using Microsoft.Midi.Settings.ViewModels; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace Microsoft.Midi.Settings.Views +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class FirstRunExperiencePage : Page + { + public FirstRunExperienceViewModel ViewModel + { + get; + } + + + public FirstRunExperiencePage() + { + ViewModel = App.GetService(); + + Loaded += FirstRunExperiencePage_Loaded; + + this.InitializeComponent(); + } + + private void FirstRunExperiencePage_Loaded(object sender, RoutedEventArgs e) + { + ShowFirstStep(); + } + + private async void ShowFirstStep() + { + var result = await Dialog_CreateConfigFile.ShowAsync(); + + + } + + + + + + } +} diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperienceViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperienceViewModel.cs new file mode 100644 index 000000000..f4fce1d20 --- /dev/null +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Sections/First Run Experience/FirstRunExperienceViewModel.cs @@ -0,0 +1,92 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Microsoft.Midi.Settings.Contracts.Services; +using Microsoft.Midi.Settings.Contracts.ViewModels; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Microsoft.Midi.Settings.ViewModels +{ + public class FirstRunExperienceViewModel : ObservableRecipient + { + private IMidiConfigFileService m_configFileService; + + private string m_configName; + public string ConfigName + { + get => m_configName; + set + { + m_configName = m_configFileService.CleanupConfigName(value); + + UpdateConfigFileName(); + + OnPropertyChanged("ConfigName"); + OnPropertyChanged("ConfigFileName"); + } + } + + public string ConfigFileName + { + get; private set; + } + + public string ConfigFileLocation + { + get + { + return m_configFileService.GetConfigFilePath(); + } + } + + + public ICommand CreateConfigFileCommand + { + get; + } + + + private void UpdateConfigFileName() + { + ConfigFileName = m_configFileService.BuildConfigFileName(ConfigName); + } + + public FirstRunExperienceViewModel(IMidiConfigFileService configService) + { + m_configFileService = configService; + m_configName = m_configFileService.GetDefaultConfigName(); + + UpdateConfigFileName(); + + CreateConfigFileCommand = new RelayCommand(() => + { + if (m_configFileService.CreateNewConfigFile(ConfigName)) + { + m_configFileService.SetCurrentConfig(ConfigName); + } + else + { + // TODO: show an error + + + } + }); + + + } + + + + + + + + + } +} diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/MidiConfigFileService.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/MidiConfigFileService.cs new file mode 100644 index 000000000..c71b9d296 --- /dev/null +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/MidiConfigFileService.cs @@ -0,0 +1,111 @@ +using Microsoft.Midi.Settings.Contracts.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Midi.Settings.Services +{ + class MidiConfigFileService : IMidiConfigFileService + { + private const string DefaultConfigurationName = "Default"; + private const string ConfigExtension = ".midiconfig.json"; + private const string ConfigFileLocation = @"%allusersprofile%\Microsoft\MIDI"; + + private string m_currentConfigName; + private string m_currentConfigFileName; + + public string GetDefaultConfigName() + { + return DefaultConfigurationName; + } + + public string BuildConfigFileName(string configName) + { + var cleanedConfigurationName = CleanupConfigName(configName); + + cleanedConfigurationName = string.Join("", cleanedConfigurationName.Split(Path.GetInvalidFileNameChars())); + cleanedConfigurationName = string.Join("", cleanedConfigurationName.Split(Path.GetInvalidPathChars())); + + return cleanedConfigurationName + ConfigExtension; + } + + public string CleanupConfigName(string configName) + { + var cleanedConfigurationName = string.Join("", configName.Split(['.', ':', ';', '`', '%', '@', '#', '&', '$', '+', ',', '"', '\'', '{', '}', '[', ']'])).Trim(); + + if (string.IsNullOrEmpty(cleanedConfigurationName)) + { + return DefaultConfigurationName; + } + + return cleanedConfigurationName; + } + + public bool ConfigExists(string configName) + { + var fullPath = Path.Combine(ConfigFileLocation, BuildConfigFileName(configName)); + + return Path.Exists(fullPath); + } + + public bool CreateNewConfigFile(string configName) + { + // TODO + + // cleanup the names + + // create the file + + if (ConfigExists(configName)) + { + return false; + } + + // create the config header + + // create section for transports + + + + + throw new NotImplementedException(); + } + + public bool SetCurrentConfig(string configName) + { + // Switch to this file as the current config, and so set the registry entry for the file + + + + + return false; + } + + public string GetConfigFilePath() + { + return Environment.ExpandEnvironmentVariables(ConfigFileLocation); + } + + public string GetCurrentConfigName() + { + return m_currentConfigName; + } + + public string GetCurrentConfigFileName() + { + return m_currentConfigFileName; + } + + + + // TODO: Methods to add common functions to the config, like a new endpoint name, or new loopbacks + // expose strongly typed stuff here, and let this class take care of the details within + // each discrete function should result in a commit to the file. + + + + + } +} diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs index f86c08feb..992b31490 100644 --- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs @@ -44,6 +44,9 @@ public PageService() Configure(); Configure(); + Configure(); + + Configure(); } diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Styles/TextBlock.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Styles/TextBlock.xaml index ab8811963..58e2e849d 100644 --- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Styles/TextBlock.xaml +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Styles/TextBlock.xaml @@ -2,7 +2,22 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - + + + + + +