Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement MVVM for the Launch page #13377

Merged
4 commits merged into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 1 addition & 44 deletions src/cascadia/TerminalSettingsEditor/Launch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "pch.h"
#include "Launch.h"
#include "Launch.g.cpp"
#include "LaunchPageNavigationState.g.cpp"
#include "EnumEntry.h"

using namespace winrt::Windows::UI::Xaml::Navigation;
Expand All @@ -17,15 +16,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
InitializeComponent();

INITIALIZE_BINDABLE_ENUM_SETTING(FirstWindowPreference, FirstWindowPreference, FirstWindowPreference, L"Globals_FirstWindowPreference", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
// More options were added to the JSON mapper when the enum was made into [Flags]
// but we want to preserve the previous set of options in the UI.
_LaunchModeList.RemoveAt(7); // maximizedFullscreenFocus
_LaunchModeList.RemoveAt(6); // fullscreenFocus
_LaunchModeList.RemoveAt(3); // maximizedFullscreen
INITIALIZE_BINDABLE_ENUM_SETTING(WindowingBehavior, WindowingMode, WindowingMode, L"Globals_WindowingBehavior", L"Content");

// BODGY
PankajBhojwani marked this conversation as resolved.
Show resolved Hide resolved
// Xaml code generator for x:Bind to this will fail to find UnloadObject() on Launch class.
// To work around, check it ourselves on construction and FindName to force load.
Expand All @@ -38,39 +28,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

void Launch::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::LaunchPageNavigationState>();
}

IInspectable Launch::CurrentDefaultProfile()
{
const auto defaultProfileGuid{ _State.Settings().GlobalSettings().DefaultProfile() };
return winrt::box_value(_State.Settings().FindProfile(defaultProfileGuid));
}

void Launch::CurrentDefaultProfile(const IInspectable& value)
{
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
_State.Settings().GlobalSettings().DefaultProfile(profile.Guid());
}

winrt::Windows::Foundation::Collections::IObservableVector<IInspectable> Launch::DefaultProfiles() const
{
const auto allProfiles = _State.Settings().AllProfiles();

std::vector<IInspectable> profiles;
profiles.reserve(allProfiles.Size());

// Remove profiles from the selection which have been explicitly deleted.
// We do want to show hidden profiles though, as they are just hidden
// from menus, but still work as the startup profile for instance.
for (const auto& profile : allProfiles)
{
if (!profile.Deleted())
{
profiles.emplace_back(profile);
}
}

return winrt::single_threaded_observable_vector(std::move(profiles));
_ViewModel = e.Parameter().as<Editor::LaunchViewModel>();
}
}
21 changes: 2 additions & 19 deletions src/cascadia/TerminalSettingsEditor/Launch.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,19 @@
#pragma once

#include "Launch.g.h"
#include "LaunchPageNavigationState.g.h"
#include "Utils.h"

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct LaunchPageNavigationState : LaunchPageNavigationStateT<LaunchPageNavigationState>
{
public:
LaunchPageNavigationState(const Model::CascadiaSettings& settings) :
_Settings{ settings } {}

WINRT_PROPERTY(Model::CascadiaSettings, Settings, nullptr)
};

struct Launch : public HasScrollViewer<Launch>, LaunchT<Launch>
{
public:
Launch();

void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);

IInspectable CurrentDefaultProfile();
void CurrentDefaultProfile(const IInspectable& value);
winrt::Windows::Foundation::Collections::IObservableVector<IInspectable> DefaultProfiles() const;

WINRT_PROPERTY(Editor::LaunchPageNavigationState, State, nullptr);

GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, State().Settings().GlobalSettings().FirstWindowPreference);
GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, State().Settings().GlobalSettings().LaunchMode);
GETSET_BINDABLE_ENUM_SETTING(WindowingBehavior, Model::WindowingMode, State().Settings().GlobalSettings().WindowingBehavior);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(Editor::LaunchViewModel, ViewModel, _PropertyChangedHandlers, nullptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the view model is observable, do we need to make the view inherit from INotifyPropertyChanged?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question... It works without it so I think not?

};
}

Expand Down
22 changes: 2 additions & 20 deletions src/cascadia/TerminalSettingsEditor/Launch.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,13 @@
// Licensed under the MIT license.

import "EnumEntry.idl";
import "LaunchViewModel.idl";

namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass LaunchPageNavigationState
{
Microsoft.Terminal.Settings.Model.CascadiaSettings Settings;
};

[default_interface] runtimeclass Launch : Windows.UI.Xaml.Controls.Page
{
Launch();
LaunchPageNavigationState State { get; };

IInspectable CurrentDefaultProfile;
// I wish this was a IObservableVector<Microsoft.Terminal.Settings.Model.Profile>, but:
// https://github.com/microsoft/microsoft-ui-xaml/issues/5395
IObservableVector<IInspectable> DefaultProfiles { get; };

IInspectable CurrentFirstWindowPreference;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FirstWindowPreferenceList { get; };

IInspectable CurrentLaunchMode;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> LaunchModeList { get; };

IInspectable CurrentWindowingBehavior;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> WindowingBehaviorList { get; };
LaunchViewModel ViewModel { get; };
}
}
26 changes: 13 additions & 13 deletions src/cascadia/TerminalSettingsEditor/Launch.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<!-- Default Profile -->
<local:SettingContainer x:Uid="Globals_DefaultProfile">
<ComboBox x:Name="DefaultProfile"
ItemsSource="{x:Bind DefaultProfiles}"
SelectedItem="{x:Bind CurrentDefaultProfile, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.DefaultProfiles}"
SelectedItem="{x:Bind ViewModel.CurrentDefaultProfile, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="SettingsModel:Profile">
Expand Down Expand Up @@ -73,8 +73,8 @@
x:Uid="Globals_DefaultTerminal"
x:Load="false">
<ComboBox x:Name="DefaultTerminal"
ItemsSource="{x:Bind State.Settings.DefaultTerminals}"
SelectedItem="{x:Bind State.Settings.CurrentDefaultTerminal, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.Settings.DefaultTerminals}"
SelectedItem="{x:Bind ViewModel.Settings.CurrentDefaultTerminal, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
Expand Down Expand Up @@ -137,16 +137,16 @@

<!-- Start on User Login -->
<local:SettingContainer x:Uid="Globals_StartOnUserLogin">
<ToggleSwitch IsOn="{x:Bind State.Settings.GlobalSettings.StartOnUserLogin, Mode=TwoWay}"
<ToggleSwitch IsOn="{x:Bind ViewModel.Settings.GlobalSettings.StartOnUserLogin, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

<!-- First Window Behavior -->
<local:SettingContainer x:Uid="Globals_FirstWindowPreference">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind FirstWindowPreferenceList}"
SelectedItem="{x:Bind CurrentFirstWindowPreference, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.FirstWindowPreferenceList}"
SelectedItem="{x:Bind ViewModel.CurrentFirstWindowPreference, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

Expand All @@ -156,17 +156,17 @@
x:Uid="Globals_LaunchMode">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind LaunchModeList}"
SelectedItem="{x:Bind CurrentLaunchMode, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

<!-- Windowing Behavior -->
<local:SettingContainer x:Uid="Globals_WindowingBehavior">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind WindowingBehaviorList}"
SelectedItem="{x:Bind CurrentWindowingBehavior, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.WindowingBehaviorList}"
SelectedItem="{x:Bind ViewModel.CurrentWindowingBehavior, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

Expand All @@ -192,7 +192,7 @@
Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource LaunchSizeNumberBoxStyle}"
Value="{x:Bind State.Settings.GlobalSettings.InitialCols, Mode=TwoWay}" />
Value="{x:Bind ViewModel.Settings.GlobalSettings.InitialCols, Mode=TwoWay}" />
<TextBlock x:Uid="Globals_InitialRows"
Grid.Row="1"
Grid.Column="0"
Expand All @@ -203,7 +203,7 @@
Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource LaunchSizeNumberBoxStyle}"
Value="{x:Bind State.Settings.GlobalSettings.InitialRows, Mode=TwoWay}" />
Value="{x:Bind ViewModel.Settings.GlobalSettings.InitialRows, Mode=TwoWay}" />
</Grid>
</local:SettingContainer>
</StackPanel>
Expand Down
65 changes: 65 additions & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "pch.h"
#include "LaunchViewModel.h"
#include "LaunchViewModel.g.cpp"
#include "EnumEntry.h"

using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::Settings::Model;

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
LaunchViewModel::LaunchViewModel(Model::CascadiaSettings settings) :
_Settings{ settings }
{
INITIALIZE_BINDABLE_ENUM_SETTING(FirstWindowPreference, FirstWindowPreference, FirstWindowPreference, L"Globals_FirstWindowPreference", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
// More options were added to the JSON mapper when the enum was made into [Flags]
// but we want to preserve the previous set of options in the UI.
_LaunchModeList.RemoveAt(7); // maximizedFullscreenFocus
_LaunchModeList.RemoveAt(6); // fullscreenFocus
_LaunchModeList.RemoveAt(3); // maximizedFullscreen
INITIALIZE_BINDABLE_ENUM_SETTING(WindowingBehavior, WindowingMode, WindowingMode, L"Globals_WindowingBehavior", L"Content");
}

Model::CascadiaSettings LaunchViewModel::Settings() const
{
return _Settings;
}

winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentDefaultProfile()
{
const auto defaultProfileGuid{ _Settings.GlobalSettings().DefaultProfile() };
return winrt::box_value(_Settings.FindProfile(defaultProfileGuid));
}

void LaunchViewModel::CurrentDefaultProfile(const IInspectable& value)
{
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
_Settings.GlobalSettings().DefaultProfile(profile.Guid());
}

winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable> LaunchViewModel::DefaultProfiles() const
{
const auto allProfiles = _Settings.AllProfiles();

std::vector<IInspectable> profiles;
profiles.reserve(allProfiles.Size());

// Remove profiles from the selection which have been explicitly deleted.
// We do want to show hidden profiles though, as they are just hidden
// from menus, but still work as the startup profile for instance.
for (const auto& profile : allProfiles)
{
if (!profile.Deleted())
{
profiles.emplace_back(profile);
}
}

return winrt::single_threaded_observable_vector(std::move(profiles));
}
}
34 changes: 34 additions & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#pragma once

#include "LaunchViewModel.g.h"
#include "ViewModelHelpers.h"
#include "Utils.h"

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct LaunchViewModel : LaunchViewModelT<LaunchViewModel>, ViewModelHelper<LaunchViewModel>
{
public:
LaunchViewModel(Model::CascadiaSettings settings);
Model::CascadiaSettings Settings() const;

IInspectable CurrentDefaultProfile();
void CurrentDefaultProfile(const IInspectable& value);
winrt::Windows::Foundation::Collections::IObservableVector<IInspectable> DefaultProfiles() const;

GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, _Settings.GlobalSettings().FirstWindowPreference);
GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, _Settings.GlobalSettings().LaunchMode);
GETSET_BINDABLE_ENUM_SETTING(WindowingBehavior, Model::WindowingMode, _Settings.GlobalSettings().WindowingBehavior);

private:
Model::CascadiaSettings _Settings;
};
};

namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(LaunchViewModel);
}
27 changes: 27 additions & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import "EnumEntry.idl";

namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass LaunchViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
LaunchViewModel(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
Microsoft.Terminal.Settings.Model.CascadiaSettings Settings { get; };

IInspectable CurrentDefaultProfile;
// I wish this was a IObservableVector<Microsoft.Terminal.Settings.Model.Profile>, but:
// https://github.com/microsoft/microsoft-ui-xaml/issues/5395
IObservableVector<IInspectable> DefaultProfiles { get; };

IInspectable CurrentFirstWindowPreference;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FirstWindowPreferenceList { get; };

IInspectable CurrentLaunchMode;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> LaunchModeList { get; };

IInspectable CurrentWindowingBehavior;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> WindowingBehaviorList { get; };
}
}
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsEditor/MainPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "GlobalAppearance.h"
#include "ColorSchemes.h"
#include "AddProfile.h"
#include "LaunchViewModel.h"
#include "..\types\inc\utils.hpp"

#include <LibraryResources.h>
Expand Down Expand Up @@ -337,7 +338,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

if (clickedItemTag == launchTag)
{
contentFrame().Navigate(xaml_typename<Editor::Launch>(), winrt::make<LaunchPageNavigationState>(_settingsClone));
contentFrame().Navigate(xaml_typename<Editor::Launch>(), winrt::make<LaunchViewModel>(_settingsClone));
const auto crumb = winrt::make<Breadcrumb>(box_value(clickedItemTag), RS_(L"Nav_Launch/Content"), BreadcrumbSubPage::None);
_breadcrumbs.Append(crumb);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
<DependentUpon>ProfileViewModel.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="LaunchViewModel.h">
<DependentUpon>LaunchViewModel.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="Profiles_Base.h">
<DependentUpon>Profiles_Base.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down Expand Up @@ -193,6 +197,10 @@
<DependentUpon>ProfileViewModel.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="LaunchViewModel.cpp">
<DependentUpon>LaunchViewModel.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="Profiles_Base.cpp">
<DependentUpon>Profiles_Base.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down Expand Up @@ -263,6 +271,7 @@
<SubType>Code</SubType>
</Midl>
<Midl Include="ProfileViewModel.idl" />
<Midl Include="LaunchViewModel.idl" />
<Midl Include="Profiles_Base.idl">
<DependentUpon>Profiles_Base.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down
Loading