Merge pull request #75 from irihitech/icon

Add TwoTone icon
This commit is contained in:
Dong Bin
2024-01-27 14:05:31 +08:00
committed by GitHub
10 changed files with 177 additions and 1 deletions

View File

@@ -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";
} }

View File

@@ -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>

View 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>

View 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();
}
}

View File

@@ -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(),
}; };
} }
} }

View File

@@ -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"},
}; };
} }
} }

View File

@@ -0,0 +1,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace Ursa.Demo.ViewModels;
public class TwoTonePathIconDemoViewModel:ObservableObject
{
}

View 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>

View File

@@ -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>

View 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);
}
}