Update boundary logic

This commit is contained in:
TheXamlGuy
2024-10-11 13:45:27 +01:00
parent 066a59b250
commit c7d2c0efd4
3 changed files with 172 additions and 23 deletions
@@ -2,7 +2,5 @@
namespace Toolkit.UI.Controls.Avalonia; namespace Toolkit.UI.Controls.Avalonia;
public class ContentCard : ContentControl public class ContentCard :
{ ContentControl;
}
@@ -25,6 +25,10 @@
<Thickness x:Key="ContentCropperTopRightThumbBorderThickness">0,3,3,0</Thickness> <Thickness x:Key="ContentCropperTopRightThumbBorderThickness">0,3,3,0</Thickness>
<Thickness x:Key="ContentCropperBottomRightThumbBorderThickness">0,0,3,3</Thickness> <Thickness x:Key="ContentCropperBottomRightThumbBorderThickness">0,0,3,3</Thickness>
<Thickness x:Key="ContentCropperBottomLeftThumbBorderThickness">3,0,0,3</Thickness> <Thickness x:Key="ContentCropperBottomLeftThumbBorderThickness">3,0,0,3</Thickness>
<Thickness x:Key="ContentCropperLeftThumbBorderThickness">3,0,0,0</Thickness>
<Thickness x:Key="ContentCropperTopThumbBorderThickness">0,3,0,0</Thickness>
<Thickness x:Key="ContentCropperRightThumbBorderThickness">0,0,3,0</Thickness>
<Thickness x:Key="ContentCropperBottomThumbBorderThickness">0,0,0,3</Thickness>
<ControlTheme x:Key="ContentCropperThumbStyle" TargetType="Thumb"> <ControlTheme x:Key="ContentCropperThumbStyle" TargetType="Thumb">
<Setter Property="BorderBrush" Value="{DynamicResource ContentCropperInnerBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource ContentCropperInnerBorderBrush}" />
@@ -91,6 +95,34 @@
BorderThickness="{StaticResource ContentCropperBottomRightThumbBorderThickness}" BorderThickness="{StaticResource ContentCropperBottomRightThumbBorderThickness}"
Cursor="BottomRightCorner" Cursor="BottomRightCorner"
Theme="{StaticResource ContentCropperThumbStyle}" /> Theme="{StaticResource ContentCropperThumbStyle}" />
<Thumb
x:Name="LeftButton"
Width="{StaticResource ContentCropperThumbWidth}"
Height="{StaticResource ContentCropperThumbHeight}"
BorderThickness="{StaticResource ContentCropperLeftThumbBorderThickness}"
Cursor="LeftSide"
Theme="{StaticResource ContentCropperThumbStyle}" />
<Thumb
x:Name="RightButton"
Width="{StaticResource ContentCropperThumbWidth}"
Height="{StaticResource ContentCropperThumbHeight}"
BorderThickness="{StaticResource ContentCropperRightThumbBorderThickness}"
Cursor="RightSide"
Theme="{StaticResource ContentCropperThumbStyle}" />
<Thumb
x:Name="TopButton"
Width="{StaticResource ContentCropperThumbWidth}"
Height="{StaticResource ContentCropperThumbHeight}"
BorderThickness="{StaticResource ContentCropperTopThumbBorderThickness}"
Cursor="TopSide"
Theme="{StaticResource ContentCropperThumbStyle}" />
<Thumb
x:Name="BottomButton"
Width="{StaticResource ContentCropperThumbWidth}"
Height="{StaticResource ContentCropperThumbHeight}"
BorderThickness="{StaticResource ContentCropperBottomThumbBorderThickness}"
Cursor="BottomSide"
Theme="{StaticResource ContentCropperThumbStyle}" />
</Canvas> </Canvas>
</Grid> </Grid>
</ControlTemplate> </ControlTemplate>
@@ -36,6 +36,10 @@ public class ContentCropper : ContentControl
private Path? overlayPath; private Path? overlayPath;
private Thumb? topLeftButton; private Thumb? topLeftButton;
private Thumb? topRightButton; private Thumb? topRightButton;
private Thumb? leftButton;
private Thumb? rightButton;
private Thumb? topButton;
private Thumb? bottomButton;
static ContentCropper() static ContentCropper()
{ {
@@ -96,6 +100,31 @@ public class ContentCropper : ContentControl
{ {
bottomRightButton.DragDelta += OnThumbDragDelta; bottomRightButton.DragDelta += OnThumbDragDelta;
} }
leftButton = args.NameScope.Find<Thumb>("LeftButton");
if (leftButton is not null)
{
leftButton.DragDelta += OnThumbDragDelta;
}
rightButton = args.NameScope.Find<Thumb>("RightButton");
if (rightButton is not null)
{
rightButton.DragDelta += OnThumbDragDelta;
}
topButton = args.NameScope.Find<Thumb>("TopButton");
if (topButton is not null)
{
topButton.DragDelta += OnThumbDragDelta;
}
bottomButton = args.NameScope.Find<Thumb>("BottomButton");
if (bottomButton is not null)
{
bottomButton.DragDelta += OnThumbDragDelta;
}
} }
protected override void OnLoaded(RoutedEventArgs args) protected override void OnLoaded(RoutedEventArgs args)
@@ -155,7 +184,6 @@ public class ContentCropper : ContentControl
RenderOverLays(); RenderOverLays();
} }
private void InitializeCropRect() private void InitializeCropRect()
{ {
if (canvas is null || Content is not Control content) if (canvas is null || Content is not Control content)
@@ -225,12 +253,17 @@ public class ContentCropper : ContentControl
UpdateCropRatios(); UpdateCropRatios();
} }
private void OnThumbDragDelta(object? sender, VectorEventArgs args) private void OnThumbDragDelta(object? sender, VectorEventArgs args)
{ {
if (canvas is null || border is null || sender is not Thumb thumb) if (canvas is null || border is null || sender is not Thumb thumb)
{ {
return; return;
} }
double minimumWidth = 20;
double minimumHeight = 20;
double deltaX = args.Vector.X; double deltaX = args.Vector.X;
double deltaY = args.Vector.Y; double deltaY = args.Vector.Y;
@@ -240,45 +273,111 @@ public class ContentCropper : ContentControl
double newWidth = border.Width; double newWidth = border.Width;
double newHeight = border.Height; double newHeight = border.Height;
bool canResizeWidth = true;
bool canResizeHeight = true;
switch (thumb.Name) switch (thumb.Name)
{ {
case "TopLeftButton": case "TopLeftButton":
newWidth = Math.Max(0, border.Width - deltaX); if (border.Width - deltaX < minimumWidth)
newHeight = Math.Max(0, border.Height - deltaY);
if (newWidth > 0)
{ {
canResizeWidth = false;
}
if (border.Height - deltaY < minimumHeight)
{
canResizeHeight = false;
}
if (canResizeWidth)
{
newWidth = border.Width - deltaX;
leftPosition += deltaX; leftPosition += deltaX;
} }
if (newHeight > 0)
if (canResizeHeight)
{ {
newHeight = border.Height - deltaY;
topPosition += deltaY; topPosition += deltaY;
} }
break; break;
case "TopRightButton": case "TopRightButton":
newWidth = Math.Max(0, border.Width + deltaX); if (border.Height - deltaY < minimumHeight)
newHeight = Math.Max(0, border.Height - deltaY);
if (newHeight > 0)
{ {
canResizeHeight = false;
}
newWidth = border.Width + deltaX;
if (canResizeHeight)
{
newHeight = border.Height - deltaY;
topPosition += deltaY; topPosition += deltaY;
} }
break; break;
case "BottomLeftButton": case "BottomLeftButton":
newWidth = Math.Max(0, border.Width - deltaX); if (border.Width - deltaX < minimumWidth)
newHeight = Math.Max(0, border.Height + deltaY);
if (newWidth > 0)
{ {
canResizeWidth = false;
}
newWidth = border.Width - deltaX;
if (canResizeWidth)
{
leftPosition += deltaX;
}
newHeight = border.Height + deltaY;
break;
case "BottomRightButton":
newWidth = border.Width + deltaX;
newHeight = border.Height + deltaY;
break;
case "TopButton":
if (border.Height - deltaY < minimumHeight)
{
canResizeHeight = false;
}
if (canResizeHeight)
{
newHeight = border.Height - deltaY;
topPosition += deltaY;
}
break;
case "BottomButton":
newHeight = border.Height + deltaY;
break;
case "LeftButton":
if (border.Width - deltaX < minimumWidth)
{
canResizeWidth = false;
}
if (canResizeWidth)
{
newWidth = border.Width - deltaX;
leftPosition += deltaX; leftPosition += deltaX;
} }
break; break;
case "BottomRightButton": case "RightButton":
newWidth = Math.Max(0, border.Width + deltaX); newWidth = border.Width + deltaX;
newHeight = Math.Max(0, border.Height + deltaY);
break; break;
} }
if (leftPosition < 0 || leftPosition + newWidth > canvas.Width ||
topPosition < 0 || topPosition + newHeight > canvas.Height ||
newWidth < minimumWidth || newHeight < minimumHeight)
{
return;
}
border.Width = newWidth; border.Width = newWidth;
border.Height = newHeight; border.Height = newHeight;
@@ -294,11 +393,7 @@ public class ContentCropper : ContentControl
private void PositionThumbs() private void PositionThumbs()
{ {
if (border == null || if (border == null || canvas == null) return;
canvas == null)
{
return;
}
double borderLeft = Canvas.GetLeft(border); double borderLeft = Canvas.GetLeft(border);
double borderTop = Canvas.GetTop(border); double borderTop = Canvas.GetTop(border);
@@ -328,6 +423,30 @@ public class ContentCropper : ContentControl
Canvas.SetLeft(bottomRightButton, borderLeft + borderWidth - bottomRightButton.Width); Canvas.SetLeft(bottomRightButton, borderLeft + borderWidth - bottomRightButton.Width);
Canvas.SetTop(bottomRightButton, borderTop + borderHeight - bottomRightButton.Height); Canvas.SetTop(bottomRightButton, borderTop + borderHeight - bottomRightButton.Height);
} }
if (leftButton is not null)
{
Canvas.SetLeft(leftButton, borderLeft);
Canvas.SetTop(leftButton, borderTop + borderHeight / 2 - leftButton.Height / 2);
}
if (rightButton is not null)
{
Canvas.SetLeft(rightButton, borderLeft + borderWidth - rightButton.Width);
Canvas.SetTop(rightButton, borderTop + borderHeight / 2 - rightButton.Height / 2);
}
if (topButton is not null)
{
Canvas.SetLeft(topButton, borderLeft + borderWidth / 2 - topButton.Width / 2);
Canvas.SetTop(topButton, borderTop);
}
if (bottomButton is not null)
{
Canvas.SetLeft(bottomButton, borderLeft + borderWidth / 2 - bottomButton.Width / 2);
Canvas.SetTop(bottomButton, borderTop + borderHeight - bottomButton.Height);
}
} }
private void RenderOverLays() private void RenderOverLays()