Compare commits
13 Commits
f9f51af3c4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
385e932401 | ||
|
|
55573f6040 | ||
|
|
2efc34846c | ||
|
|
fb3db24b90 | ||
|
|
413985e08f | ||
|
|
7d18b88172 | ||
|
|
fdcef37be3 | ||
|
|
d7ff6b3109 | ||
|
|
cce2224926 | ||
|
|
23fc6c17e6 | ||
|
|
c6c1e41cb6 | ||
|
|
f9138ff444 | ||
|
|
71c55abbcb |
@@ -1,6 +1,8 @@
|
|||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using Deedy.Testing;
|
||||||
|
|
||||||
namespace Deedy
|
namespace Deedy
|
||||||
{
|
{
|
||||||
@@ -9,6 +11,45 @@ namespace Deedy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
public App()
|
||||||
|
{
|
||||||
|
string script =
|
||||||
|
@"
|
||||||
|
VarP var1 111
|
||||||
|
VarP var2 222
|
||||||
|
Func Add var1x var2x
|
||||||
|
LetP AddResult -1
|
||||||
|
math AddResult @var1x 777 + @var2 - @var2x -
|
||||||
|
retu AddResult
|
||||||
|
EndF
|
||||||
|
//调用自定义方法
|
||||||
|
Call Add @var1 99
|
||||||
|
PopV result
|
||||||
|
ifth true 4 3 <
|
||||||
|
letp result 248
|
||||||
|
else
|
||||||
|
letp result 80
|
||||||
|
endi
|
||||||
|
letp var1 1
|
||||||
|
letp var2 1
|
||||||
|
whil false @var1 10 <
|
||||||
|
math var1 @var1 ++
|
||||||
|
ifth false @var2 4 !=
|
||||||
|
math var2 @var2 ++
|
||||||
|
cont
|
||||||
|
var var3 xxx
|
||||||
|
else
|
||||||
|
brea
|
||||||
|
endi
|
||||||
|
endw
|
||||||
|
";
|
||||||
|
Todo todo = new();
|
||||||
|
todo.Init("varp var1 111");
|
||||||
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
for (int i = 0; i < 1000000; i++)
|
||||||
|
todo.Redo();
|
||||||
|
sw.Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
1145
DeedyDesigner/Deedy.Testing/Dodo.cs
Normal file
1145
DeedyDesigner/Deedy.Testing/Dodo.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,10 @@
|
|||||||
<Button Content="测试的标题"/>
|
<Button Content="测试的标题"/>
|
||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
</deedy:WindowBorder.Header>
|
</deedy:WindowBorder.Header>
|
||||||
<Border BorderBrush="Red" BorderThickness="1"/>
|
<Border BorderBrush="Red" BorderThickness="1">
|
||||||
|
<UniformGrid>
|
||||||
|
<Button Content="打开抽屉" Click="Button_Click"/>
|
||||||
|
</UniformGrid>
|
||||||
|
</Border>
|
||||||
</deedy:WindowBorder>
|
</deedy:WindowBorder>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -31,7 +31,34 @@ namespace Deedy.Testing
|
|||||||
|
|
||||||
private void WindowBorder_Click_1(object sender, RoutedEventArgs e)
|
private void WindowBorder_Click_1(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
drawer?.HideWithAnimation();
|
||||||
|
}
|
||||||
|
private DrawerViewer? drawer;
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (this.Content is UIElement windowBorder)
|
||||||
|
{
|
||||||
|
DrawerViewer? _drawer = null;
|
||||||
|
_drawer = new DrawerViewer(windowBorder, (s, e) =>
|
||||||
|
{
|
||||||
|
_drawer?.HideWithAnimation();
|
||||||
|
}, Dock.Right, Button.ClickEvent)
|
||||||
|
{
|
||||||
|
Content = new Button()
|
||||||
|
{
|
||||||
|
Background = Brushes.Red,
|
||||||
|
Opacity = 0.75,
|
||||||
|
Visibility = Visibility.Visible,
|
||||||
|
Content = "测试按钮"
|
||||||
|
},
|
||||||
|
Background = Brushes.Green,
|
||||||
|
Margin = new Thickness(100, 40, 0, 0),
|
||||||
|
};
|
||||||
|
var al = AdornerLayer.GetAdornerLayer(this.Content as UIElement);
|
||||||
|
al.Add(_drawer);
|
||||||
|
_drawer.ShowWithAnimation();
|
||||||
|
drawer = _drawer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
220
DeedyDesigner/Deedy.Wpf/DrawerViewer.cs
Normal file
220
DeedyDesigner/Deedy.Wpf/DrawerViewer.cs
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Animation;
|
||||||
|
|
||||||
|
namespace Deedy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 抽屉窗口装饰器
|
||||||
|
/// </summary>
|
||||||
|
public class DrawerViewer : Adorner
|
||||||
|
{
|
||||||
|
private readonly VisualCollection _visualChildren;
|
||||||
|
/// <summary>
|
||||||
|
/// 抽屉外边框
|
||||||
|
/// </summary>
|
||||||
|
private readonly Border _border;
|
||||||
|
public Brush Background { get => (Brush)GetValue(BackgroundProperty); set => SetValue(BackgroundProperty, value); }
|
||||||
|
public static readonly DependencyProperty BackgroundProperty = Border.BackgroundProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
public Brush BorderBrush { get => (Brush)GetValue(BorderBrushProperty); set => SetValue(BorderBrushProperty, value); }
|
||||||
|
public static readonly DependencyProperty BorderBrushProperty = Border.BorderBrushProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
public Thickness BorderThickness { get => (Thickness)GetValue(BorderThicknessProperty); set => SetValue(BorderThicknessProperty, value); }
|
||||||
|
public static readonly DependencyProperty BorderThicknessProperty = Border.BorderThicknessProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
public CornerRadius CornerRadius { get => (CornerRadius)GetValue(CornerRadiusProperty); set => SetValue(CornerRadiusProperty, value); }
|
||||||
|
public static readonly DependencyProperty CornerRadiusProperty = Border.CornerRadiusProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
/// <summary>
|
||||||
|
/// 抽屉内容容器
|
||||||
|
/// </summary>
|
||||||
|
private readonly ContentPresenter _contentPresenter;
|
||||||
|
public object Content { get => GetValue(ContentProperty); set => SetValue(ContentProperty, value); }
|
||||||
|
public static readonly DependencyProperty ContentProperty = ContentPresenter.ContentProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
public DataTemplate ContentTemplate { get => (DataTemplate)GetValue(ContentTemplateProperty); set => SetValue(ContentTemplateProperty, value); }
|
||||||
|
public static readonly DependencyProperty ContentTemplateProperty = ContentPresenter.ContentTemplateProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
public DataTemplateSelector ContentTemplateSelector { get => (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); set => SetValue(ContentTemplateSelectorProperty, value); }
|
||||||
|
public static readonly DependencyProperty ContentTemplateSelectorProperty = ContentPresenter.ContentTemplateSelectorProperty.AddOwner(typeof(DrawerViewer));
|
||||||
|
/// <summary>
|
||||||
|
/// 动画方向:如果为「null」则使用缩放动画
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dock? _direction;
|
||||||
|
/// <summary>
|
||||||
|
/// 根据抽屉加载方向创建边距动画所需要的「Thickness」对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>动画需要的「Thickness」对象</returns>
|
||||||
|
private Thickness GetMargin4Animation()
|
||||||
|
{
|
||||||
|
switch (this._direction)
|
||||||
|
{
|
||||||
|
case Dock.Left: return new Thickness(0, 0, this.AdornedElement.RenderSize.Width, 0);
|
||||||
|
case Dock.Right: return new Thickness(this.AdornedElement.RenderSize.Width, 0, 0, 0);
|
||||||
|
case Dock.Top: return new Thickness(0, 0, 0, this.AdornedElement.RenderSize.Height);
|
||||||
|
case Dock.Bottom: return new Thickness(0, AdornedElement.RenderSize.Height, 0, 0);
|
||||||
|
default:
|
||||||
|
double horMargin = this.AdornedElement.RenderSize.Width / 2;
|
||||||
|
double verMargin = this.AdornedElement.RenderSize.Height / 2;
|
||||||
|
return new Thickness(horMargin, verMargin, horMargin, verMargin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 在特定「UIElement」上创建「WindowDrawer」蒙层
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="adornedElement">目标「UIElement」元素</param>
|
||||||
|
/// <param name="direction">抽屉的加载方向,如果不设置则使用缩放动画</param>
|
||||||
|
public DrawerViewer(UIElement adornedElement, Dock? direction = null) : base(adornedElement)
|
||||||
|
{
|
||||||
|
this.Opacity = 0;
|
||||||
|
this._direction = direction;
|
||||||
|
|
||||||
|
_visualChildren = new VisualCollection(this);
|
||||||
|
// 创建边框并绑定属性
|
||||||
|
_border = new Border() { };
|
||||||
|
var backgroundBinding = new System.Windows.Data.Binding(BackgroundProperty.Name) { Source = this };
|
||||||
|
var borderBrushBinding = new System.Windows.Data.Binding(BorderBrushProperty.Name) { Source = this };
|
||||||
|
var borderThicknessBinding = new System.Windows.Data.Binding(BorderThicknessProperty.Name) { Source = this };
|
||||||
|
var cornerRadiusBinding = new System.Windows.Data.Binding(CornerRadiusProperty.Name) { Source = this };
|
||||||
|
|
||||||
|
_border.SetBinding(Border.BackgroundProperty, backgroundBinding);
|
||||||
|
_border.SetBinding(Border.BorderBrushProperty, borderBrushBinding);
|
||||||
|
_border.SetBinding(Border.BorderThicknessProperty, borderThicknessBinding);
|
||||||
|
_border.SetBinding(Border.CornerRadiusProperty, cornerRadiusBinding);
|
||||||
|
|
||||||
|
_visualChildren.Add(_border);
|
||||||
|
|
||||||
|
// 创建内容并绑定属性
|
||||||
|
_contentPresenter = new ContentPresenter
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
VerticalAlignment = VerticalAlignment.Stretch
|
||||||
|
};
|
||||||
|
var contentBinding = new System.Windows.Data.Binding(ContentProperty.Name) { Source = this };
|
||||||
|
var contentTemplateBinding = new System.Windows.Data.Binding(ContentTemplateProperty.Name) { Source = this };
|
||||||
|
var contentTemplateSelectorBinding = new System.Windows.Data.Binding(ContentTemplateSelectorProperty.Name) { Source = this };
|
||||||
|
|
||||||
|
_contentPresenter.SetBinding(ContentPresenter.ContentProperty, contentBinding);
|
||||||
|
_contentPresenter.SetBinding(ContentPresenter.ContentTemplateProperty, contentTemplateBinding);
|
||||||
|
_contentPresenter.SetBinding(ContentPresenter.ContentTemplateSelectorProperty, contentTemplateSelectorBinding);
|
||||||
|
|
||||||
|
_border.Child = _contentPresenter;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 要注册的事件
|
||||||
|
/// </summary>
|
||||||
|
[AllowNull]
|
||||||
|
private readonly RoutedEvent[] _routedEvents;
|
||||||
|
/// <summary>
|
||||||
|
/// 事件响应方法
|
||||||
|
/// </summary>
|
||||||
|
private readonly RoutedEventHandler? _routedEventHandler;
|
||||||
|
/// <summary>
|
||||||
|
/// 在特定「UIElement」上创建「WindowDrawer」蒙层,同时绑定特定路由事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="adornedElement">目标「UIElement」元素</param>
|
||||||
|
/// <param name="routedEventHandler">路由事件处理程序</param>
|
||||||
|
/// <param name="direction">抽屉的加载方向,如果不设置则使用缩放动画</param>
|
||||||
|
/// <param name="routedEvents">要绑定的路由事件</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// 如果不设置「routedEvents」参数则注册「ButtonBase.ClickEvent」事件
|
||||||
|
/// </remarks>
|
||||||
|
public DrawerViewer(UIElement adornedElement, RoutedEventHandler routedEventHandler, Dock? direction, params RoutedEvent[] routedEvents)
|
||||||
|
: this(adornedElement, direction)
|
||||||
|
{
|
||||||
|
if (routedEvents.Length == 0) routedEvents = [ButtonBase.ClickEvent];
|
||||||
|
if (routedEventHandler != null)
|
||||||
|
{
|
||||||
|
_routedEvents = routedEvents;
|
||||||
|
_routedEventHandler = routedEventHandler;
|
||||||
|
foreach (var routedEvent in routedEvents)
|
||||||
|
this.AddHandler(routedEvent, routedEventHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 在特定「UIElement」上创建「WindowDrawer」蒙层,同时绑定特定路由事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="adornedElement">目标「UIElement」元素</param>
|
||||||
|
/// <param name="routedEventHandler">路由事件处理程序</param>
|
||||||
|
/// <param name="routedEvents">要绑定的路由事件</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>如果不设置「routedEvents」参数则注册「ButtonBase.ClickEvent」事件</para>
|
||||||
|
/// <para>抽屉采用缩放方式加载</para>
|
||||||
|
/// </remarks>
|
||||||
|
public DrawerViewer(UIElement adornedElement, RoutedEventHandler routedEventHandler, params RoutedEvent[] routedEvents)
|
||||||
|
: this(adornedElement, routedEventHandler, null, routedEvents) { }
|
||||||
|
protected override int VisualChildrenCount => _visualChildren.Count;
|
||||||
|
protected override Visual GetVisualChild(int index) => _visualChildren[index];
|
||||||
|
protected override Size MeasureOverride(Size constraint)
|
||||||
|
{
|
||||||
|
_border.Measure(constraint);
|
||||||
|
return base.MeasureOverride(constraint);
|
||||||
|
}
|
||||||
|
protected override Size ArrangeOverride(Size finalSize)
|
||||||
|
{
|
||||||
|
_border.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
|
||||||
|
return finalSize;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 显示抽屉并播放入场动画
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seconds">动画持续时间</param>
|
||||||
|
public void ShowWithAnimation(double seconds = 1)
|
||||||
|
{
|
||||||
|
var doubleAnimation = new DoubleAnimation
|
||||||
|
{
|
||||||
|
From = 0,
|
||||||
|
To = 1,
|
||||||
|
Duration = TimeSpan.FromSeconds(seconds),
|
||||||
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
|
||||||
|
};
|
||||||
|
BeginAnimation(OpacityProperty, doubleAnimation);
|
||||||
|
|
||||||
|
var marginAnimation = new ThicknessAnimation
|
||||||
|
{
|
||||||
|
From = this.GetMargin4Animation(),
|
||||||
|
To = new Thickness(0),
|
||||||
|
Duration = TimeSpan.FromSeconds(seconds),
|
||||||
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
|
||||||
|
};
|
||||||
|
_border.BeginAnimation(MarginProperty, marginAnimation);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭抽屉并播放出场动画;同时清理事件注册
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seconds">动画持续时间</param>
|
||||||
|
public void HideWithAnimation(double seconds = 1)
|
||||||
|
{
|
||||||
|
var doubleAnimation = new DoubleAnimation
|
||||||
|
{
|
||||||
|
From = 1,
|
||||||
|
To = 0,
|
||||||
|
Duration = TimeSpan.FromSeconds(seconds),
|
||||||
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
||||||
|
};
|
||||||
|
doubleAnimation.Completed += (s, e) =>
|
||||||
|
{
|
||||||
|
if (this._routedEventHandler != null)
|
||||||
|
foreach (var routedEvent in this._routedEvents)
|
||||||
|
this.RemoveHandler(routedEvent, this._routedEventHandler);
|
||||||
|
|
||||||
|
var layer = AdornerLayer.GetAdornerLayer(AdornedElement);
|
||||||
|
layer?.Remove(this);
|
||||||
|
};
|
||||||
|
BeginAnimation(OpacityProperty, doubleAnimation);
|
||||||
|
|
||||||
|
var marginAnimation = new ThicknessAnimation
|
||||||
|
{
|
||||||
|
From = new Thickness(0),
|
||||||
|
To = this.GetMargin4Animation(),
|
||||||
|
Duration = TimeSpan.FromSeconds(seconds),
|
||||||
|
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
||||||
|
};
|
||||||
|
_border.BeginAnimation(MarginProperty, marginAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,6 +82,7 @@
|
|||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</ControlTemplate.Resources>
|
</ControlTemplate.Resources>
|
||||||
|
<AdornerDecorator>
|
||||||
<DockPanel Background="{TemplateBinding Background}">
|
<DockPanel Background="{TemplateBinding Background}">
|
||||||
<Border x:Name="TitleBar" Background="{TemplateBinding Headground}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
|
<Border x:Name="TitleBar" Background="{TemplateBinding Headground}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
DockPanel.Dock="Top" MinHeight="32" Height="{TemplateBinding HeaderHeight}">
|
DockPanel.Dock="Top" MinHeight="32" Height="{TemplateBinding HeaderHeight}">
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
</Border>
|
</Border>
|
||||||
<ContentPresenter/>
|
<ContentPresenter/>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
</AdornerDecorator>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|||||||
Reference in New Issue
Block a user