diff --git a/src/cascadia/TerminalSettingsEditor/Appearances.h b/src/cascadia/TerminalSettingsEditor/Appearances.h index e8b1cac6c3c..1e0528b0946 100644 --- a/src/cascadia/TerminalSettingsEditor/Appearances.h +++ b/src/cascadia/TerminalSettingsEditor/Appearances.h @@ -233,7 +233,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::Foundation::Collections::IObservableVector _FontFeaturesNames; std::wstring _fontNameFilter; bool _ShowAllFonts = false; - bool _suppressFontFaceBoxList = false; static void _ViewModelChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e); diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp index 977e6d1bece..0836dbac13b 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp @@ -29,7 +29,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::Foundation::Collections::IObservableVector ProfileViewModel::_MonospaceFontList{ nullptr }; Windows::Foundation::Collections::IObservableVector ProfileViewModel::_FontList{ nullptr }; - Windows::Foundation::Collections::IVector ProfileViewModel::_BuiltInIcons{ nullptr }; + Windows::Foundation::Collections::IObservableVector ProfileViewModel::_BuiltInIcons{ nullptr }; static constexpr std::wstring_view HideIconValue{ L"none" }; @@ -114,7 +114,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } else if (viewModelProperty == L"CurrentBuiltInIcon") { - IconPath(unbox_value(_CurrentBuiltInIcon.as().EnumValue())); + IconPath(unbox_value(_CurrentBuiltInIcon.EnumValue())); } else if (viewModelProperty == L"CurrentEmojiIcon") { @@ -193,12 +193,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void ProfileViewModel::_UpdateBuiltInIcons() { - std::vector builtInIcons; + std::vector builtInIcons; for (auto& [val, name] : s_SegoeFluentIcons) { builtInIcons.emplace_back(make(hstring{ name }, box_value(val))); } - _BuiltInIcons = single_threaded_vector(std::move(builtInIcons)); + _BuiltInIcons = single_threaded_observable_vector(std::move(builtInIcons)); } void ProfileViewModel::_DeduceCurrentIconType() @@ -236,7 +236,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation for (uint32_t i = 0; i < _BuiltInIcons.Size(); i++) { const auto& builtIn = _BuiltInIcons.GetAt(i); - if (profileIcon == unbox_value(builtIn.as().EnumValue())) + if (profileIcon == unbox_value(builtIn.EnumValue())) { _CurrentBuiltInIcon = builtIn; return; @@ -695,7 +695,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { if (_CurrentBuiltInIcon) { - IconPath(unbox_value(_CurrentBuiltInIcon.as().EnumValue())); + IconPath(unbox_value(_CurrentBuiltInIcon.EnumValue())); } break; } diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h index efafedf5cf4..9f85cfee816 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation static void UpdateFontList() noexcept; static Windows::Foundation::Collections::IObservableVector CompleteFontList() noexcept { return _FontList; }; static Windows::Foundation::Collections::IObservableVector MonospaceFontList() noexcept { return _MonospaceFontList; }; - static Windows::Foundation::Collections::IVector BuiltInIcons() noexcept { return _BuiltInIcons; }; + static Windows::Foundation::Collections::IObservableVector BuiltInIcons() noexcept { return _BuiltInIcons; }; ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& settings, const Windows::UI::Core::CoreDispatcher& dispatcher); Control::IControlSettings TermSettings() const; @@ -134,7 +134,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation VIEW_MODEL_OBSERVABLE_PROPERTY(ProfileSubPage, CurrentPage); VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector, CurrentBellSounds); - VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, CurrentBuiltInIcon); + VIEW_MODEL_OBSERVABLE_PROPERTY(Editor::EnumEntry, CurrentBuiltInIcon, nullptr); VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, CurrentEmojiIcon); PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid); @@ -197,7 +197,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void _MarkDuplicateBellSoundDirectories(); static Windows::Foundation::Collections::IObservableVector _MonospaceFontList; static Windows::Foundation::Collections::IObservableVector _FontList; - static Windows::Foundation::Collections::IVector _BuiltInIcons; + static Windows::Foundation::Collections::IObservableVector _BuiltInIcons; Model::CascadiaSettings _appSettings; Editor::AppearanceViewModel _unfocusedAppearanceViewModel; diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl index d43b75aecc6..073afdf910e 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl @@ -116,8 +116,8 @@ namespace Microsoft.Terminal.Settings.Editor Boolean UsingImageIcon { get; }; String IconPath; - IInspectable CurrentBuiltInIcon; - Windows.Foundation.Collections.IVector BuiltInIcons { get; }; + EnumEntry CurrentBuiltInIcon; + Windows.Foundation.Collections.IObservableVector BuiltInIcons { get; }; String TabTitlePreview { get; }; String AnswerbackMessagePreview { get; }; diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp index 774ecbb34de..80f9ca8904f 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp @@ -171,8 +171,76 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } - Windows::UI::Xaml::Controls::IconSource Profiles_Base::BuiltInIconConverter(const IInspectable& iconVal) + IconSource Profiles_Base::BuiltInIconConverter(const IInspectable& iconVal) { return Microsoft::Terminal::UI::IconPathConverter::IconSourceWUX(unbox_value(iconVal)); } + + void Profiles_Base::BuiltInIconPicker_GotFocus(const IInspectable& sender, const RoutedEventArgs& /*e*/) + { + _updateIconFilter({}); + sender.as().IsSuggestionListOpen(true); + } + + void Profiles_Base::BuiltInIconPicker_QuerySubmitted(const AutoSuggestBox& /*sender*/, const AutoSuggestBoxQuerySubmittedEventArgs& e) + { + const auto iconEntry = unbox_value_or(e.ChosenSuggestion(), nullptr); + if (!iconEntry) + { + return; + } + _Profile.CurrentBuiltInIcon(iconEntry); + } + + void Profiles_Base::BuiltInIconPicker_TextChanged(const AutoSuggestBox& sender, const AutoSuggestBoxTextChangedEventArgs& e) + { + if (e.Reason() != AutoSuggestionBoxTextChangeReason::UserInput) + { + return; + } + std::wstring_view filter{ sender.Text() }; + filter = til::trim(filter, L' '); + _updateIconFilter(filter); + } + + void Profiles_Base::_updateIconFilter(std::wstring_view filter) + { + if (_iconFilter != filter) + { + _filteredBuiltInIcons = nullptr; + _iconFilter = filter; + _updateFilteredIconList(); + PropertyChanged.raise(*this, PropertyChangedEventArgs{ L"FilteredBuiltInIconList" }); + } + } + + Windows::Foundation::Collections::IObservableVector Profiles_Base::FilteredBuiltInIconList() + { + if (!_filteredBuiltInIcons) + { + _updateFilteredIconList(); + } + return _filteredBuiltInIcons; + } + + void Profiles_Base::_updateFilteredIconList() + { + _filteredBuiltInIcons = ProfileViewModel::BuiltInIcons(); + if (_iconFilter.empty()) + { + return; + } + + // Find matching icons and populate the filtered list + std::vector filtered; + filtered.reserve(_filteredBuiltInIcons.Size()); + for (const auto& icon : _filteredBuiltInIcons) + { + if (til::contains_linguistic_insensitive(icon.EnumName(), _iconFilter)) + { + filtered.emplace_back(icon); + } + } + _filteredBuiltInIcons = winrt::single_threaded_observable_vector(std::move(filtered)); + } } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.h b/src/cascadia/TerminalSettingsEditor/Profiles_Base.h index 29ca4a0f692..62bf6f573e9 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.h +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.h @@ -25,6 +25,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Advanced_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); void DeleteConfirmation_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); + Windows::Foundation::Collections::IObservableVector FilteredBuiltInIconList(); + void BuiltInIconPicker_GotFocus(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e); + void BuiltInIconPicker_TextChanged(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox& sender, const Windows::UI::Xaml::Controls::AutoSuggestBoxTextChangedEventArgs& e); + void BuiltInIconPicker_QuerySubmitted(const winrt::Windows::UI::Xaml::Controls::AutoSuggestBox& sender, const Windows::UI::Xaml::Controls::AutoSuggestBoxQuerySubmittedEventArgs& e); + static Windows::UI::Xaml::Controls::IconSource BuiltInIconConverter(const Windows::Foundation::IInspectable& iconVal); til::property_changed_event PropertyChanged; @@ -34,6 +39,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker; winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker; Editor::IHostedInWindow _windowRoot; + Windows::Foundation::Collections::IObservableVector _filteredBuiltInIcons; + std::wstring _iconFilter; + + void _updateIconFilter(std::wstring_view filter); + void _updateFilteredIconList(); }; }; diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.idl b/src/cascadia/TerminalSettingsEditor/Profiles_Base.idl index 0e85e049216..0d3f9723ea5 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.idl +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.idl @@ -9,6 +9,7 @@ namespace Microsoft.Terminal.Settings.Editor { Profiles_Base(); ProfileViewModel Profile { get; }; + Windows.Foundation.Collections.IObservableVector FilteredBuiltInIconList { get; }; static Windows.UI.Xaml.Controls.IconSource BuiltInIconConverter(IInspectable iconVal); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml b/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml index 813cada4c54..eff46a620d0 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml @@ -142,12 +142,16 @@ - - + + @@ -163,8 +167,8 @@ Text="{x:Bind EnumName}" /> - - + +