Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3283 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
73 changed files with 1283 additions and 3926 deletions
@ -1,181 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Markup; |
|
||||||
using System.ComponentModel; |
|
||||||
using System.Globalization; |
|
||||||
using System.Windows.Threading; |
|
||||||
|
|
||||||
namespace ICSharpCode.XamlDesigner |
|
||||||
{ |
|
||||||
public enum DisableMode |
|
||||||
{ |
|
||||||
Disable, Collapse |
|
||||||
} |
|
||||||
|
|
||||||
public class ActionArgs |
|
||||||
{ |
|
||||||
public FrameworkElement Element { get; internal set; } |
|
||||||
} |
|
||||||
|
|
||||||
public delegate void ActionHandler(ActionArgs e); |
|
||||||
public delegate bool CanActionHandler(ActionArgs e); |
|
||||||
|
|
||||||
public class Action |
|
||||||
{ |
|
||||||
public Action() |
|
||||||
{ |
|
||||||
Elements = new List<FrameworkElement>(); |
|
||||||
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Loaded, new System.Action(RegisterRequery)); |
|
||||||
} |
|
||||||
|
|
||||||
void RegisterRequery() |
|
||||||
{ |
|
||||||
CommandManager.RequerySuggested += new EventHandler(CommandManager_RequerySuggested); |
|
||||||
} |
|
||||||
|
|
||||||
void CommandManager_RequerySuggested(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
UpdateElements(); |
|
||||||
} |
|
||||||
|
|
||||||
public string Text { get; set; } |
|
||||||
public Shortcut Shortcut { get; set; } |
|
||||||
public ImageSource IconSource { get; set; } |
|
||||||
public DisableMode DisableMode { get; set; } |
|
||||||
public event ActionHandler Executed; |
|
||||||
public event CanActionHandler CanExecute; |
|
||||||
public List<FrameworkElement> Elements { get; private set; } |
|
||||||
|
|
||||||
public object ExecuteHost { |
|
||||||
get { |
|
||||||
if (Executed != null) return Executed.Target; |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void AttachTo(FrameworkElement f) |
|
||||||
{ |
|
||||||
SetText(f); |
|
||||||
SetShortcut(f); |
|
||||||
SetIcon(f); |
|
||||||
SetEvent(f); |
|
||||||
|
|
||||||
Elements.Add(f); |
|
||||||
} |
|
||||||
|
|
||||||
public void UpdateElements() |
|
||||||
{ |
|
||||||
if (CanExecute != null) { |
|
||||||
foreach (var f in Elements) { |
|
||||||
f.IsEnabled = CanExecute(new ActionArgs() { Element = f }); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SetText(FrameworkElement f) |
|
||||||
{ |
|
||||||
if (Text == null) return; |
|
||||||
if (f is ContentControl) { |
|
||||||
(f as ContentControl).Content = Text; |
|
||||||
} |
|
||||||
else if (f is HeaderedItemsControl) { |
|
||||||
(f as HeaderedItemsControl).Header = Text; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SetShortcut(FrameworkElement f) |
|
||||||
{ |
|
||||||
if (Shortcut == null) return; |
|
||||||
if (f is MenuItem) { |
|
||||||
(f as MenuItem).InputGestureText = Shortcut.ToString(); |
|
||||||
} |
|
||||||
if (ExecuteHost == null) return; |
|
||||||
(ExecuteHost as IInputElement).KeyDown += delegate(object sender, KeyEventArgs e) { |
|
||||||
if (e.Key == Shortcut.Key && Keyboard.Modifiers == Shortcut.Modifiers) { |
|
||||||
Executed(new ActionArgs() { Element = f }); |
|
||||||
} |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
void SetIcon(FrameworkElement f) |
|
||||||
{ |
|
||||||
if (IconSource == null) return; |
|
||||||
if (f is MenuItem) { |
|
||||||
(f as MenuItem).Icon = new Image() { Source = IconSource }; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SetEvent(FrameworkElement f) |
|
||||||
{ |
|
||||||
if (Executed == null) return; |
|
||||||
f.PreviewMouseLeftButtonUp += delegate { |
|
||||||
Executed(new ActionArgs() { Element = f }); |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static class ActionManager |
|
||||||
{ |
|
||||||
public static void SetAction(DependencyObject obj, object value) |
|
||||||
{ |
|
||||||
Action a = value as Action; |
|
||||||
if (a == null) { |
|
||||||
if (obj is FrameworkElement) { |
|
||||||
a = (Action)(obj as FrameworkElement).FindResource(value); |
|
||||||
} |
|
||||||
} |
|
||||||
a.AttachTo(obj as FrameworkElement); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
[TypeConverter(typeof(ShortcutConverter))] |
|
||||||
public class Shortcut |
|
||||||
{ |
|
||||||
public ModifierKeys Modifiers; |
|
||||||
public Key Key; |
|
||||||
|
|
||||||
static KeyConverter KeyConverter = new KeyConverter(); |
|
||||||
static ModifierKeysConverter ModifierKeysConverter = new ModifierKeysConverter(); |
|
||||||
|
|
||||||
public static Shortcut FromString(string s) |
|
||||||
{ |
|
||||||
var result = new Shortcut(); |
|
||||||
var pos = s.LastIndexOf('+'); |
|
||||||
if (pos < 0) { |
|
||||||
result.Key = (Key)KeyConverter.ConvertFromString(s); |
|
||||||
} |
|
||||||
else { |
|
||||||
result.Modifiers = (ModifierKeys)ModifierKeysConverter.ConvertFromString(s.Substring(0, pos)); |
|
||||||
result.Key = (Key)KeyConverter.ConvertFromString(s.Substring(pos + 1)); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
if (Modifiers == ModifierKeys.None) return KeyConverter.ConvertToString(Key); |
|
||||||
return ModifierKeysConverter.ConvertToString(Modifiers) + "+" + KeyConverter.ConvertToString(Key); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class ShortcutConverter : TypeConverter |
|
||||||
{ |
|
||||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|
||||||
{ |
|
||||||
return sourceType == typeof(string); |
|
||||||
} |
|
||||||
|
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|
||||||
{ |
|
||||||
return Shortcut.FromString((string)value); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,327 @@ |
|||||||
|
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.Collections.Specialized; |
||||||
|
using ICSharpCode.XamlDesigner.Converters; |
||||||
|
using System.Collections; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
// limitations:
|
||||||
|
// - Do not use ItemsSource (use Root)
|
||||||
|
// - Do not use Items (use Root)
|
||||||
|
public class DragTreeView : TreeView |
||||||
|
{ |
||||||
|
static DragTreeView() |
||||||
|
{ |
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragTreeView), |
||||||
|
new FrameworkPropertyMetadata(typeof(DragTreeView))); |
||||||
|
} |
||||||
|
|
||||||
|
public DragTreeView() |
||||||
|
{ |
||||||
|
AllowDrop = true; |
||||||
|
new DragListener(this).DragStarted += new MouseButtonEventHandler(DragTreeView_DragStarted); |
||||||
|
} |
||||||
|
|
||||||
|
DragTreeViewItem dropTarget; |
||||||
|
DragTreeViewItem treeItem; |
||||||
|
DragTreeViewItem dropAfter; |
||||||
|
int part; |
||||||
|
bool dropInside; |
||||||
|
bool dropCopy; |
||||||
|
bool canDrop; |
||||||
|
|
||||||
|
Border insertLine; |
||||||
|
|
||||||
|
public static readonly DependencyProperty RootProperty = |
||||||
|
DependencyProperty.Register("Root", typeof(object), typeof(DragTreeView)); |
||||||
|
|
||||||
|
public object Root { |
||||||
|
get { return (object)GetValue(RootProperty); } |
||||||
|
set { SetValue(RootProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
//public object[] SelectedItems
|
||||||
|
//{
|
||||||
|
// get { return Selection.Select(item => item.DataContext).ToArray(); }
|
||||||
|
//}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
||||||
|
{ |
||||||
|
base.OnPropertyChanged(e); |
||||||
|
if (e.Property == RootProperty) { |
||||||
|
ItemsSource = new[] { Root }; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void DragTreeView_DragStarted(object sender, MouseButtonEventArgs e) |
||||||
|
{ |
||||||
|
DragDrop.DoDragDrop(this, this, DragDropEffects.All); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnApplyTemplate() |
||||||
|
{ |
||||||
|
base.OnApplyTemplate(); |
||||||
|
insertLine = (Border)Template.FindName("PART_InsertLine", this); |
||||||
|
} |
||||||
|
|
||||||
|
protected override DependencyObject GetContainerForItemOverride() |
||||||
|
{ |
||||||
|
return new DragTreeViewItem(); |
||||||
|
} |
||||||
|
|
||||||
|
protected override bool IsItemItsOwnContainerOverride(object item) |
||||||
|
{ |
||||||
|
return item is DragTreeViewItem; |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnDragEnter(DragEventArgs e) |
||||||
|
{ |
||||||
|
ProcessDrag(e); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnDragOver(DragEventArgs e) |
||||||
|
{ |
||||||
|
ProcessDrag(e); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnDrop(DragEventArgs e) |
||||||
|
{ |
||||||
|
ProcessDrop(e); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnDragLeave(DragEventArgs e) |
||||||
|
{ |
||||||
|
HideDropMarker(); |
||||||
|
} |
||||||
|
|
||||||
|
void PrepareDropInfo(DragEventArgs e) |
||||||
|
{ |
||||||
|
dropTarget = null; |
||||||
|
dropAfter = null; |
||||||
|
treeItem = (e.OriginalSource as DependencyObject).FindAncestor<DragTreeViewItem>(); |
||||||
|
|
||||||
|
if (treeItem != null) { |
||||||
|
var parent = ItemsControl.ItemsControlFromItemContainer(treeItem) as DragTreeViewItem; |
||||||
|
ContentPresenter header = treeItem.HeaderPresenter; |
||||||
|
Point p = e.GetPosition(header); |
||||||
|
part = (int)(p.Y / (header.ActualHeight / 3)); |
||||||
|
dropCopy = Keyboard.IsKeyDown(Key.LeftCtrl); |
||||||
|
dropInside = false; |
||||||
|
|
||||||
|
if (part == 1 || parent == null) { |
||||||
|
dropTarget = treeItem; |
||||||
|
dropInside = true; |
||||||
|
if (treeItem.Items.Count > 0) { |
||||||
|
dropAfter = treeItem.ItemContainerGenerator.ContainerFromIndex(treeItem.Items.Count - 1) as DragTreeViewItem; |
||||||
|
} |
||||||
|
} |
||||||
|
else if (part == 0) { |
||||||
|
dropTarget = parent; |
||||||
|
var index = dropTarget.ItemContainerGenerator.IndexFromContainer(treeItem); |
||||||
|
if (index > 0) { |
||||||
|
dropAfter = dropTarget.ItemContainerGenerator.ContainerFromIndex(index - 1) as DragTreeViewItem; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
dropTarget = parent; |
||||||
|
dropAfter = treeItem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ProcessDrag(DragEventArgs e) |
||||||
|
{ |
||||||
|
e.Effects = DragDropEffects.None; |
||||||
|
e.Handled = true; |
||||||
|
canDrop = false; |
||||||
|
|
||||||
|
if (e.Data.GetData(GetType()) != this) return; |
||||||
|
|
||||||
|
HideDropMarker(); |
||||||
|
PrepareDropInfo(e); |
||||||
|
|
||||||
|
if (dropTarget != null && CanInsertInternal()) { |
||||||
|
canDrop = true; |
||||||
|
e.Effects = dropCopy ? DragDropEffects.Copy : DragDropEffects.Move; |
||||||
|
DrawDropMarker(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ProcessDrop(DragEventArgs e) |
||||||
|
{ |
||||||
|
HideDropMarker(); |
||||||
|
|
||||||
|
if (canDrop) { |
||||||
|
InsertInternal(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void DrawDropMarker() |
||||||
|
{ |
||||||
|
if (dropInside) { |
||||||
|
dropTarget.IsDragHover = true; |
||||||
|
} |
||||||
|
else { |
||||||
|
var header = treeItem.HeaderPresenter; |
||||||
|
var p = header.TransformToVisual(this).Transform( |
||||||
|
new Point(0, part == 0 ? 0 : header.ActualHeight)); |
||||||
|
|
||||||
|
insertLine.Visibility = Visibility.Visible; |
||||||
|
insertLine.Margin = new Thickness(p.X, p.Y, 0, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void HideDropMarker() |
||||||
|
{ |
||||||
|
insertLine.Visibility = Visibility.Collapsed; |
||||||
|
if (dropTarget != null) { |
||||||
|
dropTarget.IsDragHover = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal HashSet<DragTreeViewItem> Selection = new HashSet<DragTreeViewItem>(); |
||||||
|
DragTreeViewItem upSelection; |
||||||
|
|
||||||
|
internal void ItemMouseDown(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
upSelection = null; |
||||||
|
bool control = Keyboard.IsKeyDown(Key.LeftCtrl); |
||||||
|
|
||||||
|
if (Selection.Contains(item)) { |
||||||
|
if (control) { |
||||||
|
Unselect(item); |
||||||
|
} |
||||||
|
else { |
||||||
|
upSelection = item; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
if (control) { |
||||||
|
Select(item); |
||||||
|
} |
||||||
|
else { |
||||||
|
SelectOnly(item); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal void ItemMouseUp(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
if (upSelection == item) { |
||||||
|
SelectOnly(item); |
||||||
|
} |
||||||
|
upSelection = null; |
||||||
|
} |
||||||
|
|
||||||
|
internal void ItemAttached(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
if (item.IsSelected) Selection.Add(item); |
||||||
|
} |
||||||
|
|
||||||
|
internal void ItemDetached(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
if (item.IsSelected) Selection.Remove(item); |
||||||
|
} |
||||||
|
|
||||||
|
internal void ItemIsSelectedChanged(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
if (item.IsSelected) { |
||||||
|
Selection.Add(item); |
||||||
|
} |
||||||
|
else { |
||||||
|
Selection.Remove(item); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void Select(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
Selection.Add(item); |
||||||
|
item.IsSelected = true; |
||||||
|
OnSelectionChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
void Unselect(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
Selection.Remove(item); |
||||||
|
item.IsSelected = false; |
||||||
|
OnSelectionChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
void SelectOnly(DragTreeViewItem item) |
||||||
|
{ |
||||||
|
ClearSelection(); |
||||||
|
Select(item); |
||||||
|
OnSelectionChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
void ClearSelection() |
||||||
|
{ |
||||||
|
foreach (var treeItem in Selection.ToArray()) { |
||||||
|
treeItem.IsSelected = false; |
||||||
|
} |
||||||
|
Selection.Clear(); |
||||||
|
OnSelectionChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
void OnSelectionChanged() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
bool CanInsertInternal() |
||||||
|
{ |
||||||
|
if (!dropCopy) { |
||||||
|
var item = dropTarget; |
||||||
|
while (true) { |
||||||
|
if (Selection.Contains(item)) return false; |
||||||
|
item = ItemsControl.ItemsControlFromItemContainer(item) as DragTreeViewItem; |
||||||
|
if (item == null) break; |
||||||
|
} |
||||||
|
|
||||||
|
if (Selection.Contains(dropAfter)) return false; |
||||||
|
} |
||||||
|
|
||||||
|
return CanInsert(dropTarget, Selection.ToArray(), dropAfter, dropCopy); |
||||||
|
} |
||||||
|
|
||||||
|
void InsertInternal() |
||||||
|
{ |
||||||
|
var selection = Selection.ToArray(); |
||||||
|
|
||||||
|
if (!dropCopy) { |
||||||
|
foreach (var item in Selection.ToArray()) { |
||||||
|
var parent = ItemsControl.ItemsControlFromItemContainer(item) as DragTreeViewItem; |
||||||
|
//TODO
|
||||||
|
if (parent != null) { |
||||||
|
Remove(parent, item); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Insert(dropTarget, selection, dropAfter, dropCopy); |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual bool CanInsert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual void Insert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual void Remove(DragTreeViewItem target, DragTreeViewItem item) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,119 @@ |
|||||||
|
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; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public class DragTreeViewItem : TreeViewItem |
||||||
|
{ |
||||||
|
static DragTreeViewItem() |
||||||
|
{ |
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragTreeViewItem), |
||||||
|
new FrameworkPropertyMetadata(typeof(DragTreeViewItem))); |
||||||
|
} |
||||||
|
|
||||||
|
public DragTreeViewItem() |
||||||
|
{ |
||||||
|
Loaded += new RoutedEventHandler(DragTreeViewItem_Loaded); |
||||||
|
Unloaded += new RoutedEventHandler(DragTreeViewItem_Unloaded); |
||||||
|
} |
||||||
|
|
||||||
|
void DragTreeViewItem_Loaded(object sender, RoutedEventArgs e) |
||||||
|
{ |
||||||
|
ParentTree = this.FindAncestor<DragTreeView>(); |
||||||
|
if (ParentTree != null) { |
||||||
|
ParentTree.ItemAttached(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void DragTreeViewItem_Unloaded(object sender, RoutedEventArgs e) |
||||||
|
{ |
||||||
|
if (ParentTree != null) { |
||||||
|
ParentTree.ItemDetached(this); |
||||||
|
} |
||||||
|
ParentTree = null; |
||||||
|
} |
||||||
|
|
||||||
|
public new static readonly DependencyProperty IsSelectedProperty = |
||||||
|
Selector.IsSelectedProperty.AddOwner(typeof(DragTreeViewItem)); |
||||||
|
|
||||||
|
public new bool IsSelected { |
||||||
|
get { return (bool)GetValue(IsSelectedProperty); } |
||||||
|
set { SetValue(IsSelectedProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
public static readonly DependencyProperty IsDragHoverProperty = |
||||||
|
DependencyProperty.Register("IsDragHover", typeof(bool), typeof(DragTreeViewItem)); |
||||||
|
|
||||||
|
public bool IsDragHover { |
||||||
|
get { return (bool)GetValue(IsDragHoverProperty); } |
||||||
|
set { SetValue(IsDragHoverProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
internal ContentPresenter HeaderPresenter { |
||||||
|
get { return (ContentPresenter)Template.FindName("PART_Header", this); } |
||||||
|
} |
||||||
|
|
||||||
|
public static readonly DependencyProperty LevelProperty = |
||||||
|
DependencyProperty.Register("Level", typeof(int), typeof(DragTreeViewItem)); |
||||||
|
|
||||||
|
public int Level { |
||||||
|
get { return (int)GetValue(LevelProperty); } |
||||||
|
set { SetValue(LevelProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
public DragTreeView ParentTree { get; private set; } |
||||||
|
|
||||||
|
protected override void OnVisualParentChanged(DependencyObject oldParent) |
||||||
|
{ |
||||||
|
base.OnVisualParentChanged(oldParent); |
||||||
|
|
||||||
|
var parentItem = ItemsControl.ItemsControlFromItemContainer(this) as DragTreeViewItem; |
||||||
|
if (parentItem != null) Level = parentItem.Level + 1; |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
||||||
|
{ |
||||||
|
base.OnPropertyChanged(e); |
||||||
|
if (e.Property == IsSelectedProperty) { |
||||||
|
if (ParentTree != null) { |
||||||
|
ParentTree.ItemIsSelectedChanged(this); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override DependencyObject GetContainerForItemOverride() |
||||||
|
{ |
||||||
|
return new DragTreeViewItem(); |
||||||
|
} |
||||||
|
|
||||||
|
protected override bool IsItemItsOwnContainerOverride(object item) |
||||||
|
{ |
||||||
|
return item is DragTreeViewItem; |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
||||||
|
{ |
||||||
|
base.OnMouseLeftButtonDown(e); |
||||||
|
if (e.Source is ToggleButton || e.Source is ItemsPresenter) return; |
||||||
|
ParentTree.ItemMouseDown(this); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) |
||||||
|
{ |
||||||
|
base.OnMouseLeftButtonUp(e); |
||||||
|
ParentTree.ItemMouseUp(this); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
<UserControl |
||||||
|
x:Class="ICSharpCode.XamlDesigner.EnumBar" |
||||||
|
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||||
|
<StackPanel x:Name="uxPanel" |
||||||
|
Orientation="Horizontal" /> |
||||||
|
</UserControl> |
||||||
@ -0,0 +1,72 @@ |
|||||||
|
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; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public partial class EnumBar |
||||||
|
{ |
||||||
|
public EnumBar() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
Type currentEnumType; |
||||||
|
|
||||||
|
public static readonly DependencyProperty ValueProperty = |
||||||
|
DependencyProperty.Register("Value", typeof(object), typeof(EnumBar), |
||||||
|
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
||||||
|
|
||||||
|
public object Value { |
||||||
|
get { return (object)GetValue(ValueProperty); } |
||||||
|
set { SetValue(ValueProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
||||||
|
{ |
||||||
|
base.OnPropertyChanged(e); |
||||||
|
|
||||||
|
if (e.Property == ValueProperty) { |
||||||
|
var type = e.NewValue.GetType(); |
||||||
|
|
||||||
|
if (currentEnumType != type) { |
||||||
|
currentEnumType = type; |
||||||
|
uxPanel.Children.Clear(); |
||||||
|
foreach (var v in Enum.GetValues(type)) { |
||||||
|
var b = new EnumButton(); |
||||||
|
b.Value = v; |
||||||
|
b.Content = Enum.GetName(type, v); |
||||||
|
b.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(button_PreviewMouseLeftButtonDown); |
||||||
|
uxPanel.Children.Add(b); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
foreach (EnumButton c in uxPanel.Children) { |
||||||
|
if (c.Value.Equals(Value)) { |
||||||
|
c.IsChecked = true; |
||||||
|
} |
||||||
|
else { |
||||||
|
c.IsChecked = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
||||||
|
{ |
||||||
|
Value = (sender as EnumButton).Value; |
||||||
|
e.Handled = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Controls.Primitives; |
||||||
|
using System.Windows; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public class EnumButton : ToggleButton |
||||||
|
{ |
||||||
|
static EnumButton() |
||||||
|
{ |
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumButton), |
||||||
|
new FrameworkPropertyMetadata(typeof(EnumButton))); |
||||||
|
} |
||||||
|
|
||||||
|
public static readonly DependencyProperty ValueProperty = |
||||||
|
DependencyProperty.Register("Value", typeof(object), typeof(EnumButton)); |
||||||
|
|
||||||
|
public object Value { |
||||||
|
get { return (object)GetValue(ValueProperty); } |
||||||
|
set { SetValue(ValueProperty, value); } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Media; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public class IconItem : Control |
||||||
|
{ |
||||||
|
static IconItem() |
||||||
|
{ |
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(IconItem), |
||||||
|
new FrameworkPropertyMetadata(typeof(IconItem))); |
||||||
|
} |
||||||
|
|
||||||
|
public static readonly DependencyProperty IconProperty = |
||||||
|
DependencyProperty.Register("Icon", typeof(ImageSource), typeof(IconItem)); |
||||||
|
|
||||||
|
public ImageSource Icon { |
||||||
|
get { return (ImageSource)GetValue(IconProperty); } |
||||||
|
set { SetValue(IconProperty, value); } |
||||||
|
} |
||||||
|
|
||||||
|
public static readonly DependencyProperty TextProperty = |
||||||
|
DependencyProperty.Register("Text", typeof(string), typeof(IconItem)); |
||||||
|
|
||||||
|
public string Text { |
||||||
|
get { return (string)GetValue(TextProperty); } |
||||||
|
set { SetValue(TextProperty, value); } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,107 +1,29 @@ |
|||||||
<UserControl x:Class="ICSharpCode.XamlDesigner.Outline" |
<UserControl x:Class="ICSharpCode.XamlDesigner.Outline" |
||||||
|
x:Name="root" |
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
xmlns:XamlDesigner="clr-namespace:ICSharpCode.XamlDesigner;assembly=" |
xmlns:Default="clr-namespace:ICSharpCode.XamlDesigner" |
||||||
DataContext="{Binding CurrentDocument}"> |
xmlns:Converters="clr-namespace:ICSharpCode.XamlDesigner.Converters"> |
||||||
|
|
||||||
<UserControl.Resources> |
<UserControl.Resources> |
||||||
|
|
||||||
<Style TargetType="{x:Type XamlDesigner:OutlineTree}"> |
<HierarchicalDataTemplate DataType="{x:Type Default:OutlineNode}" |
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type XamlDesigner:OutlineTree}"> |
|
||||||
<Grid> |
|
||||||
<ScrollViewer> |
|
||||||
<ItemsPresenter /> |
|
||||||
</ScrollViewer> |
|
||||||
<Border x:Name="PART_InsertLine" |
|
||||||
Background="#FFC73C" |
|
||||||
Height="2" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Visibility="Collapsed" |
|
||||||
IsHitTestVisible="False" /> |
|
||||||
</Grid> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type XamlDesigner:OutlineTreeItem}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type XamlDesigner:OutlineTreeItem}"> |
|
||||||
<DockPanel Background="Transparent"> |
|
||||||
<Grid DockPanel.Dock="Top"> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
<ColumnDefinition /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<Border x:Name="Bg" |
|
||||||
Background="{TemplateBinding Background}" |
|
||||||
Grid.ColumnSpan="2" |
|
||||||
Margin="0 1 0 0" /> |
|
||||||
<ToggleButton x:Name="Expander" |
|
||||||
Width="19" |
|
||||||
Margin="{TemplateBinding Indent}" |
|
||||||
Style="{StaticResource ExpandCollapseToggleStyle}" |
|
||||||
ClickMode="Press" |
|
||||||
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" /> |
|
||||||
<ContentPresenter x:Name="PART_Header" |
|
||||||
ContentSource="Header" |
|
||||||
Grid.Column="1" /> |
|
||||||
</Grid> |
|
||||||
<ItemsPresenter x:Name="ItemsHost" /> |
|
||||||
</DockPanel> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsExpanded" |
|
||||||
Value="false"> |
|
||||||
<Setter TargetName="ItemsHost" |
|
||||||
Property="Visibility" |
|
||||||
Value="Collapsed" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="HasItems" |
|
||||||
Value="false"> |
|
||||||
<Setter TargetName="Expander" |
|
||||||
Property="Visibility" |
|
||||||
Value="Hidden" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsSelected" |
|
||||||
Value="true"> |
|
||||||
<Setter TargetName="Bg" |
|
||||||
Property="Background" |
|
||||||
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> |
|
||||||
<Setter Property="Foreground" |
|
||||||
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type XamlDesigner:TreeNode}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type XamlDesigner:TreeNode}"> |
|
||||||
<StackPanel Orientation="Horizontal"> |
|
||||||
<Image Source="{TemplateBinding Image}" |
|
||||||
Stretch="None" /> |
|
||||||
<ContentPresenter VerticalAlignment="Center" |
|
||||||
Margin="5 0 0 0" /> |
|
||||||
</StackPanel> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<HierarchicalDataTemplate DataType="{x:Type XamlDesigner:DocumentElement}" |
|
||||||
ItemsSource="{Binding Children}"> |
ItemsSource="{Binding Children}"> |
||||||
<XamlDesigner:TreeNode Image="Images/Tag.png" |
<Default:IconItem Icon="Images/Tag.png" |
||||||
Content="{Binding XamlType.Name}" /> |
Text="{Binding Name}" /> |
||||||
</HierarchicalDataTemplate> |
</HierarchicalDataTemplate> |
||||||
|
|
||||||
</UserControl.Resources> |
</UserControl.Resources> |
||||||
|
|
||||||
<XamlDesigner:OutlineTree ItemsSource="{Binding EnumerateRoot}" |
<Default:OutlineTreeView Root="{Binding Root, ElementName=root}"> |
||||||
Selection="{Binding Selection, Mode=OneWay}" /> |
<ItemsControl.ItemContainerStyle> |
||||||
|
<Style TargetType="{x:Type Default:DragTreeViewItem}"> |
||||||
|
<Setter Property="IsSelected" |
||||||
|
Value="{Binding IsSelected}" /> |
||||||
|
<Setter Property="IsExpanded" |
||||||
|
Value="{Binding IsExpanded, Mode=TwoWay}" /> |
||||||
|
</Style> |
||||||
|
</ItemsControl.ItemContainerStyle> |
||||||
|
</Default:OutlineTreeView> |
||||||
|
|
||||||
</UserControl> |
</UserControl> |
||||||
|
|||||||
@ -0,0 +1,214 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.ComponentModel; |
||||||
|
using ICSharpCode.WpfDesign; |
||||||
|
using System.Collections.ObjectModel; |
||||||
|
using System.Collections; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public class OutlineNode : INotifyPropertyChanged |
||||||
|
{ |
||||||
|
public OutlineNode(DesignItem designItem) |
||||||
|
{ |
||||||
|
DesignItem = designItem; |
||||||
|
UpdateChildren(); |
||||||
|
|
||||||
|
//TODO (possible bug)
|
||||||
|
DesignItem.NameChanged += new EventHandler(DesignItem_NameChanged); |
||||||
|
DesignItem.PropertyChanged += new PropertyChangedEventHandler(DesignItem_PropertyChanged); |
||||||
|
SelectionService.SelectionChanged += new EventHandler<DesignItemCollectionEventArgs>(Selection_SelectionChanged); |
||||||
|
} |
||||||
|
|
||||||
|
bool freezeChildren; |
||||||
|
|
||||||
|
public DesignItem DesignItem { get; private set; } |
||||||
|
public OutlineNode Parent { get; private set; } |
||||||
|
|
||||||
|
public ISelectionService SelectionService { |
||||||
|
get { return DesignItem.Services.Selection; } |
||||||
|
} |
||||||
|
|
||||||
|
bool isExpanded = true; |
||||||
|
|
||||||
|
public bool IsExpanded { |
||||||
|
get { |
||||||
|
return isExpanded; |
||||||
|
} |
||||||
|
set { |
||||||
|
isExpanded = value; |
||||||
|
RaisePropertyChanged("IsExpanded"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool isSelected; |
||||||
|
|
||||||
|
public bool IsSelected { |
||||||
|
get { |
||||||
|
return isSelected; |
||||||
|
} |
||||||
|
set { |
||||||
|
if (isSelected != value) { |
||||||
|
isSelected = value; |
||||||
|
SelectionService.SetSelectedComponents(new[] { DesignItem }, |
||||||
|
value ? SelectionTypes.Add : SelectionTypes.Remove); |
||||||
|
RaisePropertyChanged("IsSelected"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ObservableCollection<OutlineNode> children = new ObservableCollection<OutlineNode>(); |
||||||
|
|
||||||
|
public ObservableCollection<OutlineNode> Children { |
||||||
|
get { return children; } |
||||||
|
} |
||||||
|
|
||||||
|
public string Name { |
||||||
|
get { |
||||||
|
if (string.IsNullOrEmpty(DesignItem.Name)) { |
||||||
|
return DesignItem.ComponentType.Name; |
||||||
|
} |
||||||
|
return DesignItem.ComponentType.Name + " (" + DesignItem.Name + ")"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e) |
||||||
|
{ |
||||||
|
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem); |
||||||
|
} |
||||||
|
|
||||||
|
void DesignItem_NameChanged(object sender, EventArgs e) |
||||||
|
{ |
||||||
|
RaisePropertyChanged("Name"); |
||||||
|
} |
||||||
|
|
||||||
|
void DesignItem_PropertyChanged(object sender, PropertyChangedEventArgs e) |
||||||
|
{ |
||||||
|
if (e.PropertyName == DesignItem.ContentPropertyName) { |
||||||
|
UpdateChildren(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void UpdateChildren() |
||||||
|
{ |
||||||
|
if (freezeChildren) return; |
||||||
|
if (DesignItem.ContentPropertyName != null) { |
||||||
|
var content = DesignItem.ContentProperty; |
||||||
|
if (content.IsCollection) { |
||||||
|
UpdateChildrenCore(content.CollectionElements); |
||||||
|
} |
||||||
|
else { |
||||||
|
if (content.Value != null) { |
||||||
|
UpdateChildrenCore(new[] { content.Value }); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void UpdateChildrenCore(IEnumerable<DesignItem> items) |
||||||
|
{ |
||||||
|
var cache = Children.ToDictionary(n => n.DesignItem); |
||||||
|
|
||||||
|
Children.Clear(); |
||||||
|
|
||||||
|
foreach (var item in items) { |
||||||
|
OutlineNode node; |
||||||
|
if (!cache.TryGetValue(item, out node)) { |
||||||
|
node = new OutlineNode(item); |
||||||
|
} |
||||||
|
Children.Add(node); |
||||||
|
node.Parent = this; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool CanInsert(IEnumerable<OutlineNode> nodes, OutlineNode after, bool copy) |
||||||
|
{ |
||||||
|
if (DesignItem.ContentPropertyName == null) return false; |
||||||
|
|
||||||
|
if (DesignItem.ContentProperty.IsCollection) { |
||||||
|
foreach (var node in nodes) { |
||||||
|
if (!CanAdd(DesignItem.ContentProperty.ReturnType, |
||||||
|
node.DesignItem.ComponentType)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
else { |
||||||
|
return after == null && nodes.Count() == 1 && |
||||||
|
DesignItem.ContentProperty.DeclaringType.IsAssignableFrom( |
||||||
|
nodes.First().DesignItem.ComponentType); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static bool CanAdd(Type col, Type item) |
||||||
|
{ |
||||||
|
var e = col.GetInterface("IEnumerable`1"); |
||||||
|
if (e != null && e.IsGenericType) { |
||||||
|
var a = e.GetGenericArguments()[0]; |
||||||
|
return a.IsAssignableFrom(item); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public void Insert(IEnumerable<OutlineNode> nodes, OutlineNode after, bool copy) |
||||||
|
{ |
||||||
|
freezeChildren = true; |
||||||
|
|
||||||
|
if (copy) { |
||||||
|
nodes = nodes.Select(n => new OutlineNode(n.DesignItem.Clone())); |
||||||
|
} |
||||||
|
else { |
||||||
|
foreach (var node in nodes) { |
||||||
|
Remove(node); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var index = after == null ? 0 : Children.IndexOf(after) + 1; |
||||||
|
var tempIndex = index; |
||||||
|
|
||||||
|
foreach (var node in nodes) { |
||||||
|
Children.Insert(tempIndex++, node); |
||||||
|
node.Parent = this; |
||||||
|
} |
||||||
|
|
||||||
|
var content = DesignItem.ContentProperty; |
||||||
|
if (content.IsCollection) { |
||||||
|
tempIndex = index; |
||||||
|
foreach (var node in nodes) { |
||||||
|
content.CollectionElements.Insert(tempIndex++, node.DesignItem); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
content.SetValue(nodes.First().DesignItem); |
||||||
|
} |
||||||
|
|
||||||
|
freezeChildren = false; |
||||||
|
} |
||||||
|
|
||||||
|
void Remove(OutlineNode node) |
||||||
|
{ |
||||||
|
node.DesignItem.Remove(); |
||||||
|
|
||||||
|
if (node.Parent != null) { |
||||||
|
node.Parent.Children.Remove(node); |
||||||
|
node.Parent = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#region INotifyPropertyChanged Members
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged; |
||||||
|
|
||||||
|
void RaisePropertyChanged(string name) |
||||||
|
{ |
||||||
|
if (PropertyChanged != null) { |
||||||
|
PropertyChanged(this, new PropertyChangedEventArgs(name)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endregion
|
||||||
|
} |
||||||
|
} |
||||||
@ -1,267 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using System.Collections.ObjectModel; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
|
|
||||||
namespace ICSharpCode.XamlDesigner |
|
||||||
{ |
|
||||||
public class OutlineTree : TreeView |
|
||||||
{ |
|
||||||
public OutlineTree() |
|
||||||
{ |
|
||||||
AllowDrop = true; |
|
||||||
new DragListener(this).DragStarted += new MouseEventHandler(TreeList_DragStarted); |
|
||||||
DragEnter += new DragEventHandler(TreeList_DragEnter); |
|
||||||
DragOver += new DragEventHandler(TreeList_DragOver); |
|
||||||
Drop += new DragEventHandler(TreeList_Drop); |
|
||||||
|
|
||||||
//Selection = new ObservableCollection<object>();
|
|
||||||
} |
|
||||||
|
|
||||||
Border insertLine; |
|
||||||
OutlineTreeItem markedItem; |
|
||||||
OutlineTreeItem possibleSelection; |
|
||||||
List<OutlineTreeItem> selectionNodes = new List<OutlineTreeItem>(); |
|
||||||
|
|
||||||
public static readonly DependencyProperty SelectionProperty = |
|
||||||
DependencyProperty.Register("Selection", typeof(ObservableCollection<DocumentElement>), typeof(OutlineTree)); |
|
||||||
|
|
||||||
public ObservableCollection<DocumentElement> Selection { |
|
||||||
get { return (ObservableCollection<DocumentElement>)GetValue(SelectionProperty); } |
|
||||||
set { SetValue(SelectionProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
} |
|
||||||
|
|
||||||
public override void OnApplyTemplate() |
|
||||||
{ |
|
||||||
base.OnApplyTemplate(); |
|
||||||
insertLine = (Border)Template.FindName("PART_InsertLine", this); |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyObject GetContainerForItemOverride() |
|
||||||
{ |
|
||||||
return new OutlineTreeItem(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override bool IsItemItsOwnContainerOverride(object item) |
|
||||||
{ |
|
||||||
return item is OutlineTreeItem; |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual DragDropEffects CanDrag(object obj) |
|
||||||
{ |
|
||||||
return DragDropEffects.Move; |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual DragDropEffects CanDrop(object obj, object parent, int index) |
|
||||||
{ |
|
||||||
return DragDropEffects.Move; |
|
||||||
} |
|
||||||
|
|
||||||
void TreeList_DragOver(object sender, DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrag(e); |
|
||||||
} |
|
||||||
|
|
||||||
void TreeList_DragEnter(object sender, DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrag(e); |
|
||||||
} |
|
||||||
|
|
||||||
void TreeList_Drop(object sender, DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrop(e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragLeave(DragEventArgs e) |
|
||||||
{ |
|
||||||
HideDropMarkers(); |
|
||||||
} |
|
||||||
|
|
||||||
void TreeList_DragStarted(object sender, MouseEventArgs e) |
|
||||||
{ |
|
||||||
possibleSelection = null; |
|
||||||
object obj = (e.OriginalSource as FrameworkElement).DataContext; |
|
||||||
if (obj != null) { |
|
||||||
DragDropEffects effects = CanDrag(obj); |
|
||||||
if (effects != DragDropEffects.None) { |
|
||||||
DragDrop.DoDragDrop(this, obj, effects); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ProcessDrag(DragEventArgs e) |
|
||||||
{ |
|
||||||
e.Effects = DragDropEffects.Move; |
|
||||||
e.Handled = true; |
|
||||||
|
|
||||||
OutlineTreeItem treeItem = (e.OriginalSource as DependencyObject).FindAncestor<OutlineTreeItem>(); |
|
||||||
if (treeItem != null) { |
|
||||||
HideDropMarkers(); |
|
||||||
|
|
||||||
ContentPresenter header = treeItem.HeaderPresenter; |
|
||||||
Point p = e.GetPosition(header); |
|
||||||
int part = (int)(p.Y / (header.ActualHeight / 3)); |
|
||||||
|
|
||||||
if (part == 1) { |
|
||||||
markedItem = treeItem; |
|
||||||
markedItem.Background = insertLine.Background; |
|
||||||
} |
|
||||||
else { |
|
||||||
insertLine.Visibility = Visibility.Visible; |
|
||||||
p = header.TransformToVisual(this).Transform(new Point()); |
|
||||||
double y = part == 0 ? p.Y : p.Y + header.ActualHeight; |
|
||||||
insertLine.Margin = new Thickness(0, y, 0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ProcessDrop(DragEventArgs e) |
|
||||||
{ |
|
||||||
HideDropMarkers(); |
|
||||||
} |
|
||||||
|
|
||||||
void HideDropMarkers() |
|
||||||
{ |
|
||||||
insertLine.Visibility = Visibility.Collapsed; |
|
||||||
if (markedItem != null) { |
|
||||||
markedItem.ClearValue(OutlineTreeItem.BackgroundProperty); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Select(OutlineTreeItem item) |
|
||||||
{ |
|
||||||
item.IsSelected = true; |
|
||||||
Selection.Add(item.Element); |
|
||||||
selectionNodes.Add(item); |
|
||||||
} |
|
||||||
|
|
||||||
void SelectOnly(OutlineTreeItem item) |
|
||||||
{ |
|
||||||
foreach (var node in selectionNodes) { |
|
||||||
node.IsSelected = false; |
|
||||||
} |
|
||||||
Selection.Clear(); |
|
||||||
Select(item); |
|
||||||
} |
|
||||||
|
|
||||||
void Unselect(OutlineTreeItem item) |
|
||||||
{ |
|
||||||
item.IsSelected = false; |
|
||||||
Selection.Remove(item.Element); |
|
||||||
selectionNodes.Remove(item); |
|
||||||
} |
|
||||||
|
|
||||||
internal void HandleItemMouseDown(OutlineTreeItem item) |
|
||||||
{ |
|
||||||
bool control = Keyboard.IsKeyDown(Key.LeftCtrl); |
|
||||||
if (item.IsSelected) { |
|
||||||
if (control) { |
|
||||||
Unselect(item); |
|
||||||
} |
|
||||||
else { |
|
||||||
possibleSelection = item; |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
if (control) { |
|
||||||
Select(item); |
|
||||||
} |
|
||||||
else { |
|
||||||
SelectOnly(item); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal void HandleItemMouseUp(OutlineTreeItem item) |
|
||||||
{ |
|
||||||
if (possibleSelection != null) { |
|
||||||
SelectOnly(possibleSelection); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class OutlineTreeItem : TreeViewItem |
|
||||||
{ |
|
||||||
public new static readonly DependencyProperty IsSelectedProperty = |
|
||||||
Selector.IsSelectedProperty.AddOwner(typeof(OutlineTreeItem)); |
|
||||||
|
|
||||||
public new bool IsSelected { |
|
||||||
get { return (bool)GetValue(IsSelectedProperty); } |
|
||||||
set { SetValue(IsSelectedProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public ContentPresenter HeaderPresenter { |
|
||||||
get { return (ContentPresenter)Template.FindName("PART_Header", this); } |
|
||||||
} |
|
||||||
|
|
||||||
public DocumentElement Element { |
|
||||||
get { return DataContext as DocumentElement; } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty IndentProperty = |
|
||||||
DependencyProperty.Register("Indent", typeof(Thickness), typeof(OutlineTreeItem)); |
|
||||||
|
|
||||||
public Thickness Indent { |
|
||||||
get { return (Thickness)GetValue(IndentProperty); } |
|
||||||
set { SetValue(IndentProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnVisualParentChanged(DependencyObject oldParent) |
|
||||||
{ |
|
||||||
base.OnVisualParentChanged(oldParent); |
|
||||||
OutlineTreeItem parent = ItemsControl.ItemsControlFromItemContainer(this) as OutlineTreeItem; |
|
||||||
Indent = parent == null ? new Thickness() : new Thickness(parent.Indent.Left + 19, 0, 0, 0); |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyObject GetContainerForItemOverride() |
|
||||||
{ |
|
||||||
return new OutlineTreeItem(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override bool IsItemItsOwnContainerOverride(object item) |
|
||||||
{ |
|
||||||
return item is OutlineTreeItem; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Source is ToggleButton || e.Source is ItemsPresenter) return; |
|
||||||
|
|
||||||
OutlineTree tree = this.FindAncestor<OutlineTree>(); |
|
||||||
if (tree != null) { |
|
||||||
tree.HandleItemMouseDown(this); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
OutlineTree tree = this.FindAncestor<OutlineTree>(); |
|
||||||
if (tree != null) { |
|
||||||
tree.HandleItemMouseUp(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class TreeNode : ContentControl |
|
||||||
{ |
|
||||||
public static readonly DependencyProperty ImageProperty = |
|
||||||
DependencyProperty.Register("Image", typeof(ImageSource), typeof(TreeNode)); |
|
||||||
|
|
||||||
public ImageSource Image { |
|
||||||
get { return (ImageSource)GetValue(ImageProperty); } |
|
||||||
set { SetValue(ImageProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,22 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace ICSharpCode.XamlDesigner |
||||||
|
{ |
||||||
|
public class OutlineTreeView : DragTreeView |
||||||
|
{ |
||||||
|
protected override bool CanInsert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||||
|
{ |
||||||
|
return (target.DataContext as OutlineNode).CanInsert(items.Select(t => t.DataContext as OutlineNode), |
||||||
|
after == null ? null : after.DataContext as OutlineNode, copy); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void Insert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
||||||
|
{ |
||||||
|
(target.DataContext as OutlineNode).Insert(items.Select(t => t.DataContext as OutlineNode), |
||||||
|
after == null ? null : after.DataContext as OutlineNode, copy); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,159 @@ |
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:Default="clr-namespace:ICSharpCode.XamlDesigner" |
||||||
|
xmlns:Converters="clr-namespace:ICSharpCode.XamlDesigner.Converters"> |
||||||
|
|
||||||
|
<Converters:LevelConverter x:Key="LevelConverter" /> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type Default:IconItem}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type Default:IconItem}"> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Image Source="{TemplateBinding Icon}" |
||||||
|
Stretch="None" /> |
||||||
|
<TextBlock Text="{TemplateBinding Text}" |
||||||
|
VerticalAlignment="Center" |
||||||
|
Margin="5 0 0 0" /> |
||||||
|
</StackPanel> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type Default:EnumButton}" |
||||||
|
BasedOn="{StaticResource {x:Type ToggleButton}}"> |
||||||
|
<Setter Property="Margin" |
||||||
|
Value="3 3 0 3" /> |
||||||
|
<Setter Property="MinWidth" |
||||||
|
Value="50" /> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<Brush x:Key="InsertBrush">#FFC73C</Brush> |
||||||
|
|
||||||
|
<Style x:Key="ExpandButtonStyle" |
||||||
|
TargetType="ToggleButton"> |
||||||
|
<Setter Property="Focusable" |
||||||
|
Value="False" /> |
||||||
|
<Setter Property="ClickMode" |
||||||
|
Value="Press" /> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="ToggleButton"> |
||||||
|
<Border Background="Transparent"> |
||||||
|
<Border Width="9" |
||||||
|
Height="9" |
||||||
|
SnapsToDevicePixels="true" |
||||||
|
BorderBrush="#FF7898B5" |
||||||
|
BorderThickness="1" |
||||||
|
CornerRadius="1"> |
||||||
|
<Border.Background> |
||||||
|
<LinearGradientBrush EndPoint="1,1" |
||||||
|
StartPoint="0,0"> |
||||||
|
<GradientStop Color="White" |
||||||
|
Offset=".2" /> |
||||||
|
<GradientStop Color="#FFC0B7A6" |
||||||
|
Offset="1" /> |
||||||
|
</LinearGradientBrush> |
||||||
|
</Border.Background> |
||||||
|
<Path Margin="1,1,1,1" |
||||||
|
x:Name="ExpandPath" |
||||||
|
Fill="Black" |
||||||
|
Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z" /> |
||||||
|
</Border> |
||||||
|
</Border> |
||||||
|
<ControlTemplate.Triggers> |
||||||
|
<Trigger Property="IsChecked" |
||||||
|
Value="True"> |
||||||
|
<Setter Property="Data" |
||||||
|
TargetName="ExpandPath" |
||||||
|
Value="M 0 2 L 0 3 L 5 3 L 5 2 Z" /> |
||||||
|
</Trigger> |
||||||
|
</ControlTemplate.Triggers> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type Default:DragTreeView}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type Default:DragTreeView}"> |
||||||
|
<Grid Background="White"> |
||||||
|
<ScrollViewer HorizontalScrollBarVisibility="Auto" |
||||||
|
VerticalScrollBarVisibility="Auto"> |
||||||
|
<ItemsPresenter /> |
||||||
|
</ScrollViewer> |
||||||
|
<Border x:Name="PART_InsertLine" |
||||||
|
Background="{StaticResource InsertBrush}" |
||||||
|
Height="2" |
||||||
|
Width="50" |
||||||
|
HorizontalAlignment="Left" |
||||||
|
VerticalAlignment="Top" |
||||||
|
Visibility="Collapsed" |
||||||
|
IsHitTestVisible="False" /> |
||||||
|
</Grid> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type Default:DragTreeViewItem}"> |
||||||
|
<Setter Property="Foreground" |
||||||
|
Value="{x:Static SystemColors.ControlTextBrush}" /> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type Default:DragTreeViewItem}"> |
||||||
|
|
||||||
|
<DockPanel Background="White"> |
||||||
|
<DockPanel x:Name="bg" |
||||||
|
DockPanel.Dock="Top" |
||||||
|
Background="{TemplateBinding Background}"> |
||||||
|
<ToggleButton x:Name="expandButton" |
||||||
|
Style="{StaticResource ExpandButtonStyle}" |
||||||
|
DockPanel.Dock="Left" |
||||||
|
Margin="{TemplateBinding Level, Converter={StaticResource LevelConverter}}" |
||||||
|
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" /> |
||||||
|
<Border x:Name="contentBorder" |
||||||
|
HorizontalAlignment="Left"> |
||||||
|
<ContentPresenter x:Name="PART_Header" |
||||||
|
ContentSource="Header" /> |
||||||
|
</Border> |
||||||
|
</DockPanel> |
||||||
|
<ItemsPresenter x:Name="itemsHost" /> |
||||||
|
</DockPanel> |
||||||
|
|
||||||
|
<ControlTemplate.Triggers> |
||||||
|
<Trigger Property="IsExpanded" |
||||||
|
Value="False"> |
||||||
|
<Setter TargetName="itemsHost" |
||||||
|
Property="Visibility" |
||||||
|
Value="Collapsed" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="HasItems" |
||||||
|
Value="False"> |
||||||
|
<Setter TargetName="expandButton" |
||||||
|
Property="Visibility" |
||||||
|
Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsSelected" |
||||||
|
Value="True"> |
||||||
|
<Setter TargetName="bg" |
||||||
|
Property="Background" |
||||||
|
Value="{x:Static SystemColors.HighlightBrush}" /> |
||||||
|
<Setter Property="Foreground" |
||||||
|
Value="{x:Static SystemColors.HighlightTextBrush}" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsDragHover" |
||||||
|
Value="True"> |
||||||
|
<Setter TargetName="contentBorder" |
||||||
|
Property="Background" |
||||||
|
Value="{StaticResource InsertBrush}" /> |
||||||
|
</Trigger> |
||||||
|
</ControlTemplate.Triggers> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
</ResourceDictionary> |
||||||
@ -1,133 +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.ComponentModel; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// The "dot" button appearing after dependency properties to specified advanced values like data bindings.
|
|
||||||
/// </summary>
|
|
||||||
public class DependencyPropertyDotButton : ButtonBase |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Dependency property for <see cref="Checked"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly DependencyProperty CheckedProperty |
|
||||||
= DependencyProperty.Register("Checked", typeof(bool), typeof(DependencyPropertyDotButton), |
|
||||||
new FrameworkPropertyMetadata(false)); |
|
||||||
|
|
||||||
static DependencyPropertyDotButton() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DependencyPropertyDotButton), new FrameworkPropertyMetadata(typeof(DependencyPropertyDotButton))); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new DependencyPropertyDotButton instance.
|
|
||||||
/// </summary>
|
|
||||||
public DependencyPropertyDotButton() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
IPropertyEditorDataProperty property; |
|
||||||
|
|
||||||
bool isIsSetChangedEventHandlerAttached; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new DependencyPropertyDotButton instance that binds its Checked property to the
|
|
||||||
/// data properties IsSet property.
|
|
||||||
/// </summary>
|
|
||||||
public DependencyPropertyDotButton(IPropertyEditorDataProperty property) |
|
||||||
{ |
|
||||||
if (property == null) |
|
||||||
throw new ArgumentNullException("property"); |
|
||||||
this.property = property; |
|
||||||
|
|
||||||
this.Loaded += delegate { |
|
||||||
if (!isIsSetChangedEventHandlerAttached) { |
|
||||||
isIsSetChangedEventHandlerAttached = true; |
|
||||||
this.property.IsSetChanged += OnIsSetChanged; |
|
||||||
OnIsSetChanged(null, null); |
|
||||||
} |
|
||||||
}; |
|
||||||
this.Unloaded += delegate { |
|
||||||
if (isIsSetChangedEventHandlerAttached) { |
|
||||||
isIsSetChangedEventHandlerAttached = false; |
|
||||||
this.property.IsSetChanged -= OnIsSetChanged; |
|
||||||
} |
|
||||||
}; |
|
||||||
OnIsSetChanged(null, null); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates the context menu on-demand.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnContextMenuOpening(ContextMenuEventArgs e) |
|
||||||
{ |
|
||||||
ContextMenu = CreateContextMenu(); |
|
||||||
base.OnContextMenuOpening(e); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets if the button looks checked.
|
|
||||||
/// </summary>
|
|
||||||
public bool Checked { |
|
||||||
get { return (bool)GetValue(CheckedProperty); } |
|
||||||
set { SetValue(CheckedProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
void OnIsSetChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
this.Checked = property.IsSet; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fires the Click event and opens the context menu.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnClick() |
|
||||||
{ |
|
||||||
base.OnClick(); |
|
||||||
ContextMenu = CreateContextMenu(); |
|
||||||
ContextMenu.IsOpen = true; |
|
||||||
} |
|
||||||
|
|
||||||
internal ContextMenu CreateContextMenu() |
|
||||||
{ |
|
||||||
ContextMenu contextMenu = new ContextMenu(); |
|
||||||
if (property.IsSet) { |
|
||||||
contextMenu.Items.Add(CreateMenuItem("_Reset", OnResetClick)); |
|
||||||
} else { |
|
||||||
contextMenu.Items.Add(CreateMenuItem("_Copy to local", OnCopyToLocalClick)); |
|
||||||
} |
|
||||||
return contextMenu; |
|
||||||
} |
|
||||||
|
|
||||||
MenuItem CreateMenuItem(string title, RoutedEventHandler handler) |
|
||||||
{ |
|
||||||
MenuItem item = new MenuItem(); |
|
||||||
item.Header = title; |
|
||||||
item.Click += handler; |
|
||||||
return item; |
|
||||||
} |
|
||||||
|
|
||||||
void OnResetClick(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
property.IsSet = false; |
|
||||||
} |
|
||||||
|
|
||||||
void OnCopyToLocalClick(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
property.IsSet = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,80 +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: 2667$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// The combo box used to enter the event handler which an event is connected to.
|
|
||||||
/// </summary>
|
|
||||||
sealed class EventHandlerEditor : ComboBox |
|
||||||
{ |
|
||||||
readonly IPropertyEditorDataEvent dataEvent; |
|
||||||
|
|
||||||
public EventHandlerEditor(IPropertyEditorDataEvent dataEvent) |
|
||||||
{ |
|
||||||
this.dataEvent = dataEvent; |
|
||||||
this.IsEditable = true; |
|
||||||
|
|
||||||
Loaded += delegate { |
|
||||||
dataEvent.HandlerNameChanged += OnEventHandlerNameChanged; |
|
||||||
OnEventHandlerNameChanged(null, null); |
|
||||||
}; |
|
||||||
Unloaded += delegate { |
|
||||||
dataEvent.HandlerNameChanged -= OnEventHandlerNameChanged; |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
void OnEventHandlerNameChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
this.Text = dataEvent.HandlerName; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e) |
|
||||||
{ |
|
||||||
base.OnKeyDown(e); |
|
||||||
|
|
||||||
if (e.Handled) |
|
||||||
return; |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
dataEvent.HandlerName = this.Text; |
|
||||||
if (!string.IsNullOrEmpty(dataEvent.HandlerName)) { |
|
||||||
dataEvent.GoToHandler(); |
|
||||||
} |
|
||||||
e.Handled = true; |
|
||||||
} else if (e.Key == Key.Escape) { |
|
||||||
this.Text = dataEvent.HandlerName; |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnLostKeyboardFocus(e); |
|
||||||
if (string.IsNullOrEmpty(this.Text)) |
|
||||||
dataEvent.HandlerName = null; |
|
||||||
else |
|
||||||
this.Text = dataEvent.HandlerName; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseDoubleClick(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
e.Handled = true; |
|
||||||
DoubleClick(); |
|
||||||
} |
|
||||||
|
|
||||||
public void DoubleClick() |
|
||||||
{ |
|
||||||
dataEvent.GoToHandler(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,197 +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.ComponentModel; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Linq; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Shows a list of properties; supports data binding.
|
|
||||||
/// </summary>
|
|
||||||
public partial class PropertyEditor : UserControl |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Dependency property for <see cref="EditedObject"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly DependencyProperty EditedObjectProperty |
|
||||||
= DependencyProperty.Register("EditedObject", typeof(IPropertyEditorDataSource), typeof(PropertyEditor), |
|
||||||
new FrameworkPropertyMetadata(null, _OnEditedObjectPropertyChanged)); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new PropertyEditor instance.
|
|
||||||
/// </summary>
|
|
||||||
public PropertyEditor() |
|
||||||
{ |
|
||||||
try { |
|
||||||
InitializeComponent(); |
|
||||||
} catch (Exception ex) { |
|
||||||
Debug.WriteLine(ex.ToString()); |
|
||||||
throw; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets the object being edited.
|
|
||||||
/// </summary>
|
|
||||||
public IPropertyEditorDataSource EditedObject { |
|
||||||
get { return (IPropertyEditorDataSource)GetValue(EditedObjectProperty); } |
|
||||||
set { SetValue(EditedObjectProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is raised when the value of the <see cref="EditedObject"/> property changes.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler EditedObjectChanged; |
|
||||||
|
|
||||||
static void _OnEditedObjectPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
((PropertyEditor)obj).OnEditedObjectPropertyChanged(e); |
|
||||||
} |
|
||||||
|
|
||||||
void OnEditedObjectPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
IPropertyEditorDataSource dataSource = e.NewValue as IPropertyEditorDataSource; |
|
||||||
componentImage.Fill = dataSource != null ? dataSource.CreateThumbnailBrush() : null; |
|
||||||
ShowProperties(dataSource); |
|
||||||
if (EditedObjectChanged != null) { |
|
||||||
EditedObjectChanged(this, EventArgs.Empty); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ShowPropertiesButton_Click(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
ShowProperties(this.EditedObject); |
|
||||||
} |
|
||||||
|
|
||||||
void ShowEventsButton_Click(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
ShowEvents(this.EditedObject); |
|
||||||
} |
|
||||||
|
|
||||||
bool useCategories = false; |
|
||||||
|
|
||||||
void ShowProperties(IPropertyEditorDataSource dataSource) |
|
||||||
{ |
|
||||||
contentStackPanel.Children.Clear(); |
|
||||||
if (dataSource == null) |
|
||||||
return; |
|
||||||
|
|
||||||
if (useCategories) { |
|
||||||
List<PropertyEditorCategoryView> categories = new List<PropertyEditorCategoryView>(); |
|
||||||
foreach (IPropertyEditorDataProperty p in dataSource.Properties.OrderBy(p2 => p2.Name)) { |
|
||||||
if (p.Name == "Name") { |
|
||||||
continue; |
|
||||||
} |
|
||||||
PropertyEditorCategoryView cv = GetOrCreateCategory(categories, p.Category); |
|
||||||
PropertyGridView grid = (PropertyGridView)cv.Content; |
|
||||||
grid.AddProperty(p); |
|
||||||
} |
|
||||||
// Sort category titles alphabetically
|
|
||||||
categories.Sort(delegate (PropertyEditorCategoryView c1, PropertyEditorCategoryView c2) { |
|
||||||
return c1.Header.ToString().CompareTo(c2.Header.ToString()); |
|
||||||
}); |
|
||||||
// Add categories to contentStackPanel
|
|
||||||
foreach (PropertyEditorCategoryView c in categories) { |
|
||||||
contentStackPanel.Children.Add(c); |
|
||||||
} |
|
||||||
} else { |
|
||||||
PropertyGridView grid = new PropertyGridView(); |
|
||||||
contentStackPanel.Children.Add(grid); |
|
||||||
foreach (IPropertyEditorDataProperty p in dataSource.Properties.OrderBy(p2 => p2.Name)) { |
|
||||||
if (p.Name == "Name") { |
|
||||||
continue; |
|
||||||
} |
|
||||||
grid.AddProperty(p); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ShowEvents(IPropertyEditorDataSource dataSource) |
|
||||||
{ |
|
||||||
contentStackPanel.Children.Clear(); |
|
||||||
if (dataSource == null) |
|
||||||
return; |
|
||||||
|
|
||||||
PropertyGridView grid = new PropertyGridView(); |
|
||||||
contentStackPanel.Children.Add(grid); |
|
||||||
foreach (IPropertyEditorDataEvent e in dataSource.Events.OrderBy(p => p.Name)) { |
|
||||||
grid.AddEvent(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
HashSet<string> expandedCategories = new HashSet<string>(); |
|
||||||
|
|
||||||
PropertyEditorCategoryView GetOrCreateCategory(List<PropertyEditorCategoryView> categories, string category) |
|
||||||
{ |
|
||||||
foreach (PropertyEditorCategoryView c in categories) { |
|
||||||
if (c.Header.ToString() == category) |
|
||||||
return c; |
|
||||||
} |
|
||||||
PropertyEditorCategoryView newCategory = new PropertyEditorCategoryView(); |
|
||||||
newCategory.Header = category; |
|
||||||
newCategory.Content = new PropertyGridView(); |
|
||||||
newCategory.IsExpanded = expandedCategories.Contains(category); |
|
||||||
newCategory.Expanded += delegate { |
|
||||||
expandedCategories.Add(category); |
|
||||||
}; |
|
||||||
newCategory.Collapsed += delegate { |
|
||||||
expandedCategories.Remove(category); |
|
||||||
}; |
|
||||||
categories.Add(newCategory); |
|
||||||
return newCategory; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
void clearSearchButton_Click(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
searchTextBox.Text = ""; |
|
||||||
} |
|
||||||
*/ |
|
||||||
|
|
||||||
void nameTextBox_SizeChanged(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
// Display componentImage only if there is enough space left.
|
|
||||||
const double minimalNameTextBoxWidth = 80; |
|
||||||
const double switchTreshold = 5; |
|
||||||
if (componentImage.Visibility != Visibility.Collapsed) { |
|
||||||
if (nameTextBox.ActualWidth < minimalNameTextBoxWidth - switchTreshold) { |
|
||||||
componentImage.Visibility = Visibility.Collapsed; |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (nameTextBox.ActualWidth > minimalNameTextBoxWidth + componentImage.Width + switchTreshold) { |
|
||||||
componentImage.Visibility = Visibility.Visible; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void nameTextBox_KeyDown(object sender, KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Handled) return; |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
nameTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); |
|
||||||
} else if (e.Key == Key.Escape) { |
|
||||||
nameTextBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public TextBox NameTextBox { |
|
||||||
get { return nameTextBox; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,61 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
x:Name="userControl"> |
|
||||||
<DockPanel> |
|
||||||
<Border DockPanel.Dock="Top" |
|
||||||
Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" |
|
||||||
CornerRadius="0 0 0 15" Padding="4"> |
|
||||||
<StackPanel> |
|
||||||
<Grid> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
<ColumnDefinition Width="*" /> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<Rectangle Grid.Column="0" Width="32" Height="32" Name="componentImage"/> |
|
||||||
<Grid Grid.Column="1" Margin="0 0 2 0"> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
<ColumnDefinition Width="*" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<Grid.RowDefinitions> |
|
||||||
<RowDefinition Height="0.5*" /> |
|
||||||
<RowDefinition Height="0.5*" /> |
|
||||||
</Grid.RowDefinitions> |
|
||||||
<Label Grid.Column="0" Grid.Row="0" Target="{Binding ElementName=nameTextBox}">_Name:</Label> |
|
||||||
<TextBox Grid.Column="1" Grid.Row="0" Name="nameTextBox" |
|
||||||
SizeChanged="nameTextBox_SizeChanged" KeyDown="nameTextBox_KeyDown" |
|
||||||
Text="{Binding ElementName=userControl, Path=EditedObject.Name}"/> |
|
||||||
<Label Grid.Column="0" Grid.Row="1">Type:</Label> |
|
||||||
<Label Grid.Column="1" Grid.Row="1" Name="typeLabel" |
|
||||||
Content="{Binding ElementName=userControl, Path=EditedObject.Type}"/> |
|
||||||
</Grid> |
|
||||||
<StackPanel Grid.Column="2" Orientation="Horizontal"> |
|
||||||
<Rectangle Margin="2" Width="1.5" Fill="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"/> |
|
||||||
<Button VerticalAlignment="Center" Click="ShowPropertiesButton_Click">P</Button> |
|
||||||
<Button VerticalAlignment="Center" Click="ShowEventsButton_Click">E</Button> |
|
||||||
</StackPanel> |
|
||||||
</Grid> |
|
||||||
<!-- |
|
||||||
<Rectangle Margin="2" Height="1px" SnapsToDevicePixels="True" |
|
||||||
Fill="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"/> |
|
||||||
<Grid> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
<ColumnDefinition Width="*" /> |
|
||||||
<ColumnDefinition Width="Auto" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<Label>_Search:</Label> |
|
||||||
<TextBox Grid.Column="1" Name="searchTextBox"></TextBox> |
|
||||||
<Button Grid.Column="2" Click="clearSearchButton_Click">X</Button> |
|
||||||
</Grid> |
|
||||||
--> |
|
||||||
</StackPanel> |
|
||||||
</Border> |
|
||||||
<ScrollViewer Margin="0 1 0 0"> |
|
||||||
<StackPanel Name="contentStackPanel"> |
|
||||||
</StackPanel> |
|
||||||
</ScrollViewer> |
|
||||||
</DockPanel> |
|
||||||
</UserControl> |
|
||||||
@ -1,24 +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.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Control used to view a property grid category.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class PropertyEditorCategoryView : Expander |
|
||||||
{ |
|
||||||
static PropertyEditorCategoryView() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyEditorCategoryView), new FrameworkPropertyMetadata(typeof(PropertyEditorCategoryView))); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,73 +0,0 @@ |
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:src="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type src:PropertyEditorCategoryView}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type src:PropertyEditorCategoryView}"> |
|
||||||
<Border Name="border" |
|
||||||
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" |
|
||||||
CornerRadius="10" Margin="1"> |
|
||||||
<Expander Name="expander" IsExpanded="{TemplateBinding IsExpanded}"> |
|
||||||
<Expander.Header> |
|
||||||
<ContentControl Name="header" FontWeight="Bold" |
|
||||||
Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" |
|
||||||
Content="{TemplateBinding Header}"/> |
|
||||||
</Expander.Header> |
|
||||||
<Border Margin="10 0 2 2"> |
|
||||||
<ContentPresenter/> |
|
||||||
</Border> |
|
||||||
</Expander> |
|
||||||
</Border> |
|
||||||
|
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger SourceName="expander" Property="IsExpanded" Value="True"> |
|
||||||
<Setter TargetName="border" Property="Background" |
|
||||||
Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/> |
|
||||||
<Setter TargetName="header" Property="Foreground" |
|
||||||
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type src:PropertyGridView}"> |
|
||||||
|
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type src:DependencyPropertyDotButton}"> |
|
||||||
<Setter Property="Background" Value="Transparent"/> |
|
||||||
<Setter Property="Padding" Value="2"/> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type src:DependencyPropertyDotButton}"> |
|
||||||
<Border |
|
||||||
BorderBrush="{TemplateBinding Border.BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding Border.BorderThickness}" |
|
||||||
Background="{TemplateBinding Panel.Background}" |
|
||||||
SnapsToDevicePixels="True" |
|
||||||
Padding="{TemplateBinding Control.Padding}"> |
|
||||||
<Border Name="hoverBorder" Width="12" Height="12" |
|
||||||
BorderThickness="2" BorderBrush="Transparent" CornerRadius="2"> |
|
||||||
<Rectangle Name="rectangle" |
|
||||||
Stroke="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" |
|
||||||
Fill="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" Value="True"> |
|
||||||
<Setter TargetName="hoverBorder" Property="BorderBrush" Value="#808080FF"/> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="Checked" Value="False"> |
|
||||||
<Setter TargetName="rectangle" Property="Fill" Value="Transparent"/> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
</ResourceDictionary> |
|
||||||
@ -1,102 +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.Windows; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Control used to view a property grid category.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class PropertyGridView : Grid |
|
||||||
{ |
|
||||||
static PropertyGridView() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyGridView), new FrameworkPropertyMetadata(typeof(PropertyGridView))); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new PropertyGridView instance.
|
|
||||||
/// </summary>
|
|
||||||
public PropertyGridView() |
|
||||||
{ |
|
||||||
this.ColumnDefinitions.Add(new ColumnDefinition()); |
|
||||||
this.ColumnDefinitions.Add(new ColumnDefinition()); |
|
||||||
this.ColumnDefinitions.Add(new ColumnDefinition()); |
|
||||||
this.ColumnDefinitions[0].Width = new GridLength(0.48, GridUnitType.Star); |
|
||||||
this.ColumnDefinitions[0].MinWidth = 40; |
|
||||||
this.ColumnDefinitions[1].Width = new GridLength(0.52, GridUnitType.Star); |
|
||||||
this.ColumnDefinitions[2].Width = new GridLength(16); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new property to the PropertyGridView.
|
|
||||||
/// </summary>
|
|
||||||
public void AddProperty(IPropertyEditorDataProperty property) |
|
||||||
{ |
|
||||||
this.RowDefinitions.Add(new RowDefinition()); |
|
||||||
|
|
||||||
// Column 0: name of the property
|
|
||||||
PropertyNameTextBlock propertyNameText = new PropertyNameTextBlock(property); |
|
||||||
propertyNameText.Margin = new Thickness(0, 0, 2, 0); |
|
||||||
SetRow(propertyNameText, this.RowDefinitions.Count - 1); |
|
||||||
SetColumn(propertyNameText, 0); |
|
||||||
this.Children.Add(propertyNameText); |
|
||||||
|
|
||||||
// Column 1: the actual property editor
|
|
||||||
UIElement editor = property.CreateEditor(); |
|
||||||
SetRow(editor, this.RowDefinitions.Count - 1); |
|
||||||
SetColumn(editor, 1); |
|
||||||
this.Children.Add(editor); |
|
||||||
|
|
||||||
// Column 2: a "dot" button
|
|
||||||
DependencyPropertyDotButton dotButton = new DependencyPropertyDotButton(property); |
|
||||||
dotButton.VerticalAlignment = VerticalAlignment.Center; |
|
||||||
dotButton.HorizontalAlignment = HorizontalAlignment.Center; |
|
||||||
SetRow(dotButton, this.RowDefinitions.Count - 1); |
|
||||||
SetColumn(dotButton, 2); |
|
||||||
this.Children.Add(dotButton); |
|
||||||
propertyNameText.ContextMenuProvider = dotButton; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new event to the PropertyGridView.
|
|
||||||
/// </summary>
|
|
||||||
public void AddEvent(IPropertyEditorDataEvent dataEvent) |
|
||||||
{ |
|
||||||
this.RowDefinitions.Add(new RowDefinition()); |
|
||||||
|
|
||||||
// Column 0: name of the event
|
|
||||||
PropertyNameTextBlock propertyNameText = new PropertyNameTextBlock(dataEvent); |
|
||||||
propertyNameText.Margin = new Thickness(0, 0, 2, 0); |
|
||||||
SetRow(propertyNameText, this.RowDefinitions.Count - 1); |
|
||||||
SetColumn(propertyNameText, 0); |
|
||||||
this.Children.Add(propertyNameText); |
|
||||||
|
|
||||||
// Column 1: the actual property editor
|
|
||||||
EventHandlerEditor editor = new EventHandlerEditor(dataEvent); |
|
||||||
SetRow(editor, this.RowDefinitions.Count - 1); |
|
||||||
SetColumn(editor, 1); |
|
||||||
this.Children.Add(editor); |
|
||||||
|
|
||||||
propertyNameText.MouseDown += delegate(object sender, MouseButtonEventArgs e) { |
|
||||||
if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) { |
|
||||||
e.Handled = true; |
|
||||||
editor.DoubleClick(); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
// Column 2: empty
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,75 +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.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Documents; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
// Text block used in the first column of the PropertyGridView.
|
|
||||||
// Creates ToolTip and ContextMenu objects on-demand.
|
|
||||||
sealed class PropertyNameTextBlock : TextBlock |
|
||||||
{ |
|
||||||
readonly IPropertyEditorDataMember property; |
|
||||||
readonly DockPanel toolTipDockPanel; |
|
||||||
bool toolTipInitialized; |
|
||||||
internal DependencyPropertyDotButton ContextMenuProvider; |
|
||||||
|
|
||||||
public PropertyNameTextBlock(IPropertyEditorDataMember property) |
|
||||||
: base(new Run(property.Name)) |
|
||||||
{ |
|
||||||
this.property = property; |
|
||||||
this.TextAlignment = TextAlignment.Right; |
|
||||||
this.TextTrimming = TextTrimming.CharacterEllipsis; |
|
||||||
|
|
||||||
this.ToolTip = toolTipDockPanel = new DockPanel(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnToolTipOpening(ToolTipEventArgs e) |
|
||||||
{ |
|
||||||
CreateToolTip(); |
|
||||||
base.OnToolTipOpening(e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnContextMenuOpening(ContextMenuEventArgs e) |
|
||||||
{ |
|
||||||
if (ContextMenuProvider != null) { |
|
||||||
this.ContextMenu = ContextMenuProvider.CreateContextMenu(); |
|
||||||
} |
|
||||||
base.OnContextMenuOpening(e); |
|
||||||
} |
|
||||||
|
|
||||||
void CreateToolTip() |
|
||||||
{ |
|
||||||
if (toolTipInitialized) |
|
||||||
return; |
|
||||||
toolTipInitialized = true; |
|
||||||
TextBlock textBlock = new TextBlock(); |
|
||||||
textBlock.TextAlignment = TextAlignment.Left; |
|
||||||
textBlock.Inlines.Add(new Bold(new Run(property.Name))); |
|
||||||
if (property.ReturnType != null) { |
|
||||||
textBlock.Inlines.Add(" (" + property.ReturnType.Name + ")"); |
|
||||||
} |
|
||||||
DockPanel.SetDock(textBlock, Dock.Top); |
|
||||||
toolTipDockPanel.Children.Add(textBlock); |
|
||||||
object description = property.GetDescription(); |
|
||||||
if (description is UIElement) { |
|
||||||
toolTipDockPanel.Children.Add((UIElement)description); |
|
||||||
} else if (description is string) { |
|
||||||
textBlock.Inlines.Add(new LineBreak()); |
|
||||||
textBlock.Inlines.Add((string)description); |
|
||||||
} else if (description != null) { |
|
||||||
ContentControl cc = new ContentControl(); |
|
||||||
cc.Content = description; |
|
||||||
toolTipDockPanel.Children.Add(cc); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,234 +0,0 @@ |
|||||||
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
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,10 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,38 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,88 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,47 +0,0 @@ |
|||||||
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(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,12 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,38 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,116 +0,0 @@ |
|||||||
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
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,102 +0,0 @@ |
|||||||
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.0, c.G / 255.0, c.B / 255.0, 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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,232 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,203 +0,0 @@ |
|||||||
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(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,22 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,118 +0,0 @@ |
|||||||
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; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,23 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,11 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,24 +0,0 @@ |
|||||||
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(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,109 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,169 +0,0 @@ |
|||||||
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 |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,71 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,253 +0,0 @@ |
|||||||
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); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,134 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,150 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,19 +0,0 @@ |
|||||||
<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> |
|
||||||
@ -1,34 +0,0 @@ |
|||||||
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,137 +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 System.Windows.Threading; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of ContentEditor.
|
|
||||||
/// </summary>
|
|
||||||
[PropertyEditor(typeof(ContentControl), "Content")] |
|
||||||
[PropertyEditor(typeof(HeaderedContentControl), "Header")] |
|
||||||
[PropertyEditor(typeof(HeaderedItemsControl), "Header")] |
|
||||||
public class ContentEditor : DockPanel |
|
||||||
{ |
|
||||||
readonly IPropertyEditorDataProperty property; |
|
||||||
Button createObjectButton = new DropDownButton(); |
|
||||||
readonly TextBoxEditor textBoxEditor; |
|
||||||
readonly FallbackEditor fallbackEditor; |
|
||||||
readonly DataPropertyWithCustomOnValueChangedEvent textBoxEditorDataProperty, fallbackEditorDataProperty; |
|
||||||
UIElement activeEditor; |
|
||||||
DataPropertyWithCustomOnValueChangedEvent activeEditorDataProperty; |
|
||||||
|
|
||||||
public ContentEditor(IPropertyEditorDataProperty property) |
|
||||||
{ |
|
||||||
this.property = property; |
|
||||||
PropertyEditorBindingHelper.AddValueChangedEventHandler(this, property, OnValueChanged); |
|
||||||
|
|
||||||
createObjectButton.ContextMenuOpening += delegate { |
|
||||||
createObjectButton.ContextMenu = CreateContextMenu(); |
|
||||||
}; |
|
||||||
createObjectButton.Click += delegate { |
|
||||||
createObjectButton.ContextMenu = CreateContextMenu(); |
|
||||||
createObjectButton.ContextMenu.IsOpen = true; |
|
||||||
}; |
|
||||||
SetDock(createObjectButton, Dock.Right); |
|
||||||
this.Children.Add(createObjectButton); |
|
||||||
|
|
||||||
textBoxEditor = new TextBoxEditor(textBoxEditorDataProperty = new DataPropertyWithCustomOnValueChangedEvent(property)); |
|
||||||
fallbackEditor = new FallbackEditor(fallbackEditorDataProperty = new DataPropertyWithCustomOnValueChangedEvent(property)); |
|
||||||
|
|
||||||
OnValueChanged(null, null); |
|
||||||
} |
|
||||||
|
|
||||||
#region CreateObjectButton Context menu
|
|
||||||
ContextMenu CreateContextMenu() |
|
||||||
{ |
|
||||||
ContextMenu contextMenu = new ContextMenu(); |
|
||||||
contextMenu.Items.Add(CreateMenuItem("Set to _null", delegate { property.Value = null; })); |
|
||||||
contextMenu.Items.Add(CreateMenuItem("Create _string", delegate { property.Value = ""; })); |
|
||||||
contextMenu.Items.Add(CreateMenuItem("Create _Canvas", delegate { property.Value = new Canvas(); })); |
|
||||||
contextMenu.Items.Add(CreateMenuItem("Create _Grid", delegate { property.Value = new Grid(); })); |
|
||||||
return contextMenu; |
|
||||||
} |
|
||||||
|
|
||||||
static MenuItem CreateMenuItem(string title, RoutedEventHandler handler) |
|
||||||
{ |
|
||||||
MenuItem item = new MenuItem(); |
|
||||||
item.Header = title; |
|
||||||
item.Click += handler; |
|
||||||
return item; |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
void SetActiveEditor(UIElement newEditor, DataPropertyWithCustomOnValueChangedEvent newDataProperty) |
|
||||||
{ |
|
||||||
if (activeEditor != newEditor) { |
|
||||||
if (activeEditorDataProperty != null) { |
|
||||||
activeEditorDataProperty.preventSetValue = true; |
|
||||||
} |
|
||||||
this.Children.Remove(activeEditor); |
|
||||||
this.Children.Add(newEditor); |
|
||||||
activeEditor = newEditor; |
|
||||||
newDataProperty.preventSetValue = false; |
|
||||||
activeEditorDataProperty = newDataProperty; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void OnValueChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
object val = property.Value; |
|
||||||
if (val is string) { |
|
||||||
SetActiveEditor(textBoxEditor, textBoxEditorDataProperty); |
|
||||||
} else { |
|
||||||
SetActiveEditor(fallbackEditor, fallbackEditorDataProperty); |
|
||||||
} |
|
||||||
// raise ValueChanged after the new editor's Loaded event has fired
|
|
||||||
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, |
|
||||||
(Action)activeEditorDataProperty.RaiseValueChanged); |
|
||||||
} |
|
||||||
|
|
||||||
sealed class DataPropertyWithCustomOnValueChangedEvent : ProxyPropertyEditorDataProperty |
|
||||||
{ |
|
||||||
internal DataPropertyWithCustomOnValueChangedEvent(IPropertyEditorDataProperty property) |
|
||||||
: base(property) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
internal bool preventSetValue; |
|
||||||
|
|
||||||
public override object Value { |
|
||||||
get { return base.Value; } |
|
||||||
set { |
|
||||||
if (!preventSetValue) { |
|
||||||
base.Value = value; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// don't forward add/remove calls to the underlying property, but register them here
|
|
||||||
public override event EventHandler ValueChanged; |
|
||||||
|
|
||||||
public override System.ComponentModel.TypeConverter TypeConverter { |
|
||||||
get { return System.ComponentModel.TypeDescriptor.GetConverter(typeof(string)); } |
|
||||||
} |
|
||||||
|
|
||||||
internal void RaiseValueChanged() |
|
||||||
{ |
|
||||||
if (ValueChanged != null) { |
|
||||||
ValueChanged(this, EventArgs.Empty); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,25 +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.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(System.Windows.Input.Cursor))] |
|
||||||
public class CursorEditor : ComboBox |
|
||||||
{ |
|
||||||
public CursorEditor(IPropertyEditorDataProperty property) |
|
||||||
{ |
|
||||||
foreach (object o in property.TypeConverter.GetStandardValues()) { |
|
||||||
this.Items.Add(o); |
|
||||||
} |
|
||||||
SetBinding(ComboBox.SelectedItemProperty, PropertyEditorBindingHelper.CreateBinding(this, property)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,56 +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.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.PropertyEditor; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(bool?))] |
|
||||||
public class NullableBoolEditor : ComboBox |
|
||||||
{ |
|
||||||
const string NullString = "Null"; |
|
||||||
|
|
||||||
public NullableBoolEditor(IPropertyEditorDataProperty property) |
|
||||||
{ |
|
||||||
// the UI must show the difference between an ambiguous property value
|
|
||||||
// and null, so we use a combo box bound to a string property
|
|
||||||
property = new NullableBoolToStringProperty(property); |
|
||||||
this.ItemsSource = new string[] { NullString, false.ToString(), true.ToString() }; |
|
||||||
SetBinding(ComboBox.SelectedItemProperty, PropertyEditorBindingHelper.CreateBinding(this, property)); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// views a bool? property as string property
|
|
||||||
/// </summary>
|
|
||||||
sealed class NullableBoolToStringProperty : ProxyPropertyEditorDataProperty |
|
||||||
{ |
|
||||||
public NullableBoolToStringProperty(IPropertyEditorDataProperty data) |
|
||||||
: base(data) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public override object Value { |
|
||||||
get { |
|
||||||
object v = base.Value; |
|
||||||
if (v == null) |
|
||||||
return IsAmbiguous ? null : NullString; |
|
||||||
else |
|
||||||
return v.ToString(); |
|
||||||
} |
|
||||||
set { |
|
||||||
string v = (string)value; |
|
||||||
if (v == NullString) |
|
||||||
base.Value = null; |
|
||||||
else |
|
||||||
base.Value = SharedInstances.Box(bool.Parse(v)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue