Add project files.
This commit is contained in:
179
Examples/Nodify.Shared/Controls/EditableTextBlock.cs
Normal file
179
Examples/Nodify.Shared/Controls/EditableTextBlock.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using Nodify.Shared;
|
||||
|
||||
namespace Nodify
|
||||
{
|
||||
[TemplatePart(Name = ElementTextBox, Type = typeof(TextBox))]
|
||||
public class EditableTextBlock : Control
|
||||
{
|
||||
private const string ElementTextBox = "PART_TextBox";
|
||||
|
||||
public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register(nameof(IsEditing), typeof(bool), typeof(EditableTextBlock), new FrameworkPropertyMetadata(BoxValue.False, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsEditingChanged, CoerceIsEditing));
|
||||
public static readonly DependencyProperty IsEditableProperty = DependencyProperty.Register(nameof(IsEditable), typeof(bool), typeof(EditableTextBlock), new FrameworkPropertyMetadata(BoxValue.True));
|
||||
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(typeof(EditableTextBlock), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
|
||||
public static readonly DependencyProperty AcceptsReturnProperty = TextBoxBase.AcceptsReturnProperty.AddOwner(typeof(EditableTextBlock), new FrameworkPropertyMetadata(BoxValue.False));
|
||||
public static readonly DependencyProperty TextWrappingProperty = TextBlock.TextWrappingProperty.AddOwner(typeof(EditableTextBlock), new FrameworkPropertyMetadata(TextWrapping.Wrap));
|
||||
public static readonly DependencyProperty TextTrimmingProperty = TextBlock.TextTrimmingProperty.AddOwner(typeof(EditableTextBlock), new FrameworkPropertyMetadata(TextTrimming.CharacterEllipsis));
|
||||
public static readonly DependencyProperty MinLinesProperty = TextBox.MinLinesProperty.AddOwner(typeof(EditableTextBlock));
|
||||
public static readonly DependencyProperty MaxLinesProperty = TextBox.MaxLinesProperty.AddOwner(typeof(EditableTextBlock));
|
||||
public static readonly DependencyProperty MaxLengthProperty = TextBox.MaxLengthProperty.AddOwner(typeof(EditableTextBlock));
|
||||
|
||||
private static void OnIsEditingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
|
||||
|
||||
private static object CoerceIsEditing(DependencyObject d, object value)
|
||||
{
|
||||
if (!((EditableTextBlock)d).IsEditable)
|
||||
{
|
||||
return BoxValue.False;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public bool IsEditing
|
||||
{
|
||||
get => (bool)GetValue(IsEditingProperty);
|
||||
set => SetValue(IsEditingProperty, value);
|
||||
}
|
||||
|
||||
public bool IsEditable
|
||||
{
|
||||
get => (bool)GetValue(IsEditableProperty);
|
||||
set => SetValue(IsEditableProperty, value);
|
||||
}
|
||||
|
||||
public bool AcceptsReturn
|
||||
{
|
||||
get => (bool)GetValue(AcceptsReturnProperty);
|
||||
set => SetValue(AcceptsReturnProperty, value);
|
||||
}
|
||||
|
||||
public int MaxLength
|
||||
{
|
||||
get => (int)GetValue(MaxLengthProperty);
|
||||
set => SetValue(MaxLengthProperty, value);
|
||||
}
|
||||
|
||||
public int MinLines
|
||||
{
|
||||
get => (int)GetValue(MinLinesProperty);
|
||||
set => SetValue(MaxLinesProperty, value);
|
||||
}
|
||||
|
||||
public int MaxLines
|
||||
{
|
||||
get => (int)GetValue(MaxLinesProperty);
|
||||
set => SetValue(MaxLinesProperty, value);
|
||||
}
|
||||
|
||||
public TextWrapping TextWrapping
|
||||
{
|
||||
get => (TextWrapping)GetValue(TextWrappingProperty);
|
||||
set => SetValue(TextWrappingProperty, value);
|
||||
}
|
||||
|
||||
public TextTrimming TextTrimming
|
||||
{
|
||||
get => (TextTrimming)GetValue(TextTrimmingProperty);
|
||||
set => SetValue(TextTrimmingProperty, value);
|
||||
}
|
||||
|
||||
protected TextBox? TextBox { get; private set; }
|
||||
|
||||
static EditableTextBlock()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(EditableTextBlock), new FrameworkPropertyMetadata(typeof(EditableTextBlock)));
|
||||
FocusableProperty.OverrideMetadata(typeof(EditableTextBlock), new FrameworkPropertyMetadata(BoxValue.True));
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (TextBox != null)
|
||||
{
|
||||
TextBox.LostFocus -= OnLostFocus;
|
||||
TextBox.LostKeyboardFocus -= OnLostFocus;
|
||||
TextBox.IsVisibleChanged -= OnTextBoxVisiblityChanged;
|
||||
}
|
||||
|
||||
TextBox = GetTemplateChild(ElementTextBox) as TextBox;
|
||||
|
||||
if (TextBox != null)
|
||||
{
|
||||
TextBox.LostFocus += OnLostFocus;
|
||||
TextBox.LostKeyboardFocus += OnLostFocus;
|
||||
TextBox.IsVisibleChanged += OnTextBoxVisiblityChanged;
|
||||
|
||||
if (IsEditing)
|
||||
{
|
||||
TextBox.Focus();
|
||||
TextBox.SelectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTextBoxVisiblityChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (IsEditing && TextBox != null)
|
||||
{
|
||||
if (TextBox.Focus())
|
||||
{
|
||||
TextBox.SelectAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
IsEditing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (IsEditing)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (IsEditable && e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
|
||||
{
|
||||
IsEditing = true;
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
||||
{
|
||||
if (IsEditing)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IsEditing = false;
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if (IsEditing && e.Key == Key.Escape || !AcceptsReturn && e.Key == Key.Enter)
|
||||
{
|
||||
IsEditing = false;
|
||||
}
|
||||
|
||||
if (e.Key == Key.Enter && IsFocused && !IsEditing)
|
||||
{
|
||||
IsEditing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
196
Examples/Nodify.Shared/Controls/ResizablePanel.cs
Normal file
196
Examples/Nodify.Shared/Controls/ResizablePanel.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Nodify
|
||||
{
|
||||
public class ResizablePanel : ContentControl
|
||||
{
|
||||
internal static readonly object BoxedResizeDirection = ResizeDirections.All;
|
||||
|
||||
public static readonly DependencyProperty DirectionsProperty
|
||||
= DependencyProperty.Register(nameof(Directions), typeof(ResizeDirections), typeof(ResizablePanel), new FrameworkPropertyMetadata(BoxedResizeDirection));
|
||||
|
||||
public static readonly DependencyProperty ResizeStartedCommandProperty = DependencyProperty.Register(nameof(ResizeStartedCommand), typeof(ICommand), typeof(ResizablePanel));
|
||||
|
||||
public static readonly DependencyProperty ResizeCompletedCommandProperty = DependencyProperty.Register(nameof(ResizeCompletedCommand), typeof(ICommand), typeof(ResizablePanel));
|
||||
|
||||
public ResizeDirections Directions
|
||||
{
|
||||
get => (ResizeDirections)GetValue(DirectionsProperty);
|
||||
set => SetValue(DirectionsProperty, value);
|
||||
}
|
||||
|
||||
public ICommand? ResizeStartedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(ResizeStartedCommandProperty);
|
||||
set => SetValue(ResizeStartedCommandProperty, value);
|
||||
}
|
||||
|
||||
public ICommand? ResizeCompletedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(ResizeCompletedCommandProperty);
|
||||
set => SetValue(ResizeCompletedCommandProperty, value);
|
||||
}
|
||||
|
||||
static ResizablePanel()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizablePanel), new FrameworkPropertyMetadata(typeof(ResizablePanel)));
|
||||
}
|
||||
|
||||
public ResizablePanel()
|
||||
{
|
||||
AddHandler(Thumb.DragDeltaEvent, new DragDeltaEventHandler(OnResize));
|
||||
AddHandler(Thumb.DragStartedEvent, new DragStartedEventHandler(OnDragStarted));
|
||||
AddHandler(Thumb.DragCompletedEvent, new DragCompletedEventHandler(OnDragCompleted));
|
||||
}
|
||||
|
||||
private void OnDragStarted(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
if (ResizeStartedCommand?.CanExecute(null) ?? false)
|
||||
{
|
||||
ResizeStartedCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragCompleted(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
if (ResizeCompletedCommand?.CanExecute(null) ?? false)
|
||||
{
|
||||
ResizeCompletedCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnResize(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (e.OriginalSource is Resizer resizer)
|
||||
{
|
||||
double resizeX = 0;
|
||||
double resizeY = 0;
|
||||
|
||||
double moveX = 0;
|
||||
double moveY = 0;
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.Top))
|
||||
{
|
||||
moveY = resizeY = ResizeTop(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.Bottom))
|
||||
{
|
||||
resizeY = ResizeBottom(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.Left))
|
||||
{
|
||||
moveX = resizeX = ResizeLeft(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.Right))
|
||||
{
|
||||
resizeX = ResizeRight(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.TopLeft))
|
||||
{
|
||||
moveY = resizeY = ResizeTop(e);
|
||||
moveX = resizeX = ResizeLeft(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.TopRight))
|
||||
{
|
||||
moveY = resizeY = ResizeTop(e);
|
||||
resizeX = ResizeRight(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.BottomLeft))
|
||||
{
|
||||
resizeY = ResizeBottom(e);
|
||||
moveX = resizeX = ResizeLeft(e);
|
||||
}
|
||||
|
||||
if (resizer.Direction.HasFlag(ResizeDirections.BottomRight))
|
||||
{
|
||||
resizeY = ResizeBottom(e);
|
||||
resizeX = ResizeRight(e);
|
||||
}
|
||||
|
||||
OnProcessDelta(ref resizeX, ref resizeY);
|
||||
OnProcessDelta(ref moveX, ref moveY);
|
||||
|
||||
OnMove(moveX, moveY);
|
||||
|
||||
Width -= resizeX;
|
||||
Height -= resizeY;
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private double ResizeBottom(DragDeltaEventArgs e)
|
||||
{
|
||||
return Math.Min(-e.VerticalChange, ActualHeight - MinHeight);
|
||||
}
|
||||
|
||||
private double ResizeTop(DragDeltaEventArgs e)
|
||||
{
|
||||
return Math.Min(e.VerticalChange, ActualHeight - MinHeight);
|
||||
}
|
||||
|
||||
private double ResizeRight(DragDeltaEventArgs e)
|
||||
{
|
||||
return Math.Min(-e.HorizontalChange, ActualWidth - MinWidth);
|
||||
}
|
||||
|
||||
private double ResizeLeft(DragDeltaEventArgs e)
|
||||
{
|
||||
return Math.Min(e.HorizontalChange, ActualWidth - MinWidth);
|
||||
}
|
||||
|
||||
protected virtual void OnMove(double x, double y)
|
||||
{
|
||||
Canvas.SetTop(this, Canvas.GetTop(this) + y);
|
||||
Canvas.SetLeft(this, Canvas.GetLeft(this) + x);
|
||||
}
|
||||
|
||||
protected virtual void OnProcessDelta(ref double dx, ref double dy)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class Resizer : Thumb
|
||||
{
|
||||
public static readonly DependencyProperty DirectionProperty
|
||||
= DependencyProperty.Register(nameof(Direction), typeof(ResizeDirections), typeof(Resizer), new FrameworkPropertyMetadata(ResizablePanel.BoxedResizeDirection));
|
||||
|
||||
public ResizeDirections Direction
|
||||
{
|
||||
get => (ResizeDirections)GetValue(DirectionProperty);
|
||||
set => SetValue(DirectionProperty, value);
|
||||
}
|
||||
|
||||
static Resizer()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(typeof(Resizer)));
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ResizeDirections
|
||||
{
|
||||
Top = 1,
|
||||
Left = 2,
|
||||
Bottom = 4,
|
||||
Right = 8,
|
||||
TopLeft = 16,
|
||||
TopRight = 32,
|
||||
BottomLeft = 64,
|
||||
BottomRight = 128,
|
||||
|
||||
Edges = Top | Left | Bottom | Right,
|
||||
Corners = TopLeft | TopRight | BottomLeft | BottomRight,
|
||||
All = Edges | Corners
|
||||
}
|
||||
}
|
||||
48
Examples/Nodify.Shared/Controls/Swatches.xaml.cs
Normal file
48
Examples/Nodify.Shared/Controls/Swatches.xaml.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Nodify.Shared;
|
||||
|
||||
namespace Nodify
|
||||
{
|
||||
public partial class Swatches : Control
|
||||
{
|
||||
public static readonly DependencyProperty SelectedColorProperty
|
||||
= DependencyProperty.Register(nameof(SelectedColor), typeof(Color), typeof(Swatches), new FrameworkPropertyMetadata(default(Color), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
|
||||
|
||||
public static readonly DependencyProperty ColorsProperty
|
||||
= DependencyProperty.Register(nameof(Colors), typeof(IEnumerable<Color>), typeof(Swatches), new PropertyMetadata(Array.Empty<Color>()));
|
||||
|
||||
public Color SelectedColor
|
||||
{
|
||||
get => (Color)GetValue(SelectedColorProperty);
|
||||
set => SetValue(SelectedColorProperty, value);
|
||||
}
|
||||
|
||||
public IEnumerable<Color> Colors
|
||||
{
|
||||
get => (IEnumerable<Color>)GetValue(ColorsProperty);
|
||||
set => SetValue(ColorsProperty, value);
|
||||
}
|
||||
|
||||
static Swatches()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(Swatches), new FrameworkPropertyMetadata(typeof(Swatches)));
|
||||
FocusableProperty.OverrideMetadata(typeof(Swatches), new FrameworkPropertyMetadata(BoxValue.True));
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
var color = e.OriginalSource is FrameworkElement fe && fe.DataContext is Color c ? c : (Color?)null;
|
||||
if (color.HasValue)
|
||||
{
|
||||
SelectedColor = color.Value;
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Examples/Nodify.Shared/Controls/TabControlEx.cs
Normal file
57
Examples/Nodify.Shared/Controls/TabControlEx.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Nodify
|
||||
{
|
||||
[TemplatePart(Name = ElementScrollViewer, Type = typeof(ScrollViewer))]
|
||||
public class TabControlEx : TabControl
|
||||
{
|
||||
private const string ElementScrollViewer = "PART_ScrollViewer";
|
||||
|
||||
public static readonly DependencyProperty AddTabCommandProperty = DependencyProperty.Register(nameof(AddTabCommand), typeof(ICommand), typeof(TabControlEx), new PropertyMetadata(null));
|
||||
public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.Register(nameof(AutoScrollToEnd), typeof(bool), typeof(TabControlEx), new PropertyMetadata(false));
|
||||
|
||||
public ICommand AddTabCommand
|
||||
{
|
||||
get { return (ICommand)GetValue(AddTabCommandProperty); }
|
||||
set { SetValue(AddTabCommandProperty, value); }
|
||||
}
|
||||
public bool AutoScrollToEnd
|
||||
{
|
||||
get { return (bool)GetValue(AutoScrollToEndProperty); }
|
||||
set { SetValue(AutoScrollToEndProperty, value); }
|
||||
}
|
||||
|
||||
protected ScrollViewer? ScrollViewer { get; private set; }
|
||||
|
||||
static TabControlEx()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(TabControlEx), new FrameworkPropertyMetadata(typeof(TabControlEx)));
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
ScrollViewer = GetTemplateChild(ElementScrollViewer) as ScrollViewer;
|
||||
if(ScrollViewer != null)
|
||||
{
|
||||
ScrollViewer.ScrollChanged += OnScrollChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||
{
|
||||
if(e.ExtentWidthChange > 0 && e.ViewportWidth < e.ExtentWidth && AutoScrollToEnd)
|
||||
{
|
||||
ScrollViewer?.ScrollToRightEnd();
|
||||
}
|
||||
}
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
{
|
||||
return new TabItemEx();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Examples/Nodify.Shared/Controls/TabItemEx.cs
Normal file
29
Examples/Nodify.Shared/Controls/TabItemEx.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Nodify
|
||||
{
|
||||
public class TabItemEx : TabItem
|
||||
{
|
||||
public static readonly DependencyProperty CloseTabCommandProperty = DependencyProperty.Register(nameof(CloseTabCommand), typeof(ICommand), typeof(TabItemEx), new PropertyMetadata(null));
|
||||
public static readonly DependencyProperty CloseTabCommandParameterProperty = DependencyProperty.Register(nameof(CloseTabCommandParameter), typeof(object), typeof(TabItemEx), new PropertyMetadata(null));
|
||||
|
||||
public ICommand CloseTabCommand
|
||||
{
|
||||
get { return (ICommand)GetValue(CloseTabCommandProperty); }
|
||||
set { SetValue(CloseTabCommandProperty, value); }
|
||||
}
|
||||
|
||||
public object CloseTabCommandParameter
|
||||
{
|
||||
get { return (object)GetValue(CloseTabCommandParameterProperty); }
|
||||
set { SetValue(CloseTabCommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
static TabItemEx()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(TabItemEx), new FrameworkPropertyMetadata(typeof(TabItemEx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user