feat: add separator support, fix various issues.
This commit is contained in:
@@ -9,17 +9,22 @@ namespace Ursa.Demo.Converters;
|
|||||||
|
|
||||||
public class ToolBarItemTemplateSelector: IDataTemplate
|
public class ToolBarItemTemplateSelector: IDataTemplate
|
||||||
{
|
{
|
||||||
|
|
||||||
public static ToolBarItemTemplateSelector Instance { get; } = new();
|
public static ToolBarItemTemplateSelector Instance { get; } = new();
|
||||||
public Control? Build(object? param)
|
public Control? Build(object? param)
|
||||||
{
|
{
|
||||||
if (param is null) return null;
|
if (param is null) return null;
|
||||||
|
if (param is ToolBarSeparatorViewModel sep)
|
||||||
|
{
|
||||||
|
return new ToolBarSeparator();
|
||||||
|
}
|
||||||
if (param is ToolBarButtonItemViewModel vm)
|
if (param is ToolBarButtonItemViewModel vm)
|
||||||
{
|
{
|
||||||
return new Button()
|
return new Button()
|
||||||
{
|
{
|
||||||
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
[!Button.CommandProperty] = new Binding() { Path = "Command" },
|
[!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)
|
if (param is ToolBarCheckBoxItemViweModel cb)
|
||||||
@@ -28,7 +33,7 @@ public class ToolBarItemTemplateSelector: IDataTemplate
|
|||||||
{
|
{
|
||||||
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
[!ToggleButton.IsCheckedProperty] = new Binding() { Path = "IsChecked" },
|
[!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)
|
if (param is ToolBarComboBoxItemViewModel combo)
|
||||||
@@ -38,7 +43,7 @@ public class ToolBarItemTemplateSelector: IDataTemplate
|
|||||||
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
[!ContentControl.ContentProperty] = new Binding() { Path = "Content" },
|
||||||
[!SelectingItemsControl.SelectedItemProperty] = new Binding() { Path = "SelectedItem" },
|
[!SelectingItemsControl.SelectedItemProperty] = new Binding() { Path = "SelectedItem" },
|
||||||
[!ItemsControl.ItemsSourceProperty] = new Binding() { Path = "Items" },
|
[!ItemsControl.ItemsSourceProperty] = new Binding() { Path = "Items" },
|
||||||
[ToolBar.OverflowModeProperty] = OverflowMode.Always,
|
[!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new Button() { Content = "Undefined Item" };
|
return new Button() { Content = "Undefined Item" };
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
DockPanel.Dock="Top"
|
DockPanel.Dock="Top"
|
||||||
Header="Hello World">
|
Header="Hello World">
|
||||||
<Button Content="Button 1" u:ToolBar.OverflowMode="Never" />
|
<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 2" />
|
||||||
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 3" />
|
<Button u:ToolBar.OverflowMode="AsNeeded" Content="Button 3" />
|
||||||
|
<ToggleButton Content="Toggle"></ToggleButton>
|
||||||
</u:ToolBar>
|
</u:ToolBar>
|
||||||
<u:ToolBar
|
<u:ToolBar
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ public partial class ToolBarDemoViewModel: ObservableObject
|
|||||||
new ToolBarButtonItemViewModel() { Content = "Open" },
|
new ToolBarButtonItemViewModel() { Content = "Open" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save1" },
|
new ToolBarButtonItemViewModel() { Content = "Save1" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save2" },
|
new ToolBarButtonItemViewModel() { Content = "Save2" },
|
||||||
|
new ToolBarSeparatorViewModel(),
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save3" },
|
new ToolBarButtonItemViewModel() { Content = "Save3" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save4" },
|
new ToolBarButtonItemViewModel() { Content = "Save4" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save5" },
|
new ToolBarButtonItemViewModel() { Content = "Save5" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save6" },
|
new ToolBarButtonItemViewModel() { Content = "Save6" },
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save7" },
|
new ToolBarButtonItemViewModel() { Content = "Save7" },
|
||||||
|
new ToolBarSeparatorViewModel(),
|
||||||
new ToolBarButtonItemViewModel() { Content = "Save8" },
|
new ToolBarButtonItemViewModel() { Content = "Save8" },
|
||||||
new ToolBarCheckBoxItemViweModel() { Content = "Bold" },
|
new ToolBarCheckBoxItemViweModel() { Content = "Bold" },
|
||||||
new ToolBarCheckBoxItemViweModel() { Content = "Italic", OverflowMode = OverflowMode.Never},
|
new ToolBarCheckBoxItemViweModel() { Content = "Italic", OverflowMode = OverflowMode.Never},
|
||||||
@@ -73,7 +75,9 @@ public class ToolBarComboBoxItemViewModel: ToolBarItemViewModel
|
|||||||
MessageBox.ShowOverlayAsync(value);
|
MessageBox.ShowOverlayAsync(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToolBarSeparatorViewModel: ToolBarItemViewModel
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{DynamicResource SemiColorText2}"
|
||||||
Content="{TemplateBinding Header}"
|
Content="{TemplateBinding Header}"
|
||||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
DockPanel.Dock="Left"
|
DockPanel.Dock="Left"
|
||||||
@@ -94,6 +95,7 @@
|
|||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
|
Foreground="{DynamicResource SemiColorText2}"
|
||||||
Content="{TemplateBinding Header}"
|
Content="{TemplateBinding Header}"
|
||||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
DockPanel.Dock="Top"
|
DockPanel.Dock="Top"
|
||||||
@@ -112,7 +114,7 @@
|
|||||||
IsOpen="{Binding #button.IsChecked, Mode=TwoWay}"
|
IsOpen="{Binding #button.IsChecked, Mode=TwoWay}"
|
||||||
Placement="{TemplateBinding PopupPlacement}"
|
Placement="{TemplateBinding PopupPlacement}"
|
||||||
PlacementTarget="{Binding #button}">
|
PlacementTarget="{Binding #button}">
|
||||||
<Border Theme="{DynamicResource CardBorder}">
|
<Border Theme="{DynamicResource CardBorder}" Padding="2">
|
||||||
<StackPanel Name="{x:Static u:ToolBar.PART_OverflowPanel}" />
|
<StackPanel Name="{x:Static u:ToolBar.PART_OverflowPanel}" />
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
@@ -130,4 +132,23 @@
|
|||||||
<Setter Property="IsVisible" Value="True"></Setter>
|
<Setter Property="IsVisible" Value="True"></Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ControlTheme>
|
</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>
|
</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>
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ public class ToolBar: HeaderedItemsControl
|
|||||||
{
|
{
|
||||||
return c;
|
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)
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
|
|||||||
@@ -116,8 +116,24 @@ public class ToolBarPanel: StackPanel
|
|||||||
{
|
{
|
||||||
Children.Add(child);
|
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;
|
if (_parent != null) _parent.HasOverflowItems = overflow;
|
||||||
return base.ArrangeOverride(finalSize);
|
return base.ArrangeOverride(finalSize);
|
||||||
}
|
}
|
||||||
|
|||||||
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user