You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

494 lines
33 KiB

<reactive:ReactiveUserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:AuroraDesk.Presentation.ViewModels.Pages"
xmlns:reactive="using:ReactiveUI.Avalonia"
xmlns:entities="using:AuroraDesk.Core.Entities"
xmlns:converters="using:AuroraDesk.Presentation.Converters"
mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800"
x:Class="AuroraDesk.Presentation.Views.Pages.NodeCanvasPageView"
x:DataType="vm:NodeCanvasPageViewModel">
<reactive:ReactiveUserControl.Resources>
<converters:BooleanToBorderBrushConverter x:Key="BooleanToBorderBrushConverter"/>
<converters:BooleanToBorderThicknessConverter x:Key="BooleanToBorderThicknessConverter"/>
<converters:FilterInputPointsConverter x:Key="FilterInputPointsConverter"/>
<converters:FilterOutputPointsConverter x:Key="FilterOutputPointsConverter"/>
<converters:NodeToSelectionTextConverter x:Key="NodeToSelectionTextConverter"/>
<converters:IsNotNullConverter x:Key="IsNotNullConverter"/>
</reactive:ReactiveUserControl.Resources>
<Design.DataContext>
<vm:NodeCanvasPageViewModel />
</Design.DataContext>
<Grid Background="{StaticResource BackgroundWhite}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="320"/>
</Grid.ColumnDefinitions>
<!-- 左侧工具栏和组件库 -->
<Border Grid.Column="0"
Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,0,1,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 顶部标题 -->
<Border Grid.Row="0"
Background="{StaticResource BackgroundWhite}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,0,0,1"
Padding="15,12">
<TextBlock Text="节点编辑器"
FontSize="16"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/>
</Border>
<!-- 组件库区域 -->
<ScrollViewer x:Name="ComponentLibraryScrollViewer"
Grid.Row="1"
VerticalScrollBarVisibility="Auto"
Padding="12">
<StackPanel Spacing="12">
<TextBlock Text="组件库"
FontSize="13"
FontWeight="SemiBold"
Foreground="{StaticResource TextSecondary}"
Margin="0,0,0,8"/>
<!-- 节点模板列表 -->
<ItemsControl ItemsSource="{Binding NodeTemplates}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="entities:NodeTemplate">
<Border Background="{StaticResource BackgroundWhite}"
CornerRadius="8"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1"
Padding="12"
Margin="0,0,0,8"
Cursor="Hand"
x:Name="TemplateItem">
<Border.Styles>
<Style Selector="Border:pointerover">
<Setter Property="Background" Value="{StaticResource BackgroundLightHover}"/>
<Setter Property="BorderBrush" Value="{StaticResource PrimaryBlue}"/>
</Style>
<Style Selector="Border:pressed">
<Setter Property="Background" Value="{StaticResource BackgroundLightActive}"/>
</Style>
</Border.Styles>
<!-- 节点预览 -->
<StackPanel Spacing="8">
<Border Background="White"
CornerRadius="6"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1"
Padding="8"
MinWidth="80"
MinHeight="60"
HorizontalAlignment="Center">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 内容 -->
<TextBlock Grid.Row="0"
Text="{Binding Content}"
FontSize="12"
FontWeight="Medium"
Foreground="{StaticResource TextPrimary}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<!-- 连接点预览 -->
<Grid Grid.Row="1" Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧输入点 -->
<Border Grid.Column="0"
Width="12"
Height="12"
Background="White"
BorderBrush="{StaticResource PrimaryBlue}"
BorderThickness="1.5"
CornerRadius="6"
HorizontalAlignment="Left"/>
<!-- 右侧输出点 -->
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right"
Spacing="4">
<Border Width="12"
Height="12"
Background="White"
BorderBrush="{StaticResource StatusError}"
BorderThickness="1.5"
CornerRadius="6"/>
<Border Width="12"
Height="12"
Background="White"
BorderBrush="{StaticResource StatusError}"
BorderThickness="1.5"
CornerRadius="6"/>
<Border Width="12"
Height="12"
Background="White"
BorderBrush="{StaticResource StatusError}"
BorderThickness="1.5"
CornerRadius="6"/>
</StackPanel>
</Grid>
</Grid>
</Border>
<!-- 模板名称 -->
<TextBlock Text="{Binding DisplayName}"
FontSize="12"
FontWeight="Medium"
Foreground="{StaticResource TextPrimary}"
HorizontalAlignment="Center"/>
<!-- 描述 -->
<TextBlock Text="{Binding Description}"
FontSize="11"
Foreground="{StaticResource TextSecondary}"
HorizontalAlignment="Center"
TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
<!-- 底部操作按钮 -->
<Border Grid.Row="2"
Background="{StaticResource BackgroundWhite}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,1,0,0"
Padding="12">
<StackPanel Spacing="10">
<Button Content="清空画布"
Command="{Binding ClearCanvasCommand}"
Background="{StaticResource StatusError}"
Foreground="White"
BorderThickness="0"
CornerRadius="6"
Padding="12,8"
FontSize="13"
FontWeight="Medium"
Cursor="Hand">
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource ButtonCloseActive}"/>
</Style>
</Button.Styles>
</Button>
<Border Background="{StaticResource BackgroundLight}"
CornerRadius="6"
Padding="12"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1">
<TextBlock Text="提示:&#x0a;从组件库拖拽节点到画布&#x0a;或点击画布空白处添加节点"
Foreground="{StaticResource TextSecondary}"
FontSize="11"
LineHeight="18"
TextWrapping="Wrap"/>
</Border>
</StackPanel>
</Border>
</Grid>
</Border>
<!-- 中间画布区域 -->
<Grid Grid.Column="1" Background="{StaticResource BackgroundLight}">
<ScrollViewer x:Name="CanvasScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Background="{StaticResource BackgroundLight}">
<Canvas x:Name="CanvasContainer"
ClipToBounds="False"
MinWidth="2000"
MinHeight="2000"
Background="{StaticResource BackgroundWhite}">
<!-- 网格背景层 -->
<Canvas x:Name="GridBackgroundLayer"
IsHitTestVisible="False"
ClipToBounds="False"/>
<!-- 节点 -->
<ItemsControl x:Name="NodesItemsControl" ItemsSource="{Binding Nodes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ClipToBounds="False"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="entities:Node">
<ContentControl Content="{Binding}"
Canvas.Left="{Binding X}"
Canvas.Top="{Binding Y}">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<Border Background="White"
CornerRadius="6"
BorderBrush="{Binding IsSelected, Converter={StaticResource BooleanToBorderBrushConverter}}"
BorderThickness="{Binding IsSelected, Converter={StaticResource BooleanToBorderThicknessConverter}}"
Padding="12"
MinWidth="{Binding Width}"
MinHeight="{Binding Height}"
BoxShadow="0 2 8 0 #00000015">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 内容 -->
<TextBlock Grid.Row="0"
Text="{Binding Content}"
FontSize="14"
FontWeight="Medium"
Foreground="{StaticResource TextPrimary}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<!-- 连接点容器 -->
<Grid Grid.Row="1" Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧输入点 -->
<ItemsControl Grid.Column="0"
ItemsSource="{Binding ConnectionPoints, Converter={StaticResource FilterInputPointsConverter}}"
HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Spacing="4"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="entities:ConnectionPoint">
<Border Width="14"
Height="14"
Background="White"
BorderBrush="{StaticResource PrimaryBlue}"
BorderThickness="2"
CornerRadius="7"
Cursor="Hand"
Margin="0,2">
<Border.Styles>
<Style Selector="Border:pointerover">
<Setter Property="Background" Value="{StaticResource PrimaryBlue}"/>
<Setter Property="BorderBrush" Value="{StaticResource PrimaryBlueHover}"/>
</Style>
</Border.Styles>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- 右侧输出点 -->
<ItemsControl Grid.Column="1"
ItemsSource="{Binding ConnectionPoints, Converter={StaticResource FilterOutputPointsConverter}}"
HorizontalAlignment="Right">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Spacing="4"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="entities:ConnectionPoint">
<Grid Margin="0,2">
<Border Width="14"
Height="14"
Background="White"
BorderBrush="{StaticResource StatusError}"
BorderThickness="2"
CornerRadius="7"
Cursor="Hand"
HorizontalAlignment="Right">
<Border.Styles>
<Style Selector="Border:pointerover">
<Setter Property="Background" Value="{StaticResource StatusError}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonCloseActive}"/>
</Style>
</Border.Styles>
</Border>
<TextBlock Text="{Binding Label}"
FontSize="10"
FontWeight="Medium"
Foreground="{StaticResource TextSecondary}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0,0,18,0"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
</ScrollViewer>
</Grid>
<!-- 右侧属性面板 -->
<Border Grid.Column="2"
Background="{StaticResource BackgroundWhite}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1,0,0,0">
<ScrollViewer>
<StackPanel Margin="16">
<TextBlock Text="特性"
FontSize="18"
FontWeight="Bold"
Foreground="{StaticResource TextPrimary}"
Margin="0,0,0,12"/>
<TextBlock Text="{Binding SelectedNode, Converter={StaticResource NodeToSelectionTextConverter}}"
FontSize="13"
Foreground="{StaticResource TextSecondary}"
Margin="0,0,0,20"/>
<Border Background="{StaticResource BackgroundLight}"
CornerRadius="8"
Padding="16"
Margin="0,0,0,12"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1"
IsVisible="{Binding SelectedNode, Converter={StaticResource IsNotNullConverter}}">
<StackPanel Spacing="16">
<TextBlock Text="基本信息"
FontSize="14"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"
Margin="0,0,0,4"/>
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="12" RowSpacing="10">
<TextBlock Grid.Column="0"
Text="类型:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"
Width="70"/>
<TextBlock Grid.Column="1"
Text="节点"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="1"
Grid.Column="0"
Text="标题:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{Binding SelectedNode.Title}"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
</Grid>
<Separator Margin="0,8,0,8"/>
<TextBlock Text="几何"
FontSize="14"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"
Margin="0,0,0,4"/>
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="12" RowSpacing="8">
<TextBlock Grid.Column="0"
Text="X:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"
Width="70"/>
<TextBlock Grid.Column="1"
Text="{Binding SelectedNode.X, StringFormat='{}{0:F2}'}"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="1"
Grid.Column="0"
Text="Y:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{Binding SelectedNode.Y, StringFormat='{}{0:F2}'}"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="2"
Grid.Column="0"
Text="宽度:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="2"
Grid.Column="1"
Text="{Binding SelectedNode.Width, StringFormat='{}{0:F2}'}"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="3"
Grid.Column="0"
Text="高度:"
Foreground="{StaticResource TextSecondary}"
FontSize="13"
VerticalAlignment="Center"/>
<TextBlock Grid.Row="3"
Grid.Column="1"
Text="{Binding SelectedNode.Height, StringFormat='{}{0:F2}'}"
Foreground="{StaticResource TextPrimary}"
FontSize="13"
FontWeight="Medium"
VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</Border>
</Grid>
</reactive:ReactiveUserControl>