Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3162 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
28 changed files with 2283 additions and 306 deletions
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -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
|
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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; |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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; |
||||
} |
||||
} |
||||
} |
||||
@ -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
|
||||
} |
||||
} |
||||
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -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; } |
||||
} |
||||
} |
||||
} |
||||
@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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 |
||||
{ |
||||
} |
||||
} |
||||
@ -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; |
||||
} |
||||
} |
||||
} |
||||
@ -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); } |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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); } |
||||
} |
||||
} |
||||
} |
||||
@ -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> |
||||
@ -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(); |
||||
})); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue