Browse Source

遗漏外侧圆的问题

refactor/namespace-and-layering
root 1 month ago
parent
commit
e5864c96b9
  1. 2
      AuroraDesk.Core/Entities/ConnectionPoint.cs
  2. 4
      AuroraDesk.Core/Entities/Node.cs
  3. 4
      AuroraDesk.Core/Entities/NodeTemplate.cs
  4. 1
      AuroraDesk.Presentation/AuroraDesk.Presentation.csproj
  5. 45
      AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs
  6. 34
      AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs
  7. 12
      AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
  8. 520
      AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  9. 141
      modify.md

2
AuroraDesk.Core/Entities/ConnectionPoint.cs

@ -17,7 +17,7 @@ public class ConnectionPoint : ReactiveObject
private bool _isConnected; private bool _isConnected;
private double _diameter = 10; private double _diameter = 10;
private string _color = "#3498DB"; private string _color = "#3498DB";
private ConnectorPlacementMode _placement = ConnectorPlacementMode.Inside; private ConnectorPlacementMode _placement = ConnectorPlacementMode.Outside;
/// <summary> /// <summary>
/// 连接点唯一标识符 /// 连接点唯一标识符

4
AuroraDesk.Core/Entities/Node.cs

@ -28,8 +28,8 @@ public class Node : ReactiveObject
private double _rightConnectorSize = 10; private double _rightConnectorSize = 10;
private string _leftConnectorColor = "#3498DB"; private string _leftConnectorColor = "#3498DB";
private string _rightConnectorColor = "#FF6B6B"; private string _rightConnectorColor = "#FF6B6B";
private ConnectorPlacementMode _leftConnectorPlacement = ConnectorPlacementMode.Inside; private ConnectorPlacementMode _leftConnectorPlacement = ConnectorPlacementMode.Outside;
private ConnectorPlacementMode _rightConnectorPlacement = ConnectorPlacementMode.Inside; private ConnectorPlacementMode _rightConnectorPlacement = ConnectorPlacementMode.Outside;
/// <summary> /// <summary>
/// 构造函数 /// 构造函数

4
AuroraDesk.Core/Entities/NodeTemplate.cs

@ -18,8 +18,8 @@ public class NodeTemplate : ReactiveObject
private double _height = 80; private double _height = 80;
private double _leftConnectorSize = 10; private double _leftConnectorSize = 10;
private double _rightConnectorSize = 10; private double _rightConnectorSize = 10;
private ConnectorPlacementMode _leftConnectorPlacement = ConnectorPlacementMode.Inside; private ConnectorPlacementMode _leftConnectorPlacement = ConnectorPlacementMode.Outside;
private ConnectorPlacementMode _rightConnectorPlacement = ConnectorPlacementMode.Inside; private ConnectorPlacementMode _rightConnectorPlacement = ConnectorPlacementMode.Outside;
private string _leftConnectorColor = "#3498DB"; private string _leftConnectorColor = "#3498DB";
private string _rightConnectorColor = "#FF6B6B"; private string _rightConnectorColor = "#FF6B6B";

1
AuroraDesk.Presentation/AuroraDesk.Presentation.csproj

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.8" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Controls.ColorPicker" Version="11.3.8" />
<PackageReference Include="ReactiveUI.Avalonia" Version="11.3.8" /> <PackageReference Include="ReactiveUI.Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" />
<PackageReference Include="DialogHost.Avalonia" Version="0.9.3" /> <PackageReference Include="DialogHost.Avalonia" Version="0.9.3" />

45
AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs

@ -9,6 +9,15 @@ namespace AuroraDesk.Presentation.Controls;
/// </summary> /// </summary>
public class ConnectorColumnPanel : Panel public class ConnectorColumnPanel : Panel
{ {
public static readonly StyledProperty<ConnectorColumnSide> SideProperty =
AvaloniaProperty.Register<ConnectorColumnPanel, ConnectorColumnSide>(nameof(Side), ConnectorColumnSide.Center);
public ConnectorColumnSide Side
{
get => GetValue(SideProperty);
set => SetValue(SideProperty, value);
}
protected override Size MeasureOverride(Size availableSize) protected override Size MeasureOverride(Size availableSize)
{ {
var maxWidth = 0d; var maxWidth = 0d;
@ -18,8 +27,13 @@ public class ConnectorColumnPanel : Panel
{ {
child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var desired = child.DesiredSize; var desired = child.DesiredSize;
maxWidth = Math.Max(maxWidth, desired.Width); var margin = (child as Control)?.Margin ?? new Thickness(0);
totalHeight += desired.Height;
var horizontalMargin = Math.Abs(margin.Left) + Math.Abs(margin.Right);
var verticalMargin = Math.Max(0, margin.Top) + Math.Max(0, margin.Bottom);
maxWidth = Math.Max(maxWidth, desired.Width + horizontalMargin);
totalHeight += desired.Height + verticalMargin;
} }
var height = double.IsInfinity(availableSize.Height) ? totalHeight : availableSize.Height; var height = double.IsInfinity(availableSize.Height) ? totalHeight : availableSize.Height;
@ -37,7 +51,8 @@ public class ConnectorColumnPanel : Panel
var totalHeight = 0d; var totalHeight = 0d;
foreach (var child in Children) foreach (var child in Children)
{ {
totalHeight += child.DesiredSize.Height; var margin = (child as Control)?.Margin ?? new Thickness(0);
totalHeight += child.DesiredSize.Height + Math.Max(0, margin.Top) + Math.Max(0, margin.Bottom);
} }
var availableHeight = finalSize.Height; var availableHeight = finalSize.Height;
@ -49,13 +64,29 @@ public class ConnectorColumnPanel : Panel
foreach (var child in Children) foreach (var child in Children)
{ {
var childHeight = child.DesiredSize.Height; var childHeight = child.DesiredSize.Height;
var childWidth = Math.Min(child.DesiredSize.Width, finalSize.Width); var childWidth = child.DesiredSize.Width;
var x = (finalSize.Width - childWidth) / 2; var margin = (child as Control)?.Margin ?? new Thickness(0);
child.Arrange(new Rect(x, currentY, childWidth, childHeight));
currentY += childHeight + spacing; double x = Side switch
{
ConnectorColumnSide.Left => margin.Left,
ConnectorColumnSide.Right => finalSize.Width - childWidth - margin.Right,
_ => (finalSize.Width - childWidth) / 2 + (margin.Left - margin.Right) / 2
};
var y = currentY + Math.Max(0, margin.Top);
child.Arrange(new Rect(x, y, childWidth, childHeight));
currentY += Math.Max(0, margin.Top) + childHeight + Math.Max(0, margin.Bottom) + spacing;
} }
return finalSize; return finalSize;
} }
} }
public enum ConnectorColumnSide
{
Center,
Left,
Right
}

34
AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs

@ -21,6 +21,7 @@ public static class NodeCanvasConverters
public static readonly IValueConverter IsNullConverter = new IsNullConverter(); public static readonly IValueConverter IsNullConverter = new IsNullConverter();
public static readonly IValueConverter DoubleToStringConverter = new DoubleToStringConverter(); public static readonly IValueConverter DoubleToStringConverter = new DoubleToStringConverter();
public static readonly IValueConverter ColorHexToBrushConverter = new ColorHexToBrushConverter(); public static readonly IValueConverter ColorHexToBrushConverter = new ColorHexToBrushConverter();
public static readonly IValueConverter ColorHexToColorConverter = new ColorHexToColorConverter();
public static readonly IValueConverter ConnectorAttachmentModeToTextConverter = new ConnectorAttachmentModeToTextConverter(); public static readonly IValueConverter ConnectorAttachmentModeToTextConverter = new ConnectorAttachmentModeToTextConverter();
public static readonly IValueConverter ConnectionPointsToInputsConverter = new ConnectionPointsToInputsConverter(); public static readonly IValueConverter ConnectionPointsToInputsConverter = new ConnectionPointsToInputsConverter();
public static readonly IValueConverter ConnectionPointsToOutputsConverter = new ConnectionPointsToOutputsConverter(); public static readonly IValueConverter ConnectionPointsToOutputsConverter = new ConnectionPointsToOutputsConverter();
@ -318,6 +319,39 @@ public class ColorHexToBrushConverter : IValueConverter
} }
} }
/// <summary>
/// 将 Hex 字符串与 Avalonia.Media.Color 互转
/// </summary>
public class ColorHexToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string hex && !string.IsNullOrWhiteSpace(hex))
{
try
{
return Color.Parse(hex);
}
catch
{
// ignore parse error
}
}
return Colors.Transparent;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Color color)
{
return $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
return AvaloniaProperty.UnsetValue;
}
}
/// <summary> /// <summary>
/// 将零基索引转换为显示文本(圆 1、圆 2 ...) /// 将零基索引转换为显示文本(圆 1、圆 2 ...)
/// </summary> /// </summary>

12
AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs

@ -315,8 +315,8 @@ public class NodeCanvasPageViewModel : RoutableViewModel
RightConnectorSize = DefaultConnectorSize, RightConnectorSize = DefaultConnectorSize,
LeftConnectorColor = "#2D9CDB", LeftConnectorColor = "#2D9CDB",
RightConnectorColor = "#EB5757", RightConnectorColor = "#EB5757",
LeftConnectorPlacement = ConnectorPlacementMode.Inside, LeftConnectorPlacement = ConnectorPlacementMode.Outside,
RightConnectorPlacement = ConnectorPlacementMode.Inside RightConnectorPlacement = ConnectorPlacementMode.Outside
}); });
NodeTemplates.Add(new NodeTemplate NodeTemplates.Add(new NodeTemplate
@ -333,8 +333,8 @@ public class NodeCanvasPageViewModel : RoutableViewModel
RightConnectorSize = DefaultConnectorSize, RightConnectorSize = DefaultConnectorSize,
LeftConnectorColor = "#2D9CDB", LeftConnectorColor = "#2D9CDB",
RightConnectorColor = "#EB5757", RightConnectorColor = "#EB5757",
LeftConnectorPlacement = ConnectorPlacementMode.Inside, LeftConnectorPlacement = ConnectorPlacementMode.Outside,
RightConnectorPlacement = ConnectorPlacementMode.Inside RightConnectorPlacement = ConnectorPlacementMode.Outside
}); });
} }
@ -359,8 +359,8 @@ public class NodeCanvasPageViewModel : RoutableViewModel
RightConnectorSize = DefaultConnectorSize, RightConnectorSize = DefaultConnectorSize,
LeftConnectorColor = "#2D9CDB", LeftConnectorColor = "#2D9CDB",
RightConnectorColor = "#EB5757", RightConnectorColor = "#EB5757",
LeftConnectorPlacement = ConnectorPlacementMode.Inside, LeftConnectorPlacement = ConnectorPlacementMode.Outside,
RightConnectorPlacement = ConnectorPlacementMode.Inside RightConnectorPlacement = ConnectorPlacementMode.Outside
}; };
// 默认提供输入和输出连接点 // 默认提供输入和输出连接点

520
AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml

@ -5,9 +5,10 @@
xmlns:vm="using:AuroraDesk.Presentation.ViewModels.Pages" xmlns:vm="using:AuroraDesk.Presentation.ViewModels.Pages"
xmlns:reactive="using:ReactiveUI.Avalonia" xmlns:reactive="using:ReactiveUI.Avalonia"
xmlns:entities="using:AuroraDesk.Core.Entities" xmlns:entities="using:AuroraDesk.Core.Entities"
xmlns:converters="using:AuroraDesk.Presentation.Converters" xmlns:converters="using:AuroraDesk.Presentation.Converters"
xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia" xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia"
xmlns:controls="clr-namespace:AuroraDesk.Presentation.Controls" xmlns:controls="clr-namespace:AuroraDesk.Presentation.Controls"
xmlns:cp="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls.ColorPicker"
mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800" mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800"
x:Class="AuroraDesk.Presentation.Views.Pages.NodeCanvasPageView" x:Class="AuroraDesk.Presentation.Views.Pages.NodeCanvasPageView"
x:DataType="vm:NodeCanvasPageViewModel" x:DataType="vm:NodeCanvasPageViewModel"
@ -21,6 +22,7 @@
<converters:IsNullConverter x:Key="IsNullConverter"/> <converters:IsNullConverter x:Key="IsNullConverter"/>
<converters:DoubleToStringConverter x:Key="DoubleToStringConverter"/> <converters:DoubleToStringConverter x:Key="DoubleToStringConverter"/>
<converters:ColorHexToBrushConverter x:Key="ColorHexToBrushConverter"/> <converters:ColorHexToBrushConverter x:Key="ColorHexToBrushConverter"/>
<converters:ColorHexToColorConverter x:Key="ColorHexToColorConverter"/>
<converters:ConnectorAttachmentModeToTextConverter x:Key="ConnectorAttachmentModeToTextConverter"/> <converters:ConnectorAttachmentModeToTextConverter x:Key="ConnectorAttachmentModeToTextConverter"/>
<converters:ConnectionPointsToInputsConverter x:Key="ConnectionPointsToInputsConverter"/> <converters:ConnectionPointsToInputsConverter x:Key="ConnectionPointsToInputsConverter"/>
<converters:ConnectionPointsToOutputsConverter x:Key="ConnectionPointsToOutputsConverter"/> <converters:ConnectionPointsToOutputsConverter x:Key="ConnectionPointsToOutputsConverter"/>
@ -338,6 +340,7 @@
BorderBrush="{Binding IsSelected, Converter={StaticResource BooleanToBorderBrushConverter}}" BorderBrush="{Binding IsSelected, Converter={StaticResource BooleanToBorderBrushConverter}}"
BorderThickness="{Binding IsSelected, Converter={StaticResource BooleanToBorderThicknessConverter}}" BorderThickness="{Binding IsSelected, Converter={StaticResource BooleanToBorderThicknessConverter}}"
BoxShadow="0 2 8 0 #00000015" BoxShadow="0 2 8 0 #00000015"
ClipToBounds="False"
Canvas.Left="{Binding X}" Canvas.Left="{Binding X}"
Canvas.Top="{Binding Y}"> Canvas.Top="{Binding Y}">
<Grid ColumnDefinitions="Auto,*,Auto" <Grid ColumnDefinitions="Auto,*,Auto"
@ -352,7 +355,8 @@
VerticalAlignment="Center"> VerticalAlignment="Center">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<controls:ConnectorColumnPanel VerticalAlignment="Stretch"/> <controls:ConnectorColumnPanel VerticalAlignment="Stretch"
Side="Left"/>
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
@ -399,7 +403,8 @@
VerticalAlignment="Center"> VerticalAlignment="Center">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<controls:ConnectorColumnPanel VerticalAlignment="Stretch"/> <controls:ConnectorColumnPanel VerticalAlignment="Stretch"
Side="Right"/>
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
@ -477,6 +482,15 @@
<Setter Property="FontFamily" Value="Microsoft YaHei, Segoe UI, Arial"/> <Setter Property="FontFamily" Value="Microsoft YaHei, Segoe UI, Arial"/>
<Setter Property="UseLayoutRounding" Value="True"/> <Setter Property="UseLayoutRounding" Value="True"/>
</Style> </Style>
<Style Selector="cp|ColorPicker">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderLight}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Background" Value="{StaticResource BackgroundWhite}"/>
<Setter Property="Foreground" Value="{StaticResource TextPrimary}"/>
<Setter Property="MinHeight" Value="32"/>
</Style>
<Style Selector="TextBlock"> <Style Selector="TextBlock">
<Setter Property="FontFamily" Value="Microsoft YaHei, Segoe UI, Arial"/> <Setter Property="FontFamily" Value="Microsoft YaHei, Segoe UI, Arial"/>
<Setter Property="UseLayoutRounding" Value="True"/> <Setter Property="UseLayoutRounding" Value="True"/>
@ -496,41 +510,67 @@
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/> Foreground="{StaticResource TextPrimary}"/>
<Grid ColumnDefinitions="140,*" <Border BorderBrush="{StaticResource BorderLight}"
RowDefinitions="Auto,Auto,Auto" BorderThickness="1"
UseLayoutRounding="True"> CornerRadius="4">
<TextBlock Grid.Row="0" <Grid ColumnDefinitions="110,*"
Text="名称" RowDefinitions="Auto,Auto,Auto"
Margin="0,0,12,6" UseLayoutRounding="True">
FontSize="12" <Border Grid.Row="0"
Foreground="{StaticResource TextSecondary}"/> Grid.Column="0"
<TextBox Grid.Row="0" BorderBrush="{StaticResource BorderLight}"
Grid.Column="1" BorderThickness="0,0,1,1"
Text="{Binding SelectedNode.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Padding="10,8">
Watermark="请输入名称"/> <TextBlock Text="名称"
FontSize="12"
Foreground="{StaticResource TextSecondary}"/>
</Border>
<Border Grid.Row="0"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<TextBox Text="{Binding SelectedNode.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Watermark="请输入名称"/>
</Border>
<TextBlock Grid.Row="1" <Border Grid.Row="1"
Text="宽度" Grid.Column="0"
Margin="0,8,12,6" BorderBrush="{StaticResource BorderLight}"
FontSize="12" BorderThickness="0,0,1,1"
Foreground="{StaticResource TextSecondary}"/> Padding="10,8">
<TextBox Grid.Row="1" <TextBlock Text="宽度"
Grid.Column="1" FontSize="12"
Margin="0,8,0,0" Foreground="{StaticResource TextSecondary}"/>
Text="{Binding SelectedNode.Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}" </Border>
Watermark="0"/> <Border Grid.Row="1"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<TextBox Text="{Binding SelectedNode.Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}"
Watermark="0"/>
</Border>
<TextBlock Grid.Row="2" <Border Grid.Row="2"
Text="高度" Grid.Column="0"
Margin="0,8,12,0" BorderBrush="{StaticResource BorderLight}"
FontSize="12" BorderThickness="0,0,1,0"
Foreground="{StaticResource TextSecondary}"/> Padding="10,8">
<TextBox Grid.Row="2" <TextBlock Text="高度"
Grid.Column="1" FontSize="12"
Margin="0,8,0,0" Foreground="{StaticResource TextSecondary}"/>
Text="{Binding SelectedNode.Height, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}" </Border>
Watermark="0"/> <Border Grid.Row="2"
</Grid> Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,0"
Padding="10,4">
<TextBox Text="{Binding SelectedNode.Height, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}"
Watermark="0"/>
</Border>
</Grid>
</Border>
</StackPanel> </StackPanel>
</Border> </Border>
@ -545,188 +585,280 @@
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/> Foreground="{StaticResource TextPrimary}"/>
<StackPanel Spacing="12"> <Border BorderBrush="{StaticResource BorderLight}"
<StackPanel Spacing="4"> BorderThickness="1"
<TextBlock Text="显示位置" CornerRadius="4">
<Grid ColumnDefinitions="110,*"
RowDefinitions="Auto,Auto">
<Border Grid.Row="0"
Grid.Column="0"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,0,1,1"
Padding="10,8">
<TextBlock Text="左侧数量"
FontSize="12" FontSize="12"
Foreground="{StaticResource TextSecondary}"/> Foreground="{StaticResource TextSecondary}"/>
<ComboBox SelectedItem="{Binding SelectedConnectorMode, Mode=TwoWay}"> </Border>
<ComboBox.ItemTemplate> <Border Grid.Row="0"
<DataTemplate> Grid.Column="1"
<TextBlock Text="{Binding Converter={StaticResource ConnectorAttachmentModeToTextConverter}}"/> BorderBrush="{StaticResource BorderLight}"
</DataTemplate> BorderThickness="1,0,0,1"
</ComboBox.ItemTemplate> Padding="10,4">
<ComboBox.Items> <ComboBox ItemsSource="{Binding ConnectorCountOptions}"
<entities:ConnectorAttachmentMode>None</entities:ConnectorAttachmentMode> SelectedItem="{Binding SelectedLeftConnectorCount, Mode=TwoWay}"/>
<entities:ConnectorAttachmentMode>LeftOnly</entities:ConnectorAttachmentMode> </Border>
<entities:ConnectorAttachmentMode>RightOnly</entities:ConnectorAttachmentMode>
<entities:ConnectorAttachmentMode>Both</entities:ConnectorAttachmentMode>
</ComboBox.Items>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="12"> <Border Grid.Row="1"
<StackPanel Width="140" Spacing="4"> Grid.Column="0"
<TextBlock Text="左侧数量" BorderBrush="{StaticResource BorderLight}"
FontSize="12" BorderThickness="0,0,1,0"
Foreground="{StaticResource TextSecondary}"/> Padding="10,8">
<ComboBox ItemsSource="{Binding ConnectorCountOptions}" <TextBlock Text="右侧数量"
SelectedItem="{Binding SelectedLeftConnectorCount, Mode=TwoWay}"/> FontSize="12"
</StackPanel> Foreground="{StaticResource TextSecondary}"/>
<StackPanel Width="140" Spacing="4"> </Border>
<TextBlock Text="右侧数量" <Border Grid.Row="1"
FontSize="12" Grid.Column="1"
Foreground="{StaticResource TextSecondary}"/> BorderBrush="{StaticResource BorderLight}"
<ComboBox ItemsSource="{Binding ConnectorCountOptions}" BorderThickness="1,0,0,0"
SelectedItem="{Binding SelectedRightConnectorCount, Mode=TwoWay}"/> Padding="10,4">
</StackPanel> <ComboBox ItemsSource="{Binding ConnectorCountOptions}"
</StackPanel> SelectedItem="{Binding SelectedRightConnectorCount, Mode=TwoWay}"/>
</StackPanel> </Border>
</Grid>
</Border>
<Grid ColumnDefinitions="*,*" <StackPanel Spacing="16">
ColumnSpacing="16"> <Expander HorizontalAlignment="Stretch"
<StackPanel Grid.Column="0" Spacing="10"> IsExpanded="True"
Padding="0">
<Expander.Header>
<TextBlock Text="左侧圆"
FontSize="12"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/>
</Expander.Header>
<Border Background="{StaticResource BackgroundLight}" <Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}" BorderBrush="{StaticResource BorderLight}"
BorderThickness="1" BorderThickness="1"
CornerRadius="6" CornerRadius="6"
Padding="10"> Padding="6">
<StackPanel Spacing="10"> <ItemsControl ItemsSource="{Binding SelectedNode.ConnectionPoints, Converter={StaticResource ConnectionPointsToInputsConverter}}"
<TextBlock Text="左侧圆" HorizontalAlignment="Stretch">
FontSize="12" <ItemsControl.ItemsPanel>
FontWeight="SemiBold" <ItemsPanelTemplate>
Foreground="{StaticResource TextPrimary}"/> <StackPanel Orientation="Vertical"
<ItemsControl ItemsSource="{Binding SelectedNode.ConnectionPoints, Converter={StaticResource ConnectionPointsToInputsConverter}}"> Spacing="0"/>
<ItemsControl.ItemsPanel> </ItemsPanelTemplate>
<ItemsPanelTemplate> </ItemsControl.ItemsPanel>
<StackPanel Spacing="10"/> <ItemsControl.ItemTemplate>
</ItemsPanelTemplate> <DataTemplate>
</ItemsControl.ItemsPanel> <Border Background="{StaticResource BackgroundWhite}"
<ItemsControl.ItemTemplate> BorderBrush="{StaticResource BorderLight}"
<DataTemplate> BorderThickness="1"
<Border Background="{StaticResource BackgroundWhite}" CornerRadius="6"
HorizontalAlignment="Stretch">
<Grid ColumnDefinitions="110,*"
RowDefinitions="Auto,Auto,Auto,Auto">
<Border Grid.Row="0"
Grid.ColumnSpan="2"
Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}" BorderBrush="{StaticResource BorderLight}"
BorderThickness="1" BorderThickness="0,0,0,1"
CornerRadius="6" Padding="12,6">
Padding="10"> <TextBlock Text="{Binding Index, Converter={StaticResource IndexToDisplayTextConverter}}"
<StackPanel Spacing="10"> FontSize="12"
<TextBlock Text="{Binding Index, Converter={StaticResource IndexToDisplayTextConverter}}" FontWeight="SemiBold"
FontSize="12" Foreground="{StaticResource TextPrimary}"/>
FontWeight="SemiBold" </Border>
Foreground="{StaticResource TextPrimary}"/>
<StackPanel Spacing="4"> <Border Grid.Row="1"
<TextBlock Text="直径" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,1"
<TextBox Text="{Binding Diameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}" Padding="10,8">
Watermark="0"/> <TextBlock Text="直径"
</StackPanel> FontSize="12"
Foreground="{StaticResource TextSecondary}"/>
</Border>
<Border Grid.Row="1"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<TextBox Text="{Binding Diameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}"
Watermark="0"/>
</Border>
<StackPanel Spacing="4"> <Border Grid.Row="2"
<TextBlock Text="颜色" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,1"
<TextBox Text="{Binding Color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Padding="10,8">
Watermark="#RRGGBB"/> <TextBlock Text="颜色"
</StackPanel> FontSize="12"
Foreground="{StaticResource TextSecondary}"/>
</Border>
<Border Grid.Row="2"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<cp:ColorPicker Color="{Binding Color, Mode=TwoWay, Converter={StaticResource ColorHexToColorConverter}}"
IsAlphaEnabled="False"
IsColorPreviewVisible="True"
IsColorPaletteVisible="True"/>
</Border>
<StackPanel Spacing="4"> <Border Grid.Row="3"
<TextBlock Text="定位" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,0"
<ComboBox SelectedItem="{Binding Placement, Mode=TwoWay}"> Padding="10,8">
<ComboBox.ItemTemplate> <TextBlock Text="定位"
<DataTemplate> FontSize="12"
<TextBlock Text="{Binding Converter={StaticResource ConnectorPlacementToTextConverter}}"/> Foreground="{StaticResource TextSecondary}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Items>
<entities:ConnectorPlacementMode>Inside</entities:ConnectorPlacementMode>
<entities:ConnectorPlacementMode>Outside</entities:ConnectorPlacementMode>
</ComboBox.Items>
</ComboBox>
</StackPanel>
</StackPanel>
</Border> </Border>
</DataTemplate> <Border Grid.Row="3"
</ItemsControl.ItemTemplate> Grid.Column="1"
</ItemsControl> BorderBrush="{StaticResource BorderLight}"
</StackPanel> BorderThickness="1,0,0,0"
Padding="10,4">
<ComboBox SelectedItem="{Binding Placement, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ConnectorPlacementToTextConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Items>
<entities:ConnectorPlacementMode>Inside</entities:ConnectorPlacementMode>
<entities:ConnectorPlacementMode>Outside</entities:ConnectorPlacementMode>
</ComboBox.Items>
</ComboBox>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border> </Border>
</StackPanel> </Expander>
<StackPanel Grid.Column="1" Spacing="10"> <Expander HorizontalAlignment="Stretch"
IsExpanded="True"
Padding="0">
<Expander.Header>
<TextBlock Text="右侧圆"
FontSize="12"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/>
</Expander.Header>
<Border Background="{StaticResource BackgroundLight}" <Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}" BorderBrush="{StaticResource BorderLight}"
BorderThickness="1" BorderThickness="1"
CornerRadius="6" CornerRadius="6"
Padding="10"> Padding="6">
<StackPanel Spacing="10"> <ItemsControl ItemsSource="{Binding SelectedNode.ConnectionPoints, Converter={StaticResource ConnectionPointsToOutputsConverter}}"
<TextBlock Text="右侧圆" HorizontalAlignment="Stretch">
FontSize="12" <ItemsControl.ItemsPanel>
FontWeight="SemiBold" <ItemsPanelTemplate>
Foreground="{StaticResource TextPrimary}"/> <StackPanel Orientation="Vertical"
<ItemsControl ItemsSource="{Binding SelectedNode.ConnectionPoints, Converter={StaticResource ConnectionPointsToOutputsConverter}}"> Spacing="0"/>
<ItemsControl.ItemsPanel> </ItemsPanelTemplate>
<ItemsPanelTemplate> </ItemsControl.ItemsPanel>
<StackPanel Spacing="10"/> <ItemsControl.ItemTemplate>
</ItemsPanelTemplate> <DataTemplate>
</ItemsControl.ItemsPanel> <Border Background="{StaticResource BackgroundWhite}"
<ItemsControl.ItemTemplate> BorderBrush="{StaticResource BorderLight}"
<DataTemplate> BorderThickness="1"
<Border Background="{StaticResource BackgroundWhite}" CornerRadius="6"
HorizontalAlignment="Stretch">
<Grid ColumnDefinitions="110,*"
RowDefinitions="Auto,Auto,Auto,Auto">
<Border Grid.Row="0"
Grid.ColumnSpan="2"
Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}" BorderBrush="{StaticResource BorderLight}"
BorderThickness="1" BorderThickness="0,0,0,1"
CornerRadius="6" Padding="12,6">
Padding="10"> <TextBlock Text="{Binding Index, Converter={StaticResource IndexToDisplayTextConverter}}"
<StackPanel Spacing="10"> FontSize="12"
<TextBlock Text="{Binding Index, Converter={StaticResource IndexToDisplayTextConverter}}" FontWeight="SemiBold"
FontSize="12" Foreground="{StaticResource TextPrimary}"/>
FontWeight="SemiBold" </Border>
Foreground="{StaticResource TextPrimary}"/>
<StackPanel Spacing="4"> <Border Grid.Row="1"
<TextBlock Text="直径" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,1"
<TextBox Text="{Binding Diameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}" Padding="10,8">
Watermark="0"/> <TextBlock Text="直径"
</StackPanel> FontSize="12"
Foreground="{StaticResource TextSecondary}"/>
</Border>
<Border Grid.Row="1"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<TextBox Text="{Binding Diameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToStringConverter}}"
Watermark="0"/>
</Border>
<StackPanel Spacing="4"> <Border Grid.Row="2"
<TextBlock Text="颜色" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,1"
<TextBox Text="{Binding Color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Padding="10,8">
Watermark="#RRGGBB"/> <TextBlock Text="颜色"
</StackPanel> FontSize="12"
Foreground="{StaticResource TextSecondary}"/>
</Border>
<Border Grid.Row="2"
Grid.Column="1"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,1"
Padding="10,4">
<cp:ColorPicker Color="{Binding Color, Mode=TwoWay, Converter={StaticResource ColorHexToColorConverter}}"
IsAlphaEnabled="False"
IsColorPreviewVisible="True"
IsColorPaletteVisible="True"/>
</Border>
<StackPanel Spacing="4"> <Border Grid.Row="3"
<TextBlock Text="定位" Grid.Column="0"
FontSize="12" BorderBrush="{StaticResource BorderLight}"
Foreground="{StaticResource TextSecondary}"/> BorderThickness="0,0,1,0"
<ComboBox SelectedItem="{Binding Placement, Mode=TwoWay}"> Padding="10,8">
<ComboBox.ItemTemplate> <TextBlock Text="定位"
<DataTemplate> FontSize="12"
<TextBlock Text="{Binding Converter={StaticResource ConnectorPlacementToTextConverter}}"/> Foreground="{StaticResource TextSecondary}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Items>
<entities:ConnectorPlacementMode>Inside</entities:ConnectorPlacementMode>
<entities:ConnectorPlacementMode>Outside</entities:ConnectorPlacementMode>
</ComboBox.Items>
</ComboBox>
</StackPanel>
</StackPanel>
</Border> </Border>
</DataTemplate> <Border Grid.Row="3"
</ItemsControl.ItemTemplate> Grid.Column="1"
</ItemsControl> BorderBrush="{StaticResource BorderLight}"
</StackPanel> BorderThickness="1,0,0,0"
Padding="10,4">
<ComboBox SelectedItem="{Binding Placement, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ConnectorPlacementToTextConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Items>
<entities:ConnectorPlacementMode>Inside</entities:ConnectorPlacementMode>
<entities:ConnectorPlacementMode>Outside</entities:ConnectorPlacementMode>
</ComboBox.Items>
</ComboBox>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border> </Border>
</StackPanel> </Expander>
</Grid> </StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>

141
modify.md

@ -14,6 +14,147 @@
- `AuroraDesk.Core/Entities/Node.cs` - `AuroraDesk.Core/Entities/Node.cs`
- **效果**: 调整左右附件圆数量后,画布节点立即刷新圆点数量,属性面板与画布保持一致。 - **效果**: 调整左右附件圆数量后,画布节点立即刷新圆点数量,属性面板与画布保持一致。
### 调整左右附件圆属性布局为纵向卡片
- **日期**: 2025年11月6日
- **调整内容**:
1. 将左、右侧圆属性卡片改为纵向排列,避免同列并排导致内容拥挤。
2. 每个圆的属性表单重构为与“组件属性”一致的双列表格布局,字段包含序号、直径、颜色、定位。
3. 精简卡片内边距与边框样式,统一视觉层级与留白。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 左右附件圆配置区域上下排列,阅读顺序更自然。
- ✅ 单个圆属性表单与基础属性风格一致,输入焦点和字段对齐更整洁。
### 为左右附件圆卡片添加折叠交互
- **日期**: 2025年11月6日
- **修改内容**:
1. 使用 `Expander` 包裹左、右侧圆配置区域,提供可折叠的标题栏。
2. 保留原有卡片边框与间距,使内容在展开时维持一致的视觉风格。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 用户可根据需要折叠左右圆配置,保持属性面板简洁。
- ✅ 展开后内容布局与原先保持一致,无额外视觉跳变。
### 精简附件圆卡片内边距与行距
- **日期**: 2025年11月6日
- **调整内容**:
1. 将左右圆 `Expander` 的内容区 Padding 调整为 6,并取消区块间额外间距。
2. 附件圆列表使用 `StackPanel Spacing="0"`,紧凑呈现多个圆的属性表格。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 属性面板整体占用更少垂直空间,避免上下留白。
- ✅ 多个圆的配置无额外间距,信息密度更高。
### 将显示位置与数量配置改为表格布局
- **日期**: 2025年11月6日
- **调整内容**:
1. 用带边框的双列表格承载“显示位置”“左侧数量”“右侧数量”三项配置。
2. 统一标签与输入控件的对齐方式,与其他属性表格保持视觉一致。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 显示位置与数量编辑区域风格与其他属性卡片一致。
- ✅ 输入控件列宽固定,阅读与操作更清晰。
### 移除显示位置选项
- **日期**: 2025年11月6日
- **调整内容**:
1. 删除“显示位置”下拉框,仅保留左右数量配置,由数量是否为零决定显示侧。
2. 表格结构调整为两行(左/右数量),边框与间距同步更新。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 属性面板更精简,避免重复配置。
- ✅ 左右数量保持原有样式,操作习惯不变。
### 默认附件圆定位改为外侧,并修正偏移
- **日期**: 2025年11月6日
- **修改内容**:
1. 将 `Node`、`NodeTemplate`、`ConnectionPoint` 的默认 `ConnectorPlacementMode` 调整为 `Outside`,并同步更新模板/新增节点逻辑。
2. `ConnectorPlacementMarginConverter` 外侧偏移量调整为直径长度,确保圆点完全位于节点外。
3. `ConnectorColumnPanel` 新增 `Side` 属性,支持根据左右方向贴边排列,并在节点模板中分别指定 `Side="Left"/"Right"`
- **涉及文件**:
- `AuroraDesk.Core/Entities/Node.cs`
- `AuroraDesk.Core/Entities/NodeTemplate.cs`
- `AuroraDesk.Core/Entities/ConnectionPoint.cs`
- `AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs`
- `AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs`
- `AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs`
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 新增节点与模板默认渲染为外侧圆点,减少手动修改。
- ✅ 选择“外侧”后圆点完全贴在节点外部,视觉符合预期。
### 附件圆颜色编辑改用 ColorPicker
- **日期**: 2025年11月6日
- **修改内容**:
1. 引入 `av:ColorPicker` 替换原有颜色文本框,支持直接选色,禁用 Alpha 频道。
2. 新增 `ColorHexToColorConverter` 实现十六进制字符串与 `Color` 互转,配合 `ColorPicker` 双向绑定。
3. 为 `ColorPicker` 提供统一样式(圆角、边框、高度),保持与其他输入控件一致的视觉风格。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- `AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs`
- **效果**:
- ✅ 颜色编辑更直观,避免手动输入 Hex。
- ✅ 色值仍以 `#RRGGBB` 字符串形式写回实体,兼容现有数据结构。
### 修正 ColorPicker 属性名以适配新版控件
- **日期**: 2025年11月6日
- **修改内容**:
1. 将 `ShowPreview`、`PaletteVisible` 替换为 Avalonia 11 新增的 `IsColorPreviewVisible`、`IsColorPaletteVisible` 属性。
2. 保留 `IsAlphaEnabled="False"` 设置,持续禁用 Alpha 通道输入。
3. 重新启用颜色预览与调色板,便于观察和选择颜色。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 解决构建时 AVLN2000 属性解析错误,ColorPicker 正常渲染。
- ✅ 色彩预览与调色板恢复显示,调整颜色更直观。
### 确保外侧连接点可见
- **日期**: 2025年11月6日
- **修改内容**:
1. 为节点模板中的根 `Border` 设置 `ClipToBounds="False"`,允许连接点超出节点边界时仍然渲染。
2. 保持现有圆角与阴影效果不变。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 选择“外侧”定位后,左右连接点完整显示在节点外侧。
### 调整外侧连接点偏移使视觉对齐
- **日期**: 2025年11月6日
- **修改内容**:
1. 将外侧模式下的偏移量由“直径”改为“直径的一半”,使圆点一半在边外、一半在边内。
2. 保持内侧定位逻辑不变。
- **涉及文件**:
- `AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs`
- **效果**:
- ✅ 外侧圆点与内侧视觉保持一致,贴边但不会完全漂出。
### 修正 ConnectorColumnPanel 右侧排列的外侧偏移
- **日期**: 2025年11月6日
- **修改内容**:
1. 调整 `ConnectorColumnPanel``Right` 分支的排布公式,允许负 `Margin.Right` 将圆点推到节点外侧。
2. 维持正向 margin 的内缩行为不变。
- **涉及文件**:
- `AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs`
- **效果**:
- ✅ 右侧外侧圆点将按照设置偏移正确露出外部,视觉与左侧一致。
### 优化特性面板表格与附件圆横向编辑体验
- **日期**: 2025年11月6日
- **调整内容**:
1. 组件基础属性改为表格式布局,使用带边框的双列表格展示名称、宽度、高度,列宽收紧至 110,信息更集中。
2. 左右附件圆编辑面板改为卡片顶部标题+横向三列(直径/颜色/定位)布局,字段一行内即可填写。
3. 附件圆列表改回纵向 `StackPanel`,每个圆独占一行,卡片随列宽拉伸;保留单卡片分栏布局并统一边距,确保各项独立且排版整洁。
- **涉及文件**:
- `AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml`
- **效果**:
- ✅ 特性信息以带边框表格呈现,阅读更清晰。
- ✅ 左右附件圆参数可横向填写,减少垂直空间占用。
### 节点附件圆重构:逐个圆配置半径与定位 ### 节点附件圆重构:逐个圆配置半径与定位
- **日期**: 2025年11月6日 - **日期**: 2025年11月6日
- **修改内容**: - **修改内容**:

Loading…
Cancel
Save