|
@@ -1,5 +1,6 @@
|
|
|
using PixiEditor.Models.Controllers;
|
|
|
using PixiEditor.Models.DataHolders;
|
|
|
+using PixiEditor.Models.ImageManipulation;
|
|
|
using PixiEditor.Models.Layers;
|
|
|
using PixiEditor.Models.Position;
|
|
|
using PixiEditor.Models.Services;
|
|
@@ -17,22 +18,23 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
{
|
|
|
private readonly DocumentProvider _docProvider;
|
|
|
private readonly BitmapManager _bitmapManager;
|
|
|
+ private readonly string defaultActionDisplay = "Click to pick colors from the canvas. Hold Ctrl to pick from the reference layer. Hold Ctrl and Alt to blend the reference and canvas color";
|
|
|
|
|
|
public ColorPickerTool(DocumentProvider documentProvider, BitmapManager bitmapManager)
|
|
|
{
|
|
|
- ActionDisplay = "Press on a pixel to make it the primary color. Hold Ctrl to pick from the reference. Hold Ctrl and Alt to blend the reference and canvas color";
|
|
|
+ ActionDisplay = defaultActionDisplay;
|
|
|
_docProvider = documentProvider;
|
|
|
_bitmapManager = bitmapManager;
|
|
|
}
|
|
|
|
|
|
public override bool HideHighlight => true;
|
|
|
|
|
|
- public override string Tooltip => "Swaps primary color with selected on canvas. (O)";
|
|
|
+ public override string Tooltip => "Picks the primary color from the canvas. (O)";
|
|
|
|
|
|
public override void Use(List<Coordinates> coordinates)
|
|
|
{
|
|
|
var coords = coordinates.First();
|
|
|
- var doc = _docProvider.GetSurface();
|
|
|
+ var doc = _docProvider.GetDocument();
|
|
|
if (coords.X < 0 || coords.Y < 0 || coords.X >= doc.Width || coords.Y >= doc.Height)
|
|
|
return;
|
|
|
|
|
@@ -41,34 +43,73 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
|
|
|
public SKColor GetColorAt(int x, int y)
|
|
|
{
|
|
|
- SKColor? color = null;
|
|
|
- Document activeDocument = _docProvider.GetDocument();
|
|
|
- Layer referenceLayer;
|
|
|
+ Layer referenceLayer = _docProvider.GetReferenceLayer();
|
|
|
|
|
|
- if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
|
|
- && (referenceLayer = _docProvider.GetReferenceLayer()) is not null)
|
|
|
+ if (referenceLayer != null && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
|
|
|
{
|
|
|
- double actualX = activeDocument.MouseXOnCanvas * referenceLayer.Width / activeDocument.Width;
|
|
|
- double actualY = activeDocument.MouseYOnCanvas * referenceLayer.Height / activeDocument.Height;
|
|
|
+ double preciseX = _docProvider.GetDocument().MouseXOnCanvas;
|
|
|
+ double preciseY = _docProvider.GetDocument().MouseYOnCanvas;
|
|
|
+
|
|
|
+ if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)))
|
|
|
+ {
|
|
|
+ return GetCombinedColor(x, y, preciseX, preciseY);
|
|
|
+ }
|
|
|
+ return GetReferenceColor(preciseX, preciseY);
|
|
|
+ }
|
|
|
+
|
|
|
+ return GetCanvasColor(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ private SKColor GetCombinedColor(int x, int y, double preciseX, double preciseY)
|
|
|
+ {
|
|
|
+ SKColor top = GetCanvasColor(x, y);
|
|
|
+ SKColor bottom = GetReferenceColor(preciseX, preciseY);
|
|
|
+ return BitmapUtils.BlendColors(bottom, top);
|
|
|
+ }
|
|
|
+
|
|
|
+ private SKColor GetCanvasColor(int x, int y)
|
|
|
+ {
|
|
|
+ return _docProvider.GetRenderer()?.FinalSurface.GetSRGBPixel(x, y) ?? SKColors.Transparent;
|
|
|
+ }
|
|
|
|
|
|
- x = (int)Round(actualX, MidpointRounding.ToZero);
|
|
|
- y = (int)Round(actualY, MidpointRounding.ToZero);
|
|
|
+ private SKColor GetReferenceColor(double x, double y)
|
|
|
+ {
|
|
|
+ Document activeDocument = _docProvider.GetDocument();
|
|
|
+ Layer referenceLayer = _docProvider.GetReferenceLayer();
|
|
|
+ Coordinates refPos = CanvasSpaceToReferenceSpace(
|
|
|
+ x, y,
|
|
|
+ activeDocument.Width, activeDocument.Height,
|
|
|
+ referenceLayer.Width, referenceLayer.Height);
|
|
|
+
|
|
|
+ if (refPos.X >= 0 && refPos.Y >= 0 && refPos.X < referenceLayer.Width && refPos.Y < referenceLayer.Height)
|
|
|
+ return referenceLayer.LayerBitmap.GetSRGBPixel(refPos.X, refPos.Y);
|
|
|
+ return SKColors.Transparent;
|
|
|
+ }
|
|
|
|
|
|
- color = referenceLayer.LayerBitmap.GetSRGBPixel(x, y);
|
|
|
+ private Coordinates CanvasSpaceToReferenceSpace(double canvasX, double canvasY, int canvasW, int canvasH, int referenceW, int referenceH)
|
|
|
+ {
|
|
|
+ double canvasRatio = canvasW / (double)canvasH;
|
|
|
+ double referenceRatio = referenceW / (double)referenceH;
|
|
|
+ bool blackBarsAreOnTopAndBottom = referenceRatio > canvasRatio;
|
|
|
+ if (blackBarsAreOnTopAndBottom)
|
|
|
+ {
|
|
|
+ double combinedBlackBarsHeight = (1 - canvasRatio / referenceRatio) * canvasH;
|
|
|
+ double refScale = referenceH / ((double)canvasH - combinedBlackBarsHeight);
|
|
|
+
|
|
|
+ int outX = (int)Math.Floor(canvasX * referenceW / canvasW);
|
|
|
+ int outY = (int)Math.Floor((canvasY - combinedBlackBarsHeight / 2) * refScale);
|
|
|
|
|
|
- //if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)) && color != null)
|
|
|
- //{
|
|
|
- // // TODO: Blend colors
|
|
|
- // throw new NotImplementedException();
|
|
|
- // //SKColor? canvasColor = _docProvider.GetRenderer()?.FinalSurface.GetSRGBPixel(x, y);
|
|
|
- //}
|
|
|
+ return new Coordinates(outX, outY);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- color = _docProvider.GetRenderer()?.FinalSurface.GetSRGBPixel(x, y);
|
|
|
- }
|
|
|
+ double combinedBlackBarsWidth = (1 - referenceRatio / canvasRatio) * canvasW;
|
|
|
+ double refScale = referenceW / ((double)canvasW - combinedBlackBarsWidth);
|
|
|
|
|
|
- return color ?? SKColors.Transparent;
|
|
|
+ int outX = (int)Math.Floor((canvasX - combinedBlackBarsWidth / 2) * refScale);
|
|
|
+ int outY = (int)Math.Floor(canvasY * referenceH / canvasH);
|
|
|
+ return new Coordinates(outX, outY);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public override void OnKeyDown(KeyEventArgs e)
|
|
@@ -94,25 +135,25 @@ namespace PixiEditor.Models.Tools.Tools
|
|
|
|
|
|
private void UpdateActionDisplay()
|
|
|
{
|
|
|
- if (Keyboard.IsKeyDown(Key.LeftCtrl) /*|| Keyboard.IsKeyDown(Key.RightCtrl)*/)
|
|
|
+ if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
|
|
|
{
|
|
|
- //if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
|
|
|
- //{
|
|
|
- // _bitmapManager.HideReferenceLayer = false;
|
|
|
- // _bitmapManager.OnlyReferenceLayer = false;
|
|
|
- // ActionDisplay = "Press on a pixel to make the blend of the reference and canvas the primary color. Release Ctrl and Alt to pick from the canvas. Release just Alt to pick from the reference";
|
|
|
- // return;
|
|
|
- //}
|
|
|
+ if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
|
|
|
+ {
|
|
|
+ _bitmapManager.HideReferenceLayer = false;
|
|
|
+ _bitmapManager.OnlyReferenceLayer = false;
|
|
|
+ ActionDisplay = "Click to pick colors from both the canvas and the reference layer blended together. Release Ctrl and Alt to pick from the canvas. Release just Alt to pick from the reference layer";
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
_bitmapManager.HideReferenceLayer = false;
|
|
|
_bitmapManager.OnlyReferenceLayer = true;
|
|
|
- ActionDisplay = "Press on a pixel on the reference to make it the primary color. Release Ctrl to pick from the canvas. Hold Ctrl and Alt to blend the reference and canvas color";
|
|
|
+ ActionDisplay = "Click to pick colors from the reference layer. Release Ctrl to pick from the canvas. Hold Ctrl and Alt to blend the reference and canvas color";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_bitmapManager.HideReferenceLayer = true;
|
|
|
_bitmapManager.OnlyReferenceLayer = false;
|
|
|
- ActionDisplay = "Press on a pixel to make it the primary color. Hold Ctrl to pick from the reference.";
|
|
|
+ ActionDisplay = defaultActionDisplay;
|
|
|
}
|
|
|
}
|
|
|
}
|