Răsfoiți Sursa

Prevent you from putting a folder inside of itself, add blend mode dropdown

Equbuxu 3 ani în urmă
părinte
comite
ac60da3d59

+ 5 - 5
src/PixiEditor/Models/DocumentModels/DocumentStructureHelper.cs

@@ -117,7 +117,7 @@ internal class DocumentStructureHelper
 
     private void HandleMoveInside(List<StructureMemberViewModel> memberToMovePath, List<StructureMemberViewModel> memberToMoveIntoPath)
     {
-        if (memberToMoveIntoPath[0] is not FolderViewModel folder)
+        if (memberToMoveIntoPath[0] is not FolderViewModel folder || memberToMoveIntoPath.Contains(memberToMovePath[0]))
             return;
         int index = folder.Children.Count;
         if (memberToMoveIntoPath[0].GuidValue == memberToMovePath[1].GuidValue) // member is already in this folder
@@ -130,8 +130,7 @@ internal class DocumentStructureHelper
     {
         FolderViewModel targetFolder = (FolderViewModel)memberToMoveRelativeToPath[1];
         if (memberToMovePath[1].GuidValue == memberToMoveRelativeToPath[1].GuidValue)
-        {
-            // members are in the same folder
+        { // members are in the same folder
             int indexOfMemberToMove = targetFolder.Children.IndexOf(memberToMovePath[0]);
             int indexOfMemberToMoveAbove = targetFolder.Children.IndexOf(memberToMoveRelativeToPath[0]);
             int index = indexOfMemberToMoveAbove;
@@ -142,8 +141,9 @@ internal class DocumentStructureHelper
             helpers.ActionAccumulator.AddFinishedActions(new MoveStructureMember_Action(memberToMovePath[0].GuidValue, targetFolder.GuidValue, index));
         }
         else
-        {
-            // members are in different folders
+        { // members are in different folders
+            if (memberToMoveRelativeToPath.Contains(memberToMovePath[0]))
+                return;
             int index = targetFolder.Children.IndexOf(memberToMoveRelativeToPath[0]);
             if (above)
                 index++;

+ 44 - 36
src/PixiEditor/Views/UserControls/Layers/LayersManager.xaml

@@ -18,38 +18,39 @@
              d:DesignHeight="450" d:DesignWidth="250" x:Name="layersManager">
     <Grid>
         <Grid.RowDefinitions>
-            <RowDefinition Height="37.5"/>
+            <RowDefinition Height="75"/>
             <RowDefinition Height="15"/>
             <RowDefinition Height="1*"/>
         </Grid.RowDefinitions>
-        <DockPanel Background="{StaticResource MainColor}" Grid.Row="0" HorizontalAlignment="Stretch">
-            <StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
-                <Button Command="{commands:Command PixiEditor.Layer.NewLayer}" 
+        <StackPanel Grid.Row="0" HorizontalAlignment="Stretch" Background="{StaticResource MainColor}">
+            <DockPanel  HorizontalAlignment="Stretch">
+                <StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
+                    <Button Command="{commands:Command PixiEditor.Layer.NewLayer}" 
                         Height="24" Width="24" Cursor="Hand" ToolTip="New Layer"
                                                 HorizontalAlignment="Stretch" Margin="5"
                                                 Style="{StaticResource ToolButtonStyle}">
-                    <Button.Background>
-                        <ImageBrush ImageSource="/Images/Layer-add.png"/>
-                    </Button.Background>
-                </Button>
-                <Button Command="{commands:Command PixiEditor.Layer.NewFolder}" 
+                        <Button.Background>
+                            <ImageBrush ImageSource="/Images/Layer-add.png"/>
+                        </Button.Background>
+                    </Button>
+                    <Button Command="{commands:Command PixiEditor.Layer.NewFolder}" 
                         Height="24" Width="24" ToolTip="New Group" Cursor="Hand"
                                                 HorizontalAlignment="Stretch" Margin="5"
                                                 Style="{StaticResource ToolButtonStyle}">
-                    <Button.Background>
-                        <ImageBrush ImageSource="/Images/Folder-add.png"/>
-                    </Button.Background>
-                </Button>
-                <Button Command="{commands:Command PixiEditor.Layer.DeleteSelected}" Height="24" Width="24" ToolTip="Delete selected" Cursor="Hand"
+                        <Button.Background>
+                            <ImageBrush ImageSource="/Images/Folder-add.png"/>
+                        </Button.Background>
+                    </Button>
+                    <Button Command="{commands:Command PixiEditor.Layer.DeleteSelected}" Height="24" Width="24" ToolTip="Delete selected" Cursor="Hand"
                                                 HorizontalAlignment="Stretch" Margin="5"
                                                 Style="{StaticResource ToolButtonStyle}">
-                    <Button.Background>
-                        <ImageBrush ImageSource="/Images/Trash.png"/>
-                    </Button.Background>
-                </Button>
-            </StackPanel>
-            <StackPanel Orientation="Horizontal" DockPanel.Dock="Right" Margin="0,0,10,0" HorizontalAlignment="Right" Focusable="True">
-                <Slider
+                        <Button.Background>
+                            <ImageBrush ImageSource="/Images/Trash.png"/>
+                        </Button.Background>
+                    </Button>
+                </StackPanel>
+                <StackPanel Orientation="Horizontal" DockPanel.Dock="Right" Margin="0,0,10,0" HorizontalAlignment="Right" Focusable="True">
+                    <Slider
                     Width="50"
                     Minimum="0"
                     Maximum="1"
@@ -60,36 +61,43 @@
                     VerticalAlignment="Center"
                     HorizontalAlignment="Stretch"
                     Value="{Binding ElementName=layersManager, Path=ActiveDocument.SelectedStructureMember.OpacityBindable, Mode=OneWay}">
-                    <i:Interaction.Behaviors>
-                        <beh:SliderUpdateBehavior
+                        <i:Interaction.Behaviors>
+                            <beh:SliderUpdateBehavior
                             DragStarted="{commands:Command PixiEditor.Layer.OpacitySliderDragStarted}"
                             DragValueChanged="{commands:Command PixiEditor.Layer.OpacitySliderDragged, UseProvided=True}"
                             DragEnded="{commands:Command PixiEditor.Layer.OpacitySliderDragEnded}"
                             ValueFromSlider="{Binding ElementName=opacitySlider, Path=Value}" />
-                    </i:Interaction.Behaviors>
-                </Slider>
-                <userControls:NumberInput
+                        </i:Interaction.Behaviors>
+                    </Slider>
+                    <userControls:NumberInput
                     Min="0" Max="100"
                     x:Name="numberInput"
                     IsEnabled="{Binding Path=ActiveDocument, ElementName=layersManager, Converter={converters:NotNullToVisibilityConverter}}" 
                     Width="40" Height="20"
                     VerticalAlignment="Center"
                     LostFocus="NumberInput_LostFocus">
-                    <userControls:NumberInput.Value>
-                        <Binding
+                        <userControls:NumberInput.Value>
+                            <Binding
                             Mode="TwoWay"
                             ElementName="layersManager"
                             Path="ActiveDocument.SelectedStructureMember.OpacityBindable"
                             Converter="{converters:MultiplyConverter}">
-                            <Binding.ConverterParameter>
-                                <sys:Double>100</sys:Double>
-                            </Binding.ConverterParameter>
-                        </Binding>
-                    </userControls:NumberInput.Value>
-                </userControls:NumberInput>
-                <Label Content="%" Foreground="White" VerticalAlignment="Center"/>
+                                <Binding.ConverterParameter>
+                                    <sys:Double>100</sys:Double>
+                                </Binding.ConverterParameter>
+                            </Binding>
+                        </userControls:NumberInput.Value>
+                    </userControls:NumberInput>
+                    <Label Content="%" Foreground="White" VerticalAlignment="Center"/>
+                </StackPanel>
+            </DockPanel>
+            <StackPanel Orientation="Horizontal">
+                <userControls:BlendModeComboBox
+                            Margin="5,0"
+                            Width="80"
+                            SelectedBlendMode="{Binding ActiveDocument.SelectedStructureMember.BlendModeBindable, Mode=TwoWay, ElementName=layersManager}" />
             </StackPanel>
-        </DockPanel>
+        </StackPanel>
         <Separator Grid.Row="1" Margin="0,-12, 0, 0" BorderBrush="{StaticResource DarkerAccentColor}" BorderThickness="2" />
         <DockPanel LastChildFill="True" Grid.Row="2" Margin="0, -12, 0, 0">
             <layerUserControls:ReferenceLayer

+ 16 - 16
src/PixiEditorPrototype/Models/DocumentStructureHelper.cs

@@ -17,10 +17,10 @@ internal class DocumentStructureHelper
 
     public void CreateNewStructureMember(StructureMemberType type)
     {
-        var member = doc.FindFirstSelectedMember();
+        StructureMemberViewModel? member = doc.FindFirstSelectedMember();
         if (member is null)
         {
-            var guid = Guid.NewGuid();
+            Guid guid = Guid.NewGuid();
             //put member on top
             helpers.ActionAccumulator.AddActions(new CreateStructureMember_Action(doc.StructureRoot.GuidValue, guid, doc.StructureRoot.Children.Count, type));
             helpers.ActionAccumulator.AddFinishedActions(new StructureMemberName_Action(guid, type == StructureMemberType.Layer ? "New Layer" : "New Folder"));
@@ -28,7 +28,7 @@ internal class DocumentStructureHelper
         }
         if (member is FolderViewModel folder)
         {
-            var guid = Guid.NewGuid();
+            Guid guid = Guid.NewGuid();
             //put member inside folder on top
             helpers.ActionAccumulator.AddActions(new CreateStructureMember_Action(folder.GuidValue, guid, folder.Children.Count, type));
             helpers.ActionAccumulator.AddFinishedActions(new StructureMemberName_Action(guid, type == StructureMemberType.Layer ? "New Layer" : "New Folder"));
@@ -36,12 +36,12 @@ internal class DocumentStructureHelper
         }
         if (member is LayerViewModel layer)
         {
-            var guid = Guid.NewGuid();
+            Guid guid = Guid.NewGuid();
             //put member above the layer
-            var path = FindPath(layer.GuidValue);
+            List<StructureMemberViewModel>? path = FindPath(layer.GuidValue);
             if (path.Count < 2)
                 throw new InvalidOperationException("Couldn't find a path to the selected member");
-            var parent = (FolderViewModel)path[1];
+            FolderViewModel? parent = (FolderViewModel)path[1];
             helpers.ActionAccumulator.AddActions(new CreateStructureMember_Action(parent.GuidValue, guid, parent.Children.IndexOf(layer) + 1, type));
             helpers.ActionAccumulator.AddFinishedActions(new StructureMemberName_Action(guid, type == StructureMemberType.Layer ? "New Layer" : "New Folder"));
             return;
@@ -52,7 +52,7 @@ internal class DocumentStructureHelper
     public StructureMemberViewModel FindOrThrow(Guid guid) => Find(guid) ?? throw new ArgumentException("Could not find member with guid " + guid.ToString());
     public StructureMemberViewModel? Find(Guid guid)
     {
-        var list = FindPath(guid);
+        List<StructureMemberViewModel>? list = FindPath(guid);
         return list.Count > 0 ? list[0] : null;
     }
 
@@ -62,13 +62,13 @@ internal class DocumentStructureHelper
     }
     private StructureMemberViewModel? FindFirstWhere(Predicate<StructureMemberViewModel> predicate, FolderViewModel folderVM)
     {
-        foreach (var child in folderVM.Children)
+        foreach (StructureMemberViewModel? child in folderVM.Children)
         {
             if (predicate(child))
                 return child;
             if (child is FolderViewModel innerFolderVM)
             {
-                var result = FindFirstWhere(predicate, innerFolderVM);
+                StructureMemberViewModel? result = FindFirstWhere(predicate, innerFolderVM);
                 if (result is not null)
                     return result;
             }
@@ -78,14 +78,14 @@ internal class DocumentStructureHelper
 
     public (StructureMemberViewModel, FolderViewModel) FindChildAndParentOrThrow(Guid childGuid)
     {
-        var path = FindPath(childGuid);
+        List<StructureMemberViewModel>? path = FindPath(childGuid);
         if (path.Count < 2)
             throw new ArgumentException("Couldn't find child and parent");
         return (path[0], (FolderViewModel)path[1]);
     }
     public List<StructureMemberViewModel> FindPath(Guid guid)
     {
-        var list = new List<StructureMemberViewModel>();
+        List<StructureMemberViewModel>? list = new List<StructureMemberViewModel>();
         if (FillPath(doc.StructureRoot, guid, list))
             list.Add(doc.StructureRoot);
         return list;
@@ -97,7 +97,7 @@ internal class DocumentStructureHelper
         {
             return true;
         }
-        foreach (var member in folder.Children)
+        foreach (StructureMemberViewModel? member in folder.Children)
         {
             if (member is LayerViewModel childLayer && childLayer.GuidValue == guid)
             {
@@ -118,20 +118,20 @@ internal class DocumentStructureHelper
 
     public void MoveStructureMember(Guid guid, bool toSmallerIndex)
     {
-        var path = FindPath(guid);
+        List<StructureMemberViewModel>? path = FindPath(guid);
         if (path.Count < 2)
             throw new ArgumentException("Couldn't find the member to be moved");
         if (path.Count == 2)
         {
             int curIndex = doc.StructureRoot.Children.IndexOf(path[0]);
-            if (curIndex == 0 && toSmallerIndex || curIndex == doc.StructureRoot.Children.Count - 1 && !toSmallerIndex)
+            if ((curIndex == 0 && toSmallerIndex) || (curIndex == doc.StructureRoot.Children.Count - 1 && !toSmallerIndex))
                 return;
             helpers.ActionAccumulator.AddFinishedActions(new MoveStructureMember_Action(guid, doc.StructureRoot.GuidValue, toSmallerIndex ? curIndex - 1 : curIndex + 1));
             return;
         }
-        var folder = (FolderViewModel)path[1];
+        FolderViewModel? folder = (FolderViewModel)path[1];
         int index = folder.Children.IndexOf(path[0]);
-        if (toSmallerIndex && index > 0 || !toSmallerIndex && index < folder.Children.Count - 1)
+        if ((toSmallerIndex && index > 0) || (!toSmallerIndex && index < folder.Children.Count - 1))
         {
             helpers.ActionAccumulator.AddFinishedActions(new MoveStructureMember_Action(guid, path[1].GuidValue, toSmallerIndex ? index - 1 : index + 1));
         }