diff --git a/src/cascadia/TerminalApp/SettingsTab.cpp b/src/cascadia/TerminalApp/SettingsTab.cpp index dd78edabf98..46a74ac703b 100644 --- a/src/cascadia/TerminalApp/SettingsTab.cpp +++ b/src/cascadia/TerminalApp/SettingsTab.cpp @@ -12,6 +12,7 @@ using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Core; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Microsoft::Terminal::Settings::Model; +using namespace winrt::Microsoft::Terminal::Settings::Editor; using namespace winrt::Windows::System; namespace winrt @@ -22,7 +23,7 @@ namespace winrt namespace winrt::TerminalApp::implementation { - SettingsTab::SettingsTab(winrt::Microsoft::Terminal::Settings::Editor::MainPage settingsUI) + SettingsTab::SettingsTab(MainPage settingsUI) { Content(settingsUI); @@ -31,6 +32,12 @@ namespace winrt::TerminalApp::implementation _CreateIcon(); } + void SettingsTab::UpdateSettings(CascadiaSettings settings) + { + auto settingsUI{ Content().as() }; + settingsUI.UpdateSettings(settings); + } + // Method Description: // - Focus the settings UI // Arguments: diff --git a/src/cascadia/TerminalApp/SettingsTab.h b/src/cascadia/TerminalApp/SettingsTab.h index 28399b426a8..1c83fc243ba 100644 --- a/src/cascadia/TerminalApp/SettingsTab.h +++ b/src/cascadia/TerminalApp/SettingsTab.h @@ -29,6 +29,7 @@ namespace winrt::TerminalApp::implementation public: SettingsTab(winrt::Microsoft::Terminal::Settings::Editor::MainPage settingsUI); + void UpdateSettings(Microsoft::Terminal::Settings::Model::CascadiaSettings settings); void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override; private: diff --git a/src/cascadia/TerminalApp/SettingsTab.idl b/src/cascadia/TerminalApp/SettingsTab.idl index 38d53e7b64e..deb45d4f155 100644 --- a/src/cascadia/TerminalApp/SettingsTab.idl +++ b/src/cascadia/TerminalApp/SettingsTab.idl @@ -7,5 +7,6 @@ namespace TerminalApp { [default_interface] runtimeclass SettingsTab : TabBase { + void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index e73383445f7..2b415c85981 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2263,6 +2263,10 @@ namespace winrt::TerminalApp::implementation // Force the TerminalTab to re-grab its currently active control's title. terminalTab->UpdateTitle(); } + else if (auto settingsTab = tab.try_as()) + { + settingsTab.UpdateSettings(_settings); + } } auto weakThis{ get_weak() }; diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp index b7b3ac8731d..cab77cd894e 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp +++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp @@ -38,7 +38,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { MainPage::MainPage(const CascadiaSettings& settings) : _settingsSource{ settings }, - _settingsClone{ settings }, + _settingsClone{ settings.Copy() }, _profileToNavItemMap{ winrt::single_threaded_map() } { InitializeComponent(); @@ -46,6 +46,79 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _InitializeProfilesList(); } + fire_and_forget MainPage::UpdateSettings(Model::CascadiaSettings settings) + { + _settingsSource = settings; + _settingsClone = settings.Copy(); + + co_await winrt::resume_foreground(Dispatcher()); + + // reconstruct our list of profiles + auto menuItems{ SettingsNav().MenuItems() }; + unsigned int i = 0; + while (i < menuItems.Size()) + { + if (const auto navViewItem{ menuItems.GetAt(i).try_as() }) + { + const auto tag{ navViewItem.Tag() }; + if (tag.try_as()) + { + // remove NavViewItem pointing to a Profile + menuItems.RemoveAt(i); + continue; + } + else if (const auto stringTag{ tag.try_as() }) + { + if (stringTag == addProfileTag) + { + // remove NavViewItem pointing to "Add Profile" + menuItems.RemoveAt(i); + continue; + } + } + } + ++i; + } + _InitializeProfilesList(); + + _RefreshCurrentPage(); + } + + void MainPage::_RefreshCurrentPage() + { + auto navigationMenu{ SettingsNav() }; + if (const auto selectedItem{ navigationMenu.SelectedItem() }) + { + if (const auto tag{ selectedItem.as().Tag() }) + { + if (const auto profile{ tag.try_as() }) + { + // check if the profile still exists + if (_settingsClone.FindProfile(profile.Guid())) + { + // Navigate to the page with the given profile + contentFrame().Navigate(xaml_typename(), winrt::make(profile, _settingsClone.GlobalSettings().ColorSchemes(), *this)); + return; + } + } + else if (const auto stringTag{ tag.try_as() }) + { + // navigate to the page with this tag + _Navigate(*stringTag); + return; + } + } + } + + // could not find the page we were on, fallback to first menu item + const auto firstItem{ navigationMenu.MenuItems().GetAt(0) }; + navigationMenu.SelectedItem(firstItem); + if (const auto tag{ navigationMenu.SelectedItem().as().Tag() }) + { + _Navigate(unbox_value(tag)); + } + } + void MainPage::SetHostingWindow(uint64_t hostingWindow) noexcept { _hostingHwnd.emplace(reinterpret_cast(hostingWindow)); @@ -166,6 +239,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } + void MainPage::SaveButton_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/) + { + _settingsClone.WriteSettingsToDisk(); + } + + void MainPage::ResetButton_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/) + { + _settingsClone = _settingsSource.Copy(); + _RefreshCurrentPage(); + } + void MainPage::_InitializeProfilesList() { // Manually create a NavigationViewItem for each profile @@ -181,7 +265,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // Top off (the end of the nav view) with the Add Profile item MUX::Controls::NavigationViewItem addProfileItem; addProfileItem.Content(box_value(RS_(L"Nav_AddNewProfile/Content"))); - addProfileItem.Tag(box_value(L"AddProfile")); + addProfileItem.Tag(box_value(addProfileTag)); addProfileItem.SelectsOnInvoked(false); FontIcon icon; diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.h b/src/cascadia/TerminalSettingsEditor/MainPage.h index ffb8e4894e7..20f633bb677 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.h +++ b/src/cascadia/TerminalSettingsEditor/MainPage.h @@ -13,30 +13,33 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation MainPage() = delete; MainPage(const Model::CascadiaSettings& settings); + fire_and_forget UpdateSettings(Model::CascadiaSettings settings); + void OpenJsonKeyDown(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& args); void OpenJsonTapped(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs const& args); void SettingsNav_Loaded(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args); void SettingsNav_ItemInvoked(Microsoft::UI::Xaml::Controls::NavigationView const& sender, Microsoft::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs const& args); + void SaveButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args); + void ResetButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args); void SetHostingWindow(uint64_t hostingWindow) noexcept; bool TryPropagateHostingWindow(IInspectable object) noexcept; - TYPED_EVENT(OpenJson, winrt::Windows::Foundation::IInspectable, winrt::Microsoft::Terminal::Settings::Model::SettingsTarget); + TYPED_EVENT(OpenJson, Windows::Foundation::IInspectable, Model::SettingsTarget); private: - // XAML should data-bind to the _settingsClone - // When "save" is pressed, _settingsSource = _settingsClone - winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings _settingsSource; - winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings _settingsClone; - winrt::Windows::Foundation::Collections::IMap _profileToNavItemMap; + Model::CascadiaSettings _settingsSource; + Model::CascadiaSettings _settingsClone; + winrt::Windows::Foundation::Collections::IMap _profileToNavItemMap; std::optional _hostingHwnd; void _InitializeProfilesList(); void _CreateAndNavigateToNewProfile(const uint32_t index); - winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem _CreateProfileNavViewItem(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile); + winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem _CreateProfileNavViewItem(const Model::Profile& profile); void _Navigate(hstring clickedItemTag); + void _RefreshCurrentPage(); }; } diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.idl b/src/cascadia/TerminalSettingsEditor/MainPage.idl index d603cbc9647..cd35a8aa230 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.idl +++ b/src/cascadia/TerminalSettingsEditor/MainPage.idl @@ -16,6 +16,7 @@ namespace Microsoft.Terminal.Settings.Editor { MainPage(Microsoft.Terminal.Settings.Model.CascadiaSettings settings); + void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings); event Windows.Foundation.TypedEventHandler OpenJson; // Due to the aforementioned bug, we can't use IInitializeWithWindow _here_ either. diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.xaml b/src/cascadia/TerminalSettingsEditor/MainPage.xaml index 4b7079f6647..184b3387a03 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.xaml +++ b/src/cascadia/TerminalSettingsEditor/MainPage.xaml @@ -122,11 +122,13 @@ the MIT License. See LICENSE in the project root for license information. -->