mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-03 23:56:37 +08:00
项目结构调整
This commit is contained in:
549
Extensions/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml
Normal file
549
Extensions/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml
Normal file
@@ -0,0 +1,549 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
|
||||
|
||||
<dd:ColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
|
||||
<DrawingBrush x:Key="CheckerBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
|
||||
<DrawingBrush.Drawing>
|
||||
<DrawingGroup>
|
||||
<GeometryDrawing Brush="White">
|
||||
<GeometryDrawing.Geometry>
|
||||
<RectangleGeometry Rect="0,0 100,100" />
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
<GeometryDrawing Brush="LightGray">
|
||||
<GeometryDrawing.Geometry>
|
||||
<GeometryGroup>
|
||||
<RectangleGeometry Rect="0,0 50,50" />
|
||||
<RectangleGeometry Rect="50,50 50,50" />
|
||||
</GeometryGroup>
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
</DrawingGroup>
|
||||
</DrawingBrush.Drawing>
|
||||
</DrawingBrush>
|
||||
|
||||
<SolidColorBrush x:Key="HorizontalSliderTrackNormalBackground"
|
||||
Color="#FFE7EAEA" />
|
||||
|
||||
<LinearGradientBrush x:Key="HorizontalSliderTrackNormalBorder"
|
||||
EndPoint="0,1"
|
||||
StartPoint="0,0">
|
||||
<GradientStop Color="#FFAEB1AF"
|
||||
Offset="0.1" />
|
||||
<GradientStop Color="White"
|
||||
Offset=".9" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="ThumbStroke"
|
||||
EndPoint="0.5,1"
|
||||
StartPoint="0.5,0">
|
||||
<GradientStop Color="#FFA3AEB9"
|
||||
Offset="0" />
|
||||
<GradientStop Color="#FF8399A9"
|
||||
Offset="0.375" />
|
||||
<GradientStop Color="#FF718597"
|
||||
Offset="0.375" />
|
||||
<GradientStop Color="#FF617584"
|
||||
Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="ThumbFill"
|
||||
StartPoint="0,0"
|
||||
EndPoint="0,1">
|
||||
<LinearGradientBrush.GradientStops>
|
||||
<GradientStopCollection>
|
||||
<GradientStop Offset="0"
|
||||
Color="#FFfefefe" />
|
||||
<GradientStop Offset="0.5"
|
||||
Color="#FFeff1f2" />
|
||||
<GradientStop Offset="1"
|
||||
Color="#FFd0d6db" />
|
||||
</GradientStopCollection>
|
||||
</LinearGradientBrush.GradientStops>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<SolidColorBrush x:Key="ThumbMouseOver"
|
||||
Color="#FFE5F2F6" />
|
||||
|
||||
<Style x:Key="ColorCanvasTextBoxStyle"
|
||||
TargetType="TextBox"
|
||||
BasedOn="{StaticResource {x:Type TextBox}}">
|
||||
<Setter Property="Background"
|
||||
Value="Transparent" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsFocused" Value="False">
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SliderRepeatButtonStyle"
|
||||
TargetType="{x:Type RepeatButton}">
|
||||
<Setter Property="OverridesDefaultStyle"
|
||||
Value="true" />
|
||||
<Setter Property="IsTabStop"
|
||||
Value="false" />
|
||||
<Setter Property="Focusable"
|
||||
Value="false" />
|
||||
<Setter Property="Background"
|
||||
Value="Transparent" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type RepeatButton}">
|
||||
<Border Background="{TemplateBinding Background}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CustomThumbForSlider"
|
||||
TargetType="{x:Type Thumb}">
|
||||
<Setter Property="OverridesDefaultStyle"
|
||||
Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Rectangle x:Name="_thumb"
|
||||
Fill="{StaticResource ThumbFill}"
|
||||
Stroke="{StaticResource ThumbStroke}"
|
||||
Height="14"
|
||||
Width="8"
|
||||
RadiusX="1"
|
||||
RadiusY="1" />
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="True">
|
||||
<Setter TargetName="_thumb" Property="Rectangle.Fill" Value="{StaticResource ThumbMouseOver}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="VerticalSlideThumbStyle"
|
||||
TargetType="{x:Type Thumb}">
|
||||
<Setter Property="Focusable"
|
||||
Value="false" />
|
||||
<Setter Property="OverridesDefaultStyle"
|
||||
Value="true" />
|
||||
<Setter Property="Height"
|
||||
Value="12" />
|
||||
<Setter Property="Width"
|
||||
Value="11" />
|
||||
<Setter Property="Foreground"
|
||||
Value="Gray" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Canvas SnapsToDevicePixels="true">
|
||||
<Path x:Name="LeftArrow"
|
||||
Stretch="Fill"
|
||||
StrokeLineJoin="Round"
|
||||
Stroke="#FF000000"
|
||||
Fill="#FF000000"
|
||||
Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z "
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
Width="6"
|
||||
Height="8">
|
||||
<Path.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform />
|
||||
<TranslateTransform Y="6"
|
||||
X="-3" />
|
||||
</TransformGroup>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<Path x:Name="RightArrow"
|
||||
Stretch="Fill"
|
||||
StrokeLineJoin="Round"
|
||||
Stroke="#FF000000"
|
||||
Fill="#FF000000"
|
||||
Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z "
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
Width="6"
|
||||
Height="8">
|
||||
<Path.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform Angle="-180" />
|
||||
<TranslateTransform Y="6"
|
||||
X="8" />
|
||||
</TransformGroup>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Canvas>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ColorCanvasSliderStyle"
|
||||
TargetType="{x:Type Slider}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Slider}">
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
SnapsToDevicePixels="true">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto"
|
||||
MinHeight="{TemplateBinding MinHeight}" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TickBar x:Name="TopTick"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Height="4"
|
||||
Placement="Top"
|
||||
Grid.Row="0"
|
||||
Visibility="Collapsed" />
|
||||
<TickBar x:Name="BottomTick"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Height="4"
|
||||
Placement="Bottom"
|
||||
Grid.Row="2"
|
||||
Visibility="Collapsed" />
|
||||
<Border x:Name="TrackBackground"
|
||||
BorderBrush="{StaticResource HorizontalSliderTrackNormalBorder}"
|
||||
BorderThickness="1"
|
||||
Background="{StaticResource HorizontalSliderTrackNormalBackground}"
|
||||
CornerRadius="1"
|
||||
Height="4.0"
|
||||
Margin="5,0"
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="center">
|
||||
<Canvas Margin="-6,-1">
|
||||
<Rectangle x:Name="PART_SelectionRange"
|
||||
Fill="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
|
||||
Height="4.0"
|
||||
Stroke="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"
|
||||
StrokeThickness="1.0"
|
||||
Visibility="Hidden" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Track x:Name="PART_Track" Grid.Row="1">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource SliderRepeatButtonStyle}" />
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource SliderRepeatButtonStyle}" />
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb x:Name="Thumb" Style="{StaticResource CustomThumbForSlider}" />
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:ColorSpectrumSlider}">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="DarkGray" />
|
||||
<Setter Property="BorderThickness"
|
||||
Value="1" />
|
||||
<Setter Property="Orientation"
|
||||
Value="Vertical" />
|
||||
<Setter Property="Background"
|
||||
Value="Transparent" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
|
||||
<Setter Property="Minimum"
|
||||
Value="0" />
|
||||
<Setter Property="Maximum"
|
||||
Value="360" />
|
||||
<Setter Property="TickFrequency"
|
||||
Value="0.001" />
|
||||
<Setter Property="IsSnapToTickEnabled"
|
||||
Value="True" />
|
||||
<Setter Property="IsDirectionReversed"
|
||||
Value="False" />
|
||||
<Setter Property="IsMoveToPointEnabled"
|
||||
Value="True" />
|
||||
<Setter Property="Value"
|
||||
Value="0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:ColorSpectrumSlider}">
|
||||
<Grid>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Margin="0,8,0,0">
|
||||
<Border x:Name="PART_TrackBackground"
|
||||
Width="15">
|
||||
<Rectangle x:Name="PART_SpectrumDisplay"
|
||||
Stretch="Fill"
|
||||
VerticalAlignment="Stretch" />
|
||||
</Border>
|
||||
</Border>
|
||||
|
||||
<Track Name="PART_Track">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}"
|
||||
Command="Slider.DecreaseLarge" />
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}"
|
||||
Command="Slider.IncreaseLarge" />
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{StaticResource VerticalSlideThumbStyle}" />
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ColorCanvasStyle" TargetType="{x:Type controls:ColorCanvas}">
|
||||
<Setter Property="Background"
|
||||
Value="White" />
|
||||
<Setter Property="BorderBrush"
|
||||
Value="Gray" />
|
||||
<Setter Property="BorderThickness"
|
||||
Value="1" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:ColorCanvas}">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Padding="3">
|
||||
<Grid Margin="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border BorderThickness="1"
|
||||
BorderBrush="DarkGray"
|
||||
ClipToBounds="True"
|
||||
Background="{StaticResource CheckerBrush}">
|
||||
<Canvas x:Name="PART_ColorShadingCanvas"
|
||||
Width="200"
|
||||
Height="100"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top">
|
||||
<Rectangle x:Name="ColorShadingRectangle"
|
||||
Height="{Binding ElementName=PART_ColorShadingCanvas, Path=Height}"
|
||||
Width="{Binding ElementName=PART_ColorShadingCanvas, Path=Width}"
|
||||
Fill="{Binding SelectedColor, ElementName=PART_SpectrumSlider, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
|
||||
<Rectangle x:Name="WhiteGradient"
|
||||
Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}"
|
||||
Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}">
|
||||
<Rectangle.Fill>
|
||||
<LinearGradientBrush StartPoint="0,0"
|
||||
EndPoint="1,0">
|
||||
<GradientStop Offset="0"
|
||||
Color="#ffffffff" />
|
||||
<GradientStop Offset="1"
|
||||
Color="Transparent" />
|
||||
</LinearGradientBrush>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<Rectangle x:Name="BlackGradient"
|
||||
Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}"
|
||||
Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}">
|
||||
<Rectangle.Fill>
|
||||
<LinearGradientBrush StartPoint="0,1" EndPoint="0, 0">
|
||||
<GradientStop Offset="0" Color="#ff000000" />
|
||||
<GradientStop Offset="1" Color="#00000000" />
|
||||
</LinearGradientBrush>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<Canvas x:Name="PART_ColorShadeSelector"
|
||||
Width="10"
|
||||
Height="10"
|
||||
IsHitTestVisible="False">
|
||||
<Ellipse Width="10"
|
||||
Height="10"
|
||||
StrokeThickness="3"
|
||||
Stroke="#FFFFFFFF"
|
||||
IsHitTestVisible="False" />
|
||||
<Ellipse Width="10"
|
||||
Height="10"
|
||||
StrokeThickness="1"
|
||||
Stroke="#FF000000"
|
||||
IsHitTestVisible="False" />
|
||||
</Canvas>
|
||||
</Canvas>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1"
|
||||
Margin="0,5,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="SelectedColorBorder"
|
||||
Background="{StaticResource CheckerBrush}"
|
||||
Height="22"
|
||||
Margin="2,0,2,0"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#FFC9CACA">
|
||||
<Rectangle x:Name="SelectedColor"
|
||||
Fill="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
|
||||
</Border>
|
||||
<TextBox x:Name="PART_HexadecimalTextBox"
|
||||
Grid.Column="1"
|
||||
Margin="2,0,2,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ColorCanvasTextBoxStyle}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="1" Grid.RowSpan="2" Margin="4,-8,0,0" ClipToBounds="False">
|
||||
<controls:ColorSpectrumSlider x:Name="PART_SpectrumSlider" VerticalAlignment="Stretch" />
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Border x:Name="RGBBorder"
|
||||
MinWidth="180"
|
||||
Grid.Row="1"
|
||||
BorderThickness="1"
|
||||
ClipToBounds="True"
|
||||
Margin="0,10,0,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Text="R"
|
||||
VerticalAlignment="Center" />
|
||||
<Slider x:Name="PART_RSlider"
|
||||
Maximum="255"
|
||||
SmallChange="1"
|
||||
LargeChange="10"
|
||||
TickFrequency="1"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="4,6,4,6"
|
||||
Style="{StaticResource ColorCanvasSliderStyle}"
|
||||
Value="{Binding R, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Text="{Binding Value, ElementName=PART_RSlider}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ColorCanvasTextBoxStyle}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Text="G"
|
||||
VerticalAlignment="Center" />
|
||||
<Slider x:Name="PART_GSlider"
|
||||
Maximum="255"
|
||||
SmallChange="1"
|
||||
LargeChange="10"
|
||||
TickFrequency="1"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="4,6,4,6"
|
||||
Style="{StaticResource ColorCanvasSliderStyle}"
|
||||
Value="{Binding G, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Text="{Binding Value, ElementName=PART_GSlider}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ColorCanvasTextBoxStyle}" />
|
||||
|
||||
<TextBlock Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Text="B"
|
||||
VerticalAlignment="Center" />
|
||||
<Slider x:Name="PART_BSlider"
|
||||
Maximum="255"
|
||||
SmallChange="1"
|
||||
LargeChange="10"
|
||||
TickFrequency="1"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="4,6,4,6"
|
||||
Style="{StaticResource ColorCanvasSliderStyle}"
|
||||
Value="{Binding B, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="2"
|
||||
Grid.Column="3"
|
||||
Text="{Binding Value, ElementName=PART_BSlider}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ColorCanvasTextBoxStyle}" />
|
||||
|
||||
<TextBlock Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Text="A"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding Path=UsingAlphaChannel, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<Slider x:Name="PART_OpacitySlider"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Maximum="255"
|
||||
SmallChange="1"
|
||||
LargeChange="10"
|
||||
Margin="4,6,4,6"
|
||||
Style="{StaticResource ColorCanvasSliderStyle}"
|
||||
Value="{Binding Path=A, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding Path=UsingAlphaChannel, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<TextBox Grid.Row="3"
|
||||
Grid.Column="3"
|
||||
Text="{Binding Value, ElementName=PART_OpacitySlider}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ColorCanvasTextBoxStyle}"
|
||||
Visibility="{Binding Path=UsingAlphaChannel, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
|
||||
</Trigger>
|
||||
<Trigger Property="SelectedColor" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_ColorShadeSelector" />
|
||||
<Setter Property="Background" Value="Transparent" TargetName="SelectedColorBorder" />
|
||||
<!--<Setter Property="IsEnabled" Value="False" TargetName="RGBBorder" />-->
|
||||
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" TargetName="RGBBorder" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style BasedOn="{StaticResource ColorCanvasStyle}" TargetType="{x:Type controls:ColorCanvas}"/>
|
||||
|
||||
</ResourceDictionary>
|
||||
597
Extensions/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs
Normal file
597
Extensions/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs
Normal file
@@ -0,0 +1,597 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
[TemplatePart(Name = PART_ColorShadingCanvas, Type = typeof(Canvas))]
|
||||
[TemplatePart(Name = PART_ColorShadeSelector, Type = typeof(Canvas))]
|
||||
[TemplatePart(Name = PART_SpectrumSlider, Type = typeof(ColorSpectrumSlider))]
|
||||
[TemplatePart(Name = PART_HexadecimalTextBox, Type = typeof(TextBox))]
|
||||
public class ColorCanvas : Control
|
||||
{
|
||||
private const string PART_ColorShadingCanvas = "PART_ColorShadingCanvas";
|
||||
private const string PART_ColorShadeSelector = "PART_ColorShadeSelector";
|
||||
private const string PART_SpectrumSlider = "PART_SpectrumSlider";
|
||||
private const string PART_HexadecimalTextBox = "PART_HexadecimalTextBox";
|
||||
|
||||
#region Private Members
|
||||
|
||||
private TranslateTransform _colorShadeSelectorTransform = new TranslateTransform();
|
||||
private Canvas _colorShadingCanvas;
|
||||
private Canvas _colorShadeSelector;
|
||||
private ColorSpectrumSlider _spectrumSlider;
|
||||
private TextBox _hexadecimalTextBox;
|
||||
private Point? _currentColorPosition;
|
||||
private bool _surpressPropertyChanged;
|
||||
private bool _updateSpectrumSliderValue = true;
|
||||
|
||||
#endregion //Private Members
|
||||
|
||||
#region Properties
|
||||
|
||||
#region SelectedColor
|
||||
|
||||
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color?), typeof(ColorCanvas), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedColorChanged));
|
||||
public Color? SelectedColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Color?)GetValue(SelectedColorProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SelectedColorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSelectedColorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnSelectedColorChanged((Color?)e.OldValue, (Color?)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedColorChanged(Color? oldValue, Color? newValue)
|
||||
{
|
||||
SetHexadecimalStringProperty(GetFormatedColorString(newValue), false);
|
||||
UpdateRGBValues(newValue);
|
||||
UpdateColorShadeSelectorPosition(newValue);
|
||||
|
||||
RoutedPropertyChangedEventArgs<Color?> args = new RoutedPropertyChangedEventArgs<Color?>(oldValue, newValue);
|
||||
args.RoutedEvent = SelectedColorChangedEvent;
|
||||
RaiseEvent(args);
|
||||
}
|
||||
|
||||
#endregion //SelectedColor
|
||||
|
||||
#region RGB
|
||||
|
||||
#region A
|
||||
|
||||
public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, OnAChanged));
|
||||
public byte A
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)GetValue(AProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnAChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnAChanged((byte)e.OldValue, (byte)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnAChanged(byte oldValue, byte newValue)
|
||||
{
|
||||
if (!_surpressPropertyChanged)
|
||||
UpdateSelectedColor();
|
||||
}
|
||||
|
||||
#endregion //A
|
||||
|
||||
#region R
|
||||
|
||||
public static readonly DependencyProperty RProperty = DependencyProperty.Register("R", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnRChanged));
|
||||
public byte R
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)GetValue(RProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(RProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnRChanged((byte)e.OldValue, (byte)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnRChanged(byte oldValue, byte newValue)
|
||||
{
|
||||
if (!_surpressPropertyChanged)
|
||||
UpdateSelectedColor();
|
||||
}
|
||||
|
||||
#endregion //R
|
||||
|
||||
#region G
|
||||
|
||||
public static readonly DependencyProperty GProperty = DependencyProperty.Register("G", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnGChanged));
|
||||
public byte G
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)GetValue(GProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(GProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnGChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnGChanged((byte)e.OldValue, (byte)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnGChanged(byte oldValue, byte newValue)
|
||||
{
|
||||
if (!_surpressPropertyChanged)
|
||||
UpdateSelectedColor();
|
||||
}
|
||||
|
||||
#endregion //G
|
||||
|
||||
#region B
|
||||
|
||||
public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnBChanged));
|
||||
public byte B
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)GetValue(BProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(BProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnBChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnBChanged((byte)e.OldValue, (byte)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnBChanged(byte oldValue, byte newValue)
|
||||
{
|
||||
if (!_surpressPropertyChanged)
|
||||
UpdateSelectedColor();
|
||||
}
|
||||
|
||||
#endregion //B
|
||||
|
||||
#endregion //RGB
|
||||
|
||||
#region HexadecimalString
|
||||
|
||||
public static readonly DependencyProperty HexadecimalStringProperty = DependencyProperty.Register("HexadecimalString", typeof(string), typeof(ColorCanvas), new UIPropertyMetadata("", OnHexadecimalStringChanged, OnCoerceHexadecimalString));
|
||||
public string HexadecimalString
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(HexadecimalStringProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(HexadecimalStringProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnHexadecimalStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnHexadecimalStringChanged((string)e.OldValue, (string)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnHexadecimalStringChanged(string oldValue, string newValue)
|
||||
{
|
||||
string newColorString = GetFormatedColorString(newValue);
|
||||
string currentColorString = GetFormatedColorString(SelectedColor);
|
||||
if (!currentColorString.Equals(newColorString))
|
||||
{
|
||||
Color? col = null;
|
||||
if (!string.IsNullOrEmpty(newColorString))
|
||||
{
|
||||
col = (Color)ColorConverter.ConvertFromString(newColorString);
|
||||
}
|
||||
UpdateSelectedColor(col);
|
||||
}
|
||||
|
||||
SetHexadecimalTextBoxTextProperty(newValue);
|
||||
}
|
||||
|
||||
private static object OnCoerceHexadecimalString(DependencyObject d, object basevalue)
|
||||
{
|
||||
var colorCanvas = (ColorCanvas)d;
|
||||
if (colorCanvas == null)
|
||||
return basevalue;
|
||||
|
||||
return colorCanvas.OnCoerceHexadecimalString(basevalue);
|
||||
}
|
||||
|
||||
private object OnCoerceHexadecimalString(object newValue)
|
||||
{
|
||||
var value = newValue as string;
|
||||
string retValue = value;
|
||||
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(retValue))
|
||||
{
|
||||
ColorConverter.ConvertFromString(value);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//When HexadecimalString is changed via Code-Behind and hexadecimal format is bad, throw.
|
||||
throw new InvalidDataException("Color provided is not in the correct format.");
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
#endregion //HexadecimalString
|
||||
|
||||
#region UsingAlphaChannel
|
||||
|
||||
public static readonly DependencyProperty UsingAlphaChannelProperty = DependencyProperty.Register("UsingAlphaChannel", typeof(bool), typeof(ColorCanvas), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnUsingAlphaChannelPropertyChanged)));
|
||||
public bool UsingAlphaChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(UsingAlphaChannelProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(UsingAlphaChannelProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnUsingAlphaChannelPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorCanvas colorCanvas = o as ColorCanvas;
|
||||
if (colorCanvas != null)
|
||||
colorCanvas.OnUsingAlphaChannelChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnUsingAlphaChannelChanged()
|
||||
{
|
||||
SetHexadecimalStringProperty(GetFormatedColorString(SelectedColor), false);
|
||||
}
|
||||
|
||||
#endregion //UsingAlphaChannel
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
static ColorCanvas()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorCanvas), new FrameworkPropertyMetadata(typeof(ColorCanvas)));
|
||||
}
|
||||
|
||||
#endregion //Constructors
|
||||
|
||||
#region Base Class Overrides
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (_colorShadingCanvas != null)
|
||||
{
|
||||
_colorShadingCanvas.MouseLeftButtonDown -= ColorShadingCanvas_MouseLeftButtonDown;
|
||||
_colorShadingCanvas.MouseLeftButtonUp -= ColorShadingCanvas_MouseLeftButtonUp;
|
||||
_colorShadingCanvas.MouseMove -= ColorShadingCanvas_MouseMove;
|
||||
_colorShadingCanvas.SizeChanged -= ColorShadingCanvas_SizeChanged;
|
||||
}
|
||||
|
||||
_colorShadingCanvas = GetTemplateChild(PART_ColorShadingCanvas) as Canvas;
|
||||
|
||||
if (_colorShadingCanvas != null)
|
||||
{
|
||||
_colorShadingCanvas.MouseLeftButtonDown += ColorShadingCanvas_MouseLeftButtonDown;
|
||||
_colorShadingCanvas.MouseLeftButtonUp += ColorShadingCanvas_MouseLeftButtonUp;
|
||||
_colorShadingCanvas.MouseMove += ColorShadingCanvas_MouseMove;
|
||||
_colorShadingCanvas.SizeChanged += ColorShadingCanvas_SizeChanged;
|
||||
}
|
||||
|
||||
_colorShadeSelector = GetTemplateChild(PART_ColorShadeSelector) as Canvas;
|
||||
|
||||
if (_colorShadeSelector != null)
|
||||
_colorShadeSelector.RenderTransform = _colorShadeSelectorTransform;
|
||||
|
||||
if (_spectrumSlider != null)
|
||||
_spectrumSlider.ValueChanged -= SpectrumSlider_ValueChanged;
|
||||
|
||||
_spectrumSlider = GetTemplateChild(PART_SpectrumSlider) as ColorSpectrumSlider;
|
||||
|
||||
if (_spectrumSlider != null)
|
||||
_spectrumSlider.ValueChanged += SpectrumSlider_ValueChanged;
|
||||
|
||||
if (_hexadecimalTextBox != null)
|
||||
_hexadecimalTextBox.LostFocus -= new RoutedEventHandler(HexadecimalTextBox_LostFocus);
|
||||
|
||||
_hexadecimalTextBox = GetTemplateChild(PART_HexadecimalTextBox) as TextBox;
|
||||
|
||||
if (_hexadecimalTextBox != null)
|
||||
_hexadecimalTextBox.LostFocus += new RoutedEventHandler(HexadecimalTextBox_LostFocus);
|
||||
|
||||
UpdateRGBValues(SelectedColor);
|
||||
UpdateColorShadeSelectorPosition(SelectedColor);
|
||||
|
||||
// When changing theme, HexadecimalString needs to be set since it is not binded.
|
||||
SetHexadecimalTextBoxTextProperty(GetFormatedColorString(SelectedColor));
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
//hitting enter on textbox will update Hexadecimal string
|
||||
if (e.Key == Key.Enter && e.OriginalSource is TextBox)
|
||||
{
|
||||
TextBox textBox = (TextBox)e.OriginalSource;
|
||||
if (textBox.Name == PART_HexadecimalTextBox)
|
||||
SetHexadecimalStringProperty(textBox.Text, true);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Base Class Overrides
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
void ColorShadingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_colorShadingCanvas != null)
|
||||
{
|
||||
Point p = e.GetPosition(_colorShadingCanvas);
|
||||
UpdateColorShadeSelectorPositionAndCalculateColor(p, true);
|
||||
_colorShadingCanvas.CaptureMouse();
|
||||
//Prevent from closing ColorCanvas after mouseDown in ListView
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ColorShadingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_colorShadingCanvas != null)
|
||||
{
|
||||
_colorShadingCanvas.ReleaseMouseCapture();
|
||||
}
|
||||
}
|
||||
|
||||
void ColorShadingCanvas_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (_colorShadingCanvas != null)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
Point p = e.GetPosition(_colorShadingCanvas);
|
||||
UpdateColorShadeSelectorPositionAndCalculateColor(p, true);
|
||||
Mouse.Synchronize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ColorShadingCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
if (_currentColorPosition != null)
|
||||
{
|
||||
Point _newPoint = new Point
|
||||
{
|
||||
X = ((Point)_currentColorPosition).X * e.NewSize.Width,
|
||||
Y = ((Point)_currentColorPosition).Y * e.NewSize.Height
|
||||
};
|
||||
|
||||
UpdateColorShadeSelectorPositionAndCalculateColor(_newPoint, false);
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if ((_currentColorPosition != null) && (this.SelectedColor != null))
|
||||
{
|
||||
CalculateColor((Point)_currentColorPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void HexadecimalTextBox_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
TextBox textbox = sender as TextBox;
|
||||
SetHexadecimalStringProperty(textbox.Text, true);
|
||||
}
|
||||
|
||||
#endregion //Event Handlers
|
||||
|
||||
#region Events
|
||||
|
||||
public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color?>), typeof(ColorCanvas));
|
||||
public event RoutedPropertyChangedEventHandler<Color?> SelectedColorChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler(SelectedColorChangedEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler(SelectedColorChangedEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Events
|
||||
|
||||
#region Methods
|
||||
|
||||
private void UpdateSelectedColor()
|
||||
{
|
||||
SelectedColor = Color.FromArgb(A, R, G, B);
|
||||
}
|
||||
|
||||
private void UpdateSelectedColor(Color? color)
|
||||
{
|
||||
SelectedColor = ((color != null) && color.HasValue)
|
||||
? (Color?)Color.FromArgb(color.Value.A, color.Value.R, color.Value.G, color.Value.B)
|
||||
: null;
|
||||
}
|
||||
|
||||
private void UpdateRGBValues(Color? color)
|
||||
{
|
||||
if ((color == null) || !color.HasValue)
|
||||
return;
|
||||
|
||||
_surpressPropertyChanged = true;
|
||||
|
||||
A = color.Value.A;
|
||||
R = color.Value.R;
|
||||
G = color.Value.G;
|
||||
B = color.Value.B;
|
||||
|
||||
_surpressPropertyChanged = false;
|
||||
}
|
||||
|
||||
private void UpdateColorShadeSelectorPositionAndCalculateColor(Point p, bool calculateColor)
|
||||
{
|
||||
if ((_colorShadingCanvas == null) || (_colorShadeSelector == null))
|
||||
return;
|
||||
|
||||
if (p.Y < 0)
|
||||
p.Y = 0;
|
||||
|
||||
if (p.X < 0)
|
||||
p.X = 0;
|
||||
|
||||
if (p.X > _colorShadingCanvas.ActualWidth)
|
||||
p.X = _colorShadingCanvas.ActualWidth;
|
||||
|
||||
if (p.Y > _colorShadingCanvas.ActualHeight)
|
||||
p.Y = _colorShadingCanvas.ActualHeight;
|
||||
|
||||
_colorShadeSelectorTransform.X = p.X - (_colorShadeSelector.Width / 2);
|
||||
_colorShadeSelectorTransform.Y = p.Y - (_colorShadeSelector.Height / 2);
|
||||
|
||||
p.X = p.X / _colorShadingCanvas.ActualWidth;
|
||||
p.Y = p.Y / _colorShadingCanvas.ActualHeight;
|
||||
|
||||
_currentColorPosition = p;
|
||||
|
||||
if (calculateColor)
|
||||
CalculateColor(p);
|
||||
}
|
||||
|
||||
private void UpdateColorShadeSelectorPosition(Color? color)
|
||||
{
|
||||
if ((_spectrumSlider == null) || (_colorShadingCanvas == null) || (color == null) || !color.HasValue)
|
||||
return;
|
||||
|
||||
_currentColorPosition = null;
|
||||
|
||||
HsvColor hsv = ColorUtilities.ConvertRgbToHsv(color.Value.R, color.Value.G, color.Value.B);
|
||||
|
||||
if (_updateSpectrumSliderValue)
|
||||
{
|
||||
_spectrumSlider.Value = hsv.H;
|
||||
}
|
||||
|
||||
Point p = new Point(hsv.S, 1 - hsv.V);
|
||||
|
||||
_currentColorPosition = p;
|
||||
|
||||
_colorShadeSelectorTransform.X = (p.X * _colorShadingCanvas.Width) - 5;
|
||||
_colorShadeSelectorTransform.Y = (p.Y * _colorShadingCanvas.Height) - 5;
|
||||
}
|
||||
|
||||
private void CalculateColor(Point p)
|
||||
{
|
||||
if (_spectrumSlider == null)
|
||||
return;
|
||||
|
||||
HsvColor hsv = new HsvColor(360 - _spectrumSlider.Value, 1, 1)
|
||||
{
|
||||
S = p.X,
|
||||
V = 1 - p.Y
|
||||
};
|
||||
var currentColor = ColorUtilities.ConvertHsvToRgb(hsv.H, hsv.S, hsv.V);
|
||||
currentColor.A = A;
|
||||
_updateSpectrumSliderValue = false;
|
||||
SelectedColor = currentColor;
|
||||
_updateSpectrumSliderValue = true;
|
||||
SetHexadecimalStringProperty(GetFormatedColorString(SelectedColor), false);
|
||||
}
|
||||
|
||||
private string GetFormatedColorString(Color? colorToFormat)
|
||||
{
|
||||
if ((colorToFormat == null) || !colorToFormat.HasValue)
|
||||
return string.Empty;
|
||||
return ColorUtilities.FormatColorString(colorToFormat.ToString(), UsingAlphaChannel);
|
||||
}
|
||||
|
||||
private string GetFormatedColorString(string stringToFormat)
|
||||
{
|
||||
return ColorUtilities.FormatColorString(stringToFormat, UsingAlphaChannel);
|
||||
}
|
||||
|
||||
private void SetHexadecimalStringProperty(string newValue, bool modifyFromUI)
|
||||
{
|
||||
if (modifyFromUI)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(newValue))
|
||||
{
|
||||
ColorConverter.ConvertFromString(newValue);
|
||||
}
|
||||
HexadecimalString = newValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//When HexadecimalString is changed via UI and hexadecimal format is bad, keep the previous HexadecimalString.
|
||||
SetHexadecimalTextBoxTextProperty(HexadecimalString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//When HexadecimalString is changed via Code-Behind, hexadecimal format will be evaluated in OnCoerceHexadecimalString()
|
||||
HexadecimalString = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHexadecimalTextBoxTextProperty(string newValue)
|
||||
{
|
||||
if (_hexadecimalTextBox != null)
|
||||
_hexadecimalTextBox.Text = newValue;
|
||||
}
|
||||
|
||||
#endregion //Methods
|
||||
}
|
||||
}
|
||||
37
Extensions/AIStudio.Wpf.Mind/Controls/ColorItem.cs
Normal file
37
Extensions/AIStudio.Wpf.Mind/Controls/ColorItem.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
public class ColorItem
|
||||
{
|
||||
public Color? Color
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public ColorItem(Color? color, string name)
|
||||
{
|
||||
Color = color;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var ci = obj as ColorItem;
|
||||
if (ci == null)
|
||||
return false;
|
||||
return (ci.Color.Equals(Color) && ci.Name.Equals(Name));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.Color.GetHashCode() ^ this.Name.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
378
Extensions/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
Normal file
378
Extensions/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
Normal file
@@ -0,0 +1,378 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/ColorCanvas.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Geometry x:Key="DownArrowGeometry">M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z</Geometry>
|
||||
|
||||
<Style x:Key="ColorPickerToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
|
||||
|
||||
<Grid x:Name="arrowGlyph" Grid.Column="1">
|
||||
<Path x:Name="Arrow"
|
||||
Width="9"
|
||||
Height="6"
|
||||
Margin="0 0 3 0"
|
||||
Stretch="Fill"
|
||||
Data="{StaticResource DownArrowGeometry}"
|
||||
Fill="#FF000000"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<DrawingBrush x:Key="CheckerBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
|
||||
<DrawingBrush.Drawing>
|
||||
<DrawingGroup>
|
||||
<GeometryDrawing Brush="White">
|
||||
<GeometryDrawing.Geometry>
|
||||
<RectangleGeometry Rect="0,0 100,100" />
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
<GeometryDrawing Brush="LightGray">
|
||||
<GeometryDrawing.Geometry>
|
||||
<GeometryGroup>
|
||||
<RectangleGeometry Rect="0,0 50,50" />
|
||||
<RectangleGeometry Rect="50,50 50,50" />
|
||||
</GeometryGroup>
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
</DrawingGroup>
|
||||
</DrawingBrush.Drawing>
|
||||
</DrawingBrush>
|
||||
|
||||
<!-- =============================================================================== -->
|
||||
<!-- ColorPicker -->
|
||||
<!-- =============================================================================== -->
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<dd:BoolInverseConverter x:Key="BoolInverseConverter" />
|
||||
<dd:ColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
|
||||
<dd:AdditionConverter x:Key="AdditionConverter" />
|
||||
<controls:ColorModeToTabItemSelectedConverter x:Key="ColorModeToTabItemSelectedConverter" />
|
||||
<dd:GridLengthConverter x:Key="GridLengthConverter"/>
|
||||
|
||||
<Style x:Key="ColorItemContainerStyle" TargetType="{x:Type ListBoxItem}">
|
||||
<Setter Property="ToolTip" Value="{Binding Name}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Grid x:Name="mainGrid"
|
||||
ToolTip="{Binding Name}">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="ToolTip">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="Content"
|
||||
Value="{x:Static sys:String.Empty}">
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<Border BorderThickness="1" Background="Transparent" BorderBrush="Transparent" x:Name="_outerBorder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Border Background="Transparent" BorderThickness="1" BorderBrush="Transparent" x:Name="_innerBorder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="_outerBorder" Property="BorderBrush" Value="#FFFF0000" />
|
||||
<Setter TargetName="_innerBorder" Property="BorderBrush" Value="#FFFFFF00" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="_outerBorder" Property="BorderBrush" Value="#FFFF0000" />
|
||||
<Setter TargetName="_innerBorder" Property="BorderBrush" Value="#FFFFFF00" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ColorItemTemplate">
|
||||
<Grid>
|
||||
<Border Background="{StaticResource CheckerBrush}" BorderBrush="Black" BorderThickness="1" Margin="2,2,2,2" >
|
||||
<Rectangle Width="16" Height="16">
|
||||
<Rectangle.Style>
|
||||
<Style TargetType="Rectangle">
|
||||
<Setter Property="Fill" Value="{Binding Color, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
|
||||
</Style>
|
||||
</Rectangle.Style>
|
||||
</Rectangle>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="ColorDisplayStyle" TargetType="ContentControl">
|
||||
<Setter Property="Focusable"
|
||||
Value="False" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Border Background="{StaticResource CheckerBrush}">
|
||||
<Rectangle Fill="{Binding SelectedColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=controls:ColorPicker}, Converter={StaticResource ColorToSolidColorBrushConverter}}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectedColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=controls:ColorPicker}}"
|
||||
Value="{x:Null}">
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ColorListStyle" TargetType="ListBox">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="MaxHeight" Value="500" />
|
||||
<Setter Property="ItemsPanel">
|
||||
<Setter.Value>
|
||||
<ItemsPanelTemplate>
|
||||
<!-- ConverterParameter is margin/Padding from Popup-->
|
||||
<WrapPanel Width="{Binding MaxDropDownWidth, RelativeSource={RelativeSource AncestorType={x:Type controls:ColorPicker}}}" />
|
||||
</ItemsPanelTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ItemContainerStyle" Value="{StaticResource ColorItemContainerStyle}" />
|
||||
<Setter Property="ItemTemplate" Value="{StaticResource ColorItemTemplate}" />
|
||||
<Setter Property="SelectionMode" Value="Single" />
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key="TabItemTemplate"
|
||||
TargetType="{x:Type controls:ColorPickerTabItem}">
|
||||
<Grid x:Name="templateRoot"
|
||||
SnapsToDevicePixels="true">
|
||||
<Border x:Name="mainBorder"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="1,1,1,0"
|
||||
Background="#FFF0F0F0"
|
||||
Margin="0">
|
||||
<Border x:Name="innerBorder"
|
||||
BorderBrush="#ACACAC"
|
||||
BorderThickness="1,1,1,0"
|
||||
Background="#FFF0F0F0"
|
||||
Margin="-1"
|
||||
Opacity="0" />
|
||||
</Border>
|
||||
<ContentPresenter x:Name="contentPresenter"
|
||||
ContentSource="Header"
|
||||
Focusable="False"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
RecognizesAccessKey="True"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}"
|
||||
Value="true" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Panel.ZIndex"
|
||||
Value="1" />
|
||||
<Setter Property="Margin"
|
||||
Value="-2,-2,-2,0" />
|
||||
<Setter Property="Opacity"
|
||||
TargetName="innerBorder"
|
||||
Value="1" />
|
||||
</MultiDataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<Style x:Key="ColorPickerStyle" TargetType="{x:Type controls:ColorPicker}">
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="Background" Value="White" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="BorderBrush" Value="Gray" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="MaxDropDownWidth" Value="218" />
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:ColorPicker}">
|
||||
<Grid x:Name="PART_Root">
|
||||
<Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"/>
|
||||
|
||||
<Grid x:Name="PART_InnerGrid" Margin="{TemplateBinding Padding}">
|
||||
<!--下拉按钮-->
|
||||
<ToggleButton x:Name="PART_ColorPickerToggleButton" Panel.ZIndex="1" IsTabStop="False"
|
||||
Style="{StaticResource ColorPickerToggleButtonStyle}"
|
||||
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||
Foreground="{TemplateBinding BorderBrush}">
|
||||
<!--<ContentControl x:Name="ColorOnly" Style="{StaticResource ColorDisplayStyle}" />-->
|
||||
<ContentControl x:Name="ColorOnly"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{Binding Content, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
UseLayoutRounding="False" Margin="0,0,0,0" />
|
||||
</ToggleButton>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Popup x:Name="PART_ColorPickerPalettePopup"
|
||||
VerticalAlignment="Bottom"
|
||||
IsOpen="{Binding ElementName=PART_ColorPickerToggleButton, Path=IsChecked}"
|
||||
StaysOpen="False"
|
||||
AllowsTransparency="True"
|
||||
Focusable="False"
|
||||
HorizontalOffset="1"
|
||||
VerticalOffset="1"
|
||||
PopupAnimation="Slide"
|
||||
ToolTip="{x:Static sys:String.Empty}">
|
||||
<Popup.Resources>
|
||||
<Style TargetType="ToolTip">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="Content"
|
||||
Value="{x:Static sys:String.Empty}">
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Popup.Resources>
|
||||
<Border BorderThickness="1" Background="White" BorderBrush="{TemplateBinding BorderBrush}" Padding="3">
|
||||
<TabControl x:Name="ColorPickerTabControl"
|
||||
Background="Transparent"
|
||||
SelectedIndex="{Binding ColorMode, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorModeToTabItemSelectedConverter}}">
|
||||
<controls:ColorPickerTabItem x:Name="StandardTabItem"
|
||||
Header="{Binding StandardButtonHeader, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Template="{StaticResource TabItemTemplate}">
|
||||
<Grid x:Name="_colorPaletteHost" Margin="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Available Colors -->
|
||||
<Grid Grid.Row="1" Visibility="{TemplateBinding ShowAvailableColors, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{TemplateBinding AvailableColorsHeader}" Background="AliceBlue" Padding="2" Margin="0,0,0,1" />
|
||||
<ListBox x:Name="PART_AvailableColors"
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding AvailableColors, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource ColorListStyle}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Standard Colors-->
|
||||
<Grid Grid.Row="2" Visibility="{TemplateBinding ShowStandardColors, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{TemplateBinding StandardColorsHeader}" Background="AliceBlue" Padding="2" Margin="0,1,0,1" />
|
||||
<ListBox x:Name="PART_StandardColors"
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding StandardColors, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource ColorListStyle}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Recent Colors-->
|
||||
<Grid Grid.Row="3" Margin="0,1,0,1" Visibility="{TemplateBinding ShowRecentColors, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="22" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{TemplateBinding RecentColorsHeader}" Background="AliceBlue" Padding="2" Margin="0,1,0,1" />
|
||||
<ListBox x:Name="PART_RecentColors"
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding RecentColors, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource ColorListStyle}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</controls:ColorPickerTabItem>
|
||||
<controls:ColorPickerTabItem x:Name="AdvancedTabItem"
|
||||
Header="{Binding AdvancedButtonHeader, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Template="{StaticResource TabItemTemplate}">
|
||||
<!-- ColorCanvas -->
|
||||
<Grid x:Name="_colorCanvasHost">
|
||||
<controls:ColorCanvas Background="Transparent"
|
||||
BorderThickness="0"
|
||||
UsingAlphaChannel="{Binding UsingAlphaChannel, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
SelectedColor="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Width="{Binding MaxDropDownWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource AdditionConverter}, ConverterParameter=-18}" />
|
||||
</Grid>
|
||||
</controls:ColorPickerTabItem>
|
||||
</TabControl>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="ShowTabHeaders"
|
||||
Value="False">
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed"
|
||||
TargetName="StandardTabItem" />
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed"
|
||||
TargetName="AdvancedTabItem" />
|
||||
</Trigger>
|
||||
|
||||
<Trigger Property="ShowDropDownButton" Value="False">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="BorderBrush" Value="Gray"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="PART_Root" Property="Opacity" Value="0.5"></Setter>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style BasedOn="{StaticResource ColorPickerStyle}" TargetType="{x:Type controls:ColorPicker}"/>
|
||||
|
||||
</ResourceDictionary>
|
||||
809
Extensions/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
Normal file
809
Extensions/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
Normal file
@@ -0,0 +1,809 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
public enum ColorMode
|
||||
{
|
||||
ColorPalette,
|
||||
ColorCanvas
|
||||
}
|
||||
|
||||
public enum ColorSortingMode
|
||||
{
|
||||
Alphabetical,
|
||||
HueSaturationBrightness
|
||||
}
|
||||
|
||||
[TemplatePart(Name = PART_AvailableColors, Type = typeof(ListBox))]
|
||||
[TemplatePart(Name = PART_StandardColors, Type = typeof(ListBox))]
|
||||
[TemplatePart(Name = PART_RecentColors, Type = typeof(ListBox))]
|
||||
[TemplatePart(Name = PART_ColorPickerToggleButton, Type = typeof(ToggleButton))]
|
||||
[TemplatePart(Name = PART_ColorPickerPalettePopup, Type = typeof(Popup))]
|
||||
public class ColorPicker : Control
|
||||
{
|
||||
private const string PART_AvailableColors = "PART_AvailableColors";
|
||||
private const string PART_StandardColors = "PART_StandardColors";
|
||||
private const string PART_RecentColors = "PART_RecentColors";
|
||||
private const string PART_ColorPickerToggleButton = "PART_ColorPickerToggleButton";
|
||||
private const string PART_ColorPickerPalettePopup = "PART_ColorPickerPalettePopup";
|
||||
|
||||
#region Members
|
||||
|
||||
private ListBox _availableColors;
|
||||
private ListBox _standardColors;
|
||||
private ListBox _recentColors;
|
||||
private ToggleButton _toggleButton;
|
||||
private Popup _popup;
|
||||
private Color? _initialColor;
|
||||
private bool _selectionChanged;
|
||||
|
||||
#endregion //Members
|
||||
|
||||
#region Properties
|
||||
|
||||
#region AdvancedButtonHeader
|
||||
|
||||
public static readonly DependencyProperty AdvancedButtonHeaderProperty = DependencyProperty.Register("AdvancedButtonHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Advanced"));
|
||||
public string AdvancedButtonHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(AdvancedButtonHeaderProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AdvancedButtonHeaderProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //AdvancedButtonHeader
|
||||
|
||||
#region AvailableColors
|
||||
|
||||
public static readonly DependencyProperty AvailableColorsProperty = DependencyProperty.Register("AvailableColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(CreateAvailableColors()));
|
||||
public ObservableCollection<ColorItem> AvailableColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ObservableCollection<ColorItem>)GetValue(AvailableColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AvailableColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //AvailableColors
|
||||
|
||||
#region AvailableColorsSortingMode
|
||||
|
||||
public static readonly DependencyProperty AvailableColorsSortingModeProperty = DependencyProperty.Register("AvailableColorsSortingMode", typeof(ColorSortingMode), typeof(ColorPicker), new UIPropertyMetadata(ColorSortingMode.Alphabetical, OnAvailableColorsSortingModeChanged));
|
||||
public ColorSortingMode AvailableColorsSortingMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ColorSortingMode)GetValue(AvailableColorsSortingModeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AvailableColorsSortingModeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnAvailableColorsSortingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorPicker colorPicker = (ColorPicker)d;
|
||||
if (colorPicker != null)
|
||||
colorPicker.OnAvailableColorsSortingModeChanged((ColorSortingMode)e.OldValue, (ColorSortingMode)e.NewValue);
|
||||
}
|
||||
|
||||
private void OnAvailableColorsSortingModeChanged(ColorSortingMode oldValue, ColorSortingMode newValue)
|
||||
{
|
||||
ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(this.AvailableColors));
|
||||
if (lcv != null)
|
||||
{
|
||||
lcv.CustomSort = (AvailableColorsSortingMode == ColorSortingMode.HueSaturationBrightness)
|
||||
? new ColorSorter()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //AvailableColorsSortingMode
|
||||
|
||||
#region AvailableColorsHeader
|
||||
|
||||
public static readonly DependencyProperty AvailableColorsHeaderProperty = DependencyProperty.Register("AvailableColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Available Colors"));
|
||||
public string AvailableColorsHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(AvailableColorsHeaderProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AvailableColorsHeaderProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //AvailableColorsHeader
|
||||
|
||||
#region ButtonStyle
|
||||
|
||||
public static readonly DependencyProperty ButtonStyleProperty = DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(ColorPicker));
|
||||
public Style ButtonStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Style)GetValue(ButtonStyleProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ButtonStyleProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ButtonStyle
|
||||
|
||||
#region ColorMode
|
||||
|
||||
public static readonly DependencyProperty ColorModeProperty = DependencyProperty.Register("ColorMode", typeof(ColorMode), typeof(ColorPicker), new UIPropertyMetadata(ColorMode.ColorPalette));
|
||||
public ColorMode ColorMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ColorMode)GetValue(ColorModeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ColorModeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ColorMode
|
||||
|
||||
#region IsOpen
|
||||
|
||||
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false, OnIsOpenChanged));
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(IsOpenProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(IsOpenProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorPicker colorPicker = (ColorPicker)d;
|
||||
if (colorPicker != null)
|
||||
colorPicker.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue);
|
||||
|
||||
if (colorPicker.IsOpen == false)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void OnIsOpenChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
if (newValue)
|
||||
{
|
||||
_initialColor = this.SelectedColor;
|
||||
}
|
||||
RoutedEventArgs args = new RoutedEventArgs(newValue ? OpenedEvent : ClosedEvent, this);
|
||||
this.RaiseEvent(args);
|
||||
}
|
||||
|
||||
#endregion //IsOpen
|
||||
|
||||
#region MaxDropDownWidth
|
||||
|
||||
public static readonly DependencyProperty MaxDropDownWidthProperty = DependencyProperty.Register("MaxDropDownWidth", typeof(double)
|
||||
, typeof(ColorPicker), new UIPropertyMetadata(214d));
|
||||
public double MaxDropDownWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)GetValue(MaxDropDownWidthProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(MaxDropDownWidthProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnMaxDropDownWidthChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var colorPicker = o as ColorPicker;
|
||||
if (colorPicker != null)
|
||||
colorPicker.OnMaxDropDownWidthChanged((double)e.OldValue, (double)e.NewValue);
|
||||
}
|
||||
|
||||
protected virtual void OnMaxDropDownWidthChanged(double oldValue, double newValue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RecentColors
|
||||
|
||||
public static readonly DependencyProperty RecentColorsProperty = DependencyProperty.Register("RecentColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(null));
|
||||
public ObservableCollection<ColorItem> RecentColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ObservableCollection<ColorItem>)GetValue(RecentColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(RecentColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //RecentColors
|
||||
|
||||
#region RecentColorsHeader
|
||||
|
||||
public static readonly DependencyProperty RecentColorsHeaderProperty = DependencyProperty.Register("RecentColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Recent Colors"));
|
||||
public string RecentColorsHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(RecentColorsHeaderProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(RecentColorsHeaderProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //RecentColorsHeader
|
||||
|
||||
#region SelectedColor
|
||||
|
||||
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color?), typeof(ColorPicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnSelectedColorPropertyChanged)));
|
||||
public Color? SelectedColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Color?)GetValue(SelectedColorProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SelectedColorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSelectedColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorPicker colorPicker = (ColorPicker)d;
|
||||
if (colorPicker != null)
|
||||
colorPicker.OnSelectedColorChanged((Color?)e.OldValue, (Color?)e.NewValue);
|
||||
}
|
||||
|
||||
private void OnSelectedColorChanged(Color? oldValue, Color? newValue)
|
||||
{
|
||||
SelectedColorText = GetFormatedColorString(newValue);
|
||||
|
||||
RoutedPropertyChangedEventArgs<Color?> args = new RoutedPropertyChangedEventArgs<Color?>(oldValue, newValue);
|
||||
args.RoutedEvent = ColorPicker.SelectedColorChangedEvent;
|
||||
RaiseEvent(args);
|
||||
}
|
||||
|
||||
//public static readonly DependencyProperty SelectedBrushProperty = DependencyProperty.Register("SelectedBrush", typeof(Brush), typeof(ColorPicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnSelectedBrushPropertyChanged)));
|
||||
//public Brush SelectedBrush
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return (Brush)GetValue(SelectedBrushProperty);
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// SetValue(SelectedBrushProperty, value);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private static void OnSelectedBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
//{
|
||||
// ColorPicker colorPicker = (ColorPicker)d;
|
||||
// if (colorPicker != null)
|
||||
// colorPicker.OnSelectedBrushChanged((Brush)e.OldValue, (Brush)e.NewValue);
|
||||
//}
|
||||
|
||||
//private void OnSelectedBrushChanged(Brush oldValue, Brush newValue)
|
||||
//{
|
||||
// if (newValue != null)
|
||||
// {
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion //SelectedColor
|
||||
|
||||
#region SelectedColorText
|
||||
|
||||
public static readonly DependencyProperty SelectedColorTextProperty = DependencyProperty.Register("SelectedColorText", typeof(string), typeof(ColorPicker), new UIPropertyMetadata(""));
|
||||
public string SelectedColorText
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(SelectedColorTextProperty);
|
||||
}
|
||||
protected set
|
||||
{
|
||||
SetValue(SelectedColorTextProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //SelectedColorText
|
||||
|
||||
#region ShowTabHeaders
|
||||
|
||||
public static readonly DependencyProperty ShowTabHeadersProperty = DependencyProperty.Register("ShowTabHeaders", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true));
|
||||
public bool ShowTabHeaders
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowTabHeadersProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowTabHeadersProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ShowTabHeaders
|
||||
|
||||
#region ShowAvailableColors
|
||||
|
||||
public static readonly DependencyProperty ShowAvailableColorsProperty = DependencyProperty.Register("ShowAvailableColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true));
|
||||
public bool ShowAvailableColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowAvailableColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowAvailableColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ShowAvailableColors
|
||||
|
||||
#region ShowRecentColors
|
||||
|
||||
public static readonly DependencyProperty ShowRecentColorsProperty = DependencyProperty.Register("ShowRecentColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false));
|
||||
public bool ShowRecentColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowRecentColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowRecentColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //DisplayRecentColors
|
||||
|
||||
#region ShowStandardColors
|
||||
|
||||
public static readonly DependencyProperty ShowStandardColorsProperty = DependencyProperty.Register("ShowStandardColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true));
|
||||
public bool ShowStandardColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowStandardColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowStandardColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //DisplayStandardColors
|
||||
|
||||
#region ShowDropDownButton
|
||||
|
||||
public static readonly DependencyProperty ShowDropDownButtonProperty = DependencyProperty.Register("ShowDropDownButton", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true));
|
||||
public bool ShowDropDownButton
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(ShowDropDownButtonProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ShowDropDownButtonProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ShowDropDownButton
|
||||
|
||||
#region StandardButtonHeader
|
||||
|
||||
public static readonly DependencyProperty StandardButtonHeaderProperty = DependencyProperty.Register("StandardButtonHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Standard"));
|
||||
public string StandardButtonHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(StandardButtonHeaderProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(StandardButtonHeaderProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //StandardButtonHeader
|
||||
|
||||
#region StandardColors
|
||||
|
||||
public static readonly DependencyProperty StandardColorsProperty = DependencyProperty.Register("StandardColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(CreateStandardColors()));
|
||||
public ObservableCollection<ColorItem> StandardColors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ObservableCollection<ColorItem>)GetValue(StandardColorsProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(StandardColorsProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //StandardColors
|
||||
|
||||
#region StandardColorsHeader
|
||||
|
||||
public static readonly DependencyProperty StandardColorsHeaderProperty = DependencyProperty.Register("StandardColorsHeader", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Standard Colors"));
|
||||
public string StandardColorsHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(StandardColorsHeaderProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(StandardColorsHeaderProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //StandardColorsHeader
|
||||
|
||||
#region UsingAlphaChannel
|
||||
|
||||
public static readonly DependencyProperty UsingAlphaChannelProperty = DependencyProperty.Register("UsingAlphaChannel", typeof(bool), typeof(ColorPicker), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnUsingAlphaChannelPropertyChanged)));
|
||||
public bool UsingAlphaChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(UsingAlphaChannelProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(UsingAlphaChannelProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnUsingAlphaChannelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ColorPicker colorPicker = (ColorPicker)d;
|
||||
if (colorPicker != null)
|
||||
colorPicker.OnUsingAlphaChannelChanged();
|
||||
}
|
||||
|
||||
private void OnUsingAlphaChannelChanged()
|
||||
{
|
||||
SelectedColorText = GetFormatedColorString(SelectedColor);
|
||||
}
|
||||
|
||||
#endregion //UsingAlphaChannel
|
||||
|
||||
/// <summary>Identifies the <see cref="Content"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentProperty
|
||||
= DependencyProperty.Register(nameof(Content),
|
||||
typeof(object),
|
||||
typeof(ColorPicker));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of this control.
|
||||
/// </summary>
|
||||
public object Content
|
||||
{
|
||||
get => (object)this.GetValue(ContentProperty);
|
||||
set => this.SetValue(ContentProperty, value);
|
||||
}
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
static ColorPicker()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
|
||||
}
|
||||
|
||||
public ColorPicker()
|
||||
{
|
||||
#if VS2008
|
||||
this.RecentColors = new ObservableCollection<ColorItem>();
|
||||
#else
|
||||
this.SetCurrentValue(ColorPicker.RecentColorsProperty, new ObservableCollection<ColorItem>());
|
||||
#endif
|
||||
|
||||
Keyboard.AddKeyDownHandler(this, OnKeyDown);
|
||||
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement);
|
||||
}
|
||||
|
||||
#endregion //Constructors
|
||||
|
||||
#region Base Class Overrides
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (_availableColors != null)
|
||||
_availableColors.SelectionChanged -= Color_SelectionChanged;
|
||||
|
||||
_availableColors = GetTemplateChild(PART_AvailableColors) as ListBox;
|
||||
if (_availableColors != null)
|
||||
_availableColors.SelectionChanged += Color_SelectionChanged;
|
||||
|
||||
if (_standardColors != null)
|
||||
_standardColors.SelectionChanged -= Color_SelectionChanged;
|
||||
|
||||
_standardColors = GetTemplateChild(PART_StandardColors) as ListBox;
|
||||
if (_standardColors != null)
|
||||
_standardColors.SelectionChanged += Color_SelectionChanged;
|
||||
|
||||
if (_recentColors != null)
|
||||
_recentColors.SelectionChanged -= Color_SelectionChanged;
|
||||
|
||||
_recentColors = GetTemplateChild(PART_RecentColors) as ListBox;
|
||||
if (_recentColors != null)
|
||||
_recentColors.SelectionChanged += Color_SelectionChanged;
|
||||
|
||||
if (_popup != null)
|
||||
_popup.Opened -= Popup_Opened;
|
||||
|
||||
_popup = GetTemplateChild(PART_ColorPickerPalettePopup) as Popup;
|
||||
if (_popup != null)
|
||||
_popup.Opened += Popup_Opened;
|
||||
|
||||
_toggleButton = this.Template.FindName(PART_ColorPickerToggleButton, this) as ToggleButton;
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
// Close ColorPicker on MouseUp to prevent action of mouseUp on controls behind the ColorPicker.
|
||||
if (_selectionChanged)
|
||||
{
|
||||
CloseColorPicker(true);
|
||||
_selectionChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Base Class Overrides
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (!IsOpen)
|
||||
{
|
||||
if (KeyboardUtilities.IsKeyModifyingPopupState(e))
|
||||
{
|
||||
IsOpen = true;
|
||||
// Focus will be on ListBoxItem in Popup_Opened().
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyboardUtilities.IsKeyModifyingPopupState(e))
|
||||
{
|
||||
CloseColorPicker(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.Escape)
|
||||
{
|
||||
this.SelectedColor = _initialColor;
|
||||
CloseColorPicker(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
CloseColorPicker(true);
|
||||
}
|
||||
|
||||
private void Color_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
ListBox lb = (ListBox)sender;
|
||||
|
||||
if (e.AddedItems.Count > 0)
|
||||
{
|
||||
var colorItem = (ColorItem)e.AddedItems[0];
|
||||
SelectedColor = colorItem.Color;
|
||||
if (!string.IsNullOrEmpty(colorItem.Name))
|
||||
{
|
||||
this.SelectedColorText = colorItem.Name;
|
||||
}
|
||||
UpdateRecentColors(colorItem);
|
||||
_selectionChanged = true;
|
||||
lb.SelectedIndex = -1; //for now I don't care about keeping track of the selected color
|
||||
}
|
||||
}
|
||||
|
||||
private void Popup_Opened(object sender, EventArgs e)
|
||||
{
|
||||
if ((_availableColors != null) && ShowAvailableColors)
|
||||
{
|
||||
FocusOnListBoxItem(_availableColors);
|
||||
}
|
||||
else if ((_standardColors != null) && ShowStandardColors)
|
||||
FocusOnListBoxItem(_standardColors);
|
||||
else if ((_recentColors != null) && ShowRecentColors)
|
||||
FocusOnListBoxItem(_recentColors);
|
||||
}
|
||||
|
||||
private void FocusOnListBoxItem(ListBox listBox)
|
||||
{
|
||||
ListBoxItem listBoxItem = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.SelectedItem);
|
||||
if ((listBoxItem == null) && (listBox.Items.Count > 0))
|
||||
listBoxItem = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items[0]);
|
||||
if (listBoxItem != null)
|
||||
listBoxItem.Focus();
|
||||
}
|
||||
|
||||
#endregion //Event Handlers
|
||||
|
||||
#region Events
|
||||
|
||||
#region SelectedColorChangedEvent
|
||||
|
||||
public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color?>), typeof(ColorPicker));
|
||||
public event RoutedPropertyChangedEventHandler<Color?> SelectedColorChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler(SelectedColorChangedEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler(SelectedColorChangedEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OpenedEvent
|
||||
|
||||
public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent("OpenedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ColorPicker));
|
||||
public event RoutedEventHandler Opened
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler(OpenedEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler(OpenedEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //OpenedEvent
|
||||
|
||||
#region ClosedEvent
|
||||
|
||||
public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("ClosedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ColorPicker));
|
||||
public event RoutedEventHandler Closed
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler(ClosedEvent, value);
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler(ClosedEvent, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //ClosedEvent
|
||||
|
||||
#endregion //Events
|
||||
|
||||
#region Methods
|
||||
|
||||
private void CloseColorPicker(bool isFocusOnColorPicker)
|
||||
{
|
||||
if (IsOpen)
|
||||
IsOpen = false;
|
||||
ReleaseMouseCapture();
|
||||
|
||||
if (isFocusOnColorPicker && (_toggleButton != null))
|
||||
_toggleButton.Focus();
|
||||
this.UpdateRecentColors(new ColorItem(SelectedColor, SelectedColorText));
|
||||
}
|
||||
|
||||
private void UpdateRecentColors(ColorItem colorItem)
|
||||
{
|
||||
if (!RecentColors.Contains(colorItem))
|
||||
RecentColors.Add(colorItem);
|
||||
|
||||
if (RecentColors.Count > 10) //don't allow more than ten, maybe make a property that can be set by the user.
|
||||
RecentColors.RemoveAt(0);
|
||||
}
|
||||
|
||||
private string GetFormatedColorString(Color? colorToFormat)
|
||||
{
|
||||
if ((colorToFormat == null) || !colorToFormat.HasValue)
|
||||
return string.Empty;
|
||||
|
||||
return ColorUtilities.FormatColorString(colorToFormat.Value.GetColorName(), UsingAlphaChannel);
|
||||
}
|
||||
|
||||
private static ObservableCollection<ColorItem> CreateStandardColors()
|
||||
{
|
||||
ObservableCollection<ColorItem> standardColors = new ObservableCollection<ColorItem>();
|
||||
standardColors.Add(new ColorItem(Colors.Transparent, "Transparent"));
|
||||
standardColors.Add(new ColorItem(Colors.White, "White"));
|
||||
standardColors.Add(new ColorItem(Colors.Gray, "Gray"));
|
||||
standardColors.Add(new ColorItem(Colors.Black, "Black"));
|
||||
standardColors.Add(new ColorItem(Colors.Red, "Red"));
|
||||
standardColors.Add(new ColorItem(Colors.Green, "Green"));
|
||||
standardColors.Add(new ColorItem(Colors.Blue, "Blue"));
|
||||
standardColors.Add(new ColorItem(Colors.Yellow, "Yellow"));
|
||||
standardColors.Add(new ColorItem(Colors.Orange, "Orange"));
|
||||
standardColors.Add(new ColorItem(Colors.Purple, "Purple"));
|
||||
return standardColors;
|
||||
}
|
||||
|
||||
private static ObservableCollection<ColorItem> CreateAvailableColors()
|
||||
{
|
||||
ObservableCollection<ColorItem> standardColors = new ObservableCollection<ColorItem>();
|
||||
|
||||
foreach (var item in ColorUtilities.KnownColors)
|
||||
{
|
||||
if (!String.Equals(item.Key, "Transparent"))
|
||||
{
|
||||
var colorItem = new ColorItem(item.Value, item.Key);
|
||||
if (!standardColors.Contains(colorItem))
|
||||
standardColors.Add(colorItem);
|
||||
}
|
||||
}
|
||||
|
||||
return standardColors;
|
||||
}
|
||||
|
||||
#endregion //Methods
|
||||
}
|
||||
|
||||
public class KeyboardUtilities
|
||||
{
|
||||
public static bool IsKeyModifyingPopupState(KeyEventArgs e)
|
||||
{
|
||||
return ((((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) && ((e.SystemKey == Key.Down) || (e.SystemKey == Key.Up)))
|
||||
|| (e.Key == Key.F4));
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Extensions/AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs
Normal file
45
Extensions/AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
public class ColorPickerTabItem : TabItem
|
||||
{
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.Source == this || !this.IsSelected)
|
||||
return;
|
||||
|
||||
base.OnMouseLeftButtonDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
|
||||
{
|
||||
//Selection on Mouse Up
|
||||
if (e.Source == this || !this.IsSelected)
|
||||
{
|
||||
base.OnMouseLeftButtonDown(e);
|
||||
}
|
||||
|
||||
base.OnMouseLeftButtonUp(e);
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorModeToTabItemSelectedConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var colorMode = (ColorMode)value;
|
||||
return (colorMode == ColorMode.ColorPalette) ? 0 : 1;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var index = (int)value;
|
||||
return (index == 0) ? ColorMode.ColorPalette : ColorMode.ColorCanvas;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Extensions/AIStudio.Wpf.Mind/Controls/ColorSorter.cs
Normal file
57
Extensions/AIStudio.Wpf.Mind/Controls/ColorSorter.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
internal class ColorSorter : IComparer
|
||||
{
|
||||
public int Compare(object firstItem, object secondItem)
|
||||
{
|
||||
if (firstItem == null || secondItem == null)
|
||||
return -1;
|
||||
|
||||
ColorItem colorItem1 = (ColorItem)firstItem;
|
||||
ColorItem colorItem2 = (ColorItem)secondItem;
|
||||
|
||||
if ((colorItem1.Color == null) || !colorItem1.Color.HasValue ||
|
||||
(colorItem2.Color == null) || !colorItem2.Color.HasValue)
|
||||
return -1;
|
||||
|
||||
System.Drawing.Color drawingColor1 = System.Drawing.Color.FromArgb(colorItem1.Color.Value.A, colorItem1.Color.Value.R, colorItem1.Color.Value.G, colorItem1.Color.Value.B);
|
||||
System.Drawing.Color drawingColor2 = System.Drawing.Color.FromArgb(colorItem2.Color.Value.A, colorItem2.Color.Value.R, colorItem2.Color.Value.G, colorItem2.Color.Value.B);
|
||||
|
||||
// Compare Hue
|
||||
double hueColor1 = Math.Round((double)drawingColor1.GetHue(), 3);
|
||||
double hueColor2 = Math.Round((double)drawingColor2.GetHue(), 3);
|
||||
|
||||
if (hueColor1 > hueColor2)
|
||||
return 1;
|
||||
else if (hueColor1 < hueColor2)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
// Hue is equal, compare Saturation
|
||||
double satColor1 = Math.Round((double)drawingColor1.GetSaturation(), 3);
|
||||
double satColor2 = Math.Round((double)drawingColor2.GetSaturation(), 3);
|
||||
|
||||
if (satColor1 > satColor2)
|
||||
return 1;
|
||||
else if (satColor1 < satColor2)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
// Saturation is equal, compare Brightness
|
||||
double brightColor1 = Math.Round((double)drawingColor1.GetBrightness(), 3);
|
||||
double brightColor2 = Math.Round((double)drawingColor2.GetBrightness(), 3);
|
||||
|
||||
if (brightColor1 > brightColor2)
|
||||
return 1;
|
||||
else if (brightColor1 < brightColor2)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
97
Extensions/AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs
Normal file
97
Extensions/AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
[TemplatePart(Name = PART_SpectrumDisplay, Type = typeof(Rectangle))]
|
||||
public class ColorSpectrumSlider : Slider
|
||||
{
|
||||
private const string PART_SpectrumDisplay = "PART_SpectrumDisplay";
|
||||
|
||||
#region Private Members
|
||||
|
||||
private Rectangle _spectrumDisplay;
|
||||
private LinearGradientBrush _pickerBrush;
|
||||
|
||||
#endregion //Private Members
|
||||
|
||||
#region Constructors
|
||||
|
||||
static ColorSpectrumSlider()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSpectrumSlider), new FrameworkPropertyMetadata(typeof(ColorSpectrumSlider)));
|
||||
}
|
||||
|
||||
#endregion //Constructors
|
||||
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSpectrumSlider), new PropertyMetadata(System.Windows.Media.Colors.Transparent));
|
||||
public Color SelectedColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Color)GetValue(SelectedColorProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SelectedColorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Dependency Properties
|
||||
|
||||
#region Base Class Overrides
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_spectrumDisplay = (Rectangle)GetTemplateChild(PART_SpectrumDisplay);
|
||||
CreateSpectrum();
|
||||
OnValueChanged(Double.NaN, Value);
|
||||
}
|
||||
|
||||
protected override void OnValueChanged(double oldValue, double newValue)
|
||||
{
|
||||
base.OnValueChanged(oldValue, newValue);
|
||||
|
||||
Color color = ColorUtilities.ConvertHsvToRgb(360 - newValue, 1, 1);
|
||||
SelectedColor = color;
|
||||
}
|
||||
|
||||
#endregion //Base Class Overrides
|
||||
|
||||
#region Methods
|
||||
|
||||
private void CreateSpectrum()
|
||||
{
|
||||
_pickerBrush = new LinearGradientBrush();
|
||||
_pickerBrush.StartPoint = new Point(0.5, 0);
|
||||
_pickerBrush.EndPoint = new Point(0.5, 1);
|
||||
_pickerBrush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation;
|
||||
|
||||
List<Color> colorsList = ColorUtilities.GenerateHsvSpectrum();
|
||||
|
||||
double stopIncrement = (double)1 / colorsList.Count;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < colorsList.Count; i++)
|
||||
{
|
||||
_pickerBrush.GradientStops.Add(new GradientStop(colorsList[i], i * stopIncrement));
|
||||
}
|
||||
|
||||
_pickerBrush.GradientStops[i - 1].Offset = 1.0;
|
||||
if (_spectrumDisplay != null)
|
||||
{
|
||||
_spectrumDisplay.Fill = _pickerBrush;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Methods
|
||||
}
|
||||
}
|
||||
202
Extensions/AIStudio.Wpf.Mind/Controls/ColorUtilities.cs
Normal file
202
Extensions/AIStudio.Wpf.Mind/Controls/ColorUtilities.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
static class ColorUtilities
|
||||
{
|
||||
public static readonly Dictionary<string, Color> KnownColors = GetKnownColors();
|
||||
|
||||
public static string GetColorName(this Color color)
|
||||
{
|
||||
string colorName = KnownColors.Where(kvp => kvp.Value.Equals(color)).Select(kvp => kvp.Key).FirstOrDefault();
|
||||
|
||||
if (String.IsNullOrEmpty(colorName))
|
||||
colorName = color.ToString();
|
||||
|
||||
return colorName;
|
||||
}
|
||||
|
||||
public static string FormatColorString(string stringToFormat, bool isUsingAlphaChannel)
|
||||
{
|
||||
if (!isUsingAlphaChannel && (stringToFormat.Length == 9))
|
||||
return stringToFormat.Remove(1, 2);
|
||||
return stringToFormat;
|
||||
}
|
||||
|
||||
private static Dictionary<string, Color> GetKnownColors()
|
||||
{
|
||||
var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
|
||||
return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an RGB color to an HSV color.
|
||||
/// </summary>
|
||||
/// <param name="r"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="g"></param>
|
||||
/// <returns></returns>
|
||||
public static HsvColor ConvertRgbToHsv(int r, int b, int g)
|
||||
{
|
||||
double delta, min;
|
||||
double h = 0, s, v;
|
||||
|
||||
min = Math.Min(Math.Min(r, g), b);
|
||||
v = Math.Max(Math.Max(r, g), b);
|
||||
delta = v - min;
|
||||
|
||||
if (v == 0.0)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
else
|
||||
s = delta / v;
|
||||
|
||||
if (s == 0)
|
||||
h = 0.0;
|
||||
|
||||
else
|
||||
{
|
||||
if (r == v)
|
||||
h = (g - b) / delta;
|
||||
else if (g == v)
|
||||
h = 2 + (b - r) / delta;
|
||||
else if (b == v)
|
||||
h = 4 + (r - g) / delta;
|
||||
|
||||
h *= 60;
|
||||
if (h < 0.0)
|
||||
h = h + 360;
|
||||
|
||||
}
|
||||
|
||||
return new HsvColor
|
||||
{
|
||||
H = h,
|
||||
S = s,
|
||||
V = v / 255
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an HSV color to an RGB color.
|
||||
/// </summary>
|
||||
/// <param name="h"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
public static Color ConvertHsvToRgb(double h, double s, double v)
|
||||
{
|
||||
double r = 0, g = 0, b = 0;
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
r = v;
|
||||
g = v;
|
||||
b = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
double f, p, q, t;
|
||||
|
||||
if (h == 360)
|
||||
h = 0;
|
||||
else
|
||||
h = h / 60;
|
||||
|
||||
i = (int)Math.Truncate(h);
|
||||
f = h - i;
|
||||
|
||||
p = v * (1.0 - s);
|
||||
q = v * (1.0 - (s * f));
|
||||
t = v * (1.0 - (s * (1.0 - f)));
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
r = q;
|
||||
g = v;
|
||||
b = p;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
r = p;
|
||||
g = v;
|
||||
b = t;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
r = t;
|
||||
g = p;
|
||||
b = v;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Color.FromArgb(255, (byte)(Math.Round(r * 255)), (byte)(Math.Round(g * 255)), (byte)(Math.Round(b * 255)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a list of colors with hues ranging from 0 360 and a saturation and value of 1.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<Color> GenerateHsvSpectrum()
|
||||
{
|
||||
List<Color> colorsList = new List<Color>(8);
|
||||
|
||||
for (int i = 0; i < 29; i++)
|
||||
{
|
||||
colorsList.Add(ColorUtilities.ConvertHsvToRgb(i * 12, 1, 1));
|
||||
}
|
||||
|
||||
colorsList.Add(ColorUtilities.ConvertHsvToRgb(0, 1, 1));
|
||||
|
||||
return colorsList;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HsvColor
|
||||
{
|
||||
public double H;
|
||||
public double S;
|
||||
public double V;
|
||||
|
||||
public HsvColor(double h, double s, double v)
|
||||
{
|
||||
H = h;
|
||||
S = s;
|
||||
V = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
200
Extensions/AIStudio.Wpf.Mind/Controls/DropDownButton.xaml
Normal file
200
Extensions/AIStudio.Wpf.Mind/Controls/DropDownButton.xaml
Normal file
@@ -0,0 +1,200 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/ContextMenu.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<dd:BrushOpacityConverter x:Key="BrushOpacityConverter"/>
|
||||
|
||||
<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
|
||||
<Setter Property="Padding" Value="6"/>
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
|
||||
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type MenuItem}">
|
||||
<Grid Margin="{TemplateBinding Margin}" SnapsToDevicePixels="True">
|
||||
<Border x:Name="templateRoot"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
SnapsToDevicePixels="True" />
|
||||
<Border x:Name="BackgroundRoot"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="LightGray"
|
||||
SnapsToDevicePixels="True"
|
||||
Opacity="0" />
|
||||
<ContentPresenter Margin="{TemplateBinding Padding}" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Header" RecognizesAccessKey="True"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsHighlighted" Value="True">
|
||||
<Setter TargetName="BackgroundRoot" Property="Opacity" Value="0.5" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="BackgroundRoot" Property="Opacity" Value="1" />
|
||||
<Setter TargetName="BackgroundRoot" Property="Background" Value="#73a1bf" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value=".5" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DropDownButtonStyle" TargetType="{x:Type controls:DropDownButton}">
|
||||
<Setter Property="ArrowBrush" Value="Black" />
|
||||
<Setter Property="ArrowMouseOverBrush"
|
||||
Value="{Binding Foreground, RelativeSource={RelativeSource Mode=Self},
|
||||
Converter={StaticResource BrushOpacityConverter}, ConverterParameter=0.16}" />
|
||||
<Setter Property="ArrowPressedBrush" Value="Black" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="ButtonStyle" Value="{StaticResource FlatButtonStyle}" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="MenuStyle" Value="{StaticResource ContextMenuStyle}" />
|
||||
<Setter Property="ItemContainerStyle" Value="{StaticResource MenuItemStyle}" />
|
||||
<Setter Property="MinHeight" Value="26" />
|
||||
<Setter Property="Padding" Value="3" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:DropDownButton}">
|
||||
<Grid>
|
||||
<Border x:Name="PART_Border"
|
||||
Background="Transparent"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="3"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
UseLayoutRounding="True">
|
||||
<Button x:Name="PART_Button"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
FocusVisualStyle="{TemplateBinding FocusVisualStyle}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
RenderOptions.ClearTypeHint="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(RenderOptions.ClearTypeHint), Mode=OneWay}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
Style="{TemplateBinding ButtonStyle}">
|
||||
<DockPanel x:Name="PART_Content"
|
||||
Focusable="False"
|
||||
LastChildFill="True">
|
||||
<!-- Material - ChevronDown -->
|
||||
<Path x:Name="PART_Arrow"
|
||||
Width="9"
|
||||
Height="6"
|
||||
Margin="0 0 3 0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"
|
||||
DockPanel.Dock="Right"
|
||||
Stretch="Fill"
|
||||
Fill="{TemplateBinding ArrowBrush}"
|
||||
Visibility="{TemplateBinding ArrowVisibility}" />
|
||||
<StackPanel x:Name="PART_ContentOrientation"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Focusable="False"
|
||||
Orientation="Horizontal">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Icon}"
|
||||
ContentTemplate="{TemplateBinding IconTemplate}"
|
||||
Focusable="False"
|
||||
RecognizesAccessKey="True"
|
||||
UseLayoutRounding="False" />
|
||||
<ContentControl x:Name="PART_ButtonContent"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{Binding Content, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ContentStringFormat="{TemplateBinding ContentStringFormat}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
UseLayoutRounding="False" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu x:Name="PART_Menu"
|
||||
MinWidth="{TemplateBinding ActualWidth}"
|
||||
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
|
||||
GroupStyleSelector="{TemplateBinding GroupStyleSelector}"
|
||||
IsOpen="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
|
||||
ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}"
|
||||
ItemStringFormat="{TemplateBinding ItemStringFormat}"
|
||||
ItemTemplate="{TemplateBinding ItemTemplate}"
|
||||
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
|
||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||
ItemsSource="{TemplateBinding ItemsSource}"
|
||||
Placement="Bottom"
|
||||
StaysOpen="False"
|
||||
Style="{TemplateBinding MenuStyle}"
|
||||
UseLayoutRounding="False" />
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Content" Value="{x:Null}">
|
||||
<Setter TargetName="PART_ButtonContent" Property="Margin" Value="0" />
|
||||
</Trigger>
|
||||
<Trigger Property="Orientation" Value="Vertical">
|
||||
<Setter TargetName="PART_Arrow" Property="DockPanel.Dock" Value="Bottom" />
|
||||
<Setter TargetName="PART_Arrow" Property="Margin" Value="0 0 0 3" />
|
||||
<Setter TargetName="PART_ContentOrientation" Property="Orientation" Value="Vertical" />
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsMouseOver" Value="True" />
|
||||
<Condition SourceName="PART_Button" Property="IsEnabled" Value="True" />
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="PART_Arrow" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ArrowMouseOverBrush, Mode=OneWay}" />
|
||||
</MultiTrigger>
|
||||
<Trigger SourceName="PART_Button" Property="IsPressed" Value="True">
|
||||
<Setter TargetName="PART_Arrow" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ArrowPressedBrush, Mode=OneWay}" />
|
||||
</Trigger>
|
||||
<Trigger SourceName="PART_Button" Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value=".55" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsFocused" Value="True">
|
||||
<Setter Property="BorderBrush" Value="LightGray" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsKeyboardFocusWithin" Value="True">
|
||||
<Setter Property="BorderBrush" Value="LightGray" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value=".55" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:DropDownButton}" BasedOn="{StaticResource DropDownButtonStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
685
Extensions/AIStudio.Wpf.Mind/Controls/DropDownButton.xaml.cs
Normal file
685
Extensions/AIStudio.Wpf.Mind/Controls/DropDownButton.xaml.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
[ContentProperty(nameof(ItemsSource))]
|
||||
[TemplatePart(Name = "PART_Button", Type = typeof(Button))]
|
||||
[TemplatePart(Name = "PART_ButtonContent", Type = typeof(ContentControl))]
|
||||
[TemplatePart(Name = "PART_Menu", Type = typeof(ContextMenu))]
|
||||
[StyleTypedProperty(Property = nameof(ButtonStyle), StyleTargetType = typeof(Button))]
|
||||
[StyleTypedProperty(Property = nameof(MenuStyle), StyleTargetType = typeof(ContextMenu))]
|
||||
public class DropDownButton : ItemsControl, ICommandSource
|
||||
{
|
||||
public static readonly RoutedEvent ClickEvent
|
||||
= EventManager.RegisterRoutedEvent(nameof(Click),
|
||||
RoutingStrategy.Bubble,
|
||||
typeof(RoutedEventHandler),
|
||||
typeof(DropDownButton));
|
||||
|
||||
public event RoutedEventHandler Click
|
||||
{
|
||||
add => this.AddHandler(ClickEvent, value);
|
||||
remove => this.RemoveHandler(ClickEvent, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="IsExpanded"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IsExpandedProperty
|
||||
= DependencyProperty.Register(nameof(IsExpanded),
|
||||
typeof(bool),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsExpandedPropertyChangedCallback));
|
||||
|
||||
private static void OnIsExpandedPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||
{
|
||||
if (dependencyObject is DropDownButton dropDownButton
|
||||
&& !(dropDownButton.contextMenu == null))
|
||||
{
|
||||
dropDownButton.SetContextMenuPlacementTarget(dropDownButton.contextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetContextMenuPlacementTarget(ContextMenu contextMenu)
|
||||
{
|
||||
if (this.button != null)
|
||||
{
|
||||
contextMenu.PlacementTarget = this.button;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => (bool)this.GetValue(IsExpandedProperty);
|
||||
set => this.SetValue(IsExpandedProperty, (bool)value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ExtraTag"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ExtraTagProperty
|
||||
= DependencyProperty.Register(nameof(ExtraTag),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an extra tag.
|
||||
/// </summary>
|
||||
public object ExtraTag
|
||||
{
|
||||
get => this.GetValue(ExtraTagProperty);
|
||||
set => this.SetValue(ExtraTagProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Orientation"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty OrientationProperty
|
||||
= DependencyProperty.Register(nameof(Orientation),
|
||||
typeof(Orientation),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the orientation of children stacking.
|
||||
/// </summary>
|
||||
public Orientation Orientation
|
||||
{
|
||||
get => (Orientation)this.GetValue(OrientationProperty);
|
||||
set => this.SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Icon"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IconProperty
|
||||
= DependencyProperty.Register(nameof(Icon),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content for the icon part.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public object Icon
|
||||
{
|
||||
get => this.GetValue(IconProperty);
|
||||
set => this.SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="IconTemplate"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty IconTemplateProperty
|
||||
= DependencyProperty.Register(nameof(IconTemplate),
|
||||
typeof(DataTemplate),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DataTemplate for the icon part.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public DataTemplate IconTemplate
|
||||
{
|
||||
get => (DataTemplate)this.GetValue(IconTemplateProperty);
|
||||
set => this.SetValue(IconTemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Command"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandProperty
|
||||
= DependencyProperty.Register(nameof(Command),
|
||||
typeof(ICommand),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null, OnCommandPropertyChangedCallback));
|
||||
|
||||
private static void OnCommandPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
(dependencyObject as DropDownButton).OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the command to invoke when the content button is pressed.
|
||||
/// </summary>
|
||||
public ICommand Command
|
||||
{
|
||||
get => (ICommand)this.GetValue(CommandProperty);
|
||||
set => this.SetValue(CommandProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="CommandTarget"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandTargetProperty
|
||||
= DependencyProperty.Register(nameof(CommandTarget),
|
||||
typeof(IInputElement),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the element on which to raise the specified command.
|
||||
/// </summary>
|
||||
public IInputElement CommandTarget
|
||||
{
|
||||
get => (IInputElement)this.GetValue(CommandTargetProperty);
|
||||
set => this.SetValue(CommandTargetProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="CommandParameter"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty CommandParameterProperty
|
||||
= DependencyProperty.Register(nameof(CommandParameter),
|
||||
typeof(object),
|
||||
typeof(DropDownButton),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter to pass to the command property.
|
||||
/// </summary>
|
||||
public object CommandParameter
|
||||
{
|
||||
get => (object)this.GetValue(CommandParameterProperty);
|
||||
set => this.SetValue(CommandParameterProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Content"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentProperty
|
||||
= DependencyProperty.Register(nameof(Content),
|
||||
typeof(object),
|
||||
typeof(DropDownButton));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of this control.
|
||||
/// </summary>
|
||||
public object Content
|
||||
{
|
||||
get => (object)this.GetValue(ContentProperty);
|
||||
set => this.SetValue(ContentProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentTemplate"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentTemplateProperty
|
||||
= DependencyProperty.Register(nameof(ContentTemplate),
|
||||
typeof(DataTemplate),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data template used to display the content of the DropDownButton.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public DataTemplate ContentTemplate
|
||||
{
|
||||
get => (DataTemplate)this.GetValue(ContentTemplateProperty);
|
||||
set => this.SetValue(ContentTemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentTemplateSelector"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentTemplateSelectorProperty
|
||||
= DependencyProperty.Register(nameof(ContentTemplateSelector),
|
||||
typeof(DataTemplateSelector),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a template selector that enables an application writer to provide custom template-selection logic.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property is ignored if <seealso cref="ContentTemplate"/> is set.
|
||||
/// </remarks>
|
||||
[Bindable(true)]
|
||||
public DataTemplateSelector ContentTemplateSelector
|
||||
{
|
||||
get => (DataTemplateSelector)this.GetValue(ContentTemplateSelectorProperty);
|
||||
set => this.SetValue(ContentTemplateSelectorProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ContentStringFormat"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ContentStringFormatProperty
|
||||
= DependencyProperty.Register(nameof(ContentStringFormat),
|
||||
typeof(string),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a composite string that specifies how to format the content property if it is displayed as a string.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property is ignored if <seealso cref="ContentTemplate"/> is set.
|
||||
/// </remarks>
|
||||
[Bindable(true)]
|
||||
public string ContentStringFormat
|
||||
{
|
||||
get => (string)this.GetValue(ContentStringFormatProperty);
|
||||
set => this.SetValue(ContentStringFormatProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ButtonStyle"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ButtonStyleProperty
|
||||
= DependencyProperty.Register(nameof(ButtonStyle),
|
||||
typeof(Style),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Style), FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the button content style.
|
||||
/// </summary>
|
||||
public Style ButtonStyle
|
||||
{
|
||||
get => (Style)this.GetValue(ButtonStyleProperty);
|
||||
set => this.SetValue(ButtonStyleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="MenuStyle"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty MenuStyleProperty
|
||||
= DependencyProperty.Register(nameof(MenuStyle),
|
||||
typeof(Style),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Style), FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the "popup" menu style.
|
||||
/// </summary>
|
||||
public Style MenuStyle
|
||||
{
|
||||
get => (Style)this.GetValue(MenuStyleProperty);
|
||||
set => this.SetValue(MenuStyleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush for the button arrow icon.
|
||||
/// </summary>
|
||||
public Brush ArrowBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowBrushProperty);
|
||||
set => this.SetValue(ArrowBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowMouseOverBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowMouseOverBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowMouseOverBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush of the button arrow icon if the mouse is over the drop down button.
|
||||
/// </summary>
|
||||
public Brush ArrowMouseOverBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowMouseOverBrushProperty);
|
||||
set => this.SetValue(ArrowMouseOverBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowPressedBrush"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowPressedBrushProperty
|
||||
= DependencyProperty.Register(nameof(ArrowPressedBrush),
|
||||
typeof(Brush),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(default(Brush), FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground brush of the button arrow icon if the arrow button is pressed.
|
||||
/// </summary>
|
||||
public Brush ArrowPressedBrush
|
||||
{
|
||||
get => (Brush)this.GetValue(ArrowPressedBrushProperty);
|
||||
set => this.SetValue(ArrowPressedBrushProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="ArrowVisibility"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty ArrowVisibilityProperty
|
||||
= DependencyProperty.Register(nameof(ArrowVisibility),
|
||||
typeof(Visibility),
|
||||
typeof(DropDownButton),
|
||||
new FrameworkPropertyMetadata(Visibility.Visible, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visibility of the button arrow icon.
|
||||
/// </summary>
|
||||
public Visibility ArrowVisibility
|
||||
{
|
||||
get => (Visibility)this.GetValue(ArrowVisibilityProperty);
|
||||
set => this.SetValue(ArrowVisibilityProperty, value);
|
||||
}
|
||||
|
||||
static DropDownButton()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DropDownButton), new FrameworkPropertyMetadata(typeof(DropDownButton)));
|
||||
}
|
||||
|
||||
private void OnCommandChanged(ICommand oldCommand, ICommand newCommand)
|
||||
{
|
||||
if (oldCommand != null)
|
||||
{
|
||||
this.UnhookCommand(oldCommand);
|
||||
}
|
||||
|
||||
if (newCommand != null)
|
||||
{
|
||||
this.HookCommand(newCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnhookCommand(ICommand command)
|
||||
{
|
||||
CanExecuteChangedEventManager.RemoveHandler(command, this.OnCanExecuteChanged);
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void HookCommand(ICommand command)
|
||||
{
|
||||
CanExecuteChangedEventManager.AddHandler(command, this.OnCanExecuteChanged);
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void OnCanExecuteChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.UpdateCanExecute();
|
||||
}
|
||||
|
||||
private void UpdateCanExecute()
|
||||
{
|
||||
this.CanExecute = this.Command == null || CommandHelpers.CanExecuteCommandSource(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool IsEnabledCore => base.IsEnabledCore && this.CanExecute;
|
||||
|
||||
private bool canExecute = true;
|
||||
|
||||
private bool CanExecute
|
||||
{
|
||||
get => this.canExecute;
|
||||
set
|
||||
{
|
||||
if (value == this.canExecute)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.canExecute = value;
|
||||
this.CoerceValue(IsEnabledProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CommandHelpers.ExecuteCommandSource(this);
|
||||
|
||||
if (this.contextMenu?.HasItems == true)
|
||||
{
|
||||
this.SetCurrentValue(IsExpandedProperty, true);
|
||||
}
|
||||
|
||||
e.RoutedEvent = ClickEvent;
|
||||
this.RaiseEvent(e);
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (this.button != null)
|
||||
{
|
||||
this.button.Click -= this.ButtonClick;
|
||||
}
|
||||
|
||||
this.button = this.GetTemplateChild("PART_Button") as Button;
|
||||
if (this.button != null)
|
||||
{
|
||||
this.button.Click += this.ButtonClick;
|
||||
}
|
||||
|
||||
this.GroupStyle.CollectionChanged -= this.OnGroupStyleCollectionChanged;
|
||||
|
||||
this.contextMenu = this.GetTemplateChild("PART_Menu") as ContextMenu;
|
||||
if (this.contextMenu != null)
|
||||
{
|
||||
foreach (var groupStyle in this.GroupStyle)
|
||||
{
|
||||
this.contextMenu.GroupStyle.Add(groupStyle);
|
||||
}
|
||||
|
||||
this.GroupStyle.CollectionChanged += this.OnGroupStyleCollectionChanged;
|
||||
|
||||
if (this.Items != null && this.ItemsSource == null)
|
||||
{
|
||||
foreach (var newItem in this.Items)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
private void OnGroupStyleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
#else
|
||||
private void OnGroupStyleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
#endif
|
||||
{
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var groupStyle in e.OldItems.OfType<GroupStyle>())
|
||||
{
|
||||
this.contextMenu?.GroupStyle.Remove(groupStyle);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var groupStyle in e.NewItems.OfType<GroupStyle>())
|
||||
{
|
||||
this.contextMenu?.GroupStyle.Add(groupStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseRightButtonUp(e);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void TryRemoveVisualFromOldTree(object item)
|
||||
{
|
||||
if (item is Visual visual)
|
||||
{
|
||||
var parent = LogicalTreeHelper.GetParent(visual) as FrameworkElement ?? VisualTreeHelper.GetParent(visual) as FrameworkElement;
|
||||
if (Equals(this, parent))
|
||||
{
|
||||
this.RemoveLogicalChild(visual);
|
||||
this.RemoveVisualChild(visual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Invoked when the <see cref="P:System.Windows.Controls.ItemsControl.Items" /> property changes.</summary>
|
||||
/// <param name="e">Information about the change.</param>
|
||||
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
base.OnItemsChanged(e);
|
||||
if (this.contextMenu == null || this.ItemsSource != null || this.contextMenu.ItemsSource != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var newItem in e.NewItems)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var oldItem in e.OldItems)
|
||||
{
|
||||
this.contextMenu.Items.Remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var oldItem in e.OldItems)
|
||||
{
|
||||
this.contextMenu.Items.Remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var newItem in e.NewItems)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (this.Items != null)
|
||||
{
|
||||
this.contextMenu.Items.Clear();
|
||||
foreach (var newItem in this.Items)
|
||||
{
|
||||
this.TryRemoveVisualFromOldTree(newItem);
|
||||
this.contextMenu.Items.Add(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private Button button;
|
||||
private ContextMenu contextMenu;
|
||||
}
|
||||
|
||||
internal static class CommandHelpers
|
||||
{
|
||||
internal static bool CanExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
var command = commandSource.Command;
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
return routedCommand.CanExecute(commandParameter, target);
|
||||
}
|
||||
|
||||
return command.CanExecute(commandParameter);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
[SecuritySafeCritical]
|
||||
internal static void ExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
CriticalExecuteCommandSource(commandSource);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
internal static void CriticalExecuteCommandSource(ICommandSource commandSource)
|
||||
{
|
||||
var command = commandSource.Command;
|
||||
if (command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
if (routedCommand.CanExecute(commandParameter, target))
|
||||
{
|
||||
routedCommand.Execute(commandParameter, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command.CanExecute(commandParameter))
|
||||
{
|
||||
command.Execute(commandParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool CanExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
var command = theCommand;
|
||||
if (command == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
return routedCommand.CanExecute(commandParameter, target);
|
||||
}
|
||||
|
||||
return command.CanExecute(commandParameter);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
[SecuritySafeCritical]
|
||||
internal static void ExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
CriticalExecuteCommandSource(commandSource, theCommand);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
internal static void CriticalExecuteCommandSource(ICommandSource commandSource, ICommand theCommand)
|
||||
{
|
||||
var command = theCommand;
|
||||
if (command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commandParameter = commandSource.CommandParameter ?? commandSource;
|
||||
if (command is RoutedCommand routedCommand)
|
||||
{
|
||||
var target = commandSource.CommandTarget ?? commandSource as IInputElement;
|
||||
if (routedCommand.CanExecute(commandParameter, target))
|
||||
{
|
||||
routedCommand.Execute(commandParameter, target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (command.CanExecute(commandParameter))
|
||||
{
|
||||
command.Execute(commandParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Extensions/AIStudio.Wpf.Mind/Controls/LinkControl.xaml
Normal file
57
Extensions/AIStudio.Wpf.Mind/Controls/LinkControl.xaml
Normal file
@@ -0,0 +1,57 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
<Style x:Key="LinkControlStyle" TargetType="{x:Type controls:LinkControl}">
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Foreground" Value="Gray"/>
|
||||
<Setter Property="Margin" Value="3" />
|
||||
<Setter Property="Padding" Value="1" />
|
||||
<Setter Property="Width" Value="15" />
|
||||
<Setter Property="Height" Value="8" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:LinkControl}">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
SnapsToDevicePixels="true">
|
||||
<TextBlock Background="{TemplateBinding Background}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
|
||||
<Hyperlink
|
||||
x:Name="PART_InnerHyperlink"
|
||||
NavigateUri="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Url}"
|
||||
TextDecorations ="None"
|
||||
Command="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Command}"
|
||||
CommandParameter="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandParameter}"
|
||||
CommandTarget="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandTarget}">
|
||||
<Path Stretch="Uniform" Fill="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Foreground}"
|
||||
Data="M48 226Q48 191 72 168 95 144 130 144L165 144Q191 144 211 157 231 170 240 192L129 192Q115 192 106 202 96 211 96 225L96 287Q96 301 106 311 115 320 129 320L240 320Q231 342 211 355 191 368 165 368L130 368Q95 368 72 345 48 321 48 286L48 226ZM464 286Q464 321 441 345 417 368 382 368L347 368Q321 368 301 355 281 342 272 320L383 320Q397 320 407 311 416 301 416 287L416 225Q416 211 407 202 397 192 383 192L272 192Q281 170 301 157 321 144 347 144L382 144Q417 144 441 168 464 191 464 226L464 286ZM144 232L368 232 368 280 144 280 144 232Z"></Path>
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="Yellow"/>
|
||||
</Trigger>
|
||||
<Trigger SourceName="PART_InnerHyperlink" Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:LinkControl}" BasedOn="{StaticResource LinkControlStyle}"/>
|
||||
</ResourceDictionary>
|
||||
67
Extensions/AIStudio.Wpf.Mind/Controls/LinkControl.xaml.cs
Normal file
67
Extensions/AIStudio.Wpf.Mind/Controls/LinkControl.xaml.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// LinkControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
[TemplatePart(Name = "PART_InnerHyperlink", Type = typeof(Hyperlink))]
|
||||
public class LinkControl : Control
|
||||
{
|
||||
public static readonly DependencyProperty UrlProperty =
|
||||
DependencyProperty.Register(nameof(Url), typeof(string), typeof(LinkControl));
|
||||
|
||||
[Category("Common Properties"), Bindable(true)]
|
||||
public string Url
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(UrlProperty) as string;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(UrlProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
static LinkControl()
|
||||
{
|
||||
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
|
||||
typeof(LinkControl),
|
||||
new FrameworkPropertyMetadata(typeof(LinkControl)));
|
||||
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
Hyperlink innerHyperlink = GetTemplateChild("PART_InnerHyperlink") as Hyperlink;
|
||||
if (innerHyperlink != null)
|
||||
{
|
||||
innerHyperlink.Click += new RoutedEventHandler(InnerHyperlink_Click);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerHyperlink_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 激活的是当前默认的浏览器
|
||||
Process.Start("explorer.exe", Url);
|
||||
}
|
||||
}
|
||||
}
|
||||
186
Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml
Normal file
186
Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml
Normal file
@@ -0,0 +1,186 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Themes/MindNode.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ComboBox.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
<dd:ObjectConverter x:Key="ObjectConverter"/>
|
||||
|
||||
<Style x:Key="AIStudio.Styles.MindEditor" TargetType="{x:Type controls:MindEditor}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:MindEditor}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<!-- ToolBox Control -->
|
||||
<ContentControl x:Name="PART_ContentControl" Template="{Binding ToolBox,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
|
||||
|
||||
<!-- Diagram Control -->
|
||||
<dd:DiagramControl Grid.Row="1" x:Name="PART_DiagramControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
|
||||
<Border x:Name="PART_SearchControl" Grid.Row="1" BorderBrush="Gray" Background="White" BorderThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,1,1,0"
|
||||
Visibility="{Binding ShowSearch,Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid Grid.IsSharedSizeScope="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Height="24">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
|
||||
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ToggleButton x:Name="replaceToggle" Width="20" Height="20" Padding="5,0" ToolTip="查找与替换切换">
|
||||
<ToggleButton.Style>
|
||||
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
|
||||
<Setter Property="Content">
|
||||
<Setter.Value>
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"></Path>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Trigger.Setters>
|
||||
<Setter Property="Content">
|
||||
<Setter.Value>
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"></Path>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Trigger.Setters>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ToggleButton.Style>
|
||||
</ToggleButton>
|
||||
<TextBox Grid.Column="1" Width="200" x:Name="txtsearch" Text="{Binding SearchText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
|
||||
<TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
|
||||
</TextBox.InputBindings>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="LostFocus">
|
||||
<i:InvokeCommandAction Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</TextBox>
|
||||
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
|
||||
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="查找上一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchUpCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"></Path>
|
||||
</Button>
|
||||
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="查找下一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></Path>
|
||||
</Button>
|
||||
<Button Grid.Column="4" Width="20" Height="20" Padding="5,0" ToolTip="关闭" Style="{StaticResource FlatButtonStyle}" Command="{Binding CloseSearchCommand}">
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M500 455.8125L727.875 227.8749999999999L772.1250000000001 272.0625L544.1875 500L772.1250000000001 727.875L727.9375 772.125L500 544.1875L272.125 772.125L227.9375000000001 727.875L455.8125 500L227.9375000000001 272.125L272.125 227.8749999999999L500 455.8125z"></Path>
|
||||
</Button>
|
||||
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Height="24" Visibility="{Binding ElementName=replaceToggle,Path=IsChecked,Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
|
||||
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="1" x:Name="txtreplace" Text="{Binding ReplaceText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
|
||||
</TextBox>
|
||||
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
|
||||
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding ReplaceCommand}">
|
||||
<Button.CommandParameter>
|
||||
<MultiBinding Converter="{StaticResource ObjectConverter}">
|
||||
<MultiBinding.Bindings>
|
||||
<Binding ElementName="txtsearch" Path="Text"/>
|
||||
<Binding ElementName="txtreplace" Path="Text"/>
|
||||
</MultiBinding.Bindings>
|
||||
</MultiBinding>
|
||||
</Button.CommandParameter>
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M940.3 761.5c-8.5-13.3-19.3-24.8-31.9-34.1 13.3-19.5 20.7-43.7 20.7-69.2 0-61.5-43-111.5-95.9-111.5H671.8c-29.3 0-53.1 23.8-53.1 53.1v304c0 29.3 23.8 53.1 53.1 53.1h160.4c34.3 0 66.6-13.5 90.9-37.9 24.1-24.2 37.3-56 37.1-89.7 0-24.2-6.9-47.6-19.9-67.8z m-67.6 107.7c-10.6 10.6-24.7 16.5-39.5 16.5H689.8V773.6h143.3c14.8 0 28.9 5.9 39.5 16.5 10.6 10.6 16.5 24.7 16.5 39.5s-5.8 29-16.4 39.6z m-25.3-178.9c-2.1 2.5-7.7 8.4-14.3 8.4H689.8v-80.9h143.3c6.6 0 12.2 5.9 14.3 8.4 6.6 8 10.6 20 10.6 32.1 0 12-3.9 24-10.6 32zM456 406.6l-128-320C322.5 73 309.3 64 294.5 64h-64c-14.7 0-28 9-33.4 22.6l-128 320c-7.4 18.5 1.6 39.4 20.1 46.8 18.5 7.4 39.4-1.6 46.8-20.1L178.1 328H347l42.1 105.4c5.6 14.1 19.1 22.6 33.4 22.6 4.5 0 9-0.8 13.4-2.6 18.5-7.4 27.5-28.3 20.1-46.8zM206.9 256l48-120h15.3l48 120H206.9z m345.8 582.3l-113.5 67c-5.7 3.4-12 5-18.3 5-12.3 0-24.3-6.3-31-17.7-10.1-17.1-4.4-39.2 12.7-49.3l38.9-23c-47.1-14.5-88.6-35.2-124.1-62-40.2-30.3-72.5-68.1-96-112.5-39.9-75.3-40.6-143.8-40.6-146.7v-0.1c0-19.9 16.1-36 36-36s35.9 16.1 36 35.9v-0.2c0 0.6 1 56.1 33.6 116 18.7 34.4 44.3 63.8 75.9 87.2 29 21.5 63.4 38.3 102.6 50.1l-23-44.1c-9.2-17.6-2.4-39.4 15.3-48.6 17.6-9.2 39.4-2.4 48.6 15.3l60.5 115.9c8.9 17.1 2.9 38.1-13.6 47.8z"></Path>
|
||||
</Button>
|
||||
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="全部替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding ReplaceAllCommand}">
|
||||
<Button.CommandParameter>
|
||||
<MultiBinding Converter="{StaticResource ObjectConverter}">
|
||||
<MultiBinding.Bindings>
|
||||
<Binding ElementName="txtsearch" Path="Text"/>
|
||||
<Binding ElementName="txtreplace" Path="Text"/>
|
||||
</MultiBinding.Bindings>
|
||||
</MultiBinding>
|
||||
</Button.CommandParameter>
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M618.368 905.813333a88.32 88.32 0 0 1-87.082667-87.082666v-209.408a88.362667 88.362667 0 0 1 87.082667-87.082667h209.408a88.234667 88.234667 0 0 1 87.082667 87.082667v209.408a88.192 88.192 0 0 1-87.082667 87.082666z m-22.912-296.490666v209.408a24.448 24.448 0 0 0 22.912 22.997333h209.408a24.704 24.704 0 0 0 23.168-22.997333v-209.408a24.661333 24.661333 0 0 0-23.168-22.912h-209.408a24.448 24.448 0 0 0-23.04 22.912zM224.853333 826.666667a260.010667 260.010667 0 0 1-69.077333-169.514667h-33.237333l66.090666-110.250667 66.346667 110.250667H219.733333a196.266667 196.266667 0 0 0 51.2 125.354667 213.333333 213.333333 0 0 0 148.992 59.264 32.042667 32.042667 0 1 1 0 64 277.034667 277.034667 0 0 1-195.029333-79.274667z m-28.842666-324.821334a88.405333 88.405333 0 0 1-87.082667-87.082666v-209.066667a88.448 88.448 0 0 1 87.082667-87.338667h209.408a88.405333 88.405333 0 0 1 87.082666 87.338667v209.066667a86.144 86.144 0 0 1-87.082666 87.082666z m-23.168-296.32v209.066667a24.917333 24.917333 0 0 0 23.168 23.168h209.408a22.272 22.272 0 0 0 23.168-23.168v-209.066667a24.704 24.704 0 0 0-23.168-23.168H196.010667a24.704 24.704 0 0 0-23.082667 23.125334z m596.181333 165.077334h35.328a196.693333 196.693333 0 0 0-51.2-128.853334 213.333333 213.333333 0 0 0-149.333333-59.434666 32.085333 32.085333 0 0 1 0-64 277.333333 277.333333 0 0 1 195.157333 79.232 261.205333 261.205333 0 0 1 69.504 173.184h32.853333l-62.421333 110.250666z"></Path>
|
||||
</Button>
|
||||
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2" Height="24">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="区分大小写" IsChecked="{Binding SearchCaseMatch}">
|
||||
<Path Stretch="Uniform" Fill="Black" Data="M20.06,18C20,17.83 19.91,17.54 19.86,17.11C19.19,17.81 18.38,18.16 17.45,18.16C16.62,18.16 15.93,17.92 15.4,17.45C14.87,17 14.6,16.39 14.6,15.66C14.6,14.78 14.93,14.1 15.6,13.61C16.27,13.12 17.21,12.88 18.43,12.88H19.83V12.24C19.83,11.75 19.68,11.36 19.38,11.07C19.08,10.78 18.63,10.64 18.05,10.64C17.53,10.64 17.1,10.76 16.75,11C16.4,11.25 16.23,11.54 16.23,11.89H14.77C14.77,11.46 14.92,11.05 15.22,10.65C15.5,10.25 15.93,9.94 16.44,9.71C16.95,9.5 17.5,9.36 18.13,9.36C19.11,9.36 19.87,9.6 20.42,10.09C20.97,10.58 21.26,11.25 21.28,12.11V16C21.28,16.8 21.38,17.42 21.58,17.88V18H20.06M17.66,16.88C18.11,16.88 18.54,16.77 18.95,16.56C19.35,16.35 19.65,16.07 19.83,15.73V14.16H18.7C16.93,14.16 16.04,14.63 16.04,15.57C16.04,16 16.19,16.3 16.5,16.53C16.8,16.76 17.18,16.88 17.66,16.88M5.46,13.71H9.53L7.5,8.29L5.46,13.71M6.64,6H8.36L13.07,18H11.14L10.17,15.43H4.82L3.86,18H1.93L6.64,6Z"></Path>
|
||||
<ToggleButton.Style>
|
||||
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Trigger.Setters>
|
||||
<Setter Property="Background" Value="#cce4f7" />
|
||||
</Trigger.Setters>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ToggleButton.Style>
|
||||
</ToggleButton>
|
||||
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="全字匹配" IsChecked="{Binding SearchWholeWordMatch}">
|
||||
<Path Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M62.5 875H937.5V812.5H62.5V875zM875 750H812.5V250H875V750zM704.5 475.8125A147.06250000000003 147.06250000000003 0 0 1 682 524.9375A109.125 109.125 0 0 1 643.9375 558.0625A114.5 114.5 0 0 1 589.8125000000001 570.125C577.4375 570.125 566.0625 568.625 555.625 565.5624999999999A109.99999999999999 109.99999999999999 0 0 1 527.3125000000001 552.7499999999999A107.75 107.75 0 0 1 504.5000000000001 532.875L493.3125000000001 516.75V713.875H437.5V250H493.3125V285.9375L501.1875 274.9999999999999C506.625 268.6249999999999 513 263.1249999999999 520.1875 258.1874999999999C527.5000000000001 253.3124999999999 535.7500000000001 249.4374999999999 545.0625 246.5624999999999C554.375 243.6875 564.6875 242.3124999999999 576.1875 242.3124999999999C598.25 242.3124999999999 617.8125 246.7499999999999 634.7499999999999 255.5624999999999C651.7499999999999 264.5 665.9375 276.6874999999999 677.375 292.1874999999999C688.8124999999999 307.8124999999999 697.4374999999999 326.1249999999999 703.2499999999999 347.1249999999999C709.0624999999999 368.2499999999999 712 391.0624999999999 712 415.6874999999999A234.74999999999997 234.74999999999997 0 0 1 704.5 475.8124999999999zM612.0625 513.75C621.4999999999999 509.3125 629.6875 502.75 636.4375 494.1250000000001C643.25 485.375 648.5625 474.5625 652.375 461.8125000000001C655.5625 450.9375000000001 657.5000000000001 438.625 657.9375000000001 425.1250000000001L657.5000000000001 417.3125000000001C657.5000000000001 396.8750000000001 655.4375000000001 378.5625000000001 651.2500000000001 363.0000000000001A117.87500000000001 117.87500000000001 0 0 0 633.8750000000001 324.625C626.5625 314.5 617.6250000000001 306.8125 607.5625000000001 301.7500000000001C587.4375000000001 291.625 560.0625000000001 291.375 540.7500000000001 300.8125A79 79 0 0 0 516.1875 319.3125A79.5625 79.5625 0 0 0 502.5625 342.25S491.375 370.1874999999999 491.375 401.4374999999999C491.375 432.6874999999999 502.5625 464.0624999999999 502.5625 464.0624999999999C506.4375 475.1249999999999 511.0625 483.9374999999999 516.5625 490.9374999999999C523.6875000000001 499.8749999999999 532.5625 507.1249999999999 543.0625 512.4999999999999C553.5625 517.875 565.875 520.5625 579.75 520.5625C591.625 520.5625 602.5 518.25 612.0625 513.75zM937.5 187.5H62.5V125H937.5V187.5zM175.8125 375L130.3125 248.0625H62.5L64.0625 252.5624999999999L216.625 695.4375H275.4375L430.75 248.0624999999999H363.125L314.5 375H175.8125zM245.875 598.625H244.5000000000001L187.9375 426.5625H303.0000000000001L245.8750000000001 598.625z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<ToggleButton.Style>
|
||||
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Trigger.Setters>
|
||||
<Setter Property="Background" Value="#cce4f7" />
|
||||
</Trigger.Setters>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ToggleButton.Style>
|
||||
</ToggleButton>
|
||||
<TextBlock Grid.Column="1" Margin="2,0,0,0" VerticalAlignment="Center" Text="{Binding SearchInfo}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AIStudio.Styles.MindEditor.Default" TargetType="{x:Type controls:MindEditor}" BasedOn="{StaticResource AIStudio.Styles.MindEditor}">
|
||||
<Setter Property="ToolBox">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Control">
|
||||
<controls:ToolBoxControl />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:MindEditor}" BasedOn="{StaticResource AIStudio.Styles.MindEditor.Default}" />
|
||||
</ResourceDictionary>
|
||||
218
Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs
Normal file
218
Extensions/AIStudio.Wpf.Mind/Controls/MindEditor.xaml.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows;
|
||||
using System.Xml.Linq;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
using AIStudio.Wpf.Mind.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.Serializable;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// MindEditor.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
|
||||
[TemplatePart(Name = PART_ContentControl, Type = typeof(ContentControl))]
|
||||
[TemplatePart(Name = PART_SearchControl, Type = typeof(Border))]
|
||||
public partial class MindEditor : UserControl
|
||||
{
|
||||
public const string PART_DiagramControl = "PART_DiagramControl";
|
||||
public const string PART_ContentControl = "PART_ContentControl";
|
||||
public const string PART_SearchControl = "PART_SearchControl";
|
||||
private DiagramControl _diagramControl;
|
||||
private ContentControl _contentControl;
|
||||
private Border _searchborder;
|
||||
|
||||
private MindDiagramViewModel _diagramViewModel;
|
||||
|
||||
static MindEditor()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MindEditor), new FrameworkPropertyMetadata(typeof(MindEditor)));
|
||||
}
|
||||
|
||||
public MindEditor()
|
||||
{
|
||||
_diagramViewModel = new MindDiagramViewModel();
|
||||
_diagramViewModel.GridMarginSize = new Size(0, 0);
|
||||
_diagramViewModel.PageSizeType = PageSizeType.Custom;
|
||||
_diagramViewModel.PageSize = new SizeBase(1000d, 1000d);
|
||||
_diagramViewModel.ShowGrid= false;
|
||||
_diagramViewModel.DefaultZoomBox = true;
|
||||
|
||||
_diagramViewModel.PropertyChanged += DiagramViewModel_PropertyChanged;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_diagramControl = GetTemplateChild(PART_DiagramControl) as DiagramControl;
|
||||
_diagramControl.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
_diagramControl.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
_diagramControl.DataContext = _diagramViewModel;
|
||||
|
||||
_contentControl = GetTemplateChild(PART_ContentControl) as ContentControl;
|
||||
if (_contentControl != null)
|
||||
{
|
||||
_contentControl.DataContext = _diagramViewModel;
|
||||
}
|
||||
|
||||
_searchborder = GetTemplateChild(PART_SearchControl) as Border;
|
||||
if (_searchborder != null)
|
||||
{
|
||||
_searchborder.DataContext = _diagramViewModel;
|
||||
}
|
||||
|
||||
GetDataFunc = GetData;
|
||||
}
|
||||
|
||||
private void DiagramViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "IsSelected")
|
||||
{
|
||||
SelectedObject = _diagramViewModel.SelectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
//一点要绑定不为空的FlowchartModel才能用,即便为空的也要new一个再来绑定
|
||||
public static readonly DependencyProperty DataProperty =
|
||||
DependencyProperty.Register(nameof(Data),
|
||||
typeof(string),
|
||||
typeof(MindEditor),
|
||||
new FrameworkPropertyMetadata(null, OnDataChanged));
|
||||
|
||||
public string Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(DataProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(DataProperty, value);
|
||||
}
|
||||
}
|
||||
private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var view = d as MindEditor;
|
||||
var json = e.NewValue as string;
|
||||
if (json != null)
|
||||
{
|
||||
view.CreateFlowchartModel(json);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateFlowchartModel(string json)
|
||||
{
|
||||
_diagramViewModel.IsLoading = true;
|
||||
|
||||
_diagramViewModel.Items.Clear();
|
||||
_diagramViewModel.ToObject(json);
|
||||
|
||||
_diagramViewModel.Init(true);
|
||||
_diagramViewModel.IsLoading = false;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty GetDataFuncProperty =
|
||||
DependencyProperty.Register(nameof(GetDataFunc),
|
||||
typeof(Func<string>),
|
||||
typeof(MindEditor),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
public Func<string> GetDataFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Func<string>)this.GetValue(GetDataFuncProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.SetValue(GetDataFuncProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Func<string> GetData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Func<string>(() => _diagramViewModel.ToJson());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static readonly DependencyProperty ModeProperty =
|
||||
DependencyProperty.Register(nameof(Mode),
|
||||
typeof(string),
|
||||
typeof(MindEditor),
|
||||
new FrameworkPropertyMetadata("Edit", OnModeChanged));
|
||||
|
||||
public string Mode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(ModeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ModeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var view = d as MindEditor;
|
||||
var mode = e.NewValue as string;
|
||||
if (mode != "Edit")
|
||||
{
|
||||
view._diagramViewModel.IsReadOnly = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
view._diagramViewModel.IsReadOnly = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region ToolBox
|
||||
/// <summary>
|
||||
/// 附加组件模板
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ToolBoxProperty = DependencyProperty.Register(
|
||||
nameof(ToolBox), typeof(ControlTemplate), typeof(MindEditor), new FrameworkPropertyMetadata(default(ControlTemplate)));
|
||||
|
||||
public ControlTemplate ToolBox
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ControlTemplate)GetValue(ToolBoxProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ToolBoxProperty, value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SelectedObject
|
||||
|
||||
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(nameof(SelectedObject), typeof(object), typeof(MindEditor), new UIPropertyMetadata(default(object)));
|
||||
public object SelectedObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return (object)GetValue(SelectedObjectProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SelectedObjectProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
26
Extensions/AIStudio.Wpf.Mind/Controls/NodeDTSWindow.xaml
Normal file
26
Extensions/AIStudio.Wpf.Mind/Controls/NodeDTSWindow.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Window x:Class="AIStudio.Wpf.Mind.Controls.NodeDTSWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:local="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
mc:Ignorable="d"
|
||||
WindowStyle="None"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Height="450" Width="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Margin="5" Text="{Binding Title}"/>
|
||||
<Border BorderThickness="0,0,0,1" BorderBrush="DarkGray" VerticalAlignment="Bottom"></Border>
|
||||
<TextBox Grid.Row="1" Margin="5" TextWrapping="Wrap" AcceptsReturn="True" AcceptsTab="True" Text="{Binding Content}"/>
|
||||
<Border Grid.Row="2" BorderThickness="0,0,0,1" BorderBrush="DarkGray" VerticalAlignment="Top"></Border>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Margin="5" Padding="6,3" Background="#73a1bf" Foreground="White" BorderThickness="0" Content="OK" x:Name="btnOK" Click="btnOK_Click" IsDefault="True"/>
|
||||
<Button Margin="5" Padding="6,3" Background="#FFEDA46F" Foreground="White" BorderThickness="0" Content="Cancel" x:Name="btnCancel" Click="btnCancel_Click" IsCancel="True" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
71
Extensions/AIStudio.Wpf.Mind/Controls/NodeDTSWindow.xaml.cs
Normal file
71
Extensions/AIStudio.Wpf.Mind/Controls/NodeDTSWindow.xaml.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Windows;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// NodeDTSWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class NodeDTSWindow : Window
|
||||
{
|
||||
public NodeDTSWindow(string title, string content)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var viewmodel = new NodeDTSWindowViewModel();
|
||||
viewmodel.Title = title;
|
||||
viewmodel.Content = content;
|
||||
|
||||
this.DataContext = viewmodel;
|
||||
}
|
||||
|
||||
public string ContentString
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.DataContext as NodeDTSWindowViewModel).Content;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = false;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public class NodeDTSWindowViewModel : BindableBase
|
||||
{
|
||||
private string _title;
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
return _title;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _title, value);
|
||||
}
|
||||
}
|
||||
|
||||
private string _content;
|
||||
public string Content
|
||||
{
|
||||
get
|
||||
{
|
||||
return _content;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(ref _content, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Extensions/AIStudio.Wpf.Mind/Controls/OpenFileTextBox.xaml
Normal file
40
Extensions/AIStudio.Wpf.Mind/Controls/OpenFileTextBox.xaml
Normal file
@@ -0,0 +1,40 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="OpenFileTextBoxStyle" TargetType="{x:Type controls:OpenFileTextBox}">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderBrush" Value="Gray" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:OpenFileTextBox}">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="Bg"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
Grid.ColumnSpan="2"/>
|
||||
|
||||
<!--内容区域-->
|
||||
<ScrollViewer x:Name="PART_ContentHost" BorderThickness="0" IsTabStop="False" Margin="2"
|
||||
VerticalAlignment="Stretch" Background="{x:Null}" />
|
||||
<Button x:Name="PART_OpenButton" Grid.Column="1" Content="打开" Padding="6,0" Style="{StaticResource FlatButtonStyle}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:OpenFileTextBox}" BasedOn="{StaticResource OpenFileTextBoxStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
[TemplatePart(Name = PART_OpenButton, Type = typeof(Button))]
|
||||
public class OpenFileTextBox : TextBox
|
||||
{
|
||||
private const string PART_OpenButton = "PART_OpenButton";
|
||||
private Button _openButton;
|
||||
|
||||
static OpenFileTextBox()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(OpenFileTextBox), new FrameworkPropertyMetadata(typeof(OpenFileTextBox)));
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Filter"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty FilterProperty
|
||||
= DependencyProperty.Register(nameof(Filter), typeof(string), typeof(OpenFileTextBox), new UIPropertyMetadata("图像文件(*.bmp, *.jpg)|*.bmp;*.jpg|所有文件(*.*)|*.*"));
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public string Filter
|
||||
{
|
||||
get => (string)this.GetValue(FilterProperty);
|
||||
set => this.SetValue(FilterProperty, (string)value);
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (_openButton != null)
|
||||
{
|
||||
_openButton.Click -= _openButton_Click;
|
||||
}
|
||||
|
||||
_openButton = this.Template.FindName(PART_OpenButton, this) as Button;
|
||||
|
||||
if (_openButton != null)
|
||||
{
|
||||
_openButton.Click += _openButton_Click;
|
||||
}
|
||||
}
|
||||
|
||||
private void _openButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenFileDialog fd = new OpenFileDialog();
|
||||
fd.Title = "请选择文件";
|
||||
fd.Filter = Filter;
|
||||
fd.FileName = Text?.Trim();
|
||||
if (fd.ShowDialog() == true)
|
||||
{
|
||||
SetValue(TextProperty, fd.FileName);
|
||||
}
|
||||
//this.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Extensions/AIStudio.Wpf.Mind/Controls/PriorityControl.xaml
Normal file
79
Extensions/AIStudio.Wpf.Mind/Controls/PriorityControl.xaml
Normal file
@@ -0,0 +1,79 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
|
||||
<Style x:Key="PriorityControlStyle" TargetType="{x:Type controls:PriorityControl}">
|
||||
<Setter Property="Background" Value="Gray" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="3" />
|
||||
<Setter Property="Margin" Value="1" />
|
||||
<Setter Property="Width" Value="16" />
|
||||
<Setter Property="Height" Value="16" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:PriorityControl}">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="3"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Path x:Name="Path" Stretch="Uniform" Fill="{TemplateBinding Foreground}"
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
Data="">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Priority" Value="1">
|
||||
<Setter TargetName="Path" Property="Data" Value="M700 1125V100H600V1014.8L375 954.5V1058.05L625 1125z"/>
|
||||
<Setter Property="Background" Value="Red"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="2">
|
||||
<Setter TargetName="Path" Property="Data" Value="M800 825A200 200 0 1 1 400 825H300A300 300 0 1 0 833.15 636.2L467.15 200.0499999999999L900 200V100H300V156.3499999999999L753.2 696.4499999999999A199.10000000000002 199.10000000000002 0 0 1 800 825z"/>
|
||||
<Setter Property="Background" Value="Blue"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="3">
|
||||
<Setter TargetName="Path" Property="Data" Value="M900 1100V1031.9L640.4499999999999 722.5A325.05 325.05 0 1 0 284.65 321.0999999999999L381.65 345.3999999999999A225.1 225.1 0 0 1 825 400A225 225 0 0 1 499.7500000000001 601.5L488.3500000000001 595.4000000000001L453.8500000000001 655.7500000000001L742.75 1000L325 1000V1100H900z"/>
|
||||
<Setter Property="Background" Value="Green"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="4">
|
||||
<Setter TargetName="Path" Property="Data" Value="M800 1125V400H950V300H800V100H700V300H200V355.1L700 1125H800zM700 400V941.45L348.4 400H700z"/>
|
||||
<Setter Property="Background" Value="Orange"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="5">
|
||||
<Setter TargetName="Path" Property="Data" Value="M900 1100V1000H465.0000000000001L431.1500000000001 677.75A325 325 0 1 0 284.6500000000001 321.1L381.6500000000001 345.4000000000001A225.1 225.1 0 0 1 825 400A225 225 0 0 1 600 625C498.9 625 436.1 593.0500000000001 402 548.5L323.25 607.6L375 1100H900z"/>
|
||||
<Setter Property="Background" Value="Purple"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="6">
|
||||
<Setter TargetName="Path" Property="Data" Value="M744.3 1100L522.4 715.7A325 325 0 1 0 320 565L628.8000000000001 1100H744.3000000000001zM600 625A225 225 0 1 1 600 175A225 225 0 0 1 600 625z"/>
|
||||
<Setter Property="Background" Value="Gray"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="7">
|
||||
<Setter TargetName="Path" Property="Data" Value="M950 1100V1025L538.15 100H428.7L829.35 1000H300V1100z"/>
|
||||
<Setter Property="Background" Value="Gray"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="8">
|
||||
<Setter TargetName="Path" Property="Data" Value="M600 1125A275 275 0 0 0 767.6 632C861.9999999999999 579.5 925 484 925 375C925 209.3 779.5 75 600 75S275 209.3 275 375C275 484.0500000000001 338.05 579.5 432.35 632.05A275 275 0 0 0 600 1125zM600 575C474 575 375 483.6 375 375C375 266.4 474 175 600 175S825 266.4 825 375C825 483.6 726 575 600 575zM600 1025A175 175 0 1 1 600 675A175 175 0 0 1 600 1025z"/>
|
||||
<Setter Property="Background" Value="Gray"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Priority" Value="9">
|
||||
<Setter TargetName="Path" Property="Data" Value="M600 1125A325 325 0 0 0 880.95 636.5L571.15 100.05H455.7L677.6500000000001 484.35A325 325 0 1 0 600 1125zM600 1025A225 225 0 1 1 600 575A225 225 0 0 1 600 1025z"/>
|
||||
<Setter Property="Background" Value="Gray"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:PriorityControl}" BasedOn="{StaticResource PriorityControlStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// PriorityControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public class PriorityControl : Control
|
||||
{
|
||||
static PriorityControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(PriorityControl), new FrameworkPropertyMetadata(typeof(PriorityControl)));
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Priority"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty PriorityProperty
|
||||
= DependencyProperty.Register(nameof(Priority), typeof(double?), typeof(PriorityControl));
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public double? Priority
|
||||
{
|
||||
get => (double?)this.GetValue(PriorityProperty);
|
||||
set => this.SetValue(PriorityProperty, (double?)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Extensions/AIStudio.Wpf.Mind/Controls/RateControl.xaml
Normal file
66
Extensions/AIStudio.Wpf.Mind/Controls/RateControl.xaml
Normal file
@@ -0,0 +1,66 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
|
||||
<Style x:Key="RateControlStyle" TargetType="{x:Type controls:RateControl}">
|
||||
<Setter Property="Background" Value="Yellow" />
|
||||
<Setter Property="Foreground" Value="Green" />
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="3" />
|
||||
<Setter Property="Margin" Value="1" />
|
||||
<Setter Property="Width" Value="16" />
|
||||
<Setter Property="Height" Value="16" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:RateControl}">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Ellipse Fill="{TemplateBinding Background}"
|
||||
Stroke="{TemplateBinding BorderBrush}"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}"
|
||||
x:Name="border">
|
||||
</Ellipse>
|
||||
<Path x:Name="Path" Stretch="Uniform" Fill="{TemplateBinding Foreground}"
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
Data="">
|
||||
</Path>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Rate" Value="0">
|
||||
<Setter TargetName="Path" Property="Data" Value="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"/>
|
||||
<Setter Property="Foreground" Value="DarkRed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.125">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C13.93 5 15.68 5.78 16.95 7.05L12 12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.25">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12H12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.375">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 13.93 18.22 15.68 16.95 16.95L12 12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.5">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.625">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C10.07 19 8.32 18.22 7.05 16.95L12 12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.75">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C8.13 19 5 15.87 5 12H12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="0.875">
|
||||
<Setter TargetName="Path" Property="Data" Value="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C8.13 19 5 15.87 5 12C5 10.07 5.78 8.32 7.05 7.05L12 12V5Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Rate" Value="1">
|
||||
<Setter TargetName="Path" Property="Data" Value="m 256,76 c 48.1,0 93.3,18.7 127.3,52.7 34,34 52.7,79.2 52.7,127.3 0,48.1 -18.7,93.3 -52.7,127.3 -34,34 -79.2,52.7 -127.3,52.7 -48.1,0 -93.3,-18.7 -127.3,-52.7 C 94.7,349.3 76,304.1 76,256 76,207.9 94.7,162.7 128.7,128.7 162.7,94.7 207.9,76 256,76 m 0,-28 C 141.1,48 48,141.1 48,256 48,370.9 141.1,464 256,464 370.9,464 464,370.9 464,256 464,141.1 370.9,48 256,48 Z M 362.6,192.9 345,174.8 c -0.7,-0.8 -1.8,-1.2 -2.8,-1.2 -1.1,0 -2.1,0.4 -2.8,1.2 L 217.4,297.7 173,253.3 c -0.8,-0.8 -1.8,-1.2 -2.8,-1.2 -1,0 -2,0.4 -2.8,1.2 l -17.8,17.8 c -1.6,1.6 -1.6,4.1 0,5.7 l 56,56 c 3.6,3.6 8,5.7 11.7,5.7 5.3,0 9.9,-3.9 11.6,-5.5 H 229 L 362.7,198.6 c 1.4,-1.7 1.4,-4.2 -0.1,-5.7 z"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:RateControl}" BasedOn="{StaticResource RateControlStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
41
Extensions/AIStudio.Wpf.Mind/Controls/RateControl.xaml.cs
Normal file
41
Extensions/AIStudio.Wpf.Mind/Controls/RateControl.xaml.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// RateControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public class RateControl : Control
|
||||
{
|
||||
static RateControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(RateControl), new FrameworkPropertyMetadata(typeof(RateControl)));
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Rate"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty RateProperty
|
||||
= DependencyProperty.Register(nameof(Rate), typeof(double?), typeof(RateControl));
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public double? Rate
|
||||
{
|
||||
get => (double?)this.GetValue(RateProperty);
|
||||
set => this.SetValue(RateProperty, (double?)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
Extensions/AIStudio.Wpf.Mind/Controls/RemarkControl.xaml
Normal file
58
Extensions/AIStudio.Wpf.Mind/Controls/RemarkControl.xaml
Normal file
@@ -0,0 +1,58 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
|
||||
<Style x:Key="RemarkControlStyle" TargetType="{x:Type controls:RemarkControl}">
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Foreground" Value="Green"/>
|
||||
<Setter Property="Margin" Value="3" />
|
||||
<Setter Property="Padding" Value="1" />
|
||||
<Setter Property="Width" Value="12" />
|
||||
<Setter Property="Height" Value="12" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:RemarkControl}">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
SnapsToDevicePixels="true">
|
||||
<TextBlock Background="{TemplateBinding Background}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
|
||||
<Hyperlink
|
||||
x:Name="PART_InnerHyperlink"
|
||||
NavigateUri="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Url}"
|
||||
TextDecorations ="None"
|
||||
Command="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Command}"
|
||||
CommandParameter="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandParameter}"
|
||||
CommandTarget="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandTarget}">
|
||||
<Path Stretch="Uniform" Fill="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Foreground}"
|
||||
Data="M125 125V875H875V125H125ZM812.5 812.5H187.5V187.5H812.5V812.5ZM250 687.5H625V625H250V687.5ZM750 500H250V562.5H750V500ZM750 375H250V437.5H750V375Z"></Path>
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="Yellow"/>
|
||||
</Trigger>
|
||||
<Trigger SourceName="PART_InnerHyperlink" Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:RemarkControl}" BasedOn="{StaticResource RemarkControlStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
41
Extensions/AIStudio.Wpf.Mind/Controls/RemarkControl.xaml.cs
Normal file
41
Extensions/AIStudio.Wpf.Mind/Controls/RemarkControl.xaml.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// RemarkControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public class RemarkControl : Control
|
||||
{
|
||||
static RemarkControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(RemarkControl), new FrameworkPropertyMetadata(typeof(RemarkControl)));
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Remark"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty RemarkProperty
|
||||
= DependencyProperty.Register(nameof(Remark), typeof(string), typeof(RemarkControl));
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public string Remark
|
||||
{
|
||||
get => (string)this.GetValue(RemarkProperty);
|
||||
set => this.SetValue(RemarkProperty, (string)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
102
Extensions/AIStudio.Wpf.Mind/Controls/TagControl.xaml
Normal file
102
Extensions/AIStudio.Wpf.Mind/Controls/TagControl.xaml
Normal file
@@ -0,0 +1,102 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
|
||||
<Style x:Key="TagControlStyle" TargetType="{x:Type controls:TagControl}" >
|
||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
|
||||
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:TagControl}">
|
||||
<Border BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Background="{TemplateBinding Background}"
|
||||
SnapsToDevicePixels="True"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalAlignment}">
|
||||
<ScrollViewer Padding="{TemplateBinding Padding}"
|
||||
CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
|
||||
Focusable="False"
|
||||
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="AlternationCount" Value="8"/>
|
||||
<Setter Property="ItemsPanel">
|
||||
<Setter.Value>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ItemContainerStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="{x:Type ContentControl}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ContentControl}">
|
||||
<Border Margin="2" Background="{TemplateBinding Background}">
|
||||
<ContentPresenter/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#ffb3fb"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#ecffb3"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
|
||||
<Setter Property="Background" Value="#b3e5ff"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="3">
|
||||
<Setter Property="Background" Value="#b3ffe2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="4">
|
||||
<Setter Property="Background" Value="#ffb3b3"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="5">
|
||||
<Setter Property="Background" Value="#ffccb3"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="6">
|
||||
<Setter Property="Background" Value="#c4b3ff"/>
|
||||
</Trigger>
|
||||
<Trigger Property="ItemsControl.AlternationIndex" Value="7">
|
||||
<Setter Property="Background" Value="#fff7b3"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ItemTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="grid">
|
||||
<TextBlock Text="{Binding .}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type controls:TagControl}" BasedOn="{StaticResource TagControlStyle}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
39
Extensions/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs
Normal file
39
Extensions/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// TagControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public class TagControl : ItemsControl
|
||||
{
|
||||
static TagControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(TagControl), new FrameworkPropertyMetadata(typeof(TagControl)));
|
||||
}
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
{
|
||||
return new ContentControl();
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item)
|
||||
{
|
||||
return item is ContentControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
635
Extensions/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
Normal file
635
Extensions/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
Normal file
@@ -0,0 +1,635 @@
|
||||
<UserControl x:Class="AIStudio.Wpf.Mind.Controls.ToolBoxControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
|
||||
xmlns:models="clr-namespace:AIStudio.Wpf.Mind.Models"
|
||||
xmlns:converter="clr-namespace:AIStudio.Wpf.Mind.Converters"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800" >
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/ToggleButton.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/ComboBox.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/DropDownButton.xaml" />
|
||||
<ResourceDictionary>
|
||||
<dd:ColorBrushConverter x:Key="ColorBrushConverter"/>
|
||||
<dd:EnumDescriptionConverter x:Key="EnumDescriptionConverter"/>
|
||||
<dd:ObjectConverter x:Key="ObjectConverter"/>
|
||||
<converter:MindThemeFillBrushConverter x:Key="MindThemeFillBrushConverter"/>
|
||||
<converter:MindThemeFontBrushConverter x:Key="MindThemeFontBrushConverter"/>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Height="100">
|
||||
<TabControl>
|
||||
<TabItem Header="思路" Height="30" Width="50">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<UniformGrid Rows="2">
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding UndoCommand}">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Row="1" Grid.Column="0" Command="{Binding RedoCommand}">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"></Path>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Rows="2">
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding AddChildCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M992.9 500.1H355c-19.3 0-35 15.7-35 35V660H182V340.8h427.8c32 0 58-26 58-58V58c0-32-25.9-58-58-58H58C26 0 0 26 0 58v224.8c0 32 26 58 58 58h54V689c0 13.3 7.4 24.8 18.2 30.7 6.3 6.3 15.1 10.3 24.8 10.3h165v145.9c0 19.3 15.7 35 35 35h226c19.3 0 35-15.7 35-35s-15.7-35-35-35H390V570.1h567.9V611c0 19.3 15.7 35 35 35s35-15.7 35-35v-75.9c0-19.3-15.7-35-35-35zM70 70h527.8v200.8H70V70zM989 830h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z"></Path>
|
||||
<TextBlock>插入下级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding AddParentCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M992.9 500.1H355c-19.3 0-35 15.7-35 35V660H182V340.8h427.8c32 0 58-26 58-58V58c0-32-25.9-58-58-58H58C26 0 0 26 0 58v224.8c0 32 26 58 58 58h54V689c0 13.3 7.4 24.8 18.2 30.7 6.3 6.3 15.1 10.3 24.8 10.3h165v145.9c0 19.3 15.7 35 35 35h226c19.3 0 35-15.7 35-35s-15.7-35-35-35H390V570.1h567.9V611c0 19.3 15.7 35 35 35s35-15.7 35-35v-75.9c0-19.3-15.7-35-35-35zM70 70h527.8v200.8H70V70zM989 830h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleX="-1" ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<TextBlock>插入上级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding AddPearCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M651.8 775.5h-20.3v-527h178V305c0 19.3 15.7 35 35 35s35-15.7 35-35v-91.5c0-19.3-15.7-35-35-35h-248c-19.3 0-35 15.7-35 35V477H340.8V236.1c0-32-26-58-58-58H58c-32 0-58 26-58 58v551.8c0 32 26 58 58 58h224.8c32 0 58-26 58-58V547h220.7v263.5c0 19.3 15.7 35 35 35h55.3c19.3 0 35-15.7 35-35s-15.7-35-35-35z m-381 0.4H70V248.1h200.8v527.8zM990 651.5h-89v-89c0-19.3-15.7-35-35-35s-35 15.7-35 35v89h-89c-19.3 0-35 15.7-35 35s15.7 35 35 35h89v89c0 19.3 15.7 35 35 35s35-15.7 35-35v-89h89c19.3 0 35-15.7 35-35s-15.7-35-35-35z"></Path>
|
||||
<TextBlock>插入同级主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding AddRootCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M696 334.2H326.6c-27.4 0-49.7-22.3-49.7-49.7V114c0-27.4 22.3-49.7 49.7-49.7H696c27.4 0 49.7 22.3 49.7 49.7v170.5c0.1 27.4-22.2 49.7-49.7 49.7zM326.6 106.8c-3.9 0-7.1 3.3-7.1 7.1v170.5c0 3.9 3.3 7.1 7.1 7.1H696c3.9 0 7.1-3.3 7.1-7.1V114c0-3.9-3.3-7.1-7.1-7.1H326.6zM895 960.8H127.7c-27.4 0-49.7-22.3-49.7-49.7V541.6c0-27.4 22.3-49.7 49.7-49.7H895c27.4 0 49.7 22.3 49.7 49.7V911c0 27.5-22.3 49.8-49.7 49.8zM127.7 534.5c-3.9 0-7.1 3.3-7.1 7.1V911c0 3.9 3.3 7.1 7.1 7.1H895c3.9 0 7.1-3.3 7.1-7.1V541.6c0-3.9-3.3-7.1-7.1-7.1H127.7zM511.4 533.1c-11.8 0-21.3-9.5-21.3-21.3l-0.1-198.9c0-11.8 9.5-21.3 21.3-21.3s21.3 9.5 21.3 21.3l0.1 198.9c0 11.8-9.5 21.3-21.3 21.3z"></Path>
|
||||
<TextBlock>新建根主题</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Rows="2">
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding MoveForwardCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M62.5 500L312.5 500L312.5 937.5L687.5 937.5L687.5 500L937.5 500L500 62.5Z"></Path>
|
||||
<TextBlock>上移</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding MoveBackCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M687.5 62.5L312.5 62.5L312.5 500L62.5 500L500 937.5L937.4 500L687.5 500Z"></Path>
|
||||
<TextBlock>下移</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Rows="2">
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding EditCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M8,12H16V14H8V12M10,20H6V4H13V9H18V12.1L20,10.1V8L14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H10V20M8,18H12.1L13,17.1V16H8V18M20.2,13C20.3,13 20.5,13.1 20.6,13.2L21.9,14.5C22.1,14.7 22.1,15.1 21.9,15.3L20.9,16.3L18.8,14.2L19.8,13.2C19.9,13.1 20,13 20.2,13M20.2,16.9L14.1,23H12V20.9L18.1,14.8L20.2,16.9Z"></Path>
|
||||
<TextBlock>编辑</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding DeleteCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M 25.3333,23.75L 50.6667,23.75C 51.5411,23.75 51.8541,27.3125 51.8541,27.3125L 24.1458,27.3125C 24.1458,27.3125 24.4589,23.75 25.3333,23.75 Z M 35.625,19.7917L 40.375,19.7917C 40.8122,19.7917 41.9583,20.9378 41.9583,21.375C 41.9583,21.8122 40.8122,22.9584 40.375,22.9584L 35.625,22.9584C 35.1878,22.9584 34.0416,21.8122 34.0416,21.375C 34.0416,20.9378 35.1878,19.7917 35.625,19.7917 Z M 27.7083,28.5L 48.2916,28.5C 49.1661,28.5 49.875,29.2089 49.875,30.0834L 48.2916,53.8334C 48.2916,54.7078 47.5828,55.4167 46.7083,55.4167L 29.2917,55.4167C 28.4172,55.4167 27.7083,54.7078 27.7083,53.8334L 26.125,30.0834C 26.125,29.2089 26.8339,28.5 27.7083,28.5 Z M 30.0833,31.6667L 30.4792,52.25L 33.25,52.25L 32.8542,31.6667L 30.0833,31.6667 Z M 36.4167,31.6667L 36.4167,52.25L 39.5833,52.25L 39.5833,31.6667L 36.4167,31.6667 Z M 43.1458,31.6667L 42.75,52.25L 45.5208,52.25L 45.9167,31.6667L 43.1458,31.6667 Z "></Path>
|
||||
<TextBlock>删除</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Rows="1">
|
||||
<controls:DropDownButton>
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M 23.4963,46.1288L 25.0796,48.8712L 29.4053,50.0303L 33.519,47.6553L 34.8902,46.8636L 37.6326,45.2803L 38.4242,46.6515L 37.2652,50.9772L 30.4091,54.9356L 21.7577,52.6174L 18.591,47.1326L 20.9091,38.4811L 27.7652,34.5227L 32.0909,35.6818L 32.8826,37.053L 30.1402,38.6364L 28.769,39.428L 24.6553,41.803L 23.4963,46.1288 Z M 38.7348,28.1895L 45.5908,24.2311L 54.2423,26.5493L 57.409,32.0341L 55.0908,40.6856L 48.2348,44.6439L 43.9091,43.4848L 43.1174,42.1136L 45.8598,40.5303L 47.231,39.7386L 51.3446,37.3636L 52.5037,33.0379L 50.9204,30.2955L 46.5946,29.1364L 42.481,31.5114L 41.1098,32.3031L 38.3674,33.8864L 37.5757,32.5152L 38.7348,28.1895 Z M 33.9006,45.1496L 31.7377,44.5701L 30.5502,42.5133L 31.1298,40.3504L 42.0994,34.0171L 44.2623,34.5966L 45.4498,36.6534L 44.8702,38.8163L 33.9006,45.1496 Z "></Path>
|
||||
<TextBlock>链接</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="链接地址:"></TextBlock>
|
||||
<TextBox x:Name="link" Width="300" Height="50" Text="{Binding LinkInfo.Url}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="提示文本:"></TextBlock>
|
||||
<TextBox x:Name="linktext" Width="300" Height="50" Text="{Binding LinkInfo.Text}"/>
|
||||
</StackPanel>
|
||||
<MenuItem Header="插入链接" Command="{Binding AddLinkCommand}">
|
||||
<MenuItem.CommandParameter>
|
||||
<MultiBinding Converter="{StaticResource ObjectConverter}">
|
||||
<Binding ElementName="link" Path="Text"></Binding>
|
||||
<Binding ElementName="linktext" Path="Text"></Binding>
|
||||
</MultiBinding>
|
||||
</MenuItem.CommandParameter>
|
||||
</MenuItem>
|
||||
<MenuItem Header="移除已有链接" Command="{Binding RemoveLinkCommand}"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton>
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M250 645L350 745L625 470L800 645L950 495V950H250V645zM250 503.55V250H405L554.3000000000001 399.25L350 603.55L250 503.55zM546.45 250H950V353.5500000000001L800 503.5500000000001L546.45 250zM200 1050H1000A50 50 0 0 0 1050 1000V200A50 50 0 0 0 1000 150H200A50 50 0 0 0 150 200V1000A50 50 0 0 0 200 1050zM775 700A75 75 0 1 0 775 850A75 75 0 0 0 775 700z"></Path>
|
||||
<TextBlock>图片</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="文件地址:"></TextBlock>
|
||||
<TextBox x:Name="imageurl" Width="300" Height="50" Text="{Binding ImageInfo.Url}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="提示文本:"></TextBlock>
|
||||
<TextBox x:Name="imagetext" Width="300" Height="50" Text="{Binding ImageInfo.Text}"/>
|
||||
</StackPanel>
|
||||
<MenuItem Header="插入图片" Command="{Binding AddImageCommand}">
|
||||
<MenuItem.CommandParameter>
|
||||
<MultiBinding Converter="{StaticResource ObjectConverter}">
|
||||
<Binding ElementName="imageurl" Path="Text"></Binding>
|
||||
<Binding ElementName="imagetext" Path="Text"></Binding>
|
||||
</MultiBinding>
|
||||
</MenuItem.CommandParameter>
|
||||
</MenuItem>
|
||||
<MenuItem Header="移除已有图片" Command="{Binding RemoveImageCommand}"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton>
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M5,3C3.89,3 3,3.89 3,5V19C3,20.11 3.89,21 5,21H19C20.11,21 21,20.11 21,19V5C21,3.89 20.11,3 19,3H5M5,5H19V19H5V5M7,7V9H17V7H7M7,11V13H17V11H7M7,15V17H14V15H7Z"></Path>
|
||||
<TextBlock>备注</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<TextBox x:Name="remark" Width="300" Height="50" Text="{Binding Remark}"/>
|
||||
<MenuItem Header="插入备注" Command="{Binding AddRemarkCommand}" CommandParameter="{Binding ElementName=remark,Path=Text}"></MenuItem>
|
||||
<MenuItem Header="移除已有备注" Command="{Binding RemoveRemarkCommand}"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Columns="5">
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="#FFC5BDAE"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="Null">
|
||||
<Path Stretch="Uniform" Fill="DarkRed" Data="M966.4 761.6l-140.8 140.8-313.6-320-313.6 320-140.8-140.8 320-313.6-320-313.6 140.8-140.8 313.6 320 313.6-320 140.8 140.8-320 313.6z"></Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Red"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="1">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M700 1125V100H600V1014.8L375 954.5V1058.05L625 1125z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Blue"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="2">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M800 825A200 200 0 1 1 400 825H300A300 300 0 1 0 833.15 636.2L467.15 200.0499999999999L900 200V100H300V156.3499999999999L753.2 696.4499999999999A199.10000000000002 199.10000000000002 0 0 1 800 825z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Green"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="3">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M900 1100V1031.9L640.4499999999999 722.5A325.05 325.05 0 1 0 284.65 321.0999999999999L381.65 345.3999999999999A225.1 225.1 0 0 1 825 400A225 225 0 0 1 499.7500000000001 601.5L488.3500000000001 595.4000000000001L453.8500000000001 655.7500000000001L742.75 1000L325 1000V1100H900z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Orange"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="4">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M800 1125V400H950V300H800V100H700V300H200V355.1L700 1125H800zM700 400V941.45L348.4 400H700z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Purple"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="5">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M900 1100V1000H465.0000000000001L431.1500000000001 677.75A325 325 0 1 0 284.6500000000001 321.1L381.6500000000001 345.4000000000001A225.1 225.1 0 0 1 825 400A225 225 0 0 1 600 625C498.9 625 436.1 593.0500000000001 402 548.5L323.25 607.6L375 1100H900z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Gray"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="6">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M744.3 1100L522.4 715.7A325 325 0 1 0 320 565L628.8000000000001 1100H744.3000000000001zM600 625A225 225 0 1 1 600 175A225 225 0 0 1 600 625z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Gray"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="7">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M950 1100V1025L538.15 100H428.7L829.35 1000H300V1100z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Gray"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="8">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M600 1125A275 275 0 0 0 767.6 632C861.9999999999999 579.5 925 484 925 375C925 209.3 779.5 75 600 75S275 209.3 275 375C275 484.0500000000001 338.05 579.5 432.35 632.05A275 275 0 0 0 600 1125zM600 575C474 575 375 483.6 375 375C375 266.4 474 175 600 175S825 266.4 825 375C825 483.6 726 575 600 575zM600 1025A175 175 0 1 1 600 675A175 175 0 0 1 600 1025z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}"
|
||||
Background="Gray"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddPriorityCommand}"
|
||||
CommandParameter="9">
|
||||
<Path Stretch="Uniform" Fill="White" RenderTransformOrigin="0.5,0.5" Data="M600 1125A325 325 0 0 0 880.95 636.5L571.15 100.05H455.7L677.6500000000001 484.35A325 325 0 1 0 600 1125zM600 1025A225 225 0 1 1 600 575A225 225 0 0 1 600 1025z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<UniformGrid Columns="5">
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="Null">
|
||||
<Path Stretch="Uniform" Fill="DarkRed" Data="m 256,76 c 48.1,0 93.3,18.7 127.3,52.7 34,34 52.7,79.2 52.7,127.3 0,48.1 -18.7,93.3 -52.7,127.3 -34,34 -79.2,52.7 -127.3,52.7 -48.1,0 -93.3,-18.7 -127.3,-52.7 C 94.7,349.3 76,304.1 76,256 76,207.9 94.7,162.7 128.7,128.7 162.7,94.7 207.9,76 256,76 m 0,-28 C 141.1,48 48,141.1 48,256 48,370.9 141.1,464 256,464 370.9,464 464,370.9 464,256 464,141.1 370.9,48 256,48 Z m 75.3,260.7 -52.7,-52.7 52.7,-52.7 c 6.2,-6.2 6.2,-16.4 0,-22.6 -6.2,-6.2 -16.4,-6.2 -22.6,0 L 256,233.4 203.3,180.7 c -6.2,-6.2 -15.6,-7.1 -22.6,0 -7.1,7.1 -6,16.6 0,22.6 l 52.7,52.7 -52.7,52.7 c -6.7,6.7 -6.4,16.3 0,22.6 6.4,6.4 16.4,6.2 22.6,0 l 52.7,-52.7 52.7,52.7 c 6.2,6.2 16.4,6.2 22.6,0 6.3,-6.2 6.3,-16.4 0,-22.6 z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.125">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C13.93 5 15.68 5.78 16.95 7.05L12 12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.25">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12H12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.375">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 13.93 18.22 15.68 16.95 16.95L12 12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.5">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.625">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C10.07 19 8.32 18.22 7.05 16.95L12 12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.75">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C8.13 19 5 15.87 5 12H12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="0.875">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4M12 5C15.87 5 19 8.13 19 12C19 15.87 15.87 19 12 19C8.13 19 5 15.87 5 12C5 10.07 5.78 8.32 7.05 7.05L12 12V5Z"></Path>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatCircleButtonStyle}"
|
||||
Background="Yellow"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Command="{Binding AddRatioCommand}"
|
||||
CommandParameter="1">
|
||||
<Path Stretch="Uniform" Fill="Green" Data="m 256,76 c 48.1,0 93.3,18.7 127.3,52.7 34,34 52.7,79.2 52.7,127.3 0,48.1 -18.7,93.3 -52.7,127.3 -34,34 -79.2,52.7 -127.3,52.7 -48.1,0 -93.3,-18.7 -127.3,-52.7 C 94.7,349.3 76,304.1 76,256 76,207.9 94.7,162.7 128.7,128.7 162.7,94.7 207.9,76 256,76 m 0,-28 C 141.1,48 48,141.1 48,256 48,370.9 141.1,464 256,464 370.9,464 464,370.9 464,256 464,141.1 370.9,48 256,48 Z M 362.6,192.9 345,174.8 c -0.7,-0.8 -1.8,-1.2 -2.8,-1.2 -1.1,0 -2.1,0.4 -2.8,1.2 L 217.4,297.7 173,253.3 c -0.8,-0.8 -1.8,-1.2 -2.8,-1.2 -1,0 -2,0.4 -2.8,1.2 l -17.8,17.8 c -1.6,1.6 -1.6,4.1 0,5.7 l 56,56 c 3.6,3.6 8,5.7 11.7,5.7 5.3,0 9.9,-3.9 11.6,-5.5 H 229 L 362.7,198.6 c 1.4,-1.7 1.4,-4.2 -0.1,-5.7 z"></Path>
|
||||
</Button>
|
||||
</UniformGrid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Grid>
|
||||
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="3">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="txtTag" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent"/>
|
||||
<Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
|
||||
<Button Grid.Column="1" Content="添加" Padding="6,0" Style="{StaticResource FlatButtonStyle}" Command="{Binding AddTagCommand}" CommandParameter="{Binding ElementName=txtTag,Path=Text}"/>
|
||||
<Line X1="0" Y1="0" X2="150" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom" Grid.ColumnSpan="2"></Line>
|
||||
<controls:TagControl Grid.Row="1" Grid.ColumnSpan="2" BorderBrush="Gray" HorizontalAlignment="Left" ItemsSource="{Binding SelectedItem.Tags}" Width="150">
|
||||
<controls:TagControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" x:Name="grid">
|
||||
<TextBlock Text="{Binding .}"/>
|
||||
<Button x:Name="clear" Style="{StaticResource FlatButtonStyle}" Padding="0" Content="X" Command="{Binding DataContext.RemoveTagCommand, RelativeSource={RelativeSource AncestorType={x:Type controls:TagControl}}}" CommandParameter="{Binding .}" Visibility="Collapsed"/>
|
||||
</StackPanel>
|
||||
<DataTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="clear" Property="Visibility" Value="Visible"/>
|
||||
</Trigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</controls:TagControl.ItemTemplate>
|
||||
</controls:TagControl>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="外观" Height="30" Width="50">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ComboBox x:Name="mindtype" dd:EnumHelper.Enum="{x:Type models:MindType}" SelectedItem="{Binding MindType}" Style="{StaticResource FlatComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding .,Converter={StaticResource EnumDescriptionConverter}}" VerticalAlignment="Center" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<ComboBox x:Name="mindtheme" dd:EnumHelper.Enum="{x:Type models:MindTheme}" SelectedItem="{Binding MindTheme}" Style="{StaticResource FlatComboBox2ColumnStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border CornerRadius="3" Background="{Binding .,Converter={StaticResource MindThemeFillBrushConverter}}" Padding="5">
|
||||
<TextBlock Foreground="{Binding .,Converter={StaticResource MindThemeFontBrushConverter}}" Text="{Binding .,Converter={StaticResource EnumDescriptionConverter}}" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding ResetLayoutCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M358.4 0a102.4 102.4 0 0 1 102.4 102.4v819.2a102.4 102.4 0 0 1-102.4 102.4H102.4a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4h256z m0 76.8H102.4a25.6 25.6 0 0 0-25.1904 20.992L76.8 102.4v819.2a25.6 25.6 0 0 0 20.992 25.1904L102.4 947.2h256a25.6 25.6 0 0 0 25.1904-20.992L384 921.6V102.4a25.6 25.6 0 0 0-20.992-25.1904L358.4 76.8z m268.288 547.84a38.4 38.4 0 0 1 50.1248-1.8432l4.1472 3.8912a38.4 38.4 0 0 1 1.8432 50.1248L630.272 742.4h333.7216l4.6592 0.3584c16.7936 2.56 29.696 18.5856 29.696 38.0416 0 21.1968-15.36 38.4-34.3552 38.4h-333.6704l52.4288 65.6384 3.2256 4.6592a38.4 38.4 0 0 1-63.232 43.3152l-102.4-128-3.328-4.9152a38.4 38.4 0 0 1 3.328-43.0592l102.4-128zM921.6 0a102.4 102.4 0 0 1 102.4 102.4v256a102.4 102.4 0 0 1-102.4 102.4h-256a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4h256z m0 76.8h-256a25.6 25.6 0 0 0-25.1904 20.992L640 102.4v256a25.6 25.6 0 0 0 20.992 25.1904L665.6 384h256a25.6 25.6 0 0 0 25.1904-20.992L947.2 358.4V102.4a25.6 25.6 0 0 0-20.992-25.1904L921.6 76.8z"></Path>
|
||||
<TextBlock>整理布局</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.RowSpan="2" Style="{StaticResource FlatButtonStyle}" Command="{Binding ClearThemeCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M719.329882 422.249412l-255.578353 255.578353 234.315295 234.315294 255.518117-255.638588-234.315294-234.255059zM59.151059 315.813647l298.164706-298.164706a60.235294 60.235294 0 0 1 85.172706 0l596.329411 596.329412a60.235294 60.235294 0 0 1 0 85.172706l-298.164706 298.164706a60.235294 60.235294 0 0 1-85.232941 0l-596.329411-596.329412a60.235294 60.235294 0 0 1 0-85.172706z"></Path>
|
||||
<TextBlock>清除样式</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Grid.Column="1" Style="{StaticResource FlatButtonStyle}" Command="{Binding CopyThemeCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M701.248 177.6l175.104-113.024 83.456 114.88-131.136 162.304-127.424-164.16z m-133.376-61.568c51.264 6.976 300.608 346.624 294.272 384.704s-145.536 143.68-145.536 143.68L400.64 238.592s116.032-129.6 167.232-122.56zM370.368 288.448l305.024 396.672-187.136 272L65.664 359.04s83.776-3.84 153.536-24.32c45.632-13.504 151.232-46.272 151.168-46.272z"></Path>
|
||||
<TextBlock>复制样式</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Grid.Column="1" Grid.Row="1" Style="{StaticResource FlatButtonStyle}" Command="{Binding PasteThemeCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="12" Height="12" Stretch="Uniform" Fill="Black" Data="M411.880727 905.169455v-279.272728h149.876364v279.272728z m54.272-279.645091v-124.881455h412.904728V325.771636h-64.605091v116.363637h-698.181819v-279.272728h698.181819v116.363637h111.104v268.055273h-412.904728v78.289454z"></Path>
|
||||
<TextBlock>粘贴样式</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ComboBox x:Name="comboBoxFontName"
|
||||
Width="100"
|
||||
IsTextSearchEnabled="True"
|
||||
ScrollViewer.CanContentScroll="False"
|
||||
ItemsSource="{Binding SelectedItem.FontViewModel.FontFamilys}"
|
||||
SelectedItem="{Binding SelectedItem.FontViewModel.FontFamily}"
|
||||
Style="{StaticResource FlatComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"
|
||||
FontFamily="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<ComboBox x:Name="comboBoxFontSize"
|
||||
Width="50"
|
||||
HorizontalAlignment="Left"
|
||||
IsEditable="True"
|
||||
ItemsSource="{Binding SelectedItem.FontViewModel.FontSizes}"
|
||||
Text="{Binding SelectedItem.FontViewModel.FontSize}"
|
||||
Style="{StaticResource FlatComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<ToggleButton x:Name="buttonBold" Style="{StaticResource FlatToggleButtonStyle}" Width="18" Height="18"
|
||||
IsChecked="{Binding SelectedItem.FontViewModel.FontWeight,Converter={dd:ConverterValueMapToBool Parameter='Regular'}, ConverterParameter='Bold'}">
|
||||
<Path Stretch="Uniform" Margin="2" Fill="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=Foreground}" Data="M214 80Q266 80 299 107 331 134 331 176 331 201 320 222 308 243 291 251L291 253Q319 262 336 284 352 306 352 335 352 377 321 405 290 432 242 432L64 432 64 80 214 80ZM218 224Q239 224 253 211 267 198 267 180 267 164 254 154 240 144 218 144L128 144 128 224 218 224ZM236 368Q258 368 273 357 288 345 288 328 288 309 274 299 259 288 236 288L128 288 128 368 236 368Z"></Path>
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="buttonItalic" Style="{StaticResource FlatToggleButtonStyle}" Width="18" Height="18"
|
||||
IsChecked="{Binding SelectedItem.FontViewModel.FontStyle,Converter={dd:ConverterValueMapToBool Parameter='Normal'}, ConverterParameter='Italic'}">
|
||||
<Path Stretch="Uniform" Margin="2" Fill="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=Foreground}" Data="M320 48v32a16 16 0 0 1-16 16h-62.76l-80 320H208a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h62.76l80-320H112a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16z"></Path>
|
||||
</ToggleButton>
|
||||
<controls:ColorPicker SelectedColor="{Binding SelectedItem.FontViewModel.FontColor}">
|
||||
<controls:ColorPicker.Content>
|
||||
<Grid>
|
||||
<Rectangle VerticalAlignment="Bottom"
|
||||
Height="4"
|
||||
Width="14"
|
||||
HorizontalAlignment="Center">
|
||||
<Rectangle.Fill>
|
||||
<SolidColorBrush Color="{Binding SelectedItem.FontViewModel.FontColor}" />
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<Path Width="14" Height="14" Stretch="Uniform" RenderTransformOrigin="0.5,0.5" Fill="Black" Data="M725 977l-170 -450c99 -1 198 -4 297 -4c19 0 38 1 57 2c-52 152 -113 307 -184 452zM0 -128l2 79c94 29 196 9 238 117l237 616l280 724h128c4 -7 8 -14 11 -21l205 -480c75 -177 144 -356 220 -532c45 -104 80 -211 130 -313c7 -16 21 -46 35 -57 c33 -26 125 -32 172 -50c3 -19 6 -38 6 -57c0 -9 -1 -17 -1 -26c-127 0 -254 16 -381 16c-131 0 -262 -11 -393 -15c0 26 1 52 4 78l131 28c27 6 80 13 80 50c0 36 -129 333 -145 374l-450 2c-26 -58 -127 -320 -127 -358c0 -77 147 -80 204 -88c1 -19 1 -38 1 -58 c0 -9 -1 -18 -2 -27c-116 0 -233 20 -349 20c-14 0 -34 -6 -48 -8c-63 -11 -125 -14 -188 -14z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
|
||||
</Grid>
|
||||
</controls:ColorPicker.Content>
|
||||
</controls:ColorPicker>
|
||||
<controls:ColorPicker SelectedColor="{Binding SelectedItem.ColorViewModel.FillColor.Color}">
|
||||
<controls:ColorPicker.Content>
|
||||
<Grid>
|
||||
<Rectangle VerticalAlignment="Bottom"
|
||||
Height="4"
|
||||
Width="14"
|
||||
HorizontalAlignment="Center">
|
||||
<Rectangle.Fill>
|
||||
<SolidColorBrush Color="{Binding SelectedItem.ColorViewModel.FillColor.Color}" />
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<Path Width="14" Height="14" Stretch="Uniform" RenderTransformOrigin="0.5,0.5" Fill="Black" Data="M853.333 362.667c-3.925-2.731-85.333-88.875-85.333-149.333 0-63.744 40.491-104.448 85.333-106.667 38.656-1.877 85.333 38.016 85.333 106.667 0 64-81.408 146.603-85.333 149.333zM409.003 106.667c16.128-16.128 37.547-25.003 60.331-25.003s44.203 8.875 60.331 25.003l298.667 298.667-456.832 456.832-60.331-60.331 97.835-97.835-238.336-238.336c-16.128-16.128-25.003-37.547-25.003-60.331s8.875-44.203 25.003-60.331l238.336-238.336zM469.333 643.669l238.336-238.336h-476.672l238.336 238.336z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Grid>
|
||||
</controls:ColorPicker.Content>
|
||||
</controls:ColorPicker>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="视图" Height="30" Width="50">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<controls:DropDownButton>
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M877.714286 768c0 21.942857-14.628571 36.571429-36.571429 36.571429h-585.142857c-21.942857 0-36.571429-14.628571-36.571429-36.571429v-585.142857c0-21.942857 14.628571-36.571429 36.571429-36.571429h585.142857c21.942857 0 36.571429 14.628571 36.571429 36.571429v585.142857zM841.142857 73.142857h-585.142857C197.485714 73.142857 146.285714 124.342857 146.285714 182.857143v585.142857c0 58.514286 51.2 109.714286 109.714286 109.714286h585.142857c58.514286 0 109.714286-51.2 109.714286-109.714286v-585.142857c0-58.514286-51.2-109.714286-109.714286-109.714286z m-146.285714 365.714286H585.142857V329.142857c0-21.942857-14.628571-36.571429-36.571428-36.571428s-36.571429 14.628571-36.571429 36.571428V438.857143H402.285714c-21.942857 0-36.571429 14.628571-36.571428 36.571428s14.628571 36.571429 36.571428 36.571429H512v109.714286c0 21.942857 14.628571 36.571429 36.571429 36.571428s36.571429-14.628571 36.571428-36.571428V512h109.714286c21.942857 0 36.571429-14.628571 36.571428-36.571429S716.8 438.857143 694.857143 438.857143z"></Path>
|
||||
<TextBlock>展开</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="展开到一级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="1"/>
|
||||
<MenuItem Header="展开到二级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="2"/>
|
||||
<MenuItem Header="展开到三级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="3"/>
|
||||
<MenuItem Header="展开到四级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="4"/>
|
||||
<MenuItem Header="展开到五级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="5"/>
|
||||
<MenuItem Header="展开到六级节点" Command="{Binding Expand2LevelCommand}" CommandParameter="6"/>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton>
|
||||
<controls:DropDownButton.Content>
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M505.6 454.4l134.4-480 108.8 166.4 204.8-204.8 70.4 70.4-211.2 204.8 172.8 102.4zM512 192h-448v576h768v-345.6l64-12.8v422.4h-896v-704h524.8z"></Path>
|
||||
<TextBlock>全选</TextBlock>
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="全选" Command="{Binding SelectAllCommand}" />
|
||||
<MenuItem Header="反选" Command="{Binding SelectInverseCommand}" />
|
||||
<MenuItem Header="选择兄弟节点" Command="{Binding SelectBrotherCommand}" />
|
||||
<MenuItem Header="选择同级节点" Command="{Binding SelectPearCommand}" />
|
||||
<MenuItem Header="选择路径" Command="{Binding SelectRouteCommand}" />
|
||||
<MenuItem Header="选择子树" Command="{Binding SelectChildCommand}" />
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="4" Command="{Binding CenterMoveCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M256 320c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM405 107v85h43v-85c0 -23 -20 -43 -43 -43h-85v43h85zM405 448c23 0 43 -20 43 -43v-85h-43v85h-85v43h85zM107 405v-85h-43v85c0 23 20 43 43 43h85v-43h-85zM107 192v-85h85v-43h-85 c-23 0 -43 20 -43 43v85h43z"></Path>
|
||||
<TextBlock>居中</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="4" Command="{Binding FitAutoCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M1023.216289 841.246459v9.61262a268.243293 268.243293 0 0 1-1.9339 51.191468 145.725046 145.725046 0 0 1-48.0631 85.66039 153.233128 153.233128 0 0 1-65.126924 31.681831 126.897961 126.897961 0 0 1-40.441259 2.218297H175.769975a293.611509 293.611509 0 0 1-66.776427-3.640282 142.198522 142.198522 0 0 1-100.221518-91.348331A239.291674 239.291674 0 0 1 0.524516 846.081209V193.560629 132.472144a164.950286 164.950286 0 0 1 16.551908-56.253736A147.886463 147.886463 0 0 1 93.806746 8.930067a155.735822 155.735822 0 0 1 26.505805-6.768649L134.077368 0.739432h734.654446a108.070877 108.070877 0 0 1 34.127646 1.421986 152.607454 152.607454 0 0 1 65.980114 29.122257 146.180081 146.180081 0 0 1 51.191468 84.522802 254.819752 254.819752 0 0 1 2.787091 55.116147V841.417097zM942.618167 129.457535a65.126923 65.126923 0 0 0-22.751764-35.322113 53.011609 53.011609 0 0 0-50.395156-13.025385H138.798359l-5.687941 0.568794-13.821696 3.697162a64.956285 64.956285 0 0 0-31.169917 26.847081 120.29995 120.29995 0 0 0-8.816308 61.657279v661.735044a245.548409 245.548409 0 0 0 1.9339 57.391324 63.648059 63.648059 0 0 0 41.920124 44.934733 172.060212 172.060212 0 0 0 45.844804 2.843971h702.858857a54.149197 54.149197 0 0 0 23.661834-1.421986 73.033161 73.033161 0 0 0 29.520413-16.096872 98.515136 98.515136 0 0 0 19.623396-81.166917V174.16475a199.077931 199.077931 0 0 0-2.047658-44.707215z m-116.090874 694.781981a37.085375 37.085375 0 0 1-19.850914 20.362828h-0.511915a36.232184 36.232184 0 0 1-13.366661 2.730212H597.75831a36.516581 36.516581 0 0 1-31.681831-18.713326 38.052325 38.052325 0 0 1 0-37.369772 36.516581 36.516581 0 0 1 31.681831-18.713325h106.762651l-120.413709-123.030162a37.881686 37.881686 0 0 1-9.953897-36.345942 36.914736 36.914736 0 0 1 26.107649-26.676443 35.890907 35.890907 0 0 1 35.549631 10.181414l120.413708 123.030162v-109.151586a37.54041 37.54041 0 0 1 18.258291-32.364384 36.004666 36.004666 0 0 1 36.57346 0 37.54041 37.54041 0 0 1 18.25829 32.364384v199.419208a37.199133 37.199133 0 0 1-2.559573 13.594179zM402.775696 249.359329H296.297442l120.35683 123.087041a37.938566 37.938566 0 0 1 9.498861 36.118425 36.971616 36.971616 0 0 1-25.880131 26.448925 36.004666 36.004666 0 0 1-35.322113-9.6695L244.59406 302.2003v109.151586a37.654169 37.654169 0 0 1-18.31517 32.421263 36.004666 36.004666 0 0 1-36.57346 0 37.711048 37.711048 0 0 1-18.25829-32.421263V211.989557a36.857857 36.857857 0 0 1 2.616452-13.594178v-0.625674a36.914736 36.914736 0 0 1 19.907794-20.305949h0.568794a34.525801 34.525801 0 0 1 13.309781-2.673332h195.039494a36.459701 36.459701 0 0 1 31.681831 18.656446 38.166083 38.166083 0 0 1 0 37.426651 36.459701 36.459701 0 0 1-31.79559 18.485808z">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleY="-1"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<TextBlock>适应窗口大小</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="4" Command="{Binding FitWidthCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M113.777 819.198 113.777 204.8c0-50.267 40.75-91.022 91.02-91.022l614.376 0c50.29 0 91.045 40.755 91.045 91.022l0 614.398c0 50.27-40.755 91.02-91.045 91.02L204.797 910.218C154.527 910.218 113.777 869.468 113.777 819.198zM796.438 841.953c25.125 0 45.51-20.385 45.51-45.51L841.948 227.554c0-25.122-20.385-45.51-45.505-45.51L227.552 182.044c-25.125 0-45.535 20.387-45.535 45.51l0 568.889c0 25.125 20.39 45.51 45.535 45.51L796.438 841.953zM623.043 603.269l57.115-57.14L344.357 546.129l55.5 55.505c13.31 13.335 13.335 34.93 0 48.265-13.335 13.33-34.95 13.33-48.29 0l-105.765-105.77c-3.415-1.615-6.78-3.525-9.625-6.37-7.08-7.1-10.1-16.475-9.67-25.76-0.46-9.262 2.59-18.66 9.69-25.76 2.85-2.842 6.15-4.8 9.58-6.348l105.79-105.79c13.34-13.335 34.955-13.335 48.29 0 13.31 13.332 13.335 34.927 0 48.262l-55.5 55.502 335.802 0-57.115-57.117c-13.355-13.335-13.335-34.952 0-48.287s34.93-13.335 48.265 0l115.37 115.395c13.335 13.332 13.36 34.927 0 48.262l-115.37 115.395c-13.335 13.335-34.95 13.335-48.265 0C609.708 638.198 609.708 616.583 623.043 603.269z"></Path>
|
||||
<TextBlock>适应窗口宽度</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="4" Command="{Binding FitHeightCommand}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M819.198 910.218 204.799 910.218c-50.267 0-91.022-40.75-91.022-91.02L113.777 204.822c0-50.29 40.755-91.045 91.022-91.045l614.398 0c50.27 0 91.02 40.755 91.02 91.045l0 614.376C910.218 869.468 869.468 910.218 819.198 910.218zM841.953 227.554c0-25.122-20.385-45.51-45.51-45.51L227.554 182.044c-25.122 0-45.51 20.387-45.51 45.51l0 568.889c0 25.125 20.387 45.535 45.51 45.535l568.889 0c25.125 0 45.51-20.39 45.51-45.535L841.953 227.554zM603.268 400.952l-57.14-57.115 0 335.802 55.505-55.5c13.335-13.31 34.93-13.335 48.265 0 13.33 13.335 13.33 34.95 0 48.29l-105.77 105.765c-1.615 3.415-3.525 6.78-6.37 9.625-7.1 7.08-16.475 10.1-25.76 9.67-9.262 0.46-18.66-2.59-25.76-9.69-2.842-2.85-4.8-6.15-6.347-9.58l-105.79-105.79c-13.335-13.34-13.335-34.955 0-48.29 13.332-13.31 34.927-13.335 48.262 0l55.502 55.5L477.865 343.837l-57.117 57.115c-13.335 13.357-34.952 13.335-48.287 0s-13.335-34.93 0-48.265l115.395-115.37c13.332-13.335 34.927-13.357 48.262 0l115.395 115.37c13.335 13.335 13.335 34.952 0 48.265C638.198 414.286 616.583 414.286 603.268 400.952z"></Path>
|
||||
<TextBlock>适应窗口高度</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<Line Margin="2,0" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
|
||||
<StackPanel>
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M911.958045 890.721335l-241.415018-246.54112a336.369964 336.369964 0 1 0-58.095828 45.158522l247.029321 252.643623a36.859118 36.859118 0 0 0 51.749225 0 37.103218 37.103218 0 0 0 0.7323-51.261025zM176.240286 404.473897a261.431228 261.431228 0 1 1 261.431228 261.431228A261.675328 261.675328 0 0 1 176.240286 404.473897z"></Path>
|
||||
<TextBlock>搜索</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
26
Extensions/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml.cs
Normal file
26
Extensions/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace AIStudio.Wpf.Mind.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// ToolBoxControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ToolBoxControl : UserControl
|
||||
{
|
||||
public ToolBoxControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user