diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs
index b0eaf2f..17714e1 100644
--- a/demo/Ursa.Demo/Models/MenuKeys.cs
+++ b/demo/Ursa.Demo/Models/MenuKeys.cs
@@ -21,5 +21,6 @@ public static class MenuKeys
public const string MenuKeyRangeSlider = "RangeSlider";
public const string MenuKeyTagInput = "TagInput";
public const string MenuKeyTimeline = "Timeline";
+ public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml
index 3026968..4081616 100644
--- a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml
+++ b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml
@@ -18,7 +18,10 @@
ItemsSource="{Binding Items}" >
-
+
+
+
+
diff --git a/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml
new file mode 100644
index 0000000..ae22c4b
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs
new file mode 100644
index 0000000..72e0a25
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Ursa.Demo.Pages;
+
+public partial class TwoTonePathIconDemo : UserControl
+{
+ public TwoTonePathIconDemo()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
index 8ebf182..be51f3b 100644
--- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
@@ -43,6 +43,7 @@ public class MainViewViewModel : ViewModelBase
MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(),
MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
+ MenuKeys.MenuKeyTwoTonePathIcon => new TwoTonePathIconDemoViewModel(),
};
}
}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
index 95ac6f9..fa35634 100644
--- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
@@ -30,6 +30,7 @@ public class MenuViewModel: ViewModelBase
new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider, Status = "New"},
new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput },
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" },
+ new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon, Status = "New"},
};
}
}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs
new file mode 100644
index 0000000..d2112a1
--- /dev/null
+++ b/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs
@@ -0,0 +1,8 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace Ursa.Demo.ViewModels;
+
+public class TwoTonePathIconDemoViewModel:ObservableObject
+{
+
+}
\ No newline at end of file
diff --git a/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml b/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml
new file mode 100644
index 0000000..1fe4731
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
index 9f871de..fc8eba7 100644
--- a/src/Ursa.Themes.Semi/Controls/_index.axaml
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -19,5 +19,6 @@
+
diff --git a/src/Ursa/Controls/Icons/TwoTonePathIcon.cs b/src/Ursa/Controls/Icons/TwoTonePathIcon.cs
new file mode 100644
index 0000000..d44ad7c
--- /dev/null
+++ b/src/Ursa/Controls/Icons/TwoTonePathIcon.cs
@@ -0,0 +1,92 @@
+using System.ComponentModel;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
+using Avalonia.Data;
+using Avalonia.Media;
+
+namespace Ursa.Controls;
+
+[PseudoClasses(PC_Active)]
+public class TwoTonePathIcon: TemplatedControl
+{
+ public const string PC_Active = ":active";
+
+ public static readonly StyledProperty StrokeBrushProperty = AvaloniaProperty.Register(
+ nameof(StrokeBrush));
+
+ public IBrush? StrokeBrush
+ {
+ get => GetValue(StrokeBrushProperty);
+ set => SetValue(StrokeBrushProperty, value);
+ }
+
+ public static readonly StyledProperty DataProperty = AvaloniaProperty.Register(
+ nameof(Data));
+
+ public Geometry Data
+ {
+ get => GetValue(DataProperty);
+ set => SetValue(DataProperty, value);
+ }
+
+ public static readonly StyledProperty IsActiveProperty = AvaloniaProperty.Register(
+ nameof(IsActive), defaultBindingMode: BindingMode.TwoWay);
+
+ public bool IsActive
+ {
+ get => GetValue(IsActiveProperty);
+ set => SetValue(IsActiveProperty, value);
+ }
+
+ public static readonly StyledProperty ActiveForegroundProperty = AvaloniaProperty.Register(
+ nameof(ActiveForeground));
+
+ public IBrush? ActiveForeground
+ {
+ get => GetValue(ActiveForegroundProperty);
+ set => SetValue(ActiveForegroundProperty, value);
+ }
+
+ public static readonly StyledProperty ActiveStrokeBrushProperty = AvaloniaProperty.Register(
+ nameof(ActiveStrokeBrush));
+
+ public IBrush? ActiveStrokeBrush
+ {
+ get => GetValue(ActiveStrokeBrushProperty);
+ set => SetValue(ActiveStrokeBrushProperty, value);
+ }
+
+ public static readonly StyledProperty StrokeThicknessProperty =
+ AvaloniaProperty.Register(
+ nameof(StrokeThickness));
+ public double StrokeThickness
+ {
+ get => GetValue(StrokeThicknessProperty);
+ set => SetValue(StrokeThicknessProperty, value);
+ }
+
+ static TwoTonePathIcon()
+ {
+ AffectsRender(
+ DataProperty,
+ StrokeBrushProperty,
+ ForegroundProperty,
+ ActiveForegroundProperty,
+ ActiveStrokeBrushProperty);
+ IsActiveProperty.Changed.AddClassHandler((o, e) => o.OnIsActiveChanged(e));
+ }
+
+ private void OnIsActiveChanged(AvaloniaPropertyChangedEventArgs args)
+ {
+ var newValue = args.NewValue.Value;
+ PseudoClasses.Set(PC_Active, newValue);
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+ PseudoClasses.Set(PC_Active, IsActive);
+ }
+}
\ No newline at end of file