From 7e79654ee0c2368d28d90d5090a00ae24c05976f Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Tue, 22 Jun 2021 11:34:27 +0300 Subject: [PATCH] [FancyZones] Avoid unnecessary calculations when selecting a zone (#11815) --- src/modules/fancyzones/lib/Zone.cpp | 1 + src/modules/fancyzones/lib/Zone.h | 4 ++ src/modules/fancyzones/lib/ZoneSet.cpp | 60 +++++++++++++------------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/modules/fancyzones/lib/Zone.cpp b/src/modules/fancyzones/lib/Zone.cpp index 21ca046815..e9156798a3 100644 --- a/src/modules/fancyzones/lib/Zone.cpp +++ b/src/modules/fancyzones/lib/Zone.cpp @@ -33,6 +33,7 @@ public: } IFACEMETHODIMP_(RECT) GetZoneRect() const noexcept { return m_zoneRect; } + IFACEMETHODIMP_(long) GetZoneArea() const noexcept { return max(m_zoneRect.bottom - m_zoneRect.top, 0) * max(m_zoneRect.right - m_zoneRect.left, 0); } IFACEMETHODIMP_(size_t) Id() const noexcept { return m_id; } IFACEMETHODIMP_(RECT) ComputeActualZoneRect(HWND window, HWND zoneWindow) const noexcept; diff --git a/src/modules/fancyzones/lib/Zone.h b/src/modules/fancyzones/lib/Zone.h index 77b69abaa7..f768cff14e 100644 --- a/src/modules/fancyzones/lib/Zone.h +++ b/src/modules/fancyzones/lib/Zone.h @@ -14,6 +14,10 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub * @returns Zone coordinates (top-left and bottom-right corner) represented as RECT structure. */ IFACEMETHOD_(RECT, GetZoneRect)() const = 0; + /** + * @returns Zone area calculated from zone rect + */ + IFACEMETHOD_(long, GetZoneArea)() const = 0; /** * @returns Zone identifier. */ diff --git a/src/modules/fancyzones/lib/ZoneSet.cpp b/src/modules/fancyzones/lib/ZoneSet.cpp index 324d6a5807..44514223f9 100644 --- a/src/modules/fancyzones/lib/ZoneSet.cpp +++ b/src/modules/fancyzones/lib/ZoneSet.cpp @@ -161,6 +161,7 @@ private: bool CalculateCustomLayout(Rect workArea, int spacing) noexcept; bool CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing); std::vector ZoneSelectSubregion(const std::vector& capturedZones, POINT pt) const; + std::vector ZoneSelectClosestCenter(const std::vector& capturedZones, POINT pt) const; // `compare` should return true if the first argument is a better choice than the second argument. template @@ -251,33 +252,6 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept if (overlap) { - auto zoneArea = [](auto zone) { - RECT rect = zone->GetZoneRect(); - 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; @@ -285,13 +259,13 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept switch (m_config.SelectionAlgorithm) { case Algorithm::Smallest: - return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zoneArea(zone1) < zoneArea(zone2); }); + return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zone1->GetZoneArea() < zone2->GetZoneArea(); }); case Algorithm::Largest: - return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zoneArea(zone1) > zoneArea(zone2); }); + return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zone1->GetZoneArea() > zone2->GetZoneArea(); }); case Algorithm::Positional: return ZoneSelectSubregion(capturedZones, pt); case Algorithm::ClosestCenter: - return ZoneSelectPriority(capturedZones, closerToCenter); + return ZoneSelectClosestCenter(capturedZones, pt); } } catch (std::out_of_range) @@ -1018,6 +992,32 @@ std::vector ZoneSet::ZoneSelectSubregion(const std::vector& capt return { capturedZones[zoneIndex] }; } +std::vector ZoneSet::ZoneSelectClosestCenter(const std::vector& capturedZones, POINT pt) const +{ + 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 zone1->GetZoneArea() < zone2->GetZoneArea(); + }; + }; + return ZoneSelectPriority(capturedZones, closerToCenter); +} + template std::vector ZoneSet::ZoneSelectPriority(const std::vector& capturedZones, CompareF compare) const {