From 37aa84edfb628872e1d94dc91a1c38d7d82b660d Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Fri, 22 Aug 2025 01:51:32 +0800 Subject: [PATCH 1/6] feat: initial implemention. --- .../Panels/WrapPanelWithTrailingItem.cs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs diff --git a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs new file mode 100644 index 0000000..d2600a3 --- /dev/null +++ b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs @@ -0,0 +1,99 @@ +using System.Collections.Specialized; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; +using Irihi.Avalonia.Shared.Helpers; + +namespace Ursa.Controls.Panels; + +public class WrapPanelWithTrailingItem: Panel +{ + public static readonly StyledProperty TrailingItemProperty = AvaloniaProperty.Register( + nameof(TrailingItem)); + + public Layoutable? TrailingItem + { + get => GetValue(TrailingItemProperty); + set => SetValue(TrailingItemProperty, value); + } + + + + static WrapPanelWithTrailingItem() + { + AffectsMeasure(TrailingItemProperty); + AffectsArrange(TrailingItemProperty); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property == TrailingItemProperty) + { + if(change.GetOldValue() is { } oldValue) + { + VisualChildren.Remove(oldValue); + LogicalChildren.Remove(oldValue); + } + if(change.GetNewValue() is {} newValue) + { + VisualChildren.Add(newValue); + LogicalChildren.Add(newValue); + } + } + + WrapPanel p = new WrapPanel(); + } + + protected override void ChildrenChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + base.ChildrenChanged(sender, e); + } + + protected override Size MeasureOverride(Size availableSize) + { + double currentLineX = 0; + double currentLineHeight = 0; + double totalHeight = 0; + + var children = Children; + foreach (var child in children) + { + child.Measure(availableSize); + double deltaX = availableSize.Width - currentLineX; + // Width is enough to place next child + if (MathHelpers.GreaterThan(deltaX, child.DesiredSize.Width)) + { + currentLineX+=child.DesiredSize.Width; + currentLineHeight = Math.Max(currentLineHeight, child.DesiredSize.Height); + } + // Width is not enough to place next child + // reset currentLineX and currentLineHeight + // accumulate last line height to total height. + // Notice: last line height accumulation only happens when restarting a new line, so it needs to finally add one more time outside iteration. + else + { + currentLineX = child.DesiredSize.Width; + totalHeight += currentLineHeight; + currentLineHeight = child.DesiredSize.Height; + } + } + + var last = TrailingItem; + last.Measure(availableSize); + double lastDeltaX = availableSize.Width - currentLineX; + // If width is not enough, add a new line, and recalculate total height + if (lastDeltaX < 30) + { + totalHeight+=currentLineHeight; + totalHeight += last.DesiredSize.Height; + } + else + { + currentLineHeight = Math.Max(currentLineHeight, last.DesiredSize.Height); + totalHeight += currentLineHeight; + } + + return new Size(availableSize.Width, totalHeight); + } +} \ No newline at end of file From bce6e08561ec6359e459f7c94a5b160374d2ced0 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 3 Sep 2025 15:26:38 +0800 Subject: [PATCH 2/6] feat: add tests. --- .../Panels/WrapPanelWithTrailingItem.cs | 67 +++++++- .../WrapPanelWithTrailingItemTests.cs | 155 ++++++++++++++++++ 2 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs diff --git a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs index d2600a3..d6cefed 100644 --- a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs +++ b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs @@ -30,15 +30,21 @@ public class WrapPanelWithTrailingItem: Panel base.OnPropertyChanged(change); if (change.Property == TrailingItemProperty) { - if(change.GetOldValue() is { } oldValue) + if(change.GetOldValue() is { } oldValue) { VisualChildren.Remove(oldValue); - LogicalChildren.Remove(oldValue); + if (!IsItemsHost) + { + LogicalChildren.Remove(oldValue); + } } - if(change.GetNewValue() is {} newValue) + if(change.GetNewValue() is {} newValue) { VisualChildren.Add(newValue); - LogicalChildren.Add(newValue); + if (!IsItemsHost) + { + LogicalChildren.Add(newValue); + } } } @@ -80,6 +86,7 @@ public class WrapPanelWithTrailingItem: Panel } var last = TrailingItem; + if (last is null) return new Size(availableSize.Width, totalHeight); last.Measure(availableSize); double lastDeltaX = availableSize.Width - currentLineX; // If width is not enough, add a new line, and recalculate total height @@ -96,4 +103,56 @@ public class WrapPanelWithTrailingItem: Panel return new Size(availableSize.Width, totalHeight); } + + protected override Size ArrangeOverride(Size finalSize) + { + double currentLineX = 0; + double currentLineHeight = 0; + double totalHeight = 0; + var children = Children; + for (int i = 0; i < children.Count; i++) + { + var child = children[i]; + double deltaX = finalSize.Width - currentLineX; + // Width is enough to place next child + if (MathHelpers.GreaterThan(deltaX, child.DesiredSize.Width)) + { + child.Arrange(new Rect(currentLineX, totalHeight, child.DesiredSize.Width, Math.Max(child.DesiredSize.Height, currentLineHeight))); + currentLineX += child.DesiredSize.Width; + currentLineHeight = Math.Max(currentLineHeight, child.DesiredSize.Height); + } + // Width is not enough to place next child + // reset currentLineX and currentLineHeight + // accumulate last line height to total height. + // Notice: last line height accumulation only happens when restarting a new line, so it needs to finally add one more time outside iteration. + else + { + totalHeight += currentLineHeight; + child.Arrange(new Rect(0, totalHeight, Math.Min(child.DesiredSize.Width, finalSize.Width), child.DesiredSize.Height)); + currentLineX = child.DesiredSize.Width; + currentLineHeight = child.DesiredSize.Height; + } + } + + var last = TrailingItem; + if (last is null) return new Size(finalSize.Width, totalHeight); + double lastDeltaX = finalSize.Width - currentLineX; + // If width is not enough, add a new line, and recalculate total height + if (lastDeltaX < 30) + { + totalHeight += currentLineHeight; + last.Arrange(new Rect(0, totalHeight, finalSize.Width, last.DesiredSize.Height)); + totalHeight += last.DesiredSize.Height; + } + else + { + currentLineHeight = children.Count == 1 ? finalSize.Height : currentLineHeight; + last.Arrange(new Rect(currentLineX, totalHeight, lastDeltaX, + Math.Max(currentLineHeight, last.DesiredSize.Height))); + currentLineHeight = Math.Max(currentLineHeight, last.DesiredSize.Height); + totalHeight += currentLineHeight; + } + + return new Size(finalSize.Width, totalHeight); + } } \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs new file mode 100644 index 0000000..0119e0c --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs @@ -0,0 +1,155 @@ +using Avalonia.Controls; +using Avalonia.Headless.XUnit; +using Avalonia.Layout; +using Avalonia.LogicalTree; +using Avalonia.Threading; +using Avalonia.VisualTree; +using Ursa.Controls.Panels; + +namespace HeadlessTest.Ursa.Controls.PanelTests; + +public class WrapPanelWithTrailingItemTests +{ + [Fact] + public void Visual_Children_Correct() + { + var panel = new WrapPanelWithTrailingItem(); + var child1 = new Button { Content = "Button 1"}; + var child2 = new Button { Content = "Button 2"}; + var trailing = new Button { Content = "Trailing"}; + + panel.Children.Add(child1); + panel.Children.Add(child2); + panel.TrailingItem = trailing; + + var visualChildren = panel.GetVisualChildren().ToList(); + Assert.Equal(3, visualChildren.Count); + Assert.Equal(child1, visualChildren[0]); + Assert.Equal(child2, visualChildren[1]); + Assert.Equal(trailing, visualChildren[2]); + + var child3 = new Button { Content = "Button 3"}; + panel.Children.Add(child3); + + visualChildren = panel.GetVisualChildren().ToList(); + Assert.Equal(4, visualChildren.Count); + Assert.Equal(child1, visualChildren[0]); + Assert.Equal(child2, visualChildren[1]); + Assert.Equal(child3, visualChildren[2]); + Assert.Equal(trailing, visualChildren[3]); + + var trailing2 = new Button { Content = "Trailing2"}; + panel.TrailingItem = trailing2; + + visualChildren = panel.GetVisualChildren().ToList(); + Assert.Equal(4, visualChildren.Count); + Assert.Equal(child1, visualChildren[0]); + Assert.Equal(child2, visualChildren[1]); + Assert.Equal(child3, visualChildren[2]); + Assert.Equal(trailing2, visualChildren[3]); + + panel.Children.Remove(child2); + + visualChildren = panel.GetVisualChildren().ToList(); + Assert.Equal(3, visualChildren.Count); + Assert.Equal(child1, visualChildren[0]); + Assert.Equal(child3, visualChildren[1]); + Assert.Equal(trailing2, visualChildren[2]); + } + + [Fact] + // Items Appears in Logical Children because IsItemsHost is false for individual Panels + public void Logical_Children_Correct() + { + var panel = new WrapPanelWithTrailingItem(); + var child1 = new Button { Content = "Button 1"}; + var child2 = new Button { Content = "Button 2"}; + var trailing = new Button { Content = "Trailing"}; + + panel.Children.Add(child1); + panel.Children.Add(child2); + panel.TrailingItem = trailing; + + var logicalChildren = panel.GetLogicalChildren().ToList(); + Assert.Equal(3, logicalChildren.Count); + Assert.Equal(child1, logicalChildren[0]); + Assert.Equal(child2, logicalChildren[1]); + Assert.Equal(trailing, logicalChildren[2]); + + var child3 = new Button { Content = "Button 3"}; + panel.Children.Add(child3); + + logicalChildren = panel.GetLogicalChildren().ToList(); + Assert.Equal(4, logicalChildren.Count); + Assert.Equal(child1, logicalChildren[0]); + Assert.Equal(child2, logicalChildren[1]); + Assert.Equal(child3, logicalChildren[2]); + Assert.Equal(trailing, logicalChildren[3]); + + var trailing2 = new Button { Content = "Trailing2"}; + panel.TrailingItem = trailing2; + + logicalChildren = panel.GetLogicalChildren().ToList(); + Assert.Equal(4, logicalChildren.Count); + Assert.Equal(child1, logicalChildren[0]); + Assert.Equal(child2, logicalChildren[1]); + Assert.Equal(child3, logicalChildren[2]); + Assert.Equal(trailing2, logicalChildren[3]); + + panel.Children.Remove(child2); + + logicalChildren = panel.GetLogicalChildren().ToList(); + Assert.Equal(3, logicalChildren.Count); + Assert.Equal(child1, logicalChildren[0]); + Assert.Equal(child3, logicalChildren[1]); + Assert.Equal(trailing2, logicalChildren[2]); + } + + [AvaloniaFact] + public void Measure_Arrange_Children() + { + var window = new Window() + { + Height = 1000, Width = 1000, VerticalContentAlignment = VerticalAlignment.Stretch + }; + var panel = new WrapPanelWithTrailingItem(); + var child1 = new Button { Content = "Button 1", Width = 200, Height = 100 }; + var child2 = new Button { Content = "Button 2", Width = 300, Height = 100 }; + var trailing = new Button + { + Content = "Trailing", + Height = 100, + HorizontalAlignment = HorizontalAlignment.Stretch + }; + window.Content = panel; + panel.Children.Add(child1); + panel.Children.Add(child2); + panel.TrailingItem = trailing; + + window.Show(); + Dispatcher.UIThread.RunJobs(); + Assert.Equal(200, child1.Bounds.Width); + Assert.Equal(300, child2.Bounds.Width); + Assert.Equal(500, trailing.Bounds.Width); + + panel.Width = 600; + Dispatcher.UIThread.RunJobs(); + Assert.Equal(200, child1.Bounds.Width); + Assert.Equal(300, child2.Bounds.Width); + Assert.Equal(100, trailing.Bounds.Width); + + panel.Width = 510; + Dispatcher.UIThread.RunJobs(); + Assert.Equal(200, child1.Bounds.Width); + Assert.Equal(300, child2.Bounds.Width); + Assert.Equal(510, trailing.Bounds.Width); + Assert.Equal(100, trailing.Bounds.Y); + + panel.Width = 300; + Dispatcher.UIThread.RunJobs(); + Assert.Equal(200, child1.Bounds.Width); + Assert.Equal(300, child2.Bounds.Width); + Assert.Equal(300, trailing.Bounds.Width); + Assert.Equal(200, trailing.Bounds.Y); + } +} \ No newline at end of file From a778882c33f0e1be7dd3d094a984f7c6edff7606 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 3 Sep 2025 21:08:37 +0800 Subject: [PATCH 3/6] feat: update namespace for WrapPanelWithTrailingItem and its tests --- src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs | 2 +- .../Controls/PanelTests/WrapPanelWithTrailingItemTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs index d6cefed..7bdf531 100644 --- a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs +++ b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs @@ -4,7 +4,7 @@ using Avalonia.Controls; using Avalonia.Layout; using Irihi.Avalonia.Shared.Helpers; -namespace Ursa.Controls.Panels; +namespace Ursa.Controls; public class WrapPanelWithTrailingItem: Panel { diff --git a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs index 0119e0c..d4a39bc 100644 --- a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs +++ b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs @@ -4,7 +4,7 @@ using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Threading; using Avalonia.VisualTree; -using Ursa.Controls.Panels; +using Ursa.Controls; namespace HeadlessTest.Ursa.Controls.PanelTests; From 9ee89b7ce5088711037f50fcb7d9cedbeaa07680 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 3 Sep 2025 17:22:46 +0800 Subject: [PATCH 4/6] test: fix measure test. --- .../Controls/PanelTests/WrapPanelWithTrailingItemTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs index d4a39bc..76d5224 100644 --- a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs +++ b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs @@ -112,7 +112,7 @@ public class WrapPanelWithTrailingItemTests { Height = 1000, Width = 1000, VerticalContentAlignment = VerticalAlignment.Stretch }; - var panel = new WrapPanelWithTrailingItem(); + var panel = new WrapPanelWithTrailingItem() { TrailingWrapWidth = 30 }; var child1 = new Button { Content = "Button 1", Width = 200, Height = 100 }; var child2 = new Button { Content = "Button 2", Width = 300, Height = 100 }; var trailing = new Button From 8147a05b5cd319458aad0cb1e8b61b0556a4d8f6 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 3 Sep 2025 21:18:00 +0800 Subject: [PATCH 5/6] feat: add TrailingWrapWidth. --- .../Panels/WrapPanelWithTrailingItem.cs | 88 ++++++++++--------- .../WrapPanelWithTrailingItemTests.cs | 4 +- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs index 7bdf531..f26d193 100644 --- a/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs +++ b/src/Ursa/Controls/Panels/WrapPanelWithTrailingItem.cs @@ -6,18 +6,15 @@ using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; -public class WrapPanelWithTrailingItem: Panel +public class WrapPanelWithTrailingItem : Panel { - public static readonly StyledProperty TrailingItemProperty = AvaloniaProperty.Register( - nameof(TrailingItem)); + public static readonly StyledProperty TrailingItemProperty = + AvaloniaProperty.Register( + nameof(TrailingItem)); - public Layoutable? TrailingItem - { - get => GetValue(TrailingItemProperty); - set => SetValue(TrailingItemProperty, value); - } - - + public static readonly StyledProperty TrailingWrapWidthProperty = + AvaloniaProperty.Register( + nameof(TrailingWrapWidth)); static WrapPanelWithTrailingItem() { @@ -25,52 +22,55 @@ public class WrapPanelWithTrailingItem: Panel AffectsArrange(TrailingItemProperty); } + public Layoutable? TrailingItem + { + get => GetValue(TrailingItemProperty); + set => SetValue(TrailingItemProperty, value); + } + + public double TrailingWrapWidth + { + get => GetValue(TrailingWrapWidthProperty); + set => SetValue(TrailingWrapWidthProperty, value); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); if (change.Property == TrailingItemProperty) { - if(change.GetOldValue() is { } oldValue) + if (change.GetOldValue() is { } oldValue) { VisualChildren.Remove(oldValue); - if (!IsItemsHost) - { - LogicalChildren.Remove(oldValue); - } + if (!IsItemsHost) LogicalChildren.Remove(oldValue); } - if(change.GetNewValue() is {} newValue) + + if (change.GetNewValue() is { } newValue) { VisualChildren.Add(newValue); - if (!IsItemsHost) - { - LogicalChildren.Add(newValue); - } + if (!IsItemsHost) LogicalChildren.Add(newValue); } } WrapPanel p = new WrapPanel(); } - protected override void ChildrenChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - base.ChildrenChanged(sender, e); - } - protected override Size MeasureOverride(Size availableSize) { double currentLineX = 0; double currentLineHeight = 0; double totalHeight = 0; - + var children = Children; foreach (var child in children) { child.Measure(availableSize); - double deltaX = availableSize.Width - currentLineX; + var deltaX = availableSize.Width - currentLineX; // Width is enough to place next child if (MathHelpers.GreaterThan(deltaX, child.DesiredSize.Width)) { - currentLineX+=child.DesiredSize.Width; + currentLineX += child.DesiredSize.Width; currentLineHeight = Math.Max(currentLineHeight, child.DesiredSize.Height); } // Width is not enough to place next child @@ -88,11 +88,11 @@ public class WrapPanelWithTrailingItem: Panel var last = TrailingItem; if (last is null) return new Size(availableSize.Width, totalHeight); last.Measure(availableSize); - double lastDeltaX = availableSize.Width - currentLineX; + var lastDeltaX = availableSize.Width - currentLineX; // If width is not enough, add a new line, and recalculate total height - if (lastDeltaX < 30) + if (lastDeltaX < TrailingWrapWidth) { - totalHeight+=currentLineHeight; + totalHeight += currentLineHeight; totalHeight += last.DesiredSize.Height; } else @@ -103,23 +103,24 @@ public class WrapPanelWithTrailingItem: Panel return new Size(availableSize.Width, totalHeight); } - + protected override Size ArrangeOverride(Size finalSize) { double currentLineX = 0; double currentLineHeight = 0; double totalHeight = 0; var children = Children; - for (int i = 0; i < children.Count; i++) + + foreach (var child in children) { - var child = children[i]; double deltaX = finalSize.Width - currentLineX; // Width is enough to place next child if (MathHelpers.GreaterThan(deltaX, child.DesiredSize.Width)) { - child.Arrange(new Rect(currentLineX, totalHeight, child.DesiredSize.Width, Math.Max(child.DesiredSize.Height, currentLineHeight))); - currentLineX += child.DesiredSize.Width; - currentLineHeight = Math.Max(currentLineHeight, child.DesiredSize.Height); + child.Arrange(new Rect(currentLineX, totalHeight, child.DesiredSize.Width, + Math.Max(child.DesiredSize.Height, currentLineHeight))); + currentLineX += child.Bounds.Width; + currentLineHeight = Math.Max(currentLineHeight, child.Bounds.Height); } // Width is not enough to place next child // reset currentLineX and currentLineHeight @@ -128,17 +129,18 @@ public class WrapPanelWithTrailingItem: Panel else { totalHeight += currentLineHeight; - child.Arrange(new Rect(0, totalHeight, Math.Min(child.DesiredSize.Width, finalSize.Width), child.DesiredSize.Height)); - currentLineX = child.DesiredSize.Width; - currentLineHeight = child.DesiredSize.Height; + child.Arrange(new Rect(0, totalHeight, Math.Min(child.DesiredSize.Width, finalSize.Width), + child.DesiredSize.Height)); + currentLineX = child.Bounds.Width; + currentLineHeight = child.Bounds.Height; } } - + var last = TrailingItem; if (last is null) return new Size(finalSize.Width, totalHeight); - double lastDeltaX = finalSize.Width - currentLineX; + var lastDeltaX = finalSize.Width - currentLineX; // If width is not enough, add a new line, and recalculate total height - if (lastDeltaX < 30) + if (lastDeltaX < TrailingWrapWidth) { totalHeight += currentLineHeight; last.Arrange(new Rect(0, totalHeight, finalSize.Width, last.DesiredSize.Height)); diff --git a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs index 76d5224..c1387a1 100644 --- a/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs +++ b/tests/HeadlessTest.Ursa/Controls/PanelTests/WrapPanelWithTrailingItemTests.cs @@ -10,7 +10,7 @@ namespace HeadlessTest.Ursa.Controls.PanelTests; public class WrapPanelWithTrailingItemTests { - [Fact] + [AvaloniaFact] public void Visual_Children_Correct() { var panel = new WrapPanelWithTrailingItem(); @@ -57,7 +57,7 @@ public class WrapPanelWithTrailingItemTests Assert.Equal(trailing2, visualChildren[2]); } - [Fact] + [AvaloniaFact] // Items Appears in Logical Children because IsItemsHost is false for individual Panels public void Logical_Children_Correct() { From b6b8453cc42008818b2f2eda507c8918cd802a9e Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 3 Sep 2025 21:22:34 +0800 Subject: [PATCH 6/6] chore: remove pull_request_target from CI configuration --- .github/workflows/test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eeeda7a..4b418dc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,8 +5,6 @@ on: branches: [ "main", "2.0" ] pull_request: branches: [ "main", "2.0" ] - pull_request_target: - branches: [ "main", "2.0" ] workflow_dispatch: permissions: