This commit is contained in:
NaBian committed 2020-06-22 00:22:55 +08:00
commit 398e285f3d
36 files changed
+1019 -43

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@
### 加入讨论
| | 西江月群 | 定风波群 | 定风波群 |
| | 西江月群 | 定风波群 | 广寒秋群 |
|-|:-:|:-:|:-:|
| 群号码 | [![qq-group](https://img.shields.io/badge/qq-714704041-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=a571e5553c9d41e49c4f22f3a8b2865451497a795ff281fedf3285def247efc1) | [![qq-group](https://img.shields.io/badge/qq-858784803-red.svg)](//shang.qq.com/wpa/qunwpa?idkey=5c18622a0f6ee07a6f33afa8cdb85b1f72ea50e878271dfcec919c76b55afee7) | 微信群 |
| 二维码 | ![qq-group](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/qq_group_1.png) | ![qq-group](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/qq_group_2.png) | ![wechat-group](https://raw.githubusercontent.com/HandyOrg/HandyOrgResource/master/HandyControl/Resources/wechat_group.png) |
@@ -265,6 +265,9 @@
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\HoverMenu_16x.png">
<Link>Resources\Img\LeftMainContent\HoverMenu_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\Image_16x.png">
<Link>Resources\Img\LeftMainContent\Image_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\ImageBrowser_16x.png">
<Link>Resources\Img\LeftMainContent\ImageBrowser_16x.png</Link>
</Resource>
@@ -265,6 +265,9 @@
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\HoverMenu_16x.png">
<Link>Resources\Img\LeftMainContent\HoverMenu_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\Image_16x.png">
<Link>Resources\Img\LeftMainContent\Image_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\ImageBrowser_16x.png">
<Link>Resources\Img\LeftMainContent\ImageBrowser_16x.png</Link>
</Resource>
@@ -138,6 +138,9 @@
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\ImageBrowserDemoCtl.xaml">
<Link>UserControl\Controls\ImageBrowserDemoCtl.xaml</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\ImageSelectorDemoCtl.xaml">
<Link>UserControl\Controls\ImageSelectorDemoCtl.xaml</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\LoadingDemoCtl.xaml">
<Link>UserControl\Controls\LoadingDemoCtl.xaml</Link>
</Resource>
@@ -523,6 +526,10 @@
<Link>UserControl\Controls\ImageBrowserDemoCtl.xaml.cs</Link>
<DependentUpon>ImageBrowserDemoCtl.xaml</DependentUpon>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\ImageSelectorDemoCtl.xaml.cs">
<Link>UserControl\Controls\ImageSelectorDemoCtl.xaml.cs</Link>
<DependentUpon>ImageSelectorDemoCtl.xaml</DependentUpon>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\LoadingDemoCtl.xaml.cs">
<Link>UserControl\Controls\LoadingDemoCtl.xaml.cs</Link>
<DependentUpon>LoadingDemoCtl.xaml</DependentUpon>
@@ -27,7 +27,7 @@
[ "GroupBox", "GroupBoxDemoCtl", "GroupBox_16x", "" ],
[ "Menu", "MenuDemoCtl", "ContextMenu_16x", "" ],
[ "RichTextBox", "RichTextBoxDemoCtl", "RichTextBox_16x", "" ],
[ "FlowDocument", "FlowDocumentDemoCtl", "WPFFlowDocument_16x", "1" ],
[ "FlowDocument", "FlowDocumentDemoCtl", "WPFFlowDocument_16x", "" ],
[ "ToolBar", "ToolBarDemoCtl", "ToolBar_16x", "" ],
[ "Border", "BorderDemoCtl", "BorderElement_16x", "" ],
[ "Label", "LabelDemoCtl", "Label_16x", "" ],
@@ -41,6 +41,7 @@
"demoItemList": [
[ "FloatingBlock", "FloatingBlockDemoCtl", "thumbs_up", "" ],
[ "PropertyGrid", "PropertyGridDemoCtl", "PropertyGridEditorPart_16x", "1" ],
[ "ImageSelector", "ImageSelectorDemoCtl", "Image_16x", "1" ],
[ "ImageBlock", "ImageBlockDemoCtl", "ImageStack_16x", "" ],
[ "Magnifier", "MagnifierDemoCtl", "Search_16x", "" ],
[ "Gravatar", "GravatarDemoCtl", "User_16x", "" ],
@@ -55,6 +55,9 @@
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Basic\TextDialogWithTimer.xaml.cs">
<DependentUpon>TextDialogWithTimer.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Controls\ImageSelectorDemoCtl.xaml.cs">
<DependentUpon>ImageSelectorDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Controls\AnimationPathDemoCtl.xaml.cs">
<DependentUpon>AnimationPathDemoCtl.xaml</DependentUpon>
</Compile>
@@ -512,6 +515,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)UserControl\Controls\ImageSelectorDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)UserControl\Controls\AnimationPathDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -851,7 +851,18 @@ namespace HandyControlDemo.Properties.Langs {
return ResourceManager.GetString("ImageBrowser", resourceCulture);
}
}
/// <summary>
/// 查找类似 图片选择器 的本地化字符串。
/// </summary>
public static string ImageSelector
{
get
{
return ResourceManager.GetString("ImageSelector", resourceCulture);
}
}
/// <summary>
/// 查找类似 索引 的本地化字符串。
/// </summary>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>属性编辑器</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>图片选择器</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -753,4 +753,7 @@
<data name="PropertyGrid" xml:space="preserve">
<value>PropertyGrid</value>
</data>
<data name="ImageSelector" xml:space="preserve">
<value>ImageSelector</value>
</data>
</root>
@@ -125,7 +125,8 @@ namespace HandyControlDemo.Properties.Langs
OnPropertyChanged(nameof(Ignore));
OnPropertyChanged(nameof(ImageBlock));
OnPropertyChanged(nameof(ImageBrowser));
OnPropertyChanged(nameof(Index));
OnPropertyChanged(nameof(ImageSelector));
OnPropertyChanged(nameof(Index));
OnPropertyChanged(nameof(Info));
OnPropertyChanged(nameof(InteractiveDialog));
OnPropertyChanged(nameof(IsNotPhone));
@@ -691,6 +692,11 @@ namespace HandyControlDemo.Properties.Langs
/// </summary>
public string ImageBrowser => Lang.ImageBrowser;
/// <summary>
/// 查找类似 图片选择器 的本地化字符串。
/// </summary>
public string ImageSelector => Lang.ImageSelector;
/// <summary>
/// 查找类似 索引 的本地化字符串。
/// </summary>
@@ -1760,6 +1766,11 @@ namespace HandyControlDemo.Properties.Langs
/// </summary>
public static string ImageBrowser = nameof(ImageBrowser);
/// <summary>
/// 查找类似 图片选择器 的本地化字符串。
/// </summary>
public static string ImageSelector = nameof(ImageSelector);
/// <summary>
/// 查找类似 索引 的本地化字符串。
/// </summary>
Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

@@ -0,0 +1,10 @@
namespace HandyControlDemo.UserControl
{
public partial class ImageSelectorDemoCtl
{
public ImageSelectorDemoCtl()
{
InitializeComponent();
}
}
}
@@ -44,7 +44,7 @@
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<hc:SearchBar ShowClearButton="True" TextChanged="SearchBar_OnTextChanged" SearchStarted="SearchBar_OnSearchStarted" Style="{StaticResource SearchBarPlus}" hc:InfoElement.Placeholder="{ex:Lang Key={x:Static langs:LangKeys.PlsEnterKey}}" Margin="0,4,4,4" Tag="{Binding ElementName=ListBoxDemo}"/>
<hc:SearchBar ShowClearButton="True" IsRealTime="True" SearchStarted="SearchBar_OnSearchStarted" Style="{StaticResource SearchBarPlus}" hc:InfoElement.Placeholder="{ex:Lang Key={x:Static langs:LangKeys.PlsEnterKey}}" Margin="0,4,4,4" Tag="{Binding ElementName=ListBoxDemo}"/>
<ToggleButton Tag="{Binding ElementName=ListBoxDemo}" Name="ButtonStyleAscending" Click="ButtonAscending_OnClick" Grid.Row="0" Grid.Column="1" Style="{StaticResource DemoInfoSortButtonStyle}"/>
<ListBox Name="ListBoxDemo" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" VirtualizingStackPanel.IsVirtualizing="True" SelectedIndex="{Binding SelectedIndex}" ItemsSource="{Binding DemoItemList}" BorderThickness="0" SelectionMode="Single" Style="{StaticResource ListBoxTransparent}">
<ListBox.ItemTemplate>
@@ -2,7 +2,6 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using HandyControl.Controls;
using HandyControl.Data;
using HandyControlDemo.Data;
using HandyControlDemo.ViewModel;
@@ -31,6 +30,7 @@ namespace HandyControlDemo.UserControl
var selectedIndex = demoInfo.SelectedIndex;
demoInfo.SelectedIndex = -1;
demoInfo.SelectedIndex = selectedIndex;
FilterItems();
}
}
@@ -52,6 +52,11 @@ namespace HandyControlDemo.UserControl
private void SearchBar_OnSearchStarted(object sender, FunctionEventArgs<string> e)
{
_searchKey = e.Info;
FilterItems();
}
private void FilterItems()
{
if (string.IsNullOrEmpty(_searchKey))
{
foreach (var item in ViewModelLocator.Instance.Main.DemoInfoCurrent.DemoItemList)
@@ -68,7 +73,7 @@ namespace HandyControlDemo.UserControl
{
item.IsVisible = true;
}
else if(item.TargetCtlName.Replace("DemoCtl", "").ToLower().Contains(key))
else if (item.TargetCtlName.Replace("DemoCtl", "").ToLower().Contains(key))
{
item.IsVisible = true;
}
@@ -87,20 +92,5 @@ namespace HandyControlDemo.UserControl
}
}
}
private void SearchBar_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (e.OriginalSource is SearchBar searchBar)
{
_searchKey = searchBar.Text;
if (string.IsNullOrEmpty(_searchKey))
{
foreach (var item in ViewModelLocator.Instance.Main.DemoInfoCurrent.DemoItemList)
{
item.IsVisible = true;
}
}
}
}
}
}
@@ -0,0 +1,126 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using HandyControl.Data;
using HandyControl.Interactivity;
using Microsoft.Win32;
namespace HandyControl.Controls
{
public class ImageSelector : Control
{
public ImageSelector() => CommandBindings.Add(new CommandBinding(ControlCommands.Switch, SwitchImage));
private void SwitchImage(object sender, ExecutedRoutedEventArgs e)
{
if (!HasValue)
{
var dialog = new OpenFileDialog
{
RestoreDirectory = true,
Filter = Filter,
DefaultExt = DefaultExt
};
if (dialog.ShowDialog() == true)
{
SetValue(UriPropertyKey, new Uri(dialog.FileName, UriKind.RelativeOrAbsolute));
SetValue(PreviewBrushPropertyKey, new ImageBrush(BitmapFrame.Create(Uri, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.None))
{
Stretch = Stretch
});
SetValue(HasValuePropertyKey, ValueBoxes.TrueBox);
SetCurrentValue(ToolTipProperty, dialog.FileName);
}
}
else
{
SetValue(UriPropertyKey, default(Uri));
SetValue(PreviewBrushPropertyKey, default(Brush));
SetValue(HasValuePropertyKey, ValueBoxes.FalseBox);
SetCurrentValue(ToolTipProperty, default);
}
}
public static readonly DependencyProperty StretchProperty = DependencyProperty.Register(
"Stretch", typeof(Stretch), typeof(ImageSelector), new PropertyMetadata(default(Stretch)));
public Stretch Stretch
{
get => (Stretch) GetValue(StretchProperty);
set => SetValue(StretchProperty, value);
}
public static readonly DependencyPropertyKey UriPropertyKey = DependencyProperty.RegisterReadOnly(
"Uri", typeof(Uri), typeof(ImageSelector), new PropertyMetadata(default(Uri)));
public static readonly DependencyProperty UriProperty = UriPropertyKey.DependencyProperty;
public Uri Uri
{
get => (Uri) GetValue(UriProperty);
set => SetValue(UriProperty, value);
}
public static readonly DependencyPropertyKey PreviewBrushPropertyKey = DependencyProperty.RegisterReadOnly(
"PreviewBrush", typeof(Brush), typeof(ImageSelector), new PropertyMetadata(default(Brush)));
public static readonly DependencyProperty PreviewBrushProperty = PreviewBrushPropertyKey.DependencyProperty;
public Brush PreviewBrush
{
get => (Brush) GetValue(PreviewBrushProperty);
set => SetValue(PreviewBrushProperty, value);
}
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
"StrokeThickness", typeof(double), typeof(ImageSelector), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, FrameworkPropertyMetadataOptions.AffectsRender));
public double StrokeThickness
{
get => (double) GetValue(StrokeThicknessProperty);
set => SetValue(StrokeThicknessProperty, value);
}
public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register(
"StrokeDashArray", typeof(DoubleCollection), typeof(ImageSelector), new FrameworkPropertyMetadata(default(DoubleCollection), FrameworkPropertyMetadataOptions.AffectsRender));
public DoubleCollection StrokeDashArray
{
get => (DoubleCollection) GetValue(StrokeDashArrayProperty);
set => SetValue(StrokeDashArrayProperty, value);
}
public static readonly DependencyProperty DefaultExtProperty = DependencyProperty.Register(
"DefaultExt", typeof(string), typeof(ImageSelector), new PropertyMetadata(".jpg"));
public string DefaultExt
{
get => (string) GetValue(DefaultExtProperty);
set => SetValue(DefaultExtProperty, value);
}
public static readonly DependencyProperty FilterProperty = DependencyProperty.Register(
"Filter", typeof(string), typeof(ImageSelector), new PropertyMetadata("(.jpg)|*.jpg|(.png)|*.png"));
public string Filter
{
get => (string) GetValue(FilterProperty);
set => SetValue(FilterProperty, value);
}
public static readonly DependencyPropertyKey HasValuePropertyKey = DependencyProperty.RegisterReadOnly(
"HasValue", typeof(bool), typeof(ImageSelector), new PropertyMetadata(ValueBoxes.FalseBox));
public static readonly DependencyProperty HasValueProperty = HasValuePropertyKey.DependencyProperty;
public bool HasValue
{
get => (bool) GetValue(HasValueProperty);
set => SetValue(HasValueProperty, value);
}
}
}
@@ -0,0 +1,670 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Expression.Drawing;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
{
public class DashBorder : Decorator
{
private bool _useComplexRenderCodePath;
private Pen GeometryPenCache { get; set; }
private Pen LeftPenCache { get; set; }
private Pen RightPenCache { get; set; }
private Pen TopPenCache { get; set; }
private Pen BottomPenCache { get; set; }
private StreamGeometry BackgroundGeometryCache { get; set; }
private StreamGeometry BorderGeometryCache { get; set; }
private static void OnClearPenCache(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var border = (DashBorder)d;
border.LeftPenCache = null;
border.RightPenCache = null;
border.TopPenCache = null;
border.BottomPenCache = null;
border.GeometryPenCache = null;
}
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register(
"BorderThickness", typeof(Thickness), typeof(DashBorder), new FrameworkPropertyMetadata(default(Thickness),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnClearPenCache));
public Thickness BorderThickness
{
get => (Thickness) GetValue(BorderThicknessProperty);
set => SetValue(BorderThicknessProperty, value);
}
public static readonly DependencyProperty BorderDashThicknessProperty = DependencyProperty.Register(
"BorderDashThickness", typeof(double), typeof(DashBorder), new FrameworkPropertyMetadata(ValueBoxes.Double0Box,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnClearPenCache));
public double BorderDashThickness
{
get => (double) GetValue(BorderDashThicknessProperty);
set => SetValue(BorderDashThicknessProperty, value);
}
public static readonly DependencyProperty PaddingProperty = DependencyProperty.Register(
"Padding", typeof(Thickness), typeof(DashBorder), new FrameworkPropertyMetadata(default(Thickness),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public Thickness Padding
{
get => (Thickness) GetValue(PaddingProperty);
set => SetValue(PaddingProperty, value);
}
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
"CornerRadius", typeof(CornerRadius), typeof(DashBorder), new FrameworkPropertyMetadata(default(CornerRadius),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
public CornerRadius CornerRadius
{
get => (CornerRadius) GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register(
"BorderBrush", typeof(Brush), typeof(DashBorder), new FrameworkPropertyMetadata(default(Brush),
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender,
OnClearPenCache));
public Brush BorderBrush
{
get => (Brush) GetValue(BorderBrushProperty);
set => SetValue(BorderBrushProperty, value);
}
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register(
"Background", typeof(Brush), typeof(DashBorder), new FrameworkPropertyMetadata(default(Brush),
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender,
OnClearPenCache));
public Brush Background
{
get => (Brush) GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
public static readonly DependencyProperty BorderDashArrayProperty = DependencyProperty.Register(
"BorderDashArray", typeof(DoubleCollection), typeof(DashBorder), new FrameworkPropertyMetadata(default(DoubleCollection),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnClearPenCache));
public DoubleCollection BorderDashArray
{
get => (DoubleCollection) GetValue(BorderDashArrayProperty);
set => SetValue(BorderDashArrayProperty, value);
}
public static readonly DependencyProperty BorderDashCapProperty = DependencyProperty.Register(
"BorderDashCap", typeof(PenLineCap), typeof(DashBorder), new FrameworkPropertyMetadata(default(PenLineCap),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnClearPenCache));
public PenLineCap BorderDashCap
{
get => (PenLineCap) GetValue(BorderDashCapProperty);
set => SetValue(BorderDashCapProperty, value);
}
public static readonly DependencyProperty BorderDashOffsetProperty = DependencyProperty.Register(
"BorderDashOffset", typeof(double), typeof(DashBorder), new FrameworkPropertyMetadata(ValueBoxes.Double0Box,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnClearPenCache));
public double BorderDashOffset
{
get => (double) GetValue(BorderDashOffsetProperty);
set => SetValue(BorderDashOffsetProperty, value);
}
private static Size ConvertThickness2Size(Thickness th) => new Size(th.Left + th.Right, th.Top + th.Bottom);
private static Rect DeflateRect(Rect rt, Thickness thick) => new Rect(rt.Left + thick.Left,
rt.Top + thick.Top,
Math.Max(0.0, rt.Width - thick.Left - thick.Right),
Math.Max(0.0, rt.Height - thick.Top - thick.Bottom));
private static bool AreUniformCorners(CornerRadius borderRadii)
{
var topLeft = borderRadii.TopLeft;
return MathHelper.AreClose(topLeft, borderRadii.TopRight) &&
MathHelper.AreClose(topLeft, borderRadii.BottomLeft) &&
MathHelper.AreClose(topLeft, borderRadii.BottomRight);
}
private static void GenerateGeometry(StreamGeometryContext ctx, Rect rect, in Radii radii)
{
var topLeft = new Point(radii.LeftTop, 0);
var topRight = new Point(rect.Width - radii.RightTop, 0);
var rightTop = new Point(rect.Width, radii.TopRight);
var rightBottom = new Point(rect.Width, rect.Height - radii.BottomRight);
var bottomRight = new Point(rect.Width - radii.RightBottom, rect.Height);
var bottomLeft = new Point(radii.LeftBottom, rect.Height);
var leftBottom = new Point(0, rect.Height - radii.BottomLeft);
var leftTop = new Point(0, radii.TopLeft);
// top edge
if (topLeft.X > topRight.X)
{
var v = radii.LeftTop / (radii.LeftTop + radii.RightTop) * rect.Width;
topLeft.X = v;
topRight.X = v;
}
// right edge
if (rightTop.Y > rightBottom.Y)
{
var v = radii.TopRight / (radii.TopRight + radii.BottomRight) * rect.Height;
rightTop.Y = v;
rightBottom.Y = v;
}
// bottom edge
if (bottomRight.X < bottomLeft.X)
{
var v = radii.LeftBottom / (radii.LeftBottom + radii.RightBottom) * rect.Width;
bottomRight.X = v;
bottomLeft.X = v;
}
// left edge
if (leftBottom.Y < leftTop.Y)
{
var v = radii.TopLeft / (radii.TopLeft + radii.BottomLeft) * rect.Height;
leftBottom.Y = v;
leftTop.Y = v;
}
// add on offsets
var offset = new Vector(rect.TopLeft.X, rect.TopLeft.Y);
topLeft += offset;
topRight += offset;
rightTop += offset;
rightBottom += offset;
bottomRight += offset;
bottomLeft += offset;
leftBottom += offset;
leftTop += offset;
// create the border geometry
ctx.BeginFigure(topLeft, true, true);
// Top line
ctx.LineTo(topRight, true, false);
// Upper-right corner
var radiusX = rect.TopRight.X - topRight.X;
var radiusY = rightTop.Y - rect.TopRight.Y;
if (!MathHelper.IsZero(radiusX) || !MathHelper.IsZero(radiusY))
{
ctx.ArcTo(rightTop, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
}
// Right line
ctx.LineTo(rightBottom, true, false);
// Lower-right corner
radiusX = rect.BottomRight.X - bottomRight.X;
radiusY = rect.BottomRight.Y - rightBottom.Y;
if (!MathHelper.IsZero(radiusX) || !MathHelper.IsZero(radiusY))
{
ctx.ArcTo(bottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
}
// Bottom line
ctx.LineTo(bottomLeft, true, false);
// Lower-left corner
radiusX = bottomLeft.X - rect.BottomLeft.X;
radiusY = rect.BottomLeft.Y - leftBottom.Y;
if (!MathHelper.IsZero(radiusX) || !MathHelper.IsZero(radiusY))
{
ctx.ArcTo(leftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
}
// Left line
ctx.LineTo(leftTop, true, false);
// Upper-left corner
radiusX = topLeft.X - rect.TopLeft.X;
radiusY = leftTop.Y - rect.TopLeft.Y;
if (!MathHelper.IsZero(radiusX) || !MathHelper.IsZero(radiusY))
{
ctx.ArcTo(topLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
}
}
protected override Size MeasureOverride(Size constraint)
{
var child = Child;
var borderThickness = BorderThickness;
var padding = Padding;
if (UseLayoutRounding)
{
var dpiScaleX = DpiHelper.DeviceDpiX;
var dpiScaleY = DpiHelper.DeviceDpiY;
borderThickness = new Thickness(
DpiHelper.RoundLayoutValue(borderThickness.Left, dpiScaleX),
DpiHelper.RoundLayoutValue(borderThickness.Top, dpiScaleY),
DpiHelper.RoundLayoutValue(borderThickness.Right, dpiScaleX),
DpiHelper.RoundLayoutValue(borderThickness.Bottom, dpiScaleY));
}
var borderSize = ConvertThickness2Size(borderThickness);
var paddingSize = ConvertThickness2Size(padding);
var mySize = new Size();
if (child != null)
{
var combined = new Size(borderSize.Width + paddingSize.Width, borderSize.Height + paddingSize.Height);
var childConstraint = new Size(Math.Max(0.0, constraint.Width - combined.Width), Math.Max(0.0, constraint.Height - combined.Height));
child.Measure(childConstraint);
var childSize = child.DesiredSize;
mySize.Width = childSize.Width + combined.Width;
mySize.Height = childSize.Height + combined.Height;
}
else
{
mySize = new Size(borderSize.Width + paddingSize.Width, borderSize.Height + paddingSize.Height);
}
return mySize;
}
protected override Size ArrangeOverride(Size arrangeSize)
{
var borderThickness = BorderThickness;
if (UseLayoutRounding)
{
var dpiScaleX = DpiHelper.DeviceDpiX;
var dpiScaleY = DpiHelper.DeviceDpiY;
borderThickness = new Thickness(
DpiHelper.RoundLayoutValue(borderThickness.Left, dpiScaleX),
DpiHelper.RoundLayoutValue(borderThickness.Top, dpiScaleY),
DpiHelper.RoundLayoutValue(borderThickness.Right, dpiScaleX),
DpiHelper.RoundLayoutValue(borderThickness.Bottom, dpiScaleY));
}
var boundRect = new Rect(arrangeSize);
var innerRect = DeflateRect(boundRect, borderThickness);
var child = Child;
if (child != null)
{
var padding = Padding;
var childRect = DeflateRect(innerRect, padding);
child.Arrange(childRect);
}
var radii = CornerRadius;
var borderBrush = BorderBrush;
var uniformCorners = AreUniformCorners(radii);
_useComplexRenderCodePath = !uniformCorners;
if (!_useComplexRenderCodePath && borderBrush != null)
{
_useComplexRenderCodePath = !MathHelper.IsZero(radii.TopLeft) && !borderThickness.IsUniform();
}
if (_useComplexRenderCodePath)
{
var innerRadii = new Radii(radii, borderThickness, false);
StreamGeometry backgroundGeometry = null;
if (!MathHelper.IsZero(innerRect.Width) && !MathHelper.IsZero(innerRect.Height))
{
backgroundGeometry = new StreamGeometry();
using (var ctx = backgroundGeometry.Open())
{
GenerateGeometry(ctx, innerRect, innerRadii);
}
backgroundGeometry.Freeze();
BackgroundGeometryCache = backgroundGeometry;
}
else
{
BackgroundGeometryCache = null;
}
if (!MathHelper.IsZero(boundRect.Width) && !MathHelper.IsZero(boundRect.Height))
{
var outerRadii = new Radii(radii, borderThickness, true);
var borderGeometry = new StreamGeometry();
using (var ctx = borderGeometry.Open())
{
GenerateGeometry(ctx, boundRect, outerRadii);
if (backgroundGeometry != null)
{
GenerateGeometry(ctx, innerRect, innerRadii);
}
}
borderGeometry.Freeze();
BorderGeometryCache = borderGeometry;
}
else
{
BorderGeometryCache = null;
}
}
else
{
BackgroundGeometryCache = null;
BorderGeometryCache = null;
}
return arrangeSize;
}
protected override void OnRender(DrawingContext drawingContext)
{
var background = Background;
var borderBrush = BorderBrush;
var useLayoutRounding = UseLayoutRounding;
if (_useComplexRenderCodePath)
{
var borderGeometry = BorderGeometryCache;
if (borderGeometry != null && borderBrush != null)
{
var pen = GeometryPenCache;
if (pen == null)
{
pen = new Pen
{
Brush = borderBrush,
Thickness = BorderDashThickness,
DashCap = BorderDashCap,
DashStyle = new DashStyle(BorderDashArray, BorderDashOffset)
};
if (borderBrush.IsFrozen)
{
pen.Freeze();
}
GeometryPenCache = pen;
}
drawingContext.DrawGeometry(null, pen, borderGeometry);
}
var backgroundGeometry = BackgroundGeometryCache;
if (backgroundGeometry != null && background != null)
{
drawingContext.DrawGeometry(background, null, backgroundGeometry);
}
}
else
{
var dpiScaleX = DpiHelper.DeviceDpiX;
var dpiScaleY = DpiHelper.DeviceDpiY;
var borderThickness = BorderThickness;
var cornerRadius = CornerRadius;
var outerCornerRadius = cornerRadius.TopLeft;
var roundedCorners = !MathHelper.IsZero(outerCornerRadius);
if (!borderThickness.IsZero() && borderBrush != null)
{
var pen = LeftPenCache;
if (pen == null)
{
pen = new Pen
{
Brush = borderBrush,
Thickness = useLayoutRounding
? DpiHelper.RoundLayoutValue(borderThickness.Left, dpiScaleX)
: borderThickness.Left,
DashCap = BorderDashCap,
DashStyle = new DashStyle(BorderDashArray, BorderDashOffset)
};
if (borderBrush.IsFrozen)
{
pen.Freeze();
}
LeftPenCache = pen;
}
double halfThickness;
var renderSize = RenderSize;
if (borderThickness.IsUniform())
{
halfThickness = pen.Thickness * 0.5;
var rect = new Rect(new Point(halfThickness, halfThickness), new Point(renderSize.Width - halfThickness, renderSize.Height - halfThickness));
if (roundedCorners)
{
drawingContext.DrawRoundedRectangle(null, pen, rect, outerCornerRadius, outerCornerRadius);
}
else
{
drawingContext.DrawRectangle(null, pen, rect);
}
}
else
{
if (MathHelper.GreaterThan(borderThickness.Left, 0))
{
halfThickness = pen.Thickness * 0.5;
drawingContext.DrawLine(pen, new Point(halfThickness, 0), new Point(halfThickness, renderSize.Height));
}
if (MathHelper.GreaterThan(borderThickness.Right, 0))
{
pen = RightPenCache;
if (pen == null)
{
pen = new Pen
{
Brush = borderBrush,
Thickness = useLayoutRounding
? DpiHelper.RoundLayoutValue(borderThickness.Right, dpiScaleX)
: borderThickness.Right,
DashCap = BorderDashCap,
DashStyle = new DashStyle(BorderDashArray, BorderDashOffset)
};
if (borderBrush.IsFrozen)
{
pen.Freeze();
}
RightPenCache = pen;
}
halfThickness = pen.Thickness * 0.5;
drawingContext.DrawLine(pen, new Point(renderSize.Width - halfThickness, 0), new Point(renderSize.Width - halfThickness, renderSize.Height));
}
if (MathHelper.GreaterThan(borderThickness.Top, 0))
{
pen = TopPenCache;
if (pen == null)
{
pen = new Pen
{
Brush = borderBrush,
Thickness = useLayoutRounding
? DpiHelper.RoundLayoutValue(borderThickness.Top, dpiScaleY)
: borderThickness.Top,
DashCap = BorderDashCap,
DashStyle = new DashStyle(BorderDashArray, BorderDashOffset)
};
if (borderBrush.IsFrozen)
{
pen.Freeze();
}
TopPenCache = pen;
}
halfThickness = pen.Thickness * 0.5;
drawingContext.DrawLine(pen, new Point(0, halfThickness), new Point(renderSize.Width, halfThickness));
}
if (MathHelper.GreaterThan(borderThickness.Bottom, 0))
{
pen = BottomPenCache;
if (pen == null)
{
pen = new Pen
{
Brush = borderBrush,
Thickness = useLayoutRounding
? DpiHelper.RoundLayoutValue(borderThickness.Bottom, dpiScaleY)
: borderThickness.Bottom,
DashCap = BorderDashCap,
DashStyle = new DashStyle(BorderDashArray, BorderDashOffset)
};
if (borderBrush.IsFrozen)
{
pen.Freeze();
}
BottomPenCache = pen;
}
halfThickness = pen.Thickness * 0.5;
drawingContext.DrawLine(pen, new Point(0, renderSize.Height - halfThickness), new Point(renderSize.Width, renderSize.Height - halfThickness));
}
}
}
if (background != null)
{
Point ptTL, ptBR;
if (useLayoutRounding)
{
ptTL = new Point(DpiHelper.RoundLayoutValue(borderThickness.Left, dpiScaleX), DpiHelper.RoundLayoutValue(borderThickness.Top, dpiScaleY));
ptBR = new Point(RenderSize.Width - DpiHelper.RoundLayoutValue(borderThickness.Right, dpiScaleX),
RenderSize.Height - DpiHelper.RoundLayoutValue(borderThickness.Bottom, dpiScaleY));
}
else
{
ptTL = new Point(borderThickness.Left, borderThickness.Top);
ptBR = new Point(RenderSize.Width - borderThickness.Right, RenderSize.Height - borderThickness.Bottom);
}
if (ptBR.X > ptTL.X && ptBR.Y > ptTL.Y)
{
if (roundedCorners)
{
var innerRadii = new Radii(cornerRadius, borderThickness, false);
var innerCornerRadius = innerRadii.TopLeft;
drawingContext.DrawRoundedRectangle(background, null, new Rect(ptTL, ptBR), innerCornerRadius, innerCornerRadius);
}
else
{
drawingContext.DrawRectangle(background, null, new Rect(ptTL, ptBR));
}
}
}
}
}
private readonly struct Radii
{
internal Radii(CornerRadius radii, Thickness borders, bool outer)
{
var left = 0.5 * borders.Left;
var top = 0.5 * borders.Top;
var right = 0.5 * borders.Right;
var bottom = 0.5 * borders.Bottom;
if (outer)
{
if (MathHelper.IsZero(radii.TopLeft))
{
LeftTop = TopLeft = 0.0;
}
else
{
LeftTop = radii.TopLeft + left;
TopLeft = radii.TopLeft + top;
}
if (MathHelper.IsZero(radii.TopRight))
{
TopRight = RightTop = 0.0;
}
else
{
TopRight = radii.TopRight + top;
RightTop = radii.TopRight + right;
}
if (MathHelper.IsZero(radii.BottomRight))
{
RightBottom = BottomRight = 0.0;
}
else
{
RightBottom = radii.BottomRight + right;
BottomRight = radii.BottomRight + bottom;
}
if (MathHelper.IsZero(radii.BottomLeft))
{
BottomLeft = LeftBottom = 0.0;
}
else
{
BottomLeft = radii.BottomLeft + bottom;
LeftBottom = radii.BottomLeft + left;
}
}
else
{
LeftTop = Math.Max(0.0, radii.TopLeft - left);
TopLeft = Math.Max(0.0, radii.TopLeft - top);
TopRight = Math.Max(0.0, radii.TopRight - top);
RightTop = Math.Max(0.0, radii.TopRight - right);
RightBottom = Math.Max(0.0, radii.BottomRight - right);
BottomRight = Math.Max(0.0, radii.BottomRight - bottom);
BottomLeft = Math.Max(0.0, radii.BottomLeft - bottom);
LeftBottom = Math.Max(0.0, radii.BottomLeft - left);
}
}
internal readonly double LeftTop;
internal readonly double TopLeft;
internal readonly double TopRight;
internal readonly double RightTop;
internal readonly double RightBottom;
internal readonly double BottomRight;
internal readonly double BottomLeft;
internal readonly double LeftBottom;
}
}
}
@@ -73,7 +73,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty HidingHeightProperty = DependencyProperty.Register(
"HidingHeight", typeof(double), typeof(GotoTop), new PropertyMetadata(default(double)));
"HidingHeight", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double0Box));
public double HidingHeight
{
@@ -12,7 +12,7 @@ namespace HandyControl.Controls
/// </remarks>
public class SimplePanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
protected override Size MeasureOverride(Size constraint)
{
var maxSize = new Size();
@@ -20,7 +20,7 @@ namespace HandyControl.Controls
{
if (child != null)
{
child.Measure(availableSize);
child.Measure(constraint);
maxSize.Width = Math.Max(maxSize.Width, child.DesiredSize.Width);
maxSize.Height = Math.Max(maxSize.Height, child.DesiredSize.Height);
}
@@ -76,7 +76,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty MaxTitleWidthProperty = DependencyProperty.Register(
"MaxTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
"MaxTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(ValueBoxes.Double0Box));
public double MaxTitleWidth
{
@@ -85,7 +85,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty MinTitleWidthProperty = DependencyProperty.Register(
"MinTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
"MinTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(ValueBoxes.Double0Box));
public double MinTitleWidth
{
@@ -2,6 +2,7 @@
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
namespace HandyControl.Controls
{
@@ -62,7 +63,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(
"IsReadOnly", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
"IsReadOnly", typeof(bool), typeof(PropertyItem), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsReadOnly
{
@@ -107,7 +108,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
"IsSelected", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
"IsSelected", typeof(bool), typeof(PropertyItem), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsSelected
{
@@ -116,7 +117,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty IsExpandedEnabledProperty = DependencyProperty.Register(
"IsExpandedEnabled", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
"IsExpandedEnabled", typeof(bool), typeof(PropertyItem), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsExpandedEnabled
{
@@ -76,10 +76,8 @@ namespace HandyControl.Data
{
FrameCount = 1;
}
if (_frameDelay == null)
{
_frameDelay = new int[FrameCount];
}
_frameDelay ??= new int[FrameCount];
}
public int FrameDelay(int frame) => _frameDelay[frame];
@@ -4,6 +4,8 @@ namespace HandyControl.Expression.Drawing
{
internal static class MathHelper
{
internal const double DBL_EPSILON = 2.2204460492503131e-016;
public static bool AreClose(double value1, double value2) =>
// ReSharper disable once CompareOfFloatsByEqualityOperator
value1 == value2 || IsVerySmall(value1 - value2);
@@ -12,6 +14,8 @@ namespace HandyControl.Expression.Drawing
public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06;
public static bool IsZero(double value) => Math.Abs(value) < 10.0 * DBL_EPSILON;
public static bool IsFiniteDouble(double x) => !double.IsInfinity(x) && !double.IsNaN(x);
public static double DoubleFromMantissaAndExponent(double x, int exp) => x * Math.Pow(2.0, exp);
@@ -31,7 +31,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Dialog\DialogContainer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\GrowlWindow.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Image\ImageBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Input\ImageSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Input\PinBox.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\DashBorder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Divider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Drawer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Magnifier.cs" />
@@ -436,6 +438,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\ImageSelector.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\ImageSelectorBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\PropertyGrid.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -42,7 +42,8 @@
<Geometry o:Freeze="True" x:Key="AudioGeometry">M627.52666696 962L550.66666696 890.47999971c116.82-92.99999971 191.09999971-230.94 191.09999971-385.2 0-146.99999971-67.61999971-279-174.96-371.57999942L643.84666667 62C770.86666638 172.99999971 850.66666667 330.2 850.66666667 505.09999971c0 182.27999971-86.58 345.42-223.13999971 456.90000029zM405.64666638 782l-76.32-77.22a227.88 227.88 0 0 0 116.40000058-199.26A228.06 228.06 0 0 0 347.86666638 317.84000029L422.86666696 242A334.37999971 334.37999971 0 0 1 550.66666696 505.52 334.62 334.62 0 0 1 405.64666638 782zM205.66666638 596.6C164.26666638 596.6 130.66666667 562.51999971 130.66666667 520.64 130.66666667 478.76000029 164.26666638 444.79999971 205.66666638 444.79999971s74.99999971 33.95999971 75.00000058 75.90000058c0 41.87999971-33.59999971 75.84000029-75.00000058 75.83999942z</Geometry>
<Geometry o:Freeze="True" x:Key="BubbleTailGeometry">M0,0L28,0 28,14.0000006258488 28,15.0010000765324 28.0151405334473,15.0010000765324 28.0455417633057,15.8010965883732C28.4084091186524,22.9596563875675,30.92209815979,29.5507589876652,34.9532623291016,34.9410597383976L34.9984359741211,34.9999815523624 34.0966339111328,34.9885679781437C15.1841707229614,34.5094191133976,2.0535663480814E-07,19.0279375612736,0,0z</Geometry>
<Geometry o:Freeze="True" x:Key="StarGeometry">M535.9 165.2l96.5 195.4c3.9 7.9 11.4 13.3 20.1 14.6l215.7 31.3c21.9 3.2 30.6 30 14.8 45.5L726.8 604.1c-6.3 6.1-9.1 14.9-7.7 23.6L756 842.5c3.7 21.8-19.1 38.4-38.7 28.1L524.4 769.2c-7.8-4.1-17-4.1-24.8 0L306.7 870.6c-19.6 10.3-42.4-6.3-38.7-28.1l36.8-214.8c1.5-8.6-1.4-17.5-7.7-23.6L141.1 452c-15.8-15.4-7.1-42.3 14.8-45.5l215.7-31.3c8.7-1.3 16.2-6.7 20.1-14.6l96.5-195.4c9.7-19.9 37.9-19.9 47.7 0z</Geometry>
<Geometry o:Freeze="True" x:Key="AddGeometry">M938.666667 426.666667h-341.333334V85.333333c0-46.933333-38.4-85.333333-85.333333-85.333333s-85.333333 38.4-85.333333 85.333333v341.333334H85.333333c-46.933333 0-85.333333 38.4-85.333333 85.333333s38.4 85.333333 85.333333 85.333333h341.333334v341.333334c0 46.933333 38.4 85.333333 85.333333 85.333333s85.333333-38.4 85.333333-85.333333v-341.333334h341.333334c46.933333 0 85.333333-38.4 85.333333-85.333333s-38.4-85.333333-85.333333-85.333333z</Geometry>
<Geometry o:Freeze="True" x:Key="AddGeometry">M8,0 C8.5522847,0 9,0.44771525 9,1 L9,7 15,7 C15.552285,7 16,7.4477153 16,8 16,8.5522852 15.552285,9 15,9 L9,9 9,15 C9,15.552285 8.5522847,16 8,16 7.4477153,16 7,15.552285 7,15 L7,9 1,9 C0.44771528,9 0,8.5522852 0,8 0,7.4477153 0.44771528,7 1,7 L7,7 7,1 C7,0.44771525 7.4477153,0 8,0 z</Geometry>
<Geometry o:Freeze="True" x:Key="RemoveGeometry">M10.899495,0 C11.155417,0 11.411339,0.097630501 11.606602,0.29289246 11.997126,0.68341732 11.997126,1.3165817 11.606602,1.7071066 L7.3639612,5.9497471 11.606602,10.192388 C11.997126,10.582912 11.997126,11.216077 11.606602,11.606601 11.216077,11.997126 10.582912,11.997126 10.192388,11.606601 L5.9497476,7.3639607 1.7071068,11.606601 C1.3165827,11.997126 0.68341756,11.997126 0.29289341,11.606601 -0.097630978,11.216077 -0.097630978,10.582912 0.29289341,10.192388 L4.5355338,5.9497471 0.29289341,1.7071066 C-0.097630978,1.3165817 -0.097630978,0.68341732 0.29289341,0.29289246 0.48815536,0.097630501 0.74407768,0 1,0 1.2559223,0 1.5118446,0.097630501 1.7071068,0.29289246 L5.9497476,4.5355334 10.192388,0.29289246 C10.38765,0.097630501 10.643572,0 10.899495,0 z</Geometry>
<Geometry o:Freeze="True" x:Key="SubGeometry">M62.5797 488.9508c0.2632 42.5185 34.985 77.2116 77.5035 77.5035l743.0216-0.6728c42.5185 0.3215 76.7437-33.9333 76.4518-76.4805l0 0c-0.2918-42.5175-34.985-77.2106-77.5045-77.5035l-743.0216-0.087C96.513 411.4473 62.2879 446.4323 62.5797 488.9508L62.5797 488.9508z</Geometry>
<Geometry o:Freeze="True" x:Key="WarningGeometry">M943.644188 827.215696l-351.176649-608.204749c-42.945473-74.36249-113.147387-74.36249-156.092861 0l-351.176649 608.204749c-42.946498 74.431167-7.811716 135.14955 78.012605 135.14955l702.420949 0C951.455904 962.36422 986.555836 901.645838 943.644188 827.215696zM466.187532 391.579035c12.621133-13.644108 28.66175-20.466675 48.233578-20.466675 19.580028 0 35.612444 6.75389 48.241778 20.194018 12.544256 13.473954 18.820484 30.325365 18.820484 50.587035 0 17.430551-26.19759 145.621205-34.929778 238.882082l-63.105666 0c-7.666162-93.259852-36.090106-221.450507-36.090106-238.882082C447.358847 421.938226 453.643275 405.155491 466.187532 391.579035zM561.76804 835.026386c-13.268949 12.928641-29.062535 19.375023-47.345906 19.375023-18.275171 0-34.076957-6.447407-47.346931-19.375023-13.235123-12.89379-19.818859-28.517221-19.818859-46.869269 0-18.249546 6.583736-34.043131 19.818859-47.278254 13.268949-13.235123 29.07176-19.852685 47.346931-19.852685 18.283371 0 34.076957 6.617562 47.345906 19.852685 13.235123 13.235123 19.827059 29.028709 19.827059 47.278254C581.595099 806.51019 575.003163 822.132597 561.76804 835.026386z</Geometry>
<Geometry o:Freeze="True" x:Key="InfoGeometry">M505.6512 39.0144c-261.2224 3.4816-470.1184 218.112-466.6368 479.4368 3.4816 261.12 218.112 470.1184 479.3344 466.6368 261.2224-3.4816 470.1184-218.112 466.7392-479.3344C981.504 244.4288 766.8736 35.5328 505.6512 39.0144zM558.08 196.608c48.128 0 62.2592 27.9552 62.2592 59.8016 0 39.8336-31.9488 76.6976-86.3232 76.6976-45.568 0-67.1744-22.9376-65.9456-60.8256C468.0704 240.4352 494.7968 196.608 558.08 196.608zM434.7904 807.6288c-32.8704 0-56.9344-19.968-33.8944-107.6224l37.6832-155.5456c6.5536-24.8832 7.68-34.9184 0-34.9184-9.8304 0-52.5312 17.2032-77.7216 34.2016l-16.384-26.9312c79.9744-66.7648 171.8272-105.8816 211.2512-105.8816 32.8704 0 38.2976 38.912 21.9136 98.6112l-43.2128 163.5328c-7.68 28.8768-4.4032 38.912 3.2768 38.912 9.9328 0 42.1888-11.9808 73.9328-36.9664l18.6368 24.8832C552.5504 777.728 467.6608 807.6288 434.7904 807.6288z</Geometry>
@@ -0,0 +1,55 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hc="clr-namespace:HandyControl.Controls"
xmlns:themes="clr-namespace:HandyControl.Themes"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
<ResourceDictionary.MergedDictionaries>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Basic/Geometries.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Rectangle.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Border.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ImageSelectorBaseStyle" TargetType="hc:ImageSelector">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Stretch" Value="UniformToFill"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="StrokeDashArray" Value="2,2"/>
<Setter Property="hc:IconSwitchElement.Geometry" Value="{StaticResource AddGeometry}"/>
<Setter Property="hc:IconSwitchElement.GeometrySelected" Value="{StaticResource RemoveGeometry}"/>
<Setter Property="hc:BorderElement.CornerRadius" Value="{StaticResource DefaultCornerRadius}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="hc:ImageSelector">
<Button Command="interactivity:ControlCommands.Switch" Style="{StaticResource ButtonCustom}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Border Background="{TemplateBinding Background}" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}">
<hc:DashBorder BorderDashArray="{TemplateBinding StrokeDashArray}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" BorderDashThickness="{TemplateBinding StrokeThickness}" Background="{TemplateBinding PreviewBrush}" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}">
<Border Width="30" Height="30" Background="{TemplateBinding Background}" Style="{StaticResource BorderCircular}">
<hc:ToggleBlock IsChecked="{TemplateBinding HasValue}">
<hc:ToggleBlock.CheckedContent>
<Path Data="{TemplateBinding hc:IconSwitchElement.GeometrySelected}" Width="12" Height="12" Fill="{DynamicResource PrimaryBrush}"/>
</hc:ToggleBlock.CheckedContent>
<hc:ToggleBlock.UnCheckedContent>
<Path Data="{TemplateBinding hc:IconSwitchElement.Geometry}" Width="16" Height="16" Fill="{DynamicResource PrimaryBrush}"/>
</hc:ToggleBlock.UnCheckedContent>
</hc:ToggleBlock>
</Border>
</hc:DashBorder>
</Border>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource SecondaryRegionBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
@@ -2,7 +2,7 @@
<Style TargetType="Image">
<Setter Property="Stretch" Value="Uniform" />
<Setter Property="RenderOptions.BitmapScalingMode" Value="LowQuality" />
<Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" />
</Style>
</ResourceDictionary>
@@ -0,0 +1,11 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:hc="clr-namespace:HandyControl.Controls"
xmlns:themes="clr-namespace:HandyControl.Themes">
<ResourceDictionary.MergedDictionaries>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Base/ImageSelectorBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource ImageSelectorBaseStyle}" TargetType="hc:ImageSelector"/>
</ResourceDictionary>
@@ -88,6 +88,7 @@
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/BlendEffectBox.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Screenshot.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Watermark.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/ImageSelector.xaml"/>
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/PropertyGrid.xaml"/>
</ResourceDictionary.MergedDictionaries>
@@ -1,9 +1,21 @@
using System.Windows;
using HandyControl.Expression.Drawing;
namespace HandyControl.Tools.Extension
{
public static class ValueExtension
{
public static Thickness Add(this Thickness a, Thickness b) => new Thickness(a.Left + b.Left, a.Top + b.Top, a.Right + b.Right, a.Bottom + b.Bottom);
public static bool IsZero(this Thickness thickness) =>
MathHelper.IsZero(thickness.Left)
&& MathHelper.IsZero(thickness.Top)
&& MathHelper.IsZero(thickness.Right)
&& MathHelper.IsZero(thickness.Bottom);
public static bool IsUniform(this Thickness thickness) =>
MathHelper.AreClose(thickness.Left, thickness.Top)
&& MathHelper.AreClose(thickness.Left, thickness.Right)
&& MathHelper.AreClose(thickness.Left, thickness.Bottom);
}
}
@@ -92,10 +92,7 @@ namespace HandyControl.Tools
{
// Construct the image array
//
if (ImageInfoList == null)
{
ImageInfoList = new List<GifImageInfo>();
}
ImageInfoList ??= new List<GifImageInfo>();
// Add the new image
//
@@ -108,7 +105,7 @@ namespace HandyControl.Tools
{
AnimationThread = new Thread(AnimateImages50Ms)
{
Name = typeof(ImageAnimator).Name,
Name = nameof(ImageAnimator),
IsBackground = true
};
AnimationThread.Start();
@@ -168,13 +165,18 @@ namespace HandyControl.Tools
if (Equals(image, imageInfo.Image))
{
if ((onFrameChangedHandler == imageInfo.FrameChangedHandler) || (onFrameChangedHandler != null && onFrameChangedHandler.Equals(imageInfo.FrameChangedHandler)))
if (onFrameChangedHandler == imageInfo.FrameChangedHandler || onFrameChangedHandler != null && onFrameChangedHandler.Equals(imageInfo.FrameChangedHandler))
{
ImageInfoList.Remove(imageInfo);
}
break;
}
}
if (!ImageInfoList.Any())
{
AnimationThread = null;
}
}
finally
{
@@ -224,7 +226,7 @@ namespace HandyControl.Tools
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals")]
private static void AnimateImages50Ms()
{
while (true)
while (ImageInfoList.Any())
{
// Acquire reader-lock to access imageInfoList, elemens in the list can be modified w/o needing a writer-lock.
// Observe that we don't need to check if the thread is waiting or a writer lock here since the thread this
@@ -1,6 +1,7 @@
using System;
using System.Windows;
using System.Windows.Media;
using HandyControl.Expression.Drawing;
using HandyControl.Tools.Interop;
namespace HandyControl.Tools
@@ -79,5 +80,25 @@ namespace HandyControl.Tools
result.Transform(TransformFromDevice.Matrix);
return result;
}
public static double RoundLayoutValue(double value, double dpiScale)
{
double newValue;
if (!MathHelper.AreClose(dpiScale, 1.0))
{
newValue = Math.Round(value * dpiScale) / dpiScale;
if (double.IsNaN(newValue) || double.IsInfinity(newValue) || MathHelper.AreClose(newValue, double.MaxValue))
{
newValue = value;
}
}
else
{
newValue = Math.Round(value);
}
return newValue;
}
}
}