[FanzyZones] Zone activation based on zone center (#11361)

* Started work on algorithm to select the zone with the center closest to the cursor.

* Fixed algorithm to compute center of rectangle

* Revert to taking the smallest area when the centers are too close (75 pixels).
Temporary turned off buffer of window selection to better see how the algorithm is working.

* Remove change to sensitivity radius.

* Changes in response to SeraphimaZ's comments.

* spelling fix

Co-authored-by: ulazy1 <ulazy198@gmail.com>
This commit is contained in:
ulazy1 2021-06-16 10:49:29 -04:00 committed by GitHub
parent 3f00aa0981
commit 482163daf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 1 deletions

View File

@ -20,7 +20,8 @@ struct Settings
Smallest = 0,
Largest = 1,
Positional = 2,
EnumElements = 3, // number of elements in the enum, not counting this
ClosestCenter = 3,
EnumElements = 4, // number of elements in the enum, not counting this
};
// The values specified here are the defaults.

View File

@ -20,6 +20,7 @@ using namespace FancyZonesUtils;
namespace
{
constexpr int C_MULTIPLIER = 10000;
constexpr int OVERLAPPING_CENTERS_SENSITIVITY = 75;
// PriorityGrid layout is unique for zoneCount <= 11. For zoneCount > 11 PriorityGrid is same as Grid
FancyZonesDataTypes::GridLayoutInfo predefinedPriorityGridLayouts[11] = {
@ -255,6 +256,28 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept
return max(rect.bottom - rect.top, 0) * max(rect.right - rect.left, 0);
};
auto getCenter = [](auto zone) {
RECT rect = zone->GetZoneRect();
return POINT{ (rect.right + rect.left) / 2, (rect.top + rect.bottom) / 2 };
};
auto pointDifference = [](POINT pt1, POINT pt2) {
return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y);
};
auto distanceFromCenter = [&](auto zone) {
POINT center = getCenter(zone);
return pointDifference(center, pt);
};
auto closerToCenter = [&](auto zone1, auto zone2) {
if (pointDifference(getCenter(zone1), getCenter(zone2)) > OVERLAPPING_CENTERS_SENSITIVITY)
{
return distanceFromCenter(zone1) < distanceFromCenter(zone2);
}
else
{
return zoneArea(zone1) < zoneArea(zone2);
};
};
try
{
using Algorithm = Settings::OverlappingZonesAlgorithm;
@ -267,6 +290,8 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept
return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zoneArea(zone1) > zoneArea(zone2); });
case Algorithm::Positional:
return ZoneSelectSubregion(capturedZones, pt);
case Algorithm::ClosestCenter:
return ZoneSelectPriority(capturedZones, closerToCenter);
}
}
catch (std::out_of_range)

View File

@ -957,6 +957,9 @@
<data name="ColorPicker_Editor.Text" xml:space="preserve">
<value>Editor</value>
</data>
<data name="FancyZones_OverlappingZonesClosestCenter.Content" xml:space="preserve">
<value>Activate the zone whose center is closest to the cursor</value>
</data>
<data name="FancyZones_OverlappingZonesLargest.Content" xml:space="preserve">
<value>Activate the largest zone by area</value>
</data>

View File

@ -134,6 +134,7 @@
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesSmallest" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesLargest" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesPositional" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesClosestCenter" />
</ComboBox>
<TextBlock x:Uid="FancyZones_WindowBehavior_GroupSettings"