add OutlineText

This commit is contained in:
NaBian committed 2018-11-25 22:41:35 +08:00
1 parent bb024f5f0b
commit 979b3326a7
28 files changed
+324 -17

No files matched your search

File renamed without changes.
File renamed without changes.
File renamed without changes.
+236
View File
@@ -0,0 +1,236 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class OutlineText : FrameworkElement
{
private FormattedText _formattedText;
private Geometry _textGeometry;
static OutlineText()
{
SnapsToDevicePixelsProperty.OverrideMetadata(typeof(OutlineText), new FrameworkPropertyMetadata(ValueBoxes.TrueBox));
UseLayoutRoundingProperty.OverrideMetadata(typeof(OutlineText), new FrameworkPropertyMetadata(ValueBoxes.TrueBox));
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(OutlineText), new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsRender, OnFormattedTextInvalidated));
public string Text
{
get => (string) GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register(
"TextAlignment", typeof(TextAlignment), typeof(OutlineText),
new PropertyMetadata(default(TextAlignment), OnFormattedTextUpdated));
public TextAlignment TextAlignment
{
get => (TextAlignment) GetValue(TextAlignmentProperty);
set => SetValue(TextAlignmentProperty, value);
}
public static readonly DependencyProperty TextTrimmingProperty = DependencyProperty.Register(
"TextTrimming", typeof(TextTrimming), typeof(OutlineText),
new PropertyMetadata(default(TextTrimming), OnFormattedTextInvalidated));
public TextTrimming TextTrimming
{
get => (TextTrimming) GetValue(TextTrimmingProperty);
set => SetValue(TextTrimmingProperty, value);
}
public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register(
"TextWrapping", typeof(TextWrapping), typeof(OutlineText),
new PropertyMetadata(TextWrapping.NoWrap, OnFormattedTextInvalidated));
public TextWrapping TextWrapping
{
get => (TextWrapping) GetValue(TextWrappingProperty);
set => SetValue(TextWrappingProperty, value);
}
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
"Fill", typeof(Brush), typeof(OutlineText), new PropertyMetadata(Brushes.Black, OnFormattedTextUpdated));
public Brush Fill
{
get => (Brush) GetValue(FillProperty);
set => SetValue(FillProperty, value);
}
public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
"Stroke", typeof(Brush), typeof(OutlineText), new PropertyMetadata(Brushes.Black, OnFormattedTextUpdated));
public Brush Stroke
{
get => (Brush) GetValue(StrokeProperty);
set => SetValue(StrokeProperty, value);
}
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
"StrokeThickness", typeof(double), typeof(OutlineText), new PropertyMetadata(ValueBoxes.Double0Box, OnFormattedTextUpdated));
public double StrokeThickness
{
get => (double) GetValue(StrokeThicknessProperty);
set => SetValue(StrokeThicknessProperty, value);
}
public static readonly DependencyProperty FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(
typeof(OutlineText),
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
public FontFamily FontFamily
{
get => (FontFamily)GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
public static readonly DependencyProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
typeof(OutlineText),
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
[TypeConverter(typeof(FontSizeConverter))]
public double FontSize
{
get => (double)GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
public static readonly DependencyProperty FontStretchProperty = TextElement.FontStretchProperty.AddOwner(
typeof(OutlineText),
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
public FontStretch FontStretch
{
get => (FontStretch)GetValue(FontStretchProperty);
set => SetValue(FontStretchProperty, value);
}
public static readonly DependencyProperty FontStyleProperty = TextElement.FontStyleProperty.AddOwner(
typeof(OutlineText),
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
public FontStyle FontStyle
{
get => (FontStyle)GetValue(FontStyleProperty);
set => SetValue(FontStyleProperty, value);
}
public static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(
typeof(OutlineText),
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
public FontWeight FontWeight
{
get => (FontWeight)GetValue(FontWeightProperty);
set => SetValue(FontWeightProperty, value);
}
protected override void OnRender(DrawingContext drawingContext)
{
EnsureGeometry();
drawingContext.DrawGeometry(Fill, new Pen(Stroke, StrokeThickness), _textGeometry);
}
private void EnsureFormattedText()
{
if (_formattedText != null || Text == null)
{
return;
}
var source = PresentationSource.FromVisual(this);
var dpi = 1.0;
if (source?.CompositionTarget != null)
{
dpi = 96.0 * source.CompositionTarget.TransformToDevice.M11 / 96.0;
}
_formattedText = new FormattedText(
Text,
CultureInfo.CurrentUICulture,
FlowDirection,
new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
FontSize, Fill, dpi);
UpdateFormattedText();
}
private void EnsureGeometry()
{
if (_textGeometry != null)
{
return;
}
EnsureFormattedText();
_textGeometry = _formattedText.BuildGeometry(new Point(0, 0));
}
private void UpdateFormattedText()
{
if (_formattedText == null)
{
return;
}
_formattedText.MaxLineCount = TextWrapping == TextWrapping.NoWrap ? 1 : int.MaxValue;
_formattedText.TextAlignment = TextAlignment;
_formattedText.Trimming = TextTrimming;
_formattedText.SetFontSize(FontSize);
_formattedText.SetFontStyle(FontStyle);
_formattedText.SetFontWeight(FontWeight);
_formattedText.SetFontFamily(FontFamily);
_formattedText.SetFontStretch(FontStretch);
}
private static void OnFormattedTextUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var outlinedTextBlock = (OutlineText)d;
outlinedTextBlock.UpdateFormattedText();
outlinedTextBlock._textGeometry = null;
outlinedTextBlock.InvalidateMeasure();
outlinedTextBlock.InvalidateVisual();
}
private static void OnFormattedTextInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var outlinedTextBlock = (OutlineText)d;
outlinedTextBlock._formattedText = null;
outlinedTextBlock._textGeometry = null;
outlinedTextBlock.InvalidateMeasure();
outlinedTextBlock.InvalidateVisual();
}
protected override Size MeasureOverride(Size availableSize)
{
EnsureFormattedText();
// constrain the formatted text according to the available size
// the Math.Min call is important - without this constraint (which seems arbitrary, but is the maximum allowable text width), things blow up when availableSize is infinite in both directions
// the Math.Max call is to ensure we don't hit zero, which will cause MaxTextHeight to throw
_formattedText.MaxTextWidth = Math.Min(3579139, availableSize.Width);
_formattedText.MaxTextHeight = Math.Max(0.0001d, availableSize.Height);
// return the desired size
return new Size(_formattedText.Width, _formattedText.Height);
}
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Windows;
namespace HandyControl.Controls
{
public class StackText : FrameworkElement
{
}
}
+16 -14
View File
@@ -33,7 +33,7 @@
<DocumentationFile>bin\Release\HandyControl.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Controls\AnimationPath.cs" />
<Compile Include="Controls\Other\AnimationPath.cs" />
<Compile Include="Controls\Attach\BackgroundSwitchElement.cs" />
<Compile Include="Controls\Attach\BorderElement.cs" />
<Compile Include="Controls\Attach\DataGridAttach.cs" />
@@ -46,37 +46,39 @@
<Compile Include="Controls\Attach\TitleElement.cs" />
<Compile Include="Controls\Button\ContextMenuButton.cs" />
<Compile Include="Controls\Button\ContextMenuToggleButton.cs" />
<Compile Include="Controls\Carousel.cs" />
<Compile Include="Controls\CirclePanel.cs" />
<Compile Include="Controls\CircleProgressBar.cs" />
<Compile Include="Controls\GifImage.cs" />
<Compile Include="Controls\Other\Carousel.cs" />
<Compile Include="Controls\Other\CirclePanel.cs" />
<Compile Include="Controls\Other\CircleProgressBar.cs" />
<Compile Include="Controls\Text\OutlineText.cs" />
<Compile Include="Controls\Other\GifImage.cs" />
<Compile Include="Controls\Input\SearchBar.cs" />
<Compile Include="Controls\Text\StackText.cs" />
<Compile Include="Controls\Tag\TagPanel.cs" />
<Compile Include="Controls\Tag\Tag.cs" />
<Compile Include="Controls\Time\CalendarWithClock.cs" />
<Compile Include="Controls\Time\Clock\Clock.cs" />
<Compile Include="Controls\Time\Clock\ClockRadioButton.cs" />
<Compile Include="Controls\Growl.cs" />
<Compile Include="Controls\ImageViewer.cs" />
<Compile Include="Controls\Other\Growl.cs" />
<Compile Include="Controls\Other\ImageViewer.cs" />
<Compile Include="Controls\Input\ComboBox.cs" />
<Compile Include="Controls\Input\DatePicker.cs" />
<Compile Include="Controls\Input\DateTimePicker.cs" />
<Compile Include="Controls\Input\IDataInput.cs" />
<Compile Include="Controls\Input\PasswordBox.cs" />
<Compile Include="Controls\Input\TextBox.cs" />
<Compile Include="Controls\ISingleOpen.cs" />
<Compile Include="Controls\Other\ISingleOpen.cs" />
<Compile Include="Controls\Input\NumericUpDown.cs" />
<Compile Include="Controls\Pagination.cs" />
<Compile Include="Controls\Other\Pagination.cs" />
<Compile Include="Controls\Attach\IconElement.cs" />
<Compile Include="Controls\Slider\CompareSlider.cs" />
<Compile Include="Controls\ColorPicker.cs" />
<Compile Include="Controls\Other\ColorPicker.cs" />
<Compile Include="Controls\Slider\CompareTrack.cs" />
<Compile Include="Controls\Slider\PreviewSlider.cs" />
<Compile Include="Controls\ScrollViewer.cs" />
<Compile Include="Controls\Other\ScrollViewer.cs" />
<Compile Include="Controls\Loading\LoadingBase.cs" />
<Compile Include="Controls\Loading\LoadingCircle.cs" />
<Compile Include="Controls\Loading\LoadingLine.cs" />
<Compile Include="Controls\InternalCanvas.cs" />
<Compile Include="Controls\Other\InternalCanvas.cs" />
<Compile Include="Controls\StepBar\StepBar.cs" />
<Compile Include="Controls\StepBar\StepBarItem.cs" />
<Compile Include="Data\Args\CancelRoutedEventArgs.cs" />
@@ -140,8 +142,8 @@
<Compile Include="Controls\Time\TimeBar\SpeTextBlock.cs" />
<Compile Include="Controls\Input\TimePicker.cs" />
<Compile Include="Controls\Time\TimeBar\TimeBar.cs" />
<Compile Include="Controls\TransitioningContentControl.cs" />
<Compile Include="Controls\WatermarkTextBox.cs" />
<Compile Include="Controls\Other\TransitioningContentControl.cs" />
<Compile Include="Controls\Input\WatermarkTextBox.cs" />
<Compile Include="Controls\Window\ImageBrowser.cs" />
<Compile Include="Controls\Window\PopupWindow.cs" />
<Compile Include="Controls\Window\WindowBorderless.cs" />
+2
View File
@@ -56,6 +56,8 @@
public static readonly string GifImageDemoCtl = nameof(GifImageDemoCtl);
public static readonly string OutlineTextDemoCtl = nameof(OutlineTextDemoCtl);
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
+2 -1
View File
@@ -30,7 +30,8 @@ var controlList = new List<string>
"CalendarWithClockDemoCtl",
"SearchBarDemoCtl",
"TagDemoCtl",
"GifImageDemoCtl"
"GifImageDemoCtl",
"OutlineTextDemoCtl"
};
var styleList = new List<string>
{
+7
View File
@@ -129,6 +129,9 @@
<Compile Include="UserControl\Controls\DateTimePickerDemoCtl.xaml.cs">
<DependentUpon>DateTimePickerDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\OutlineTextDemoCtl.xaml.cs">
<DependentUpon>OutlineTextDemoCtl.xaml</DependentUpon>
</Compile>
<Compile Include="UserControl\Controls\GifImageDemoCtl.xaml.cs">
<DependentUpon>GifImageDemoCtl.xaml</DependentUpon>
</Compile>
@@ -386,6 +389,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\OutlineTextDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UserControl\Controls\GifImageDemoCtl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
+9
View File
@@ -627,6 +627,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 轮廓文本 的本地化字符串。
/// </summary>
public static string OutlineText {
get {
return ResourceManager.GetString("OutlineText", resourceCulture);
}
}
/// <summary>
/// 查找类似 页码条 的本地化字符串。
/// </summary>
@@ -432,4 +432,7 @@
<data name="GifImage" xml:space="preserve">
<value>GifImage</value>
</data>
<data name="OutlineText" xml:space="preserve">
<value>OutlineText</value>
</data>
</root>
@@ -412,4 +412,7 @@
<data name="GifImage" xml:space="preserve">
<value>Gif图片</value>
</data>
<data name="OutlineText" xml:space="preserve">
<value>轮廓文本</value>
</data>
</root>
@@ -0,0 +1,16 @@
<UserControl x:Class="HandyControlDemo.UserControl.OutlineTextDemoCtl"
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" Width="400">
<controls:OutlineText Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=20}"/>
<controls:OutlineText Margin="0,10,0,0" FontSize="30" Fill="{DynamicResource SuccessBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=8}"/>
<controls:OutlineText Margin="0,10,0,0" FontSize="30" FontStyle="Italic" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=8}"/>
<controls:OutlineText Margin="0,10,0,0" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" FontSize="50" StrokeThickness="2" Fill="{DynamicResource DangerBrush}" Stroke="{DynamicResource PrimaryBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=5}"/>
<controls:OutlineText Margin="0,10,0,0" FontSize="80" FontWeight="Bold" StrokeThickness="4" Fill="{DynamicResource PrimaryBrush}" Stroke="{DynamicResource DangerBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=2}"/>
</StackPanel>
</controls:TransitioningContentControl>
</UserControl>
@@ -0,0 +1,10 @@
namespace HandyControlDemo.UserControl
{
public partial class OutlineTextDemoCtl
{
public OutlineTextDemoCtl()
{
InitializeComponent();
}
}
}
@@ -204,6 +204,11 @@
<Image Source="../../Resources/Img/LeftMainContent/Animation_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.OutlineTextDemoCtl}" Content="{x:Static langs:Lang.OutlineText}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/TextBlock_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Tag="{x:Static data:MessageToken.CirclePanelDemoCtl}" Content="{x:Static langs:Lang.CirclePanel}">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/ColorWheel_16x.png"/>
+6 -2
View File
@@ -6,6 +6,10 @@
## Latest examples
### OutlineText
![OutlineText](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/OutlineText.png)
### Tag
![Tag](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Tag.png)
@@ -22,12 +26,12 @@
![CircleProgressBar](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/CircleProgressBar.png)
## History publication
### DataGrid
![DataGrid](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/DataGrid.png)
## History publication
### Now you can switch to dark theme
![dark theme](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/DarkTheme.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB