mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
[FancyZones] Customize default layouts (#21156)
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
|
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/LayoutTemplates.h>
|
#include <FancyZonesLib/FancyZonesData/LayoutTemplates.h>
|
||||||
#include <FancyZonesLib/FancyZonesWindowProcessing.h>
|
#include <FancyZonesLib/FancyZonesWindowProcessing.h>
|
||||||
@@ -73,6 +74,7 @@ public:
|
|||||||
LayoutHotkeys::instance().LoadData();
|
LayoutHotkeys::instance().LoadData();
|
||||||
AppliedLayouts::instance().LoadData();
|
AppliedLayouts::instance().LoadData();
|
||||||
AppZoneHistory::instance().LoadData();
|
AppZoneHistory::instance().LoadData();
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFancyZones
|
// IFancyZones
|
||||||
@@ -662,6 +664,10 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
|||||||
AppliedLayouts::instance().LoadData();
|
AppliedLayouts::instance().LoadData();
|
||||||
UpdateZoneSets();
|
UpdateZoneSets();
|
||||||
}
|
}
|
||||||
|
else if (message == WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE)
|
||||||
|
{
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
}
|
||||||
else if (message == WM_PRIV_QUICK_LAYOUT_KEY)
|
else if (message == WM_PRIV_QUICK_LAYOUT_KEY)
|
||||||
{
|
{
|
||||||
ApplyQuickLayout(static_cast<int>(lparam));
|
ApplyQuickLayout(static_cast<int>(lparam));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <FancyZonesLib/GuidUtils.h>
|
#include <FancyZonesLib/GuidUtils.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
#include <FancyZonesLib/JsonHelpers.h>
|
#include <FancyZonesLib/JsonHelpers.h>
|
||||||
@@ -73,7 +74,7 @@ namespace JsonUtils
|
|||||||
struct AppliedLayoutsJSON
|
struct AppliedLayoutsJSON
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static std::optional<FancyZonesDataTypes::WorkAreaId> WorkAreaIdFromJson(const json::JsonObject& json)
|
static std::pair<std::optional<FancyZonesDataTypes::WorkAreaId>, bool> WorkAreaIdFromJson(const json::JsonObject& json)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -89,7 +90,7 @@ namespace JsonUtils
|
|||||||
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
|
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
|
||||||
if (!virtualDesktopGuid)
|
if (!virtualDesktopGuid)
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return { std::nullopt, false };
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::DeviceId deviceId{};
|
FancyZonesDataTypes::DeviceId deviceId{};
|
||||||
@@ -104,16 +105,17 @@ namespace JsonUtils
|
|||||||
deviceId.instanceId = monitorInstance;
|
deviceId.instanceId = monitorInstance;
|
||||||
deviceId.number = monitorNumber;
|
deviceId.number = monitorNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::MonitorId monitorId{
|
FancyZonesDataTypes::MonitorId monitorId{
|
||||||
.deviceId = deviceId,
|
.deviceId = deviceId,
|
||||||
.serialNumber = monitorSerialNumber
|
.serialNumber = monitorSerialNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
return FancyZonesDataTypes::WorkAreaId{
|
return { FancyZonesDataTypes::WorkAreaId{
|
||||||
.monitorId = monitorId,
|
.monitorId = monitorId,
|
||||||
.virtualDesktopId = virtualDesktopGuid.value(),
|
.virtualDesktopId = virtualDesktopGuid.value(),
|
||||||
};
|
},
|
||||||
|
false };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -121,24 +123,26 @@ namespace JsonUtils
|
|||||||
auto bcDeviceId = BackwardsCompatibility::DeviceIdData::ParseDeviceId(deviceIdStr);
|
auto bcDeviceId = BackwardsCompatibility::DeviceIdData::ParseDeviceId(deviceIdStr);
|
||||||
if (!bcDeviceId)
|
if (!bcDeviceId)
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return { std::nullopt, false };
|
||||||
}
|
}
|
||||||
|
|
||||||
return FancyZonesDataTypes::WorkAreaId{
|
return { FancyZonesDataTypes::WorkAreaId{
|
||||||
.monitorId = { .deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(bcDeviceId->deviceName) },
|
.monitorId = { .deviceId = MonitorUtils::Display::ConvertObsoleteDeviceId(bcDeviceId->deviceName) },
|
||||||
.virtualDesktopId = bcDeviceId->virtualDesktopId,
|
.virtualDesktopId = bcDeviceId->virtualDesktopId,
|
||||||
};
|
},
|
||||||
|
true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const winrt::hresult_error&)
|
catch (const winrt::hresult_error&)
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return { std::nullopt, false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FancyZonesDataTypes::WorkAreaId workAreaId;
|
FancyZonesDataTypes::WorkAreaId workAreaId;
|
||||||
Layout data{};
|
Layout data{};
|
||||||
|
bool hasResolutionInId = false;
|
||||||
|
|
||||||
static std::optional<AppliedLayoutsJSON> FromJson(const json::JsonObject& json)
|
static std::optional<AppliedLayoutsJSON> FromJson(const json::JsonObject& json)
|
||||||
{
|
{
|
||||||
@@ -147,7 +151,7 @@ namespace JsonUtils
|
|||||||
AppliedLayoutsJSON result;
|
AppliedLayoutsJSON result;
|
||||||
|
|
||||||
auto deviceIdOpt = WorkAreaIdFromJson(json);
|
auto deviceIdOpt = WorkAreaIdFromJson(json);
|
||||||
if (!deviceIdOpt.has_value())
|
if (!deviceIdOpt.first.has_value())
|
||||||
{
|
{
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@@ -158,8 +162,10 @@ namespace JsonUtils
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.workAreaId = std::move(deviceIdOpt.value());
|
result.workAreaId = std::move(deviceIdOpt.first.value());
|
||||||
result.data = std::move(layout.value());
|
result.data = std::move(layout.value());
|
||||||
|
result.hasResolutionInId = deviceIdOpt.second;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (const winrt::hresult_error&)
|
catch (const winrt::hresult_error&)
|
||||||
@@ -200,8 +206,13 @@ namespace JsonUtils
|
|||||||
if (auto obj = AppliedLayoutsJSON::FromJson(layouts.GetObjectAt(i)); obj.has_value())
|
if (auto obj = AppliedLayoutsJSON::FromJson(layouts.GetObjectAt(i)); obj.has_value())
|
||||||
{
|
{
|
||||||
// skip default layouts in case if they were applied to different resolutions on the same monitor.
|
// skip default layouts in case if they were applied to different resolutions on the same monitor.
|
||||||
// NOTE: keep the default layout check for users who update PT version from the v0.57
|
// NOTE: keep the default layout check for users who update PT version from the v0.57
|
||||||
if (!map.contains(obj->workAreaId) && !isLayoutDefault(obj->data))
|
if (obj->hasResolutionInId && isLayoutDefault(obj->data))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!map.contains(obj->workAreaId))
|
||||||
{
|
{
|
||||||
map[obj->workAreaId] = std::move(obj->data);
|
map[obj->workAreaId] = std::move(obj->data);
|
||||||
}
|
}
|
||||||
@@ -456,16 +467,8 @@ bool AppliedLayouts::ApplyDefaultLayout(const FancyZonesDataTypes::WorkAreaId& d
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout layout{
|
// TODO: vertical or horizontal
|
||||||
.uuid = guid,
|
m_layouts[deviceId] = DefaultLayouts::instance().GetDefaultLayout();
|
||||||
.type = FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid,
|
|
||||||
.showSpacing = DefaultValues::ShowSpacing,
|
|
||||||
.spacing = DefaultValues::Spacing,
|
|
||||||
.zoneCount = DefaultValues::ZoneCount,
|
|
||||||
.sensitivityRadius = DefaultValues::SensitivityRadius
|
|
||||||
};
|
|
||||||
|
|
||||||
m_layouts[deviceId] = std::move(layout);
|
|
||||||
|
|
||||||
// Saving default layout data doesn't make sense, since it's ignored on parsing.
|
// Saving default layout data doesn't make sense, since it's ignored on parsing.
|
||||||
// Given that default layouts are ignored when parsing,
|
// Given that default layouts are ignored when parsing,
|
||||||
|
|||||||
@@ -227,11 +227,7 @@ std::optional<Layout> CustomLayouts::GetLayout(const GUID& id) const noexcept
|
|||||||
FancyZonesDataTypes::CustomLayoutData customLayout = iter->second;
|
FancyZonesDataTypes::CustomLayoutData customLayout = iter->second;
|
||||||
Layout layout{
|
Layout layout{
|
||||||
.uuid = id,
|
.uuid = id,
|
||||||
.type = FancyZonesDataTypes::ZoneSetLayoutType::Custom,
|
.type = FancyZonesDataTypes::ZoneSetLayoutType::Custom
|
||||||
.showSpacing = DefaultValues::ShowSpacing,
|
|
||||||
.spacing = DefaultValues::Spacing,
|
|
||||||
.zoneCount = DefaultValues::ZoneCount,
|
|
||||||
.sensitivityRadius = DefaultValues::SensitivityRadius
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (customLayout.type == FancyZonesDataTypes::CustomLayoutType::Grid)
|
if (customLayout.type == FancyZonesDataTypes::CustomLayoutType::Grid)
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#include "../pch.h"
|
||||||
|
#include "DefaultLayouts.h"
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
|
#include <common/logger/logger.h>
|
||||||
|
|
||||||
|
namespace DefaultLayoutsJsonUtils
|
||||||
|
{
|
||||||
|
MonitorConfiguraionType TypeFromString(const std::wstring& data)
|
||||||
|
{
|
||||||
|
if (data == L"vertical")
|
||||||
|
{
|
||||||
|
return MonitorConfiguraionType::Vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MonitorConfiguraionType::Horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring TypeToString(MonitorConfiguraionType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MonitorConfiguraionType::Horizontal:
|
||||||
|
return L"horizontal";
|
||||||
|
case MonitorConfiguraionType::Vertical:
|
||||||
|
return L"vertical";
|
||||||
|
default:
|
||||||
|
return L"horizontal";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LayoutJSON
|
||||||
|
{
|
||||||
|
static std::optional<Layout> FromJson(const json::JsonObject& json)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Layout data{};
|
||||||
|
auto idStr = json.GetNamedString(NonLocalizable::DefaultLayoutsIds::UuidID, L"");
|
||||||
|
if (!idStr.empty())
|
||||||
|
{
|
||||||
|
auto id = FancyZonesUtils::GuidFromString(idStr.c_str());
|
||||||
|
if (!id.has_value())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.uuid = id.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
data.type = FancyZonesDataTypes::TypeFromString(std::wstring{ json.GetNamedString(NonLocalizable::DefaultLayoutsIds::TypeID) });
|
||||||
|
data.showSpacing = json.GetNamedBoolean(NonLocalizable::DefaultLayoutsIds::ShowSpacingID, DefaultValues::ShowSpacing);
|
||||||
|
data.spacing = static_cast<int>(json.GetNamedNumber(NonLocalizable::DefaultLayoutsIds::SpacingID, DefaultValues::Spacing));
|
||||||
|
data.zoneCount = static_cast<int>(json.GetNamedNumber(NonLocalizable::DefaultLayoutsIds::ZoneCountID, DefaultValues::ZoneCount));
|
||||||
|
data.sensitivityRadius = static_cast<int>(json.GetNamedNumber(NonLocalizable::DefaultLayoutsIds::SensitivityRadiusID, DefaultValues::SensitivityRadius));
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error&)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static json::JsonObject ToJson(const Layout& data)
|
||||||
|
{
|
||||||
|
json::JsonObject result{};
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::UuidID, json::value(FancyZonesUtils::GuidToString(data.uuid).value()));
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::TypeID, json::value(FancyZonesDataTypes::TypeToString(data.type)));
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ShowSpacingID, json::value(data.showSpacing));
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SpacingID, json::value(data.spacing));
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ZoneCountID, json::value(data.zoneCount));
|
||||||
|
result.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SensitivityRadiusID, json::value(data.sensitivityRadius));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefaultLayoutJSON
|
||||||
|
{
|
||||||
|
MonitorConfiguraionType monitorConfigurationType{ MonitorConfiguraionType::Horizontal };
|
||||||
|
Layout layout{};
|
||||||
|
|
||||||
|
static std::optional<DefaultLayoutJSON> FromJson(const json::JsonObject& json)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DefaultLayoutJSON result;
|
||||||
|
|
||||||
|
auto type = TypeFromString(std::wstring{ json.GetNamedString(NonLocalizable::DefaultLayoutsIds::MonitorConfigurationTypeID) });
|
||||||
|
auto layout = DefaultLayoutsJsonUtils::LayoutJSON::FromJson(json.GetNamedObject(NonLocalizable::DefaultLayoutsIds::LayoutID));
|
||||||
|
if (!layout.has_value())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.monitorConfigurationType = std::move(type);
|
||||||
|
result.layout = std::move(layout.value());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error&)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DefaultLayouts::TDefaultLayoutsContainer ParseJson(const json::JsonObject& json)
|
||||||
|
{
|
||||||
|
DefaultLayouts::TDefaultLayoutsContainer map{};
|
||||||
|
auto layouts = json.GetNamedArray(NonLocalizable::DefaultLayoutsIds::DefaultLayoutsArrayID);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < layouts.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (auto obj = DefaultLayoutJSON::FromJson(layouts.GetObjectAt(i)); obj.has_value())
|
||||||
|
{
|
||||||
|
map[static_cast<MonitorConfiguraionType>(obj->monitorConfigurationType)] = std::move(obj->layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DefaultLayouts::DefaultLayouts()
|
||||||
|
{
|
||||||
|
const std::wstring& dataFileName = DefaultLayoutsFileName();
|
||||||
|
m_fileWatcher = std::make_unique<FileWatcher>(dataFileName, [&]() {
|
||||||
|
PostMessageW(HWND_BROADCAST, WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE, NULL, NULL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DefaultLayouts& DefaultLayouts::instance()
|
||||||
|
{
|
||||||
|
static DefaultLayouts self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultLayouts::LoadData()
|
||||||
|
{
|
||||||
|
auto data = json::from_file(DefaultLayoutsFileName());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
m_layouts = DefaultLayoutsJsonUtils::ParseJson(data.value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_layouts.clear();
|
||||||
|
Logger::info(L"default-layouts.json file is missing or malformed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error& e)
|
||||||
|
{
|
||||||
|
Logger::error(L"Parsing default-layouts error: {}", e.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout DefaultLayouts::GetDefaultLayout(MonitorConfiguraionType type) const noexcept
|
||||||
|
{
|
||||||
|
auto iter = m_layouts.find(type);
|
||||||
|
if (iter != m_layouts.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Layout{};
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/Layout.h>
|
||||||
|
#include <FancyZonesLib/ModuleConstants.h>
|
||||||
|
|
||||||
|
#include <common/SettingsAPI/FileWatcher.h>
|
||||||
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
|
|
||||||
|
namespace NonLocalizable
|
||||||
|
{
|
||||||
|
namespace DefaultLayoutsIds
|
||||||
|
{
|
||||||
|
const static wchar_t* DefaultLayoutsArrayID = L"default-layouts";
|
||||||
|
const static wchar_t* MonitorConfigurationTypeID = L"monitor-configuration";
|
||||||
|
const static wchar_t* LayoutID = L"layout";
|
||||||
|
const static wchar_t* UuidID = L"uuid";
|
||||||
|
const static wchar_t* TypeID = L"type";
|
||||||
|
const static wchar_t* ShowSpacingID = L"show-spacing";
|
||||||
|
const static wchar_t* SpacingID = L"spacing";
|
||||||
|
const static wchar_t* ZoneCountID = L"zone-count";
|
||||||
|
const static wchar_t* SensitivityRadiusID = L"sensitivity-radius";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MonitorConfiguraionType
|
||||||
|
{
|
||||||
|
Horizontal = 0,
|
||||||
|
Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
class DefaultLayouts
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using TDefaultLayoutsContainer = std::map<MonitorConfiguraionType, Layout>;
|
||||||
|
|
||||||
|
static DefaultLayouts& instance();
|
||||||
|
|
||||||
|
inline static std::wstring DefaultLayoutsFileName()
|
||||||
|
{
|
||||||
|
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::ModuleKey);
|
||||||
|
#if defined(UNIT_TESTS)
|
||||||
|
return saveFolderPath + L"\\test-default-layouts.json";
|
||||||
|
#endif
|
||||||
|
return saveFolderPath + L"\\default-layouts.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadData();
|
||||||
|
|
||||||
|
Layout GetDefaultLayout(MonitorConfiguraionType type = MonitorConfiguraionType::Horizontal) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DefaultLayouts();
|
||||||
|
~DefaultLayouts() = default;
|
||||||
|
|
||||||
|
TDefaultLayoutsContainer m_layouts;
|
||||||
|
std::unique_ptr<FileWatcher> m_fileWatcher;
|
||||||
|
};
|
||||||
@@ -2,14 +2,25 @@
|
|||||||
|
|
||||||
#include <guiddef.h>
|
#include <guiddef.h>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||||
|
|
||||||
struct Layout
|
struct Layout
|
||||||
{
|
{
|
||||||
GUID uuid;
|
GUID uuid = GUID_NULL;
|
||||||
FancyZonesDataTypes::ZoneSetLayoutType type;
|
FancyZonesDataTypes::ZoneSetLayoutType type = FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid;
|
||||||
bool showSpacing;
|
bool showSpacing = DefaultValues::ShowSpacing;
|
||||||
int spacing;
|
int spacing = DefaultValues::Spacing;
|
||||||
int zoneCount;
|
int zoneCount = DefaultValues::ZoneCount;
|
||||||
int sensitivityRadius;
|
int sensitivityRadius = DefaultValues::SensitivityRadius;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const Layout& lhs, const Layout& rhs)
|
||||||
|
{
|
||||||
|
return lhs.uuid == rhs.uuid &&
|
||||||
|
lhs.type == rhs.type &&
|
||||||
|
lhs.showSpacing == rhs.showSpacing &&
|
||||||
|
lhs.spacing == rhs.spacing &&
|
||||||
|
lhs.zoneCount == rhs.zoneCount &&
|
||||||
|
lhs.sensitivityRadius == rhs.sensitivityRadius;
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
<ClInclude Include="FancyZonesData\AppZoneHistory.h" />
|
<ClInclude Include="FancyZonesData\AppZoneHistory.h" />
|
||||||
<ClInclude Include="FancyZones.h" />
|
<ClInclude Include="FancyZones.h" />
|
||||||
<ClInclude Include="FancyZonesDataTypes.h" />
|
<ClInclude Include="FancyZonesDataTypes.h" />
|
||||||
|
<ClInclude Include="FancyZonesData\DefaultLayouts.h" />
|
||||||
<ClInclude Include="FancyZonesData\Layout.h" />
|
<ClInclude Include="FancyZonesData\Layout.h" />
|
||||||
<ClInclude Include="FancyZonesData\LayoutDefaults.h" />
|
<ClInclude Include="FancyZonesData\LayoutDefaults.h" />
|
||||||
<ClInclude Include="FancyZonesData\LayoutTemplates.h" />
|
<ClInclude Include="FancyZonesData\LayoutTemplates.h" />
|
||||||
@@ -90,6 +91,9 @@
|
|||||||
<ClCompile Include="FancyZonesData\AppliedLayouts.cpp">
|
<ClCompile Include="FancyZonesData\AppliedLayouts.cpp">
|
||||||
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\DefaultLayouts.cpp">
|
||||||
|
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="FancyZonesData\LayoutTemplates.cpp">
|
<ClCompile Include="FancyZonesData\LayoutTemplates.cpp">
|
||||||
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -16,6 +16,12 @@
|
|||||||
<Filter Include="Generated Files">
|
<Filter Include="Generated Files">
|
||||||
<UniqueIdentifier>{093625ff-2415-4c2c-842c-0ee7fcb1d203}</UniqueIdentifier>
|
<UniqueIdentifier>{093625ff-2415-4c2c-842c-0ee7fcb1d203}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Header Files\FancyZonesData">
|
||||||
|
<UniqueIdentifier>{dcbd2932-a3b2-400a-ad0d-6315f9795b13}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files\FancyZonesData">
|
||||||
|
<UniqueIdentifier>{5b35a312-b878-49e9-92c0-e098c2b97deb}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h">
|
<ClInclude Include="pch.h">
|
||||||
@@ -90,30 +96,9 @@
|
|||||||
<ClInclude Include="GuidUtils.h">
|
<ClInclude Include="GuidUtils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="FancyZonesData\AppZoneHistory.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesData\AppliedLayouts.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesData\CustomLayouts.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesData\LayoutHotkeys.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ModuleConstants.h">
|
<ClInclude Include="ModuleConstants.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="FancyZonesData\LayoutTemplates.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesData\LayoutDefaults.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesData\Layout.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ZoneIndexSetBitmask.h">
|
<ClInclude Include="ZoneIndexSetBitmask.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -132,6 +117,30 @@
|
|||||||
<ClInclude Include="FancyZonesWindowProcessing.h">
|
<ClInclude Include="FancyZonesWindowProcessing.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\AppliedLayouts.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\AppZoneHistory.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\CustomLayouts.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\DefaultLayouts.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\Layout.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\LayoutDefaults.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\LayoutHotkeys.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\LayoutTemplates.h">
|
||||||
|
<Filter>Header Files\FancyZonesData</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="EditorParameters.h">
|
<ClInclude Include="EditorParameters.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -194,21 +203,6 @@
|
|||||||
<ClCompile Include="MonitorUtils.cpp">
|
<ClCompile Include="MonitorUtils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="FancyZonesData\CustomLayouts.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesData\LayoutHotkeys.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesData\AppZoneHistory.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesData\AppliedLayouts.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesData\LayoutTemplates.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesWindowProperties.cpp">
|
<ClCompile Include="FancyZonesWindowProperties.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -224,6 +218,24 @@
|
|||||||
<ClCompile Include="EditorParameters.cpp">
|
<ClCompile Include="EditorParameters.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\AppliedLayouts.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\AppZoneHistory.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\CustomLayouts.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\DefaultLayouts.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\LayoutHotkeys.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\LayoutTemplates.cpp">
|
||||||
|
<Filter>Source Files\FancyZonesData</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ UINT WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE;
|
|||||||
UINT WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE;
|
UINT WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE;
|
||||||
UINT WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE;
|
UINT WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE;
|
||||||
UINT WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE;
|
UINT WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE;
|
||||||
|
UINT WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE;
|
||||||
UINT WM_PRIV_SNAP_HOTKEY;
|
UINT WM_PRIV_SNAP_HOTKEY;
|
||||||
UINT WM_PRIV_QUICK_LAYOUT_KEY;
|
UINT WM_PRIV_QUICK_LAYOUT_KEY;
|
||||||
UINT WM_PRIV_SETTINGS_CHANGED;
|
UINT WM_PRIV_SETTINGS_CHANGED;
|
||||||
@@ -37,6 +38,7 @@ void InitializeWinhookEventIds()
|
|||||||
WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE = RegisterWindowMessage(L"{4686f019-5d3d-4c5c-9051-b7cbbccca77d}");
|
WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE = RegisterWindowMessage(L"{4686f019-5d3d-4c5c-9051-b7cbbccca77d}");
|
||||||
WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE = RegisterWindowMessage(L"{0972787e-cdab-4e16-b228-91acdc38f40f}");
|
WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE = RegisterWindowMessage(L"{0972787e-cdab-4e16-b228-91acdc38f40f}");
|
||||||
WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE = RegisterWindowMessage(L"{2ef2c8a7-e0d5-4f31-9ede-52aade2d284d}");
|
WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE = RegisterWindowMessage(L"{2ef2c8a7-e0d5-4f31-9ede-52aade2d284d}");
|
||||||
|
WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE = RegisterWindowMessage(L"{61fd2afb-e909-41b2-b6f3-b9f546f2ae3f}");
|
||||||
WM_PRIV_SNAP_HOTKEY = RegisterWindowMessage(L"{72f4fd8e-23f1-43ab-bbbc-029363df9a84}");
|
WM_PRIV_SNAP_HOTKEY = RegisterWindowMessage(L"{72f4fd8e-23f1-43ab-bbbc-029363df9a84}");
|
||||||
WM_PRIV_QUICK_LAYOUT_KEY = RegisterWindowMessage(L"{15baab3d-c67b-4a15-aFF0-13610e05e947}");
|
WM_PRIV_QUICK_LAYOUT_KEY = RegisterWindowMessage(L"{15baab3d-c67b-4a15-aFF0-13610e05e947}");
|
||||||
WM_PRIV_SETTINGS_CHANGED = RegisterWindowMessage(L"{89ca3Daa-bf2d-4e73-9f3f-c60716364e27}");
|
WM_PRIV_SETTINGS_CHANGED = RegisterWindowMessage(L"{89ca3Daa-bf2d-4e73-9f3f-c60716364e27}");
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ extern UINT WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE; // Scheduled when the watched la
|
|||||||
extern UINT WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE; // Scheduled when the watched layout-templates.json file is updated
|
extern UINT WM_PRIV_LAYOUT_TEMPLATES_FILE_UPDATE; // Scheduled when the watched layout-templates.json file is updated
|
||||||
extern UINT WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE; // Scheduled when the watched custom-layouts.json file is updated
|
extern UINT WM_PRIV_CUSTOM_LAYOUTS_FILE_UPDATE; // Scheduled when the watched custom-layouts.json file is updated
|
||||||
extern UINT WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE; // Scheduled when the watched applied-layouts.json file is updated
|
extern UINT WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE; // Scheduled when the watched applied-layouts.json file is updated
|
||||||
|
extern UINT WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE; // Scheduled when the watched default-layouts.json file is updated
|
||||||
extern UINT WM_PRIV_SNAP_HOTKEY; // Scheduled when we receive a snap hotkey key down press
|
extern UINT WM_PRIV_SNAP_HOTKEY; // Scheduled when we receive a snap hotkey key down press
|
||||||
extern UINT WM_PRIV_QUICK_LAYOUT_KEY; // Scheduled when we receive a key down press to quickly apply a layout
|
extern UINT WM_PRIV_QUICK_LAYOUT_KEY; // Scheduled when we receive a key down press to quickly apply a layout
|
||||||
extern UINT WM_PRIV_SETTINGS_CHANGED; // Scheduled when the a watched settings file is updated
|
extern UINT WM_PRIV_SETTINGS_CHANGED; // Scheduled when the a watched settings file is updated
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutDefaults.h>
|
||||||
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace FancyZonesUnitTests
|
||||||
|
{
|
||||||
|
TEST_CLASS (DefaultLayoutsUnitTests)
|
||||||
|
{
|
||||||
|
std::wstring m_testFolder = L"FancyZonesUnitTests";
|
||||||
|
std::wstring m_testFolderPath = PTSettingsHelper::get_module_save_folder_location(m_testFolder);
|
||||||
|
|
||||||
|
TEST_METHOD_CLEANUP(CleanUp)
|
||||||
|
{
|
||||||
|
std::filesystem::remove(DefaultLayouts::DefaultLayoutsFileName());
|
||||||
|
std::filesystem::remove_all(m_testFolderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (DefaultLayoutsParse)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray layoutsArray{};
|
||||||
|
|
||||||
|
// custom, horizontal
|
||||||
|
{
|
||||||
|
json::JsonObject layout{};
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::UuidID, json::value(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}"));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::TypeID, json::value(L"custom"));
|
||||||
|
|
||||||
|
json::JsonObject obj{};
|
||||||
|
obj.SetNamedValue(NonLocalizable::DefaultLayoutsIds::MonitorConfigurationTypeID, json::value(L"horizontal"));
|
||||||
|
obj.SetNamedValue(NonLocalizable::DefaultLayoutsIds::LayoutID, layout);
|
||||||
|
layoutsArray.Append(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template, vertical
|
||||||
|
{
|
||||||
|
json::JsonObject layout{};
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::TypeID, json::value(L"grid"));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ShowSpacingID, json::value(true));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SpacingID, json::value(1));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ZoneCountID, json::value(4));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SensitivityRadiusID, json::value(30));
|
||||||
|
|
||||||
|
json::JsonObject obj{};
|
||||||
|
obj.SetNamedValue(NonLocalizable::DefaultLayoutsIds::MonitorConfigurationTypeID, json::value(L"vertical"));
|
||||||
|
obj.SetNamedValue(NonLocalizable::DefaultLayoutsIds::LayoutID, layout);
|
||||||
|
layoutsArray.Append(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
root.SetNamedValue(NonLocalizable::DefaultLayoutsIds::DefaultLayoutsArrayID, layoutsArray);
|
||||||
|
json::to_file(DefaultLayouts::DefaultLayoutsFileName(), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
|
||||||
|
Layout horizontal{
|
||||||
|
.uuid = FancyZonesUtils::GuidFromString(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}").value(),
|
||||||
|
.type = FancyZonesDataTypes::ZoneSetLayoutType::Custom
|
||||||
|
};
|
||||||
|
Assert::IsTrue(horizontal == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Horizontal));
|
||||||
|
|
||||||
|
Layout vertical{
|
||||||
|
.uuid = GUID_NULL,
|
||||||
|
.type = FancyZonesDataTypes::ZoneSetLayoutType::Grid,
|
||||||
|
.showSpacing = true,
|
||||||
|
.spacing = 1,
|
||||||
|
.zoneCount = 4,
|
||||||
|
.sensitivityRadius = 30
|
||||||
|
};
|
||||||
|
Assert::IsTrue(vertical == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Vertical));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (DefaultLayoutsParseEmpty)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray layoutsArray{};
|
||||||
|
root.SetNamedValue(NonLocalizable::DefaultLayoutsIds::DefaultLayoutsArrayID, layoutsArray);
|
||||||
|
json::to_file(DefaultLayouts::DefaultLayoutsFileName(), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
|
||||||
|
Layout priorityGrid{
|
||||||
|
.uuid = GUID_NULL,
|
||||||
|
.type = FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid,
|
||||||
|
.showSpacing = DefaultValues::ShowSpacing,
|
||||||
|
.spacing = DefaultValues::Spacing,
|
||||||
|
.zoneCount = DefaultValues::ZoneCount,
|
||||||
|
.sensitivityRadius = DefaultValues::SensitivityRadius
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert::IsTrue(priorityGrid == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Horizontal));
|
||||||
|
Assert::IsTrue(priorityGrid == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Vertical));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (DefaultLayoutsNoFile)
|
||||||
|
{
|
||||||
|
// test
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
|
||||||
|
Layout priorityGrid{
|
||||||
|
.uuid = GUID_NULL,
|
||||||
|
.type = FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid,
|
||||||
|
.showSpacing = DefaultValues::ShowSpacing,
|
||||||
|
.spacing = DefaultValues::Spacing,
|
||||||
|
.zoneCount = DefaultValues::ZoneCount,
|
||||||
|
.sensitivityRadius = DefaultValues::SensitivityRadius
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert::IsTrue(priorityGrid == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Horizontal));
|
||||||
|
Assert::IsTrue(priorityGrid == DefaultLayouts::instance().GetDefaultLayout(MonitorConfiguraionType::Vertical));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
<ClCompile Include="AppliedLayoutsTests.Spec.cpp" />
|
<ClCompile Include="AppliedLayoutsTests.Spec.cpp" />
|
||||||
<ClCompile Include="AppZoneHistoryTests.Spec.cpp" />
|
<ClCompile Include="AppZoneHistoryTests.Spec.cpp" />
|
||||||
<ClCompile Include="CustomLayoutsTests.Spec.cpp" />
|
<ClCompile Include="CustomLayoutsTests.Spec.cpp" />
|
||||||
|
<ClCompile Include="DefaultLayoutsTests.Spec.cpp" />
|
||||||
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
||||||
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
||||||
<ClCompile Include="LayoutHotkeysTests.Spec.cpp" />
|
<ClCompile Include="LayoutHotkeysTests.Spec.cpp" />
|
||||||
|
|||||||
@@ -57,6 +57,9 @@
|
|||||||
<ClCompile Include="WorkAreaIdTests.Spec.cpp">
|
<ClCompile Include="WorkAreaIdTests.Spec.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="DefaultLayoutsTests.Spec.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h">
|
<ClInclude Include="pch.h">
|
||||||
|
|||||||
@@ -2,20 +2,14 @@
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <FancyZonesLib/util.h>
|
|
||||||
#include <FancyZonesLib/ZoneSet.h>
|
|
||||||
#include <FancyZonesLib/WorkArea.h>
|
#include <FancyZonesLib/WorkArea.h>
|
||||||
#include <FancyZonesLib/FancyZones.h>
|
|
||||||
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
|
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
|
||||||
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
||||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||||
#include <FancyZonesLib/JsonHelpers.h>
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
#include <common/utils/process_path.h>
|
#include <common/utils/process_path.h>
|
||||||
|
|
||||||
#include <CppUnitTestLogger.h>
|
|
||||||
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
namespace FancyZonesUnitTests
|
namespace FancyZonesUnitTests
|
||||||
@@ -40,36 +34,43 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
AppZoneHistory::instance().LoadData();
|
AppZoneHistory::instance().LoadData();
|
||||||
AppliedLayouts::instance().LoadData();
|
AppliedLayouts::instance().LoadData();
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD_CLEANUP(CleanUp)
|
TEST_METHOD_CLEANUP(CleanUp)
|
||||||
{
|
{
|
||||||
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
||||||
std::filesystem::remove(AppZoneHistory::AppZoneHistoryFileName());
|
std::filesystem::remove(AppZoneHistory::AppZoneHistoryFileName());
|
||||||
|
|
||||||
|
std::filesystem::remove(DefaultLayouts::DefaultLayoutsFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (CreateWorkArea)
|
TEST_METHOD (CreateWorkArea)
|
||||||
{
|
{
|
||||||
|
const auto defaultLayout = DefaultLayouts::instance().GetDefaultLayout();
|
||||||
|
|
||||||
auto workArea = MakeWorkArea({}, Mocks::Monitor(), m_uniqueId, m_emptyUniqueId);
|
auto workArea = MakeWorkArea({}, Mocks::Monitor(), m_uniqueId, m_emptyUniqueId);
|
||||||
Assert::IsFalse(workArea == nullptr);
|
Assert::IsFalse(workArea == nullptr);
|
||||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||||
|
|
||||||
auto* zoneSet{ workArea->ZoneSet() };
|
auto* zoneSet{ workArea->ZoneSet() };
|
||||||
Assert::IsNotNull(zoneSet);
|
Assert::IsNotNull(zoneSet);
|
||||||
Assert::AreEqual(static_cast<int>(zoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
Assert::AreEqual(static_cast<int>(defaultLayout.type), static_cast<int>(zoneSet->LayoutType()));
|
||||||
Assert::AreEqual(zoneSet->GetZones().size(), static_cast<size_t>(3));
|
Assert::AreEqual(static_cast<size_t>(defaultLayout.zoneCount), zoneSet->GetZones().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (CreateCombinedWorkArea)
|
TEST_METHOD (CreateCombinedWorkArea)
|
||||||
{
|
{
|
||||||
|
const auto defaultLayout = DefaultLayouts::instance().GetDefaultLayout();
|
||||||
|
|
||||||
auto workArea = MakeWorkArea({}, {}, m_uniqueId, m_emptyUniqueId);
|
auto workArea = MakeWorkArea({}, {}, m_uniqueId, m_emptyUniqueId);
|
||||||
Assert::IsFalse(workArea == nullptr);
|
Assert::IsFalse(workArea == nullptr);
|
||||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||||
|
|
||||||
auto* zoneSet{ workArea->ZoneSet() };
|
auto* zoneSet{ workArea->ZoneSet() };
|
||||||
Assert::IsNotNull(zoneSet);
|
Assert::IsNotNull(zoneSet);
|
||||||
Assert::AreEqual(static_cast<int>(zoneSet->LayoutType()), static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid));
|
Assert::AreEqual(static_cast<int>(defaultLayout.type), static_cast<int>(zoneSet->LayoutType()));
|
||||||
Assert::AreEqual(zoneSet->GetZones().size(), static_cast<size_t>(3));
|
Assert::AreEqual(static_cast<size_t>(defaultLayout.zoneCount), zoneSet->GetZones().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (CreateWorkAreaClonedFromParent)
|
TEST_METHOD (CreateWorkAreaClonedFromParent)
|
||||||
@@ -107,6 +108,67 @@ namespace FancyZonesUnitTests
|
|||||||
Assert::AreEqual(layout.spacing, actualLayout.spacing);
|
Assert::AreEqual(layout.spacing, actualLayout.spacing);
|
||||||
Assert::AreEqual(layout.zoneCount, actualLayout.zoneCount);
|
Assert::AreEqual(layout.zoneCount, actualLayout.zoneCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (CreateWorkAreaWithCustomDefault)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray layoutsArray{};
|
||||||
|
json::JsonObject layout{};
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::UuidID, json::value(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}"));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::TypeID, json::value(L"custom"));
|
||||||
|
json::JsonObject item{};
|
||||||
|
item.SetNamedValue(NonLocalizable::DefaultLayoutsIds::MonitorConfigurationTypeID, json::value(L"horizontal"));
|
||||||
|
item.SetNamedValue(NonLocalizable::DefaultLayoutsIds::LayoutID, layout);
|
||||||
|
layoutsArray.Append(item);
|
||||||
|
root.SetNamedValue(NonLocalizable::DefaultLayoutsIds::DefaultLayoutsArrayID, layoutsArray);
|
||||||
|
|
||||||
|
json::to_file(DefaultLayouts::DefaultLayoutsFileName(), root);
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
|
||||||
|
// test
|
||||||
|
auto workArea = MakeWorkArea({}, Mocks::Monitor(), m_uniqueId, m_emptyUniqueId);
|
||||||
|
Assert::IsFalse(workArea == nullptr);
|
||||||
|
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||||
|
|
||||||
|
auto* zoneSet{ workArea->ZoneSet() };
|
||||||
|
Assert::IsNotNull(zoneSet);
|
||||||
|
Assert::AreEqual(static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::Custom), static_cast<int>(zoneSet->LayoutType()));
|
||||||
|
Assert::IsTrue(FancyZonesUtils::GuidFromString(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}").value() == zoneSet->Id());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (CreateWorkAreaWithTemplateDefault)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray layoutsArray{};
|
||||||
|
json::JsonObject layout{};
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::TypeID, json::value(L"grid"));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ShowSpacingID, json::value(true));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SpacingID, json::value(1));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::ZoneCountID, json::value(4));
|
||||||
|
layout.SetNamedValue(NonLocalizable::DefaultLayoutsIds::SensitivityRadiusID, json::value(30));
|
||||||
|
|
||||||
|
json::JsonObject item{};
|
||||||
|
item.SetNamedValue(NonLocalizable::DefaultLayoutsIds::MonitorConfigurationTypeID, json::value(L"horizontal"));
|
||||||
|
item.SetNamedValue(NonLocalizable::DefaultLayoutsIds::LayoutID, layout);
|
||||||
|
layoutsArray.Append(item);
|
||||||
|
root.SetNamedValue(NonLocalizable::DefaultLayoutsIds::DefaultLayoutsArrayID, layoutsArray);
|
||||||
|
|
||||||
|
json::to_file(DefaultLayouts::DefaultLayoutsFileName(), root);
|
||||||
|
DefaultLayouts::instance().LoadData();
|
||||||
|
|
||||||
|
// test
|
||||||
|
auto workArea = MakeWorkArea({}, Mocks::Monitor(), m_uniqueId, m_emptyUniqueId);
|
||||||
|
Assert::IsFalse(workArea == nullptr);
|
||||||
|
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||||
|
|
||||||
|
auto* zoneSet{ workArea->ZoneSet() };
|
||||||
|
Assert::IsNotNull(zoneSet);
|
||||||
|
Assert::AreEqual(static_cast<int>(FancyZonesDataTypes::ZoneSetLayoutType::Grid), static_cast<int>(zoneSet->LayoutType()));
|
||||||
|
Assert::AreEqual(static_cast<size_t>(4), zoneSet->GetZones().size());
|
||||||
|
Assert::IsTrue(GUID_NULL == zoneSet->Id());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CLASS (WorkAreaUnitTests)
|
TEST_CLASS (WorkAreaUnitTests)
|
||||||
|
|||||||
@@ -113,6 +113,13 @@ namespace FancyZonesEditor
|
|||||||
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Data_Title, MessageBoxButton.OK);
|
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Data_Title, MessageBoxButton.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseResult = FancyZonesEditorIO.ParseDefaultLayouts();
|
||||||
|
if (!parseResult.Result)
|
||||||
|
{
|
||||||
|
Logger.LogError(ParsingErrorReportTag + ": " + parseResult.Message + "; " + ParsingErrorDataTag + ": " + parseResult.MalformedData);
|
||||||
|
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Data_Title, MessageBoxButton.OK);
|
||||||
|
}
|
||||||
|
|
||||||
MainWindowSettingsModel settings = ((App)Current).MainWindowSettings;
|
MainWindowSettingsModel settings = ((App)Current).MainWindowSettings;
|
||||||
settings.UpdateSelectedLayoutModel();
|
settings.UpdateSelectedLayoutModel();
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
FontSize="24" />
|
FontSize="24" />
|
||||||
|
|
||||||
<ui:GridView ItemsSource="{Binding DefaultModels}"
|
<ui:GridView ItemsSource="{Binding TemplateModels}"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
ItemTemplate="{StaticResource LayoutItemTemplate}"
|
ItemTemplate="{StaticResource LayoutItemTemplate}"
|
||||||
AutomationProperties.LabeledBy="{Binding ElementName=TemplatesHeaderBlock}"
|
AutomationProperties.LabeledBy="{Binding ElementName=TemplatesHeaderBlock}"
|
||||||
@@ -589,9 +589,6 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Margin="0, 12, 0, 0">
|
<StackPanel Margin="0, 12, 0, 0">
|
||||||
<TextBlock Text="{x:Static props:Resources.Distance_adjacent_zones}"
|
<TextBlock Text="{x:Static props:Resources.Distance_adjacent_zones}"
|
||||||
x:Name="distanceTitle"
|
x:Name="distanceTitle"
|
||||||
@@ -635,6 +632,97 @@
|
|||||||
VerticalAlignment="Center" />
|
VerticalAlignment="Center" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="0,16,0,0"
|
||||||
|
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeTemplateToVisibilityConverter}}">
|
||||||
|
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="16"
|
||||||
|
Margin="0,16,0,0"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Number_of_zones}"
|
||||||
|
ToolTip="{x:Static props:Resources.Number_of_zones}"
|
||||||
|
Text="" />
|
||||||
|
|
||||||
|
<ui:NumberBox Minimum="1"
|
||||||
|
Maximum="128"
|
||||||
|
Width="216"
|
||||||
|
KeyDown="EditDialogNumberBox_KeyDown"
|
||||||
|
Margin="12,0,0,0"
|
||||||
|
Header="{x:Static props:Resources.Number_of_zones}"
|
||||||
|
Loaded="NumberBox_Loaded"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Number_of_zones}"
|
||||||
|
SpinButtonPlacementMode="Compact"
|
||||||
|
Text="{Binding TemplateZoneCount}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="0,16,0,0">
|
||||||
|
|
||||||
|
<Button x:Name="SetLayoutAsHorizontalDefaultButton"
|
||||||
|
Click="SetLayoutAsHorizontalDefaultButton_Click"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Set_Layout_As_Horizontal_Default}"
|
||||||
|
ToolTip="{x:Static props:Resources.Set_Layout_As_Horizontal_Default}"
|
||||||
|
Style="{StaticResource IconOnlyButtonStyle}"
|
||||||
|
Visibility="{Binding CanBeSetAsHorizontalDefault, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<Button.Content>
|
||||||
|
<TextBlock AutomationProperties.Name="{x:Static props:Resources.Set_Layout_As_Horizontal_Default}"
|
||||||
|
FontSize="14">
|
||||||
|
<Run Text="" FontFamily="Segoe MDL2 Assets"/>
|
||||||
|
<Run Text="{x:Static props:Resources.Default_Layout_Horizontal}"/>
|
||||||
|
</TextBlock>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
<Button x:Name="HorizontalDefaultLayoutButton"
|
||||||
|
Click="HorizontalDefaultLayoutButton_Click"
|
||||||
|
ToolTip="{x:Static props:Resources.Default_Layout_Horizontal}"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Default_Layout_Horizontal}"
|
||||||
|
Style="{StaticResource IconOnlyButtonStyle}"
|
||||||
|
Visibility="{Binding IsHorizontalDefault, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<Button.Content>
|
||||||
|
<TextBlock AutomationProperties.Name="{x:Static props:Resources.Default_Layout_Horizontal}"
|
||||||
|
FontSize="14">
|
||||||
|
<Run Text="" FontFamily="Segoe MDL2 Assets"/>
|
||||||
|
<Run Text="{x:Static props:Resources.Default_Layout_Horizontal}"/>
|
||||||
|
</TextBlock>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button x:Name="SetLayoutAsVerticalDefaultButton"
|
||||||
|
Click="SetLayoutAsVerticalDefaultButton_Click"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Set_Layout_As_Vertical_Default}"
|
||||||
|
ToolTip="{x:Static props:Resources.Set_Layout_As_Vertical_Default}"
|
||||||
|
Style="{StaticResource IconOnlyButtonStyle}"
|
||||||
|
Visibility="{Binding CanBeSetAsVerticalDefault, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<Button.Content>
|
||||||
|
<TextBlock AutomationProperties.Name="{x:Static props:Resources.Set_Layout_As_Vertical_Default}"
|
||||||
|
FontSize="14">
|
||||||
|
<Run Text="" FontFamily="Segoe MDL2 Assets"/>
|
||||||
|
<Run Text="{x:Static props:Resources.Default_Layout_Vertical}"/>
|
||||||
|
</TextBlock>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
<Button x:Name="VerticalDefaultLayoutButton"
|
||||||
|
Click="VerticalDefaultLayoutButton_Click"
|
||||||
|
ToolTip="{x:Static props:Resources.Default_Layout_Vertical}"
|
||||||
|
AutomationProperties.Name="{x:Static props:Resources.Default_Layout_Vertical}"
|
||||||
|
Style="{StaticResource IconOnlyButtonStyle}"
|
||||||
|
Visibility="{Binding IsVerticalDefault, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<Button.Content>
|
||||||
|
<TextBlock AutomationProperties.Name="{x:Static props:Resources.Default_Layout_Vertical}"
|
||||||
|
FontSize="14">
|
||||||
|
<Run Text="" FontFamily="Segoe MDL2 Assets"/>
|
||||||
|
<Run Text="{x:Static props:Resources.Default_Layout_Vertical}"/>
|
||||||
|
</TextBlock>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ui:ContentDialog>
|
</ui:ContentDialog>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
private readonly MainWindowSettingsModel _settings = ((App)Application.Current).MainWindowSettings;
|
private readonly MainWindowSettingsModel _settings = ((App)Application.Current).MainWindowSettings;
|
||||||
private LayoutModel _backup;
|
private LayoutModel _backup;
|
||||||
|
private List<LayoutModel> _defaultLayoutsBackup;
|
||||||
|
|
||||||
private ContentDialog _openedDialog;
|
private ContentDialog _openedDialog;
|
||||||
private TextBlock _createLayoutAnnounce;
|
private TextBlock _createLayoutAnnounce;
|
||||||
@@ -322,6 +323,8 @@ namespace FancyZonesEditor
|
|||||||
_backup = new CanvasLayoutModel(canvas);
|
_backup = new CanvasLayoutModel(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_defaultLayoutsBackup = new List<LayoutModel>(MainWindowSettingsModel.DefaultLayouts.DefaultLayouts);
|
||||||
|
|
||||||
Keyboard.ClearFocus();
|
Keyboard.ClearFocus();
|
||||||
EditLayoutDialogTitle.Text = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Edit_Template, ((LayoutModel)dataContext).Name);
|
EditLayoutDialogTitle.Text = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Edit_Template, ((LayoutModel)dataContext).Name);
|
||||||
await EditLayoutDialog.ShowAsync();
|
await EditLayoutDialog.ShowAsync();
|
||||||
@@ -424,6 +427,7 @@ namespace FancyZonesEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
_backup = null;
|
_backup = null;
|
||||||
|
_defaultLayoutsBackup = null;
|
||||||
|
|
||||||
// update current settings
|
// update current settings
|
||||||
if (model == _settings.AppliedModel)
|
if (model == _settings.AppliedModel)
|
||||||
@@ -464,6 +468,8 @@ namespace FancyZonesEditor
|
|||||||
_backup = null;
|
_backup = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Reset(model.Uuid);
|
||||||
|
|
||||||
if (model == _settings.AppliedModel)
|
if (model == _settings.AppliedModel)
|
||||||
{
|
{
|
||||||
_settings.SetAppliedModel(_settings.BlankModel);
|
_settings.SetAppliedModel(_settings.BlankModel);
|
||||||
@@ -480,6 +486,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
App.FancyZonesEditorIO.SerializeAppliedLayouts();
|
App.FancyZonesEditorIO.SerializeAppliedLayouts();
|
||||||
App.FancyZonesEditorIO.SerializeCustomLayouts();
|
App.FancyZonesEditorIO.SerializeCustomLayouts();
|
||||||
|
App.FancyZonesEditorIO.SerializeDefaultLayouts();
|
||||||
model.Delete();
|
model.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -543,6 +550,12 @@ namespace FancyZonesEditor
|
|||||||
_settings.RestoreSelectedModel(_backup);
|
_settings.RestoreSelectedModel(_backup);
|
||||||
_backup = null;
|
_backup = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_defaultLayoutsBackup != null)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Restore(_defaultLayoutsBackup);
|
||||||
|
_defaultLayoutsBackup = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NumberBox_Loaded(object sender, RoutedEventArgs e)
|
private void NumberBox_Loaded(object sender, RoutedEventArgs e)
|
||||||
@@ -586,5 +599,45 @@ namespace FancyZonesEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetLayoutAsVerticalDefaultButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var dataContext = ((FrameworkElement)sender).DataContext;
|
||||||
|
if (dataContext is LayoutModel model)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Set(model, MonitorConfigurationType.Vertical);
|
||||||
|
App.FancyZonesEditorIO.SerializeDefaultLayouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetLayoutAsHorizontalDefaultButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var dataContext = ((FrameworkElement)sender).DataContext;
|
||||||
|
if (dataContext is LayoutModel model)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Set(model, MonitorConfigurationType.Horizontal);
|
||||||
|
App.FancyZonesEditorIO.SerializeDefaultLayouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HorizontalDefaultLayoutButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var dataContext = ((FrameworkElement)sender).DataContext;
|
||||||
|
if (dataContext is LayoutModel model)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Reset(MonitorConfigurationType.Horizontal);
|
||||||
|
App.FancyZonesEditorIO.SerializeDefaultLayouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VerticalDefaultLayoutButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var dataContext = ((FrameworkElement)sender).DataContext;
|
||||||
|
if (dataContext is LayoutModel model)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Reset(MonitorConfigurationType.Vertical);
|
||||||
|
App.FancyZonesEditorIO.SerializeDefaultLayouts();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// 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.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace FancyZonesEditor.Models
|
||||||
|
{
|
||||||
|
public class DefaultLayoutsModel : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
private static int Count { get; } = Enum.GetValues(typeof(MonitorConfigurationType)).Length;
|
||||||
|
|
||||||
|
public List<LayoutModel> DefaultLayouts { get; } = new List<LayoutModel>(Count);
|
||||||
|
|
||||||
|
public DefaultLayoutsModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
public void Reset(MonitorConfigurationType type)
|
||||||
|
{
|
||||||
|
Set(MainWindowSettingsModel.TemplateModels[(int)LayoutType.PriorityGrid], type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(string uuid)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
if (DefaultLayouts[i].Uuid == uuid)
|
||||||
|
{
|
||||||
|
Set(MainWindowSettingsModel.TemplateModels[(int)LayoutType.PriorityGrid], (MonitorConfigurationType)i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(LayoutModel layout, MonitorConfigurationType type)
|
||||||
|
{
|
||||||
|
if (DefaultLayouts.Count <= (int)type)
|
||||||
|
{
|
||||||
|
DefaultLayouts.Insert((int)type, layout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultLayouts[(int)type] = layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
FirePropertyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore(List<LayoutModel> layouts)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
Set(layouts[i], (MonitorConfigurationType)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void FirePropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,8 @@ namespace FancyZonesEditor.Models
|
|||||||
{
|
{
|
||||||
_guid = Guid.NewGuid();
|
_guid = Guid.NewGuid();
|
||||||
Type = LayoutType.Custom;
|
Type = LayoutType.Custom;
|
||||||
|
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.PropertyChanged += DefaultLayouts_PropertyChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LayoutModel(string name)
|
protected LayoutModel(string name)
|
||||||
@@ -144,6 +146,38 @@ namespace FancyZonesEditor.Models
|
|||||||
|
|
||||||
private bool _isApplied;
|
private bool _isApplied;
|
||||||
|
|
||||||
|
public bool IsHorizontalDefault
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return MainWindowSettingsModel.DefaultLayouts.DefaultLayouts[(int)MonitorConfigurationType.Horizontal].Uuid == this.Uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanBeSetAsHorizontalDefault
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return MainWindowSettingsModel.DefaultLayouts.DefaultLayouts[(int)MonitorConfigurationType.Horizontal].Uuid != this.Uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsVerticalDefault
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return MainWindowSettingsModel.DefaultLayouts.DefaultLayouts[(int)MonitorConfigurationType.Vertical].Uuid == this.Uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanBeSetAsVerticalDefault
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return MainWindowSettingsModel.DefaultLayouts.DefaultLayouts[(int)MonitorConfigurationType.Vertical].Uuid != this.Uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int SensitivityRadius
|
public int SensitivityRadius
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -334,5 +368,13 @@ namespace FancyZonesEditor.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DefaultLayouts_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
FirePropertyChanged(nameof(IsHorizontalDefault));
|
||||||
|
FirePropertyChanged(nameof(IsVerticalDefault));
|
||||||
|
FirePropertyChanged(nameof(CanBeSetAsHorizontalDefault));
|
||||||
|
FirePropertyChanged(nameof(CanBeSetAsVerticalDefault));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ namespace FancyZonesEditor
|
|||||||
VirtualDesktopId,
|
VirtualDesktopId,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-localizable strings
|
|
||||||
public static readonly string RegistryPath = "SOFTWARE\\SuperFancyZones";
|
|
||||||
public static readonly string FullRegistryPath = "HKEY_CURRENT_USER\\" + RegistryPath;
|
|
||||||
|
|
||||||
public bool IsCustomLayoutActive
|
public bool IsCustomLayoutActive
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -43,6 +39,8 @@ namespace FancyZonesEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DefaultLayoutsModel DefaultLayouts { get; } = new DefaultLayoutsModel();
|
||||||
|
|
||||||
public MainWindowSettingsModel()
|
public MainWindowSettingsModel()
|
||||||
{
|
{
|
||||||
// Initialize default layout models: Blank, Focus, Columns, Rows, Grid, and PriorityGrid
|
// Initialize default layout models: Blank, Focus, Columns, Rows, Grid, and PriorityGrid
|
||||||
@@ -51,11 +49,11 @@ namespace FancyZonesEditor
|
|||||||
TemplateZoneCount = 0,
|
TemplateZoneCount = 0,
|
||||||
SensitivityRadius = 0,
|
SensitivityRadius = 0,
|
||||||
};
|
};
|
||||||
DefaultModels.Insert((int)LayoutType.Blank, blankModel);
|
TemplateModels.Insert((int)LayoutType.Blank, blankModel);
|
||||||
|
|
||||||
var focusModel = new CanvasLayoutModel(Properties.Resources.Template_Layout_Focus, LayoutType.Focus);
|
var focusModel = new CanvasLayoutModel(Properties.Resources.Template_Layout_Focus, LayoutType.Focus);
|
||||||
focusModel.InitTemplateZones();
|
focusModel.InitTemplateZones();
|
||||||
DefaultModels.Insert((int)LayoutType.Focus, focusModel);
|
TemplateModels.Insert((int)LayoutType.Focus, focusModel);
|
||||||
|
|
||||||
var columnsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Columns, LayoutType.Columns)
|
var columnsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Columns, LayoutType.Columns)
|
||||||
{
|
{
|
||||||
@@ -63,7 +61,7 @@ namespace FancyZonesEditor
|
|||||||
RowPercents = new List<int>(1) { GridLayoutModel.GridMultiplier },
|
RowPercents = new List<int>(1) { GridLayoutModel.GridMultiplier },
|
||||||
};
|
};
|
||||||
columnsModel.InitTemplateZones();
|
columnsModel.InitTemplateZones();
|
||||||
DefaultModels.Insert((int)LayoutType.Columns, columnsModel);
|
TemplateModels.Insert((int)LayoutType.Columns, columnsModel);
|
||||||
|
|
||||||
var rowsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Rows, LayoutType.Rows)
|
var rowsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Rows, LayoutType.Rows)
|
||||||
{
|
{
|
||||||
@@ -71,15 +69,19 @@ namespace FancyZonesEditor
|
|||||||
ColumnPercents = new List<int>(1) { GridLayoutModel.GridMultiplier },
|
ColumnPercents = new List<int>(1) { GridLayoutModel.GridMultiplier },
|
||||||
};
|
};
|
||||||
rowsModel.InitTemplateZones();
|
rowsModel.InitTemplateZones();
|
||||||
DefaultModels.Insert((int)LayoutType.Rows, rowsModel);
|
TemplateModels.Insert((int)LayoutType.Rows, rowsModel);
|
||||||
|
|
||||||
var gridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Grid, LayoutType.Grid);
|
var gridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Grid, LayoutType.Grid);
|
||||||
gridModel.InitTemplateZones();
|
gridModel.InitTemplateZones();
|
||||||
DefaultModels.Insert((int)LayoutType.Grid, gridModel);
|
TemplateModels.Insert((int)LayoutType.Grid, gridModel);
|
||||||
|
|
||||||
var priorityGridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Priority_Grid, LayoutType.PriorityGrid);
|
var priorityGridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Priority_Grid, LayoutType.PriorityGrid);
|
||||||
priorityGridModel.InitTemplateZones();
|
priorityGridModel.InitTemplateZones();
|
||||||
DefaultModels.Insert((int)LayoutType.PriorityGrid, priorityGridModel);
|
TemplateModels.Insert((int)LayoutType.PriorityGrid, priorityGridModel);
|
||||||
|
|
||||||
|
// set default layouts
|
||||||
|
DefaultLayouts.Set(priorityGridModel, MonitorConfigurationType.Horizontal);
|
||||||
|
DefaultLayouts.Set(priorityGridModel, MonitorConfigurationType.Vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsShiftKeyPressed - is the shift key currently being held down
|
// IsShiftKeyPressed - is the shift key currently being held down
|
||||||
@@ -126,11 +128,11 @@ namespace FancyZonesEditor
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return DefaultModels[(int)LayoutType.Blank];
|
return TemplateModels[(int)LayoutType.Blank];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IList<LayoutModel> DefaultModels { get; } = new List<LayoutModel>(6);
|
public static IList<LayoutModel> TemplateModels { get; } = new List<LayoutModel>(6);
|
||||||
|
|
||||||
public static ObservableCollection<LayoutModel> CustomModels
|
public static ObservableCollection<LayoutModel> CustomModels
|
||||||
{
|
{
|
||||||
@@ -213,7 +215,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
public void InitModels()
|
public void InitModels()
|
||||||
{
|
{
|
||||||
foreach (var model in DefaultModels)
|
foreach (var model in TemplateModels)
|
||||||
{
|
{
|
||||||
model.InitTemplateZones();
|
model.InitTemplateZones();
|
||||||
}
|
}
|
||||||
@@ -239,7 +241,7 @@ namespace FancyZonesEditor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (LayoutModel model in DefaultModels)
|
foreach (LayoutModel model in TemplateModels)
|
||||||
{
|
{
|
||||||
if (model.Type == currentApplied.Type)
|
if (model.Type == currentApplied.Type)
|
||||||
{
|
{
|
||||||
@@ -261,7 +263,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
if (foundModel == null)
|
if (foundModel == null)
|
||||||
{
|
{
|
||||||
foundModel = DefaultModels[(int)LayoutType.PriorityGrid];
|
foundModel = TemplateModels[(int)LayoutType.PriorityGrid];
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSelectedModel(foundModel);
|
SetSelectedModel(foundModel);
|
||||||
@@ -321,9 +323,9 @@ namespace FancyZonesEditor
|
|||||||
AppliedModel = model;
|
AppliedModel = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDefaultModels()
|
public void UpdateTemplateModels()
|
||||||
{
|
{
|
||||||
foreach (LayoutModel model in DefaultModels)
|
foreach (LayoutModel model in TemplateModels)
|
||||||
{
|
{
|
||||||
if (App.Overlay.CurrentLayoutSettings.Type == model.Type && App.Overlay.CurrentLayoutSettings.ZoneCount != model.TemplateZoneCount)
|
if (App.Overlay.CurrentLayoutSettings.Type == model.Type && App.Overlay.CurrentLayoutSettings.ZoneCount != model.TemplateZoneCount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace FancyZonesEditor.Models
|
||||||
|
{
|
||||||
|
public enum MonitorConfigurationType
|
||||||
|
{
|
||||||
|
Horizontal = 0,
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,7 +107,7 @@ namespace FancyZonesEditor
|
|||||||
if (settings != null)
|
if (settings != null)
|
||||||
{
|
{
|
||||||
settings.SetAppliedModel(null);
|
settings.SetAppliedModel(null);
|
||||||
settings.UpdateDefaultModels();
|
settings.UpdateTemplateModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
|
|||||||
@@ -222,6 +222,24 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Default layout for horizontal monitor orientation.
|
||||||
|
/// </summary>
|
||||||
|
public static string Default_Layout_Horizontal {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Default_Layout_Horizontal", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Default layout for vertical monitor orientation.
|
||||||
|
/// </summary>
|
||||||
|
public static string Default_Layout_Vertical {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Default_Layout_Vertical", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Delete.
|
/// Looks up a localized string similar to Delete.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -451,6 +469,15 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to An error occurred while parsing default layouts..
|
||||||
|
/// </summary>
|
||||||
|
public static string Error_Parsing_Default_Layouts_Message {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Error_Parsing_Default_Layouts_Message", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Error parsing device info data..
|
/// Looks up a localized string similar to Error parsing device info data..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -762,6 +789,24 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Set layout as a default for horizontal monitor orientation.
|
||||||
|
/// </summary>
|
||||||
|
public static string Set_Layout_As_Horizontal_Default {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Set_Layout_As_Horizontal_Default", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Set layout as a default for vertical monitor orientation.
|
||||||
|
/// </summary>
|
||||||
|
public static string Set_Layout_As_Vertical_Default {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Set_Layout_As_Vertical_Default", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Template settings.
|
/// Looks up a localized string similar to Template settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -414,4 +414,19 @@
|
|||||||
<data name="Slider_Value" xml:space="preserve">
|
<data name="Slider_Value" xml:space="preserve">
|
||||||
<value>{0} pixels</value>
|
<value>{0} pixels</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Default_Layout_Horizontal" xml:space="preserve">
|
||||||
|
<value>Default layout for horizontal monitor orientation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Set_Layout_As_Horizontal_Default" xml:space="preserve">
|
||||||
|
<value>Set layout as a default for horizontal monitor orientation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error_Parsing_Default_Layouts_Message" xml:space="preserve">
|
||||||
|
<value>An error occurred while parsing default layouts.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Default_Layout_Vertical" xml:space="preserve">
|
||||||
|
<value>Default layout for vertical monitor orientation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Set_Layout_As_Vertical_Default" xml:space="preserve">
|
||||||
|
<value>Set layout as a default for vertical monitor orientation</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -27,12 +27,15 @@ namespace FancyZonesEditor.Utils
|
|||||||
private const string GridJsonTag = "grid";
|
private const string GridJsonTag = "grid";
|
||||||
private const string PriorityGridJsonTag = "priority-grid";
|
private const string PriorityGridJsonTag = "priority-grid";
|
||||||
private const string CustomJsonTag = "custom";
|
private const string CustomJsonTag = "custom";
|
||||||
|
private const string HorizontalJsonTag = "horizontal";
|
||||||
|
private const string VerticalJsonTag = "vertical";
|
||||||
|
|
||||||
// Non-localizable strings: Files
|
// Non-localizable strings: Files
|
||||||
private const string AppliedLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\applied-layouts.json";
|
private const string AppliedLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\applied-layouts.json";
|
||||||
private const string LayoutHotkeysFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-hotkeys.json";
|
private const string LayoutHotkeysFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-hotkeys.json";
|
||||||
private const string LayoutTemplatesFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-templates.json";
|
private const string LayoutTemplatesFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-templates.json";
|
||||||
private const string CustomLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\custom-layouts.json";
|
private const string CustomLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\custom-layouts.json";
|
||||||
|
private const string DefaultLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\default-layouts.json";
|
||||||
private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
|
private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
|
||||||
|
|
||||||
// Non-localizable string: default virtual desktop id
|
// Non-localizable string: default virtual desktop id
|
||||||
@@ -56,6 +59,8 @@ namespace FancyZonesEditor.Utils
|
|||||||
|
|
||||||
public string FancyZonesCustomLayoutsFile { get; private set; }
|
public string FancyZonesCustomLayoutsFile { get; private set; }
|
||||||
|
|
||||||
|
public string FancyZonesDefaultLayoutsFile { get; private set; }
|
||||||
|
|
||||||
public string FancyZonesEditorParamsFile { get; private set; }
|
public string FancyZonesEditorParamsFile { get; private set; }
|
||||||
|
|
||||||
private enum CmdArgs
|
private enum CmdArgs
|
||||||
@@ -264,6 +269,35 @@ namespace FancyZonesEditor.Utils
|
|||||||
public List<LayoutHotkeyWrapper> LayoutHotkeys { get; set; }
|
public List<LayoutHotkeyWrapper> LayoutHotkeys { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default-layouts.json
|
||||||
|
private struct DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
public struct LayoutWrapper
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public bool ShowSpacing { get; set; }
|
||||||
|
|
||||||
|
public int Spacing { get; set; }
|
||||||
|
|
||||||
|
public int ZoneCount { get; set; }
|
||||||
|
|
||||||
|
public int SensitivityRadius { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MonitorConfiguration { get; set; }
|
||||||
|
|
||||||
|
public LayoutWrapper Layout { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// default-layouts.json
|
||||||
|
private struct DefaultLayoutsListWrapper
|
||||||
|
{
|
||||||
|
public List<DefaultLayoutWrapper> DefaultLayouts { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private struct EditorParams
|
private struct EditorParams
|
||||||
{
|
{
|
||||||
public int ProcessId { get; set; }
|
public int ProcessId { get; set; }
|
||||||
@@ -296,6 +330,7 @@ namespace FancyZonesEditor.Utils
|
|||||||
FancyZonesLayoutHotkeysFile = localAppDataDir + LayoutHotkeysFile;
|
FancyZonesLayoutHotkeysFile = localAppDataDir + LayoutHotkeysFile;
|
||||||
FancyZonesLayoutTemplatesFile = localAppDataDir + LayoutTemplatesFile;
|
FancyZonesLayoutTemplatesFile = localAppDataDir + LayoutTemplatesFile;
|
||||||
FancyZonesCustomLayoutsFile = localAppDataDir + CustomLayoutsFile;
|
FancyZonesCustomLayoutsFile = localAppDataDir + CustomLayoutsFile;
|
||||||
|
FancyZonesDefaultLayoutsFile = localAppDataDir + DefaultLayoutsFile;
|
||||||
FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
|
FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,6 +593,46 @@ namespace FancyZonesEditor.Utils
|
|||||||
return new ParsingResult(true);
|
return new ParsingResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ParsingResult ParseDefaultLayouts()
|
||||||
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
|
if (_fileSystem.File.Exists(FancyZonesDefaultLayoutsFile))
|
||||||
|
{
|
||||||
|
DefaultLayoutsListWrapper wrapper;
|
||||||
|
string dataString = string.Empty;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dataString = ReadFile(FancyZonesDefaultLayoutsFile);
|
||||||
|
wrapper = JsonSerializer.Deserialize<DefaultLayoutsListWrapper>(dataString, _options);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Default layouts parsing error", ex);
|
||||||
|
return new ParsingResult(false, ex.Message, dataString);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool parsingResult = SetDefaultLayouts(wrapper.DefaultLayouts);
|
||||||
|
if (parsingResult)
|
||||||
|
{
|
||||||
|
return new ParsingResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ParsingResult(false, FancyZonesEditor.Properties.Resources.Error_Parsing_Default_Layouts_Message, dataString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Default layouts parsing error", ex);
|
||||||
|
return new ParsingResult(false, ex.Message, dataString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ParsingResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void SerializeAppliedLayouts()
|
public void SerializeAppliedLayouts()
|
||||||
{
|
{
|
||||||
Logger.LogTrace();
|
Logger.LogTrace();
|
||||||
@@ -658,7 +733,7 @@ namespace FancyZonesEditor.Utils
|
|||||||
TemplateLayoutsListWrapper templates = new TemplateLayoutsListWrapper { };
|
TemplateLayoutsListWrapper templates = new TemplateLayoutsListWrapper { };
|
||||||
templates.LayoutTemplates = new List<TemplateLayoutWrapper>();
|
templates.LayoutTemplates = new List<TemplateLayoutWrapper>();
|
||||||
|
|
||||||
foreach (LayoutModel layout in MainWindowSettingsModel.DefaultModels)
|
foreach (LayoutModel layout in MainWindowSettingsModel.TemplateModels)
|
||||||
{
|
{
|
||||||
TemplateLayoutWrapper wrapper = new TemplateLayoutWrapper
|
TemplateLayoutWrapper wrapper = new TemplateLayoutWrapper
|
||||||
{
|
{
|
||||||
@@ -790,6 +865,107 @@ namespace FancyZonesEditor.Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SerializeDefaultLayouts()
|
||||||
|
{
|
||||||
|
DefaultLayoutsListWrapper layouts = new DefaultLayoutsListWrapper { };
|
||||||
|
layouts.DefaultLayouts = new List<DefaultLayoutWrapper>();
|
||||||
|
|
||||||
|
foreach (LayoutModel layout in MainWindowSettingsModel.TemplateModels)
|
||||||
|
{
|
||||||
|
if (layout.IsHorizontalDefault || layout.IsVerticalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper.LayoutWrapper layoutWrapper = new DefaultLayoutWrapper.LayoutWrapper
|
||||||
|
{
|
||||||
|
Uuid = string.Empty,
|
||||||
|
Type = LayoutTypeToJsonTag(layout.Type),
|
||||||
|
SensitivityRadius = layout.SensitivityRadius,
|
||||||
|
ZoneCount = layout.TemplateZoneCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (layout is GridLayoutModel grid)
|
||||||
|
{
|
||||||
|
layoutWrapper.ShowSpacing = grid.ShowSpacing;
|
||||||
|
layoutWrapper.Spacing = grid.Spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// can be both horizontal and vertical, so check separately
|
||||||
|
if (layout.IsHorizontalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper wrapper = new DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
MonitorConfiguration = MonitorConfigurationTypeToJsonTag(MonitorConfigurationType.Horizontal),
|
||||||
|
Layout = layoutWrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
layouts.DefaultLayouts.Add(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout.IsVerticalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper wrapper = new DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
MonitorConfiguration = MonitorConfigurationTypeToJsonTag(MonitorConfigurationType.Vertical),
|
||||||
|
Layout = layoutWrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
layouts.DefaultLayouts.Add(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (LayoutModel layout in MainWindowSettingsModel.CustomModels)
|
||||||
|
{
|
||||||
|
if (layout.IsHorizontalDefault || layout.IsVerticalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper.LayoutWrapper layoutWrapper = new DefaultLayoutWrapper.LayoutWrapper
|
||||||
|
{
|
||||||
|
Uuid = layout.Uuid,
|
||||||
|
Type = LayoutTypeToJsonTag(LayoutType.Custom),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (layout is GridLayoutModel grid)
|
||||||
|
{
|
||||||
|
layoutWrapper.ShowSpacing = grid.ShowSpacing;
|
||||||
|
layoutWrapper.Spacing = grid.Spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// can be both horizontal and vertical, so check separately
|
||||||
|
if (layout.IsHorizontalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper wrapper = new DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
MonitorConfiguration = MonitorConfigurationTypeToJsonTag(MonitorConfigurationType.Horizontal),
|
||||||
|
Layout = layoutWrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
layouts.DefaultLayouts.Add(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout.IsVerticalDefault)
|
||||||
|
{
|
||||||
|
DefaultLayoutWrapper wrapper = new DefaultLayoutWrapper
|
||||||
|
{
|
||||||
|
MonitorConfiguration = MonitorConfigurationTypeToJsonTag(MonitorConfigurationType.Vertical),
|
||||||
|
Layout = layoutWrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
layouts.DefaultLayouts.Add(wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string jsonString = JsonSerializer.Serialize(layouts, _options);
|
||||||
|
_fileSystem.File.WriteAllText(FancyZonesDefaultLayoutsFile, jsonString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Serialize default layout error", ex);
|
||||||
|
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string ReadFile(string fileName)
|
private string ReadFile(string fileName)
|
||||||
{
|
{
|
||||||
Logger.LogTrace();
|
Logger.LogTrace();
|
||||||
@@ -942,7 +1118,7 @@ namespace FancyZonesEditor.Utils
|
|||||||
foreach (var wrapper in templateLayouts)
|
foreach (var wrapper in templateLayouts)
|
||||||
{
|
{
|
||||||
LayoutType type = JsonTagToLayoutType(wrapper.Type);
|
LayoutType type = JsonTagToLayoutType(wrapper.Type);
|
||||||
LayoutModel layout = MainWindowSettingsModel.DefaultModels[(int)type];
|
LayoutModel layout = MainWindowSettingsModel.TemplateModels[(int)type];
|
||||||
|
|
||||||
layout.SensitivityRadius = wrapper.SensitivityRadius;
|
layout.SensitivityRadius = wrapper.SensitivityRadius;
|
||||||
layout.TemplateZoneCount = wrapper.ZoneCount;
|
layout.TemplateZoneCount = wrapper.ZoneCount;
|
||||||
@@ -972,6 +1148,41 @@ namespace FancyZonesEditor.Utils
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool SetDefaultLayouts(List<DefaultLayoutWrapper> layouts)
|
||||||
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
|
if (layouts == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var layout in layouts)
|
||||||
|
{
|
||||||
|
if (layout.Layout.Uuid != null && layout.Layout.Uuid != string.Empty)
|
||||||
|
{
|
||||||
|
MonitorConfigurationType type = JsonTagToMonitorConfigurationType(layout.MonitorConfiguration);
|
||||||
|
|
||||||
|
foreach (var customLayout in MainWindowSettingsModel.CustomModels)
|
||||||
|
{
|
||||||
|
if (customLayout.Uuid == layout.Layout.Uuid)
|
||||||
|
{
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Set(customLayout, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LayoutType layoutType = JsonTagToLayoutType(layout.Layout.Type);
|
||||||
|
MonitorConfigurationType type = JsonTagToMonitorConfigurationType(layout.MonitorConfiguration);
|
||||||
|
MainWindowSettingsModel.DefaultLayouts.Set(MainWindowSettingsModel.TemplateModels[(int)layoutType], type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private CanvasLayoutModel ParseCanvasInfo(CustomLayoutWrapper wrapper)
|
private CanvasLayoutModel ParseCanvasInfo(CustomLayoutWrapper wrapper)
|
||||||
{
|
{
|
||||||
var info = JsonSerializer.Deserialize<CanvasInfoWrapper>(wrapper.Info.GetRawText(), _options);
|
var info = JsonSerializer.Deserialize<CanvasInfoWrapper>(wrapper.Info.GetRawText(), _options);
|
||||||
@@ -1089,5 +1300,31 @@ namespace FancyZonesEditor.Utils
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MonitorConfigurationType JsonTagToMonitorConfigurationType(string tag)
|
||||||
|
{
|
||||||
|
switch (tag)
|
||||||
|
{
|
||||||
|
case HorizontalJsonTag:
|
||||||
|
return MonitorConfigurationType.Horizontal;
|
||||||
|
case VerticalJsonTag:
|
||||||
|
return MonitorConfigurationType.Vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MonitorConfigurationType.Horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string MonitorConfigurationTypeToJsonTag(MonitorConfigurationType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MonitorConfigurationType.Horizontal:
|
||||||
|
return HorizontalJsonTag;
|
||||||
|
case MonitorConfigurationType.Vertical:
|
||||||
|
return VerticalJsonTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HorizontalJsonTag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user