Browse Source

Resize popups implemented

Krzysztof Krysiński 1 year ago
parent
commit
ead1c2de65

+ 7 - 11
src/PixiEditor.AvaloniaUI/Models/Dialogs/ResizeDocumentDialog.cs

@@ -1,8 +1,6 @@
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
-using PixiEditor.AvaloniaUI.Helpers.Extensions;
-using PixiEditor.AvaloniaUI.Views.Windows;
+using PixiEditor.AvaloniaUI.Views.Dialogs;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Enums;
 
 
 namespace PixiEditor.AvaloniaUI.Models.Dialogs;
 namespace PixiEditor.AvaloniaUI.Models.Dialogs;
@@ -70,10 +68,12 @@ internal class ResizeDocumentDialog : CustomDialog
         {
         {
             Width = popup.NewAbsoluteWidth;
             Width = popup.NewAbsoluteWidth;
             Height = popup.NewAbsoluteHeight;
             Height = popup.NewAbsoluteHeight;
-            /*if (popup is ResizeCanvasPopup resizeCanvas) TODO: Implement
+            if (popup is ResizeCanvasPopup resizeCanvas)
             {
             {
                 ResizeAnchor = resizeCanvas.SelectedAnchorPoint;
                 ResizeAnchor = resizeCanvas.SelectedAnchorPoint;
-            }*/
+            }
+
+            return true;
         }
         }
 
 
         return false;
         return false;
@@ -81,15 +81,11 @@ internal class ResizeDocumentDialog : CustomDialog
 
 
     private async Task<bool> ShowResizeDocumentCanvas()
     private async Task<bool> ShowResizeDocumentCanvas()
     {
     {
-        //TODO: Implement
-        //return await ShowDialog<ResizeDocumentPopup>();
-        return false;
+        return await ShowDialog<ResizeDocumentPopup>();
     }
     }
 
 
     private async Task<bool> ShowResizeCanvasDialog()
     private async Task<bool> ShowResizeCanvasDialog()
     {
     {
-        //TODO: Implement
-        //return await ShowDialog<ResizeCanvasPopup>();
-        return false;
+        return await ShowDialog<ResizeCanvasPopup>();
     }
     }
 }
 }

+ 0 - 1
src/PixiEditor.AvaloniaUI/PixiEditor.AvaloniaUI.csproj

@@ -106,5 +106,4 @@
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
     </Content>
   </ItemGroup>
   </ItemGroup>
-  
 </Project>
 </Project>

+ 4 - 0
src/PixiEditor.AvaloniaUI/Styles/PortingWipStyles.axaml

@@ -82,4 +82,8 @@
     <Style Selector="Button.SocialMediaButton:pointerover">
     <Style Selector="Button.SocialMediaButton:pointerover">
         <Setter Property="Background" Value="{Binding Tag, RelativeSource={RelativeSource Self}}"/>
         <Setter Property="Background" Value="{Binding Tag, RelativeSource={RelativeSource Self}}"/>
     </Style>
     </Style>
+
+    <Style Selector="ToggleButton.AnchorPointToggleButtonStyle">
+
+    </Style>
 </Styles>
 </Styles>

+ 1 - 0
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/ViewOptionsViewModel.cs

@@ -1,5 +1,6 @@
 using Avalonia.Input;
 using Avalonia.Input;
 using PixiEditor.AvaloniaUI.Models.Commands.Attributes.Commands;
 using PixiEditor.AvaloniaUI.Models.Commands.Attributes.Commands;
+using PixiEditor.DrawingApi.Core.Numerics;
 
 
 namespace PixiEditor.AvaloniaUI.ViewModels.SubViewModels;
 namespace PixiEditor.AvaloniaUI.ViewModels.SubViewModels;
 #nullable enable
 #nullable enable

+ 0 - 4
src/PixiEditor.AvaloniaUI/Views/Dialogs/ConfirmationPopup.axaml

@@ -4,12 +4,8 @@
                  xmlns="https://github.com/avaloniaui"
                  xmlns="https://github.com/avaloniaui"
                  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-                 xmlns:views="clr-namespace:PixiEditor.Views"
                  xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
                  xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
-                 xmlns:controls="https://github.com/avaloniaui"
                  xmlns:system="clr-namespace:System;assembly=System.Runtime"
                  xmlns:system="clr-namespace:System;assembly=System.Runtime"
-                 xmlns:markupExtensions="clr-namespace:PixiEditor.AvaloniaUI.Helpers.MarkupExtensions"
-                 xmlns:behaviours="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Behaviours"
                  xmlns:dialogs1="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
                  xmlns:dialogs1="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
                  mc:Ignorable="d" d:Title="Unsaved changes"
                  mc:Ignorable="d" d:Title="Unsaved changes"
                  Name="popup"
                  Name="popup"

+ 1 - 3
src/PixiEditor.AvaloniaUI/Views/Dialogs/DialogTitleBar.axaml

@@ -5,10 +5,7 @@
     xmlns="https://github.com/avaloniaui"
     xmlns="https://github.com/avaloniaui"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:views="clr-namespace:PixiEditor.Views"
     xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
     xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
-    xmlns:controls="https://github.com/avaloniaui"
-    xmlns:vm="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
     xmlns:converters="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Converters"
     xmlns:converters="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Converters"
     mc:Ignorable="d"
     mc:Ignorable="d"
     x:Name="uc"
     x:Name="uc"
@@ -59,6 +56,7 @@
                 Theme="{StaticResource DialogButtonTheme}"
                 Theme="{StaticResource DialogButtonTheme}"
                 IsVisible="{Binding ElementName=uc, Path=CanMinimize}"
                 IsVisible="{Binding ElementName=uc, Path=CanMinimize}"
                 ui:Translator.TooltipKey="MINIMIZE"
                 ui:Translator.TooltipKey="MINIMIZE"
+                Padding="0, 0, 0, 5"
                 Click="MinimizeWindow">
                 Click="MinimizeWindow">
                 🗕
                 🗕
             </Button>
             </Button>

+ 0 - 3
src/PixiEditor.AvaloniaUI/Views/Dialogs/ExportFilePopup.axaml

@@ -1,10 +1,7 @@
 <dialogs:PixiEditorPopup xmlns="https://github.com/avaloniaui"
 <dialogs:PixiEditorPopup xmlns="https://github.com/avaloniaui"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         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:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
         xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
         xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input"
         xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input"
-        xmlns:ui="clr-namespace:PixiEditor.AvaloniaUI.Helpers.UI"
         xmlns:ui1="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
         xmlns:ui1="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
         CanResize="False"
         CanResize="False"
         CanMinimize="False"
         CanMinimize="False"

+ 2 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/NewFilePopup.axaml

@@ -24,6 +24,8 @@
 
 
         <input:SizePicker HorizontalAlignment="Center" MinWidth="230" Height="125" Margin="15,30,15,0"
         <input:SizePicker HorizontalAlignment="Center" MinWidth="230" Height="125" Margin="15,30,15,0"
                           PreserveAspectRatio="False"
                           PreserveAspectRatio="False"
+                          Background="{DynamicResource ThemeBackgroundBrush1}"
+                          CornerRadius="{DynamicResource ControlCornerRadius}"
                           ChosenHeight="{Binding FileHeight, Mode=TwoWay, ElementName=popup}"
                           ChosenHeight="{Binding FileHeight, Mode=TwoWay, ElementName=popup}"
                           ChosenWidth="{Binding FileWidth, Mode=TwoWay, ElementName=popup}"
                           ChosenWidth="{Binding FileWidth, Mode=TwoWay, ElementName=popup}"
                           x:Name="sizePicker"/>
                           x:Name="sizePicker"/>

+ 0 - 2
src/PixiEditor.AvaloniaUI/Views/Dialogs/NoticePopup.axaml

@@ -5,8 +5,6 @@
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
         xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
-        xmlns:controls="https://github.com/avaloniaui"
-        xmlns:markupExtensions="clr-namespace:PixiEditor.AvaloniaUI.Helpers.MarkupExtensions"
         xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
         xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
         mc:Ignorable="d"
         mc:Ignorable="d"
         d:Title="Notice" Height="180" Width="400" MinHeight="180" MinWidth="400"
         d:Title="Notice" Height="180" Width="400" MinHeight="180" MinWidth="400"

+ 0 - 1
src/PixiEditor.AvaloniaUI/Views/Dialogs/OptionPopup.axaml

@@ -5,7 +5,6 @@
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:local="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
     xmlns:local="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
     xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
     xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
-    xmlns:markupExtensions="clr-namespace:PixiEditor.AvaloniaUI.Helpers.MarkupExtensions"
     xmlns:panels="clr-namespace:PixiEditor.AvaloniaUI.Views.Panels"
     xmlns:panels="clr-namespace:PixiEditor.AvaloniaUI.Views.Panels"
     mc:Ignorable="d"
     mc:Ignorable="d"
     d:DesignWidth="800"
     d:DesignWidth="800"

+ 46 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/ResizeCanvasPopup.axaml

@@ -0,0 +1,46 @@
+<dialogs:ResizeCanvasPopup x:Class="PixiEditor.AvaloniaUI.Views.Dialogs.ResizeCanvasPopup"
+                         x:ClassModifier="internal"
+                         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:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
+                         xmlns:windows="clr-namespace:PixiEditor.AvaloniaUI.Views.Windows"
+                         xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input"
+                         xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
+                         mc:Ignorable="d"
+                         Name="window"
+                         Title="RESIZE_CANVAS"
+                         Height="420" Width="320" MinHeight="420" MinWidth="320">
+    <DockPanel Focusable="True">
+        <Button DockPanel.Dock="Bottom" Padding="5 0" HorizontalAlignment="Center" Margin="15"
+                ui:Translator.Key="RESIZE" Click="Button_Click"
+                IsDefault="True" />
+
+        <Border HorizontalAlignment="Center" Margin="0,30,0,0" Background="{DynamicResource ThemeBackgroundBrush}"
+                VerticalAlignment="Top" Grid.Row="1" Width="250" Height="290" CornerRadius="10">
+            <StackPanel>
+                <input:SizePicker Margin="0,8,0,0"
+                                         Width="240"
+                                         Height="170"
+                                         x:Name="sizePicker"
+                                         Focusable="True"
+                                         ChosenHeight="{Binding NewAbsoluteHeight, Mode=TwoWay, ElementName=window}"
+                                         ChosenWidth="{Binding NewAbsoluteWidth, Mode=TwoWay, ElementName=window}"
+                                         ChosenPercentageSize="{Binding NewPercentageSize, Mode=TwoWay, ElementName=window}"
+                                         SelectedUnit="{ Binding NewSelectedUnit, Mode=TwoWay, ElementName=window}"
+                                         IsSizeUnitSelectionVisible="True" />
+                <Separator Margin="10,5,10,0" Background="{StaticResource AccentColor}" Height="1" />
+                <DockPanel>
+                    <Label ui:Translator.Key="ANCHOR_POINT" Foreground="White" Margin="25,5,0,0"
+                           HorizontalAlignment="Left"
+                           FontSize="12" />
+                    <input:AnchorPointPicker
+                        AnchorPoint="{Binding Path=SelectedAnchorPoint, Mode=TwoWay, ElementName=window}"
+                        HorizontalAlignment="Right"
+                        Width="78" Margin="0,10,30,0" Height="78" />
+                </DockPanel>
+            </StackPanel>
+        </Border>
+    </DockPanel>
+</dialogs:ResizeCanvasPopup>

+ 31 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/ResizeCanvasPopup.axaml.cs

@@ -0,0 +1,31 @@
+using Avalonia;
+using Avalonia.Interactivity;
+using PixiEditor.ChangeableDocument.Enums;
+
+namespace PixiEditor.AvaloniaUI.Views.Dialogs;
+
+/// <summary>
+///     Interaction logic for ResizeCanvasPopup.xaml
+/// </summary>
+internal partial class ResizeCanvasPopup : ResizeablePopup
+{
+    public static readonly StyledProperty<ResizeAnchor> SelectedAnchorPointProperty =
+        AvaloniaProperty.Register<ResizeCanvasPopup, ResizeAnchor>(nameof(SelectedAnchorPoint), ResizeAnchor.TopLeft);
+
+    public ResizeAnchor SelectedAnchorPoint
+    {
+        get => GetValue(SelectedAnchorPointProperty);
+        set => SetValue(SelectedAnchorPointProperty, value);
+    }
+
+    public ResizeCanvasPopup()
+    {
+        InitializeComponent();
+        Loaded += (_, _) => sizePicker.FocusWidthPicker();
+    }
+
+    private void Button_Click(object sender, RoutedEventArgs e)
+    {
+        Close(true);
+    }
+}

+ 29 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/ResizeDocumentPopup.axaml

@@ -0,0 +1,29 @@
+<dialogs:ResizeDocumentPopup x:Class="PixiEditor.AvaloniaUI.Views.Dialogs.ResizeDocumentPopup"
+                      x:ClassModifier="internal"
+                      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:userControls="clr-namespace:PixiEditor.Views.UserControls"
+                      xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
+        xmlns:windows="clr-namespace:PixiEditor.AvaloniaUI.Views.Windows"
+        xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input"
+        xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
+        mc:Ignorable="d" Name="window"
+                      Title="RESIZE_IMAGE"
+                      Height="305" Width="310" MinHeight="305" MinWidth="310">
+    <DockPanel Focusable="True">
+        <Button DockPanel.Dock="Bottom" Padding="5 0" HorizontalAlignment="Center" Margin="15"
+                ui:Translator.Key="RESIZE" Click="Button_Click" IsDefault="True" />
+
+        <input:SizePicker HorizontalAlignment="Center" Width="240" Height="180" Margin="0,30,0,0"
+            x:Name="sizePicker"
+            PreserveAspectRatio="True" Focusable="True"
+            ChosenHeight="{Binding NewAbsoluteHeight, Mode=TwoWay, ElementName=window}"
+            ChosenWidth="{Binding NewAbsoluteWidth, Mode=TwoWay, ElementName=window}" 
+            ChosenPercentageSize="{Binding NewPercentageSize, Mode=TwoWay, ElementName=window}"
+            SelectedUnit="{Binding NewSelectedUnit, Mode=TwoWay, ElementName=window}"
+            IsSizeUnitSelectionVisible="True"/>
+
+    </DockPanel>
+</dialogs:ResizeDocumentPopup>

+ 21 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/ResizeDocumentPopup.axaml.cs

@@ -0,0 +1,21 @@
+using Avalonia.Interactivity;
+
+namespace PixiEditor.AvaloniaUI.Views.Dialogs;
+
+/// <summary>
+///     Interaction logic for ResizeDocumentPopup.xaml
+/// </summary>
+internal partial class ResizeDocumentPopup : ResizeablePopup
+{
+    public ResizeDocumentPopup()
+    {
+        InitializeComponent();
+        DataContext = this;
+        Loaded += (_, _) => sizePicker.FocusWidthPicker();
+    }
+
+    private void Button_Click(object sender, RoutedEventArgs e)
+    {
+        Close(true);
+    }
+}

+ 44 - 0
src/PixiEditor.AvaloniaUI/Views/Dialogs/ResizeablePopup.cs

@@ -0,0 +1,44 @@
+using Avalonia;
+using Avalonia.Styling;
+using PixiEditor.AvaloniaUI.Models.Dialogs;
+
+namespace PixiEditor.AvaloniaUI.Views.Dialogs;
+
+internal class ResizeablePopup : PixiEditorPopup, IStyleable
+{
+    public static readonly StyledProperty<int> NewPercentageSizeProperty =
+        AvaloniaProperty.Register<ResizeablePopup, int>(nameof(NewPercentageSize), 0);
+
+    public static readonly StyledProperty<SizeUnit> NewSelectedUnitProperty =
+        AvaloniaProperty.Register<ResizeablePopup, SizeUnit>(nameof(NewSelectedUnit), SizeUnit.Pixel);
+
+    public static readonly StyledProperty<int> NewAbsoluteHeightProperty =
+        AvaloniaProperty.Register<ResizeablePopup, int>(nameof(NewAbsoluteHeight), 0);
+
+    public static readonly StyledProperty<int> NewAbsoluteWidthProperty =
+        AvaloniaProperty.Register<ResizeablePopup, int>(nameof(NewAbsoluteWidth), 0);
+
+    public int NewPercentageSize
+    {
+        get => GetValue(NewPercentageSizeProperty);
+        set => SetValue(NewPercentageSizeProperty, value);
+    }
+
+    public SizeUnit NewSelectedUnit
+    {
+        get => GetValue(NewSelectedUnitProperty);
+        set => SetValue(NewSelectedUnitProperty, value);
+    }
+
+    public int NewAbsoluteHeight
+    {
+        get => GetValue(NewAbsoluteHeightProperty);
+        set => SetValue(NewAbsoluteHeightProperty, value);
+    }
+
+    public int NewAbsoluteWidth
+    {
+        get => GetValue(NewAbsoluteWidthProperty);
+        set => SetValue(NewAbsoluteWidthProperty, value);
+    }
+}

+ 87 - 0
src/PixiEditor.AvaloniaUI/Views/Input/AnchorPointPicker.axaml

@@ -0,0 +1,87 @@
+<controls:UserControl x:Class="PixiEditor.AvaloniaUI.Views.Input.AnchorPointPicker"
+             x:ClassModifier="internal"
+             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:views="clr-namespace:PixiEditor.Views"
+             xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
+             xmlns:controls="https://github.com/avaloniaui"
+             mc:Ignorable="d"
+             d:DesignHeight="78" d:DesignWidth="78">
+    <Grid Name="container">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="26" />
+            <RowDefinition Height="26" />
+            <RowDefinition Height="26" />
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="26" />
+            <ColumnDefinition Width="26" />
+            <ColumnDefinition Width="26" />
+        </Grid.ColumnDefinitions>
+        <ToggleButton IsChecked="True" Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" ui:Translator.TooltipKey="TOP_LEFT" Grid.Row="0"
+                      Grid.Column="0" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="0" ui:Translator.TooltipKey="TOP_CENTER"
+                      Grid.Column="1" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" ui:Translator.TooltipKey="TOP_RIGHT" Grid.Row="0"
+                      Grid.Column="2" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="1" ui:Translator.TooltipKey="MIDDLE_LEFT"
+                      Grid.Column="0" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="1" Grid.Column="1"
+                      ui:Translator.TooltipKey="MIDDLE_CENTER" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="1" Grid.Column="2"
+                      ui:Translator.TooltipKey="MIDDLE_RIGHT" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="2" Grid.Column="0"
+                      ui:Translator.TooltipKey="BOTTOM_LEFT" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="2" Grid.Column="1"
+                      ui:Translator.TooltipKey="BOTTOM_CENTER" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+        <ToggleButton Checked="ToggleButton_Checked" PointerPressed="ToggleButton_Click" Margin="0.25"
+                      Classes="AnchorPointToggleButtonStyle" Grid.Row="2" Grid.Column="2"
+                      ui:Translator.TooltipKey="BOTTOM_RIGHT" BorderBrush="Black">
+            <ToggleButton.Background>
+                <ImageBrush Source="../../Images/AnchorDot.png" />
+            </ToggleButton.Background>
+        </ToggleButton>
+    </Grid>
+</controls:UserControl>

+ 59 - 0
src/PixiEditor.AvaloniaUI/Views/Input/AnchorPointPicker.axaml.cs

@@ -0,0 +1,59 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using PixiEditor.ChangeableDocument.Enums;
+
+namespace PixiEditor.AvaloniaUI.Views.Input;
+
+/// <summary>
+///     Interaction logic for AnchorPointPicker.xaml
+/// </summary>
+internal partial class AnchorPointPicker : UserControl
+{
+    public static readonly StyledProperty<ResizeAnchor> AnchorPointProperty =
+        AvaloniaProperty.Register<AnchorPointPicker, ResizeAnchor>(nameof(AnchorPoint), ResizeAnchor.TopLeft);
+
+    public ResizeAnchor AnchorPoint
+    {
+        get => GetValue(AnchorPointProperty);
+        set => SetValue(AnchorPointProperty, value);
+    }
+
+
+    private ToggleButton _selectedToggleButton;
+
+    public AnchorPointPicker()
+    {
+        InitializeComponent();
+    }
+
+    private void ToggleButton_Checked(object sender, RoutedEventArgs e)
+    {
+        ToggleButton btn = (ToggleButton)sender;
+        int row = Grid.GetRow(btn);
+        int column = Grid.GetColumn(btn);
+        AnchorPoint = (column, row) switch
+        {
+            (0, 0) => ResizeAnchor.TopLeft,
+            (1, 0) => ResizeAnchor.Top,
+            (2, 0) => ResizeAnchor.TopRight,
+            (0, 1) => ResizeAnchor.Left,
+            (1, 1) => ResizeAnchor.Center,
+            (2, 1) => ResizeAnchor.Right,
+            (0, 2) => ResizeAnchor.BottomLeft,
+            (1, 2) => ResizeAnchor.Bottom,
+            (2, 2) => ResizeAnchor.BottomRight,
+            _ => throw new NotImplementedException()
+        };
+        if (_selectedToggleButton != null) _selectedToggleButton.IsChecked = false;
+        _selectedToggleButton = btn;
+    }
+
+    private void ToggleButton_Click(object sender, PointerPressedEventArgs e)
+    {
+        if ((sender as ToggleButton).IsChecked.Value)
+            e.Handled = true;
+    }
+}

+ 9 - 1
src/PixiEditor.AvaloniaUI/Views/Main/Viewport.axaml.cs

@@ -12,6 +12,7 @@ using ChunkyImageLib.DataHolders;
 using Hardware.Info;
 using Hardware.Info;
 using PixiEditor.AvaloniaUI.Helpers.UI;
 using PixiEditor.AvaloniaUI.Helpers.UI;
 using PixiEditor.AvaloniaUI.Models.Controllers.InputDevice;
 using PixiEditor.AvaloniaUI.Models.Controllers.InputDevice;
+using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Position;
 using PixiEditor.AvaloniaUI.Models.Position;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
@@ -306,6 +307,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         this.Bind(BitmapsProperty, binding);
         this.Bind(BitmapsProperty, binding);
 
 
         MainImage!.Loaded += OnImageLoaded;
         MainImage!.Loaded += OnImageLoaded;
+        MainImage.SizeChanged += OnMainImageSizeChanged;
         Loaded += OnLoad;
         Loaded += OnLoad;
         Unloaded += OnUnload;
         Unloaded += OnUnload;
 
 
@@ -346,7 +348,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     private static void OnBitmapsChange(AvaloniaPropertyChangedEventArgs<Dictionary<ChunkResolution, WriteableBitmap>?> e)
     private static void OnBitmapsChange(AvaloniaPropertyChangedEventArgs<Dictionary<ChunkResolution, WriteableBitmap>?> e)
     {
     {
         Viewport viewportObj = (Viewport)e.Sender;
         Viewport viewportObj = (Viewport)e.Sender;
-        ((Viewport)viewportObj).PropertyChanged?.Invoke(viewportObj, new(nameof(TargetBitmap)));
+        viewportObj.PropertyChanged?.Invoke(viewportObj, new(nameof(TargetBitmap)));
     }
     }
 
 
     private ChunkResolution CalculateResolution()
     private ChunkResolution CalculateResolution()
@@ -440,6 +442,12 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     {
     {
         zoombox.CenterContent();
         zoombox.CenterContent();
     }
     }
+
+    private void OnMainImageSizeChanged(object? sender, SizeChangedEventArgs e)
+    {
+        if (zoombox.Dimensions is { X: 0, Y: 0 }) return;
+        zoombox.CenterContent(new VecD(e.NewSize.Width, e.NewSize.Height));
+    }
     
     
     private void ResetViewportClicked(object sender, RoutedEventArgs e)
     private void ResetViewportClicked(object sender, RoutedEventArgs e)
     {
     {

+ 1 - 1
src/PixiEditor.AvaloniaUI/Views/Panels/AlignableWrapPanel.cs

@@ -15,7 +15,7 @@ internal class AlignableWrapPanel : Panel
     public static readonly StyledProperty<HorizontalAlignment> HorizontalContentAlignmentProperty =
     public static readonly StyledProperty<HorizontalAlignment> HorizontalContentAlignmentProperty =
         AvaloniaProperty.Register<AlignableWrapPanel, HorizontalAlignment>(
         AvaloniaProperty.Register<AlignableWrapPanel, HorizontalAlignment>(
             nameof(HorizontalContentAlignment),
             nameof(HorizontalContentAlignment),
-            HorizontalAlignment.Left);//TODO: AffectedArrange was here
+            HorizontalAlignment.Left);
 
 
     static AlignableWrapPanel()
     static AlignableWrapPanel()
     {
     {