Skip to content

Commit def4190

Browse files
committed
Try to do the DataTemplate thing, and fail.
Surprise surprise! we ran into an old friend: * #9288 * #9487 * microsoft/microsoft-ui-xaml#2121 so uh, this is ded.
1 parent 8d8590d commit def4190

File tree

4 files changed

+168
-2
lines changed

4 files changed

+168
-2
lines changed

src/cascadia/TerminalApp/SnippetsPaneContent.cpp

+107-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "SnippetsPaneContent.h"
66
#include "SnippetsPaneContent.g.cpp"
77
#include "FilteredTask.g.cpp"
8+
#include "SnippetsItemTemplateSelector.g.cpp"
89

910
using namespace winrt::Windows::Foundation;
1011
using namespace winrt::Microsoft::Terminal::Settings;
@@ -23,7 +24,8 @@ namespace winrt::TerminalApp::implementation
2324
{
2425
InitializeComponent();
2526

26-
// auto res = Windows::UI::Xaml::Application::Current().Resources();
27+
// _itemTemplateSelector = Resources().Lookup(winrt::box_value(L"SnippetsItemTemplateSelector")).try_as<SnippetsItemTemplateSelector>();
28+
2729
auto bg = Resources().Lookup(winrt::box_value(L"PageBackground"));
2830
Background(bg.try_as<WUX::Media::Brush>());
2931
}
@@ -129,4 +131,108 @@ namespace winrt::TerminalApp::implementation
129131
}
130132
}
131133

134+
// // Method Description:
135+
// // - This event is triggered when filteredActionView is looking for item container (ListViewItem)
136+
// // to use to present the filtered actions.
137+
// // GH#9288: unfortunately the default lookup seems to choose items with wrong data templates,
138+
// // e.g., using DataTemplate rendering actions for tab palette items.
139+
// // We handle this event by manually selecting an item from the cache.
140+
// // If no item is found we allocate a new one.
141+
// // Arguments:
142+
// // - args: the ChoosingItemContainerEventArgs allowing to get container candidate suggested by the
143+
// // system and replace it with another candidate if required.
144+
// // Return Value:
145+
// // - <none>
146+
// void SnippetsPaneContent::_choosingItemContainer(
147+
// const Windows::UI::Xaml::Controls::ListViewBase& /*sender*/,
148+
// const Windows::UI::Xaml::Controls::ChoosingItemContainerEventArgs& args)
149+
// {
150+
// const auto dataTemplate = _itemTemplateSelector.SelectTemplate(args.Item());
151+
// const auto itemContainer = args.ItemContainer();
152+
// if (itemContainer && itemContainer.ContentTemplate() == dataTemplate)
153+
// {
154+
// // If the suggested candidate is OK simply remove it from the cache
155+
// // (so we won't allocate it until it is released) and return
156+
// _listViewItemsCache[dataTemplate].erase(itemContainer);
157+
// }
158+
// else
159+
// {
160+
// // We need another candidate, let's look it up inside the cache
161+
// auto& containersByTemplate = _listViewItemsCache[dataTemplate];
162+
// if (!containersByTemplate.empty())
163+
// {
164+
// // There cache contains available items for required DataTemplate
165+
// // Let's return one of them (and remove it from the cache)
166+
// auto firstItem = containersByTemplate.begin();
167+
// args.ItemContainer(*firstItem);
168+
// containersByTemplate.erase(firstItem);
169+
// }
170+
// else
171+
// {
172+
// ElementFactoryGetArgs factoryArgs{};
173+
// const auto listViewItem = _listItemTemplate.GetElement(factoryArgs).try_as<Controls::ListViewItem>();
174+
// listViewItem.ContentTemplate(dataTemplate);
175+
176+
// if (dataTemplate == _itemTemplateSelector.NestedItemTemplate())
177+
// {
178+
// const auto helpText = winrt::box_value(RS_(L"CommandPalette_MoreOptions/[using:Windows.UI.Xaml.Automation]AutomationProperties/HelpText"));
179+
// listViewItem.SetValue(Automation::AutomationProperties::HelpTextProperty(), helpText);
180+
// }
181+
182+
// args.ItemContainer(listViewItem);
183+
// }
184+
// }
185+
// args.IsContainerPrepared(true);
186+
// }
187+
188+
// // Method Description:
189+
// // - This event is triggered when the data item associate with filteredActionView list item is changing.
190+
// // We check if the item is being recycled. In this case we return it to the cache
191+
// // Arguments:
192+
// // - args: the ContainerContentChangingEventArgs describing the container change
193+
// // Return Value:
194+
// // - <none>
195+
// void SnippetsPaneContent::_containerContentChanging(
196+
// const Windows::UI::Xaml::Controls::ListViewBase& /*sender*/,
197+
// const Windows::UI::Xaml::Controls::ContainerContentChangingEventArgs& args)
198+
// {
199+
// const auto itemContainer = args.ItemContainer();
200+
// if (args.InRecycleQueue() && itemContainer && itemContainer.ContentTemplate())
201+
// {
202+
// _listViewItemsCache[itemContainer.ContentTemplate()].insert(itemContainer);
203+
// itemContainer.DataContext(nullptr);
204+
// }
205+
// else
206+
// {
207+
// itemContainer.DataContext(args.Item());
208+
// }
209+
// }
210+
211+
#pragma region(SnippetsItemTemplateSelector)
212+
213+
WUX::DataTemplate SnippetsItemTemplateSelector::SelectTemplateCore(const winrt::IInspectable& item, const winrt::WUX::DependencyObject& /*container*/)
214+
{
215+
return SelectTemplateCore(item);
216+
}
217+
218+
// Method Description:
219+
// - This method is called once command palette decides how to render a filtered command.
220+
// Currently we support two ways to render command, that depend on its palette item type:
221+
// - For TabPalette item we render an icon, a title, and some tab-related indicators like progress bar (as defined by TabItemTemplate)
222+
// - All other items are currently rendered with icon, title and optional key-chord (as defined by GeneralItemTemplate)
223+
// Arguments:
224+
// - item - an instance of filtered command to render
225+
// Return Value:
226+
// - data template to use for rendering
227+
WUX::DataTemplate SnippetsItemTemplateSelector::SelectTemplateCore(const winrt::IInspectable& item)
228+
{
229+
if (const auto filteredTask{ item.try_as<winrt::TerminalApp::FilteredTask>() })
230+
{
231+
return filteredTask.HasChildren() ? NestedItemTemplate() : GeneralItemTemplate();
232+
}
233+
234+
return GeneralItemTemplate();
235+
}
236+
#pragma endregion
237+
132238
}

src/cascadia/TerminalApp/SnippetsPaneContent.h

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55
#include "SnippetsPaneContent.g.h"
66
#include "FilteredTask.g.h"
7+
#include "SnippetsItemTemplateSelector.g.h"
78
#include "FilteredCommand.h"
89
#include "ActionPaletteItem.h"
910
#include <LibraryResources.h>
@@ -58,6 +59,11 @@ namespace winrt::TerminalApp::implementation
5859
void _filterTextChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
5960

6061
void _updateFilteredCommands();
62+
63+
// void _choosingItemContainer(const Windows::UI::Xaml::Controls::ListViewBase& sender, const Windows::UI::Xaml::Controls::ChoosingItemContainerEventArgs& args);
64+
// void _containerContentChanging(const Windows::UI::Xaml::Controls::ListViewBase& sender, const Windows::UI::Xaml::Controls::ContainerContentChangingEventArgs& args);
65+
// winrt::TerminalApp::SnippetsItemTemplateSelector _itemTemplateSelector{ nullptr };
66+
// std::unordered_map<Windows::UI::Xaml::DataTemplate, std::unordered_set<Windows::UI::Xaml::Controls::Primitives::SelectorItem, winrt_object_hash>, winrt_object_hash> _listViewItemsCache;
6167
};
6268

6369
struct FilteredTask : FilteredTaskT<FilteredTask, TerminalApp::implementation::FilteredCommand>
@@ -135,9 +141,21 @@ namespace winrt::TerminalApp::implementation
135141
winrt::Microsoft::Terminal::Settings::Model::Command _command{ nullptr };
136142
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> _children{ nullptr };
137143
};
144+
145+
struct SnippetsItemTemplateSelector : SnippetsItemTemplateSelectorT<SnippetsItemTemplateSelector>
146+
{
147+
SnippetsItemTemplateSelector() = default;
148+
149+
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::UI::Xaml::DependencyObject&);
150+
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&);
151+
152+
til::property<winrt::Windows::UI::Xaml::DataTemplate> NestedItemTemplate;
153+
til::property<winrt::Windows::UI::Xaml::DataTemplate> GeneralItemTemplate;
154+
};
138155
}
139156

140157
namespace winrt::TerminalApp::factory_implementation
141158
{
142159
BASIC_FACTORY(SnippetsPaneContent);
160+
BASIC_FACTORY(SnippetsItemTemplateSelector);
143161
}

src/cascadia/TerminalApp/SnippetsPaneContent.xaml

+36-1
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,38 @@
183183
</mux:TreeViewItem>
184184
</DataTemplate>
185185

186+
<DataTemplate x:Key="NestedItemTemplate"
187+
x:DataType="local:FilteredTask">
188+
<mux:TreeViewItem x:Name="rootItem"
189+
ItemsSource="{x:Bind Children}"
190+
Visibility="{x:Bind Visibility, Mode=OneWay}">
191+
<Grid>
192+
<Grid.RowDefinitions>
193+
<RowDefinition Height="*" />
194+
</Grid.RowDefinitions>
195+
<Grid.ColumnDefinitions>
196+
<ColumnDefinition Width="Auto" />
197+
<ColumnDefinition Width="*" />
198+
</Grid.ColumnDefinitions>
199+
200+
<ContentPresenter Grid.Column="0">
201+
<IconSourceElement Width="16"
202+
Height="16"
203+
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Item.Icon), Mode=OneTime}"
204+
Visibility="Collapsed" />
205+
</ContentPresenter>
206+
207+
<local:HighlightedTextControl Grid.Column="1"
208+
HorizontalAlignment="Left"
209+
Text="{x:Bind HighlightedName, Mode=OneWay}" />
210+
</Grid>
211+
</mux:TreeViewItem>
212+
</DataTemplate>
213+
214+
<local:SnippetsItemTemplateSelector x:Key="SnippetsItemTemplateSelector"
215+
GeneralItemTemplate="{StaticResource TaskItemTemplate}"
216+
NestedItemTemplate="{StaticResource NestedItemTemplate}" />
217+
186218
<ResourceDictionary.ThemeDictionaries>
187219
<!-- same as in MainPage, this is SolidBackgroundFillColorTertiary -->
188220
<ResourceDictionary x:Key="Dark">
@@ -245,8 +277,11 @@
245277
AllowFocusOnInteraction="True"
246278
CanDragItems="False"
247279
CanReorderItems="False"
248-
ItemTemplate="{StaticResource TaskItemTemplate}"
280+
ItemContainerStyleSelector="{StaticResource SnippetsItemTemplateSelector}"
249281
Visibility="{x:Bind HasSnippets, Mode=OneWay}" />
282+
283+
<!-- ChoosingItemContainer="_choosingItemContainer" -->
284+
<!-- ContainerContentChanging="_containerContentChanging" -->
250285
</Grid>
251286

252287
</UserControl>

src/cascadia/TerminalApp/TerminalPaneContent.idl

+7
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,11 @@ namespace TerminalApp
3333
Boolean HasSnippets { get; };
3434
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
3535
}
36+
37+
[default_interface] runtimeclass SnippetsItemTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
38+
{
39+
SnippetsItemTemplateSelector();
40+
Windows.UI.Xaml.DataTemplate GeneralItemTemplate;
41+
Windows.UI.Xaml.DataTemplate NestedItemTemplate;
42+
}
3643
}

0 commit comments

Comments
 (0)