From 0ede3e01fea4eac5ce4e4b9d0226628291974597 Mon Sep 17 00:00:00 2001 From: almedina-ms <35784165+almedina-ms@users.noreply.github.com> Date: Thu, 23 May 2019 15:36:23 -0700 Subject: [PATCH] [.NET][WPF][HTML] Fix Bleed behaviour for columns (#2879) * Fix visibility issue for columns * Fix separator issue in WPF * Almost fix HTML renderer * Fix toggle visibility select actions * Add test for checking initial state of separators * Fix html for hiding separators in initial state * Fix logic in column separators * Fix sample app to render tall cards * Fix PR Comments * Fix test files * Fix test results * Fix comments * Add test app results * Fix more comments * Add results for new card * Fix behaviour for bleed in WPF * Fix HTML behavior * Fix HTML tes * Fix some of the PR comments * Fix PR comments --- .../AdaptiveCardRenderer.cs | 104 ++++++++---------- .../AdaptiveColumnRenderer.cs | 2 +- .../AdaptiveColumnSetRenderer.cs | 94 ++++------------ .../AdaptiveContainerRenderer.cs | 84 +++++++++----- .../Rendering/AdaptiveRenderArgs.cs | 12 +- .../HtmlRendererTests.cs | 2 +- 6 files changed, 138 insertions(+), 160 deletions(-) diff --git a/source/dotnet/Library/AdaptiveCards.Rendering.Html/AdaptiveCardRenderer.cs b/source/dotnet/Library/AdaptiveCards.Rendering.Html/AdaptiveCardRenderer.cs index 5721c0f478..b8dcd3df9e 100644 --- a/source/dotnet/Library/AdaptiveCards.Rendering.Html/AdaptiveCardRenderer.cs +++ b/source/dotnet/Library/AdaptiveCards.Rendering.Html/AdaptiveCardRenderer.cs @@ -466,10 +466,25 @@ protected static void AddContainerElements(HtmlTag uiContainer, IList 0) + if (uiColumnSet.ColumnDefinitions.Count > 0 && (column.Separator || column.Spacing != AdaptiveSpacing.None)) { - if (column.Separator || column.Spacing != AdaptiveSpacing.None) - { - var uiSep = new Grid(); - uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator"); - - uiSep.VerticalAlignment = VerticalAlignment.Stretch; - - int spacing = context.Config.GetSpacing(column.Spacing); - uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0); + var uiSep = new Grid(); + uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator"); - uiSep.Width = context.Config.Separator.LineThickness; - if (column.Separator && context.Config.Separator.LineColor != null) - { - uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor); - } + uiSep.VerticalAlignment = VerticalAlignment.Stretch; - tag = new TagContent(uiSep, uiColumnSet); + int spacing = context.Config.GetSpacing(column.Spacing); + uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0); - uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); - Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1); - uiColumnSet.Children.Add(uiSep); - } - else + uiSep.Width = context.Config.Separator.LineThickness; + if (column.Separator && context.Config.Separator.LineColor != null) { - tag = new TagContent(null, uiColumnSet); + uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor); } + + tag = new TagContent(uiSep, uiColumnSet); + + uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); + Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1); + uiColumnSet.Children.Add(uiSep); } else { diff --git a/source/dotnet/Library/AdaptiveCards.Rendering.Wpf/AdaptiveContainerRenderer.cs b/source/dotnet/Library/AdaptiveCards.Rendering.Wpf/AdaptiveContainerRenderer.cs index 2777901186..c6c9ad95af 100644 --- a/source/dotnet/Library/AdaptiveCards.Rendering.Wpf/AdaptiveContainerRenderer.cs +++ b/source/dotnet/Library/AdaptiveCards.Rendering.Wpf/AdaptiveContainerRenderer.cs @@ -58,7 +58,7 @@ public static FrameworkElement Render(AdaptiveContainer container, AdaptiveRende if (hasPadding) { - childRenderArgs.BleedDirection = BleedDirection.Both; + childRenderArgs.BleedDirection = BleedDirection.BleedAll; } // Modify context outer parent style so padding necessity can be determined @@ -76,8 +76,24 @@ public static FrameworkElement Render(AdaptiveContainer container, AdaptiveRende public static void AddContainerElements(Grid uiContainer, IList elements, AdaptiveRenderContext context) { + // Keeping track of the index so we don't have to call IndexOf function on every iteration + int index = 0; foreach (var cardElement in elements) { + if (index != 0) + { + // Only the first element can bleed to the top + context.RenderArgs.BleedDirection &= ~BleedDirection.BleedUp; + } + + if (index != elements.Count - 1) + { + // Only the last element can bleed to the bottom + context.RenderArgs.BleedDirection &= ~BleedDirection.BleedDown; + } + + index++; + // each element has a row FrameworkElement uiElement = context.Render(cardElement); if (uiElement != null) @@ -128,17 +144,16 @@ public static void AddContainerElements(Grid uiContainer, IList uiContainer.RowDefinitions.Add(rowDefinition); + // Row definition is stored in the tag for containers and elements that stretch + // so when the elements are shown, the row can have it's original definition, + // while when the element is hidden, the extra space is not reserved in the layout + tag.RowDefinition = rowDefinition; + tag.ViewIndex = rowDefinitionIndex; + if (cardElement.Type == "Container") { Grid.SetRow(uiElement, rowDefinitionIndex); uiContainer.Children.Add(uiElement); - - // Row definition is stored in the tag for containers and elements that stretch - // so when the elements are shown, the row can have it's original definition, - // while when the element is hidden, the extra space is not reserved in the layout - tag.RowDefinition = rowDefinition; - tag.ViewIndex = rowDefinitionIndex; - context.SetVisibility(uiElement, cardElement.IsVisible, tag); } else @@ -155,13 +170,6 @@ public static void AddContainerElements(Grid uiContainer, IList Grid.SetRow(panel, rowDefinitionIndex); uiContainer.Children.Add(panel); - - // Row definition is stored in the tag for containers and elements that stretch - // so when the elements are shown, the row can have it's original definition, - // while when the element is hidden, the extra space is not reserved in the layout - tag.RowDefinition = rowDefinition; - tag.ViewIndex = rowDefinitionIndex; - context.SetVisibility(panel, cardElement.IsVisible, tag); } } @@ -187,7 +195,9 @@ public static void AddContainerElements(Grid uiContainer, IList public static Grid AddSpacing(AdaptiveRenderContext context, AdaptiveElement element, Grid uiContainer) { if (element.Spacing == AdaptiveSpacing.None) + { return null; + } var uiSpa = new Grid(); uiSpa.Style = context.GetStyle($"Adaptive.Spacing"); @@ -205,7 +215,9 @@ public static Grid AddSpacing(AdaptiveRenderContext context, AdaptiveElement ele public static Grid AddSeparator(AdaptiveRenderContext context, AdaptiveElement element, Grid uiContainer) { if (element.Spacing == AdaptiveSpacing.None && !element.Separator) + { return null; + } var uiSep = new Grid(); uiSep.Style = context.GetStyle($"Adaptive.Separator"); @@ -224,6 +236,33 @@ public static Grid AddSeparator(AdaptiveRenderContext context, AdaptiveElement e return uiSep; } + private static Thickness GetBleedMargin(AdaptiveRenderArgs parentRenderArgs, int padding) + { + Thickness bleedMargin = new Thickness(0); + + if ((parentRenderArgs.BleedDirection & BleedDirection.BleedLeft) != BleedDirection.BleedNone) + { + bleedMargin.Left = padding; + } + + if ((parentRenderArgs.BleedDirection & BleedDirection.BleedRight) != BleedDirection.BleedNone) + { + bleedMargin.Right = padding; + } + + if ((parentRenderArgs.BleedDirection & BleedDirection.BleedUp) != BleedDirection.BleedNone) + { + bleedMargin.Top = padding; + } + + if ((parentRenderArgs.BleedDirection & BleedDirection.BleedDown) != BleedDirection.BleedNone) + { + bleedMargin.Bottom = padding; + } + + return bleedMargin; + } + // For applying bleeding, we must know if the element has padding, so both properties are applied in the same method public static bool ApplyPadding(Border border, Grid uiElement, AdaptiveCollectionElement element, AdaptiveRenderArgs parentRenderArgs, AdaptiveRenderContext context) { @@ -243,22 +282,11 @@ public static bool ApplyPadding(Border border, Grid uiElement, AdaptiveCollectio if (canApplyPadding) { - uiElement.Margin = new Thickness { Left = padding, Top = padding, Right = padding, Bottom = padding }; + uiElement.Margin = new Thickness(padding); if (element.Bleed) { - int leftMargin = 0, rightMargin = 0; - if (parentRenderArgs.BleedDirection == BleedDirection.Left || parentRenderArgs.BleedDirection == BleedDirection.Both) - { - leftMargin = -padding; - } - - if (parentRenderArgs.BleedDirection == BleedDirection.Right || parentRenderArgs.BleedDirection == BleedDirection.Both) - { - rightMargin = -padding; - } - - border.Margin = new Thickness { Left = leftMargin, Right = rightMargin }; + border.Margin = GetBleedMargin(parentRenderArgs, -padding); } } diff --git a/source/dotnet/Library/AdaptiveCards/Rendering/AdaptiveRenderArgs.cs b/source/dotnet/Library/AdaptiveCards/Rendering/AdaptiveRenderArgs.cs index 7041caec0b..693a7aabbe 100644 --- a/source/dotnet/Library/AdaptiveCards/Rendering/AdaptiveRenderArgs.cs +++ b/source/dotnet/Library/AdaptiveCards/Rendering/AdaptiveRenderArgs.cs @@ -9,7 +9,15 @@ // This class contains all properties that are used for rendering and need to be passed down between parent and child elements namespace AdaptiveCards.Rendering { - public enum BleedDirection { Left, Both, Right, None }; + public enum BleedDirection + { + BleedNone = 0x0000, + BleedLeft = 0x0001, + BleedRight = 0x0010, + BleedUp = 0x0100, + BleedDown = 0x1000, + BleedAll = 0x1111 + }; public class AdaptiveRenderArgs { @@ -29,7 +37,7 @@ public AdaptiveRenderArgs(AdaptiveRenderArgs previousRenderArgs) public ForegroundColorsConfig ForegroundColors { get; set; } // Default value for the direction where the elements of the adaptive card can bleed to - public BleedDirection BleedDirection { get; set; } = BleedDirection.Both; + public BleedDirection BleedDirection { get; set; } = BleedDirection.BleedAll; public bool HasParentWithPadding { get; set; } = true; diff --git a/source/dotnet/Test/AdaptiveCards.Rendering.Html.Test/HtmlRendererTests.cs b/source/dotnet/Test/AdaptiveCards.Rendering.Html.Test/HtmlRendererTests.cs index 162602c878..bafd1671b7 100644 --- a/source/dotnet/Test/AdaptiveCards.Rendering.Html.Test/HtmlRendererTests.cs +++ b/source/dotnet/Test/AdaptiveCards.Rendering.Html.Test/HtmlRendererTests.cs @@ -345,7 +345,7 @@ public void BleedProperty() // Generated HTML should have an additional disabled and hidden option which is selected. Assert.AreEqual( - "
", + "
", workingBleedHtml); Assert.AreEqual(