Skip to content

Commit

Permalink
Add display name and icon to SUI extensions page
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Feb 27, 2025
1 parent 7cdbb7c commit 27008bf
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 251 deletions.
237 changes: 113 additions & 124 deletions src/cascadia/TerminalSettingsEditor/Extensions.cpp

Large diffs are not rendered by default.

59 changes: 38 additions & 21 deletions src/cascadia/TerminalSettingsEditor/Extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "FragmentExtensionViewModel.g.h"
#include "FragmentProfileViewModel.g.h"
#include "FragmentColorSchemeViewModel.g.h"
#include "ExtensionPackageTemplateSelector.g.h"
#include "ViewModelHelpers.h"
#include "Utils.h"

Expand All @@ -20,14 +21,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Extensions();

void OnNavigatedTo(const Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
void ExtensionLoaded(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
void ExtensionToggled(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);

void ExtensionNavigator_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
void NavigateToProfile_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
void NavigateToColorScheme_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);

WINRT_PROPERTY(Editor::ExtensionsViewModel, ViewModel, nullptr);

private:
Editor::ExtensionPackageTemplateSelector _extensionPackageTemplateSelector;
};

struct ExtensionsViewModel : ExtensionsViewModelT<ExtensionsViewModel>, ViewModelHelper<ExtensionsViewModel>
Expand All @@ -36,57 +38,59 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
ExtensionsViewModel(const Model::CascadiaSettings& settings, const Editor::ColorSchemesPageViewModel& colorSchemesPageVM);

// Properties
bool IsExtensionView() const noexcept { return _CurrentExtensionSource != hstring{}; }
Windows::Foundation::Collections::IVector<IInspectable> CurrentExtensionFragments() const noexcept;
hstring CurrentExtensionScope() const noexcept;
bool NoActiveExtensions() const noexcept { return _fragmentExtensions.Size() == 0; }
bool IsExtensionView() const noexcept { return _CurrentExtensionPackage != nullptr; }
bool NoExtensionPackages() const noexcept { return _extensionPackages.Size() == 0; }
bool NoProfilesModified() const noexcept { return _profilesModifiedView.Size() == 0; }
bool NoProfilesAdded() const noexcept { return _profilesAddedView.Size() == 0; }
bool NoSchemesAdded() const noexcept { return _colorSchemesAddedView.Size() == 0; }

// Views
Windows::Foundation::Collections::IObservableVector<Editor::ExtensionPackageViewModel> ExtensionPackages() const noexcept;
Windows::Foundation::Collections::IObservableVector<Editor::ExtensionPackageViewModel> ExtensionPackages() const noexcept { return _extensionPackages; }
Windows::Foundation::Collections::IObservableVector<Editor::FragmentProfileViewModel> ProfilesModified() const noexcept { return _profilesModifiedView; }
Windows::Foundation::Collections::IObservableVector<Editor::FragmentProfileViewModel> ProfilesAdded() const noexcept { return _profilesAddedView; }
Windows::Foundation::Collections::IObservableVector<Editor::FragmentColorSchemeViewModel> ColorSchemesAdded() const noexcept { return _colorSchemesAddedView; }

// Methods
void UpdateSettings(const Model::CascadiaSettings& settings, const Editor::ColorSchemesPageViewModel& colorSchemesPageVM);
bool GetExtensionState(hstring extensionSource) const;
void SetExtensionState(hstring extensionSource, bool enableExt);
void NavigateToProfile(const guid profileGuid);
void NavigateToColorScheme(const Editor::ColorSchemeViewModel& schemeVM);

static bool GetExtensionState(hstring extensionSource, const Model::CascadiaSettings& settings);
static void SetExtensionState(hstring extensionSource, const Model::CascadiaSettings& settings, bool enableExt);

til::typed_event<IInspectable, guid> NavigateToProfileRequested;
til::typed_event<IInspectable, Editor::ColorSchemeViewModel> NavigateToColorSchemeRequested;

VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, CurrentExtensionSource);
VIEW_MODEL_OBSERVABLE_PROPERTY(Editor::ExtensionPackageViewModel, CurrentExtensionPackage, nullptr);

private:
Model::CascadiaSettings _settings;
Editor::ColorSchemesPageViewModel _colorSchemesPageVM;
std::unordered_set<hstring> _extensionSources;
Windows::Foundation::Collections::IVector<Editor::FragmentExtensionViewModel> _fragmentExtensions;
Windows::Foundation::Collections::IObservableVector<Editor::ExtensionPackageViewModel> _extensionPackages;
Windows::Foundation::Collections::IObservableVector<Editor::FragmentProfileViewModel> _profilesModifiedView;
Windows::Foundation::Collections::IObservableVector<Editor::FragmentProfileViewModel> _profilesAddedView;
Windows::Foundation::Collections::IObservableVector<Editor::FragmentColorSchemeViewModel> _colorSchemesAddedView;

Windows::Foundation::Collections::IVector<hstring> _DisabledProfileSources() const noexcept { return _settings.GlobalSettings().DisabledProfileSources(); }
};

struct ExtensionPackageViewModel : ExtensionPackageViewModelT<ExtensionPackageViewModel>, ViewModelHelper<ExtensionPackageViewModel>
{
public:
ExtensionPackageViewModel(hstring source, bool enabled) :
_source{ source },
_enabled{ enabled } {}
hstring Source() const noexcept { return _source; }
bool Enabled() const noexcept { return _enabled; }
ExtensionPackageViewModel(const Model::ExtensionPackage& pkg, const Model::CascadiaSettings& settings) :
_package{ pkg },
_settings{ settings },
_fragmentExtensions{ single_threaded_observable_vector<Editor::FragmentExtensionViewModel>() } {}

Model::ExtensionPackage Package() const noexcept { return _package; }
hstring Scope() const noexcept;
bool Enabled() const;
void Enabled(bool val);
hstring AccessibleName() const noexcept;
Windows::Foundation::Collections::IObservableVector<Editor::FragmentExtensionViewModel> FragmentExtensions() { return _fragmentExtensions; }

private:
hstring _source;
bool _enabled;
Model::ExtensionPackage _package;
Model::CascadiaSettings _settings;
Windows::Foundation::Collections::IObservableVector<Editor::FragmentExtensionViewModel> _fragmentExtensions;
};

struct FragmentExtensionViewModel : FragmentExtensionViewModelT<FragmentExtensionViewModel>, ViewModelHelper<FragmentExtensionViewModel>
Expand Down Expand Up @@ -148,9 +152,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Model::FragmentSettings _fragment;
Editor::ColorSchemeViewModel _deducedSchemeVM;
};

struct ExtensionPackageTemplateSelector : public ExtensionPackageTemplateSelectorT<ExtensionPackageTemplateSelector>
{
public:
ExtensionPackageTemplateSelector() = default;

Windows::UI::Xaml::DataTemplate SelectTemplateCore(const Windows::Foundation::IInspectable& item, const Windows::UI::Xaml::DependencyObject& container);
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const Windows::Foundation::IInspectable& item);

WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, DefaultTemplate, nullptr);
WINRT_PROPERTY(Windows::UI::Xaml::DataTemplate, ComplexTemplate, nullptr);
};
};

namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Extensions);
BASIC_FACTORY(ExtensionPackageTemplateSelector);
}
24 changes: 15 additions & 9 deletions src/cascadia/TerminalSettingsEditor/Extensions.idl
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,33 @@ namespace Microsoft.Terminal.Settings.Editor
[default_interface] runtimeclass ExtensionsViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
// Properties
String CurrentExtensionSource;
IVector<Object> CurrentExtensionFragments { get; };
String CurrentExtensionScope { get; };
ExtensionPackageViewModel CurrentExtensionPackage;
Boolean IsExtensionView { get; };
Boolean NoActiveExtensions { get; };
Boolean NoExtensionPackages { get; };
Boolean NoProfilesModified { get; };
Boolean NoProfilesAdded { get; };
Boolean NoSchemesAdded { get; };

// Views
IObservableVector<ExtensionPackageViewModel> ExtensionPackages { get; };
IVector<ExtensionPackageViewModel> ExtensionPackages { get; };
IObservableVector<FragmentProfileViewModel> ProfilesModified { get; };
IObservableVector<FragmentProfileViewModel> ProfilesAdded { get; };
IObservableVector<FragmentColorSchemeViewModel> ColorSchemesAdded { get; };

// Methods
void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings, ColorSchemesPageViewModel colorSchemesPageVM);
Boolean GetExtensionState(String extensionSource);
void SetExtensionState(String extensionSource, Boolean enableExt);

event Windows.Foundation.TypedEventHandler<Object, Guid> NavigateToProfileRequested;
event Windows.Foundation.TypedEventHandler<Object, ColorSchemeViewModel> NavigateToColorSchemeRequested;
}

[default_interface] runtimeclass ExtensionPackageViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Source { get; };
Boolean Enabled { get; };
Microsoft.Terminal.Settings.Model.ExtensionPackage Package { get; };
Boolean Enabled;
String Scope { get; };
String AccessibleName { get; };
IVector<FragmentExtensionViewModel> FragmentExtensions { get; };
}

[default_interface] runtimeclass FragmentExtensionViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
Expand All @@ -66,4 +64,12 @@ namespace Microsoft.Terminal.Settings.Editor
String SourceName { get; };
String Json { get; };
}

[default_interface] runtimeclass ExtensionPackageTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
{
ExtensionPackageTemplateSelector();

Windows.UI.Xaml.DataTemplate DefaultTemplate;
Windows.UI.Xaml.DataTemplate ComplexTemplate;
}
}
74 changes: 61 additions & 13 deletions src/cascadia/TerminalSettingsEditor/Extensions.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,71 @@
<Setter Property="VerticalScrollBarVisibility" Value="Disabled" />
</Style>

<DataTemplate x:Key="ExtensionNavigatorTemplate"
<local:ExtensionPackageTemplateSelector x:Key="ExtensionPackageTemplateSelector"
DefaultTemplate="{StaticResource DefaultExtensionNavigatorTemplate}"
ComplexTemplate="{StaticResource ComplexExtensionNavigatorTemplate}" />

<DataTemplate x:Key="DefaultExtensionNavigatorTemplate"
x:DataType="local:ExtensionPackageViewModel">
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Style="{StaticResource NavigatorButtonStyle}"
Tag="{x:Bind Source}">
Tag="{x:Bind}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<TextBlock Grid.Column="0"
Text="{x:Bind Source}" />
Text="{x:Bind Package.Source}"/>
<TextBlock x:Uid="Extension_StateDisabled"
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{StaticResource SecondaryTextBlockStyle}"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Enabled)}" />
</Grid>
</Button>
</DataTemplate>

<DataTemplate x:Key="ComplexExtensionNavigatorTemplate"
x:DataType="local:ExtensionPackageViewModel">
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Style="{StaticResource NavigatorButtonStyle}"
Tag="{x:Bind}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<IconSourceElement Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Width="32"
Height="32"
Margin="0,0,8,0"
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Package.Icon)}"/>
<TextBlock Grid.Column="1"
Grid.Row="0"
Text="{x:Bind Package.DisplayName}"/>
<TextBlock Grid.Column="1"
Grid.Row="1"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{x:Bind Package.Source}" />
<TextBlock x:Uid="Extension_StateDisabled"
Grid.Column="2"
Grid.Row="0"
Grid.RowSpan="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{StaticResource SecondaryTextBlockStyle}"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Enabled)}" />
</Grid>
Expand Down Expand Up @@ -291,9 +340,9 @@
Style="{StaticResource TextBlockSubHeaderStyle}" />
<TextBlock x:Uid="Extensions_NoActiveExtensionsDisclaimer"
Style="{StaticResource ItalicDisclaimerStyle}"
Visibility="{x:Bind ViewModel.NoActiveExtensions, Mode=OneWay}" />
Visibility="{x:Bind ViewModel.NoExtensionPackages, Mode=OneWay}" />
<ItemsControl IsTabStop="False"
ItemTemplate="{StaticResource ExtensionNavigatorTemplate}"
ItemTemplateSelector="{StaticResource ExtensionPackageTemplateSelector}"
ItemsSource="{x:Bind ViewModel.ExtensionPackages}" />
</StackPanel>

Expand All @@ -303,26 +352,25 @@
Margin="0,-20,0,0"
Visibility="{x:Bind ViewModel.IsExtensionView, Mode=OneWay}">
<!-- Extension Status -->
<local:SettingContainer Header="{x:Bind ViewModel.CurrentExtensionSource, Mode=OneWay}"
<local:SettingContainer Header="{x:Bind ViewModel.CurrentExtensionPackage.Package.Source, Mode=OneWay}"
StartExpanded="True"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<ToggleSwitch Loaded="ExtensionLoaded"
Style="{StaticResource ToggleSwitchInExpanderStyle}"
Tag="{x:Bind ViewModel.CurrentExtensionSource, Mode=OneWay}"
Toggled="ExtensionToggled" />
<ToggleSwitch Style="{StaticResource ToggleSwitchInExpanderStyle}"
Tag="{x:Bind ViewModel.CurrentExtensionPackage.Package.Source, Mode=OneWay}"
IsOn="{x:Bind ViewModel.CurrentExtensionPackage.Enabled, Mode=TwoWay}" />
</local:SettingContainer.CurrentValue>
<local:SettingContainer.Content>
<StackPanel>
<!-- Scope -->
<local:SettingContainer x:Uid="Extensions_Scope"
Content="{x:Bind ViewModel.CurrentExtensionScope, Mode=OneWay}"
Content="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}"
IsTabStop="False"
Style="{StaticResource SettingContainerWithTextContent}" />
<!-- JSON -->
<ItemsControl IsTabStop="False"
ItemTemplate="{StaticResource JsonTemplate}"
ItemsSource="{x:Bind ViewModel.CurrentExtensionFragments, Mode=OneWay}" />
ItemsSource="{x:Bind ViewModel.CurrentExtensionPackage.FragmentExtensions, Mode=OneWay}" />
</StackPanel>
</local:SettingContainer.Content>
</local:SettingContainer>
Expand Down
Loading

0 comments on commit 27008bf

Please sign in to comment.