Browse Source

Adjust how StyledBox is represented in the Companion app

Marcin Ziąbek 5 months ago
parent
commit
f700b06cbb

+ 1 - 1
Source/QuestPDF/Companion/CompanionModels.cs

@@ -35,7 +35,7 @@ namespace QuestPDF.Companion
                 public float Height { get; set; }
             }
             
-            internal sealed class DocumentHierarchyElement
+            internal sealed record DocumentHierarchyElement
             {
                 internal Element Element { get; set; }
                 

+ 29 - 9
Source/QuestPDF/Companion/Helpers.cs

@@ -18,8 +18,7 @@ internal static class CompanionModelHelpers
         
         CompanionCommands.UpdateDocumentStructure.DocumentHierarchyElement Traverse(TreeNode<LayoutProxy> node)
         {
-            var layout = node.Value;
-            var child = layout.Child;
+            var child = node.Value.Child;
 
             while (child is ElementProxy elementProxy)
                 child = elementProxy.Child;
@@ -27,25 +26,46 @@ internal static class CompanionModelHelpers
             if (child is Container)
                 return Traverse(node.Children.Single());
             
-            var element = new CompanionCommands.UpdateDocumentStructure.DocumentHierarchyElement
+            var hierarchyElement = MapToHierarchyElement(node);
+            
+            // special case to optimize the hierarchy structure in the Companion App
+            if (child is StyledBox styledBox)
             {
-                Element = child,
+                var customContentChildren = styledBox
+                    .GetCompanionCustomContent()
+                    .Select(x => hierarchyElement with { ElementType = x.Type, Hint = x.Hint })
+                    .ToArray();
+
+                if (customContentChildren.Length == 0)
+                    return hierarchyElement;
+                
+                for (var i = 0; i <= customContentChildren.Length - 2; i++)
+                    customContentChildren[i].Children = [customContentChildren[i + 1]];
+                
+                return customContentChildren.First();
+            }
+
+            return hierarchyElement;
+        }
+        
+        CompanionCommands.UpdateDocumentStructure.DocumentHierarchyElement MapToHierarchyElement(TreeNode<LayoutProxy> node)
+        {
+            var layout = node.Value;
+            var child = layout.Child;
                 
+            return new CompanionCommands.UpdateDocumentStructure.DocumentHierarchyElement
+            {
+                Element = child,
                 ElementType = child.GetType().Name,
                 Hint = child.GetCompanionHint(),
                 SearchableContent = child.GetCompanionSearchableContent(),
-                
                 PageLocations = layout.Snapshots,
                 SourceCodeDeclarationPath = GetSourceCodePath(child.CodeLocation),
                 LayoutErrorMeasurements = layout.LayoutErrorMeasurements,
-                
                 IsSingleChildContainer = child is ContainerElement,
                 Properties = child.GetCompanionProperties()?.Select(x => new CompanionCommands.ElementProperty { Label = x.Key, Value = x.Value }).ToList() ?? [],
-                
                 Children = node.Children.Select(Traverse).ToList()
             };
-
-            return element;
         }
     }
 

+ 46 - 0
Source/QuestPDF/Elements/StyledBox.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using QuestPDF.Drawing.DrawingCanvases;
 using QuestPDF.Helpers;
@@ -14,6 +15,12 @@ namespace QuestPDF.Elements
         public float BorderRight { get; set; }
         public float BorderBottom { get; set; }
 
+        private bool HasBorder =>
+            BorderLeft > 0 || 
+            BorderTop > 0 || 
+            BorderRight > 0 || 
+            BorderBottom > 0;
+        
         private bool HasFullBorder =>
             BorderLeft > 0 && 
             BorderTop > 0 && 
@@ -35,6 +42,11 @@ namespace QuestPDF.Elements
             BorderRadiusTopRight > 0 || 
             BorderRadiusBottomLeft > 0 || 
             BorderRadiusBottomRight > 0;
+        
+        private bool HasUniformRoundedCorners =>
+            BorderRadiusTopLeft == BorderRadiusTopRight && 
+            BorderRadiusBottomLeft == BorderRadiusBottomRight && 
+            BorderRadiusTopLeft == BorderRadiusBottomLeft;
   
         public float? BorderAlignment { get; set; } // 0 = inset, 1 = outset
     
@@ -308,5 +320,39 @@ namespace QuestPDF.Elements
                 }
             };
         }
+
+        internal IEnumerable<(string Type, string? Hint)> GetCompanionCustomContent()
+        {
+            // shadow
+            if (Shadow != null)
+                yield return ("Shadow", null);
+
+            // rounded corners
+            if (HasRoundedCorners)
+            {
+                if (HasUniformRoundedCorners)
+                    yield return ("Border", $"R={BorderRadiusTopLeft}");
+                else
+                    yield return ("Border", $"TL={BorderRadiusTopLeft}   TR={BorderRadiusTopRight}   BL={BorderRadiusBottomLeft}   BR={BorderRadiusBottomRight}");
+            }
+
+            // border
+            if (HasBorder)
+            {
+                var color = BorderGradientColors.Any() ? "gradient" : BorderColor.ToString();
+                
+                if (HasUniformBorder)
+                    yield return ("Border", $"A={BorderLeft}   C={color}");
+                else
+                    yield return ("Border", $"L={BorderLeft}   T={BorderTop}   R={BorderRight}   B={BorderBottom}   C={color}");
+            }
+
+            // background
+            if (BackgroundGradientColors.Length > 0)
+                yield return ("Background", $"Gradient with {BackgroundGradientColors.Length} colors");
+
+            else if (BackgroundColor.Hex != Colors.Transparent.Hex)
+                yield return ("Background", BackgroundColor);
+        }
     }
 }