@@ -21,5 +21,6 @@ public static class MenuKeys
|
|||||||
public const string MenuKeyRangeSlider = "RangeSlider";
|
public const string MenuKeyRangeSlider = "RangeSlider";
|
||||||
public const string MenuKeyTagInput = "TagInput";
|
public const string MenuKeyTagInput = "TagInput";
|
||||||
public const string MenuKeyTimeline = "Timeline";
|
public const string MenuKeyTimeline = "Timeline";
|
||||||
|
public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,10 @@
|
|||||||
ItemsSource="{Binding Items}" >
|
ItemsSource="{Binding Items}" >
|
||||||
<u:ButtonGroup.ItemTemplate>
|
<u:ButtonGroup.ItemTemplate>
|
||||||
<DataTemplate x:DataType="vm:ButtonItem">
|
<DataTemplate x:DataType="vm:ButtonItem">
|
||||||
<TextBlock Text="{Binding Name}" Foreground="{DynamicResource SemiGrey3}"></TextBlock>
|
<TextBlock>
|
||||||
|
<Run Text="🐼"></Run>
|
||||||
|
<Run Text="{Binding Name}"></Run>
|
||||||
|
</TextBlock>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</u:ButtonGroup.ItemTemplate>
|
</u:ButtonGroup.ItemTemplate>
|
||||||
</u:ButtonGroup>
|
</u:ButtonGroup>
|
||||||
|
|||||||
18
demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml
Normal file
18
demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Ursa.Demo.Pages.TwoTonePathIconDemo">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="Size"></TextBlock>
|
||||||
|
<Slider Name="width" Minimum="0" Maximum="100" Value="20" Width="300"></Slider>
|
||||||
|
<ToggleSwitch Name="active" Content="Active"></ToggleSwitch>
|
||||||
|
<u:TwoTonePathIcon
|
||||||
|
IsActive="{Binding ElementName=active, Path=IsChecked}"
|
||||||
|
Width="{Binding #width.Value}"
|
||||||
|
Height="{Binding #width.Value}"
|
||||||
|
Data="M12 3L2 12H5V20H19V12H22L12 3M13 18H11V16H13V18M13 14H11V8H13V14Z"/>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
13
demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs
Normal file
13
demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ public class MainViewViewModel : ViewModelBase
|
|||||||
MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(),
|
MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(),
|
||||||
MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
|
MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(),
|
||||||
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
|
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
|
||||||
|
MenuKeys.MenuKeyTwoTonePathIcon => new TwoTonePathIconDemoViewModel(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ public class MenuViewModel: ViewModelBase
|
|||||||
new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider, Status = "New"},
|
new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider, Status = "New"},
|
||||||
new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput },
|
new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput },
|
||||||
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" },
|
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" },
|
||||||
|
new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon, Status = "New"},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.ViewModels;
|
||||||
|
|
||||||
|
public class TwoTonePathIconDemoViewModel:ObservableObject
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
38
src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml
Normal file
38
src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:u="https://irihi.tech/ursa">
|
||||||
|
<!-- Add Resources Here -->
|
||||||
|
<ControlTheme x:Key="{x:Type u:TwoTonePathIcon}" TargetType="u:TwoTonePathIcon">
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="Height" Value="{DynamicResource IconElementThemeHeight}" />
|
||||||
|
<Setter Property="Width" Value="{DynamicResource IconElementThemeWidth}" />
|
||||||
|
<Setter Property="StrokeThickness" Value="0.4" />
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource SemiBlue2}" />
|
||||||
|
<Setter Property="StrokeBrush" Value="{DynamicResource SemiBlue6}" />
|
||||||
|
<Setter Property="ActiveForeground" Value="{DynamicResource SemiBlue6}" />
|
||||||
|
<Setter Property="ActiveStrokeBrush" Value="{DynamicResource SemiBlue6}" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate TargetType="u:TwoTonePathIcon">
|
||||||
|
<Border Background="{TemplateBinding Background}">
|
||||||
|
<Panel>
|
||||||
|
<Viewbox Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
|
||||||
|
<Path
|
||||||
|
Name="PART_Fill"
|
||||||
|
Data="{TemplateBinding Data}"
|
||||||
|
StrokeThickness="{TemplateBinding StrokeThickness}"
|
||||||
|
StrokeJoin="Round"
|
||||||
|
Fill="{TemplateBinding Foreground}"
|
||||||
|
Stroke="{TemplateBinding StrokeBrush}"
|
||||||
|
Stretch="Uniform" />
|
||||||
|
</Viewbox>
|
||||||
|
</Panel>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
<Style Selector="^:active /template/ Path#PART_Fill">
|
||||||
|
<Setter Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActiveForeground}" />
|
||||||
|
<Setter Property="Stroke" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActiveStrokeBrush}" />
|
||||||
|
</Style>
|
||||||
|
</ControlTheme>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -19,5 +19,6 @@
|
|||||||
<ResourceInclude Source="RangeSlider.axaml" />
|
<ResourceInclude Source="RangeSlider.axaml" />
|
||||||
<ResourceInclude Source="TagInput.axaml" />
|
<ResourceInclude Source="TagInput.axaml" />
|
||||||
<ResourceInclude Source="Timeline.axaml" />
|
<ResourceInclude Source="Timeline.axaml" />
|
||||||
|
<ResourceInclude Source="TwoTonePathIcon.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
92
src/Ursa/Controls/Icons/TwoTonePathIcon.cs
Normal file
92
src/Ursa/Controls/Icons/TwoTonePathIcon.cs
Normal file
@@ -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<IBrush?> StrokeBrushProperty = AvaloniaProperty.Register<TwoTonePathIcon, IBrush?>(
|
||||||
|
nameof(StrokeBrush));
|
||||||
|
|
||||||
|
public IBrush? StrokeBrush
|
||||||
|
{
|
||||||
|
get => GetValue(StrokeBrushProperty);
|
||||||
|
set => SetValue(StrokeBrushProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Geometry> DataProperty = AvaloniaProperty.Register<PathIcon, Geometry>(
|
||||||
|
nameof(Data));
|
||||||
|
|
||||||
|
public Geometry Data
|
||||||
|
{
|
||||||
|
get => GetValue(DataProperty);
|
||||||
|
set => SetValue(DataProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> IsActiveProperty = AvaloniaProperty.Register<TwoTonePathIcon, bool>(
|
||||||
|
nameof(IsActive), defaultBindingMode: BindingMode.TwoWay);
|
||||||
|
|
||||||
|
public bool IsActive
|
||||||
|
{
|
||||||
|
get => GetValue(IsActiveProperty);
|
||||||
|
set => SetValue(IsActiveProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush?> ActiveForegroundProperty = AvaloniaProperty.Register<TwoTonePathIcon, IBrush?>(
|
||||||
|
nameof(ActiveForeground));
|
||||||
|
|
||||||
|
public IBrush? ActiveForeground
|
||||||
|
{
|
||||||
|
get => GetValue(ActiveForegroundProperty);
|
||||||
|
set => SetValue(ActiveForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush?> ActiveStrokeBrushProperty = AvaloniaProperty.Register<TwoTonePathIcon, IBrush?>(
|
||||||
|
nameof(ActiveStrokeBrush));
|
||||||
|
|
||||||
|
public IBrush? ActiveStrokeBrush
|
||||||
|
{
|
||||||
|
get => GetValue(ActiveStrokeBrushProperty);
|
||||||
|
set => SetValue(ActiveStrokeBrushProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<double> StrokeThicknessProperty =
|
||||||
|
AvaloniaProperty.Register<TwoTonePathIcon, double>(
|
||||||
|
nameof(StrokeThickness));
|
||||||
|
public double StrokeThickness
|
||||||
|
{
|
||||||
|
get => GetValue(StrokeThicknessProperty);
|
||||||
|
set => SetValue(StrokeThicknessProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TwoTonePathIcon()
|
||||||
|
{
|
||||||
|
AffectsRender<TwoTonePathIcon>(
|
||||||
|
DataProperty,
|
||||||
|
StrokeBrushProperty,
|
||||||
|
ForegroundProperty,
|
||||||
|
ActiveForegroundProperty,
|
||||||
|
ActiveStrokeBrushProperty);
|
||||||
|
IsActiveProperty.Changed.AddClassHandler<TwoTonePathIcon, bool>((o, e) => o.OnIsActiveChanged(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnIsActiveChanged(AvaloniaPropertyChangedEventArgs<bool> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user