@@ -5,6 +5,6 @@
|
|||||||
xmlns:u-semi="https://irihi.tech/ursa/themes/semi">
|
xmlns:u-semi="https://irihi.tech/ursa/themes/semi">
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
|
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
|
||||||
<u-semi:SemiTheme Locale="zh-CN"/>
|
<u-semi:SemiTheme Locale="zh-CN" />
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
</Application>
|
</Application>
|
||||||
56
demo/Ursa.Demo/DataTemplates/ToolBarItemTemplateSelector.cs
Normal file
56
demo/Ursa.Demo/DataTemplates/ToolBarItemTemplateSelector.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
using Avalonia.Data;
|
||||||
|
using Ursa.Controls;
|
||||||
|
using Ursa.Demo.ViewModels;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.Converters;
|
||||||
|
|
||||||
|
public class ToolBarItemTemplateSelector: IDataTemplate
|
||||||
|
{
|
||||||
|
|
||||||
|
public static ToolBarItemTemplateSelector Instance { get; } = new();
|
||||||
|
public Control? Build(object? param)
|
||||||
|
{
|
||||||
|
if (param is null) return null;
|
||||||
|
if (param is ToolBarSeparatorViewModel sep)
|
||||||
|
{
|
||||||
|
return new ToolBarSeparator();
|
||||||
|
}
|
||||||
|
if (param is ToolBarButtonItemViewModel vm)
|
||||||
|
{
|
||||||
|
return new Button()
|
||||||
|
{
|
||||||
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
|
[!Button.CommandProperty] = new Binding() { Path = "Command" },
|
||||||
|
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (param is ToolBarCheckBoxItemViweModel cb)
|
||||||
|
{
|
||||||
|
return new CheckBox()
|
||||||
|
{
|
||||||
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
|
[!ToggleButton.IsCheckedProperty] = new Binding() { Path = "IsChecked" },
|
||||||
|
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (param is ToolBarComboBoxItemViewModel combo)
|
||||||
|
{
|
||||||
|
return new ComboBox()
|
||||||
|
{
|
||||||
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
|
[!SelectingItemsControl.SelectedItemProperty] = new Binding() { Path = "SelectedItem" },
|
||||||
|
[!ItemsControl.ItemsSourceProperty] = new Binding() { Path = "Items" },
|
||||||
|
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new Button() { Content = "Undefined Item" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Match(object? data)
|
||||||
|
{
|
||||||
|
return data is ToolBarItemViewModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,5 +31,6 @@ public static class MenuKeys
|
|||||||
public const string MenuKeyTimeline = "Timeline";
|
public const string MenuKeyTimeline = "Timeline";
|
||||||
public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
|
public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon";
|
||||||
public const string MenuKeyThemeToggler = "ThemeToggler";
|
public const string MenuKeyThemeToggler = "ThemeToggler";
|
||||||
|
public const string MenuKeyToolBar = "ToolBar";
|
||||||
|
|
||||||
}
|
}
|
||||||
136
demo/Ursa.Demo/Pages/ToolBarDemo.axaml
Normal file
136
demo/Ursa.Demo/Pages/ToolBarDemo.axaml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="Ursa.Demo.Pages.ToolBarDemo"
|
||||||
|
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:template="using:Ursa.Demo.Converters"
|
||||||
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
|
xmlns:vm="using:Ursa.Demo.ViewModels"
|
||||||
|
d:DesignHeight="450"
|
||||||
|
d:DesignWidth="800"
|
||||||
|
x:CompileBindings="True"
|
||||||
|
x:DataType="vm:ToolBarDemoViewModel"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<StreamGeometry x:Key="BoldGlyph">M13.5,15.5H10V12.5H13.5A1.5,1.5 0 0,1 15,14A1.5,1.5 0 0,1 13.5,15.5M10,6.5H13A1.5,1.5 0 0,1 14.5,8A1.5,1.5 0 0,1 13,9.5H10M15.6,10.79C16.57,10.11 17.25,9 17.25,8C17.25,5.74 15.5,4 13.25,4H7V18H14.04C16.14,18 17.75,16.3 17.75,14.21C17.75,12.69 16.89,11.39 15.6,10.79Z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="ItalicGlyph">M10,4V7H12.21L8.79,15H6V18H14V15H11.79L15.21,7H18V4H10Z</StreamGeometry>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid ColumnDefinitions="Auto, Auto, *" RowDefinitions="Auto, Auto, *">
|
||||||
|
<u:EnumSelector Name="Orientation" EnumType="Orientation" />
|
||||||
|
<u:ToolBar
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
Header="Hello World"
|
||||||
|
Orientation="{Binding #Orientation.Value}">
|
||||||
|
<Button u:ToolBar.OverflowMode="Never" Content="Button 1" />
|
||||||
|
<u:ToolBarSeparator />
|
||||||
|
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 2" />
|
||||||
|
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 3" />
|
||||||
|
<ToggleButton Content="Toggle" />
|
||||||
|
<u:ToolBar.Styles>
|
||||||
|
<Style Selector="u|ToolBar[Orientation=Vertical]">
|
||||||
|
<Setter Property="Grid.Row" Value="1" />
|
||||||
|
<Setter Property="Grid.Column" Value="1" />
|
||||||
|
<Setter Property="Grid.RowSpan" Value="2" />
|
||||||
|
<Setter Property="Grid.ColumnSpan" Value="1" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="u|ToolBar[Orientation=Horizontal]">
|
||||||
|
<Setter Property="Grid.Row" Value="1" />
|
||||||
|
<Setter Property="Grid.Column" Value="1" />
|
||||||
|
<Setter Property="Grid.RowSpan" Value="1" />
|
||||||
|
<Setter Property="Grid.ColumnSpan" Value="3" />
|
||||||
|
</Style>
|
||||||
|
</u:ToolBar.Styles>
|
||||||
|
</u:ToolBar>
|
||||||
|
<u:ToolBar
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
ItemsSource="{Binding Items}"
|
||||||
|
Orientation="{Binding #Orientation.Value}">
|
||||||
|
<u:ToolBar.ItemTemplate>
|
||||||
|
<template:ToolBarItemTemplateSelector />
|
||||||
|
</u:ToolBar.ItemTemplate>
|
||||||
|
<u:ToolBar.Styles>
|
||||||
|
<Style Selector="u|ToolBar[Orientation=Vertical]">
|
||||||
|
<Setter Property="Grid.Row" Value="1" />
|
||||||
|
<Setter Property="Grid.Column" Value="0" />
|
||||||
|
<Setter Property="Grid.RowSpan" Value="2" />
|
||||||
|
<Setter Property="Grid.ColumnSpan" Value="1" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="u|ToolBar[Orientation=Horizontal]">
|
||||||
|
<Setter Property="Grid.Row" Value="0" />
|
||||||
|
<Setter Property="Grid.Column" Value="1" />
|
||||||
|
<Setter Property="Grid.RowSpan" Value="1" />
|
||||||
|
<Setter Property="Grid.ColumnSpan" Value="3" />
|
||||||
|
</Style>
|
||||||
|
</u:ToolBar.Styles>
|
||||||
|
</u:ToolBar>
|
||||||
|
<Grid
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="2"
|
||||||
|
RowDefinitions="Auto, *">
|
||||||
|
<u:ToolBar Margin="16">
|
||||||
|
<ToggleButton Name="bold">
|
||||||
|
<PathIcon
|
||||||
|
Width="16"
|
||||||
|
Height="16"
|
||||||
|
Data="{DynamicResource BoldGlyph}" />
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton Name="italic">
|
||||||
|
<PathIcon
|
||||||
|
Width="16"
|
||||||
|
Height="16"
|
||||||
|
Data="{DynamicResource ItalicGlyph}" />
|
||||||
|
</ToggleButton>
|
||||||
|
<u:ToolBarSeparator />
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="8,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Font Size" />
|
||||||
|
<ComboBox
|
||||||
|
Name="size"
|
||||||
|
Width="90"
|
||||||
|
SelectedIndex="0">
|
||||||
|
<x:Double>8</x:Double>
|
||||||
|
<x:Double>16</x:Double>
|
||||||
|
<x:Double>32</x:Double>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<u:ToolBar.Styles>
|
||||||
|
<Style Selector="u|ToolBar[Orientation=Horizontal]">
|
||||||
|
<Setter Property="Grid.Row" Value="2" />
|
||||||
|
<Setter Property="Grid.Column" Value="1" />
|
||||||
|
<Setter Property="Grid.RowSpan" Value="1" />
|
||||||
|
<Setter Property="Grid.ColumnSpan" Value="3" />
|
||||||
|
</Style>
|
||||||
|
</u:ToolBar.Styles>
|
||||||
|
|
||||||
|
</u:ToolBar>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes.Bold="{Binding #bold.IsChecked}"
|
||||||
|
Classes.Italic="{Binding #italic.IsChecked}"
|
||||||
|
FontSize="{Binding #size.SelectedItem}"
|
||||||
|
Text="Hello Ursa Avalonia">
|
||||||
|
<TextBlock.Styles>
|
||||||
|
<Style Selector="TextBlock">
|
||||||
|
<Setter Property="FontWeight" Value="Regular" />
|
||||||
|
<Setter Property="FontSize" Value="8" />
|
||||||
|
<Setter Property="FontStyle" Value="Normal" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="TextBlock.Bold">
|
||||||
|
<Setter Property="FontWeight" Value="Bold" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="TextBlock.Italic">
|
||||||
|
<Setter Property="FontStyle" Value="Italic" />
|
||||||
|
</Style>
|
||||||
|
</TextBlock.Styles>
|
||||||
|
</TextBlock>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
13
demo/Ursa.Demo/Pages/ToolBarDemo.axaml.cs
Normal file
13
demo/Ursa.Demo/Pages/ToolBarDemo.axaml.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.Pages;
|
||||||
|
|
||||||
|
public partial class ToolBarDemo : UserControl
|
||||||
|
{
|
||||||
|
public ToolBarDemo()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,7 @@ public class MainViewViewModel : ViewModelBase
|
|||||||
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
|
MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(),
|
||||||
MenuKeys.MenuKeyTwoTonePathIcon => new TwoTonePathIconDemoViewModel(),
|
MenuKeys.MenuKeyTwoTonePathIcon => new TwoTonePathIconDemoViewModel(),
|
||||||
MenuKeys.MenuKeyThemeToggler => new ThemeTogglerDemoViewModel(),
|
MenuKeys.MenuKeyThemeToggler => new ThemeTogglerDemoViewModel(),
|
||||||
|
MenuKeys.MenuKeyToolBar => new ToolBarDemoViewModel(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,7 @@ public class MenuViewModel: ViewModelBase
|
|||||||
new() { MenuHeader = "Theme Toggler", Key = MenuKeys.MenuKeyThemeToggler },
|
new() { MenuHeader = "Theme Toggler", Key = MenuKeys.MenuKeyThemeToggler },
|
||||||
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" },
|
new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" },
|
||||||
new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon, Status = "New"},
|
new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon, Status = "New"},
|
||||||
|
new() { MenuHeader = "ToolBar", Key = MenuKeys.MenuKeyToolBar, Status = "New" }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
83
demo/Ursa.Demo/ViewModels/ToolBarDemoViewModel.cs
Normal file
83
demo/Ursa.Demo/ViewModels/ToolBarDemoViewModel.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Ursa.Controls;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.ViewModels;
|
||||||
|
|
||||||
|
public partial class ToolBarDemoViewModel: ObservableObject
|
||||||
|
{
|
||||||
|
public ObservableCollection<ToolBarItemViewModel> Items { get; set; }
|
||||||
|
public ToolBarDemoViewModel()
|
||||||
|
{
|
||||||
|
Items = new()
|
||||||
|
{
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "New", OverflowMode = OverflowMode.AsNeeded},
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Open" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save1" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save2" },
|
||||||
|
new ToolBarSeparatorViewModel(),
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save3" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save4" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save5" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save6" },
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save7" },
|
||||||
|
new ToolBarSeparatorViewModel(),
|
||||||
|
new ToolBarButtonItemViewModel() { Content = "Save8" },
|
||||||
|
new ToolBarCheckBoxItemViweModel() { Content = "Bold" },
|
||||||
|
new ToolBarCheckBoxItemViweModel() { Content = "Italic", OverflowMode = OverflowMode.Never},
|
||||||
|
new ToolBarComboBoxItemViewModel() { Content = "Font Size", Items = new (){ "10", "12", "14" } }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ToolBarItemViewModel: ObservableObject
|
||||||
|
{
|
||||||
|
public OverflowMode OverflowMode { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolBarButtonItemViewModel: ToolBarItemViewModel
|
||||||
|
{
|
||||||
|
public string Content { get; set; }
|
||||||
|
public ICommand Command { get; set; }
|
||||||
|
|
||||||
|
public ToolBarButtonItemViewModel()
|
||||||
|
{
|
||||||
|
Command = new AsyncRelayCommand(async () => { await MessageBox.ShowOverlayAsync(Content); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolBarCheckBoxItemViweModel: ToolBarItemViewModel
|
||||||
|
{
|
||||||
|
public string Content { get; set; }
|
||||||
|
public bool IsChecked { get; set; }
|
||||||
|
public ICommand Command { get; set; }
|
||||||
|
|
||||||
|
public ToolBarCheckBoxItemViweModel()
|
||||||
|
{
|
||||||
|
Command = new AsyncRelayCommand(async () => { await MessageBox.ShowOverlayAsync(Content); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolBarComboBoxItemViewModel: ToolBarItemViewModel
|
||||||
|
{
|
||||||
|
public string Content { get; set; }
|
||||||
|
public ObservableCollection<string> Items { get; set; }
|
||||||
|
|
||||||
|
private string _selectedItem;
|
||||||
|
public string SelectedItem
|
||||||
|
{
|
||||||
|
get => _selectedItem;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetProperty(ref _selectedItem, value);
|
||||||
|
MessageBox.ShowOverlayAsync(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolBarSeparatorViewModel: ToolBarItemViewModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
|
||||||
namespace Ursa.Demo.Views;
|
namespace Ursa.Demo.Views;
|
||||||
|
|
||||||
|
|||||||
137
src/Ursa.Themes.Semi/Controls/ToolBar.axaml
Normal file
137
src/Ursa.Themes.Semi/Controls/ToolBar.axaml
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<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="ToolBarExpandToggleButton" TargetType="ToggleButton">
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="PART_ContentPresenter"
|
||||||
|
Padding="{TemplateBinding Padding}"
|
||||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
|
RecognizesAccessKey="True"
|
||||||
|
TextElement.FontSize="{TemplateBinding FontSize}"
|
||||||
|
TextElement.FontWeight="{TemplateBinding FontWeight}"
|
||||||
|
UseLayoutRounding="False" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</ControlTheme>
|
||||||
|
<ControlTheme x:Key="{x:Type u:ToolBar}" TargetType="u:ToolBar">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
|
<Setter Property="ItemsPanel">
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<u:ToolBarPanel />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</Setter>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate TargetType="u:ToolBar">
|
||||||
|
<Border
|
||||||
|
Padding="2"
|
||||||
|
Margin="0"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||||
|
CornerRadius="4"
|
||||||
|
Theme="{DynamicResource CardBorder}">
|
||||||
|
<DockPanel LastChildFill="True">
|
||||||
|
<ContentPresenter
|
||||||
|
Name="PART_Header"
|
||||||
|
Margin="8,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content="{TemplateBinding Header}"
|
||||||
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
|
DockPanel.Dock="Left"
|
||||||
|
Foreground="{DynamicResource SemiColorText2}"
|
||||||
|
IsVisible="{TemplateBinding Header,
|
||||||
|
Converter={x:Static ObjectConverters.IsNotNull}}" />
|
||||||
|
<Panel Name="PART_PopupButtonPanel" DockPanel.Dock="Right">
|
||||||
|
<ToggleButton
|
||||||
|
Name="button"
|
||||||
|
Padding="8,0"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
IsVisible="False"
|
||||||
|
Theme="{DynamicResource ToolBarExpandToggleButton}">
|
||||||
|
<PathIcon
|
||||||
|
Name="PART_Icon"
|
||||||
|
Height="12"
|
||||||
|
Foreground="{DynamicResource SemiColorText2}"
|
||||||
|
Data="{DynamicResource ToolBarHorizontalMoreGlyph}" />
|
||||||
|
</ToggleButton>
|
||||||
|
<Popup
|
||||||
|
IsLightDismissEnabled="True"
|
||||||
|
IsOpen="{Binding #button.IsChecked, Mode=TwoWay}"
|
||||||
|
Placement="{TemplateBinding PopupPlacement}"
|
||||||
|
PlacementTarget="{Binding #button}">
|
||||||
|
<Border Padding="2" Theme="{DynamicResource CardBorder}">
|
||||||
|
<StackPanel Name="{x:Static u:ToolBar.PART_OverflowPanel}" />
|
||||||
|
</Border>
|
||||||
|
</Popup>
|
||||||
|
</Panel>
|
||||||
|
<ItemsPresenter
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ItemsPanel="{TemplateBinding ItemsPanel}" />
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
<Style Selector="^[Orientation=Horizontal]">
|
||||||
|
<Setter Property="PopupPlacement" Value="BottomEdgeAlignedLeft" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^[Orientation=Vertical]">
|
||||||
|
<Setter Property="PopupPlacement" Value="RightEdgeAlignedTop" />
|
||||||
|
<Style Selector="^ /template/ ContentPresenter#PART_Header">
|
||||||
|
<Setter Property="DockPanel.Dock" Value="Top" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top" />
|
||||||
|
<Setter Property="Margin" Value="0 8" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^ /template/ Panel#PART_PopupButtonPanel">
|
||||||
|
<Setter Property="DockPanel.Dock" Value="Bottom" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^ /template/ ToggleButton#button">
|
||||||
|
<Setter Property="Padding" Value="0 8" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^ /template/ PathIcon#PART_Icon">
|
||||||
|
<Setter Property="Data" Value="{DynamicResource ToolBarVerticalMoreGlyph}" />
|
||||||
|
<Setter Property="Width" Value="12" />
|
||||||
|
<Setter Property="Height" Value="{x:Static x:Double.NaN}" />
|
||||||
|
</Style>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^:overflow /template/ ToggleButton#button">
|
||||||
|
<Setter Property="IsVisible" Value="True" />
|
||||||
|
</Style>
|
||||||
|
</ControlTheme>
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type u:ToolBarSeparator}" TargetType="u:ToolBarSeparator">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<Rectangle
|
||||||
|
Name="PART_Rect"
|
||||||
|
Margin="4"
|
||||||
|
Fill="{DynamicResource SemiColorBorder}" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
<Style Selector="^ /template/ Rectangle#PART_Rect">
|
||||||
|
<Setter Property="Width" Value="1" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="^:vertical /template/ Rectangle#PART_Rect">
|
||||||
|
<Setter Property="Height" Value="1" />
|
||||||
|
<Setter Property="Width" Value="{x:Static x:Double.NaN}" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
</ControlTheme>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -30,5 +30,6 @@
|
|||||||
<ResourceInclude Source="ThemeSelector.axaml" />
|
<ResourceInclude Source="ThemeSelector.axaml" />
|
||||||
<ResourceInclude Source="Timeline.axaml" />
|
<ResourceInclude Source="Timeline.axaml" />
|
||||||
<ResourceInclude Source="TwoTonePathIcon.axaml" />
|
<ResourceInclude Source="TwoTonePathIcon.axaml" />
|
||||||
|
<ResourceInclude Source="ToolBar.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
26
src/Ursa.Themes.Semi/Styles/ToolBar.axaml
Normal file
26
src/Ursa.Themes.Semi/Styles/ToolBar.axaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<Styles xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:u="https://irihi.tech/ursa">
|
||||||
|
<Design.PreviewWith>
|
||||||
|
<Border Padding="20">
|
||||||
|
<!-- Add Controls for Previewer Here -->
|
||||||
|
</Border>
|
||||||
|
</Design.PreviewWith>
|
||||||
|
<Style Selector="u|ToolBar Button">
|
||||||
|
<Setter Property="Theme" Value="{DynamicResource BorderlessButton}"></Setter>
|
||||||
|
<Setter Property="FontWeight" Value="Regular" />
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource SemiColorText0}"></Setter>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="u|ToolBar CheckBox">
|
||||||
|
<Setter Property="Margin" Value="8 0" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="u|ToolBar ToggleButton">
|
||||||
|
<Setter Property="FontWeight" Value="Regular" />
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource SemiColorText0}"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="u|ToolBar ComboBox">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||||
|
</Style>
|
||||||
|
<!-- Add Styles Here -->
|
||||||
|
</Styles>
|
||||||
@@ -5,5 +5,6 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
<StyleInclude Source="ButtonGroup.axaml" />
|
<StyleInclude Source="ButtonGroup.axaml" />
|
||||||
|
<StyleInclude Source="ToolBar.axaml"/>
|
||||||
<!-- Add Styles Here -->
|
<!-- Add Styles Here -->
|
||||||
</Styles>
|
</Styles>
|
||||||
|
|||||||
6
src/Ursa.Themes.Semi/Themes/Shared/ToolBar.axaml
Normal file
6
src/Ursa.Themes.Semi/Themes/Shared/ToolBar.axaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<!-- Add Resources Here -->
|
||||||
|
<StreamGeometry x:Key="ToolBarHorizontalMoreGlyph">M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="ToolBarVerticalMoreGlyph">M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z</StreamGeometry>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -15,5 +15,6 @@
|
|||||||
<MergeResourceInclude Source="Pagination.axaml" />
|
<MergeResourceInclude Source="Pagination.axaml" />
|
||||||
<MergeResourceInclude Source="TagInput.axaml" />
|
<MergeResourceInclude Source="TagInput.axaml" />
|
||||||
<MergeResourceInclude Source="ThemeSelector.axaml" />
|
<MergeResourceInclude Source="ThemeSelector.axaml" />
|
||||||
|
<MergeResourceInclude Source="ToolBar.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
8
src/Ursa/Controls/ToolBar/OverflowMode.cs
Normal file
8
src/Ursa/Controls/ToolBar/OverflowMode.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
public enum OverflowMode
|
||||||
|
{
|
||||||
|
AsNeeded,
|
||||||
|
Always,
|
||||||
|
Never
|
||||||
|
}
|
||||||
101
src/Ursa/Controls/ToolBar/ToolBar.cs
Normal file
101
src/Ursa/Controls/ToolBar/ToolBar.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Metadata;
|
||||||
|
using Avalonia.Controls.Presenters;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
using Avalonia.Layout;
|
||||||
|
using Avalonia.Markup.Xaml.Templates;
|
||||||
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
|
|
||||||
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
[PseudoClasses(PC_Overflow)]
|
||||||
|
[TemplatePart(PART_OverflowPanel, typeof(Panel))]
|
||||||
|
public class ToolBar: HeaderedItemsControl
|
||||||
|
{
|
||||||
|
public const string PART_OverflowPanel = "PART_OverflowPanel";
|
||||||
|
public const string PC_Overflow = ":overflow";
|
||||||
|
|
||||||
|
internal Panel? OverflowPanel { get; private set; }
|
||||||
|
|
||||||
|
private static readonly ITemplate<Panel?> DefaultTemplate =
|
||||||
|
new FuncTemplate<Panel?>(() => new ToolBarPanel() { Orientation = Orientation.Horizontal });
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Orientation> OrientationProperty =
|
||||||
|
StackPanel.OrientationProperty.AddOwner<ToolBar>();
|
||||||
|
|
||||||
|
public Orientation Orientation
|
||||||
|
{
|
||||||
|
get => GetValue(OrientationProperty);
|
||||||
|
set => SetValue(OrientationProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<PlacementMode> PopupPlacementProperty =
|
||||||
|
Popup.PlacementProperty.AddOwner<ToolBar>();
|
||||||
|
|
||||||
|
public PlacementMode PopupPlacement
|
||||||
|
{
|
||||||
|
get => GetValue(PopupPlacementProperty);
|
||||||
|
set => SetValue(PopupPlacementProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly AttachedProperty<OverflowMode> OverflowModeProperty =
|
||||||
|
AvaloniaProperty.RegisterAttached<ToolBar, Control, OverflowMode>("OverflowMode");
|
||||||
|
|
||||||
|
public static void SetOverflowMode(Control obj, OverflowMode value) => obj.SetValue(OverflowModeProperty, value);
|
||||||
|
public static OverflowMode GetOverflowMode(Control obj) => obj.GetValue(OverflowModeProperty);
|
||||||
|
|
||||||
|
internal static readonly AttachedProperty<bool> IsOverflowItemProperty =
|
||||||
|
AvaloniaProperty.RegisterAttached<ToolBar, Control, bool>("IsOverflowItem");
|
||||||
|
|
||||||
|
internal static void SetIsOverflowItem(Control obj, bool value) => obj.SetValue(IsOverflowItemProperty, value);
|
||||||
|
internal static bool GetIsOverflowItem(Control obj) => obj.GetValue(IsOverflowItemProperty);
|
||||||
|
|
||||||
|
private bool _hasOverflowItems;
|
||||||
|
internal bool HasOverflowItems
|
||||||
|
{
|
||||||
|
get => _hasOverflowItems;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_hasOverflowItems = value;
|
||||||
|
PseudoClasses.Set(PC_Overflow, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ToolBar()
|
||||||
|
{
|
||||||
|
IsTabStopProperty.OverrideDefaultValue<ToolBar>(false);
|
||||||
|
ItemsPanelProperty.OverrideDefaultValue<ToolBar>(DefaultTemplate);
|
||||||
|
OrientationProperty.OverrideDefaultValue<ToolBar>(Orientation.Horizontal);
|
||||||
|
// TODO: use helper method after merged and upgrade helper dependency.
|
||||||
|
IsOverflowItemProperty.Changed.AddClassHandler<Control, bool>((o, e) =>
|
||||||
|
{
|
||||||
|
PseudolassesExtensions.Set(o.Classes, PC_Overflow, e.NewValue.Value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
|
||||||
|
{
|
||||||
|
return NeedsContainer<Control>(item, out recycleKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
||||||
|
{
|
||||||
|
if(item is Control c)
|
||||||
|
{
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if(ItemTemplate is not null && ItemTemplate.Match(item))
|
||||||
|
{
|
||||||
|
return ItemTemplate.Build(item)?? new ContentPresenter();
|
||||||
|
}
|
||||||
|
return new ContentPresenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnApplyTemplate(e);
|
||||||
|
OverflowPanel = e.NameScope.Find<Panel>(PART_OverflowPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
151
src/Ursa/Controls/ToolBar/ToolBarPanel.cs
Normal file
151
src/Ursa/Controls/ToolBar/ToolBarPanel.cs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Layout;
|
||||||
|
using Avalonia.LogicalTree;
|
||||||
|
|
||||||
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
public class ToolBarPanel: StackPanel
|
||||||
|
{
|
||||||
|
private ToolBar? _parent;
|
||||||
|
private Panel? _overflowPanel;
|
||||||
|
|
||||||
|
private Panel? OverflowPanel => _overflowPanel ??= _parent?.OverflowPanel;
|
||||||
|
internal ToolBar? ParentToolBar => _parent ??= this.TemplatedParent as ToolBar;
|
||||||
|
|
||||||
|
static ToolBarPanel()
|
||||||
|
{
|
||||||
|
OrientationProperty.OverrideDefaultValue<ToolBarPanel>(Orientation.Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnAttachedToLogicalTree(e);
|
||||||
|
_parent = this.TemplatedParent as ToolBar;
|
||||||
|
if (_parent is null) return;
|
||||||
|
this[!OrientationProperty] = _parent[!OrientationProperty];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
|
{
|
||||||
|
var logicalChildren = _parent?.GetLogicalChildren().OfType<Control>().ToList();
|
||||||
|
Size size = new Size();
|
||||||
|
double spacing = 0;
|
||||||
|
Size measureSize = availableSize;
|
||||||
|
bool horizontal = Orientation == Orientation.Horizontal;
|
||||||
|
bool hasVisibleChildren = false;
|
||||||
|
if (logicalChildren is null) return size;
|
||||||
|
for (int i = 0; i < logicalChildren.Count; i++)
|
||||||
|
{
|
||||||
|
Control control = logicalChildren[i];
|
||||||
|
var mode = ToolBar.GetOverflowMode(control);
|
||||||
|
control.Measure(measureSize);
|
||||||
|
if (mode == OverflowMode.Always)
|
||||||
|
{
|
||||||
|
ToolBar.SetIsOverflowItem(control, true);
|
||||||
|
}
|
||||||
|
else if (mode == OverflowMode.Never)
|
||||||
|
{
|
||||||
|
if (control.IsVisible)
|
||||||
|
{
|
||||||
|
hasVisibleChildren = true;
|
||||||
|
size = horizontal
|
||||||
|
? size.WithWidth(size.Width + control.DesiredSize.Width + spacing)
|
||||||
|
.WithHeight(Math.Max(size.Height, control.DesiredSize.Height))
|
||||||
|
: size.WithHeight(size.Height + control.DesiredSize.Height + spacing)
|
||||||
|
.WithWidth(Math.Max(size.Width, control.DesiredSize.Width));
|
||||||
|
ToolBar.SetIsOverflowItem(control, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool isOverflow = false;
|
||||||
|
for(int i = 0; i < logicalChildren.Count; i++)
|
||||||
|
{
|
||||||
|
Control control = logicalChildren[i];
|
||||||
|
var mode = ToolBar.GetOverflowMode(control);
|
||||||
|
if (mode != OverflowMode.AsNeeded) continue;
|
||||||
|
//Always keeps the order of display. It's very un reasonable to display the second but short control
|
||||||
|
//and push the first control to the overflow panel. So once a control is marked as overflow, the following
|
||||||
|
//controls will be marked as overflow too.
|
||||||
|
if (isOverflow)
|
||||||
|
{
|
||||||
|
ToolBar.SetIsOverflowItem(control, isOverflow);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool isFit = horizontal
|
||||||
|
? (size.Width + control.DesiredSize.Width <= availableSize.Width)
|
||||||
|
: (size.Height + control.DesiredSize.Height <= availableSize.Height);
|
||||||
|
if (isFit)
|
||||||
|
{
|
||||||
|
ToolBar.SetIsOverflowItem(control, false);
|
||||||
|
size = horizontal
|
||||||
|
? size.WithWidth(size.Width + control.DesiredSize.Width + spacing)
|
||||||
|
.WithHeight(Math.Max(size.Height, control.DesiredSize.Height))
|
||||||
|
: size.WithHeight(size.Height + control.DesiredSize.Height + spacing)
|
||||||
|
.WithWidth(Math.Max(size.Width, control.DesiredSize.Width));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isOverflow = true;
|
||||||
|
ToolBar.SetIsOverflowItem(control, isOverflow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasVisibleChildren)
|
||||||
|
{
|
||||||
|
size = horizontal ? size.WithWidth(size.Width - spacing) : size.WithHeight(size.Height - spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size ArrangeOverride(Size finalSize)
|
||||||
|
{
|
||||||
|
Children.Clear();
|
||||||
|
OverflowPanel?.Children.Clear();
|
||||||
|
var logicalChildren = _parent?.GetLogicalChildren().OfType<Control>().ToList();
|
||||||
|
if(logicalChildren is null) return finalSize;
|
||||||
|
bool overflow = false;
|
||||||
|
foreach (var child in logicalChildren)
|
||||||
|
{
|
||||||
|
if (ToolBar.GetIsOverflowItem(child))
|
||||||
|
{
|
||||||
|
OverflowPanel?.Children.Add(child);
|
||||||
|
overflow = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Children.Add(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child is ToolBarSeparator s)
|
||||||
|
{
|
||||||
|
s.IsVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var thisLast = this.Children.LastOrDefault();
|
||||||
|
if (thisLast is ToolBarSeparator s2)
|
||||||
|
{
|
||||||
|
s2.IsVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var thatFirst = OverflowPanel?.Children.FirstOrDefault();
|
||||||
|
if (thatFirst is ToolBarSeparator s3)
|
||||||
|
{
|
||||||
|
s3.IsVisible = false;
|
||||||
|
}
|
||||||
|
if (_parent != null) _parent.HasOverflowItems = overflow;
|
||||||
|
return base.ArrangeOverride(finalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
var list = OverflowPanel?.Children.ToList();
|
||||||
|
if (list is not null)
|
||||||
|
{
|
||||||
|
OverflowPanel?.Children.Clear();
|
||||||
|
Children.AddRange(list);
|
||||||
|
}
|
||||||
|
base.OnDetachedFromVisualTree(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/Ursa/Controls/ToolBar/ToolBarSeparator.cs
Normal file
41
src/Ursa/Controls/ToolBar/ToolBarSeparator.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Metadata;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Layout;
|
||||||
|
using Avalonia.LogicalTree;
|
||||||
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
|
|
||||||
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
[PseudoClasses(PC_Vertical)]
|
||||||
|
public class ToolBarSeparator: TemplatedControl
|
||||||
|
{
|
||||||
|
public const string PC_Vertical = ":vertical";
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Orientation> OrientationProperty =
|
||||||
|
ToolBar.OrientationProperty.AddOwner<ToolBarSeparator>();
|
||||||
|
|
||||||
|
public Orientation Orientation
|
||||||
|
{
|
||||||
|
get => GetValue(OrientationProperty);
|
||||||
|
set => SetValue(OrientationProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ToolBarSeparator()
|
||||||
|
{
|
||||||
|
OrientationProperty.OverrideDefaultValue<ToolBarSeparator>(Orientation.Horizontal);
|
||||||
|
OrientationProperty.Changed.AddClassHandler<ToolBarSeparator, Orientation>((separator, args) =>
|
||||||
|
{
|
||||||
|
separator.PseudoClasses.Set(PC_Vertical, args.NewValue.Value == Orientation.Vertical);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnAttachedToLogicalTree(e);
|
||||||
|
var ancestor = this.GetLogicalAncestors().OfType<ToolBar>().FirstOrDefault();
|
||||||
|
if (ancestor is null) return;
|
||||||
|
this[!OrientationProperty] = ancestor[!ToolBar.OrientationProperty];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,4 +17,8 @@
|
|||||||
<PackageReference Include="Irihi.Avalonia.Shared" Version="0.1.2" />
|
<PackageReference Include="Irihi.Avalonia.Shared" Version="0.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Controls\Panels\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user