Add CanResize property to drawers and dialogs with corresponding UI controls

This commit introduces a new `CanResize` property to `DrawerOptions`, `OverlayDialogOptions`, and their respective controls. It also adds UI resizing functionality through the `DialogResizer` control, with styles adjusted to support different drawer positions. Code formatting and organization have been improved for readability across modified files.
This commit is contained in:
rabbitism
2024-09-17 23:06:00 +08:00
parent c512cb6e13
commit 219ead2172
6 changed files with 320 additions and 177 deletions

View File

@@ -1,25 +1,33 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="https://irihi.tech/ursa"
xmlns:c="clr-namespace:Ursa.Themes.Semi.Converters">
<ControlTheme TargetType="u:CustomDrawerControl" x:Key="{x:Type u:CustomDrawerControl}">
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="Padding" Value="{DynamicResource DrawerMargin}"/>
<Setter Property="BorderThickness" Value="{DynamicResource DrawerBorderThickness}"/>
<Setter Property="CornerRadius" Value="{DynamicResource DrawerCornerRadius}"/>
xmlns:c="clr-namespace:Ursa.Themes.Semi.Converters"
xmlns:u="https://irihi.tech/ursa">
<ControlTheme x:Key="{x:Type u:CustomDrawerControl}" TargetType="u:CustomDrawerControl">
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="MinWidth" Value="96" />
<Setter Property="MinHeight" Value="96" />
<Setter Property="Padding" Value="{DynamicResource DrawerMargin}" />
<Setter Property="BorderThickness" Value="{DynamicResource DrawerBorderThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource DrawerCornerRadius}" />
<Setter Property="Template">
<ControlTemplate TargetType="u:CustomDrawerControl">
<Border Name="PART_Root"
Focusable="True"
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
<Panel>
<Border
Name="PART_Root"
Margin="{TemplateBinding Padding,
Converter={x:Static c:ThicknessTakeConverter.Left}}"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="{TemplateBinding BorderThickness,
Converter={x:Static c:ThicknessTakeConverter.Left}}"
Classes="Shadow"
ClipToBounds="False"
CornerRadius="{TemplateBinding CornerRadius, Converter={x:Static c:CornerRadiusTakeConverter.Left}}"
BorderThickness="{TemplateBinding BorderThickness, Converter={x:Static c:ThicknessTakeConverter.Left}}"
CornerRadius="{TemplateBinding CornerRadius,
Converter={x:Static c:CornerRadiusTakeConverter.Left}}"
Focusable="True"
IsHitTestVisible="True"
Theme="{DynamicResource CardBorder}">
<Border ClipToBounds="True" CornerRadius="{Binding #PART_Root.CornerRadius}">
@@ -45,6 +53,8 @@
</Grid>
</Border>
</Border>
<u:DialogResizer IsVisible="{TemplateBinding CanResize}" />
</Panel>
</ControlTemplate>
</Setter>
<Style Selector="^[Position=Right] /template/ Border#PART_Root">
@@ -67,26 +77,45 @@
<Setter Property="CornerRadius" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CornerRadius, Converter={x:Static c:CornerRadiusTakeConverter.Top}}" />
<Setter Property="BorderThickness" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness, Converter={x:Static c:ThicknessTakeConverter.Top}}" />
</Style>
<Style Selector="^[Position=Top] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Bottom"/>
</Style>
<Style Selector="^[Position=Bottom] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Top"/>
</Style>
<Style Selector="^[Position=Left] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Right"/>
</Style>
<Style Selector="^[Position=Right] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Left"/>
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:DefaultDrawerControl}" TargetType="u:DefaultDrawerControl">
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="Padding" Value="{DynamicResource DrawerMargin}"/>
<Setter Property="BorderThickness" Value="{DynamicResource DrawerBorderThickness}"/>
<Setter Property="CornerRadius" Value="{DynamicResource DrawerCornerRadius}"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="MinWidth" Value="96" />
<Setter Property="MinHeight" Value="96" />
<Setter Property="Padding" Value="{DynamicResource DrawerMargin}" />
<Setter Property="BorderThickness" Value="{DynamicResource DrawerBorderThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource DrawerCornerRadius}" />
<Setter Property="Template">
<ControlTemplate TargetType="u:DefaultDrawerControl">
<Border Name="PART_Root"
Focusable="True"
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
<Panel>
<Border
Name="PART_Root"
Margin="{TemplateBinding Padding,
Converter={x:Static c:ThicknessTakeConverter.Left}}"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="{TemplateBinding BorderThickness,
Converter={x:Static c:ThicknessTakeConverter.Left}}"
Classes="Shadow"
ClipToBounds="False"
CornerRadius="{TemplateBinding CornerRadius, Converter={x:Static c:CornerRadiusTakeConverter.Left}}"
BorderThickness="{TemplateBinding BorderThickness, Converter={x:Static c:ThicknessTakeConverter.Left}}"
CornerRadius="{TemplateBinding CornerRadius,
Converter={x:Static c:CornerRadiusTakeConverter.Left}}"
Focusable="True"
IsHitTestVisible="True"
Theme="{DynamicResource CardBorder}">
<Border ClipToBounds="True" CornerRadius="{Binding #PART_Root.CornerRadius}">
@@ -149,6 +178,8 @@
</Grid>
</Border>
</Border>
<u:DialogResizer IsVisible="{TemplateBinding CanResize}" />
</Panel>
</ControlTemplate>
</Setter>
<Style Selector="^[Position=Right] /template/ Border#PART_Root">
@@ -171,5 +202,17 @@
<Setter Property="CornerRadius" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CornerRadius, Converter={x:Static c:CornerRadiusTakeConverter.Top}}" />
<Setter Property="BorderThickness" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness, Converter={x:Static c:ThicknessTakeConverter.Top}}" />
</Style>
<Style Selector="^[Position=Top] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Bottom"/>
</Style>
<Style Selector="^[Position=Bottom] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Top"/>
</Style>
<Style Selector="^[Position=Left] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Right"/>
</Style>
<Style Selector="^[Position=Right] /template/ u|DialogResizer">
<Setter Property="ResizeDirection" Value="Left"/>
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@@ -1,57 +1,144 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="https://irihi.tech/ursa"
xmlns:iri="https://irihi.tech/shared">
xmlns:iri="https://irihi.tech/shared"
xmlns:u="https://irihi.tech/ursa">
<!-- Add Resources Here -->
<ControlTheme TargetType="u:WindowResizerThumb" x:Key="{x:Type u:WindowResizerThumb}">
<ControlTheme x:Key="{x:Type u:WindowResizerThumb}" TargetType="u:WindowResizerThumb">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<ControlTemplate TargetType="u:WindowResizerThumb">
<iri:PureRectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{TemplateBinding Background}"/>
<iri:PureRectangle
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme TargetType="u:DialogResizerThumb" x:Key="{x:Type u:DialogResizerThumb}">
<ControlTheme x:Key="{x:Type u:DialogResizerThumb}" TargetType="u:DialogResizerThumb">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<ControlTemplate TargetType="u:DialogResizerThumb">
<Panel>
<iri:PureRectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{TemplateBinding Background}"/>
<iri:PureRectangle
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{TemplateBinding Background}" />
</Panel>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme TargetType="u:DialogResizer" x:Key="{x:Type u:DialogResizer}">
<ControlTheme x:Key="{x:Type u:DialogResizer}" TargetType="u:DialogResizer">
<Setter Property="Template">
<ControlTemplate TargetType="u:WindowResizer">
<Grid RowDefinitions="Auto, *, Auto" ColumnDefinitions="Auto, *, Auto" >
<u:DialogResizerThumb Grid.Row="0" Grid.Column="0" ResizeDirection="TopLeft" Cursor="TopLeftCorner" />
<u:DialogResizerThumb Grid.Row="0" Grid.Column="1" ResizeDirection="Top" Cursor="TopSide" Height="{DynamicResource ResizerThumbHeight}" />
<u:DialogResizerThumb Grid.Row="0" Grid.Column="2" ResizeDirection="TopRight" Cursor="TopRightCorner" />
<u:DialogResizerThumb Grid.Row="1" Grid.Column="0" ResizeDirection="Left" Cursor="LeftSide" Width="{DynamicResource ResizerThumbWidth}" />
<u:DialogResizerThumb Grid.Row="1" Grid.Column="2" ResizeDirection="Right" Cursor="RightSide" Width="{DynamicResource ResizerThumbWidth}" />
<u:DialogResizerThumb Grid.Row="2" Grid.Column="0" ResizeDirection="BottomLeft" Cursor="BottomLeftCorner" />
<u:DialogResizerThumb Grid.Row="2" Grid.Column="1" ResizeDirection="Bottom" Cursor="BottomSide" Height="{DynamicResource ResizerThumbHeight}" />
<u:DialogResizerThumb Grid.Row="2" Grid.Column="2" ResizeDirection="BottomRight" Cursor="BottomRightCorner" />
<Grid ColumnDefinitions="Auto, *, Auto" RowDefinitions="Auto, *, Auto">
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_TopLeft}"
Grid.Row="0"
Grid.Column="0"
Cursor="TopLeftCorner"
ResizeDirection="TopLeft" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_Top}"
Grid.Row="0"
Grid.Column="1"
Height="{DynamicResource ResizerThumbHeight}"
Cursor="TopSide"
ResizeDirection="Top" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_TopRight}"
Grid.Row="0"
Grid.Column="2"
Cursor="TopRightCorner"
ResizeDirection="TopRight" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_Left}"
Grid.Row="1"
Grid.Column="0"
Width="{DynamicResource ResizerThumbWidth}"
Cursor="LeftSide"
ResizeDirection="Left" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_Right}"
Grid.Row="1"
Grid.Column="2"
Width="{DynamicResource ResizerThumbWidth}"
Cursor="RightSide"
ResizeDirection="Right" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_BottomLeft}"
Grid.Row="2"
Grid.Column="0"
Cursor="BottomLeftCorner"
ResizeDirection="BottomLeft" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_Bottom}"
Grid.Row="2"
Grid.Column="1"
Height="{DynamicResource ResizerThumbHeight}"
Cursor="BottomSide"
ResizeDirection="Bottom" />
<u:DialogResizerThumb
Name="{x:Static u:DialogResizer.PART_BottomRight}"
Grid.Row="2"
Grid.Column="2"
Cursor="BottomRightCorner"
ResizeDirection="BottomRight" />
</Grid>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme TargetType="u:WindowResizer" x:Key="{x:Type u:WindowResizer}">
<ControlTheme x:Key="{x:Type u:WindowResizer}" TargetType="u:WindowResizer">
<Setter Property="Template">
<ControlTemplate TargetType="u:WindowResizer">
<Grid RowDefinitions="Auto, *, Auto" ColumnDefinitions="Auto, *, Auto" >
<u:WindowResizerThumb Grid.Row="0" Grid.Column="0" ResizeDirection="TopLeft" Cursor="TopLeftCorner" />
<u:WindowResizerThumb Grid.Row="0" Grid.Column="1" ResizeDirection="Top" Cursor="TopSide" Height="{DynamicResource ResizerThumbHeight}" />
<u:WindowResizerThumb Grid.Row="0" Grid.Column="2" ResizeDirection="TopRight" Cursor="TopRightCorner" />
<u:WindowResizerThumb Grid.Row="1" Grid.Column="0" ResizeDirection="Left" Cursor="LeftSide" Width="{DynamicResource ResizerThumbWidth}" />
<u:WindowResizerThumb Grid.Row="1" Grid.Column="2" ResizeDirection="Right" Cursor="RightSide" Width="{DynamicResource ResizerThumbWidth}" />
<u:WindowResizerThumb Grid.Row="2" Grid.Column="0" ResizeDirection="BottomLeft" Cursor="BottomLeftCorner" />
<u:WindowResizerThumb Grid.Row="2" Grid.Column="1" ResizeDirection="Bottom" Cursor="BottomSide" Height="{DynamicResource ResizerThumbHeight}" />
<u:WindowResizerThumb Grid.Row="2" Grid.Column="2" ResizeDirection="BottomRight" Cursor="BottomRightCorner" />
<Grid ColumnDefinitions="Auto, *, Auto" RowDefinitions="Auto, *, Auto">
<u:WindowResizerThumb
Grid.Row="0"
Grid.Column="0"
Cursor="TopLeftCorner"
ResizeDirection="TopLeft" />
<u:WindowResizerThumb
Grid.Row="0"
Grid.Column="1"
Height="{DynamicResource ResizerThumbHeight}"
Cursor="TopSide"
ResizeDirection="Top" />
<u:WindowResizerThumb
Grid.Row="0"
Grid.Column="2"
Cursor="TopRightCorner"
ResizeDirection="TopRight" />
<u:WindowResizerThumb
Grid.Row="1"
Grid.Column="0"
Width="{DynamicResource ResizerThumbWidth}"
Cursor="LeftSide"
ResizeDirection="Left" />
<u:WindowResizerThumb
Grid.Row="1"
Grid.Column="2"
Width="{DynamicResource ResizerThumbWidth}"
Cursor="RightSide"
ResizeDirection="Right" />
<u:WindowResizerThumb
Grid.Row="2"
Grid.Column="0"
Cursor="BottomLeftCorner"
ResizeDirection="BottomLeft" />
<u:WindowResizerThumb
Grid.Row="2"
Grid.Column="1"
Height="{DynamicResource ResizerThumbHeight}"
Cursor="BottomSide"
ResizeDirection="Bottom" />
<u:WindowResizerThumb
Grid.Row="2"
Grid.Column="2"
Cursor="BottomRightCorner"
ResizeDirection="BottomRight" />
</Grid>
</ControlTemplate>
</Setter>

View File

@@ -205,16 +205,17 @@ public static class Drawer
drawer.Position = options.Position;
drawer.IsCloseButtonVisible = options.IsCloseButtonVisible;
drawer.CanLightDismiss = options.CanLightDismiss;
drawer.CanResize = options.CanResize;
if (options.Position == Position.Left || options.Position == Position.Right)
{
drawer.MinWidth = options.MinWidth ?? 0.0;
drawer.MaxWidth = options.MaxWidth ?? double.PositiveInfinity;
if(options.MinWidth is not null) drawer.MinWidth = options.MinWidth.Value;
if(options.MaxWidth is not null) drawer.MaxWidth = options.MaxWidth.Value;
}
if (options.Position is Position.Top or Position.Bottom)
{
drawer.MinHeight = options.MinHeight ?? 0.0;
drawer.MaxHeight = options.MaxHeight ?? double.PositiveInfinity;
if(options.MinHeight is not null) drawer.MinHeight = options.MinHeight.Value;
if(options.MaxHeight is not null) drawer.MaxHeight = options.MaxHeight.Value;
}
}
@@ -226,16 +227,17 @@ public static class Drawer
drawer.CanLightDismiss = options.CanLightDismiss;
drawer.Buttons = options.Buttons;
drawer.Title = options.Title;
drawer.CanResize = options.CanResize;
if (options.Position == Position.Left || options.Position == Position.Right)
{
drawer.MinWidth = options.MinWidth ?? 0.0;
drawer.MaxWidth = options.MaxWidth ?? double.PositiveInfinity;
if(options.MinWidth is not null) drawer.MinWidth = options.MinWidth.Value;
if(options.MaxWidth is not null) drawer.MaxWidth = options.MaxWidth.Value;
}
if (options.Position is Position.Top or Position.Bottom)
{
drawer.MinHeight = options.MinHeight ?? 0.0;
drawer.MaxHeight = options.MaxHeight ?? double.PositiveInfinity;
if(options.MinHeight is not null) drawer.MinHeight = options.MinHeight.Value;
if(options.MaxHeight is not null) drawer.MaxHeight = options.MaxHeight.Value;
}
}
}

View File

@@ -22,6 +22,15 @@ public abstract class DrawerControlBase: OverlayFeedbackElement
AvaloniaProperty.Register<DrawerControlBase, Position>(
nameof(Position), defaultValue: Position.Right);
public static readonly StyledProperty<bool> CanResizeProperty = AvaloniaProperty.Register<DrawerControlBase, bool>(
nameof(CanResize));
public bool CanResize
{
get => GetValue(CanResizeProperty);
set => SetValue(CanResizeProperty, value);
}
public Position Position
{
get => GetValue(PositionProperty);

View File

@@ -20,4 +20,6 @@ public class DrawerOptions
/// The hash code of the top level dialog host. This is used to identify the dialog host if there are multiple dialog hosts with the same id. If this is not provided, the dialog will be added to the first dialog host with the same id.
/// </summary>
public int? TopLevelHashCode { get; set; }
public bool CanResize { get; set; }
}