mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 01:08:18 +08:00
[FancyZones] Fix canvas layout with scaling reset issue (#17186)
* canvas scaling * predef layout check * return false on custom layout error * clean up * update unit tests * spelling * floating point convert * fix build
This commit is contained in:
parent
403969587e
commit
4aadaf9bf1
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@ -294,6 +294,7 @@ comsupp
|
||||
Concat
|
||||
concrt
|
||||
configs
|
||||
Configurator
|
||||
CONFLICTINGMODIFIERKEY
|
||||
CONFLICTINGMODIFIERSHORTCUT
|
||||
CONOUT
|
||||
|
@ -44,7 +44,7 @@ namespace DPIAware
|
||||
return GetScreenDPIForMonitor(targetMonitor, dpi);
|
||||
}
|
||||
|
||||
void Convert(HMONITOR monitor_handle, int& width, int& height)
|
||||
void Convert(HMONITOR monitor_handle, float& width, float& height)
|
||||
{
|
||||
if (monitor_handle == NULL)
|
||||
{
|
||||
@ -55,12 +55,12 @@ namespace DPIAware
|
||||
UINT dpi_x, dpi_y;
|
||||
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
|
||||
{
|
||||
width = width * static_cast<int>(dpi_x) / DEFAULT_DPI;
|
||||
height = height * static_cast<int>(dpi_y) / DEFAULT_DPI;
|
||||
width = width * dpi_x / DEFAULT_DPI;
|
||||
height = height * dpi_y / DEFAULT_DPI;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertByCursorPosition(int& width, int& height)
|
||||
void ConvertByCursorPosition(float& width, float& height)
|
||||
{
|
||||
HMONITOR targetMonitor = nullptr;
|
||||
POINT currentCursorPos{ 0 };
|
||||
@ -73,7 +73,7 @@ namespace DPIAware
|
||||
Convert(targetMonitor, width, height);
|
||||
}
|
||||
|
||||
void InverseConvert(HMONITOR monitor_handle, int& width, int& height)
|
||||
void InverseConvert(HMONITOR monitor_handle, float& width, float& height)
|
||||
{
|
||||
if (monitor_handle == NULL)
|
||||
{
|
||||
@ -84,8 +84,8 @@ namespace DPIAware
|
||||
UINT dpi_x, dpi_y;
|
||||
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
|
||||
{
|
||||
width = width * DEFAULT_DPI / static_cast<int>(dpi_x);
|
||||
height = height * DEFAULT_DPI / static_cast<int>(dpi_y);
|
||||
width = width * DEFAULT_DPI / dpi_x;
|
||||
height = height * DEFAULT_DPI / dpi_y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,9 @@ namespace DPIAware
|
||||
HRESULT GetScreenDPIForWindow(HWND hwnd, UINT& dpi);
|
||||
HRESULT GetScreenDPIForPoint(POINT p, UINT& dpi);
|
||||
HRESULT GetScreenDPIForCursor(UINT& dpi);
|
||||
void Convert(HMONITOR monitor_handle, int& width, int& height);
|
||||
void ConvertByCursorPosition(int& width, int& height);
|
||||
void InverseConvert(HMONITOR monitor_handle, int& width, int& height);
|
||||
void Convert(HMONITOR monitor_handle, float& width, float& height);
|
||||
void ConvertByCursorPosition(float& width, float& height);
|
||||
void InverseConvert(HMONITOR monitor_handle, float& width, float& height);
|
||||
void EnableDPIAwarenessForThisProcess();
|
||||
|
||||
enum AwarenessLevel
|
||||
|
@ -58,6 +58,7 @@
|
||||
<ClInclude Include="JsonHelpers.h" />
|
||||
<ClInclude Include="KeyState.h" />
|
||||
<ClInclude Include="FancyZonesData\LayoutHotkeys.h" />
|
||||
<ClInclude Include="LayoutConfigurator.h" />
|
||||
<ClInclude Include="ModuleConstants.h" />
|
||||
<ClInclude Include="MonitorUtils.h" />
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
||||
@ -109,6 +110,7 @@
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LayoutConfigurator.cpp" />
|
||||
<ClCompile Include="MonitorUtils.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||
<ClCompile Include="OnThreadExecutor.cpp" />
|
||||
|
@ -126,6 +126,9 @@
|
||||
<ClInclude Include="WindowUtils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LayoutConfigurator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
@ -209,6 +212,9 @@
|
||||
<ClCompile Include="WindowUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LayoutConfigurator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
433
src/modules/fancyzones/FancyZonesLib/LayoutConfigurator.cpp
Normal file
433
src/modules/fancyzones/FancyZonesLib/LayoutConfigurator.cpp
Normal file
@ -0,0 +1,433 @@
|
||||
#include "pch.h"
|
||||
#include "LayoutConfigurator.h"
|
||||
|
||||
#include <common/display/dpi_aware.h>
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int C_MULTIPLIER = 10000;
|
||||
|
||||
// PriorityGrid layout is unique for zoneCount <= 11. For zoneCount > 11 PriorityGrid is same as Grid
|
||||
FancyZonesDataTypes::GridLayoutInfo predefinedPriorityGridLayouts[11] = {
|
||||
/* 1 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 1,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 10000 },
|
||||
.cellChildMap = { { 0 } } }),
|
||||
/* 2 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 2,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 6667, 3333 },
|
||||
.cellChildMap = { { 0, 1 } } }),
|
||||
/* 3 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 } } }),
|
||||
/* 4 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 } } }),
|
||||
/* 5 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 } } }),
|
||||
/* 6 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 }, { 4, 1, 5 } } }),
|
||||
/* 7 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 }, { 5, 1, 6 } } }),
|
||||
/* 8 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 2, 7 } } }),
|
||||
/* 9 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 7, 8 } } }),
|
||||
/* 10 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 1, 8, 9 } } }),
|
||||
/* 11 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 8, 9, 10 } } }),
|
||||
};
|
||||
}
|
||||
|
||||
bool AddZone(winrt::com_ptr<IZone> zone, ZonesMap& zones) noexcept
|
||||
{
|
||||
auto zoneId = zone->Id();
|
||||
if (zones.contains(zoneId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zones[zoneId] = zone;
|
||||
return true;
|
||||
}
|
||||
|
||||
ZonesMap CalculateGridZones(FancyZonesUtils::Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing)
|
||||
{
|
||||
ZonesMap zones;
|
||||
|
||||
long totalWidth = workArea.width();
|
||||
long totalHeight = workArea.height();
|
||||
struct Info
|
||||
{
|
||||
long Extent;
|
||||
long Start;
|
||||
long End;
|
||||
};
|
||||
std::vector<Info> rowInfo(gridLayoutInfo.rows());
|
||||
std::vector<Info> columnInfo(gridLayoutInfo.columns());
|
||||
|
||||
// Note: The expressions below are carefully written to
|
||||
// make the sum of all zones' sizes exactly total{Width|Height}
|
||||
int totalPercents = 0;
|
||||
for (int row = 0; row < gridLayoutInfo.rows(); row++)
|
||||
{
|
||||
rowInfo[row].Start = totalPercents * totalHeight / C_MULTIPLIER;
|
||||
totalPercents += gridLayoutInfo.rowsPercents()[row];
|
||||
rowInfo[row].End = totalPercents * totalHeight / C_MULTIPLIER;
|
||||
rowInfo[row].Extent = rowInfo[row].End - rowInfo[row].Start;
|
||||
}
|
||||
|
||||
totalPercents = 0;
|
||||
for (int col = 0; col < gridLayoutInfo.columns(); col++)
|
||||
{
|
||||
columnInfo[col].Start = totalPercents * totalWidth / C_MULTIPLIER;
|
||||
totalPercents += gridLayoutInfo.columnsPercents()[col];
|
||||
columnInfo[col].End = totalPercents * totalWidth / C_MULTIPLIER;
|
||||
columnInfo[col].Extent = columnInfo[col].End - columnInfo[col].Start;
|
||||
}
|
||||
|
||||
for (int row = 0; row < gridLayoutInfo.rows(); row++)
|
||||
{
|
||||
for (int col = 0; col < gridLayoutInfo.columns(); col++)
|
||||
{
|
||||
int i = gridLayoutInfo.cellChildMap()[row][col];
|
||||
if (((row == 0) || (gridLayoutInfo.cellChildMap()[row - 1][col] != i)) &&
|
||||
((col == 0) || (gridLayoutInfo.cellChildMap()[row][col - 1] != i)))
|
||||
{
|
||||
long left = columnInfo[col].Start;
|
||||
long top = rowInfo[row].Start;
|
||||
|
||||
int maxRow = row;
|
||||
while (((maxRow + 1) < gridLayoutInfo.rows()) && (gridLayoutInfo.cellChildMap()[maxRow + 1][col] == i))
|
||||
{
|
||||
maxRow++;
|
||||
}
|
||||
int maxCol = col;
|
||||
while (((maxCol + 1) < gridLayoutInfo.columns()) && (gridLayoutInfo.cellChildMap()[row][maxCol + 1] == i))
|
||||
{
|
||||
maxCol++;
|
||||
}
|
||||
|
||||
long right = columnInfo[maxCol].End;
|
||||
long bottom = rowInfo[maxRow].End;
|
||||
|
||||
top += row == 0 ? spacing : spacing / 2;
|
||||
bottom -= maxRow == gridLayoutInfo.rows() - 1 ? spacing : spacing / 2;
|
||||
left += col == 0 ? spacing : spacing / 2;
|
||||
right -= maxCol == gridLayoutInfo.columns() - 1 ? spacing : spacing / 2;
|
||||
|
||||
auto zone = MakeZone(RECT{ left, top, right, bottom }, i);
|
||||
if (zone)
|
||||
{
|
||||
if (!AddZone(zone, zones))
|
||||
{
|
||||
Logger::error(L"Failed to create grid layout. Invalid zone id");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
Logger::error(L"Failed to create grid layout. Invalid zone");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::Focus(FancyZonesUtils::Rect workArea, int zoneCount) noexcept
|
||||
{
|
||||
ZonesMap zones;
|
||||
|
||||
long left{ 100 };
|
||||
long top{ 100 };
|
||||
long right{ left + long(workArea.width() * 0.4) };
|
||||
long bottom{ top + long(workArea.height() * 0.4) };
|
||||
|
||||
RECT focusZoneRect{ left, top, right, bottom };
|
||||
|
||||
long focusRectXIncrement = (zoneCount <= 1) ? 0 : 50;
|
||||
long focusRectYIncrement = (zoneCount <= 1) ? 0 : 50;
|
||||
|
||||
for (int i = 0; i < zoneCount; i++)
|
||||
{
|
||||
auto zone = MakeZone(focusZoneRect, zones.size());
|
||||
if (zone)
|
||||
{
|
||||
if (!AddZone(zone, zones))
|
||||
{
|
||||
Logger::error(L"Failed to create Focus layout. Invalid zone id");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
Logger::error(L"Failed to create Focus layout. Invalid zone");
|
||||
return {};
|
||||
}
|
||||
|
||||
focusZoneRect.left += focusRectXIncrement;
|
||||
focusZoneRect.right += focusRectXIncrement;
|
||||
focusZoneRect.bottom += focusRectYIncrement;
|
||||
focusZoneRect.top += focusRectYIncrement;
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::Rows(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
ZonesMap zones;
|
||||
|
||||
long totalWidth = workArea.width() - (spacing * 2);
|
||||
long totalHeight = workArea.height() - (spacing * (zoneCount + 1));
|
||||
|
||||
long top = spacing;
|
||||
long left = spacing;
|
||||
long bottom;
|
||||
long right;
|
||||
|
||||
// Note: The expressions below are NOT equal to total{Width|Height} / zoneCount and are done
|
||||
// like this to make the sum of all zones' sizes exactly total{Width|Height}.
|
||||
for (int zoneIndex = 0; zoneIndex < zoneCount; ++zoneIndex)
|
||||
{
|
||||
right = totalWidth + spacing;
|
||||
bottom = top + (zoneIndex + 1) * totalHeight / zoneCount - zoneIndex * totalHeight / zoneCount;
|
||||
|
||||
auto zone = MakeZone(RECT{ left, top, right, bottom }, zones.size());
|
||||
if (zone)
|
||||
{
|
||||
if (!AddZone(zone, zones))
|
||||
{
|
||||
Logger::error(L"Failed to create Rows layout. Invalid zone id");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
Logger::error(L"Failed to create Rows layout. Invalid zone");
|
||||
return {};
|
||||
}
|
||||
|
||||
top = bottom + spacing;
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::Columns(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
ZonesMap zones;
|
||||
|
||||
long totalWidth = workArea.width() - (spacing * (zoneCount + 1));
|
||||
long totalHeight = workArea.height() - (spacing * 2);
|
||||
|
||||
long top = spacing;
|
||||
long left = spacing;
|
||||
long bottom;
|
||||
long right;
|
||||
|
||||
// Note: The expressions below are NOT equal to total{Width|Height} / zoneCount and are done
|
||||
// like this to make the sum of all zones' sizes exactly total{Width|Height}.
|
||||
for (int zoneIndex = 0; zoneIndex < zoneCount; ++zoneIndex)
|
||||
{
|
||||
right = left + (zoneIndex + 1) * totalWidth / zoneCount - zoneIndex * totalWidth / zoneCount;
|
||||
bottom = totalHeight + spacing;
|
||||
|
||||
auto zone = MakeZone(RECT{ left, top, right, bottom }, zones.size());
|
||||
if (zone)
|
||||
{
|
||||
if (!AddZone(zone, zones))
|
||||
{
|
||||
Logger::error(L"Failed to create Columns layout. Invalid zone id");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
Logger::error(L"Failed to create Columns layout. Invalid zone");
|
||||
return {};
|
||||
}
|
||||
|
||||
left = right + spacing;
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::Grid(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
int rows = 1, columns = 1;
|
||||
while (zoneCount / rows >= rows)
|
||||
{
|
||||
rows++;
|
||||
}
|
||||
rows--;
|
||||
columns = zoneCount / rows;
|
||||
if (zoneCount % rows == 0)
|
||||
{
|
||||
// even grid
|
||||
}
|
||||
else
|
||||
{
|
||||
columns++;
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = rows, .columns = columns });
|
||||
|
||||
// Note: The expressions below are NOT equal to C_MULTIPLIER / {rows|columns} and are done
|
||||
// like this to make the sum of all percents exactly C_MULTIPLIER
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
gridLayoutInfo.rowsPercents()[row] = C_MULTIPLIER * (row + 1) / rows - C_MULTIPLIER * row / rows;
|
||||
}
|
||||
for (int col = 0; col < columns; col++)
|
||||
{
|
||||
gridLayoutInfo.columnsPercents()[col] = C_MULTIPLIER * (col + 1) / columns - C_MULTIPLIER * col / columns;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
gridLayoutInfo.cellChildMap()[i] = std::vector<int>(columns);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < columns; col++)
|
||||
{
|
||||
gridLayoutInfo.cellChildMap()[row][col] = index++;
|
||||
if (index == zoneCount)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CalculateGridZones(workArea, gridLayoutInfo, spacing);
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::PriorityGrid(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
if (zoneCount <= 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
constexpr int predefinedLayoutsCount = sizeof(predefinedPriorityGridLayouts) / sizeof(FancyZonesDataTypes::GridLayoutInfo);
|
||||
if (zoneCount < predefinedLayoutsCount)
|
||||
{
|
||||
return CalculateGridZones(workArea, predefinedPriorityGridLayouts[zoneCount - 1], spacing);
|
||||
}
|
||||
|
||||
return Grid(workArea, zoneCount, spacing);
|
||||
}
|
||||
|
||||
ZonesMap LayoutConfigurator::Custom(FancyZonesUtils::Rect workArea, HMONITOR monitor, const FancyZonesDataTypes::CustomLayoutData& zoneSet, int spacing) noexcept
|
||||
{
|
||||
if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Canvas && std::holds_alternative<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
ZonesMap zones;
|
||||
const auto& zoneSetInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info);
|
||||
|
||||
float width = static_cast<float>(workArea.width());
|
||||
float height = static_cast<float>(workArea.height());
|
||||
|
||||
DPIAware::InverseConvert(monitor, width, height);
|
||||
|
||||
for (const auto& zone : zoneSetInfo.zones)
|
||||
{
|
||||
float x = static_cast<float>(zone.x) * width / zoneSetInfo.lastWorkAreaWidth;
|
||||
float y = static_cast<float>(zone.y) * height / zoneSetInfo.lastWorkAreaHeight;
|
||||
float zoneWidth = static_cast<float>(zone.width) * width / zoneSetInfo.lastWorkAreaWidth;
|
||||
float zoneHeight = static_cast<float>(zone.height) * height / zoneSetInfo.lastWorkAreaHeight;
|
||||
|
||||
DPIAware::Convert(monitor, x, y);
|
||||
DPIAware::Convert(monitor, zoneWidth, zoneHeight);
|
||||
|
||||
auto zone = MakeZone(RECT{ static_cast<long>(x), static_cast<long>(y), static_cast<long>(x + zoneWidth), static_cast<long>(y + zoneHeight) }, zones.size());
|
||||
if (zone)
|
||||
{
|
||||
if (!AddZone(zone, zones))
|
||||
{
|
||||
Logger::error(L"Failed to create Custom layout. Invalid zone id");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
Logger::error(L"Failed to create Custom layout. Invalid zone");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
else if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Grid && std::holds_alternative<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& info = std::get<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info);
|
||||
return CalculateGridZones(workArea, info, spacing);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
23
src/modules/fancyzones/FancyZonesLib/LayoutConfigurator.h
Normal file
23
src/modules/fancyzones/FancyZonesLib/LayoutConfigurator.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <FancyZonesLib/Zone.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
// Mapping zone id to zone
|
||||
using ZonesMap = std::map<ZoneIndex, winrt::com_ptr<IZone>>;
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
{
|
||||
struct CustomLayoutData;
|
||||
}
|
||||
|
||||
class LayoutConfigurator
|
||||
{
|
||||
public:
|
||||
static ZonesMap Focus(FancyZonesUtils::Rect workArea, int zoneCount) noexcept;
|
||||
static ZonesMap Rows(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
static ZonesMap Columns(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
static ZonesMap Grid(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
static ZonesMap PriorityGrid(FancyZonesUtils::Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
static ZonesMap Custom(FancyZonesUtils::Rect workArea, HMONITOR monitor, const FancyZonesDataTypes::CustomLayoutData& data, int spacing) noexcept;
|
||||
};
|
@ -373,16 +373,16 @@ void FancyZonesWindowUtils::SaveWindowSizeAndOrigin(HWND window) noexcept
|
||||
RECT rect;
|
||||
if (GetWindowRect(window, &rect))
|
||||
{
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
int originX = rect.left;
|
||||
int originY = rect.top;
|
||||
float width = static_cast<float>(rect.right - rect.left);
|
||||
float height = static_cast<float>(rect.bottom - rect.top);
|
||||
float originX = static_cast<float>(rect.left);
|
||||
float originY = static_cast<float>(rect.top);
|
||||
|
||||
DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), width, height);
|
||||
DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), originX, originY);
|
||||
|
||||
std::array<int, 2> windowSizeData = { width, height };
|
||||
std::array<int, 2> windowOriginData = { originX, originY };
|
||||
std::array<int, 2> windowSizeData = { static_cast<int>(width), static_cast<int>(height) };
|
||||
std::array<int, 2> windowOriginData = { static_cast<int>(originX), static_cast<int>(originY) };
|
||||
HANDLE rawData;
|
||||
memcpy(&rawData, windowSizeData.data(), sizeof rawData);
|
||||
SetPropW(window, ZonedWindowProperties::PropertyRestoreSizeID, rawData);
|
||||
@ -399,8 +399,10 @@ void FancyZonesWindowUtils::RestoreWindowSize(HWND window) noexcept
|
||||
std::array<int, 2> windowSize;
|
||||
memcpy(windowSize.data(), &windowSizeData, sizeof windowSize);
|
||||
|
||||
float windowWidth = static_cast<float>(windowSize[0]), windowHeight = static_cast<float>(windowSize[1]);
|
||||
|
||||
// {width, height}
|
||||
DPIAware::Convert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), windowSize[0], windowSize[1]);
|
||||
DPIAware::Convert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), windowWidth, windowHeight);
|
||||
|
||||
RECT rect;
|
||||
if (GetWindowRect(window, &rect))
|
||||
@ -428,8 +430,10 @@ void FancyZonesWindowUtils::RestoreWindowOrigin(HWND window) noexcept
|
||||
std::array<int, 2> windowOrigin;
|
||||
memcpy(windowOrigin.data(), &windowOriginData, sizeof windowOrigin);
|
||||
|
||||
float windowWidth = static_cast<float>(windowOrigin[0]), windowHeight = static_cast<float>(windowOrigin[1]);
|
||||
|
||||
// {width, height}
|
||||
DPIAware::Convert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), windowOrigin[0], windowOrigin[1]);
|
||||
DPIAware::Convert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), windowWidth, windowHeight);
|
||||
|
||||
RECT rect;
|
||||
if (GetWindowRect(window, &rect))
|
||||
|
@ -3,108 +3,17 @@
|
||||
#include "ZoneSet.h"
|
||||
|
||||
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
||||
#include "FancyZonesDataTypes.h"
|
||||
#include "FancyZonesWindowProperties.h"
|
||||
#include "Settings.h"
|
||||
#include "Zone.h"
|
||||
#include <FancyZonesLib/util.h>
|
||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||
#include <FancyZonesLib/WindowUtils.h>
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/display/dpi_aware.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
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] = {
|
||||
/* 1 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 1,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 10000 },
|
||||
.cellChildMap = { { 0 } } }),
|
||||
/* 2 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 2,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 6667, 3333 },
|
||||
.cellChildMap = { { 0, 1 } } }),
|
||||
/* 3 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 } } }),
|
||||
/* 4 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 } } }),
|
||||
/* 5 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 } } }),
|
||||
/* 6 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 }, { 4, 1, 5 } } }),
|
||||
/* 7 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 }, { 5, 1, 6 } } }),
|
||||
/* 8 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 2, 7 } } }),
|
||||
/* 9 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 7, 8 } } }),
|
||||
/* 10 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 1, 8, 9 } } }),
|
||||
/* 11 */
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 8, 9, 10 } } }),
|
||||
};
|
||||
}
|
||||
|
||||
struct ZoneSet : winrt::implements<ZoneSet, IZoneSet>
|
||||
@ -125,7 +34,6 @@ public:
|
||||
Id() const noexcept { return m_config.Id; }
|
||||
IFACEMETHODIMP_(FancyZonesDataTypes::ZoneSetLayoutType)
|
||||
LayoutType() const noexcept { return m_config.LayoutType; }
|
||||
IFACEMETHODIMP AddZone(winrt::com_ptr<IZone> zone) noexcept;
|
||||
IFACEMETHODIMP_(ZoneIndexSet) ZonesFromPoint(POINT pt) const noexcept;
|
||||
IFACEMETHODIMP_(ZoneIndexSet) GetZoneIndexSetFromWindow(HWND window) const noexcept;
|
||||
IFACEMETHODIMP_(ZonesMap) GetZones()const noexcept override { return m_zones; }
|
||||
@ -151,12 +59,6 @@ public:
|
||||
IFACEMETHODIMP_(ZoneIndexSet) GetCombinedZoneRange(const ZoneIndexSet& initialZones, const ZoneIndexSet& finalZones) const noexcept;
|
||||
|
||||
private:
|
||||
bool CalculateFocusLayout(Rect workArea, int zoneCount) noexcept;
|
||||
bool CalculateColumnsAndRowsLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateGridLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateUniquePriorityGridLayout(Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateCustomLayout(Rect workArea, int spacing) noexcept;
|
||||
bool CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing);
|
||||
HWND GetNextTab(ZoneIndexSet indexSet, HWND current, bool reverse) noexcept;
|
||||
void InsertTabIntoZone(HWND window, std::optional<size_t> tabSortKeyWithinZone, const ZoneIndexSet& indexSet);
|
||||
ZoneIndexSet ZoneSelectSubregion(const ZoneIndexSet& capturedZones, POINT pt) const;
|
||||
@ -178,18 +80,6 @@ private:
|
||||
ZoneSetConfig m_config;
|
||||
};
|
||||
|
||||
IFACEMETHODIMP ZoneSet::AddZone(winrt::com_ptr<IZone> zone) noexcept
|
||||
{
|
||||
auto zoneId = zone->Id();
|
||||
if (m_zones.contains(zoneId))
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
m_zones[zoneId] = zone;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ZoneIndexSet)
|
||||
ZoneSet::ZonesFromPoint(POINT pt) const noexcept
|
||||
{
|
||||
@ -691,26 +581,40 @@ ZoneSet::CalculateZones(RECT workAreaRect, int zoneCount, int spacing) noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
switch (m_config.LayoutType)
|
||||
{
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Focus:
|
||||
success = CalculateFocusLayout(workArea, zoneCount);
|
||||
m_zones = LayoutConfigurator::Focus(workArea, zoneCount);
|
||||
break;
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Columns:
|
||||
m_zones = LayoutConfigurator::Columns(workArea, zoneCount, spacing);
|
||||
break;
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Rows:
|
||||
success = CalculateColumnsAndRowsLayout(workArea, m_config.LayoutType, zoneCount, spacing);
|
||||
m_zones = LayoutConfigurator::Rows(workArea, zoneCount, spacing);
|
||||
break;
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Grid:
|
||||
m_zones = LayoutConfigurator::Grid(workArea, zoneCount, spacing);
|
||||
break;
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid:
|
||||
success = CalculateGridLayout(workArea, m_config.LayoutType, zoneCount, spacing);
|
||||
m_zones = LayoutConfigurator::PriorityGrid(workArea, zoneCount, spacing);
|
||||
break;
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Custom:
|
||||
success = CalculateCustomLayout(workArea, spacing);
|
||||
break;
|
||||
{
|
||||
const auto zoneSetSearchResult = CustomLayouts::instance().GetCustomLayoutData(m_config.Id);
|
||||
if (zoneSetSearchResult.has_value())
|
||||
{
|
||||
m_zones = LayoutConfigurator::Custom(workArea, m_config.Monitor, zoneSetSearchResult.value(), spacing);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error(L"Custom layout not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return success;
|
||||
return m_zones.size() == zoneCount;
|
||||
}
|
||||
|
||||
bool ZoneSet::IsZoneEmpty(ZoneIndex zoneIndex) const noexcept
|
||||
@ -726,296 +630,6 @@ bool ZoneSet::IsZoneEmpty(ZoneIndex zoneIndex) const noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateFocusLayout(Rect workArea, int zoneCount) noexcept
|
||||
{
|
||||
long left{ 100 };
|
||||
long top{ 100 };
|
||||
long right{ left + long(workArea.width() * 0.4) };
|
||||
long bottom{ top + long(workArea.height() * 0.4) };
|
||||
|
||||
RECT focusZoneRect{ left, top, right, bottom };
|
||||
|
||||
long focusRectXIncrement = (zoneCount <= 1) ? 0 : 50;
|
||||
long focusRectYIncrement = (zoneCount <= 1) ? 0 : 50;
|
||||
|
||||
for (int i = 0; i < zoneCount; i++)
|
||||
{
|
||||
auto zone = MakeZone(focusZoneRect, m_zones.size());
|
||||
if (zone)
|
||||
{
|
||||
AddZone(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
m_zones.clear();
|
||||
return false;
|
||||
}
|
||||
focusZoneRect.left += focusRectXIncrement;
|
||||
focusZoneRect.right += focusRectXIncrement;
|
||||
focusZoneRect.bottom += focusRectYIncrement;
|
||||
focusZoneRect.top += focusRectYIncrement;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
long totalWidth;
|
||||
long totalHeight;
|
||||
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
totalWidth = workArea.width() - (spacing * (zoneCount + 1));
|
||||
totalHeight = workArea.height() - (spacing * 2);
|
||||
}
|
||||
else
|
||||
{ //Rows
|
||||
totalWidth = workArea.width() - (spacing * 2);
|
||||
totalHeight = workArea.height() - (spacing * (zoneCount + 1));
|
||||
}
|
||||
|
||||
long top = spacing;
|
||||
long left = spacing;
|
||||
long bottom;
|
||||
long right;
|
||||
|
||||
// Note: The expressions below are NOT equal to total{Width|Height} / zoneCount and are done
|
||||
// like this to make the sum of all zones' sizes exactly total{Width|Height}.
|
||||
for (int zoneIndex = 0; zoneIndex < zoneCount; ++zoneIndex)
|
||||
{
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
right = left + (zoneIndex + 1) * totalWidth / zoneCount - zoneIndex * totalWidth / zoneCount;
|
||||
bottom = totalHeight + spacing;
|
||||
}
|
||||
else
|
||||
{ //Rows
|
||||
right = totalWidth + spacing;
|
||||
bottom = top + (zoneIndex + 1) * totalHeight / zoneCount - zoneIndex * totalHeight / zoneCount;
|
||||
}
|
||||
|
||||
|
||||
auto zone = MakeZone(RECT{ left, top, right, bottom }, m_zones.size());
|
||||
if (zone)
|
||||
{
|
||||
AddZone(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
m_zones.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
left = right + spacing;
|
||||
}
|
||||
else
|
||||
{ //Rows
|
||||
top = bottom + spacing;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateGridLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
const auto count = sizeof(predefinedPriorityGridLayouts) / sizeof(FancyZonesDataTypes::GridLayoutInfo);
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid && zoneCount < count)
|
||||
{
|
||||
return CalculateUniquePriorityGridLayout(workArea, zoneCount, spacing);
|
||||
}
|
||||
|
||||
int rows = 1, columns = 1;
|
||||
while (zoneCount / rows >= rows)
|
||||
{
|
||||
rows++;
|
||||
}
|
||||
rows--;
|
||||
columns = zoneCount / rows;
|
||||
if (zoneCount % rows == 0)
|
||||
{
|
||||
// even grid
|
||||
}
|
||||
else
|
||||
{
|
||||
columns++;
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = rows, .columns = columns });
|
||||
|
||||
// Note: The expressions below are NOT equal to C_MULTIPLIER / {rows|columns} and are done
|
||||
// like this to make the sum of all percents exactly C_MULTIPLIER
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
gridLayoutInfo.rowsPercents()[row] = C_MULTIPLIER * (row + 1) / rows - C_MULTIPLIER * row / rows;
|
||||
}
|
||||
for (int col = 0; col < columns; col++)
|
||||
{
|
||||
gridLayoutInfo.columnsPercents()[col] = C_MULTIPLIER * (col + 1) / columns - C_MULTIPLIER * col / columns;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
gridLayoutInfo.cellChildMap()[i] = std::vector<int>(columns);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < columns; col++)
|
||||
{
|
||||
gridLayoutInfo.cellChildMap()[row][col] = index++;
|
||||
if (index == zoneCount)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CalculateGridZones(workArea, gridLayoutInfo, spacing);
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateUniquePriorityGridLayout(Rect workArea, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
if (zoneCount <= 0 || zoneCount >= sizeof(predefinedPriorityGridLayouts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CalculateGridZones(workArea, predefinedPriorityGridLayouts[zoneCount - 1], spacing);
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
{
|
||||
const auto zoneSetSearchResult = CustomLayouts::instance().GetCustomLayoutData(m_config.Id);
|
||||
if (!zoneSetSearchResult.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& zoneSet = *zoneSetSearchResult;
|
||||
if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Canvas && std::holds_alternative<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& zoneSetInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info);
|
||||
for (const auto& zone : zoneSetInfo.zones)
|
||||
{
|
||||
int x = zone.x;
|
||||
int y = zone.y;
|
||||
int width = zone.width;
|
||||
int height = zone.height;
|
||||
|
||||
DPIAware::Convert(m_config.Monitor, x, y);
|
||||
DPIAware::Convert(m_config.Monitor, width, height);
|
||||
|
||||
auto zone = MakeZone(RECT{ x, y, x + width, y + height }, m_zones.size());
|
||||
if (zone)
|
||||
{
|
||||
AddZone(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
m_zones.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Grid && std::holds_alternative<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& info = std::get<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info);
|
||||
return CalculateGridZones(workArea, info, spacing);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing)
|
||||
{
|
||||
long totalWidth = workArea.width();
|
||||
long totalHeight = workArea.height();
|
||||
struct Info
|
||||
{
|
||||
long Extent;
|
||||
long Start;
|
||||
long End;
|
||||
};
|
||||
std::vector<Info> rowInfo(gridLayoutInfo.rows());
|
||||
std::vector<Info> columnInfo(gridLayoutInfo.columns());
|
||||
|
||||
// Note: The expressions below are carefully written to
|
||||
// make the sum of all zones' sizes exactly total{Width|Height}
|
||||
int totalPercents = 0;
|
||||
for (int row = 0; row < gridLayoutInfo.rows(); row++)
|
||||
{
|
||||
rowInfo[row].Start = totalPercents * totalHeight / C_MULTIPLIER;
|
||||
totalPercents += gridLayoutInfo.rowsPercents()[row];
|
||||
rowInfo[row].End = totalPercents * totalHeight / C_MULTIPLIER;
|
||||
rowInfo[row].Extent = rowInfo[row].End - rowInfo[row].Start;
|
||||
}
|
||||
|
||||
totalPercents = 0;
|
||||
for (int col = 0; col < gridLayoutInfo.columns(); col++)
|
||||
{
|
||||
columnInfo[col].Start = totalPercents * totalWidth / C_MULTIPLIER;
|
||||
totalPercents += gridLayoutInfo.columnsPercents()[col];
|
||||
columnInfo[col].End = totalPercents * totalWidth / C_MULTIPLIER;
|
||||
columnInfo[col].Extent = columnInfo[col].End - columnInfo[col].Start;
|
||||
}
|
||||
|
||||
for (int row = 0; row < gridLayoutInfo.rows(); row++)
|
||||
{
|
||||
for (int col = 0; col < gridLayoutInfo.columns(); col++)
|
||||
{
|
||||
int i = gridLayoutInfo.cellChildMap()[row][col];
|
||||
if (((row == 0) || (gridLayoutInfo.cellChildMap()[row - 1][col] != i)) &&
|
||||
((col == 0) || (gridLayoutInfo.cellChildMap()[row][col - 1] != i)))
|
||||
{
|
||||
long left = columnInfo[col].Start;
|
||||
long top = rowInfo[row].Start;
|
||||
|
||||
int maxRow = row;
|
||||
while (((maxRow + 1) < gridLayoutInfo.rows()) && (gridLayoutInfo.cellChildMap()[maxRow + 1][col] == i))
|
||||
{
|
||||
maxRow++;
|
||||
}
|
||||
int maxCol = col;
|
||||
while (((maxCol + 1) < gridLayoutInfo.columns()) && (gridLayoutInfo.cellChildMap()[row][maxCol + 1] == i))
|
||||
{
|
||||
maxCol++;
|
||||
}
|
||||
|
||||
long right = columnInfo[maxCol].End;
|
||||
long bottom = rowInfo[maxRow].End;
|
||||
|
||||
top += row == 0 ? spacing : spacing / 2;
|
||||
bottom -= maxRow == gridLayoutInfo.rows() - 1 ? spacing : spacing / 2;
|
||||
left += col == 0 ? spacing : spacing / 2;
|
||||
right -= maxCol == gridLayoutInfo.columns() - 1 ? spacing : spacing / 2;
|
||||
|
||||
auto zone = MakeZone(RECT{ left, top, right, bottom }, i);
|
||||
if (zone)
|
||||
{
|
||||
AddZone(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// All zones within zone set should be valid in order to use its functionality.
|
||||
m_zones.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ZoneIndexSet ZoneSet::GetCombinedZoneRange(const ZoneIndexSet& initialZones, const ZoneIndexSet& finalZones) const noexcept
|
||||
{
|
||||
ZoneIndexSet combinedZones, result;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone.h"
|
||||
#include <FancyZonesLib/LayoutConfigurator.h>
|
||||
#include "Settings.h"
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
@ -13,9 +13,6 @@ namespace FancyZonesDataTypes
|
||||
*/
|
||||
interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : public IUnknown
|
||||
{
|
||||
// Mapping zone id to zone
|
||||
using ZonesMap = std::map<ZoneIndex, winrt::com_ptr<IZone>>;
|
||||
|
||||
/**
|
||||
* @returns Unique identifier of zone layout.
|
||||
*/
|
||||
@ -24,12 +21,6 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
||||
* @returns Type of the zone layout. Layout type can be focus, columns, rows, grid, priority grid or custom.
|
||||
*/
|
||||
IFACEMETHOD_(FancyZonesDataTypes::ZoneSetLayoutType, LayoutType)() const = 0;
|
||||
/**
|
||||
* Add zone to the zone layout.
|
||||
*
|
||||
* @param zone Zone object (defining coordinates of the zone).
|
||||
*/
|
||||
IFACEMETHOD(AddZone)(winrt::com_ptr<IZone> zone) = 0;
|
||||
/**
|
||||
* Get zones from cursor coordinates.
|
||||
*
|
||||
|
@ -277,7 +277,7 @@ void ZonesOverlay::Flash()
|
||||
m_cv.notify_all();
|
||||
}
|
||||
|
||||
void ZonesOverlay::DrawActiveZoneSet(const IZoneSet::ZonesMap& zones,
|
||||
void ZonesOverlay::DrawActiveZoneSet(const ZonesMap& zones,
|
||||
const ZoneIndexSet& highlightZones,
|
||||
const Colors::ZoneColors& colors,
|
||||
const bool showZoneText)
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
void Hide();
|
||||
void Show();
|
||||
void Flash();
|
||||
void DrawActiveZoneSet(const IZoneSet::ZonesMap& zones,
|
||||
void DrawActiveZoneSet(const ZonesMap& zones,
|
||||
const ZoneIndexSet& highlightZones,
|
||||
const Colors::ZoneColors& colors,
|
||||
const bool showZoneText);
|
||||
|
@ -407,8 +407,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsNotNull(workArea->ZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
workArea->ZoneSet()->AddZone(zone);
|
||||
workArea->ZoneSet()->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
@ -434,8 +433,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == appHistoryArray1[0].zoneIndexSet);
|
||||
|
||||
// add zone without window
|
||||
const auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
workArea->ZoneSet()->AddZone(zone);
|
||||
workArea->ZoneSet()->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(window);
|
||||
Assert::AreEqual((size_t)1, AppZoneHistory::instance().GetFullAppZoneHistory().size());
|
||||
@ -454,8 +452,7 @@ namespace FancyZonesUnitTests
|
||||
const auto deviceId = workArea->UniqueId();
|
||||
const auto zoneSetId = workArea->ZoneSet()->Id();
|
||||
|
||||
auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1);
|
||||
workArea->ZoneSet()->AddZone(zone);
|
||||
workArea->ZoneSet()->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
workArea->MoveWindowIntoZoneByIndex(window, 0);
|
||||
|
||||
//fill app zone history map
|
||||
@ -487,9 +484,7 @@ namespace FancyZonesUnitTests
|
||||
SetWindowPos(window, nullptr, 150, 150, originalWidth, originalHeight, SWP_SHOWWINDOW);
|
||||
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
|
||||
auto zone = MakeZone(RECT{ 50, 50, 300, 300 }, 1);
|
||||
workArea->ZoneSet()->AddZone(zone);
|
||||
|
||||
workArea->ZoneSet()->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_LEFT, true);
|
||||
|
||||
RECT inZoneRect;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "pch.h"
|
||||
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
||||
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||
#include "FancyZonesLib\FancyZonesDataTypes.h"
|
||||
#include "FancyZonesLib\ZoneIndexSetBitmask.h"
|
||||
@ -19,18 +20,23 @@ namespace FancyZonesUnitTests
|
||||
TEST_CLASS (ZoneSetUnitTests)
|
||||
{
|
||||
GUID m_id;
|
||||
const ZoneSetLayoutType m_layoutType = ZoneSetLayoutType::Custom;
|
||||
const ZoneSetLayoutType m_layoutType = ZoneSetLayoutType::Grid;
|
||||
|
||||
winrt::com_ptr<IZoneSet> m_set;
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
auto hres = CoCreateGuid(&m_id);
|
||||
Assert::AreEqual(S_OK, hres);
|
||||
{
|
||||
auto hres = CoCreateGuid(&m_id);
|
||||
Assert::AreEqual(S_OK, hres);
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, m_layoutType, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
m_set = MakeZoneSet(m_config);
|
||||
}
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, m_layoutType, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
m_set = MakeZoneSet(m_config);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
std::filesystem::remove_all(CustomLayouts::CustomLayoutsFileName());
|
||||
}
|
||||
|
||||
void compareZones(const winrt::com_ptr<IZone>& expected, const winrt::com_ptr<IZone>& actual)
|
||||
{
|
||||
@ -41,6 +47,40 @@ namespace FancyZonesUnitTests
|
||||
Assert::AreEqual(expected->GetZoneRect().bottom, actual->GetZoneRect().bottom);
|
||||
}
|
||||
|
||||
void saveCustomLayout(const std::vector<RECT>& zones)
|
||||
{
|
||||
json::JsonObject root{};
|
||||
json::JsonArray layoutsArray{};
|
||||
|
||||
json::JsonObject canvasLayoutJson{};
|
||||
canvasLayoutJson.SetNamedValue(NonLocalizable::CustomLayoutsIds::UuidID, json::value(FancyZonesUtils::GuidToString(m_id).value()));
|
||||
canvasLayoutJson.SetNamedValue(NonLocalizable::CustomLayoutsIds::NameID, json::value(L"Custom canvas layout"));
|
||||
canvasLayoutJson.SetNamedValue(NonLocalizable::CustomLayoutsIds::TypeID, json::value(NonLocalizable::CustomLayoutsIds::CanvasID));
|
||||
|
||||
json::JsonObject info{};
|
||||
info.SetNamedValue(NonLocalizable::CustomLayoutsIds::RefWidthID, json::value(1920));
|
||||
info.SetNamedValue(NonLocalizable::CustomLayoutsIds::RefHeightID, json::value(1080));
|
||||
|
||||
json::JsonArray zonesArray{};
|
||||
for (const auto& zoneRect : zones)
|
||||
{
|
||||
json::JsonObject zone{};
|
||||
zone.SetNamedValue(NonLocalizable::CustomLayoutsIds::XID, json::value(zoneRect.left));
|
||||
zone.SetNamedValue(NonLocalizable::CustomLayoutsIds::YID, json::value(zoneRect.top));
|
||||
zone.SetNamedValue(NonLocalizable::CustomLayoutsIds::WidthID, json::value(zoneRect.right - zoneRect.left));
|
||||
zone.SetNamedValue(NonLocalizable::CustomLayoutsIds::HeightID, json::value(zoneRect.bottom - zoneRect.top));
|
||||
zonesArray.Append(zone);
|
||||
}
|
||||
|
||||
info.SetNamedValue(NonLocalizable::CustomLayoutsIds::ZonesID, zonesArray);
|
||||
canvasLayoutJson.SetNamedValue(NonLocalizable::CustomLayoutsIds::InfoID, info);
|
||||
layoutsArray.Append(canvasLayoutJson);
|
||||
root.SetNamedValue(NonLocalizable::CustomLayoutsIds::CustomLayoutsArrayID, layoutsArray);
|
||||
json::to_file(CustomLayouts::CustomLayoutsFileName(), root);
|
||||
|
||||
CustomLayouts::instance().LoadData();
|
||||
}
|
||||
|
||||
public:
|
||||
TEST_METHOD (TestCreateZoneSet)
|
||||
{
|
||||
@ -84,52 +124,6 @@ namespace FancyZonesUnitTests
|
||||
Assert::AreEqual((size_t)0, zones.size());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddOne)
|
||||
{
|
||||
constexpr ZoneIndex zoneId = 0;
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 100, 100 }, zoneId);
|
||||
Assert::IsNotNull(zone.get());
|
||||
m_set->AddZone(zone);
|
||||
auto zones = m_set->GetZones();
|
||||
Assert::AreEqual((size_t)1, zones.size());
|
||||
compareZones(zone, zones[zoneId]);
|
||||
Assert::AreEqual(zoneId, zones[zoneId]->Id());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddManyEqual)
|
||||
{
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
{
|
||||
ZoneIndex zoneId = i;
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 100, 100 }, zoneId);
|
||||
Assert::IsNotNull(zone.get());
|
||||
m_set->AddZone(zone);
|
||||
auto zones = m_set->GetZones();
|
||||
Assert::AreEqual(i + 1, zones.size());
|
||||
compareZones(zone, zones[zoneId]);
|
||||
Assert::AreEqual(zoneId, zones[zoneId]->Id());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (AddManyDifferent)
|
||||
{
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
{
|
||||
ZoneIndex zoneId = i;
|
||||
int left = rand() % 10;
|
||||
int top = rand() % 10;
|
||||
int right = left + 1 + rand() % 100;
|
||||
int bottom = top + 1 + rand() % 100;
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ left, top, right, bottom }, zoneId);
|
||||
Assert::IsNotNull(zone.get());
|
||||
m_set->AddZone(zone);
|
||||
auto zones = m_set->GetZones();
|
||||
Assert::AreEqual(i + 1, zones.size());
|
||||
compareZones(zone, zones[zoneId]);
|
||||
Assert::AreEqual(zoneId, zones[zoneId]->Id());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (MakeZoneFromZeroRect)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 0, 0 }, 1);
|
||||
@ -163,143 +157,71 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (ZoneFromPointInner)
|
||||
{
|
||||
const int left = 0, top = 0, right = 100, bottom = 100;
|
||||
winrt::com_ptr<IZone> expected = MakeZone({ left, top, right, bottom }, 1);
|
||||
m_set->AddZone(expected);
|
||||
|
||||
for (int i = left + 1; i < right; i++)
|
||||
{
|
||||
for (int j = top + 1; j < bottom; j++)
|
||||
{
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, j });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
}
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 1, 1 });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointBorder)
|
||||
{
|
||||
const int left = 0, top = 0, right = 100, bottom = 100;
|
||||
winrt::com_ptr<IZone> expected = MakeZone({ left, top, right, bottom }, 1);
|
||||
m_set->AddZone(expected);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
for (int i = left; i < right; i++)
|
||||
{
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, top });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
|
||||
for (int i = top; i < bottom; i++)
|
||||
{
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ left, i });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
|
||||
//bottom and right borders considered to be outside
|
||||
for (int i = left; i < right; i++)
|
||||
{
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, bottom });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
for (int i = top; i < bottom; i++)
|
||||
{
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ right, i });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
Assert::IsTrue(m_set->ZonesFromPoint(POINT{ 0, 0 }).size() == 1);
|
||||
Assert::IsTrue(m_set->ZonesFromPoint(POINT{ 1920, 1080 }).size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointOuter)
|
||||
{
|
||||
const int left = 0, top = 0, right = 100, bottom = 100;
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ left, top, right, bottom }, 1);
|
||||
m_set->AddZone(zone);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 200, 200 });
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 1921, 1080 });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointOverlapping)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 10, 10, 90, 90 }, 2);
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 10, 10, 150, 150 }, 3);
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 10, 10, 50, 50 }, 4);
|
||||
m_set->AddZone(zone4);
|
||||
// prepare layout with overlapping zones
|
||||
saveCustomLayout({ RECT{ 0, 0, 100, 100 }, RECT{ 10, 10, 90, 90 }, RECT{ 10, 10, 150, 150 }, RECT{ 10, 10, 50, 50 } });
|
||||
|
||||
ZoneSetConfig config = ZoneSetConfig(m_id, FancyZonesDataTypes::ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
auto set = MakeZoneSet(config);
|
||||
set->CalculateZones(RECT{0,0,1920,1080}, 4, 0);
|
||||
|
||||
// zone4 is expected because it's the smallest one, and it's considered to be inside
|
||||
// since Multizones support
|
||||
auto zones = set->ZonesFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(zones.size() == 1);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(zone4, m_set->GetZones()[actual[0]]);
|
||||
auto expected = MakeZone({ 10, 10, 50, 50 }, 3);
|
||||
auto actual = set->GetZones()[zones[0]];
|
||||
compareZones(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointMultizoneHorizontal)
|
||||
TEST_METHOD (ZoneFromPointMultizone)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 }, 2);
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 }, 3);
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 }, 4);
|
||||
m_set->AddZone(zone4);
|
||||
// prepare layout with overlapping zones
|
||||
saveCustomLayout({ RECT{ 0, 0, 100, 100 }, RECT{ 100, 0, 200, 100 }, RECT{ 0, 100, 100, 200 }, RECT{ 100, 100, 200, 200 } });
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 50, 100 });
|
||||
ZoneSetConfig config = ZoneSetConfig(m_id, FancyZonesDataTypes::ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
auto set = MakeZoneSet(config);
|
||||
set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 4, 0);
|
||||
|
||||
auto actual = set->ZonesFromPoint(POINT{ 50, 100 });
|
||||
Assert::IsTrue(actual.size() == 2);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone3, m_set->GetZones()[actual[1]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointMultizoneVertical)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 }, 2);
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 }, 3);
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 }, 4);
|
||||
m_set->AddZone(zone4);
|
||||
auto zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
compareZones(zone1, set->GetZones()[actual[0]]);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 100, 50 });
|
||||
Assert::IsTrue(actual.size() == 2);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointMultizoneQuad)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 }, 2);
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 }, 3);
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 }, 4);
|
||||
m_set->AddZone(zone4);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 100, 100 });
|
||||
Assert::IsTrue(actual.size() == 4);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||
compareZones(zone3, m_set->GetZones()[actual[2]]);
|
||||
compareZones(zone4, m_set->GetZones()[actual[3]]);
|
||||
auto zone3 = MakeZone({ 0, 100, 100, 200 }, 2);
|
||||
compareZones(zone3, set->GetZones()[actual[1]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneIndexFromWindowUnknown)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
HWND window = Mocks::Window();
|
||||
HWND workArea = Mocks::Window();
|
||||
m_set->AddZone(zone);
|
||||
m_set->CalculateZones(RECT{0,0,1920, 1080}, 1, 0);
|
||||
m_set->MoveWindowIntoZoneByIndexSet(window, workArea, { 0 });
|
||||
|
||||
auto actual = m_set->GetZoneIndexSetFromWindow(Mocks::Window());
|
||||
@ -308,10 +230,9 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (ZoneIndexFromWindowNull)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
HWND window = Mocks::Window();
|
||||
HWND workArea = Mocks::Window();
|
||||
m_set->AddZone(zone);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
m_set->MoveWindowIntoZoneByIndexSet(window, workArea, { 0 });
|
||||
|
||||
auto actual = m_set->GetZoneIndexSetFromWindow(nullptr);
|
||||
@ -320,16 +241,16 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndex)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 0, 0, 100, 100 }, 2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 0, 100, 100 }, 3);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
m_set->AddZone(zone3);
|
||||
// prepare layout with overlapping zones
|
||||
saveCustomLayout({ RECT{ 0, 0, 100, 100 }, RECT{ 0, 0, 100, 100 }, RECT{ 0, 0, 100, 100 } });
|
||||
|
||||
ZoneSetConfig config = ZoneSetConfig(m_id, FancyZonesDataTypes::ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
auto set = MakeZoneSet(config);
|
||||
set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 0);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithNoZones)
|
||||
@ -340,12 +261,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithInvalidIndex)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 0, 0, 100, 100 }, 2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 0, 100, 100 }, 3);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
m_set->AddZone(zone3);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100);
|
||||
@ -354,13 +270,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameWindow)
|
||||
{
|
||||
// Add a couple of zones.
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 1, 1, 101, 101 }, 1);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 2, 2, 102, 102 }, 2);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
m_set->AddZone(zone3);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 0);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
@ -375,17 +285,13 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameIndex)
|
||||
{
|
||||
// Add a couple of zones.
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 1, 1, 101, 101 }, 1);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 2, 2, 102, 102 }, 2);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
m_set->AddZone(zone3);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 0);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
@ -397,19 +303,17 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointOuterPoint)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
auto window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 200, 200 });
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 1921, 1081 });
|
||||
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{} == m_set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointInnerPoint)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 1, 0);
|
||||
|
||||
auto window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
@ -419,71 +323,33 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointInnerPointOverlappingZones)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 10, 10, 90, 90 }, 1);
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
saveCustomLayout({ RECT{ 0, 0, 100, 100 }, RECT{ 10, 10, 90, 90 } });
|
||||
|
||||
ZoneSetConfig config = ZoneSetConfig(m_id, FancyZonesDataTypes::ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
auto set = MakeZoneSet(config);
|
||||
set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 0);
|
||||
|
||||
auto window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointDropAddWindow)
|
||||
{
|
||||
saveCustomLayout({ RECT{ 0, 0, 100, 100 }, RECT{ 10, 10, 90, 90 } });
|
||||
|
||||
ZoneSetConfig config = ZoneSetConfig(m_id, FancyZonesDataTypes::ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius, OverlappingZonesAlgorithm::Smallest);
|
||||
auto set = MakeZoneSet(config);
|
||||
set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 0);
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
const auto workArea = Mocks::Window();
|
||||
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 10, 10, 90, 90 }, 1);
|
||||
set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointDropAddWindowToSameZone)
|
||||
{
|
||||
const auto window = Mocks::Window();
|
||||
const auto workArea = Mocks::Window();
|
||||
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 10, 10, 90, 90 }, 1);
|
||||
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
||||
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByPointSeveralZonesWithSameWindow)
|
||||
{
|
||||
const auto window = Mocks::Window();
|
||||
const auto workArea = Mocks::Window();
|
||||
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 10, 10, 90, 90 }, 1);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 20, 20, 80, 80 }, 2);
|
||||
|
||||
m_set->AddZone(zone1);
|
||||
m_set->AddZone(zone2);
|
||||
m_set->AddZone(zone3);
|
||||
|
||||
m_set->MoveWindowIntoZoneByIndexSet(window, Mocks::Window(), { 0, 1, 2 });
|
||||
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 });
|
||||
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 2 } == m_set->GetZoneIndexSetFromWindow(window));
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 1 } == set->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
};
|
||||
|
||||
@ -497,16 +363,9 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
ZoneSetConfig config({}, ZoneSetLayoutType::Custom, Mocks::Monitor(), DefaultValues::SensitivityRadius);
|
||||
ZoneSetConfig config({}, ZoneSetLayoutType::Grid, Mocks::Monitor(), DefaultValues::SensitivityRadius);
|
||||
m_set = MakeZoneSet(config);
|
||||
|
||||
// Add a couple of zones.
|
||||
m_zone1 = MakeZone({ 0, 0, 100, 100 }, 0);
|
||||
m_zone2 = MakeZone({ 0, 0, 100, 100 }, 1);
|
||||
m_zone3 = MakeZone({ 0, 0, 100, 100 }, 2);
|
||||
m_set->AddZone(m_zone1);
|
||||
m_set->AddZone(m_zone2);
|
||||
m_set->AddZone(m_zone3);
|
||||
m_set->CalculateZones(RECT{ 0, 0, 1920, 1080 }, 3, 10);
|
||||
}
|
||||
|
||||
TEST_METHOD (EmptyZonesLeft)
|
||||
|
@ -144,8 +144,8 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
|
||||
RECT desktopRect = UIHelpers::GetForegroundWindowDesktopRect();
|
||||
|
||||
// Calculate DPI dependent window size
|
||||
int windowWidth = EditorConstants::DefaultEditKeyboardWindowWidth;
|
||||
int windowHeight = EditorConstants::DefaultEditKeyboardWindowHeight;
|
||||
float windowWidth = EditorConstants::DefaultEditKeyboardWindowWidth;
|
||||
float windowHeight = EditorConstants::DefaultEditKeyboardWindowHeight;
|
||||
|
||||
DPIAware::ConvertByCursorPosition(windowWidth, windowHeight);
|
||||
DPIAware::GetScreenDPIForCursor(g_currentDPI);
|
||||
@ -155,10 +155,10 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
|
||||
szWindowClass,
|
||||
GET_RESOURCE_STRING(IDS_EDITKEYBOARD_WINDOWNAME).c_str(),
|
||||
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX,
|
||||
((desktopRect.right + desktopRect.left) / 2) - (windowWidth / 2),
|
||||
((desktopRect.bottom + desktopRect.top) / 2) - (windowHeight / 2),
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
((desktopRect.right + desktopRect.left) / 2) - ((int)windowWidth / 2),
|
||||
((desktopRect.bottom + desktopRect.top) / 2) - ((int)windowHeight / 2),
|
||||
static_cast<int>(windowWidth),
|
||||
static_cast<int>(windowHeight),
|
||||
NULL,
|
||||
NULL,
|
||||
hInst,
|
||||
@ -415,11 +415,11 @@ LRESULT CALLBACK EditKeyboardWindowProc(HWND hWnd, UINT messageCode, WPARAM wPar
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
|
||||
int minWidth = EditorConstants::MinimumEditKeyboardWindowWidth;
|
||||
int minHeight = EditorConstants::MinimumEditKeyboardWindowHeight;
|
||||
float minWidth = EditorConstants::MinimumEditKeyboardWindowWidth;
|
||||
float minHeight = EditorConstants::MinimumEditKeyboardWindowHeight;
|
||||
DPIAware::Convert(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL), minWidth, minHeight);
|
||||
mmi->ptMinTrackSize.x = minWidth;
|
||||
mmi->ptMinTrackSize.y = minHeight;
|
||||
mmi->ptMinTrackSize.x = static_cast<LONG>(minWidth);
|
||||
mmi->ptMinTrackSize.y = static_cast<LONG>(minHeight);
|
||||
}
|
||||
break;
|
||||
case WM_GETDPISCALEDSIZE:
|
||||
|
@ -96,8 +96,8 @@ inline void CreateEditShortcutsWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMa
|
||||
RECT desktopRect = UIHelpers::GetForegroundWindowDesktopRect();
|
||||
|
||||
// Calculate DPI dependent window size
|
||||
int windowWidth = EditorConstants::DefaultEditShortcutsWindowWidth;
|
||||
int windowHeight = EditorConstants::DefaultEditShortcutsWindowHeight;
|
||||
float windowWidth = EditorConstants::DefaultEditShortcutsWindowWidth;
|
||||
float windowHeight = EditorConstants::DefaultEditShortcutsWindowHeight;
|
||||
DPIAware::ConvertByCursorPosition(windowWidth, windowHeight);
|
||||
DPIAware::GetScreenDPIForCursor(g_currentDPI);
|
||||
|
||||
@ -106,10 +106,10 @@ inline void CreateEditShortcutsWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMa
|
||||
szWindowClass,
|
||||
GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_WINDOWNAME).c_str(),
|
||||
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX,
|
||||
((desktopRect.right + desktopRect.left) / 2) - (windowWidth / 2),
|
||||
((desktopRect.bottom + desktopRect.top) / 2) - (windowHeight / 2),
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
((desktopRect.right + desktopRect.left) / 2) - ((int)windowWidth / 2),
|
||||
((desktopRect.bottom + desktopRect.top) / 2) - ((int)windowHeight / 2),
|
||||
static_cast<int>(windowWidth),
|
||||
static_cast<int>(windowHeight),
|
||||
NULL,
|
||||
NULL,
|
||||
hInst,
|
||||
@ -387,11 +387,11 @@ LRESULT CALLBACK EditShortcutsWindowProc(HWND hWnd, UINT messageCode, WPARAM wPa
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
|
||||
int minWidth = EditorConstants::MinimumEditShortcutsWindowWidth;
|
||||
int minHeight = EditorConstants::MinimumEditShortcutsWindowHeight;
|
||||
float minWidth = EditorConstants::MinimumEditShortcutsWindowWidth;
|
||||
float minHeight = EditorConstants::MinimumEditShortcutsWindowHeight;
|
||||
DPIAware::Convert(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL), minWidth, minHeight);
|
||||
mmi->ptMinTrackSize.x = minWidth;
|
||||
mmi->ptMinTrackSize.y = minHeight;
|
||||
mmi->ptMinTrackSize.x = static_cast<LONG>(minWidth);
|
||||
mmi->ptMinTrackSize.y = static_cast<LONG>(minHeight);
|
||||
}
|
||||
break;
|
||||
case WM_GETDPISCALEDSIZE:
|
||||
|
Loading…
Reference in New Issue
Block a user