Skip to content

Commit

Permalink
Align TabView visuals with Edge (#2201)
Browse files Browse the repository at this point in the history
* Add initial wip

* More improvements, added shadow

* remove unused corners

* Improve hit testing

* Switch to rounded corners

* Add rounded corners

* Switch to single shadow

* Switch to TemplateSettings

* Cleanup

* CR feedback

* Fix test failure

* workaround vsm crash on <rs4

* simplify TabViewItem element tree. Add x:Load=false on Path elements

* Mark new templateproperties as preview

Co-authored-by: Keith Mahoney <[email protected]>
  • Loading branch information
marcelwgn and kmahone authored May 19, 2020
1 parent 3c5de5c commit 98a6b74
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 21 deletions.
10 changes: 3 additions & 7 deletions dev/AutoSuggestBox/AutoSuggestBoxHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "AutoSuggestBoxHelper.h"
#include "DispatcherHelper.h"
#include "CornerRadiusFilterConverter.h"
#include "ResourceAccessor.h"

static constexpr auto c_popupName = L"SuggestionsPopup"sv;
static constexpr auto c_popupBorderName = L"SuggestionsContainer"sv;
Expand Down Expand Up @@ -103,8 +104,8 @@ void AutoSuggestBoxHelper::OnAutoSuggestBoxLoaded(const winrt::IInspectable& sen

void AutoSuggestBoxHelper::UpdateCornerRadius(const winrt::AutoSuggestBox& autoSuggestBox, bool isPopupOpen)
{
auto textBoxRadius = unbox_value<winrt::CornerRadius>(ResourceLookup(autoSuggestBox, box_value(c_controlCornerRadiusKey)));
auto popupRadius = unbox_value<winrt::CornerRadius>(ResourceLookup(autoSuggestBox, box_value(c_overlayCornerRadiusKey)));
auto textBoxRadius = unbox_value<winrt::CornerRadius>(ResourceAccessor::ResourceLookup(autoSuggestBox, box_value(c_controlCornerRadiusKey)));
auto popupRadius = unbox_value<winrt::CornerRadius>(ResourceAccessor::ResourceLookup(autoSuggestBox, box_value(c_overlayCornerRadiusKey)));

if (winrt::IControl7 autoSuggextBoxControl7 = autoSuggestBox)
{
Expand Down Expand Up @@ -158,8 +159,3 @@ bool AutoSuggestBoxHelper::IsPopupOpenDown(const winrt::AutoSuggestBox& autoSugg
}
return verticalOffset >= 0;
}

winrt::IInspectable AutoSuggestBoxHelper::ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key)
{
return control.Resources().HasKey(key) ? control.Resources().Lookup(key) : winrt::Application::Current().Resources().TryLookup(key);
}
1 change: 0 additions & 1 deletion dev/AutoSuggestBox/AutoSuggestBoxHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class AutoSuggestBoxHelper

static void UpdateCornerRadius(const winrt::AutoSuggestBox& autoSuggestBox, bool isPopupOpen);
static bool IsPopupOpenDown(const winrt::AutoSuggestBox& autoSuggestBox);
static winrt::IInspectable ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key);
};

class AutoSuggestEventRevokers
Expand Down
10 changes: 3 additions & 7 deletions dev/ComboBox/ComboBoxHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ComboBoxHelper.h"
#include "DispatcherHelper.h"
#include "CornerRadiusFilterConverter.h"
#include "ResourceAccessor.h"

static constexpr auto c_popupBorderName = L"PopupBorder"sv;
static constexpr auto c_editableTextName = L"EditableText"sv;
Expand Down Expand Up @@ -93,8 +94,8 @@ void ComboBoxHelper::UpdateCornerRadius(const winrt::ComboBox& comboBox, bool is
{
if (comboBox.IsEditable())
{
auto textBoxRadius = unbox_value<winrt::CornerRadius>(ResourceLookup(comboBox, box_value(c_controlCornerRadiusKey)));
auto popupRadius = unbox_value<winrt::CornerRadius>(ResourceLookup(comboBox, box_value(c_overlayCornerRadiusKey)));
auto textBoxRadius = unbox_value<winrt::CornerRadius>(ResourceAccessor::ResourceLookup(comboBox, box_value(c_controlCornerRadiusKey)));
auto popupRadius = unbox_value<winrt::CornerRadius>(ResourceAccessor::ResourceLookup(comboBox, box_value(c_overlayCornerRadiusKey)));

if (winrt::IControl7 comboBoxControl7 = comboBox)
{
Expand Down Expand Up @@ -149,8 +150,3 @@ bool ComboBoxHelper::IsPopupOpenDown(const winrt::ComboBox& comboBox)
}
return verticalOffset > 0;
}

winrt::IInspectable ComboBoxHelper::ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key)
{
return control.Resources().HasKey(key) ? control.Resources().Lookup(key) : winrt::Application::Current().Resources().TryLookup(key);
}
1 change: 0 additions & 1 deletion dev/ComboBox/ComboBoxHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class ComboBoxHelper

static void UpdateCornerRadius(const winrt::ComboBox& comboBox, bool isDropDownOpen);
static bool IsPopupOpenDown(const winrt::ComboBox& comboBox);
static winrt::IInspectable ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key);
};

class ComboBoxDropDownEventRevokers
Expand Down
46 changes: 46 additions & 0 deletions dev/Generated/TabViewItemTemplateSettings.properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace winrt::Microsoft::UI::Xaml::Controls
#include "TabViewItemTemplateSettings.g.cpp"

GlobalDependencyProperty TabViewItemTemplateSettingsProperties::s_IconElementProperty{ nullptr };
GlobalDependencyProperty TabViewItemTemplateSettingsProperties::s_LeftInsetRadiusMarginProperty{ nullptr };
GlobalDependencyProperty TabViewItemTemplateSettingsProperties::s_RightInsetRadiusMarginProperty{ nullptr };

TabViewItemTemplateSettingsProperties::TabViewItemTemplateSettingsProperties()
{
Expand All @@ -33,11 +35,35 @@ void TabViewItemTemplateSettingsProperties::EnsureProperties()
ValueHelper<winrt::IconElement>::BoxedDefaultValue(),
nullptr);
}
if (!s_LeftInsetRadiusMarginProperty)
{
s_LeftInsetRadiusMarginProperty =
InitializeDependencyProperty(
L"LeftInsetRadiusMargin",
winrt::name_of<winrt::Thickness>(),
winrt::name_of<winrt::TabViewItemTemplateSettings>(),
false /* isAttached */,
ValueHelper<winrt::Thickness>::BoxedDefaultValue(),
nullptr);
}
if (!s_RightInsetRadiusMarginProperty)
{
s_RightInsetRadiusMarginProperty =
InitializeDependencyProperty(
L"RightInsetRadiusMargin",
winrt::name_of<winrt::Thickness>(),
winrt::name_of<winrt::TabViewItemTemplateSettings>(),
false /* isAttached */,
ValueHelper<winrt::Thickness>::BoxedDefaultValue(),
nullptr);
}
}

void TabViewItemTemplateSettingsProperties::ClearProperties()
{
s_IconElementProperty = nullptr;
s_LeftInsetRadiusMarginProperty = nullptr;
s_RightInsetRadiusMarginProperty = nullptr;
}

void TabViewItemTemplateSettingsProperties::IconElement(winrt::IconElement const& value)
Expand All @@ -49,3 +75,23 @@ winrt::IconElement TabViewItemTemplateSettingsProperties::IconElement()
{
return ValueHelper<winrt::IconElement>::CastOrUnbox(static_cast<TabViewItemTemplateSettings*>(this)->GetValue(s_IconElementProperty));
}

void TabViewItemTemplateSettingsProperties::LeftInsetRadiusMargin(winrt::Thickness const& value)
{
static_cast<TabViewItemTemplateSettings*>(this)->SetValue(s_LeftInsetRadiusMarginProperty, ValueHelper<winrt::Thickness>::BoxValueIfNecessary(value));
}

winrt::Thickness TabViewItemTemplateSettingsProperties::LeftInsetRadiusMargin()
{
return ValueHelper<winrt::Thickness>::CastOrUnbox(static_cast<TabViewItemTemplateSettings*>(this)->GetValue(s_LeftInsetRadiusMarginProperty));
}

void TabViewItemTemplateSettingsProperties::RightInsetRadiusMargin(winrt::Thickness const& value)
{
static_cast<TabViewItemTemplateSettings*>(this)->SetValue(s_RightInsetRadiusMarginProperty, ValueHelper<winrt::Thickness>::BoxValueIfNecessary(value));
}

winrt::Thickness TabViewItemTemplateSettingsProperties::RightInsetRadiusMargin()
{
return ValueHelper<winrt::Thickness>::CastOrUnbox(static_cast<TabViewItemTemplateSettings*>(this)->GetValue(s_RightInsetRadiusMarginProperty));
}
10 changes: 10 additions & 0 deletions dev/Generated/TabViewItemTemplateSettings.properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ class TabViewItemTemplateSettingsProperties
void IconElement(winrt::IconElement const& value);
winrt::IconElement IconElement();

void LeftInsetRadiusMargin(winrt::Thickness const& value);
winrt::Thickness LeftInsetRadiusMargin();

void RightInsetRadiusMargin(winrt::Thickness const& value);
winrt::Thickness RightInsetRadiusMargin();

static winrt::DependencyProperty IconElementProperty() { return s_IconElementProperty; }
static winrt::DependencyProperty LeftInsetRadiusMarginProperty() { return s_LeftInsetRadiusMarginProperty; }
static winrt::DependencyProperty RightInsetRadiusMarginProperty() { return s_RightInsetRadiusMarginProperty; }

static GlobalDependencyProperty s_IconElementProperty;
static GlobalDependencyProperty s_LeftInsetRadiusMarginProperty;
static GlobalDependencyProperty s_RightInsetRadiusMarginProperty;

static void EnsureProperties();
static void ClearProperties();
Expand Down
7 changes: 6 additions & 1 deletion dev/ResourceHelper/ResourceAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,9 @@ winrt::LoadedImageSurface ResourceAccessor::GetImageSurface(const wstring_view &
}
}();
return winrt::LoadedImageSurface::StartLoadFromUri(imageUri, imageSize);
}
}

winrt::IInspectable ResourceAccessor::ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key)
{
return control.Resources().HasKey(key) ? control.Resources().Lookup(key) : winrt::Application::Current().Resources().TryLookup(key);
}
1 change: 1 addition & 0 deletions dev/ResourceHelper/ResourceAccessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ResourceAccessor sealed
public:
static winrt::hstring GetLocalizedStringResource(const wstring_view &resourceName);
static winrt::LoadedImageSurface GetImageSurface(const wstring_view &assetName, winrt::Size imageSize);
static winrt::IInspectable ResourceLookup(const winrt::Control& control, const winrt::IInspectable& key);

static bool IsResourceIdNull(ResourceIdType resourceId)
{
Expand Down
2 changes: 1 addition & 1 deletion dev/TabView/InteractionTests/TabViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void TabSizeAndScrollButtonsTest()
{
using (var setup = new TestSetupHelper("TabView Tests"))
{
UIObject smallerTab = FindElement.ByName("FirstTab");
UIObject smallerTab = FindElement.ByName("SecondTab");
UIObject largerTab = FindElement.ByName("LongHeaderTab");

FindElement.ByName<Button>("SetTabViewWidth").InvokeAndWait();
Expand Down
11 changes: 11 additions & 0 deletions dev/TabView/TabView.idl
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,19 @@ unsealed runtimeclass TabViewItemTemplateSettings : Windows.UI.Xaml.DependencyOb
TabViewItemTemplateSettings();

Windows.UI.Xaml.Controls.IconElement IconElement;
[WUXC_VERSION_PREVIEW]
{
Windows.UI.Xaml.Thickness LeftInsetRadiusMargin;
Windows.UI.Xaml.Thickness RightInsetRadiusMargin;
}

static Windows.UI.Xaml.DependencyProperty IconElementProperty{ get; };

[WUXC_VERSION_PREVIEW]
{
static Windows.UI.Xaml.DependencyProperty LeftInsetRadiusMarginProperty{ get; };
static Windows.UI.Xaml.DependencyProperty RightInsetRadiusMarginProperty{ get; };
}
}

}
Expand Down
41 changes: 40 additions & 1 deletion dev/TabView/TabView.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down Expand Up @@ -389,6 +389,12 @@
Padding="{TemplateBinding Padding}"
Margin="-1,0,0,0"> <!-- This item will cover the separator on its left side. -->

<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftColumn" Width="0"/>
<ColumnDefinition Width="*" />
<ColumnDefinition x:Name="RightColumn" Width="0"/>
</Grid.ColumnDefinitions>

<Grid.RenderTransform>
<ScaleTransform x:Name="LayoutRootScale" />
</Grid.RenderTransform>
Expand Down Expand Up @@ -424,6 +430,9 @@
<Setter Target="IconControl.Foreground" Value="{ThemeResource TabViewItemIconForegroundSelected}" />
<Setter Target="CloseButton.Background" Value="{ThemeResource TabViewButtonBackgroundActiveTab}" />
<Setter Target="CloseButton.Foreground" Value="{ThemeResource TabViewButtonForegroundActiveTab}" />
<Setter Target="LeftRadiusRender.Visibility" Value="Visible"/>
<Setter Target="RightRadiusRender.Visibility" Value="Visible"/>
<Setter Target="LayoutRoot.Background" Value="Transparent"/>
</VisualState.Setters>
</VisualState>

Expand All @@ -434,6 +443,9 @@
<Setter Target="IconControl.Foreground" Value="{ThemeResource TabViewItemIconForegroundPointerOver}" />
<Setter Target="CloseButton.Background" Value="{ThemeResource TabViewButtonBackgroundActiveTab}" />
<Setter Target="CloseButton.Foreground" Value="{ThemeResource TabViewButtonForegroundActiveTab}" />
<Setter Target="LayoutRoot.Background" Value="Transparent"/>
<Setter Target="LeftRadiusRender.Visibility" Value="Visible"/>
<Setter Target="RightRadiusRender.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>

Expand All @@ -444,6 +456,9 @@
<Setter Target="IconControl.Foreground" Value="{ThemeResource TabViewItemIconForegroundPressed}" />
<Setter Target="CloseButton.Background" Value="{ThemeResource TabViewButtonBackgroundActiveTab}" />
<Setter Target="CloseButton.Foreground" Value="{ThemeResource TabViewButtonForegroundActiveTab}" />
<Setter Target="LayoutRoot.Background" Value="Transparent"/>
<Setter Target="LeftRadiusRender.Visibility" Value="Visible"/>
<Setter Target="RightRadiusRender.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
Expand Down Expand Up @@ -604,9 +619,33 @@
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

<Path
x:Name="LeftRadiusRender"
x:Load="False"
Grid.Column="0"
Visibility="Collapsed"
VerticalAlignment="Bottom"
Height="{Binding Source={ThemeResource OverlayCornerRadius}, Path=BottomLeft}"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TabViewTemplateSettings.LeftInsetRadiusMargin}"
Stretch="Uniform"
Fill="{ThemeResource TabViewItemHeaderBackgroundSelected}"
Data="M4 0 L4 4 L0 4 A4,4 90 0 0 4 0 Z" />
<Path
x:Name="RightRadiusRender"
x:Load="False"
Grid.Column="2"
Visibility="Collapsed"
VerticalAlignment="Bottom"
Height="{Binding Source={ThemeResource OverlayCornerRadius}, Path=BottomRight}"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TabViewTemplateSettings.RightInsetRadiusMargin}"
Stretch="Uniform"
Fill="{ThemeResource TabViewItemHeaderBackgroundSelected}"
Data="M0 0 L0 4 L4 4 A4 4 90 0 1 0 0 Z" />

<Border x:Name="TabSeparator"
HorizontalAlignment="Right"
Width="1"
Grid.Column="1"
BorderBrush="{ThemeResource TabViewItemSeparator}"
BorderThickness="1"
Margin="0,6,0,6"/>
Expand Down
17 changes: 17 additions & 0 deletions dev/TabView/TabViewItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "ResourceAccessor.h"
#include "SharedHelpers.h"

static constexpr auto c_overlayCornerRadiusKey = L"OverlayCornerRadius"sv;

TabViewItem::TabViewItem()
{
__RP_Marker_ClassById(RuntimeProfiler::ProfId_TabViewItem);
Expand All @@ -22,6 +24,12 @@ TabViewItem::TabViewItem()

void TabViewItem::OnApplyTemplate()
{
auto const templateSettings = winrt::get_self<TabViewItemTemplateSettings>(TabViewTemplateSettings());
auto popupRadius = unbox_value<winrt::CornerRadius>(ResourceAccessor::ResourceLookup(*this, box_value(c_overlayCornerRadiusKey)));

templateSettings->LeftInsetRadiusMargin(winrt::Thickness({ -popupRadius.BottomLeft,0,0,0 }));
templateSettings->RightInsetRadiusMargin(winrt::Thickness({0,0,-popupRadius.BottomRight,0}));

winrt::IControlProtected controlProtected{ *this };

auto tabView = SharedHelpers::GetAncestorOfType<winrt::TabView>(winrt::VisualTreeHelper::GetParent(*this));
Expand Down Expand Up @@ -84,6 +92,15 @@ void TabViewItem::OnApplyTemplate()

void TabViewItem::OnIsSelectedPropertyChanged(const winrt::DependencyObject& sender, const winrt::DependencyProperty& args)
{
if (IsSelected())
{
SetValue(winrt::Canvas::ZIndexProperty(),box_value(20));
}
else
{
SetValue(winrt::Canvas::ZIndexProperty(), box_value(0));
}

UpdateShadow();
UpdateWidthModeVisualState();

Expand Down
2 changes: 1 addition & 1 deletion dev/TabView/TabView_themeresources.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

<Thickness x:Key="TabViewHeaderPadding">8,8,0,0</Thickness>
<Thickness x:Key="TabViewHeaderPadding">8,8,4,0</Thickness>
<Thickness x:Key="TabViewItemHeaderPadding">12,8,10,8</Thickness>

<x:Double x:Key="TabViewItemMaxWidth">240</x:Double>
Expand Down
8 changes: 7 additions & 1 deletion dev/TabView/TestUI/TabViewPage.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<local:TestPage
x:Class="MUXControlsTestApp.TabViewPage"
x:Name="TabViewTestPage"
Expand Down Expand Up @@ -217,6 +217,12 @@
</Grid.ColumnDefinitions>

<controls:TabView x:Name="DataBindingTabView" IsAddTabButtonVisible="false" Background="#66336699" SelectedIndex="2">
<controls:TabView.Resources>
<ResourceDictionary>
<StaticResource x:Key="TabViewItemHeaderBackgroundSelected" ResourceKey="SystemAccentColor"/>
</ResourceDictionary>
</controls:TabView.Resources>

<controls:TabView.TabItemTemplate>
<DataTemplate x:DataType="local:TabDataItem">
<controls:TabViewItem Header="{x:Bind Header}" IconSource="{x:Bind IconSource}" Content="{x:Bind Content}">
Expand Down

0 comments on commit 98a6b74

Please sign in to comment.