diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
index 3e4e033..3b7c51f 100644
--- a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
+++ b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
@@ -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
{
diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs
index 5f405c4..eb5803b 100644
--- a/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs
+++ b/AIStudio.Wpf.DiagramApp/ViewModels/PageViewModel.cs
@@ -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
{
diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs
index 8dd88f5..a7bae62 100644
--- a/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs
+++ b/AIStudio.Wpf.DiagramApp/ViewModels/ToolBoxViewModel.cs
@@ -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
{
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml b/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml
index 5008c8e..e4f0d8d 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/MainWindow.xaml
@@ -9,7 +9,7 @@
Icon="A.ico"
Identifier="RootWindow"
Style="{StaticResource AIStudio.Styles.WindowBase}"
- Height="600" Width="850">
+ Height="800" Width="1000">
diff --git a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj
index 0b20917..fc20e18 100644
--- a/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj
+++ b/AIStudio.Wpf.DiagramDesigner/AIStudio.Wpf.DiagramDesigner.csproj
@@ -2,7 +2,7 @@
true
- AIStudio.Wpf.Controls
+ AIStudio.Wpf.DiagramDesigner.Controls
akwkevin
https://gitee.com/akwkevin
A.png
diff --git a/AIStudio.Wpf.DiagramDesigner/Adorners/RubberbandAdorner.cs b/AIStudio.Wpf.DiagramDesigner/Adorners/RubberbandAdorner.cs
index 2466d20..573d5b2 100644
--- a/AIStudio.Wpf.DiagramDesigner/Adorners/RubberbandAdorner.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Adorners/RubberbandAdorner.cs
@@ -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
{
diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs
index 04872b1..6a0060d 100644
--- a/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Controls/DesignerCanvas.cs
@@ -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
{
diff --git a/AIStudio.Wpf.DiagramDesigner/Converters/AditionConverter.cs b/AIStudio.Wpf.DiagramDesigner/Converters/AditionConverter.cs
new file mode 100644
index 0000000..1e0fca8
--- /dev/null
+++ b/AIStudio.Wpf.DiagramDesigner/Converters/AditionConverter.cs
@@ -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();
+ }
+ }
+}
diff --git a/AIStudio.Wpf.DiagramDesigner/Converters/GridLengthConverter.cs b/AIStudio.Wpf.DiagramDesigner/Converters/GridLengthConverter.cs
new file mode 100644
index 0000000..f29ad7a
--- /dev/null
+++ b/AIStudio.Wpf.DiagramDesigner/Converters/GridLengthConverter.cs
@@ -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;
+ }
+ }
+}
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/DiagramServicesProvider.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramServicesProvider.cs
similarity index 90%
rename from AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/DiagramServicesProvider.cs
rename to AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramServicesProvider.cs
index 90e08fb..e579807 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/DiagramServicesProvider.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramServicesProvider.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
-namespace AIStudio.Wpf.DiagramDesigner
+namespace AIStudio.Wpf.DiagramDesigner.ViewModels.BaseViewModel
{
///
/// 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(ColorViewModel, nameof(ColorViewModel));
- SetOldValue(FontViewModel, nameof(FontViewModel));
- SetOldValue(ShapeViewModel, nameof(ShapeViewModel));
- SetOldValue(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;
+ }
}
}
}
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs
index ba5d57c..fda6d07 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/SelectableViewModelBase.cs
@@ -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
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IDiagramServiceProvider.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramServiceProvider.cs
similarity index 95%
rename from AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IDiagramServiceProvider.cs
rename to AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramServiceProvider.cs
index 8934d26..6d82f1d 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/AdditionViewModel/Interface/IDiagramServiceProvider.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramServiceProvider.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
-namespace AIStudio.Wpf.DiagramDesigner
+namespace AIStudio.Wpf.DiagramDesigner.ViewModels
{
///
/// Simple service interface
diff --git a/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml b/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml
new file mode 100644
index 0000000..30840df
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml
@@ -0,0 +1,549 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs b/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs
new file mode 100644
index 0000000..7dcabd8
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorCanvas.xaml.cs
@@ -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 args = new RoutedPropertyChangedEventArgs(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 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), typeof(ColorCanvas));
+ public event RoutedPropertyChangedEventHandler 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
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorItem.cs b/AIStudio.Wpf.Mind/Controls/ColorItem.cs
new file mode 100644
index 0000000..45cedce
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorItem.cs
@@ -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();
+ }
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml b/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
new file mode 100644
index 0000000..c63d1e2
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml
@@ -0,0 +1,400 @@
+
+
+
+
+
+ M0,0 L3,0 4.5,1.5 6,0 9,0 4.5,4.5 z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs b/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
new file mode 100644
index 0000000..7c530c4
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorPicker.xaml.cs
@@ -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), typeof(ColorPicker), new UIPropertyMetadata(CreateAvailableColors()));
+ public ObservableCollection AvailableColors
+ {
+ get
+ {
+ return (ObservableCollection)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), typeof(ColorPicker), new UIPropertyMetadata(null));
+ public ObservableCollection RecentColors
+ {
+ get
+ {
+ return (ObservableCollection)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 args = new RoutedPropertyChangedEventArgs(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), typeof(ColorPicker), new UIPropertyMetadata(CreateStandardColors()));
+ public ObservableCollection StandardColors
+ {
+ get
+ {
+ return (ObservableCollection)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();
+#else
+ this.SetCurrentValue(ColorPicker.RecentColorsProperty, new ObservableCollection());
+#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), typeof(ColorPicker));
+ public event RoutedPropertyChangedEventHandler 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 CreateStandardColors()
+ {
+ ObservableCollection standardColors = new ObservableCollection();
+ 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 CreateAvailableColors()
+ {
+ ObservableCollection standardColors = new ObservableCollection();
+
+ 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));
+ }
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs b/AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs
new file mode 100644
index 0000000..961b5c2
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorPickerTabItem.cs
@@ -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;
+ }
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorSorter.cs b/AIStudio.Wpf.Mind/Controls/ColorSorter.cs
new file mode 100644
index 0000000..d30aed7
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorSorter.cs
@@ -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;
+ }
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs b/AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs
new file mode 100644
index 0000000..a54423d
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorSpectrumSlider.cs
@@ -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 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
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/ColorUtilities.cs b/AIStudio.Wpf.Mind/Controls/ColorUtilities.cs
new file mode 100644
index 0000000..0d48ecd
--- /dev/null
+++ b/AIStudio.Wpf.Mind/Controls/ColorUtilities.cs
@@ -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 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 GetKnownColors()
+ {
+ var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
+ return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null));
+ }
+
+ ///
+ /// Converts an RGB color to an HSV color.
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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
+ };
+ }
+
+ ///
+ /// Converts an HSV color to an RGB color.
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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)));
+ }
+
+ ///
+ /// Generates a list of colors with hues ranging from 0 360 and a saturation and value of 1.
+ ///
+ ///
+ public static List GenerateHsvSpectrum()
+ {
+ List colorsList = new List(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;
+ }
+ }
+}
diff --git a/AIStudio.Wpf.Mind/Controls/LinkControl.xaml b/AIStudio.Wpf.Mind/Controls/LinkControl.xaml
index 1cd2d9f..15132fc 100644
--- a/AIStudio.Wpf.Mind/Controls/LinkControl.xaml
+++ b/AIStudio.Wpf.Mind/Controls/LinkControl.xaml
@@ -4,7 +4,15 @@
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls">
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs b/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs
index d526d55..18ff3cc 100644
--- a/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs
+++ b/AIStudio.Wpf.Mind/Controls/TagControl.xaml.cs
@@ -19,24 +19,21 @@ namespace AIStudio.Wpf.Mind.Controls
///
/// TagControl.xaml 的交互逻辑
///
- public class TagControl : Control
+ public class TagControl : ItemsControl
{
static TagControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TagControl), new FrameworkPropertyMetadata(typeof(TagControl)));
}
- /// Identifies the dependency property.
- public static readonly DependencyProperty TagsProperty
- = DependencyProperty.Register(nameof(Tags), typeof(ObservableCollection), typeof(TagControl));
-
- ///
- /// Whether or not the "popup" menu for this control is currently open
- ///
- public ObservableCollection Tags
+ protected override DependencyObject GetContainerForItemOverride()
{
- get => (ObservableCollection)this.GetValue(TagsProperty);
- set => this.SetValue(TagsProperty, (ObservableCollection)value);
+ return new ContentControl();
+ }
+
+ protected override bool IsItemItsOwnContainerOverride(object item)
+ {
+ return item is ContentControl;
}
}
}
diff --git a/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml b/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
index 7cab0da..60cc950 100644
--- a/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
+++ b/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
@@ -131,8 +131,8 @@
-
-
+
+
@@ -143,8 +143,8 @@
-
-
+
+
@@ -345,6 +345,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -444,7 +477,7 @@
-
+
@@ -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}">
+ ItemsSource="{Binding SelectedItem.FontViewModel.FontSizes}"
+ Text="{Binding SelectedItem.FontViewModel.FontSize}">
@@ -482,13 +515,15 @@
+ IsChecked="{Binding SelectedItem.FontViewModel.FontWeight,Converter={dd:ConverterValueMapToBool Parameter='Regular'}, ConverterParameter='Bold'}">
+ IsChecked="{Binding SelectedItem.FontViewModel.FontStyle,Converter={dd:ConverterValueMapToBool Parameter='Normal'}, ConverterParameter='Italic'}">
+
+
@@ -571,7 +606,7 @@
适应窗口高度
-
+