feat: add separator support, fix various issues.

This commit is contained in:
rabbitism
2024-02-23 17:51:05 +08:00
parent 1ccb395ab0
commit 0965f9d1f8
9 changed files with 127 additions and 7 deletions

View File

@@ -9,17 +9,22 @@ 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 = "OverflowMode" }
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
};
}
if (param is ToolBarCheckBoxItemViweModel cb)
@@ -28,7 +33,7 @@ public class ToolBarItemTemplateSelector: IDataTemplate
{
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
[!ToggleButton.IsCheckedProperty] = new Binding() { Path = "IsChecked" },
//[!ToolBar.OverflowModeProperty] = new Binding(){ Path = "OverflowMode" }
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
};
}
if (param is ToolBarComboBoxItemViewModel combo)
@@ -38,7 +43,7 @@ public class ToolBarItemTemplateSelector: IDataTemplate
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
[!SelectingItemsControl.SelectedItemProperty] = new Binding() { Path = "SelectedItem" },
[!ItemsControl.ItemsSourceProperty] = new Binding() { Path = "Items" },
[ToolBar.OverflowModeProperty] = OverflowMode.Always,
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
};
}
return new Button() { Content = "Undefined Item" };

View File

@@ -18,8 +18,10 @@
DockPanel.Dock="Top"
Header="Hello World">
<Button Content="Button 1" u:ToolBar.OverflowMode="Never" />
<u:ToolBarSeparator/>
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 2" />
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 3" />
<ToggleButton Content="Toggle"></ToggleButton>
</u:ToolBar>
<u:ToolBar
HorizontalAlignment="Left"

View File

@@ -17,11 +17,13 @@ public partial class ToolBarDemoViewModel: ObservableObject
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},
@@ -73,7 +75,9 @@ public class ToolBarComboBoxItemViewModel: ToolBarItemViewModel
MessageBox.ShowOverlayAsync(value);
}
}
}
public class ToolBarSeparatorViewModel: ToolBarItemViewModel
{
}

View File

@@ -44,6 +44,7 @@
Margin="8,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{DynamicResource SemiColorText2}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
DockPanel.Dock="Left"
@@ -94,6 +95,7 @@
Margin="8,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Foreground="{DynamicResource SemiColorText2}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
DockPanel.Dock="Top"
@@ -112,7 +114,7 @@
IsOpen="{Binding #button.IsChecked, Mode=TwoWay}"
Placement="{TemplateBinding PopupPlacement}"
PlacementTarget="{Binding #button}">
<Border Theme="{DynamicResource CardBorder}">
<Border Theme="{DynamicResource CardBorder}" Padding="2">
<StackPanel Name="{x:Static u:ToolBar.PART_OverflowPanel}" />
</Border>
</Popup>
@@ -130,4 +132,23 @@
<Setter Property="IsVisible" Value="True"></Setter>
</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}"></Rectangle>
</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>
<Setter Property="Width" Value="{x:Static x:Double.NaN}" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
</ControlTheme>
</ResourceDictionary>

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

View File

@@ -5,5 +5,6 @@
</Border>
</Design.PreviewWith>
<StyleInclude Source="ButtonGroup.axaml" />
<StyleInclude Source="ToolBar.axaml"/>
<!-- Add Styles Here -->
</Styles>

View File

@@ -86,7 +86,11 @@ public class ToolBar: HeaderedItemsControl
{
return c;
}
return ItemTemplate?.Build(item) ?? new ContentPresenter();
if(ItemTemplate is not null && ItemTemplate.Match(item))
{
return ItemTemplate.Build(item)?? new ContentPresenter();
}
return new ContentPresenter();
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)

View File

@@ -116,8 +116,24 @@ public class ToolBarPanel: StackPanel
{
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);
}

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