ソースを参照

Improved color picking behaviour when reference layer is set to top most

CPKreuz 2 年 前
コミット
ad4fdb9bb9

+ 3 - 3
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/ColorPickerToolExecutor.cs

@@ -24,7 +24,7 @@ internal class ColorPickerToolExecutor : UpdateableChangeExecutor
         includeReference = tool.PickFromReferenceLayer && document!.ReferenceLayerViewModel.ReferenceBitmap is not null;
         includeCanvas = tool.PickFromCanvas;
         
-        colorsViewModel.PrimaryColor = document.PickColor(controller.LastPrecisePosition, scope, includeReference, includeCanvas);
+        colorsViewModel.PrimaryColor = document.PickColor(controller.LastPrecisePosition, scope, includeReference, includeCanvas, document.ReferenceLayerViewModel.IsTopMost);
         return ExecutionState.Success;
     }
 
@@ -32,12 +32,12 @@ internal class ColorPickerToolExecutor : UpdateableChangeExecutor
     {
         if (!includeReference)
             return;
-        colorsViewModel.PrimaryColor = document.PickColor(pos, scope, includeReference, includeCanvas);
+        colorsViewModel.PrimaryColor = document.PickColor(pos, scope, includeReference, includeCanvas, document.ReferenceLayerViewModel.IsTopMost);
     }
 
     public override void OnPixelPositionChange(VecI pos)
     {
-        colorsViewModel.PrimaryColor = document.PickColor(pos, scope, includeReference, includeCanvas);
+        colorsViewModel.PrimaryColor = document.PickColor(pos, scope, includeReference, includeCanvas, document.ReferenceLayerViewModel.IsTopMost);
     }
 
     public override void OnLeftMouseButtonUp()

+ 15 - 4
src/PixiEditor/ViewModels/SubViewModels/Document/DocumentViewModel.cs

@@ -386,7 +386,8 @@ internal partial class DocumentViewModel : NotifyableObject
     /// </summary>
     /// <param name="includeReference">Should the color be picked from the reference layer</param>
     /// <param name="includeCanvas">Should the color be picked from the canvas</param>
-    public Color PickColor(VecD pos, DocumentScope scope, bool includeReference, bool includeCanvas)
+    /// <param name="referenceTopmost">Is the reference layer topmost. (Only affects the result is includeReference and includeCanvas are set.)</param>
+    public Color PickColor(VecD pos, DocumentScope scope, bool includeReference, bool includeCanvas, bool referenceTopmost = false)
     {
         if (scope == DocumentScope.SingleLayer && includeReference && includeCanvas)
             includeReference = false;
@@ -394,10 +395,20 @@ internal partial class DocumentViewModel : NotifyableObject
         if (includeCanvas && includeReference)
         {
             Color canvasColor = PickColorFromCanvas((VecI)pos, scope);
-            Color? referenceColor = PickColorFromReferenceLayer(pos);
-            if (referenceColor is null)
+            Color? potentialReferenceColor = PickColorFromReferenceLayer(pos);
+            if (potentialReferenceColor is not { } referenceColor)
                 return canvasColor;
-            return ColorHelpers.BlendColors((Color)referenceColor, canvasColor);
+
+            if (!referenceTopmost)
+            {
+                return ColorHelpers.BlendColors(referenceColor, canvasColor);
+            }
+
+            byte referenceAlpha = canvasColor.A == 0 ? referenceColor.A : (byte)(referenceColor.A * 0.6f);
+            
+            referenceColor = new Color(referenceColor.R, referenceColor.G, referenceColor.B, referenceAlpha);
+            return ColorHelpers.BlendColors(canvasColor, referenceColor);
+
         }
         if (includeCanvas)
             return PickColorFromCanvas((VecI)pos, scope);

+ 16 - 1
src/PixiEditor/ViewModels/SubViewModels/Document/ReferenceLayerViewModel.cs

@@ -8,6 +8,7 @@ using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Helpers;
 using PixiEditor.Models.DocumentModels;
+using PixiEditor.ViewModels.SubViewModels.Tools.Tools;
 
 namespace PixiEditor.ViewModels.SubViewModels.Document;
 
@@ -78,7 +79,7 @@ internal class ReferenceLayerViewModel : INotifyPropertyChanged
     
     public bool ShowHighest
     {
-        get => IsTopMost || IsTransforming;
+        get => (IsTopMost || IsTransforming) && !IsColorPickerSelected();
     }
 
     public ReferenceLayerViewModel(DocumentViewModel doc, DocumentInternalParts internals)
@@ -87,6 +88,18 @@ internal class ReferenceLayerViewModel : INotifyPropertyChanged
         this.internals = internals;
     }
 
+    private bool IsColorPickerSelected()
+    {
+        var viewModel = ViewModelMain.Current.ToolsSubViewModel;
+        
+        if (viewModel.ActiveTool is ColorPickerToolViewModel colorPicker)
+        {
+            return colorPicker.PickFromReferenceLayer && !colorPicker.PickFromCanvas;
+        }
+
+        return false;
+    }
+    
     private void RaisePropertyChanged(string name)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
@@ -94,6 +107,8 @@ internal class ReferenceLayerViewModel : INotifyPropertyChanged
     
     #region Internal methods
 
+    public void RaiseShowHighestChanged() => RaisePropertyChanged(nameof(ShowHighest));
+    
     public void InternalSetReferenceLayer(ImmutableArray<byte> imagePbgra32Bytes, VecI imageSize, ShapeCorners shape)
     {
         ReferenceBitmap = WriteableBitmapHelpers.FromPbgra32Array(imagePbgra32Bytes.ToArray(), imageSize);

+ 2 - 0
src/PixiEditor/ViewModels/SubViewModels/Tools/Tools/ColorPickerToolViewModel.cs

@@ -68,5 +68,7 @@ internal class ColorPickerToolViewModel : ToolViewModel
             PickFromReferenceLayer = true;
             ActionDisplay = defaultActionDisplay;
         }
+        
+        ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.ReferenceLayerViewModel.RaiseShowHighestChanged();
     }
 }