Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let teachingtip treat placement logically not physically #3165

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,12 @@ public CheckBox GetTeachingTipContentUnloadedCheck()
}
private CheckBox effectiveTeachingTipContentUnloadedCheckbox;

public CheckBox GetPageRTLCheckbox()
{
return GetElement(ref effectivePageRTLCheckbox, "PageRTLCheckbox");
}
private CheckBox effectivePageRTLCheckbox;

public Button GetRemoveOpenButtonFromVisualTreeButton()
{
return GetElement(ref effectiveRemoveOpenButton, "RemoveButtonFromVisualTreeButton");
Expand Down
179 changes: 179 additions & 0 deletions dev/TeachingTip/InteractionTests/TeachingTipTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ public void SpecifiedPlacement()
var targetRect = GetTargetBounds();

// All positions are valid
// The following might not always work, so repeat.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// The following might not always work, so repeat. [](start = 20, length = 50)

Really? what happens? was that the case before this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not entirely sure what the root cause is, however when running those tests locally, I noticed that the rect (and the red border we use to show it) don't always show up. The problem is that this leaves the TeachingTip to believe it has more space and fails the test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wasn't this causing the test to fail before this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test was very unreliable on my machine before that change, only 20% of the time it actually ran through.

UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);
UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
Expand Down Expand Up @@ -502,6 +504,183 @@ public void SpecifiedPlacement()
}
}

[TestMethod]
public void SpecifiedPlacementRTL()
{
using (var setup = new TestSetupHelper("TeachingTip Tests"))
{
elements = new TeachingTipTestPageElements();

foreach (TipLocationOptions location in Enum.GetValues(typeof(TipLocationOptions)))
{
SetTeachingTipLocation(location);

ScrollTargetIntoView();
ScrollBy(10);

elements.GetPageRTLCheckbox().Check();

SetHeroContent(HeroContentOptions.NoContent);

var targetRect = GetTargetBounds();

// All positions are valid
// The following might not always work, so repeat.
UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);
UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.Bottom);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.Left);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.Right);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.TopRight);
VerifyPlacement("TopLeft");
SetPreferredPlacement(PlacementOptions.TopLeft);
VerifyPlacement("TopRight");
SetPreferredPlacement(PlacementOptions.BottomRight);
VerifyPlacement("BottomLeft");
SetPreferredPlacement(PlacementOptions.BottomLeft);
VerifyPlacement("BottomRight");
SetPreferredPlacement(PlacementOptions.LeftTop);
VerifyPlacement("RightTop");
SetPreferredPlacement(PlacementOptions.LeftBottom);
VerifyPlacement("RightBottom");
SetPreferredPlacement(PlacementOptions.RightTop);
VerifyPlacement("LeftTop");
SetPreferredPlacement(PlacementOptions.RightBottom);
VerifyPlacement("LeftBottom");
SetPreferredPlacement(PlacementOptions.Center);
VerifyPlacement("Center");

// Eliminate left of the target
UseTestBounds(targetRect.W - 120, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.Bottom);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.Left);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.Right);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.TopRight);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.TopLeft);
VerifyPlacement("TopRight");
SetPreferredPlacement(PlacementOptions.BottomRight);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.BottomLeft);
VerifyPlacement("BottomRight");
SetPreferredPlacement(PlacementOptions.LeftTop);
VerifyPlacement("RightTop");
SetPreferredPlacement(PlacementOptions.LeftBottom);
VerifyPlacement("RightBottom");
SetPreferredPlacement(PlacementOptions.RightTop);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.RightBottom);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.Center);
VerifyPlacement("Center");

// Eliminate top of the target
UseTestBounds(targetRect.W - 500, targetRect.X - 1, targetRect.Y + 1000, targetRect.Z + 1000, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.Bottom);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.Left);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.Right);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.TopRight);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.TopLeft);
VerifyPlacement("Bottom");
SetPreferredPlacement(PlacementOptions.BottomRight);
VerifyPlacement("BottomLeft");
SetPreferredPlacement(PlacementOptions.BottomLeft);
VerifyPlacement("BottomRight");
SetPreferredPlacement(PlacementOptions.LeftTop);
VerifyPlacement("RightTop");
SetPreferredPlacement(PlacementOptions.LeftBottom);
VerifyPlacement("RightBottom");
SetPreferredPlacement(PlacementOptions.RightTop);
VerifyPlacement("LeftTop");
SetPreferredPlacement(PlacementOptions.RightBottom);
VerifyPlacement("LeftBottom");
SetPreferredPlacement(PlacementOptions.Center);
VerifyPlacement("Center");

// Eliminate right of the target
UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 500, targetRect.Z + 1000, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.Bottom);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.Left);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.Right);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.TopRight);
VerifyPlacement("TopLeft");
SetPreferredPlacement(PlacementOptions.TopLeft);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.BottomRight);
VerifyPlacement("BottomLeft");
SetPreferredPlacement(PlacementOptions.BottomLeft);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.LeftTop);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.LeftBottom);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.RightTop);
VerifyPlacement("LeftTop");
SetPreferredPlacement(PlacementOptions.RightBottom);
VerifyPlacement("LeftBottom");
SetPreferredPlacement(PlacementOptions.Center);
VerifyPlacement("Left");

// Eliminate bottom of target
UseTestBounds(targetRect.W - 500, targetRect.X - 500, targetRect.Y + 1000, targetRect.Z + 501, targetRect, true);

SetPreferredPlacement(PlacementOptions.Top);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.Bottom);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.Left);
VerifyPlacement("Right");
SetPreferredPlacement(PlacementOptions.Right);
VerifyPlacement("Left");
SetPreferredPlacement(PlacementOptions.TopRight);
VerifyPlacement("TopLeft");
SetPreferredPlacement(PlacementOptions.TopLeft);
VerifyPlacement("TopRight");
SetPreferredPlacement(PlacementOptions.BottomRight);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.BottomLeft);
VerifyPlacement("Top");
SetPreferredPlacement(PlacementOptions.LeftTop);
VerifyPlacement("RightTop");
SetPreferredPlacement(PlacementOptions.LeftBottom);
VerifyPlacement("RightBottom");
SetPreferredPlacement(PlacementOptions.RightTop);
VerifyPlacement("LeftTop");
SetPreferredPlacement(PlacementOptions.RightBottom);
VerifyPlacement("LeftBottom");
SetPreferredPlacement(PlacementOptions.Center);
VerifyPlacement("Center");

elements.GetPageRTLCheckbox().Uncheck();
}
}
}


[TestMethod]
public void NoIconDoesNotCrash()
Expand Down
52 changes: 48 additions & 4 deletions dev/TeachingTip/TeachingTip.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "pch.h"
#include "pch.h"
#include "common.h"
#include "TeachingTip.h"
#include "RuntimeProfiler.h"
Expand Down Expand Up @@ -556,7 +556,7 @@ bool TeachingTip::PositionUntargetedPopup()
// offset property to determine the appropriate vertical and horizontal offsets of the popup that the tip is contained in.
if (auto&& popup = m_popup.get())
{
switch (PreferredPlacement())
switch (GetFlowDirectionAdjustedPlacement(PreferredPlacement()))
{
case winrt::TeachingTipPlacementMode::Auto:
case winrt::TeachingTipPlacementMode::Bottom:
Expand Down Expand Up @@ -1343,6 +1343,49 @@ void TeachingTip::ClosePopup()
}
}

winrt::TeachingTipPlacementMode TeachingTip::GetFlowDirectionAdjustedPlacement(const winrt::TeachingTipPlacementMode& placementMode)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetFlowDirectionAdjustedPlacement [](start = 45, length = 33)

@jevansaks do you remember why we didn't do this for the initial check in? I know that we talked about it but I can't recall what we got hung up on.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, unfortunately I don't remember either.

{
if (FlowDirection() == winrt::FlowDirection::LeftToRight)
{
return placementMode;
}
else
{
switch (placementMode)
{
case winrt::TeachingTipPlacementMode::Auto:
return winrt::TeachingTipPlacementMode::Auto;
case winrt::TeachingTipPlacementMode::Left:
return winrt::TeachingTipPlacementMode::Right;
case winrt::TeachingTipPlacementMode::Right:
return winrt::TeachingTipPlacementMode::Left;
case winrt::TeachingTipPlacementMode::Top:
return winrt::TeachingTipPlacementMode::Top;
case winrt::TeachingTipPlacementMode::Bottom:
return winrt::TeachingTipPlacementMode::Bottom;
case winrt::TeachingTipPlacementMode::LeftBottom:
return winrt::TeachingTipPlacementMode::RightBottom;
case winrt::TeachingTipPlacementMode::LeftTop:
return winrt::TeachingTipPlacementMode::RightTop;
case winrt::TeachingTipPlacementMode::TopLeft:
return winrt::TeachingTipPlacementMode::TopRight;
case winrt::TeachingTipPlacementMode::TopRight:
return winrt::TeachingTipPlacementMode::TopLeft;
case winrt::TeachingTipPlacementMode::RightTop:
return winrt::TeachingTipPlacementMode::LeftTop;
case winrt::TeachingTipPlacementMode::RightBottom:
return winrt::TeachingTipPlacementMode::LeftBottom;
case winrt::TeachingTipPlacementMode::BottomRight:
return winrt::TeachingTipPlacementMode::BottomLeft;
case winrt::TeachingTipPlacementMode::BottomLeft:
return winrt::TeachingTipPlacementMode::BottomRight;
case winrt::TeachingTipPlacementMode::Center:
return winrt::TeachingTipPlacementMode::Center;
}
}
return winrt::TeachingTipPlacementMode::Auto;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeachingTipPlacementMode [](start = 18, length = 24)

Is this needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either this or a default cause for our switch case, otherwise not all code paths would return a value according to the compiler.

}

void TeachingTip::OnTargetChanged()
{
m_targetLayoutUpdatedRevoker.revoke();
Expand Down Expand Up @@ -1668,7 +1711,7 @@ std::tuple<winrt::TeachingTipPlacementMode, bool> TeachingTip::DetermineEffectiv
// SetReturnTopForOutOfWindowBounds test hook.
if (!ShouldConstrainToRootBounds() && m_returnTopForOutOfWindowPlacement)
{
auto const placement = PreferredPlacement();
auto const placement = GetFlowDirectionAdjustedPlacement(PreferredPlacement());
if (placement == winrt::TeachingTipPlacementMode::Auto)
{
return std::make_tuple(winrt::TeachingTipPlacementMode::Top, false);
Expand Down Expand Up @@ -1893,7 +1936,8 @@ std::tuple<winrt::TeachingTipPlacementMode, bool> TeachingTip::DetermineEffectiv
availability[winrt::TeachingTipPlacementMode::RightBottom] = false;
}

auto const priorities = GetPlacementFallbackOrder(PreferredPlacement());
auto const wantedDirection = GetFlowDirectionAdjustedPlacement(PreferredPlacement());
auto const priorities = GetPlacementFallbackOrder(wantedDirection);

for (auto const mode : priorities)
{
Expand Down
2 changes: 2 additions & 0 deletions dev/TeachingTip/TeachingTip.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ class TeachingTip :
void ClosePopupWithAnimationIfAvailable();
void ClosePopup();

winrt::TeachingTipPlacementMode GetFlowDirectionAdjustedPlacement(const winrt::TeachingTipPlacementMode& placementMode);

void SetViewportChangedEvent(const gsl::strict_not_null<winrt::FrameworkElement>& target);
void RevokeViewportChangedEvent();
void WindowSizeChanged(const winrt::CoreWindow&, const winrt::WindowSizeChangedEventArgs&);
Expand Down
2 changes: 1 addition & 1 deletion dev/TeachingTip/TestUI/TeachingTipPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@
<Slider Grid.Row="46" Grid.ColumnSpan="2" Minimum="0" Maximum="100" ValueChanged="TailElevationSliderChanged" Value="0"/>

<TextBlock Grid.Row="47" Foreground="Red" Text="Is Page RTL" VerticalAlignment="Center"/>
<CheckBox Grid.Row="47" Grid.Column="1" IsChecked="{x:Bind IsPageRTL, Mode=TwoWay}"/>
<CheckBox Grid.Row="47" Grid.Column="1" AutomationProperties.Name="PageRTLCheckbox" IsChecked="{x:Bind IsPageRTL, Mode=TwoWay}"/>
<Button Grid.Row="48" Grid.Column="0" x:Name="RemoveTeachingTipButton" Click="RemoveTeachingTipButton_Click">Remove tooltip from page</Button>
<CheckBox Grid.Row="48" Grid.Column="1" x:Name="VisualTreeTeachingTipContentTextBlockUnloaded">Visual tree teachingtip unloaded</CheckBox>
<Button Grid.Row="49" x:Name="RemoveButtonFromVisualTreeButton" Click="RemoveOpenButton_Click">Remove button from visual tree</Button>
Expand Down