add Gravatar

This commit is contained in:
NaBian committed 2019-03-03 16:12:12 +08:00
1 parent 3a425d0058
commit 5d8e4e566a
35 files changed
+636 -93

No files matched your search

+42 -1
View File
@@ -1,4 +1,9 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using HandyControl.Data;
using HandyControl.Tools.Converter;
namespace HandyControl.Controls
{
@@ -10,5 +15,41 @@ namespace HandyControl.Controls
public static void SetCornerRadius(DependencyObject element, CornerRadius value) => element.SetValue(CornerRadiusProperty, value);
public static CornerRadius GetCornerRadius(DependencyObject element) => (CornerRadius)element.GetValue(CornerRadiusProperty);
public static readonly DependencyProperty CircularProperty = DependencyProperty.RegisterAttached(
"Circular", typeof(bool), typeof(BorderElement), new PropertyMetadata(ValueBoxes.FalseBox, OnCircularChanged));
private static void OnCircularChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Border border)
{
if ((bool)e.NewValue)
{
border.SetBinding(FrameworkElement.MinWidthProperty,
new Binding(FrameworkElement.ActualWidthProperty.Name) { Source = border });
border.SetBinding(FrameworkElement.MinHeightProperty,
new Binding(FrameworkElement.ActualHeightProperty.Name) { Source = border });
var binding = new MultiBinding
{
Converter = new BorderCircularConverter()
};
binding.Bindings.Add(new Binding(FrameworkElement.ActualWidthProperty.Name) {Source = border});
binding.Bindings.Add(new Binding(FrameworkElement.ActualHeightProperty.Name) { Source = border });
border.SetBinding(Border.CornerRadiusProperty, binding);
}
else
{
BindingOperations.ClearBinding(border, FrameworkElement.MinWidthProperty);
BindingOperations.ClearBinding(border, FrameworkElement.MinHeightProperty);
BindingOperations.ClearBinding(border, Border.CornerRadiusProperty);
}
}
}
public static void SetCircular(DependencyObject element, bool value)
=> element.SetValue(CircularProperty, value);
public static bool GetCircular(DependencyObject element)
=> (bool) element.GetValue(CircularProperty);
}
}
@@ -12,6 +12,6 @@ namespace HandyControl.Controls
=> element.SetValue(HighlightBrushProperty, value);
public static Brush GetHighlightBrush(DependencyObject element)
=> (Brush) element.GetValue(HighlightBrushProperty);
=> (Brush) element.GetValue(HighlightBrushProperty);
}
}
@@ -0,0 +1,7 @@
namespace HandyControl.Controls
{
public interface IGravatarGenerator
{
object GetGravatar(string id);
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Windows.Controls;
namespace HandyControl.Controls
{
public class Badge : ContentControl
{
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Windows.Controls;
namespace HandyControl.Controls
{
public class Dialog : ContentControl
{
}
}
+51
View File
@@ -0,0 +1,51 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Tools;
namespace HandyControl.Controls
{
public class Gravatar : ContentControl
{
public static readonly DependencyProperty GeneratorProperty = DependencyProperty.Register(
"Generator", typeof(IGravatarGenerator), typeof(Gravatar), new PropertyMetadata(new GithubGravatarGenerator()));
public IGravatarGenerator Generator
{
get => (IGravatarGenerator) GetValue(GeneratorProperty);
set => SetValue(GeneratorProperty, value);
}
public static readonly DependencyProperty IdProperty = DependencyProperty.Register(
"Id", typeof(string), typeof(Gravatar), new PropertyMetadata(default(string), OnIdChanged));
private static void OnIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar) d;
if (ctl.Source != null) return;
ctl.Content = ctl.Generator.GetGravatar((string)e.NewValue);
}
public string Id
{
get => (string) GetValue(IdProperty);
set => SetValue(IdProperty, value);
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source", typeof(ImageSource), typeof(Gravatar), new PropertyMetadata(default(ImageSource), OnSourceChanged));
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Gravatar)d;
ctl.Background = new ImageBrush((ImageSource)e.NewValue);
}
public ImageSource Source
{
get => (ImageSource) GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
}
}
+15
View File
@@ -86,6 +86,7 @@
<Compile Include="Controls\Attach\PanelElement.cs" />
<Compile Include="Controls\Attach\VisualElement.cs" />
<Compile Include="Controls\Base\HeaderedSelectableItem.cs" />
<Compile Include="Controls\Base\IGravatarGenerator.cs" />
<Compile Include="Controls\Base\ISelectable.cs" />
<Compile Include="Controls\Base\RegularItemsControl.cs" />
<Compile Include="Controls\Base\SelectableItem.cs" />
@@ -108,10 +109,13 @@
<Compile Include="Controls\Attach\TitleElement.cs" />
<Compile Include="Controls\Button\ContextMenuButton.cs" />
<Compile Include="Controls\Button\ContextMenuToggleButton.cs" />
<Compile Include="Controls\Other\Badge.cs" />
<Compile Include="Controls\Other\Carousel.cs" />
<Compile Include="Controls\Cover\CoverView\CoverView.cs" />
<Compile Include="Controls\Other\ChatBubble.cs" />
<Compile Include="Controls\Other\Dialog.cs" />
<Compile Include="Controls\Other\GotoTop.cs" />
<Compile Include="Controls\Other\Gravatar.cs" />
<Compile Include="Controls\Transfer\Transfer.cs" />
<Compile Include="Controls\Transfer\TransferGroup.cs" />
<Compile Include="Controls\Transfer\TransferItem.cs" />
@@ -174,8 +178,11 @@
<Compile Include="Data\ResourceToken.cs" />
<Compile Include="Data\SystemVersionInfo.cs" />
<Compile Include="Tools\Converter\Boolean2StrConverter.cs" />
<Compile Include="Tools\Converter\BorderClipConverter.cs" />
<Compile Include="Tools\Converter\BorderCircularConverter.cs" />
<Compile Include="Tools\Converter\Int2StrConverter.cs" />
<Compile Include="Tools\Extension\EnumerableExtension.cs" />
<Compile Include="Tools\GithubGravatarGenerator.cs" />
<Compile Include="Tools\Helper\ColorHelper.cs" />
<Compile Include="Tools\GifImageAnimator.cs" />
<Compile Include="Data\GrowlInfo.cs" />
@@ -384,6 +391,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles\Base\GravatarBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles\Base\ProgressButtonBaseStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -436,6 +447,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles\Gravatar.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles\GroupBox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
+61 -80
View File
@@ -1,95 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
@@ -108,13 +89,13 @@
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Confirm" xml:space="preserve">
<value>Confirm</value>
@@ -15,5 +15,7 @@
<converter:Object2BooleanConverter x:Key="Object2BooleanConverter"/>
<converter:Boolean2StrConverter x:Key="Boolean2StrConverter"/>
<converter:Int2StrConverter x:Key="Int2StrConverter"/>
<converter:BorderClipConverter x:Key="BorderClipConverter"/>
<converter:BorderCircularConverter x:Key="BorderCircularConverter"/>
</ResourceDictionary>
@@ -0,0 +1,22 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<Style x:Key="GravatarBaseStyle" TargetType="controls:Gravatar">
<Setter Property="Width" Value="72"/>
<Setter Property="Height" Value="72"/>
<Setter Property="Background" Value="{DynamicResource SecondaryRegionBrush}"/>
<Setter Property="controls:BorderElement.CornerRadius" Value="4"/>
<Setter Property="Padding" Value="6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Gravatar">
<Border ClipToBounds="True" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
+22 -1
View File
@@ -1,6 +1,11 @@
<ResourceDictionary 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:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Basic/Converters.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--用于包裹一个区域-->
<Style x:Key="BorderRegionStyle" TargetType="Border">
<Setter Property="Padding" Value="10"/>
@@ -21,4 +26,20 @@
<Setter Property="Background" Value="{DynamicResource ThirdlyTextBrush}"/>
</Style>
<Style x:Key="BorderCircular" TargetType="Border">
<Setter Property="controls:BorderElement.Circular" Value="True"/>
</Style>
<Style x:Key="BorderClip" BasedOn="{StaticResource BorderCircular}" TargetType="Border">
<Setter Property="Clip">
<Setter.Value>
<MultiBinding Converter="{StaticResource BorderClipConverter}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
<Binding Path="CornerRadius" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
+29
View File
@@ -0,0 +1,29 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Base/GravatarBaseStyle.xaml"/>
<ResourceDictionary Source="Border.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource GravatarBaseStyle}" TargetType="controls:Gravatar"/>
<Style x:Key="GravatarCircle" BasedOn="{StaticResource GravatarBaseStyle}" TargetType="controls:Gravatar">
<Setter Property="Padding" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Gravatar">
<Border Style="{StaticResource BorderClip}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GravatarCircleImg" BasedOn="{StaticResource GravatarCircle}" TargetType="controls:Gravatar">
<Setter Property="Padding" Value="0"/>
</Style>
</ResourceDictionary>
+1
View File
@@ -58,6 +58,7 @@
<ResourceDictionary Source="Transfer.xaml"/>
<ResourceDictionary Source="ChatBubble.xaml"/>
<ResourceDictionary Source="GotoTop.xaml"/>
<ResourceDictionary Source="Gravatar.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -0,0 +1,31 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace HandyControl.Tools.Converter
{
public class BorderCircularConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length == 2 && values[0] is double width && values[1] is double height)
{
if (width < double.Epsilon || height < double.Epsilon)
{
return new CornerRadius();
}
var min = Math.Min(width, height);
return new CornerRadius(min/2);
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
@@ -0,0 +1,36 @@
//referenced from https://stackoverflow.com/a/5650367/9639378
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
namespace HandyControl.Tools.Converter
{
public class BorderClipConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length == 3 && values[0] is double width && values[1] is double height && values[2] is CornerRadius radius)
{
if (width < double.Epsilon || height < double.Epsilon)
{
return Geometry.Empty;
}
var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft);
clip.Freeze();
return clip;
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
@@ -0,0 +1,119 @@
using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using HandyControl.Controls;
namespace HandyControl.Tools
{
public class GithubGravatarGenerator : IGravatarGenerator
{
private const int RenderDataMaxLength = 15;
public object GetGravatar(string id)
{
var hashcode = GetHashCode(id);
var renderData = GetRenderData(hashcode);
var renderBrush = GetRenderBrush(hashcode);
var geometryGroup = new GeometryGroup();
void AddRec(int i, int j, bool hidden = false)
{
var rec = new RectangleGeometry(new Rect(new Point(i, j), hidden ? new Size() : new Size(1, 1)));
geometryGroup.Children.Add(rec);
}
var index = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 5; j++, index++)
{
AddRec(i, j, renderData[index] == 0);
}
}
for (int j = 0; j < 5; j++, index++)
{
AddRec(2, j, renderData[index] == 0);
}
index -= 10;
for (int i = 3; i < 5; i++)
{
for (int j = 0; j < 5; j++, index++)
{
AddRec(i, j, renderData[index] == 0);
}
index -= 10;
}
var path = new Path
{
Data = geometryGroup,
Fill = renderBrush,
VerticalAlignment = VerticalAlignment.Top
};
RenderOptions.SetEdgeMode(path, EdgeMode.Aliased);
return path;
}
private string GetHashCode(string id)
{
var md5 = MD5.Create();
var bytes = Encoding.ASCII.GetBytes(id);
var hash = md5.ComputeHash(bytes);
var stringBuilder = new StringBuilder();
foreach (var item in hash)
{
stringBuilder.Append(item.ToString("X2"));
}
return stringBuilder.ToString();
}
private int[] GetRenderData(string hashcode)
{
var arr = new int[RenderDataMaxLength];
for (int i = 0; i < RenderDataMaxLength; i++)
{
var c = hashcode[i];
var v = (int) c;
arr[i] = v % 2;
}
return arr;
}
private Brush GetRenderBrush(string hashcode)
{
var v = (double)int.Parse(hashcode.Substring(hashcode.Length - 7), NumberStyles.HexNumber);
var scale = v / 0xfffffff;
var color = Hsl2Rgb(scale);
return new SolidColorBrush(color);
}
//adapted from https://github.com/stewartlord/identicon.js/blob/4fad7cafec1b7a4d896015e084e861625ef5d64f/identicon.js#L110
private Color Hsl2Rgb(double h, double s = 0.7, double b = 0.5)
{
h *= 6;
var arr = new[]
{
b += s *= b < .5 ? b : 1 - b,
b - h % 1 * s * 2,
b -= s *= 2,
b,
b + h % 1 * s,
b + s
};
var hValue = (int) Math.Floor(h);
return Color.FromRgb((byte) (arr[hValue % 6] * 255), (byte) (arr[(hValue | 16) % 6] * 255),
(byte) (arr[(hValue | 8) % 6] * 255));
}
}
}
+4
View File
@@ -84,6 +84,10 @@
public static readonly string GotoTopDemoCtl = nameof(GotoTopDemoCtl);
public static readonly string BadgeDemoCtl = nameof(BadgeDemoCtl);
public static readonly string GravatarDemoCtl = nameof(GravatarDemoCtl);
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
+3 -1
View File
@@ -44,7 +44,9 @@ var controlList = new List<string>
"ProgressButtonDemoCtl",
"TransferDemoCtl",
"ChatBubbleDemoCtl",
"GotoTopDemoCtl"
"GotoTopDemoCtl",
"BadgeDemoCtl",
"GravatarDemoCtl"
};
var styleList = new List<string>
{
+24
View File
@@ -133,6 +133,9 @@
<Compile Include="UserControl\Controls\AnimationPathDemoCtl.xaml.cs">
<DependentUpon>AnimationPathDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\BadgeDemoCtl.xaml.cs">
<DependentUpon>BadgeDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\CalendarWithClockDemoCtl.xaml.cs">
<DependentUpon>CalendarWithClockDemoCtl.xaml</DependentUpon>
</Compile>
@@ -178,6 +181,9 @@
<Compile Include="UserControl\Controls\GotoTopDemoCtl.xaml.cs">
<DependentUpon>GotoTopDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\GravatarDemoCtl.xaml.cs">
<DependentUpon>GravatarDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\OutlineTextDemoCtl.xaml.cs">
<DependentUpon>OutlineTextDemoCtl.xaml</DependentUpon>
</Compile>
@@ -247,6 +253,9 @@
<Compile Include="UserControl\Main\QQGroupView.xaml.cs">
<DependentUpon>QQGroupView.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Main\UnderConstruction.xaml.cs">
<DependentUpon>UnderConstruction.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Styles\BorderDemoCtl.xaml.cs">
<DependentUpon>BorderDemoCtl.xaml</DependentUpon>
</Compile>
@@ -435,6 +444,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\BadgeDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\CalendarWithClockDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -495,6 +508,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\GravatarDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\OutlineTextDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -587,6 +604,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Main\UnderConstruction.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Styles\BorderDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -753,6 +774,9 @@
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>MessageToken.cs</LastGenOutput>
</Content>
<Resource Include="Resources\Img\under_construction.gif" />
<Resource Include="Resources\Img\LeftMainContent\User_16x.png" />
<Resource Include="Resources\Img\LeftMainContent\DotLarge_16x.png" />
<Resource Include="Resources\Img\LeftMainContent\GoToTop_16x.png" />
<Resource Include="Resources\Img\LeftMainContent\Label_16x.png" />
<Resource Include="Resources\Img\Chat\chat_back1.jpg" />
+28 -1
View File
@@ -47,7 +47,7 @@ namespace HandyControlDemo.Properties.Langs {
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
@@ -87,6 +87,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 标记 的本地化字符串。
/// </summary>
public static string Badge {
get {
return ResourceManager.GetString("Badge", resourceCulture);
}
}
/// <summary>
/// 查找类似 填写基本信息 的本地化字符串。
/// </summary>
@@ -258,6 +267,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 敬请期待 的本地化字符串。
/// </summary>
public static string ComingSoon {
get {
return ResourceManager.GetString("ComingSoon", resourceCulture);
}
}
/// <summary>
/// 查找类似 一般 的本地化字符串。
/// </summary>
@@ -447,6 +465,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 头像 的本地化字符串。
/// </summary>
public static string Gravatar {
get {
return ResourceManager.GetString("Gravatar", resourceCulture);
}
}
/// <summary>
/// 查找类似 分组框 的本地化字符串。
/// </summary>
@@ -501,4 +501,13 @@
<data name="GotoTop" xml:space="preserve">
<value>GotoTop</value>
</data>
<data name="Badge" xml:space="preserve">
<value>Badge</value>
</data>
<data name="Gravatar" xml:space="preserve">
<value>Gravatar</value>
</data>
<data name="ComingSoon" xml:space="preserve">
<value>Coming Soon</value>
</data>
</root>
@@ -501,4 +501,13 @@
<data name="GotoTop" xml:space="preserve">
<value>回到顶部</value>
</data>
<data name="Badge" xml:space="preserve">
<value>标记</value>
</data>
<data name="Gravatar" xml:space="preserve">
<value>头像</value>
</data>
<data name="ComingSoon" xml:space="preserve">
<value>敬请期待</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 KiB

@@ -0,0 +1,6 @@
<UserControl x:Class="HandyControlDemo.UserControl.BadgeDemoCtl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:userControl="clr-namespace:HandyControlDemo.UserControl">
<userControl:UnderConstruction/>
</UserControl>
@@ -0,0 +1,10 @@
namespace HandyControlDemo.UserControl
{
public partial class BadgeDemoCtl
{
public BadgeDemoCtl()
{
InitializeComponent();
}
}
}
@@ -4,10 +4,10 @@
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
Background="{DynamicResource RegionBrush}">
<controls:TransitioningContentControl>
<controls:GifImage x:Name="GifImageMain" Margin="32" Width="400" Height="300">
<controls:GifImage.Source>
<controls:GifImage x:Name="GifImageMain" Margin="32" Width="400" Height="300">
<controls:GifImage.Source>
<BitmapImage UriSource="/HandyControlDemo;component/Resources/Img/car_chase.gif"/>
</controls:GifImage.Source>
</controls:GifImage>
</controls:GifImage.Source>
</controls:GifImage>
</controls:TransitioningContentControl>
</UserControl>
@@ -0,0 +1,27 @@
<UserControl x:Class="HandyControlDemo.UserControl.GravatarDemoCtl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
Background="{DynamicResource RegionBrush}">
<controls:TransitioningContentControl>
<StackPanel Margin="32" Orientation="Horizontal">
<UniformGrid Rows="3" Columns="3" Width="240" Height="240">
<controls:Gravatar Id="User1"/>
<controls:Gravatar Id="User2"/>
<controls:Gravatar Style="{StaticResource GravatarCircleImg}">
<Image Source="/HandyControlDemo;component/Resources/Img/Album/2.jpg"/>
</controls:Gravatar>
<controls:Gravatar Id="User4"/>
<controls:Gravatar Id="User5" Style="{StaticResource GravatarCircle}"/>
<controls:Gravatar Id="User6"/>
<controls:Gravatar Style="{StaticResource GravatarCircle}" Source="/HandyControlDemo;component/Resources/Img/Album/1.jpg"/>
<controls:Gravatar Id="User8"/>
<controls:Gravatar Id="User9"/>
</UniformGrid>
<StackPanel Margin="16,0,0,0" Height="220" VerticalAlignment="Center">
<TextBox Text="User1" Name="TextBoxName" Width="180"/>
<controls:Gravatar Height="180" Width="180" Id="{Binding Text,ElementName=TextBoxName}" Margin="10"/>
</StackPanel>
</StackPanel>
</controls:TransitioningContentControl>
</UserControl>
@@ -0,0 +1,10 @@
namespace HandyControlDemo.UserControl
{
public partial class GravatarDemoCtl
{
public GravatarDemoCtl()
{
InitializeComponent();
}
}
}
@@ -188,12 +188,22 @@
</controls:StatusSwitchElement.CheckedElement>
</ToggleButton>
<ListBox Name="ListBoxControl" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" BorderThickness="0" SelectionMode="Single" Style="{StaticResource ListBoxTransparent}">
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.GravatarDemoCtl}" Content="{x:Static langs:Lang.Gravatar}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/User_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.BadgeDemoCtl}" Content="{x:Static langs:Lang.Badge}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/DotLarge_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.GotoTopDemoCtl}" Content="{x:Static langs:Lang.GotoTop}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/GoToTop_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.ProgressButtonDemoCtl}" Content="{x:Static langs:Lang.ProgressButton}">
<ListBoxItem Tag="{x:Static data:MessageToken.ProgressButtonDemoCtl}" Content="{x:Static langs:Lang.ProgressButton}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/ProgressButton_16x.png"/>
</controls:EdgeElement.LeftContent>
@@ -303,7 +313,7 @@
<Image Source="../../Resources/Img/LeftMainContent/DetailDataView_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.CoverFlowDemoCtl}" Content="{x:Static langs:Lang.CoverFlow}">
<ListBoxItem Tag="{x:Static data:MessageToken.CoverFlowDemoCtl}" Content="{x:Static langs:Lang.CoverFlow}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/LinearCarousel_16x.png"/>
</controls:EdgeElement.LeftContent>
@@ -0,0 +1,17 @@
<UserControl x:Class="HandyControlDemo.UserControl.UnderConstruction"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
Background="{DynamicResource RegionBrush}">
<controls:TransitioningContentControl>
<StackPanel Margin="32">
<controls:GifImage Width="400" Height="300">
<controls:GifImage.Source>
<BitmapImage UriSource="/HandyControlDemo;component/Resources/Img/under_construction.gif"/>
</controls:GifImage.Source>
</controls:GifImage>
<TextBlock Margin="0,16,0,0" HorizontalAlignment="Center" Text="{x:Static langs:Lang.ComingSoon}" Style="{StaticResource TextBlockLargeBold}"/>
</StackPanel>
</controls:TransitioningContentControl>
</UserControl>
@@ -0,0 +1,10 @@
namespace HandyControlDemo.UserControl
{
public partial class UnderConstruction
{
public UnderConstruction()
{
InitializeComponent();
}
}
}
+6 -2
View File
@@ -39,6 +39,10 @@ Step 3:enjoy coding
## Latest examples
### Gravatar
![Gravatar](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Gravatar.gif)
### ChatBubble
![ChatBubble](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/ChatBubble.png)
@@ -51,6 +55,8 @@ Step 3:enjoy coding
![ProgressButton](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/ProgressButton.png)
## History publication
### CoverFlow
![CoverFlow](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/CoverFlow.gif)
@@ -59,8 +65,6 @@ Step 3:enjoy coding
![CoverView](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/CoverView.gif)
## History publication
### MessageBox
![MessageBox](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/MessageBox.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB