mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
[FancyZones] Hold Ctrl to select any number of zones (#4850)
* Started work * Did something, not yet sure that it works * Sort of works * Cleari highlighted zones when using Ctrl after leaving a monitor * Remove unnecessary line * Enhanced UX. Maybe refactor? * Changed the logic behind zone selection when dragging * Various fixups
This commit is contained in:
@@ -212,7 +212,7 @@ public:
|
||||
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones);
|
||||
|
||||
IFACEMETHODIMP MoveSizeEnter(HWND window) noexcept;
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
||||
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
RestoreOriginalTransparency() noexcept;
|
||||
@@ -238,6 +238,8 @@ public:
|
||||
HideZoneWindow() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
UpdateActiveZoneSet() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
ClearSelectedZones() noexcept;
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
@@ -263,6 +265,7 @@ private:
|
||||
bool m_flashMode{};
|
||||
winrt::com_ptr<IZoneSet> m_activeZoneSet;
|
||||
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
|
||||
std::vector<int> m_initialHighlightZone;
|
||||
std::vector<int> m_highlightZone;
|
||||
WPARAM m_keyLast{};
|
||||
size_t m_keyCycle{};
|
||||
@@ -368,11 +371,12 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept
|
||||
m_windowMoveSize = window;
|
||||
m_drawHints = true;
|
||||
m_highlightZone = {};
|
||||
m_initialHighlightZone = {};
|
||||
ShowZoneWindow();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept
|
||||
IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept
|
||||
{
|
||||
bool redraw = false;
|
||||
POINT ptClient = ptScreen;
|
||||
@@ -381,6 +385,61 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
|
||||
if (dragEnabled)
|
||||
{
|
||||
auto highlightZone = ZonesFromPoint(ptClient);
|
||||
|
||||
if (selectManyZones)
|
||||
{
|
||||
if (m_initialHighlightZone.empty())
|
||||
{
|
||||
// first time
|
||||
m_initialHighlightZone = highlightZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<int> newHighlightZone;
|
||||
std::set_union(begin(highlightZone), end(highlightZone), begin(m_initialHighlightZone), end(m_initialHighlightZone), std::back_inserter(newHighlightZone));
|
||||
|
||||
RECT boundingRect;
|
||||
bool boundingRectEmpty = true;
|
||||
auto zones = m_activeZoneSet->GetZones();
|
||||
|
||||
for (int zoneId : newHighlightZone)
|
||||
{
|
||||
RECT rect = zones[zoneId]->GetZoneRect();
|
||||
if (boundingRectEmpty)
|
||||
{
|
||||
boundingRect = rect;
|
||||
boundingRectEmpty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
boundingRect.left = min(boundingRect.left, rect.left);
|
||||
boundingRect.top = min(boundingRect.top, rect.top);
|
||||
boundingRect.right = max(boundingRect.right, rect.right);
|
||||
boundingRect.bottom = max(boundingRect.bottom, rect.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
highlightZone.clear();
|
||||
|
||||
if (!boundingRectEmpty)
|
||||
{
|
||||
for (size_t zoneId = 0; zoneId < zones.size(); zoneId++)
|
||||
{
|
||||
RECT rect = zones[zoneId]->GetZoneRect();
|
||||
if (boundingRect.left <= rect.left && rect.right <= boundingRect.right &&
|
||||
boundingRect.top <= rect.top && rect.bottom <= boundingRect.bottom)
|
||||
{
|
||||
highlightZone.push_back(static_cast<int>(zoneId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_initialHighlightZone = {};
|
||||
}
|
||||
|
||||
redraw = (highlightZone != m_highlightZone);
|
||||
m_highlightZone = std::move(highlightZone);
|
||||
}
|
||||
@@ -410,7 +469,7 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexc
|
||||
{
|
||||
POINT ptClient = ptScreen;
|
||||
MapWindowPoints(nullptr, m_window.get(), &ptClient, 1);
|
||||
m_activeZoneSet->MoveWindowIntoZoneByPoint(window, m_window.get(), ptClient);
|
||||
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), m_highlightZone);
|
||||
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
}
|
||||
@@ -545,6 +604,16 @@ ZoneWindow::UpdateActiveZoneSet() noexcept
|
||||
CalculateZoneSet();
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneWindow::ClearSelectedZones() noexcept
|
||||
{
|
||||
if (m_highlightZone.size())
|
||||
{
|
||||
m_highlightZone.clear();
|
||||
InvalidateRect(m_window.get(), nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region private
|
||||
|
||||
void ZoneWindow::InitializeZoneSets(const std::wstring& parentUniqueId) noexcept
|
||||
|
||||
Reference in New Issue
Block a user