mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-05 00:37:19 +08:00
mind
This commit is contained in:
@@ -17,6 +17,8 @@ using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using AIStudio.Wpf.DiagramDesigner.Additionals;
|
||||
using AIStudio.Wpf.DiagramDesigner.Additionals.Commands;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramApp.ViewModels
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ using System.Xml.Serialization;
|
||||
using AIStudio.Wpf.DiagramDesigner;
|
||||
using ZXing;
|
||||
using AIStudio.Wpf.DiagramDesigner.Helpers;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramApp.ViewModels
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@ using AIStudio.Wpf.SFC.Models;
|
||||
using System.Windows;
|
||||
using System;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramApp.ViewModels
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Icon="A.ico"
|
||||
Identifier="RootWindow"
|
||||
Style="{StaticResource AIStudio.Styles.WindowBase}"
|
||||
Height="600" Width="850">
|
||||
Height="800" Width="1000">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Company>AIStudio.Wpf.Controls</Company>
|
||||
<Company> AIStudio.Wpf.DiagramDesigner.Controls</Company>
|
||||
<Authors>akwkevin</Authors>
|
||||
<PackageProjectUrl>https://gitee.com/akwkevin</PackageProjectUrl>
|
||||
<PackageIcon>A.png</PackageIcon>
|
||||
|
||||
@@ -6,6 +6,8 @@ using System.Windows.Media;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
|
||||
@@ -14,6 +14,8 @@ using System.Windows.Resources;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
|
||||
27
AIStudio.Wpf.DiagramDesigner/Converters/AditionConverter.cs
Normal file
27
AIStudio.Wpf.DiagramDesigner/Converters/AditionConverter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class AdditionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if ((value != null) && (parameter != null))
|
||||
{
|
||||
var firstValue = (double)value;
|
||||
var secondValue = double.Parse(parameter?.ToString());
|
||||
|
||||
return firstValue + secondValue;
|
||||
}
|
||||
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public class GridLengthConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var length = value?.ToString();
|
||||
try
|
||||
{
|
||||
double add = 0;
|
||||
double.TryParse(parameter?.ToString(), out add);
|
||||
return new GridLength(double.Parse(length) + add, GridUnitType.Pixel);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new GridLength(1, GridUnitType.Auto);
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
}
|
||||
|
||||
public class GridLengthAutoConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var length = value?.ToString();
|
||||
try
|
||||
{
|
||||
if (Regex.IsMatch(length, @"^\d+(\.\d+)?$"))
|
||||
{
|
||||
return new GridLength(double.Parse(length), GridUnitType.Pixel);
|
||||
}
|
||||
else if (length == "*")
|
||||
{
|
||||
return new GridLength(1, GridUnitType.Star);
|
||||
}
|
||||
else if (Regex.IsMatch(length, @"^\d+(\.\d+)?\*$"))
|
||||
{
|
||||
return new GridLength(double.Parse(length.Substring(0, length.Length - 1)), GridUnitType.Star);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GridLength(1, GridUnitType.Auto);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new GridLength(1, GridUnitType.Auto);
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
namespace AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple service locator
|
||||
@@ -18,14 +18,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
_drawModeViewModel = new DrawModeViewModel();
|
||||
_quickThemeViewModel = new QuickThemeViewModel();
|
||||
|
||||
|
||||
_drawModeViewModel.PropertyChanged += ViewModel_PropertyChanged;
|
||||
_quickThemeViewModel.PropertyChanged += ViewModel_PropertyChanged;
|
||||
|
||||
SetOldValue<IColorViewModel>(ColorViewModel, nameof(ColorViewModel));
|
||||
SetOldValue<IFontViewModel>(FontViewModel, nameof(FontViewModel));
|
||||
SetOldValue<IShapeViewModel>(ShapeViewModel, nameof(ShapeViewModel));
|
||||
SetOldValue<ILockObjectViewModel>(LockObjectViewModel, nameof(LockObjectViewModel));
|
||||
SetOldValue(ColorViewModel, nameof(ColorViewModel));
|
||||
SetOldValue(FontViewModel, nameof(FontViewModel));
|
||||
SetOldValue(ShapeViewModel, nameof(ShapeViewModel));
|
||||
SetOldValue(LockObjectViewModel, nameof(LockObjectViewModel));
|
||||
}
|
||||
|
||||
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
@@ -70,7 +70,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
_colorViewModel.PropertyChanged += ViewModel_PropertyChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IFontViewModel _fontViewModel;
|
||||
public IFontViewModel FontViewModel
|
||||
@@ -117,13 +117,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
private IDrawModeViewModel _drawModeViewModel;
|
||||
public IDrawModeViewModel DrawModeViewModel
|
||||
{
|
||||
get { return _drawModeViewModel; }
|
||||
get
|
||||
{
|
||||
return _drawModeViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private IQuickThemeViewModel _quickThemeViewModel;
|
||||
public IQuickThemeViewModel QuickThemeViewModel
|
||||
{
|
||||
get { return _quickThemeViewModel; }
|
||||
get
|
||||
{
|
||||
return _quickThemeViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private ILockObjectViewModel _lockObjectViewModel;
|
||||
@@ -161,7 +167,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
return _selectedItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
{
|
||||
if (SetProperty(ref _selectedItem, value))
|
||||
{
|
||||
if (_selectedItem == null)
|
||||
@@ -198,12 +204,18 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
public IDiagramServiceProvider Provider
|
||||
{
|
||||
get { return serviceProvider; }
|
||||
get
|
||||
{
|
||||
return serviceProvider;
|
||||
}
|
||||
}
|
||||
|
||||
public static DiagramServicesProvider Instance
|
||||
{
|
||||
get { return instance.Value; }
|
||||
get
|
||||
{
|
||||
return instance.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using System.Text;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using AIStudio.Wpf.DiagramDesigner.Models;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels;
|
||||
using AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
namespace AIStudio.Wpf.DiagramDesigner.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple service interface
|
||||
549
AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml
Normal file
549
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
AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs
Normal file
597
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
AIStudio.Wpf.Mind/Controls/ColorItem.cs
Normal file
37
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
400
AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
Normal file
400
AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
Normal file
@@ -0,0 +1,400 @@
|
||||
<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">M0,0 L3,0 4.5,1.5 6,0 9,0 4.5,4.5 z</Geometry>
|
||||
|
||||
<Style x:Key="ColorPickerToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid SnapsToDevicePixels="True">
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
|
||||
<ContentPresenter Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
|
||||
</Border>
|
||||
|
||||
<Grid x:Name="arrowGlyph" Grid.Column="1" Margin="5">
|
||||
<Path x:Name="Arrow"
|
||||
Width="9"
|
||||
Height="5"
|
||||
Data="{StaticResource DownArrowGeometry}"
|
||||
Fill="#FF000000"
|
||||
Margin="0,1,0,0"/>
|
||||
</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>
|
||||
<DataTrigger Binding="{Binding DisplayColorAndName, RelativeSource={RelativeSource AncestorType={x:Type controls:ColorPicker}}}"
|
||||
Value="False">
|
||||
<Setter Property="ToolTip"
|
||||
Value="{x:Static sys:String.Empty}"
|
||||
TargetName="mainGrid" />
|
||||
</DataTrigger>
|
||||
</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"
|
||||
HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
RecognizesAccessKey="True"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
||||
</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="1" />
|
||||
<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="3,0" />
|
||||
<Setter Property="DisplayColorAndName" Value="True"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type controls:ColorPicker}">
|
||||
<Grid x:Name="PART_Root">
|
||||
<Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||
CornerRadius="3"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"/>
|
||||
|
||||
<Grid x:Name="PART_InnerGrid" Margin="{TemplateBinding Padding}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="0" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid>
|
||||
<ContentControl x:Name="ColorOnly" Style="{StaticResource ColorDisplayStyle}" />
|
||||
|
||||
<Border x:Name="ColorAndName" Background="White" Visibility="Hidden">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ContentControl HorizontalAlignment="Left" Width="20" Margin="2,1,4,1" Style="{StaticResource ColorDisplayStyle}" BorderThickness="1" BorderBrush="#FFC9CACA" />
|
||||
<TextBlock Text="{Binding SelectedColorText, RelativeSource={RelativeSource TemplatedParent}}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!--下拉按钮-->
|
||||
<ToggleButton x:Name="PART_ColorPickerToggleButton" Panel.ZIndex="1" IsTabStop="False" Style="{StaticResource ColorPickerToggleButtonStyle}"
|
||||
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||
Grid.Column="0" Grid.ColumnSpan="2" Margin="0"
|
||||
Foreground="{TemplateBinding BorderBrush}"/>
|
||||
|
||||
</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="DisplayColorAndName" Value="True">
|
||||
<Setter TargetName="ColorOnly" Property="Visibility" Value="Collapsed" />
|
||||
<Setter TargetName="ColorAndName" Property="Visibility" Value="Visible" />
|
||||
</Trigger>
|
||||
|
||||
<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>
|
||||
811
AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
Normal file
811
AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
Normal file
@@ -0,0 +1,811 @@
|
||||
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 DisplayColorAndName
|
||||
|
||||
public static readonly DependencyProperty DisplayColorAndNameProperty = DependencyProperty.Register("DisplayColorAndName", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false));
|
||||
public bool DisplayColorAndName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(DisplayColorAndNameProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(DisplayColorAndNameProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //DisplayColorAndName
|
||||
|
||||
#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
|
||||
|
||||
#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
AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs
Normal file
45
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
AIStudio.Wpf.Mind/Controls/ColorSorter.cs
Normal file
57
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
AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs
Normal file
97
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
AIStudio.Wpf.Mind/Controls/ColorUtilities.cs
Normal file
202
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,15 @@
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
<Style x:Key="LinkControlStyle" TargetType="{x:Type controls:LinkControl}">
|
||||
<Setter Property="Foreground" Value="Gray"/>
|
||||
<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}">
|
||||
@@ -24,12 +32,15 @@
|
||||
Command="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Command}"
|
||||
CommandParameter="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandParameter}"
|
||||
CommandTarget="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=CommandTarget}">
|
||||
<Path Width="18" Height="18" Stretch="Uniform" Fill="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Foreground}"
|
||||
<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>
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<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}">
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<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}">
|
||||
|
||||
@@ -4,11 +4,50 @@
|
||||
|
||||
|
||||
<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}">
|
||||
<Grid>
|
||||
</Grid>
|
||||
<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>
|
||||
|
||||
@@ -3,15 +3,98 @@
|
||||
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
|
||||
|
||||
|
||||
<Style x:Key="TagControlStyle" TargetType="{x:Type controls:TagControl}">
|
||||
<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}">
|
||||
<Grid>
|
||||
</Grid>
|
||||
<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}" />
|
||||
|
||||
@@ -19,24 +19,21 @@ namespace AIStudio.Wpf.Mind.Controls
|
||||
/// <summary>
|
||||
/// TagControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public class TagControl : Control
|
||||
public class TagControl : ItemsControl
|
||||
{
|
||||
static TagControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(TagControl), new FrameworkPropertyMetadata(typeof(TagControl)));
|
||||
}
|
||||
|
||||
/// <summary>Identifies the <see cref="Tags"/> dependency property.</summary>
|
||||
public static readonly DependencyProperty TagsProperty
|
||||
= DependencyProperty.Register(nameof(Tags), typeof(ObservableCollection<string>), typeof(TagControl));
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the "popup" menu for this control is currently open
|
||||
/// </summary>
|
||||
public ObservableCollection<string> Tags
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
{
|
||||
get => (ObservableCollection<string>)this.GetValue(TagsProperty);
|
||||
set => this.SetValue(TagsProperty, (ObservableCollection<string>)value);
|
||||
return new ContentControl();
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item)
|
||||
{
|
||||
return item is ContentControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +131,8 @@
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="插入图片"></MenuItem>
|
||||
<MenuItem Header="移除已有图片"></MenuItem>
|
||||
<MenuItem Header="插入图片" Command="{Binding AddImageCommand}"></MenuItem>
|
||||
<MenuItem Header="移除已有图片" Command="{Binding RemoveImageCommand}"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
<controls:DropDownButton>
|
||||
@@ -143,8 +143,8 @@
|
||||
</StackPanel>
|
||||
</controls:DropDownButton.Content>
|
||||
<controls:DropDownButton.Items>
|
||||
<MenuItem Header="插入备注"></MenuItem>
|
||||
<MenuItem Header="移除已有备注"></MenuItem>
|
||||
<MenuItem Header="插入备注" Command="{Binding AddRemarkCommand}"></MenuItem>
|
||||
<MenuItem Header="移除已有备注" Command="{Binding RemoveRemarkCommand}"></MenuItem>
|
||||
</controls:DropDownButton.Items>
|
||||
</controls:DropDownButton>
|
||||
</UniformGrid>
|
||||
@@ -345,6 +345,39 @@
|
||||
<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>
|
||||
<Grid Grid.Column="13" >
|
||||
<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>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="外观">
|
||||
@@ -444,7 +477,7 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
<Line Grid.Column="7" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Grid Grid.Column="8" DataContext="{Binding SelectedItem.FontViewModel}">
|
||||
<Grid Grid.Column="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
@@ -456,8 +489,8 @@
|
||||
BorderBrush="Gainsboro"
|
||||
IsTextSearchEnabled="True"
|
||||
ScrollViewer.CanContentScroll="False"
|
||||
ItemsSource="{Binding FontFamilys}"
|
||||
SelectedItem="{Binding FontFamily}">
|
||||
ItemsSource="{Binding SelectedItem.FontViewModel.FontFamilys}"
|
||||
SelectedItem="{Binding SelectedItem.FontViewModel.FontFamily}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"
|
||||
@@ -471,8 +504,8 @@
|
||||
Height="22"
|
||||
BorderBrush="Gainsboro"
|
||||
IsEditable="True"
|
||||
ItemsSource="{Binding FontSizes}"
|
||||
Text="{Binding FontSize}">
|
||||
ItemsSource="{Binding SelectedItem.FontViewModel.FontSizes}"
|
||||
Text="{Binding SelectedItem.FontViewModel.FontSize}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"/>
|
||||
@@ -482,13 +515,15 @@
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<ToggleButton x:Name="buttonBold" Style="{StaticResource FlatToggleButtonStyle}" Width="18" Height="18"
|
||||
IsChecked="{Binding FontWeight,Converter={dd:ConverterValueMapToBool Parameter='Regular'}, ConverterParameter='Bold'}">
|
||||
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 FontStyle,Converter={dd:ConverterValueMapToBool Parameter='Normal'}, ConverterParameter='Italic'}">
|
||||
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 SelectedColor="{Binding SelectedItem.ColorViewModel.FillColor.Color}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -571,7 +606,7 @@
|
||||
<TextBlock>适应窗口高度</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<Line Grid.Column="4" X1="0" Y1="0" X2="0" Y2="100" StrokeDashArray="1" Stroke="Gray" StrokeThickness="1"></Line>
|
||||
<Button Style="{StaticResource FlatButtonStyle}" Grid.Column="5" Command="{Binding AddChildCommand}">
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/RateControl.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/RemarkControl.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/TagControl.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/ColorCanvas.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Controls/ColorPicker.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -57,40 +57,45 @@
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<Grid IsHitTestVisible="{Binding IsEditing}">
|
||||
<Grid>
|
||||
<Border BorderThickness="{Binding BorderThickness}"
|
||||
BorderBrush="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
Background="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
|
||||
CornerRadius="{Binding CornerRadius}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Image x:Name="image" Source="{Binding Icon}" Stretch="Fill" Width="64" Height="64" Visibility="Collapsed"/>
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:RateControl Grid.Column="0" Width="20" Height="20" Rate="{Binding Rate}"
|
||||
Visibility="{Binding Rate,Converter={StaticResource NullableToVisibilityConverter}}"/>
|
||||
<controls:PriorityControl Grid.Column="1" Width="20" Height="20" Priority="{Binding Priority}"
|
||||
Visibility="{Binding Priority,Converter={StaticResource NullableToVisibilityConverter}}"/>
|
||||
<dd:TextControl Grid.Column="2" />
|
||||
<controls:LinkControl Grid.Column="3"
|
||||
CornerRadius="{Binding CornerRadius}"
|
||||
IsHitTestVisible="False">
|
||||
</Border>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Image x:Name="image" Source="{Binding Icon}" Stretch="Fill" Width="64" Height="64" Visibility="Collapsed" IsHitTestVisible="False"/>
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:RateControl Grid.Column="0" Rate="{Binding Rate}"
|
||||
Visibility="{Binding Rate,Converter={StaticResource NullableToVisibilityConverter}}"
|
||||
IsHitTestVisible="False"/>
|
||||
<controls:PriorityControl Grid.Column="1" Priority="{Binding Priority}"
|
||||
Visibility="{Binding Priority,Converter={StaticResource NullableToVisibilityConverter}}"
|
||||
IsHitTestVisible="False"/>
|
||||
<dd:TextControl Grid.Column="2" IsHitTestVisible="{Binding IsEditing}"/>
|
||||
<controls:LinkControl Grid.Column="3"
|
||||
Visibility="{Binding LinkInfo,Converter={StaticResource NullableToVisibilityConverter}}"
|
||||
Url="{Binding LinkInfo.Url}"
|
||||
ToolTip="{Binding LinkInfo.Text}" IsHitTestVisible="True"/>
|
||||
<controls:RemarkControl Grid.Column="4"/>
|
||||
<controls:TagControl Grid.Column="5"/>
|
||||
</Grid>
|
||||
ToolTip="{Binding LinkInfo.Text}" />
|
||||
<controls:RemarkControl Grid.Column="4"
|
||||
Visibility="{Binding Remark,Converter={StaticResource NullableToVisibilityConverter}}"
|
||||
ToolTip="{Binding Remark}"/>
|
||||
<controls:TagControl Grid.Column="5" IsHitTestVisible="False" ItemsSource="{Binding Tags}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ToggleButton x:Name="toggle" IsChecked="{Binding IsExpanded}" Style="{StaticResource ExpandCollapseToggleStyle}" HorizontalAlignment="Left" Margin="-15,0,0,0" Visibility="{Binding Children.Count,Converter={StaticResource IntToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
|
||||
@@ -219,6 +219,15 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleCommand _removeTagCommand;
|
||||
public SimpleCommand RemoveTagCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._removeTagCommand ?? (this._removeTagCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveTagCommand));
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleCommand _changeMindTypeCommand;
|
||||
public SimpleCommand ChangeMindTypeCommand
|
||||
{
|
||||
@@ -645,12 +654,12 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
|
||||
private void ExecuteAddRemarkCommand(object obj)
|
||||
{
|
||||
|
||||
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Remark = "备注");
|
||||
}
|
||||
|
||||
private void ExecuteRemoveRemarkCommand(object obj)
|
||||
{
|
||||
|
||||
SelectedItems.OfType<MindNode>().ToList().ForEach(p => p.Remark = null);
|
||||
}
|
||||
|
||||
private void ExecuteAddPriorityCommand(object obj)
|
||||
@@ -679,12 +688,16 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
|
||||
private void ExecuteAddTagCommand(object obj)
|
||||
{
|
||||
|
||||
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
|
||||
p.Tags.Add(obj?.ToString());
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecuteRemoveTagCommand(object obj)
|
||||
{
|
||||
|
||||
SelectedItems.OfType<MindNode>().ToList().ForEach(p => {
|
||||
p.Tags.Remove(obj?.ToString());
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecutedChangeMindTypeCommand(object obj)
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
MoveForwardCommand = (Root as IMindDiagramViewModel)?.MoveForwardCommand;
|
||||
MoveBackCommand = (Root as IMindDiagramViewModel)?.MoveBackCommand;
|
||||
BuildMenuOptions();
|
||||
Tags = new ObservableCollection<string>();
|
||||
}
|
||||
|
||||
public void InitLayout(bool initAppearance)
|
||||
@@ -300,7 +301,36 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_tags != null)
|
||||
{
|
||||
_tags.CollectionChanged -= _tags_CollectionChanged;
|
||||
}
|
||||
SetProperty(ref _tags, value);
|
||||
if (_tags != null)
|
||||
{
|
||||
_tags.CollectionChanged += _tags_CollectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void _tags_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var item in e.NewItems.OfType<string>())
|
||||
{
|
||||
var width = GetTextDisplayWidthHelper.GetTextDisplayWidth(item, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, 12) + 6;
|
||||
ItemWidth += width;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var item in e.OldItems.OfType<string>())
|
||||
{
|
||||
var width = GetTextDisplayWidthHelper.GetTextDisplayWidth(item, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, 12) + 6;
|
||||
ItemWidth -= width;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -473,6 +503,24 @@ namespace AIStudio.Wpf.Mind.ViewModels
|
||||
ItemWidth = Math.Max(ItemWidth, GetTextDisplayWidthHelper.GetTextDisplayWidth(Text, new FontFamily(FontViewModel.FontFamily), FontViewModel.FontStyle, FontViewModel.FontWeight, FontViewModel.FontStretch, FontViewModel.FontSize) + 30);
|
||||
break;
|
||||
}
|
||||
case nameof(Rate):
|
||||
case nameof(Priority):
|
||||
case nameof(LinkInfo):
|
||||
case nameof(Remark):
|
||||
{
|
||||
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
|
||||
{
|
||||
if (valuePropertyChangedEventArgs.OldValue == null && valuePropertyChangedEventArgs.NewValue != null)
|
||||
{
|
||||
ItemWidth += 24;
|
||||
}
|
||||
else if (valuePropertyChangedEventArgs.OldValue != null && valuePropertyChangedEventArgs.NewValue == null)
|
||||
{
|
||||
ItemWidth -= 24;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user