From a29c1b4cb681164db2b54bedd4be1682ff5c8de1 Mon Sep 17 00:00:00 2001 From: Stephen L Peters Date: Tue, 17 Sep 2019 12:50:12 -0700 Subject: [PATCH] Fix Teaching Tip's Rounded Corners (#1305) * Attempt to fix a rare crash in calculator app. * Do proper event token clean up. * Use the routedEventHelpers instead of doing these events by hand * Clean up * Fix a silly mistake * rename handler to revoker * PTR: Fix high contrast list item display, remove background and add border to display PTR correctly in test page * Fix teaching tips adorners to be compatible with rounded corners. * Rename the converter peices * UseNonstandardConditionalXaml * move converter definitions out of the teaching tip style. --- dev/Common/Common.vcxitems | 4 ++ .../CornerRadiusToThicknessConverter.cpp | 61 +++++++++++++++++++ dev/Common/CornerRadiusToThicknessConverter.h | 28 +++++++++ .../CornerRadiusToThicknessConverter.idl | 27 ++++++++ .../CornerRadius_themeresources.xaml | 8 ++- ...rRadiusToThicknessConverter.properties.cpp | 46 ++++++++++++++ ...nerRadiusToThicknessConverter.properties.h | 21 +++++++ .../ThicknessFilterConverter.properties.cpp | 46 ++++++++++++++ .../ThicknessFilterConverter.properties.h | 21 +++++++ dev/TeachingTip/TeachingTip.h | 18 +++--- dev/TeachingTip/TeachingTip.xaml | 31 +++++++++- .../TestUI/TeachingTipPage.xaml.cs | 6 +- 12 files changed, 303 insertions(+), 14 deletions(-) create mode 100644 dev/Common/CornerRadiusToThicknessConverter.cpp create mode 100644 dev/Common/CornerRadiusToThicknessConverter.h create mode 100644 dev/Common/CornerRadiusToThicknessConverter.idl create mode 100644 dev/Generated/CornerRadiusToThicknessConverter.properties.cpp create mode 100644 dev/Generated/CornerRadiusToThicknessConverter.properties.h create mode 100644 dev/Generated/ThicknessFilterConverter.properties.cpp create mode 100644 dev/Generated/ThicknessFilterConverter.properties.h diff --git a/dev/Common/Common.vcxitems b/dev/Common/Common.vcxitems index c2c91d64de..cb1b4c485f 100644 --- a/dev/Common/Common.vcxitems +++ b/dev/Common/Common.vcxitems @@ -18,12 +18,15 @@ + + + @@ -33,6 +36,7 @@ + \ No newline at end of file diff --git a/dev/Common/CornerRadiusToThicknessConverter.cpp b/dev/Common/CornerRadiusToThicknessConverter.cpp new file mode 100644 index 0000000000..62b496d98e --- /dev/null +++ b/dev/Common/CornerRadiusToThicknessConverter.cpp @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#include +#include +#include "CornerRadiusToThicknessConverter.h" + +winrt::Thickness CornerRadiusToThicknessConverter::Convert(winrt::CornerRadius const& radius, winrt::CornerRadiusToThicknessConverterKind const& filterKind) +{ + auto result = winrt::Thickness{}; + + switch (filterKind) + { + case winrt::CornerRadiusToThicknessConverterKind::FilterLeftAndRightFromTop: + result.Left = radius.TopLeft; + result.Right = radius.TopRight; + result.Top = 0; + result.Bottom = 0; + break; + case winrt::CornerRadiusToThicknessConverterKind::FilterLeftAndRightFromBottom: + result.Left = radius.BottomLeft; + result.Right = radius.BottomRight; + result.Top = 0; + result.Bottom = 0; + break; + case winrt::CornerRadiusToThicknessConverterKind::FilterTopAndBottomFromLeft: + result.Left = 0; + result.Right = 0; + result.Top = radius.TopLeft; + result.Bottom = radius.BottomLeft; + break; + case winrt::CornerRadiusToThicknessConverterKind::FilterTopAndBottomFromRight: + result.Left = 0; + result.Right = 0; + result.Top = radius.TopRight; + result.Bottom = radius.BottomRight; + break; + } + + return result; +} + +winrt::IInspectable CornerRadiusToThicknessConverter::Convert( + winrt::IInspectable const& value, + winrt::TypeName const& targetType, + winrt::IInspectable const& parameter, + winrt::hstring const& language) +{ + auto radius = unbox_value(value); + + return box_value(Convert(radius, ConversionKind())); +} + +winrt::IInspectable CornerRadiusToThicknessConverter::ConvertBack( + winrt::IInspectable const& value, + winrt::TypeName const& targetType, + winrt::IInspectable const& parameter, + winrt::hstring const& language) +{ + winrt::throw_hresult(E_NOTIMPL); +} diff --git a/dev/Common/CornerRadiusToThicknessConverter.h b/dev/Common/CornerRadiusToThicknessConverter.h new file mode 100644 index 0000000000..887657a36c --- /dev/null +++ b/dev/Common/CornerRadiusToThicknessConverter.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma once +#include "CornerRadiusToThicknessConverter.g.h" +#include "CornerRadiusToThicknessConverter.properties.h" + +class CornerRadiusToThicknessConverter : + public winrt::implementation::CornerRadiusToThicknessConverterT, + public CornerRadiusToThicknessConverterProperties +{ +public: + winrt::Thickness Convert( + winrt::CornerRadius const& radius, + winrt::CornerRadiusToThicknessConverterKind const& filterKind); + + winrt::IInspectable Convert( + winrt::IInspectable const& value, + winrt::TypeName const& targetType, + winrt::IInspectable const& parameter, + winrt::hstring const& language); + + winrt::IInspectable ConvertBack( + winrt::IInspectable const& value, + winrt::TypeName const& targetType, + winrt::IInspectable const& parameter, + winrt::hstring const& language); +}; diff --git a/dev/Common/CornerRadiusToThicknessConverter.idl b/dev/Common/CornerRadiusToThicknessConverter.idl new file mode 100644 index 0000000000..30a9aef4ee --- /dev/null +++ b/dev/Common/CornerRadiusToThicknessConverter.idl @@ -0,0 +1,27 @@ +namespace MU_XCP_NAMESPACE +{ + +[WUXC_VERSION_MUXONLY] +[webhosthidden] +[default_interface] +runtimeclass CornerRadiusToThicknessConverter : Windows.UI.Xaml.DependencyObject, Windows.UI.Xaml.Data.IValueConverter +{ + CornerRadiusToThicknessConverter(); + + [MUX_DEFAULT_VALUE("winrt::CornerRadiusToThicknessConverterKind::FilterLeftAndRightFromTop")] + CornerRadiusToThicknessConverterKind ConversionKind{ get; set; }; + + static Windows.UI.Xaml.DependencyProperty ConversionKindProperty{ get; }; +}; + +[WUXC_VERSION_MUXONLY] +[webhosthidden] +enum CornerRadiusToThicknessConverterKind +{ + FilterTopAndBottomFromLeft, + FilterTopAndBottomFromRight, + FilterLeftAndRightFromTop, + FilterLeftAndRightFromBottom, +}; + +} diff --git a/dev/CommonStyles/CornerRadius_themeresources.xaml b/dev/CommonStyles/CornerRadius_themeresources.xaml index f1416c5464..00f8627aee 100644 --- a/dev/CommonStyles/CornerRadius_themeresources.xaml +++ b/dev/CommonStyles/CornerRadius_themeresources.xaml @@ -24,5 +24,11 @@ - + + + + + + + diff --git a/dev/Generated/CornerRadiusToThicknessConverter.properties.cpp b/dev/Generated/CornerRadiusToThicknessConverter.properties.cpp new file mode 100644 index 0000000000..fb20748051 --- /dev/null +++ b/dev/Generated/CornerRadiusToThicknessConverter.properties.cpp @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen +#include "pch.h" +#include "common.h" +#include "CornerRadiusToThicknessConverter.h" + +CppWinRTActivatableClassWithDPFactory(CornerRadiusToThicknessConverter) + +GlobalDependencyProperty CornerRadiusToThicknessConverterProperties::s_ConversionKindProperty{ nullptr }; + +CornerRadiusToThicknessConverterProperties::CornerRadiusToThicknessConverterProperties() +{ + EnsureProperties(); +} + +void CornerRadiusToThicknessConverterProperties::EnsureProperties() +{ + if (!s_ConversionKindProperty) + { + s_ConversionKindProperty = + InitializeDependencyProperty( + L"ConversionKind", + winrt::name_of(), + winrt::name_of(), + false /* isAttached */, + ValueHelper::BoxValueIfNecessary(winrt::CornerRadiusToThicknessConverterKind::FilterLeftAndRightFromTop), + nullptr); + } +} + +void CornerRadiusToThicknessConverterProperties::ClearProperties() +{ + s_ConversionKindProperty = nullptr; +} + +void CornerRadiusToThicknessConverterProperties::ConversionKind(winrt::CornerRadiusToThicknessConverterKind const& value) +{ + static_cast(this)->SetValue(s_ConversionKindProperty, ValueHelper::BoxValueIfNecessary(value)); +} + +winrt::CornerRadiusToThicknessConverterKind CornerRadiusToThicknessConverterProperties::ConversionKind() +{ + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_ConversionKindProperty)); +} diff --git a/dev/Generated/CornerRadiusToThicknessConverter.properties.h b/dev/Generated/CornerRadiusToThicknessConverter.properties.h new file mode 100644 index 0000000000..49352ed4e6 --- /dev/null +++ b/dev/Generated/CornerRadiusToThicknessConverter.properties.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen +#pragma once + +class CornerRadiusToThicknessConverterProperties +{ +public: + CornerRadiusToThicknessConverterProperties(); + + void ConversionKind(winrt::CornerRadiusToThicknessConverterKind const& value); + winrt::CornerRadiusToThicknessConverterKind ConversionKind(); + + static winrt::DependencyProperty ConversionKindProperty() { return s_ConversionKindProperty; } + + static GlobalDependencyProperty s_ConversionKindProperty; + + static void EnsureProperties(); + static void ClearProperties(); +}; diff --git a/dev/Generated/ThicknessFilterConverter.properties.cpp b/dev/Generated/ThicknessFilterConverter.properties.cpp new file mode 100644 index 0000000000..d96c0f2eb9 --- /dev/null +++ b/dev/Generated/ThicknessFilterConverter.properties.cpp @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen +#include "pch.h" +#include "common.h" +#include "ThicknessFilterConverter.h" + +CppWinRTActivatableClassWithDPFactory(ThicknessFilterConverter) + +GlobalDependencyProperty ThicknessFilterConverterProperties::s_FilterProperty{ nullptr }; + +ThicknessFilterConverterProperties::ThicknessFilterConverterProperties() +{ + EnsureProperties(); +} + +void ThicknessFilterConverterProperties::EnsureProperties() +{ + if (!s_FilterProperty) + { + s_FilterProperty = + InitializeDependencyProperty( + L"Filter", + winrt::name_of(), + winrt::name_of(), + false /* isAttached */, + ValueHelper::BoxValueIfNecessary(winrt::ThicknessFilterConverterKind::Top), + nullptr); + } +} + +void ThicknessFilterConverterProperties::ClearProperties() +{ + s_FilterProperty = nullptr; +} + +void ThicknessFilterConverterProperties::Filter(winrt::ThicknessFilterConverterKind const& value) +{ + static_cast(this)->SetValue(s_FilterProperty, ValueHelper::BoxValueIfNecessary(value)); +} + +winrt::ThicknessFilterConverterKind ThicknessFilterConverterProperties::Filter() +{ + return ValueHelper::CastOrUnbox(static_cast(this)->GetValue(s_FilterProperty)); +} diff --git a/dev/Generated/ThicknessFilterConverter.properties.h b/dev/Generated/ThicknessFilterConverter.properties.h new file mode 100644 index 0000000000..3f19a8800b --- /dev/null +++ b/dev/Generated/ThicknessFilterConverter.properties.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen +#pragma once + +class ThicknessFilterConverterProperties +{ +public: + ThicknessFilterConverterProperties(); + + void Filter(winrt::ThicknessFilterConverterKind const& value); + winrt::ThicknessFilterConverterKind Filter(); + + static winrt::DependencyProperty FilterProperty() { return s_FilterProperty; } + + static GlobalDependencyProperty s_FilterProperty; + + static void EnsureProperties(); + static void ClearProperties(); +}; diff --git a/dev/TeachingTip/TeachingTip.h b/dev/TeachingTip/TeachingTip.h index 48a1a95684..2be3766597 100644 --- a/dev/TeachingTip/TeachingTip.h +++ b/dev/TeachingTip/TeachingTip.h @@ -238,18 +238,18 @@ class TeachingTip : } // These values are shifted by one because this is the 1px highlight that sits adjacent to the tip border. - inline winrt::Thickness BottomPlacementTopRightHighlightMargin(double width, double height) { return { (width / 2) + (TailShortSideLength() - 1.0f), 0, 1, 0 }; } - inline winrt::Thickness BottomRightPlacementTopRightHighlightMargin(double width, double height) { return { MinimumTipEdgeToTailEdgeMargin() + TailLongSideLength() - 1.0f, 0, 1, 0 }; } - inline winrt::Thickness BottomLeftPlacementTopRightHighlightMargin(double width, double height) { return { width - (MinimumTipEdgeToTailEdgeMargin() + 1.0f), 0, 1, 0 }; } + inline winrt::Thickness BottomPlacementTopRightHighlightMargin(double width, double height) { return { (width / 2) + (TailShortSideLength() - 1.0f), 0, 3, 0 }; } + inline winrt::Thickness BottomRightPlacementTopRightHighlightMargin(double width, double height) { return { MinimumTipEdgeToTailEdgeMargin() + TailLongSideLength() - 1.0f, 0, 3, 0 }; } + inline winrt::Thickness BottomLeftPlacementTopRightHighlightMargin(double width, double height) { return { width - (MinimumTipEdgeToTailEdgeMargin() + 1.0f), 0, 3, 0 }; } static inline winrt::Thickness OtherPlacementTopRightHighlightMargin(double width, double height) { return { 0, 0, 0, 0 }; } - inline winrt::Thickness BottomPlacementTopLeftHighlightMargin(double width, double height) { return { 1, 0, (width / 2) + (TailShortSideLength() - 1.0f), 0 }; } - inline winrt::Thickness BottomRightPlacementTopLeftHighlightMargin(double width, double height) { return { 1, 0, width - (MinimumTipEdgeToTailEdgeMargin() + 1.0f), 0 }; } - inline winrt::Thickness BottomLeftPlacementTopLeftHighlightMargin(double width, double height) { return { 1, 0, MinimumTipEdgeToTailEdgeMargin() + TailLongSideLength() - 1.0f, 0 }; } - static inline winrt::Thickness TopEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 1, 1, 1, 0 }; } + inline winrt::Thickness BottomPlacementTopLeftHighlightMargin(double width, double height) { return { 3, 0, (width / 2) + (TailShortSideLength() - 1.0f), 0 }; } + inline winrt::Thickness BottomRightPlacementTopLeftHighlightMargin(double width, double height) { return { 3, 0, width - (MinimumTipEdgeToTailEdgeMargin() + 1.0f), 0 }; } + inline winrt::Thickness BottomLeftPlacementTopLeftHighlightMargin(double width, double height) { return { 3, 0, MinimumTipEdgeToTailEdgeMargin() + TailLongSideLength() - 1.0f, 0 }; } + static inline winrt::Thickness TopEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 3, 1, 3, 0 }; } // Shifted by one since the tail edge's border is not accounted for automatically. - static inline winrt::Thickness LeftEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 1, 1, 0, 0 }; } - static inline winrt::Thickness RightEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 0, 1, 1, 0 }; } + static inline winrt::Thickness LeftEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 3, 1, 2, 0 }; } + static inline winrt::Thickness RightEdgePlacementTopLeftHighlightMargin(double width, double height) { return { 2, 1, 3, 0 }; } static inline double UntargetedTipFarPlacementOffset(float farWindowCoordinateInCoreWindowSpace, double tipSize, double offset) { return farWindowCoordinateInCoreWindowSpace - (tipSize + s_untargetedTipWindowEdgeMargin + offset); } static inline double UntargetedTipCenterPlacementOffset(float nearWindowCoordinateInCoreWindowSpace, float farWindowCoordinateInCoreWindowSpace, double tipSize, double nearOffset, double farOffset) { return ((nearWindowCoordinateInCoreWindowSpace + farWindowCoordinateInCoreWindowSpace) / 2) - (tipSize / 2) + nearOffset - farOffset; } diff --git a/dev/TeachingTip/TeachingTip.xaml b/dev/TeachingTip/TeachingTip.xaml index 4c0abdcd3d..f29a8ebcf8 100644 --- a/dev/TeachingTip/TeachingTip.xaml +++ b/dev/TeachingTip/TeachingTip.xaml @@ -3,7 +3,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Microsoft.UI.Xaml.Controls" xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)" - xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)"> + xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)" + xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives">