Files
PowerToys/src/modules/fancyzones/editor/FancyZonesEditor/MagneticSnap.cs
Ivan Stošić e586a7ad64 [FancyZones] Rework grid editor (#10116)
* Started rewriting

* Making progress

* Fix resizers not moving around

* Implemented splitting, fixed some bugs

* Removed more code, renamed methods

* Merging zones works

* Fix Shift key behavior

* Added spacing (has bugs)

* Implement minimum size restriction

* Match preview and editor visuals

* Snapping works

* Show when splitting is not possible

* Fix spell checker complaining

* Tweak FZ Lib function computing grid zones

* Fix potential crash when loading old zone layouts

* Fix dead objects talking

* Fix splitters being shown when they shouldn't be

* Fix index numbering

* Fix small glitch with the shift key

* Do not snap to borders outside the zone
2021-03-10 13:22:19 +01:00

80 lines
2.5 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace FancyZonesEditor
{
public class MagneticSnap
{
private List<int> _keyPoints;
private double _workAreaSize;
private const int MagnetZoneMaxSize = GridData.Multiplier / 12;
public MagneticSnap(List<int> keyPoints, double workAreaSize)
{
_keyPoints = keyPoints;
_workAreaSize = workAreaSize;
}
public int PixelToDataWithSnapping(double pixel, int low, int high)
{
var keyPoints = _keyPoints.Where(x => low < x && x < high).ToList();
var magnetZoneSizes = new List<int>();
for (int i = 0; i < keyPoints.Count; i++)
{
int previous = i == 0 ? low : keyPoints[i - 1];
int next = i == keyPoints.Count - 1 ? high : keyPoints[i + 1];
magnetZoneSizes.Add(Math.Min(keyPoints[i] - previous, Math.Min(next - keyPoints[i], MagnetZoneMaxSize)) / 2);
}
int data = Convert.ToInt32(pixel / _workAreaSize * GridData.Multiplier);
data = Math.Clamp(data, low, high);
int result;
int snapId = -1;
for (int i = 0; i < keyPoints.Count; ++i)
{
if (Math.Abs(data - keyPoints[i]) <= magnetZoneSizes[i])
{
snapId = i;
break;
}
}
if (snapId == -1)
{
result = data;
}
else
{
int deadZoneWidth = (magnetZoneSizes[snapId] + 1) / 2;
if (Math.Abs(data - keyPoints[snapId]) <= deadZoneWidth)
{
result = keyPoints[snapId];
}
else if (data < keyPoints[snapId])
{
result = data + (data - (keyPoints[snapId] - magnetZoneSizes[snapId]));
}
else
{
result = data - ((keyPoints[snapId] + magnetZoneSizes[snapId]) - data);
}
}
return Math.Clamp(result, low, high);
}
public double DataToPixelWithoutSnapping(int data)
{
return _workAreaSize * data / GridData.Multiplier;
}
}
}