-
-
Notifications
You must be signed in to change notification settings - Fork 832
Fixed the markup extension for the SymbolIcon and FontIcon class not working at all. #1067
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
d33ecf3
Fixed the markup extension for the SymbolIcon and FontIcon class not …
m0lDaViA 5525c2b
Rewrite of the arc class. Added SweepDirection as property, viewbox t…
m0lDaViA a35eb01
Fixed the PenLineCap property.
m0lDaViA 4471cb9
Added back doc and removed regions.
m0lDaViA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,10 +3,13 @@ | |
// Copyright (C) Leszek Pomianowski and WPF UI Contributors. | ||
// All Rights Reserved. | ||
|
||
using System.Windows.Controls; | ||
using System.Windows.Shapes; | ||
using Point = System.Windows.Point; | ||
using Size = System.Windows.Size; | ||
// ReSharper disable CheckNamespace | ||
Check warning on line 10 in src/Wpf.Ui/Controls/Arc/Arc.cs
|
||
#pragma warning disable CS0108 | ||
|
||
// ReSharper disable once CheckNamespace | ||
namespace Wpf.Ui.Controls; | ||
|
||
/// <summary> | ||
|
@@ -22,8 +25,10 @@ | |
/// Visibility="Visible" /> | ||
/// </code> | ||
/// </example> | ||
public class Arc : System.Windows.Shapes.Shape | ||
public class Arc : Shape | ||
{ | ||
private Viewbox? _rootLayout; | ||
|
||
/// <summary>Identifies the <see cref="StartAngle"/> dependency property.</summary> | ||
public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register( | ||
nameof(StartAngle), | ||
|
@@ -40,6 +45,24 @@ | |
new PropertyMetadata(0.0d, PropertyChangedCallback) | ||
); | ||
|
||
/// <summary>Identifies the <see cref="SweepDirection"/> dependency property.</summary> | ||
public static readonly DependencyProperty SweepDirectionProperty = | ||
DependencyProperty.Register( | ||
nameof(SweepDirection), | ||
typeof(SweepDirection), | ||
typeof(Arc), | ||
new PropertyMetadata(SweepDirection.Clockwise, PropertyChangedCallback) | ||
); | ||
|
||
/// <summary>Identifies the <see cref="StrokeStartLineCap"/> dependency property.</summary> | ||
public static readonly DependencyProperty StrokeStartLineCapProperty = | ||
DependencyProperty.Register( | ||
nameof(StrokeStartLineCap), | ||
typeof(PenLineCap), | ||
typeof(Arc), | ||
new PropertyMetadata(PenLineCap.Round, PropertyChangedCallback) | ||
); | ||
|
||
/// <summary> | ||
/// Gets or sets the initial angle from which the arc will be drawn. | ||
/// </summary> | ||
|
@@ -59,58 +82,63 @@ | |
} | ||
|
||
/// <summary> | ||
/// Gets a value indicating whether one of the two larger arc sweeps is chosen; otherwise, if is <see langword="false"/>, one of the smaller arc sweeps is chosen. | ||
/// Gets or sets the direction to where the arc will be drawn. | ||
/// </summary> | ||
public bool IsLargeArc { get; internal set; } = false; | ||
public SweepDirection SweepDirection | ||
{ | ||
get => (SweepDirection)GetValue(SweepDirectionProperty); | ||
set => SetValue(SweepDirectionProperty, value); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override Geometry DefiningGeometry => GetDefiningGeometry(); | ||
public PenLineCap StrokeStartLineCap | ||
{ | ||
get { return (PenLineCap)GetValue(StrokeStartLineCapProperty); } | ||
set { SetValue(StrokeStartLineCapProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Initializes static members of the <see cref="Arc"/> class. | ||
/// Gets a value indicating whether one of the two larger arc sweeps is chosen; otherwise, if is <see langword="false"/>, one of the smaller arc sweeps is chosen. | ||
/// </summary> | ||
/// <remarks> | ||
/// Overrides default properties. | ||
/// </remarks> | ||
static Arc() | ||
public bool IsLargeArc { get; internal set; } = false; | ||
|
||
private void EnsureRootLayout() | ||
{ | ||
StrokeStartLineCapProperty.OverrideMetadata( | ||
typeof(Arc), | ||
new FrameworkPropertyMetadata(PenLineCap.Round) | ||
); | ||
if (_rootLayout != null) | ||
{ | ||
return; | ||
} | ||
|
||
StrokeEndLineCapProperty.OverrideMetadata( | ||
typeof(Arc), | ||
new FrameworkPropertyMetadata(PenLineCap.Round) | ||
); | ||
_rootLayout = new Viewbox { SnapsToDevicePixels = true }; | ||
AddVisualChild(_rootLayout); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override Geometry DefiningGeometry => DefinedGeometry(); | ||
|
||
/// <summary> | ||
/// Get the geometry that defines this shape. | ||
/// <para><see href="https://stackoverflow.com/a/36756365/13224348">Based on Mark Feldman implementation.</see></para> | ||
/// </summary> | ||
protected Geometry GetDefiningGeometry() | ||
protected Geometry DefinedGeometry() | ||
{ | ||
var geometryStream = new StreamGeometry(); | ||
var arcSize = new Size( | ||
Math.Max(0, (RenderSize.Width - StrokeThickness) / 2), | ||
Math.Max(0, (RenderSize.Height - StrokeThickness) / 2) | ||
); | ||
|
||
using (StreamGeometryContext context = geometryStream.Open()) | ||
{ | ||
context.BeginFigure(PointAtAngle(Math.Min(StartAngle, EndAngle)), false, false); | ||
|
||
context.ArcTo( | ||
PointAtAngle(Math.Max(StartAngle, EndAngle)), | ||
arcSize, | ||
0, | ||
IsLargeArc, | ||
SweepDirection.Counterclockwise, | ||
true, | ||
false | ||
); | ||
} | ||
using StreamGeometryContext context = geometryStream.Open(); | ||
context.BeginFigure(PointAtAngle(Math.Min(StartAngle, EndAngle)), false, false); | ||
|
||
context.ArcTo( | ||
PointAtAngle(Math.Max(StartAngle, EndAngle)), | ||
arcSize, | ||
0, | ||
IsLargeArc, | ||
SweepDirection, | ||
true, | ||
false | ||
); | ||
|
||
geometryStream.Transform = new TranslateTransform(StrokeThickness / 2, StrokeThickness / 2); | ||
|
||
|
@@ -124,11 +152,36 @@ | |
/// <param name="angle">The angle at which to create the point.</param> | ||
protected Point PointAtAngle(double angle) | ||
{ | ||
var radAngle = angle * (Math.PI / 180); | ||
var xRadius = (RenderSize.Width - StrokeThickness) / 2; | ||
var yRadius = (RenderSize.Height - StrokeThickness) / 2; | ||
|
||
return new Point(xRadius + (xRadius * Math.Cos(radAngle)), yRadius - (yRadius * Math.Sin(radAngle))); | ||
if (SweepDirection == SweepDirection.Counterclockwise) | ||
{ | ||
angle += 90; | ||
angle %= 360; | ||
if (angle < 0) | ||
{ | ||
angle += 360; | ||
} | ||
|
||
var radAngle = angle * (Math.PI / 180); | ||
var xRadius = (RenderSize.Width - StrokeThickness) / 2; | ||
var yRadius = (RenderSize.Height - StrokeThickness) / 2; | ||
|
||
return new Point(xRadius + (xRadius * Math.Cos(radAngle)), yRadius - (yRadius * Math.Sin(radAngle))); | ||
} | ||
else | ||
{ | ||
angle -= 90; | ||
angle %= 360; | ||
if (angle < 0) | ||
{ | ||
angle += 360; | ||
} | ||
|
||
var radAngle = angle * (Math.PI / 180); | ||
var xRadius = (RenderSize.Width - StrokeThickness) / 2; | ||
var yRadius = (RenderSize.Height - StrokeThickness) / 2; | ||
|
||
return new Point(xRadius + (xRadius * Math.Cos(-radAngle)), yRadius - (yRadius * Math.Sin(-radAngle))); | ||
} | ||
} | ||
|
||
/// <summary> | ||
|
@@ -142,8 +195,48 @@ | |
} | ||
|
||
control.IsLargeArc = Math.Abs(control.EndAngle - control.StartAngle) > 180; | ||
|
||
// Force complete new layout pass | ||
control.InvalidateVisual(); | ||
} | ||
|
||
protected override Visual? GetVisualChild(int index) | ||
{ | ||
if (index != 0) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(index), "Arc should have only 1 child"); | ||
} | ||
|
||
EnsureRootLayout(); | ||
|
||
return _rootLayout; | ||
} | ||
|
||
protected override Size MeasureOverride(Size availableSize) | ||
{ | ||
EnsureRootLayout(); | ||
|
||
_rootLayout!.Measure(availableSize); | ||
return _rootLayout.DesiredSize; | ||
} | ||
|
||
protected override Size ArrangeOverride(Size finalSize) | ||
{ | ||
EnsureRootLayout(); | ||
|
||
_rootLayout!.Arrange(new Rect(default, finalSize)); | ||
return finalSize; | ||
} | ||
|
||
/// <summary>Overrides the default OnRender method to draw the <see cref="Arc" /> element.</summary> | ||
/// <param name="drawingContext">A <see cref="DrawingContext" /> object that is drawn during the rendering pass of this <see cref="System.Windows.Shapes.Shape" />.</param> | ||
protected override void OnRender(DrawingContext drawingContext) | ||
{ | ||
base.OnRender(drawingContext); | ||
Pen pen = new(Stroke, StrokeThickness) | ||
{ | ||
StartLineCap = StrokeStartLineCap, | ||
EndLineCap = StrokeStartLineCap | ||
}; | ||
|
||
drawingContext.DrawGeometry(Stroke, pen, DefinedGeometry()); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,12 @@ | |
[ContentProperty(nameof(Symbol))] | ||
[MarkupExtensionReturnType(typeof(SymbolIcon))] | ||
public class SymbolIconExtension : MarkupExtension | ||
{ | ||
Check warning on line 34 in src/Wpf.Ui/Markup/SymbolIconExtension.cs
|
||
|
||
public SymbolIconExtension() | ||
{ | ||
} | ||
|
||
public SymbolIconExtension(SymbolRegular symbol) | ||
{ | ||
Symbol = symbol; | ||
|
@@ -58,7 +63,12 @@ | |
|
||
public override object ProvideValue(IServiceProvider serviceProvider) | ||
{ | ||
var symbolIcon = new SymbolIcon { Symbol = Symbol, Filled = Filled }; | ||
if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget { TargetObject: Setter }) | ||
{ | ||
return this; | ||
} | ||
|
||
SymbolIcon symbolIcon = new() { Symbol = Symbol, Filled = Filled }; | ||
|
||
if (FontSize > 0) | ||
{ | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why removing docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well i removed them for a better overview and just forgot to add them back.