Browse Source

Applied BrushEditor patch by Ivan Shumilin.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3162 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
9282eeeba2
  1. 84
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor.cs
  2. 234
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditor.cs
  3. 10
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorPopup.xaml
  4. 38
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorPopup.xaml.cs
  5. 88
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorView.xaml
  6. 47
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorView.xaml.cs
  7. 12
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushTypeEditor.xaml
  8. 38
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushTypeEditor.xaml.cs
  9. 116
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/CallExtension.cs
  10. 102
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorHelper.cs
  11. 232
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorPicker.xaml
  12. 203
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorPicker.xaml.cs
  13. 22
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/Converters.cs
  14. 118
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/DragListener.cs
  15. 23
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ExtensionMethods.cs
  16. 11
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientBrushEditor.xaml
  17. 24
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientBrushEditor.xaml.cs
  18. 109
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientSlider.xaml
  19. 169
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientSlider.xaml.cs
  20. 71
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NormalizedPanel.cs
  21. 253
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NumericUpDown.cs
  22. 134
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NumericUpDown.xaml
  23. 150
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/Picker.cs
  24. 19
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/SolidBrushEditor.xaml
  25. 34
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/SolidBrushEditor.xaml.cs
  26. 31
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditorDialog.xaml
  27. 184
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditorDialog.xaml.cs
  28. 33
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

84
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using ICSharpCode.WpfDesign.PropertyEditor;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors
{
/// <summary>
/// Type editor used to edit Brush properties.
/// </summary>
[TypeEditor(typeof(Brush))]
public sealed class BrushEditor : DockPanel
{
readonly IPropertyEditorDataProperty property;
Border brushShowingBorder = new Border {
SnapsToDevicePixels = true,
BorderThickness = new Thickness(1)
};
DropDownButton ddb = new DropDownButton {
HorizontalAlignment = HorizontalAlignment.Right
};
/// <summary>
/// Creates a new BooleanEditor instance.
/// </summary>
public BrushEditor(IPropertyEditorDataProperty property)
{
this.property = property;
PropertyEditorBindingHelper.AddValueChangedEventHandler(this, property, OnValueChanged);
OnValueChanged(null, null);
ddb.Click += new RoutedEventHandler(DropDownButtonClick);
SetDock(ddb, Dock.Right);
this.Children.Add(ddb);
this.Children.Add(brushShowingBorder);
this.Unloaded += delegate {
if (dlg != null)
dlg.Close();
};
}
BrushEditorDialog dlg;
void DropDownButtonClick(object sender, RoutedEventArgs e)
{
dlg = new BrushEditorDialog(property);
Point pos = ddb.PointToScreen(new Point(ddb.ActualWidth, ddb.ActualHeight));
dlg.Left = pos.X - dlg.Width;
dlg.Top = pos.Y;
dlg.SelectedBrush = property.Value as Brush;
dlg.SelectedBrushChanged += delegate {
property.Value = dlg.SelectedBrush;
};
dlg.Show();
}
void OnValueChanged(object sender, EventArgs e)
{
Brush val = property.Value as Brush;
brushShowingBorder.Background = val;
if (val == null) {
brushShowingBorder.BorderBrush = null;
} else if (property.IsSet) {
brushShowingBorder.BorderBrush = Brushes.Black;
} else {
brushShowingBorder.BorderBrush = Brushes.Gray;
}
}
}
}

234
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditor.cs

@ -0,0 +1,234 @@ @@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using ICSharpCode.WpfDesign.PropertyEditor;
using System.Windows.Media;
using System.Reflection;
using System.Windows;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public enum BrushEditorKind
{
None,
Solid,
Linear,
Radial,
List
}
public class BrushItem
{
public string Name { get; set; }
public Brush Brush { get; set; }
}
public class BrushEditor : INotifyPropertyChanged
{
public BrushEditor()
{
GradientStopCollection stops = new GradientStopCollection();
stops.Add(new GradientStop(Colors.Black, 0));
stops.Add(new GradientStop(Colors.White, 1));
linearGradientBrush = new LinearGradientBrush(stops);
linearGradientBrush.EndPoint = new Point(1, 0);
radialGradientBrush = new RadialGradientBrush(stops);
}
public static BrushEditor Instance = new BrushEditor();
public static BrushItem[] SystemBrushes = typeof(SystemColors)
.GetProperties(BindingFlags.Static | BindingFlags.Public)
.Where(p => p.PropertyType == typeof(SolidColorBrush))
.Select(p => new BrushItem() { Name = p.Name, Brush = (Brush)p.GetValue(null, null) })
.ToArray();
public static BrushItem[] SystemColors = typeof(SystemColors)
.GetProperties(BindingFlags.Static | BindingFlags.Public)
.Where(p => p.PropertyType == typeof(Color))
.Select(p => new BrushItem()
{
Name = p.Name,
Brush = new SolidColorBrush((Color)p.GetValue(null, null))
})
.ToArray();
SolidColorBrush solidColorBrush = new SolidColorBrush(Colors.White);
LinearGradientBrush linearGradientBrush;
RadialGradientBrush radialGradientBrush;
IPropertyEditorDataProperty property;
public IPropertyEditorDataProperty Property
{
get
{
return property;
}
set
{
property = value;
if (property != null)
{
var f = property.Value as Freezable;
if (f != null && f.IsFrozen) property.Value = f.Clone();
}
DetermineCurrentKind();
RaisePropertyChanged("Property");
RaisePropertyChanged("Brush");
}
}
public Brush Brush
{
get
{
if (property != null)
{
return property.Value as Brush;
}
return null;
}
set
{
if (property != null && property.Value != value)
{
if (value != null && value.IsFrozen)
{
value = value.Clone();
}
property.Value = value;
DetermineCurrentKind();
RaisePropertyChanged("Brush");
}
}
}
void DetermineCurrentKind()
{
if (Brush == null)
{
CurrentKind = BrushEditorKind.None;
}
else if (Brush is SolidColorBrush)
{
solidColorBrush = Brush as SolidColorBrush;
CurrentKind = BrushEditorKind.Solid;
}
else if (Brush is LinearGradientBrush)
{
linearGradientBrush = Brush as LinearGradientBrush;
radialGradientBrush.GradientStops = linearGradientBrush.GradientStops;
CurrentKind = BrushEditorKind.Linear;
}
else if (Brush is RadialGradientBrush)
{
radialGradientBrush = Brush as RadialGradientBrush;
linearGradientBrush.GradientStops = linearGradientBrush.GradientStops;
CurrentKind = BrushEditorKind.Radial;
}
}
BrushEditorKind currentKind;
public BrushEditorKind CurrentKind
{
get
{
return currentKind;
}
set
{
currentKind = value;
RaisePropertyChanged("CurrentKind");
switch (CurrentKind)
{
case BrushEditorKind.None:
Brush = null;
break;
case BrushEditorKind.Solid:
Brush = solidColorBrush;
break;
case BrushEditorKind.Linear:
Brush = linearGradientBrush;
break;
case BrushEditorKind.Radial:
Brush = radialGradientBrush;
break;
case BrushEditorKind.List:
Brush = solidColorBrush;
break;
}
}
}
public double GradientAngle
{
get
{
var x = linearGradientBrush.EndPoint.X - linearGradientBrush.StartPoint.X;
var y = linearGradientBrush.EndPoint.Y - linearGradientBrush.StartPoint.Y;
return Vector.AngleBetween(new Vector(1, 0), new Vector(x, -y));
}
set
{
var d = value * Math.PI / 180;
var p = new Point(Math.Cos(d), -Math.Sin(d));
var k = 1 / Math.Max(Math.Abs(p.X), Math.Abs(p.Y));
p.X *= k;
p.Y *= k;
var p2 = new Point(-p.X, -p.Y);
linearGradientBrush.StartPoint = new Point((p2.X + 1) / 2, (p2.Y + 1) / 2);
linearGradientBrush.EndPoint = new Point((p.X + 1) / 2, (p.Y + 1) / 2);
RaisePropertyChanged("GradientAngle");
}
}
public IEnumerable<BrushItem> AvailableColors
{
get { return SystemColors; }
}
public IEnumerable<BrushItem> AvailableBrushes
{
get { return SystemBrushes; }
}
public void MakeGradientHorizontal()
{
GradientAngle = 0;
}
public void MakeGradientVertical()
{
GradientAngle = -90;
}
public void Commit()
{
Property.Value = Property.Value;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
}

10
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorPopup.xaml

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
<Popup x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.BrushEditorPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor"
Placement="Bottom"
AllowsTransparency="True"
SnapsToDevicePixels="True"
StaysOpen="False">
<c:BrushEditorView />
</Popup>

38
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorPopup.xaml.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class BrushEditorPopup
{
public BrushEditorPopup()
{
InitializeComponent();
}
public static BrushEditorPopup Instance = new BrushEditorPopup();
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
BrushEditor.Instance.Commit();
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Escape) IsOpen = false;
}
}
}

88
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorView.xaml

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.BrushEditorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor"
DataContext="{x:Static c:BrushEditor.Instance}"
Width="395">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="NumericUpDown.xaml" />
</ResourceDictionary.MergedDictionaries>
<c:IntFromEnumConverter x:Key="IntFromEnumConverter" />
<DataTemplate DataType="{x:Type c:BrushItem}">
<StackPanel Orientation="Horizontal">
<Border Background="{Binding Brush}"
Width="30"
Height="15"
Margin="2"
BorderThickness="1"
BorderBrush="Black" />
<TextBlock Text="{Binding Name}"
VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<TabControl x:Name="tabControl"
SelectedIndex="{Binding CurrentKind, Converter={StaticResource IntFromEnumConverter}}">
<TabItem Header="None">
<Border Background="White"
BorderThickness="1"
BorderBrush="Black"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Line X1="0"
Y1="40"
X2="70"
Y2="0"
Stroke="Red"
StrokeThickness="1" />
</Border>
</TabItem>
<TabItem Header="Solid">
<c:SolidBrushEditor Color="{Binding Brush.Color}" />
</TabItem>
<TabItem Header="Linear">
<DockPanel>
<StackPanel DockPanel.Dock="Top"
Orientation="Horizontal"
Margin="5">
<TextBlock Text="Angle"
VerticalAlignment="Center" />
<c:NumericUpDown Value="{Binding GradientAngle}"
Minimum="-360"
Maximum="360"
Margin="5 0 0 0"
Width="50" />
<Button Content="H"
Command="{c:Call MakeGradientHorizontal}"
Margin="5 0 0 0"
Width="30" />
<Button Content="V"
Command="{c:Call MakeGradientVertical}"
Margin="5 0 0 0"
Width="30" />
</StackPanel>
<c:GradientBrushEditor />
</DockPanel>
</TabItem>
<TabItem Header="Radial">
<c:GradientBrushEditor />
</TabItem>
<TabItem Header="Brush List">
<ListBox ItemsSource="{Binding AvailableBrushes}"
SelectedValue="{Binding Brush.Color}"
SelectedValuePath="Brush.Color" />
</TabItem>
</TabControl>
</UserControl>

47
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushEditorView.xaml.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Globalization;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class BrushEditorView
{
public BrushEditorView()
{
InitializeComponent();
SetBinding(HeightProperty, new Binding("Brush")
{
Converter = HeightConverter.Instance
});
}
class HeightConverter : IValueConverter
{
public static HeightConverter Instance = new HeightConverter();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is GradientBrush) return double.NaN;
return 315;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
}

12
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushTypeEditor.xaml

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.BrushTypeEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border BorderThickness="1"
BorderBrush="Black"
Background="Transparent"
HorizontalAlignment="Left"
Cursor="Hand"
Width="30">
<Border Background="{Binding Value}" />
</Border>
</UserControl>

38
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/BrushTypeEditor.xaml.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ICSharpCode.WpfDesign.PropertyEditor;
using System.Windows.Controls.Primitives;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
[TypeEditor(typeof(Brush))]
public partial class BrushTypeEditor
{
public BrushTypeEditor(IPropertyEditorDataProperty property)
{
this.property = property;
DataContext = property;
InitializeComponent();
}
IPropertyEditorDataProperty property;
protected override void OnMouseUp(MouseButtonEventArgs e)
{
BrushEditor.Instance.Property = property;
BrushEditorPopup.Instance.PlacementTarget = this;
BrushEditorPopup.Instance.IsOpen = true;
}
}
}

116
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/CallExtension.cs

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Reflection;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public class CallExtension : MarkupExtension
{
public CallExtension(string methodName)
{
this.methodName = methodName;
}
string methodName;
public override object ProvideValue(IServiceProvider sp)
{
var t = (IProvideValueTarget)sp.GetService(typeof(IProvideValueTarget));
return new CallCommand(t.TargetObject as FrameworkElement, methodName);
}
}
public class CallCommand : DependencyObject, ICommand
{
public CallCommand(FrameworkElement element, string methodName)
{
this.element = element;
this.methodName = methodName;
element.DataContextChanged += target_DataContextChanged;
BindingOperations.SetBinding(this, CanCallProperty, new Binding("DataContext.Can" + methodName)
{
Source = element
});
GetMethod();
}
FrameworkElement element;
string methodName;
MethodInfo method;
public static readonly DependencyProperty CanCallProperty =
DependencyProperty.Register("CanCall", typeof(bool), typeof(CallCommand),
new PropertyMetadata(true));
public bool CanCall
{
get { return (bool)GetValue(CanCallProperty); }
set { SetValue(CanCallProperty, value); }
}
public object DataContext
{
get { return element.DataContext; }
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == CanCallProperty)
{
RaiseCanExecuteChanged();
}
}
void GetMethod()
{
if (DataContext == null)
{
method = null;
}
else
{
method = DataContext.GetType().GetMethod(methodName, Type.EmptyTypes);
}
}
void target_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
GetMethod();
RaiseCanExecuteChanged();
}
void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
#region ICommand Members
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return method != null && CanCall;
}
public void Execute(object parameter)
{
method.Invoke(DataContext, null);
}
#endregion
}
}

102
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorHelper.cs

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public static class ColorHelper
{
public static Color ColorFromString(string s)
{
if (string.IsNullOrEmpty(s))
{
return Colors.White;
}
if (s[0] != '#') s = "#" + s;
try
{
return (Color)ColorConverter.ConvertFromString(s);
}
catch
{
return Colors.White;
}
}
public static string StringFromColor(Color c)
{
return c.ToString().Substring(1);
}
public static Color ColorFromHsv(double h, double s, double v)
{
double r, g, b;
RgbFromHsv(h, s, v, out r, out g, out b);
return Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
}
public static void HsvFromColor(Color c, out double h, out double s, out double v)
{
HsvFromRgb(c.R / 255, c.G / 255, c.B / 255, out h, out s, out v);
}
// http://en.wikipedia.org/wiki/HSV_color_space
public static void HsvFromRgb(double r, double g, double b, out double h, out double s, out double v)
{
var max = Math.Max(r, Math.Max(g, b));
var min = Math.Min(r, Math.Min(g, b));
if (max == min)
{
h = 0;
}
else if (max == r)
{
h = (60 * (g - b) / (max - min)) % 360;
}
else if (max == g)
{
h = 60 * (b - r) / (max - min) + 120;
}
else // if (max == b)
{
h = 60 * (r - g) / (max - min) + 240;
}
if (max == 0)
{
s = 0;
}
else
{
s = 1 - min / max;
}
v = max;
}
// http://en.wikipedia.org/wiki/HSV_color_space
public static void RgbFromHsv(double h, double s, double v, out double r, out double g, out double b)
{
h = h % 360;
int hi = (int)(h / 60) % 6;
var f = h / 60 - (int)(h / 60);
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (hi)
{
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;
}
}
}
}

232
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorPicker.xaml

@ -0,0 +1,232 @@ @@ -0,0 +1,232 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.ColorPicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor"
x:Name="this"
Padding="5"
Width="373">
<UserControl.Resources>
<DrawingBrush x:Key="ChessBrush"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 9 9">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0 0 2 2" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Gray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0 0 1 1" />
<RectangleGeometry Rect="1 1 1 1" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</UserControl.Resources>
<DockPanel>
<StackPanel VerticalAlignment="Top"
DockPanel.Dock="Right"
Margin="10 0 0 0">
<Border Background="{StaticResource ChessBrush}"
HorizontalAlignment="Right"
BorderBrush="Black"
BorderThickness="1"
Height="50"
Width="70">
<Rectangle>
<Rectangle.Fill>
<SolidColorBrush Color="{Binding Color, ElementName=this}" />
</Rectangle.Fill>
</Rectangle>
</Border>
<DockPanel Margin="0 3 0 0">
<c:EnterTextBox Text="{Binding Hex, ElementName=this, UpdateSourceTrigger=PropertyChanged}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="#"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding H, ElementName=this}"
Maximum="360"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="H"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding S, ElementName=this}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="S"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding V, ElementName=this}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="V"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding R, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="R"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding G, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="G"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding B, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="B"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<c:NumericUpDown Value="{Binding A, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="A"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
</StackPanel>
<Border Margin="10 0 0 0"
DockPanel.Dock="Right">
<c:Picker Orientation="Vertical"
Value="{Binding H, ElementName=this}"
Minimum="360"
Maximum="0"
Marker="{Binding ElementName=arrows}"
Width="20">
<Border Margin="0 -1">
<Border.Background>
<LinearGradientBrush EndPoint="0 1">
<GradientStop Offset="0"
Color="#F00" />
<GradientStop Offset="0.16"
Color="#F0F" />
<GradientStop Offset="0.33"
Color="#00F" />
<GradientStop Offset="0.5"
Color="#0FF" />
<GradientStop Offset="0.76"
Color="#0F0" />
<GradientStop Offset="0.85"
Color="#FF0" />
<GradientStop Offset="1"
Color="#F00" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Grid x:Name="arrows"
IsHitTestVisible="False"
VerticalAlignment="Top"
Margin="-5">
<Path HorizontalAlignment="Left"
Data="M 0 0 L 5 5 L 0 10 Z"
Fill="Black" />
<Path HorizontalAlignment="Right"
Data="M 0 0 L -5 5 L 0 10 Z"
Fill="Black" />
</Grid>
</c:Picker>
</Border>
<Border BorderBrush="Black"
BorderThickness="1">
<c:Picker Value="{Binding S, ElementName=this}"
Marker="{Binding ElementName=point}"
ClipToBounds="True">
<c:Picker Orientation="Vertical"
Value="{Binding V, ElementName=this}"
Minimum="100"
Maximum="0"
Marker="{Binding ElementName=point}">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1 0">
<GradientStop Offset="0"
Color="White" />
<GradientStop Offset="1"
Color="{Binding HueColor, ElementName=this}" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0 1">
<GradientStop Offset="0"
Color="#0000" />
<GradientStop Offset="1"
Color="#F000" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid x:Name="point"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Width="12"
Height="12"
Margin="-6 -6 0 0">
<Ellipse Stroke="Black"
IsHitTestVisible="False" />
<Ellipse Stroke="White"
Margin="1"
IsHitTestVisible="False" />
</Grid>
</c:Picker>
</c:Picker>
</Border>
</DockPanel>
</UserControl>

203
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ColorPicker.xaml.cs

@ -0,0 +1,203 @@ @@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class ColorPicker
{
public ColorPicker()
{
InitializeComponent();
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(Color), typeof(ColorPicker),
new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
public static readonly DependencyProperty HProperty =
DependencyProperty.Register("H", typeof(int), typeof(ColorPicker));
public int H
{
get { return (int)GetValue(HProperty); }
set { SetValue(HProperty, value); }
}
public static readonly DependencyProperty SProperty =
DependencyProperty.Register("S", typeof(int), typeof(ColorPicker));
public int S
{
get { return (int)GetValue(SProperty); }
set { SetValue(SProperty, value); }
}
public static readonly DependencyProperty VProperty =
DependencyProperty.Register("V", typeof(int), typeof(ColorPicker));
public int V
{
get { return (int)GetValue(VProperty); }
set { SetValue(VProperty, value); }
}
public static readonly DependencyProperty RProperty =
DependencyProperty.Register("R", typeof(byte), typeof(ColorPicker));
public byte R
{
get { return (byte)GetValue(RProperty); }
set { SetValue(RProperty, value); }
}
public static readonly DependencyProperty GProperty =
DependencyProperty.Register("G", typeof(byte), typeof(ColorPicker));
public byte G
{
get { return (byte)GetValue(GProperty); }
set { SetValue(GProperty, value); }
}
public static readonly DependencyProperty BProperty =
DependencyProperty.Register("B", typeof(byte), typeof(ColorPicker));
public byte B
{
get { return (byte)GetValue(BProperty); }
set { SetValue(BProperty, value); }
}
public static readonly DependencyProperty AProperty =
DependencyProperty.Register("A", typeof(byte), typeof(ColorPicker));
public byte A
{
get { return (byte)GetValue(AProperty); }
set { SetValue(AProperty, value); }
}
public static readonly DependencyProperty HexProperty =
DependencyProperty.Register("Hex", typeof(string), typeof(ColorPicker));
public string Hex
{
get { return (string)GetValue(HexProperty); }
set { SetValue(HexProperty, value); }
}
public static readonly DependencyProperty HueColorProperty =
DependencyProperty.Register("HueColor", typeof(Color), typeof(ColorPicker));
public Color HueColor
{
get { return (Color)GetValue(HueColorProperty); }
set { SetValue(HueColorProperty, value); }
}
bool updating;
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (updating) return;
updating = true;
if (e.Property == ColorProperty)
{
UpdateSource(ColorSource.Hsv);
UpdateRest(ColorSource.Hsv);
}
else if (e.Property == HProperty || e.Property == SProperty || e.Property == VProperty)
{
var c = ColorHelper.ColorFromHsv(H, S / 100.0, V / 100.0);
c.A = A;
Color = c;
UpdateRest(ColorSource.Hsv);
}
else if (e.Property == RProperty || e.Property == GProperty || e.Property == BProperty || e.Property == AProperty)
{
Color = Color.FromArgb(A, R, G, B);
UpdateRest(ColorSource.Rgba);
}
else if (e.Property == HexProperty)
{
Color = ColorHelper.ColorFromString(Hex);
UpdateRest(ColorSource.Hex);
}
updating = false;
}
void UpdateRest(ColorSource source)
{
HueColor = ColorHelper.ColorFromHsv(H, 1, 1);
UpdateSource((ColorSource)(((int)source + 1) % 3));
UpdateSource((ColorSource)(((int)source + 2) % 3));
}
void UpdateSource(ColorSource source)
{
if (source == ColorSource.Hsv)
{
double h, s, v;
ColorHelper.HsvFromColor(Color, out h, out s, out v);
H = (int)h;
S = (int)(s * 100);
V = (int)(v * 100);
}
else if (source == ColorSource.Rgba)
{
R = Color.R;
G = Color.G;
B = Color.B;
A = Color.A;
}
else
{
Hex = ColorHelper.StringFromColor(Color);
}
}
enum ColorSource
{
Hsv, Rgba, Hex
}
}
public class EnterTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
SelectAll();
var b = BindingOperations.GetBindingExpressionBase(this, TextProperty);
if (b != null)
{
b.UpdateTarget();
}
}
}
}
}

22
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/Converters.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public class IntFromEnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum.ToObject(targetType, (int)value);
}
}
}

118
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/DragListener.cs

@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public delegate void DragHandler(DragListener drag);
public class DragListener
{
static DragListener()
{
InputManager.Current.PostProcessInput += new ProcessInputEventHandler(PostProcessInput);
}
public DragListener(IInputElement target)
{
Target = target;
Target.PreviewMouseLeftButtonDown += Target_MouseDown;
Target.PreviewMouseMove += Target_MouseMove;
Target.PreviewMouseLeftButtonUp += Target_MouseUp;
}
static DragListener CurrentListener;
static void PostProcessInput(object sender, ProcessInputEventArgs e)
{
if (CurrentListener != null)
{
var a = e.StagingItem.Input as KeyEventArgs;
if (a != null && a.Key == Key.Escape)
{
Mouse.Capture(null);
CurrentListener.IsDown = false;
CurrentListener.Complete();
}
}
}
void Target_MouseDown(object sender, MouseButtonEventArgs e)
{
StartPoint = Mouse.GetPosition(null);
CurrentPoint = StartPoint;
DeltaDelta = new Vector();
IsDown = true;
if (Started != null)
{
Started(this);
}
}
void Target_MouseMove(object sender, MouseEventArgs e)
{
if (IsDown)
{
DeltaDelta = e.GetPosition(null) - CurrentPoint;
CurrentPoint += DeltaDelta;
if (!IsActive)
{
if (Math.Abs(Delta.X) >= SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(Delta.Y) >= SystemParameters.MinimumVerticalDragDistance)
{
IsActive = true;
CurrentListener = this;
}
}
if (IsActive && Changed != null)
{
Changed(this);
}
}
}
void Target_MouseUp(object sender, MouseButtonEventArgs e)
{
IsDown = false;
if (IsActive)
{
Complete();
}
}
void Complete()
{
IsActive = false;
CurrentListener = null;
if (Completed != null)
{
Completed(this);
}
}
public event DragHandler Started;
public event DragHandler Changed;
public event DragHandler Completed;
public IInputElement Target { get; private set; }
public Point StartPoint { get; private set; }
public Point CurrentPoint { get; private set; }
public Vector DeltaDelta { get; private set; }
public bool IsActive { get; private set; }
public bool IsDown { get; private set; }
public Vector Delta
{
get { return CurrentPoint - StartPoint; }
}
}
}

23
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/ExtensionMethods.cs

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public static class ExtensionMethods
{
//public static T[] GetValues<T>(this Type type)
//{
// return type
// .GetProperties(BindingFlags.Static | BindingFlags.Public)
// .Select(p => p.GetValue(null, null)).OfType<T>().ToArray();
//}
public static double Coerce(this double d, double min, double max)
{
return Math.Max(Math.Min(d, max), min);
}
}
}

11
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientBrushEditor.xaml

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.GradientBrushEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor">
<DockPanel>
<c:GradientSlider x:Name="slider"
DockPanel.Dock="Top"
Brush="{Binding Brush}" />
<c:SolidBrushEditor Color="{Binding SelectedStop.Color, ElementName=slider}" />
</DockPanel>
</UserControl>

24
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientBrushEditor.xaml.cs

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class GradientBrushEditor
{
public GradientBrushEditor()
{
InitializeComponent();
}
}
}

109
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientSlider.xaml

@ -0,0 +1,109 @@ @@ -0,0 +1,109 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.GradientSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor"
x:Name="this"
>
<UserControl.Resources>
<DataTemplate x:Key="GradientStopTemplate">
<Grid>
<Path x:Name="thumb"
Data="m 6 0 l 6 5 v 12 h -12 v -12 z"
Stroke="Black"
Fill="Orange" />
<Border Margin="2 7 2 2"
BorderBrush="Black"
BorderThickness="1">
<Border BorderBrush="White"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="red" />
</Border.Background>
</Border>
</Border>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="Selector.IsSelected"
Value="True">
<Setter TargetName="thumb"
Property="Fill"
Value="Gold" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="{x:Type c:GradientThumb}">
<Setter Property="c:NormalizedPanel.X"
Value="{Binding Offset}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:GradientThumb}">
<StackPanel>
<Path x:Name="thumb"
Data="m 0 0 l 6 -5 l 6 5"
Stroke="Black"
Fill="White" />
<Border BorderBrush="Black"
BorderThickness="1"
Width="12"
Height="12">
<Border BorderBrush="White"
BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="{Binding Color}" />
</Border.Background>
</Border>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected"
Value="True">
<Setter TargetName="thumb"
Property="Fill"
Value="Orange" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type c:Dragger}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:Dragger}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<c:Dragger x:Name="strip"
BorderBrush="Black"
BorderThickness="1"
VerticalAlignment="Top"
Height="20"
Margin="6 0 6 0">
<Control.Background>
<LinearGradientBrush EndPoint="1 0"
GradientStops="{Binding Brush.GradientStops, ElementName=this}" />
</Control.Background>
</c:Dragger>
<c:GradientItemsControl x:Name="itemsControl"
ItemsSource="{Binding GradientStops, ElementName=this}"
Margin="6 28 6 10">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<c:NormalizedPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</c:GradientItemsControl>
</Grid>
</UserControl>

169
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/GradientSlider.xaml.cs

@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class GradientSlider
{
public GradientSlider()
{
InitializeComponent();
BindingOperations.SetBinding(this, SelectedStopProperty, new Binding("SelectedItem")
{
Source = itemsControl,
Mode = BindingMode.TwoWay
});
strip.DragStarted += new DragStartedEventHandler(strip_DragStarted);
strip.DragDelta += new DragDeltaEventHandler(strip_DragDelta);
}
static GradientSlider()
{
EventManager.RegisterClassHandler(typeof(GradientSlider),
Thumb.DragDeltaEvent, new DragDeltaEventHandler(ClassDragDelta));
}
GradientStop newStop;
double startOffset;
public static readonly DependencyProperty BrushProperty =
DependencyProperty.Register("Brush", typeof(GradientBrush), typeof(GradientSlider));
public GradientBrush Brush
{
get { return (GradientBrush)GetValue(BrushProperty); }
set { SetValue(BrushProperty, value); }
}
public static readonly DependencyProperty SelectedStopProperty =
DependencyProperty.Register("SelectedStop", typeof(GradientStop), typeof(GradientSlider));
public GradientStop SelectedStop
{
get { return (GradientStop)GetValue(SelectedStopProperty); }
set { SetValue(SelectedStopProperty, value); }
}
public static readonly DependencyProperty GradientStopsProperty =
DependencyProperty.Register("GradientStops", typeof(BindingList<GradientStop>), typeof(GradientSlider));
public BindingList<GradientStop> GradientStops
{
get { return (BindingList<GradientStop>)GetValue(GradientStopsProperty); }
set { SetValue(GradientStopsProperty, value); }
}
public static Color GetColorAtOffset(IList<GradientStop> stops, double offset)
{
GradientStop s1 = stops[0], s2 = stops.Last();
foreach (var item in stops)
{
if (item.Offset < offset && item.Offset > s1.Offset) s1 = item;
if (item.Offset > offset && item.Offset < s2.Offset) s2 = item;
}
return Color.FromArgb(
(byte)((s1.Color.A + s2.Color.A) / 2),
(byte)((s1.Color.R + s2.Color.R) / 2),
(byte)((s1.Color.G + s2.Color.G) / 2),
(byte)((s1.Color.B + s2.Color.B) / 2)
);
}
static void ClassDragDelta(object sender, DragDeltaEventArgs e)
{
(sender as GradientSlider).thumb_DragDelta(sender, e);
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == BrushProperty)
{
if (Brush != null)
{
GradientStops = new BindingList<GradientStop>(Brush.GradientStops);
SelectedStop = GradientStops.FirstOrDefault();
}
else
{
GradientStops = null;
}
}
}
void strip_DragStarted(object sender, DragStartedEventArgs e)
{
startOffset = e.HorizontalOffset / strip.ActualWidth;
newStop = new GradientStop(GetColorAtOffset(GradientStops, startOffset), startOffset);
GradientStops.Add(newStop);
SelectedStop = newStop;
e.Handled = true;
}
void strip_DragDelta(object sender, DragDeltaEventArgs e)
{
MoveStop(newStop, startOffset, e);
e.Handled = true;
}
void thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
var stop = (e.OriginalSource as GradientThumb).GradientStop;
MoveStop(stop, stop.Offset, e);
}
void MoveStop(GradientStop stop, double oldOffset, DragDeltaEventArgs e)
{
if (e.VerticalChange > 50 && GradientStops.Count > 2)
{
GradientStops.Remove(stop);
SelectedStop = GradientStops.FirstOrDefault();
return;
}
stop.Offset = (oldOffset + e.HorizontalChange / strip.ActualWidth).Coerce(0, 1);
}
}
public class GradientItemsControl : Selector
{
protected override DependencyObject GetContainerForItemOverride()
{
return new GradientThumb();
}
}
public class GradientThumb : Thumb
{
public GradientStop GradientStop
{
get { return DataContext as GradientStop; }
}
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
base.OnPreviewMouseDown(e);
var itemsControl = ItemsControl.ItemsControlFromItemContainer(this) as GradientItemsControl;
itemsControl.SelectedItem = GradientStop;
}
}
public class Dragger : Thumb
{
}
}

71
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NormalizedPanel.cs

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public class NormalizedPanel : Panel
{
public static double GetX(DependencyObject obj)
{
return (double)obj.GetValue(XProperty);
}
public static void SetX(DependencyObject obj, double value)
{
obj.SetValue(XProperty, value);
}
public static readonly DependencyProperty XProperty =
DependencyProperty.RegisterAttached("X", typeof(double), typeof(NormalizedPanel),
new PropertyMetadata(OnPositioningChanged));
public static double GetY(DependencyObject obj)
{
return (double)obj.GetValue(YProperty);
}
public static void SetY(DependencyObject obj, double value)
{
obj.SetValue(YProperty, value);
}
public static readonly DependencyProperty YProperty =
DependencyProperty.RegisterAttached("Y", typeof(double), typeof(NormalizedPanel),
new PropertyMetadata(OnPositioningChanged));
static void OnPositioningChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NormalizedPanel parent = VisualTreeHelper.GetParent(d) as NormalizedPanel;
if (parent != null)
{
parent.InvalidateArrange();
}
}
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement item in Children)
{
item.Measure(availableSize);
}
return new Size();
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement item in Children)
{
Rect r = new Rect(item.DesiredSize);
r.X = GetX(item) * finalSize.Width - item.DesiredSize.Width / 2;
r.Y = GetY(item) * finalSize.Height - item.DesiredSize.Height / 2;
item.Arrange(r);
}
return finalSize;
}
}
}

253
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NumericUpDown.cs

@ -0,0 +1,253 @@ @@ -0,0 +1,253 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Globalization;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public class NumericUpDown : RangeBase
{
static NumericUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown),
new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}
TextBox textBox;
DragRepeatButton upButton;
DragRepeatButton downButton;
bool IsDragging
{
get
{
return upButton.IsDragging;
}
set
{
upButton.IsDragging = value; downButton.IsDragging = value;
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
upButton = (DragRepeatButton)Template.FindName("PART_UpButton", this);
downButton = (DragRepeatButton)Template.FindName("PART_DownButton", this);
textBox = (TextBox)Template.FindName("PART_TextBox", this);
upButton.Click += new RoutedEventHandler(upButton_Click);
downButton.Click += new RoutedEventHandler(downButton_Click);
var upDrag = new DragListener(upButton);
var downDrag = new DragListener(downButton);
upDrag.Changed += drag_Changed;
downDrag.Changed += drag_Changed;
upDrag.Completed += drag_Completed;
downDrag.Completed += drag_Completed;
Print();
}
void drag_Changed(DragListener drag)
{
IsDragging = true;
UpdateValue(-drag.DeltaDelta.Y);
}
void drag_Completed(DragListener drag)
{
IsDragging = false;
}
void downButton_Click(object sender, RoutedEventArgs e)
{
if (!IsDragging) SmallDown();
}
void upButton_Click(object sender, RoutedEventArgs e)
{
if (!IsDragging) SmallUp();
}
public void SmallUp()
{
UpdateValue(SmallChange);
}
public void SmallDown()
{
UpdateValue(-SmallChange);
}
public void LargeUp()
{
UpdateValue(LargeChange);
}
public void LargeDown()
{
UpdateValue(-LargeChange);
}
public void Minimize()
{
Parse();
Value = Minimum;
}
public void Maximize()
{
Parse();
Value = Maximum;
}
void UpdateValue(double delta)
{
Parse();
SetValue(Value + delta);
}
void Parse()
{
double result;
if (double.TryParse(textBox.Text, out result))
{
SetValue(result);
}
else
{
Print();
}
}
void Print()
{
if (textBox != null)
{
textBox.Text = Value.ToString();
textBox.CaretIndex = int.MaxValue;
}
}
//wpf bug?: Value = -1 updates bindings without coercing
//workaround
void SetValue(double newValue)
{
newValue = (double)Math.Max(Minimum, Math.Min(newValue, Maximum));
if (Value != newValue)
{
Value = newValue;
}
}
protected override void OnValueChanged(double oldValue, double newValue)
{
base.OnValueChanged(oldValue, newValue);
Print();
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
if (e.Key == Key.Enter)
{
Parse();
textBox.SelectAll();
e.Handled = true;
}
else if (e.Key == Key.Up)
{
SmallUp();
e.Handled = true;
}
else if (e.Key == Key.Down)
{
SmallDown();
e.Handled = true;
}
else if (e.Key == Key.PageUp)
{
LargeUp();
e.Handled = true;
}
else if (e.Key == Key.PageDown)
{
LargeDown();
e.Handled = true;
}
else if (e.Key == Key.Home)
{
Maximize();
e.Handled = true;
}
else if (e.Key == Key.End)
{
Minimize();
e.Handled = true;
}
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
if (Keyboard.IsKeyDown(Key.LeftShift))
{
LargeUp();
}
else
{
SmallUp();
}
}
else
{
if (Keyboard.IsKeyDown(Key.LeftShift))
{
LargeDown();
}
else
{
SmallDown();
}
}
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == SmallChangeProperty &&
ReadLocalValue(LargeChangeProperty) == DependencyProperty.UnsetValue)
{
LargeChange = SmallChange * 10;
}
}
}
public class DragRepeatButton : RepeatButton
{
public static readonly DependencyProperty IsDraggingProperty =
DependencyProperty.Register("IsDragging", typeof(bool), typeof(DragRepeatButton));
public bool IsDragging
{
get { return (bool)GetValue(IsDraggingProperty); }
set { SetValue(IsDraggingProperty, value); }
}
}
}

134
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/NumericUpDown.xaml

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor">
<Brush x:Key="ButtonNormal">#B6CEFB</Brush>
<Brush x:Key="ButtonHover">#C7DFFF</Brush>
<Brush x:Key="ButtonPressed">#9CB1D8</Brush>
<Brush x:Key="BorderBrush">#FF7F9DB9</Brush>
<Style x:Key="UpButton"
TargetType="RepeatButton">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:DragRepeatButton}">
<Border x:Name="bg"
Background="{StaticResource ButtonNormal}"
CornerRadius="2 2 0 0">
<Path Fill="Black"
Data="M 0 3 L 3 0 L 6 3"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonHover}" />
</Trigger>
<Trigger Property="IsMouseCaptured"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
<Trigger Property="IsDragging"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DownButton"
TargetType="RepeatButton">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:DragRepeatButton}">
<Border x:Name="bg"
Background="{StaticResource ButtonNormal}"
CornerRadius="0 0 2 2">
<Path Fill="Black"
Data="M 0 0 L 3 3 L 6 0"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonHover}" />
</Trigger>
<Trigger Property="IsMouseCaptured"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
<Trigger Property="IsDragging"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type c:NumericUpDown}">
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="BorderBrush"
Value="{StaticResource BorderBrush}" />
<Setter Property="Focusable"
Value="False" />
<Setter Property="Maximum"
Value="100" />
<Setter Property="SmallChange"
Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:NumericUpDown}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="12" />
</Grid.ColumnDefinitions>
<TextBox x:Name="PART_TextBox"
BorderThickness="0"
Grid.RowSpan="2" />
<c:DragRepeatButton x:Name="PART_UpButton"
Style="{StaticResource UpButton}"
Grid.Column="1" />
<c:DragRepeatButton x:Name="PART_DownButton"
Style="{StaticResource DownButton}"
Grid.Column="1"
Grid.Row="1" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

150
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/Picker.cs

@ -0,0 +1,150 @@ @@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls.Primitives;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Data;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public class Picker : Grid
{
public Picker()
{
SizeChanged += delegate { UpdateValueOffset(); };
}
public static readonly DependencyProperty MarkerProperty =
DependencyProperty.Register("Marker", typeof(UIElement), typeof(Picker));
public UIElement Marker
{
get { return (UIElement)GetValue(MarkerProperty); }
set { SetValue(MarkerProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(Picker),
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueOffsetProperty =
DependencyProperty.Register("ValueOffset", typeof(double), typeof(Picker));
public double ValueOffset
{
get { return (double)GetValue(ValueOffsetProperty); }
set { SetValue(ValueOffsetProperty, value); }
}
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Picker));
public Orientation Orientation
{
get { return (Orientation)GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(Picker));
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(Picker),
new FrameworkPropertyMetadata(100.0));
public double Maximum
{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == MarkerProperty)
{
TranslateTransform t = Marker.RenderTransform as TranslateTransform;
if (t == null)
{
t = new TranslateTransform();
Marker.RenderTransform = t;
}
var property = Orientation == Orientation.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty;
BindingOperations.SetBinding(t, property, new Binding("ValueOffset")
{
Source = this
});
}
else if (e.Property == ValueProperty)
{
UpdateValueOffset();
}
}
bool isMouseDown;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
isMouseDown = true;
CaptureMouse();
UpdateValue();
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
if (isMouseDown)
{
UpdateValue();
}
}
protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
{
isMouseDown = false;
ReleaseMouseCapture();
}
void UpdateValue()
{
Point p = Mouse.GetPosition(this);
double length = 0, pos = 0;
if (Orientation == Orientation.Horizontal)
{
length = ActualWidth;
pos = p.X;
}
else
{
length = ActualHeight;
pos = p.Y;
}
pos = Math.Max(0, Math.Min(length, pos));
Value = Minimum + (Maximum - Minimum) * pos / length;
}
void UpdateValueOffset()
{
var length = Orientation == Orientation.Horizontal ? ActualWidth : ActualHeight;
ValueOffset = length * (Value - Minimum) / (Maximum - Minimum);
}
}
}

19
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/SolidBrushEditor.xaml

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
<UserControl
x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor.SolidBrushEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor"
x:Name="this"
Height="284"
>
<TabControl>
<TabItem Header="Color Picker">
<c:ColorPicker Color="{Binding Color, ElementName=this}" />
</TabItem>
<TabItem Header="Color List">
<ListBox ItemsSource="{Binding AvailableColors}"
SelectedValue="{Binding Color, ElementName=this}"
SelectedValuePath="Brush.Color" />
</TabItem>
</TabControl>
</UserControl>

34
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditor/SolidBrushEditor.xaml.cs

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor
{
public partial class SolidBrushEditor
{
public SolidBrushEditor()
{
InitializeComponent();
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(Color), typeof(SolidBrushEditor),
new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
}

31
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditorDialog.xaml

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditorDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None"
Height="246"
Width="272"
ResizeMode="NoResize"
SizeToContent="Height">
<Window.Resources>
<ControlTemplate TargetType="{x:Type RadioButton}" x:Key="RadioButtonTemplate">
<Border Name="outerBorder" BorderThickness="1" BorderBrush="Transparent">
<Border Name="innerBorder" BorderThickness="1" BorderBrush="Gray" Background="{TemplateBinding Background}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="innerBorder" Value="Black"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderBrush" TargetName="outerBorder" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<Border
BorderBrush="Black"
BorderThickness="1,1,1,1">
<Canvas Name="canvas" Margin="4">
</Canvas>
</Border>
</Window>

184
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/TypeEditors/BrushEditorDialog.xaml.cs

@ -1,184 +0,0 @@ @@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ICSharpCode.WpfDesign.PropertyEditor;
using System.Windows.Threading;
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors
{
/// <summary>
/// Interaction logic for BrushEditorDialog.xaml
/// </summary>
public partial class BrushEditorDialog : Window
{
static readonly Brush[] specialBrushes = {
Brushes.White, Brushes.Black, Brushes.Transparent, null
};
ControlTemplate RadioButtonTemplate;
public BrushEditorDialog(IPropertyEditorDataProperty property)
{
InitializeComponent();
RadioButtonTemplate = (ControlTemplate)FindResource("RadioButtonTemplate");
const int bigColorSquareSize = 18;
const int smallColorSquareSize = 12;
// special brushes:
AddColorSquare(null, null, "null", bigColorSquareSize).IsChecked = true;
AddColorSquare(Brushes.Black, null, "Black", bigColorSquareSize);
AddColorSquare(Brushes.White, null, "White", bigColorSquareSize);
AddColorSquare(Brushes.Transparent, null, "Transparent", bigColorSquareSize);
x = 0;
y += bigColorSquareSize;
AddSeparatorLine();
foreach (PropertyInfo p in typeof(Brushes).GetProperties()) {
Brush brush = (Brush)p.GetValue(null, null);
if (!specialBrushes.Contains(brush))
AddColorSquare(brush, null, p.Name, smallColorSquareSize);
}
y += smallColorSquareSize;
if (property != null) {
AddSeparatorLine();
TextBoxEditor textBoxEditor = new TextBoxEditor(property);
textBoxEditor.Width = 100;
Canvas.SetTop(textBoxEditor, y);
canvas.Children.Add(textBoxEditor);
textBoxEditor.ValueSaved += delegate {
this.SelectedBrush = textBoxEditor.Property.Value as Brush;
};
y += 21;
}
canvas.Height = y;
}
int x = 0;
int y = 0;
RadioButton AddColorSquare(Brush brush, UIElement content, string tooltip, int size)
{
RadioButton radioButton = new RadioButton {
Background = brush,
Width = size,
Height = size
};
radioButton.ToolTip = tooltip;
radioButton.Template = RadioButtonTemplate;
Canvas.SetLeft(radioButton, x);
Canvas.SetTop(radioButton, y);
canvas.Children.Add(radioButton);
radioButton.Checked += delegate {
if (selectedBrush != radioButton.Background) {
selectedBrush = radioButton.Background;
if (SelectedBrushChanged != null) {
SelectedBrushChanged(this, EventArgs.Empty);
}
}
};
x += size;
if (x > 260) {
x = 0;
y += size;
}
return radioButton;
}
void AddSeparatorLine()
{
Line line = new Line {
StrokeThickness = 1,
Stroke = Brushes.Gray,
Height = 1,
X2 = 260,
Y1 = 0.5,
Y2 = 0.5
};
Canvas.SetTop(line, y + 1);
canvas.Children.Add(line);
y += 3;
}
Brush selectedBrush;
public Brush SelectedBrush {
get {
return selectedBrush;
}
set {
if (selectedBrush != value) {
selectedBrush = value;
foreach (RadioButton btn in canvas.Children.OfType<RadioButton>()) {
btn.IsChecked = BrushEquals(btn.Background, value);
}
if (SelectedBrushChanged != null) {
SelectedBrushChanged(this, EventArgs.Empty);
}
}
}
}
bool BrushEquals(Brush b1, Brush b2)
{
if (b1 == b2)
return true;
SolidColorBrush scb1 = b1 as SolidColorBrush;
SolidColorBrush scb2 = b2 as SolidColorBrush;
if (scb1 == null || scb2 == null)
return false;
return scb1.Color == scb2.Color;
}
public event EventHandler SelectedBrushChanged;
protected override void OnDeactivated(EventArgs e)
{
base.OnDeactivated(e);
CloseIfNotActive(null, null);
}
Window activeWindow;
void CloseIfNotActive(object sender, EventArgs e)
{
if (activeWindow != null) {
activeWindow.Deactivated -= CloseIfNotActive;
activeWindow = null;
}
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(
delegate {
if (IsActive)
return;
foreach (Window child in OwnedWindows) {
Debug.WriteLine(child + " isActive=" + child.IsActive);
if (child.IsActive) {
activeWindow = child;
child.Deactivated += CloseIfNotActive;
return;
}
}
Close();
}));
}
}
}

33
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -75,11 +75,22 @@ @@ -75,11 +75,22 @@
<Compile Include="Controls\PropertyEditor\PropertyNameTextBlock.cs" />
<Compile Include="Controls\ResizeThumb.cs" />
<Compile Include="Controls\SingleVisualChildElement.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor.cs" />
<Compile Include="Controls\TypeEditors\BrushEditorDialog.xaml.cs">
<DependentUpon>BrushEditorDialog.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Controls\TypeEditors\BrushEditor\BrushEditor.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\BrushEditorPopup.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\BrushEditorView.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\BrushTypeEditor.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\CallExtension.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\ColorHelper.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\ColorPicker.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\Converters.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\DragListener.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\ExtensionMethods.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\GradientBrushEditor.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\GradientSlider.xaml.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\NormalizedPanel.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\NumericUpDown.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\Picker.cs" />
<Compile Include="Controls\TypeEditors\BrushEditor\SolidBrushEditor.xaml.cs" />
<Compile Include="Controls\TypeEditors\ContentEditor.cs" />
<Compile Include="Controls\TypeEditors\CursorEditor.cs" />
<Compile Include="Controls\TypeEditors\NullableBoolEditor.cs" />
@ -126,6 +137,7 @@ @@ -126,6 +137,7 @@
<Folder Include="Controls" />
<Folder Include="Controls\TypeEditors" />
<Folder Include="Controls\PropertyEditor" />
<Folder Include="Controls\TypeEditors\BrushEditor" />
<Folder Include="Extensions" />
<Folder Include="themes" />
<Folder Include="Xaml" />
@ -146,7 +158,14 @@ @@ -146,7 +158,14 @@
</Page>
<Page Include="Controls\PropertyEditor\PropertyEditorStyles.xaml" />
<Page Include="Controls\ControlStyles.xaml" />
<Page Include="Controls\TypeEditors\BrushEditorDialog.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\BrushEditorPopup.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\BrushEditorView.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\BrushTypeEditor.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\ColorPicker.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\GradientBrushEditor.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\GradientSlider.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\NumericUpDown.xaml" />
<Page Include="Controls\TypeEditors\BrushEditor\SolidBrushEditor.xaml" />
<Page Include="themes\generic.xaml" />
</ItemGroup>
</Project>
</Project>

Loading…
Cancel
Save