mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 13:35:31 +02:00
add horizontal and vertical options for MousePointerCrosshairs (#41789)
## Summary of the Pull Request This PR addresses two logged issues for MousePointerCrosshairs, these are: https://github.com/microsoft/PowerToys/issues/24944 https://github.com/microsoft/PowerToys/issues/31817 ## PR Checklist - [x] Closes: #24944, #31817 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments The PR adds a new combo box to MousePointerCrosshairs XAML options, this gives the option for 'both', 'vertical only' or 'horizontal only'. The default option is 'both' which mirrors the existing behavior. ## Validation Steps Performed Validation has been completed on two separate PCs, a Surface laptop 7 Pro and a Dell Workstation. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -94,6 +94,21 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetCrosshairsOrientation(CrosshairsOrientation orientation)
|
||||||
|
{
|
||||||
|
if (instance != nullptr)
|
||||||
|
{
|
||||||
|
auto dispatcherQueue = instance->m_dispatcherQueueController.DispatcherQueue();
|
||||||
|
dispatcherQueue.TryEnqueue([orientation]() {
|
||||||
|
if (instance != nullptr)
|
||||||
|
{
|
||||||
|
instance->m_crosshairs_orientation = orientation;
|
||||||
|
instance->UpdateCrosshairsPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class MouseButton
|
enum class MouseButton
|
||||||
{
|
{
|
||||||
@@ -147,6 +162,7 @@ private:
|
|||||||
int m_crosshairs_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE;
|
int m_crosshairs_border_size = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE;
|
||||||
bool m_crosshairs_is_fixed_length_enabled = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED;
|
bool m_crosshairs_is_fixed_length_enabled = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED;
|
||||||
int m_crosshairs_fixed_length = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
int m_crosshairs_fixed_length = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
||||||
|
CrosshairsOrientation m_crosshairs_orientation = static_cast<CrosshairsOrientation>(INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_ORIENTATION);
|
||||||
float m_crosshairs_opacity = max(0.f, min(1.f, (float)INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY / 100.0f));
|
float m_crosshairs_opacity = max(0.f, min(1.f, (float)INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY / 100.0f));
|
||||||
bool m_crosshairs_auto_hide = INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE;
|
bool m_crosshairs_auto_hide = INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE;
|
||||||
};
|
};
|
||||||
@@ -286,6 +302,8 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
|||||||
float halfPixelAdjustment = m_crosshairs_thickness % 2 == 1 ? 0.5f : 0.0f;
|
float halfPixelAdjustment = m_crosshairs_thickness % 2 == 1 ? 0.5f : 0.0f;
|
||||||
float borderSizePadding = m_crosshairs_border_size * 2.f;
|
float borderSizePadding = m_crosshairs_border_size * 2.f;
|
||||||
|
|
||||||
|
// Left and Right crosshairs (horizontal line)
|
||||||
|
if (m_crosshairs_orientation == CrosshairsOrientation::Both || m_crosshairs_orientation == CrosshairsOrientation::HorizontalOnly)
|
||||||
{
|
{
|
||||||
float leftCrosshairsFullScreenLength = ptCursor.x - ptMonitorUpperLeft.x - m_crosshairs_radius + halfPixelAdjustment * 2.f;
|
float leftCrosshairsFullScreenLength = ptCursor.x - ptMonitorUpperLeft.x - m_crosshairs_radius + halfPixelAdjustment * 2.f;
|
||||||
float leftCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : leftCrosshairsFullScreenLength;
|
float leftCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : leftCrosshairsFullScreenLength;
|
||||||
@@ -294,9 +312,7 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
|||||||
m_left_crosshairs_border.Size({ leftCrosshairsBorderLength, m_crosshairs_thickness + borderSizePadding });
|
m_left_crosshairs_border.Size({ leftCrosshairsBorderLength, m_crosshairs_thickness + borderSizePadding });
|
||||||
m_left_crosshairs.Offset({ ptCursor.x - m_crosshairs_radius + halfPixelAdjustment * 2.f, ptCursor.y + halfPixelAdjustment, .0f });
|
m_left_crosshairs.Offset({ ptCursor.x - m_crosshairs_radius + halfPixelAdjustment * 2.f, ptCursor.y + halfPixelAdjustment, .0f });
|
||||||
m_left_crosshairs.Size({ leftCrosshairsLength, static_cast<float>(m_crosshairs_thickness) });
|
m_left_crosshairs.Size({ leftCrosshairsLength, static_cast<float>(m_crosshairs_thickness) });
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
float rightCrosshairsFullScreenLength = static_cast<float>(ptMonitorBottomRight.x) - ptCursor.x - m_crosshairs_radius;
|
float rightCrosshairsFullScreenLength = static_cast<float>(ptMonitorBottomRight.x) - ptCursor.x - m_crosshairs_radius;
|
||||||
float rightCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : rightCrosshairsFullScreenLength;
|
float rightCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : rightCrosshairsFullScreenLength;
|
||||||
float rightCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : rightCrosshairsFullScreenLength + m_crosshairs_border_size;
|
float rightCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : rightCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||||
@@ -305,7 +321,17 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
|||||||
m_right_crosshairs.Offset({ static_cast<float>(ptCursor.x) + m_crosshairs_radius, ptCursor.y + halfPixelAdjustment, .0f });
|
m_right_crosshairs.Offset({ static_cast<float>(ptCursor.x) + m_crosshairs_radius, ptCursor.y + halfPixelAdjustment, .0f });
|
||||||
m_right_crosshairs.Size({ rightCrosshairsLength, static_cast<float>(m_crosshairs_thickness) });
|
m_right_crosshairs.Size({ rightCrosshairsLength, static_cast<float>(m_crosshairs_thickness) });
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hide horizontal crosshairs by setting size to 0
|
||||||
|
m_left_crosshairs_border.Size({ 0.0f, 0.0f });
|
||||||
|
m_left_crosshairs.Size({ 0.0f, 0.0f });
|
||||||
|
m_right_crosshairs_border.Size({ 0.0f, 0.0f });
|
||||||
|
m_right_crosshairs.Size({ 0.0f, 0.0f });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top and Bottom crosshairs (vertical line)
|
||||||
|
if (m_crosshairs_orientation == CrosshairsOrientation::Both || m_crosshairs_orientation == CrosshairsOrientation::VerticalOnly)
|
||||||
{
|
{
|
||||||
float topCrosshairsFullScreenLength = ptCursor.y - ptMonitorUpperLeft.y - m_crosshairs_radius + halfPixelAdjustment * 2.f;
|
float topCrosshairsFullScreenLength = ptCursor.y - ptMonitorUpperLeft.y - m_crosshairs_radius + halfPixelAdjustment * 2.f;
|
||||||
float topCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : topCrosshairsFullScreenLength;
|
float topCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : topCrosshairsFullScreenLength;
|
||||||
@@ -314,9 +340,7 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
|||||||
m_top_crosshairs_border.Size({ m_crosshairs_thickness + borderSizePadding, topCrosshairsBorderLength });
|
m_top_crosshairs_border.Size({ m_crosshairs_thickness + borderSizePadding, topCrosshairsBorderLength });
|
||||||
m_top_crosshairs.Offset({ ptCursor.x + halfPixelAdjustment, ptCursor.y - m_crosshairs_radius + halfPixelAdjustment * 2.f, .0f });
|
m_top_crosshairs.Offset({ ptCursor.x + halfPixelAdjustment, ptCursor.y - m_crosshairs_radius + halfPixelAdjustment * 2.f, .0f });
|
||||||
m_top_crosshairs.Size({ static_cast<float>(m_crosshairs_thickness), topCrosshairsLength });
|
m_top_crosshairs.Size({ static_cast<float>(m_crosshairs_thickness), topCrosshairsLength });
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
float bottomCrosshairsFullScreenLength = static_cast<float>(ptMonitorBottomRight.y) - ptCursor.y - m_crosshairs_radius;
|
float bottomCrosshairsFullScreenLength = static_cast<float>(ptMonitorBottomRight.y) - ptCursor.y - m_crosshairs_radius;
|
||||||
float bottomCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : bottomCrosshairsFullScreenLength;
|
float bottomCrosshairsLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length : bottomCrosshairsFullScreenLength;
|
||||||
float bottomCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : bottomCrosshairsFullScreenLength + m_crosshairs_border_size;
|
float bottomCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : bottomCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||||
@@ -325,6 +349,14 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
|||||||
m_bottom_crosshairs.Offset({ ptCursor.x + halfPixelAdjustment, static_cast<float>(ptCursor.y) + m_crosshairs_radius, .0f });
|
m_bottom_crosshairs.Offset({ ptCursor.x + halfPixelAdjustment, static_cast<float>(ptCursor.y) + m_crosshairs_radius, .0f });
|
||||||
m_bottom_crosshairs.Size({ static_cast<float>(m_crosshairs_thickness), bottomCrosshairsLength });
|
m_bottom_crosshairs.Size({ static_cast<float>(m_crosshairs_thickness), bottomCrosshairsLength });
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hide vertical crosshairs by setting size to 0
|
||||||
|
m_top_crosshairs_border.Size({ 0.0f, 0.0f });
|
||||||
|
m_top_crosshairs.Size({ 0.0f, 0.0f });
|
||||||
|
m_bottom_crosshairs_border.Size({ 0.0f, 0.0f });
|
||||||
|
m_bottom_crosshairs.Size({ 0.0f, 0.0f });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK InclusiveCrosshairs::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept
|
LRESULT CALLBACK InclusiveCrosshairs::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept
|
||||||
@@ -398,6 +430,7 @@ void InclusiveCrosshairs::ApplySettings(InclusiveCrosshairsSettings& settings, b
|
|||||||
m_crosshairs_auto_hide = settings.crosshairsAutoHide;
|
m_crosshairs_auto_hide = settings.crosshairsAutoHide;
|
||||||
m_crosshairs_is_fixed_length_enabled = settings.crosshairsIsFixedLengthEnabled;
|
m_crosshairs_is_fixed_length_enabled = settings.crosshairsIsFixedLengthEnabled;
|
||||||
m_crosshairs_fixed_length = settings.crosshairsFixedLength;
|
m_crosshairs_fixed_length = settings.crosshairsFixedLength;
|
||||||
|
m_crosshairs_orientation = settings.crosshairsOrientation;
|
||||||
|
|
||||||
if (applyToRunTimeObjects)
|
if (applyToRunTimeObjects)
|
||||||
{
|
{
|
||||||
@@ -618,6 +651,11 @@ void InclusiveCrosshairsSetExternalControl(bool enabled)
|
|||||||
InclusiveCrosshairs::SetExternalControl(enabled);
|
InclusiveCrosshairs::SetExternalControl(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InclusiveCrosshairsSetOrientation(CrosshairsOrientation orientation)
|
||||||
|
{
|
||||||
|
InclusiveCrosshairs::SetCrosshairsOrientation(orientation);
|
||||||
|
}
|
||||||
|
|
||||||
int InclusiveCrosshairsMain(HINSTANCE hInstance, InclusiveCrosshairsSettings& settings)
|
int InclusiveCrosshairsMain(HINSTANCE hInstance, InclusiveCrosshairsSettings& settings)
|
||||||
{
|
{
|
||||||
Logger::info("Starting a crosshairs instance.");
|
Logger::info("Starting a crosshairs instance.");
|
||||||
|
|||||||
@@ -10,8 +10,16 @@ constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE = 1;
|
|||||||
constexpr bool INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE = false;
|
constexpr bool INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE = false;
|
||||||
constexpr bool INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED = false;
|
constexpr bool INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED = false;
|
||||||
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH = 1;
|
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH = 1;
|
||||||
|
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_ORIENTATION = 0; // 0=Both, 1=Vertical, 2=Horizontal
|
||||||
constexpr bool INCLUSIVE_MOUSE_DEFAULT_AUTO_ACTIVATE = false;
|
constexpr bool INCLUSIVE_MOUSE_DEFAULT_AUTO_ACTIVATE = false;
|
||||||
|
|
||||||
|
enum struct CrosshairsOrientation : int
|
||||||
|
{
|
||||||
|
Both = 0,
|
||||||
|
VerticalOnly = 1,
|
||||||
|
HorizontalOnly = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct InclusiveCrosshairsSettings
|
struct InclusiveCrosshairsSettings
|
||||||
{
|
{
|
||||||
winrt::Windows::UI::Color crosshairsColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR;
|
winrt::Windows::UI::Color crosshairsColor = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_COLOR;
|
||||||
@@ -23,6 +31,7 @@ struct InclusiveCrosshairsSettings
|
|||||||
bool crosshairsAutoHide = INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE;
|
bool crosshairsAutoHide = INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE;
|
||||||
bool crosshairsIsFixedLengthEnabled = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED;
|
bool crosshairsIsFixedLengthEnabled = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED;
|
||||||
int crosshairsFixedLength = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
int crosshairsFixedLength = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
||||||
|
CrosshairsOrientation crosshairsOrientation = static_cast<CrosshairsOrientation>(INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_ORIENTATION);
|
||||||
bool autoActivate = INCLUSIVE_MOUSE_DEFAULT_AUTO_ACTIVATE;
|
bool autoActivate = INCLUSIVE_MOUSE_DEFAULT_AUTO_ACTIVATE;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,3 +44,4 @@ void InclusiveCrosshairsRequestUpdatePosition();
|
|||||||
void InclusiveCrosshairsEnsureOn();
|
void InclusiveCrosshairsEnsureOn();
|
||||||
void InclusiveCrosshairsEnsureOff();
|
void InclusiveCrosshairsEnsureOff();
|
||||||
void InclusiveCrosshairsSetExternalControl(bool enabled);
|
void InclusiveCrosshairsSetExternalControl(bool enabled);
|
||||||
|
void InclusiveCrosshairsSetOrientation(CrosshairsOrientation orientation);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
extern void InclusiveCrosshairsRequestUpdatePosition();
|
extern void InclusiveCrosshairsRequestUpdatePosition();
|
||||||
extern void InclusiveCrosshairsEnsureOn();
|
extern void InclusiveCrosshairsEnsureOn();
|
||||||
@@ -30,6 +31,7 @@ namespace
|
|||||||
const wchar_t JSON_KEY_CROSSHAIRS_AUTO_HIDE[] = L"crosshairs_auto_hide";
|
const wchar_t JSON_KEY_CROSSHAIRS_AUTO_HIDE[] = L"crosshairs_auto_hide";
|
||||||
const wchar_t JSON_KEY_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED[] = L"crosshairs_is_fixed_length_enabled";
|
const wchar_t JSON_KEY_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED[] = L"crosshairs_is_fixed_length_enabled";
|
||||||
const wchar_t JSON_KEY_CROSSHAIRS_FIXED_LENGTH[] = L"crosshairs_fixed_length";
|
const wchar_t JSON_KEY_CROSSHAIRS_FIXED_LENGTH[] = L"crosshairs_fixed_length";
|
||||||
|
const wchar_t JSON_KEY_CROSSHAIRS_ORIENTATION[] = L"crosshairs_orientation";
|
||||||
const wchar_t JSON_KEY_AUTO_ACTIVATE[] = L"auto_activate";
|
const wchar_t JSON_KEY_AUTO_ACTIVATE[] = L"auto_activate";
|
||||||
const wchar_t JSON_KEY_GLIDE_TRAVEL_SPEED[] = L"gliding_travel_speed";
|
const wchar_t JSON_KEY_GLIDE_TRAVEL_SPEED[] = L"gliding_travel_speed";
|
||||||
const wchar_t JSON_KEY_GLIDE_DELAY_SPEED[] = L"gliding_delay_speed";
|
const wchar_t JSON_KEY_GLIDE_DELAY_SPEED[] = L"gliding_delay_speed";
|
||||||
@@ -402,6 +404,8 @@ private:
|
|||||||
InclusiveCrosshairsEnsureOn();
|
InclusiveCrosshairsEnsureOn();
|
||||||
// Disable internal mouse hook so we control position updates explicitly
|
// Disable internal mouse hook so we control position updates explicitly
|
||||||
InclusiveCrosshairsSetExternalControl(true);
|
InclusiveCrosshairsSetExternalControl(true);
|
||||||
|
// Override crosshairs to show both for Gliding Cursor
|
||||||
|
InclusiveCrosshairsSetOrientation(CrosshairsOrientation::Both);
|
||||||
|
|
||||||
s->currentXPos = 0;
|
s->currentXPos = 0;
|
||||||
s->currentXSpeed = s->fastHSpeed;
|
s->currentXSpeed = s->fastHSpeed;
|
||||||
@@ -450,6 +454,8 @@ private:
|
|||||||
LeftClick();
|
LeftClick();
|
||||||
InclusiveCrosshairsEnsureOff();
|
InclusiveCrosshairsEnsureOff();
|
||||||
InclusiveCrosshairsSetExternalControl(false);
|
InclusiveCrosshairsSetExternalControl(false);
|
||||||
|
// Restore original crosshairs orientation setting
|
||||||
|
InclusiveCrosshairsSetOrientation(m_inclusiveCrosshairsSettings.crosshairsOrientation);
|
||||||
s->xFraction = 0.0;
|
s->xFraction = 0.0;
|
||||||
s->yFraction = 0.0;
|
s->yFraction = 0.0;
|
||||||
break;
|
break;
|
||||||
@@ -475,264 +481,287 @@ private:
|
|||||||
|
|
||||||
void parse_settings(PowerToysSettings::PowerToyValues& settings)
|
void parse_settings(PowerToysSettings::PowerToyValues& settings)
|
||||||
{
|
{
|
||||||
// TODO: refactor to use common/utils/json.h instead
|
// Refactored JSON parsing: uses inline try-catch blocks for each property for clarity and error handling
|
||||||
auto settingsObject = settings.get_raw_json();
|
auto settingsObject = settings.get_raw_json();
|
||||||
InclusiveCrosshairsSettings inclusiveCrosshairsSettings;
|
InclusiveCrosshairsSettings inclusiveCrosshairsSettings;
|
||||||
|
|
||||||
if (settingsObject.GetView().Size())
|
if (settingsObject.GetView().Size())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Parse primary activation HotKey (for centralized hook)
|
auto propertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES);
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_ACTIVATION_SHORTCUT);
|
|
||||||
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonPropertiesObject);
|
// Parse activation hotkey
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto jsonHotkeyObject = propertiesObject.GetNamedObject(JSON_KEY_ACTIVATION_SHORTCUT);
|
||||||
|
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonHotkeyObject);
|
||||||
|
m_activationHotkey.win = hotkey.win_pressed();
|
||||||
|
m_activationHotkey.ctrl = hotkey.ctrl_pressed();
|
||||||
|
m_activationHotkey.shift = hotkey.shift_pressed();
|
||||||
|
m_activationHotkey.alt = hotkey.alt_pressed();
|
||||||
|
m_activationHotkey.key = static_cast<unsigned char>(hotkey.get_code());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
Logger::warn("Failed to initialize Mouse Pointer Crosshairs activation shortcut");
|
||||||
|
}
|
||||||
|
|
||||||
// Map to legacy Hotkey for multi-hotkey API
|
// Parse gliding cursor hotkey
|
||||||
m_activationHotkey.win = hotkey.win_pressed();
|
try
|
||||||
m_activationHotkey.ctrl = hotkey.ctrl_pressed();
|
|
||||||
m_activationHotkey.shift = hotkey.shift_pressed();
|
|
||||||
m_activationHotkey.alt = hotkey.alt_pressed();
|
|
||||||
m_activationHotkey.key = static_cast<unsigned char>(hotkey.get_code());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize Mouse Pointer Crosshairs activation shortcut");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Gliding Cursor HotKey
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_GLIDING_ACTIVATION_SHORTCUT);
|
|
||||||
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonPropertiesObject);
|
|
||||||
m_glidingHotkey.win = hotkey.win_pressed();
|
|
||||||
m_glidingHotkey.ctrl = hotkey.ctrl_pressed();
|
|
||||||
m_glidingHotkey.shift = hotkey.shift_pressed();
|
|
||||||
m_glidingHotkey.alt = hotkey.alt_pressed();
|
|
||||||
m_glidingHotkey.key = static_cast<unsigned char>(hotkey.get_code());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
// note that this is also defined in src\settings-ui\Settings.UI.Library\MousePointerCrosshairsProperties.cs, DefaultGlidingCursorActivationShortcut
|
|
||||||
// both need to be kept in sync!
|
|
||||||
Logger::warn("Failed to initialize Gliding Cursor activation shortcut. Using default Win+Alt+.");
|
|
||||||
m_glidingHotkey.win = true;
|
|
||||||
m_glidingHotkey.alt = true;
|
|
||||||
m_glidingHotkey.ctrl = false;
|
|
||||||
m_glidingHotkey.shift = false;
|
|
||||||
m_glidingHotkey.key = VK_OEM_PERIOD;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Opacity
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_OPACITY);
|
|
||||||
int value = static_cast<uint8_t>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 0)
|
|
||||||
{
|
{
|
||||||
inclusiveCrosshairsSettings.crosshairsOpacity = value;
|
auto jsonHotkeyObject = propertiesObject.GetNamedObject(JSON_KEY_GLIDING_ACTIVATION_SHORTCUT);
|
||||||
|
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonHotkeyObject);
|
||||||
|
m_glidingHotkey.win = hotkey.win_pressed();
|
||||||
|
m_glidingHotkey.ctrl = hotkey.ctrl_pressed();
|
||||||
|
m_glidingHotkey.shift = hotkey.shift_pressed();
|
||||||
|
m_glidingHotkey.alt = hotkey.alt_pressed();
|
||||||
|
m_glidingHotkey.key = static_cast<unsigned char>(hotkey.get_code());
|
||||||
}
|
}
|
||||||
else
|
catch (...)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid Opacity value");
|
Logger::warn("Failed to initialize Gliding Cursor activation shortcut. Using default Win+Alt+.");
|
||||||
|
m_glidingHotkey.win = true;
|
||||||
|
m_glidingHotkey.alt = true;
|
||||||
|
m_glidingHotkey.ctrl = false;
|
||||||
|
m_glidingHotkey.shift = false;
|
||||||
|
m_glidingHotkey.key = VK_OEM_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse individual properties with error handling and defaults
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_opacity"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_opacity");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsOpacity = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_radius"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_radius");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsRadius = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_thickness"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_thickness");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsThickness = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_border_size"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_border_size");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsBorderSize = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_fixed_length"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_fixed_length");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsFixedLength = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_auto_hide"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_auto_hide");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsAutoHide = propertyObj.GetNamedBoolean(L"value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_is_fixed_length_enabled"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_is_fixed_length_enabled");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsIsFixedLengthEnabled = propertyObj.GetNamedBoolean(L"value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"auto_activate"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"auto_activate");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.autoActivate = propertyObj.GetNamedBoolean(L"value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value */ }
|
||||||
|
|
||||||
|
// Parse orientation with validation - this fixes the original issue!
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_orientation"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_orientation");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
int orientationValue = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
if (orientationValue >= 0 && orientationValue <= 2)
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsOrientation = static_cast<CrosshairsOrientation>(orientationValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default value (Both = 0) */ }
|
||||||
|
|
||||||
|
// Parse colors with validation
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_color"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_color");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
std::wstring crosshairsColorValue = std::wstring(propertyObj.GetNamedString(L"value").c_str());
|
||||||
|
uint8_t r, g, b;
|
||||||
|
if (checkValidRGB(crosshairsColorValue, &r, &g, &b))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default color */ }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"crosshairs_border_color"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"crosshairs_border_color");
|
||||||
|
if (propertyObj.HasKey(L"value"))
|
||||||
|
{
|
||||||
|
std::wstring borderColorValue = std::wstring(propertyObj.GetNamedString(L"value").c_str());
|
||||||
|
uint8_t r, g, b;
|
||||||
|
if (checkValidRGB(borderColorValue, &r, &g, &b))
|
||||||
|
{
|
||||||
|
inclusiveCrosshairsSettings.crosshairsBorderColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { /* Use default border color */ }
|
||||||
|
|
||||||
|
// Parse speed settings with validation
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"gliding_travel_speed"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"gliding_travel_speed");
|
||||||
|
if (propertyObj.HasKey(L"value") && m_state)
|
||||||
|
{
|
||||||
|
int travelSpeedValue = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
if (travelSpeedValue >= 5 && travelSpeedValue <= 60)
|
||||||
|
{
|
||||||
|
m_state->fastHSpeed = travelSpeedValue;
|
||||||
|
m_state->fastVSpeed = travelSpeedValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clamp to valid range
|
||||||
|
int clampedValue = travelSpeedValue;
|
||||||
|
if (clampedValue < 5) clampedValue = 5;
|
||||||
|
if (clampedValue > 60) clampedValue = 60;
|
||||||
|
m_state->fastHSpeed = clampedValue;
|
||||||
|
m_state->fastVSpeed = clampedValue;
|
||||||
|
Logger::warn("Travel speed value out of range, clamped to valid range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (m_state)
|
||||||
|
{
|
||||||
|
m_state->fastHSpeed = 25;
|
||||||
|
m_state->fastVSpeed = 25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertiesObject.HasKey(L"gliding_delay_speed"))
|
||||||
|
{
|
||||||
|
auto propertyObj = propertiesObject.GetNamedObject(L"gliding_delay_speed");
|
||||||
|
if (propertyObj.HasKey(L"value") && m_state)
|
||||||
|
{
|
||||||
|
int delaySpeedValue = static_cast<int>(propertyObj.GetNamedNumber(L"value"));
|
||||||
|
if (delaySpeedValue >= 5 && delaySpeedValue <= 60)
|
||||||
|
{
|
||||||
|
m_state->slowHSpeed = delaySpeedValue;
|
||||||
|
m_state->slowVSpeed = delaySpeedValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clamp to valid range
|
||||||
|
int clampedValue = delaySpeedValue;
|
||||||
|
if (clampedValue < 5) clampedValue = 5;
|
||||||
|
if (clampedValue > 60) clampedValue = 60;
|
||||||
|
m_state->slowHSpeed = clampedValue;
|
||||||
|
m_state->slowVSpeed = clampedValue;
|
||||||
|
Logger::warn("Delay speed value out of range, clamped to valid range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (m_state)
|
||||||
|
{
|
||||||
|
m_state->slowHSpeed = 5;
|
||||||
|
m_state->slowVSpeed = 5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
Logger::warn("Failed to initialize Opacity from settings. Will use default value");
|
Logger::warn("Error parsing some MousePointerCrosshairs properties. Using defaults for failed properties.");
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse crosshairs color
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_COLOR);
|
|
||||||
auto crosshairsColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE);
|
|
||||||
uint8_t r, g, b;
|
|
||||||
if (!checkValidRGB(crosshairsColor, &r, &g, &b))
|
|
||||||
{
|
|
||||||
Logger::error("Crosshairs color RGB value is invalid. Will use default value");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize crosshairs color from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Radius
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_RADIUS);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 0)
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsRadius = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid Radius value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize Radius from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Thickness
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_THICKNESS);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 0)
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsThickness = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid Thickness value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize Thickness from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse crosshairs border color
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_BORDER_COLOR);
|
|
||||||
auto crosshairsBorderColor = (std::wstring)jsonPropertiesObject.GetNamedString(JSON_KEY_VALUE);
|
|
||||||
uint8_t r, g, b;
|
|
||||||
if (!checkValidRGB(crosshairsBorderColor, &r, &g, &b))
|
|
||||||
{
|
|
||||||
Logger::error("Crosshairs border color RGB value is invalid. Will use default value");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsBorderColor = winrt::Windows::UI::ColorHelper::FromArgb(255, r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize crosshairs border color from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse border size
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_BORDER_SIZE);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 0)
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsBorderSize = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid Border Color value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize border color from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse auto hide
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_AUTO_HIDE);
|
|
||||||
inclusiveCrosshairsSettings.crosshairsAutoHide = jsonPropertiesObject.GetNamedBoolean(JSON_KEY_VALUE);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize auto hide from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse whether the fixed length is enabled
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED);
|
|
||||||
bool value = jsonPropertiesObject.GetNamedBoolean(JSON_KEY_VALUE);
|
|
||||||
inclusiveCrosshairsSettings.crosshairsIsFixedLengthEnabled = value;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize fixed length enabled from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse fixed length
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_CROSSHAIRS_FIXED_LENGTH);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 0)
|
|
||||||
{
|
|
||||||
inclusiveCrosshairsSettings.crosshairsFixedLength = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid Fixed Length value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize fixed length from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse auto activate
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_AUTO_ACTIVATE);
|
|
||||||
inclusiveCrosshairsSettings.autoActivate = jsonPropertiesObject.GetNamedBoolean(JSON_KEY_VALUE);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize auto activate from settings. Will use default value");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Travel speed (fast speed mapping)
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_GLIDE_TRAVEL_SPEED);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 5 && value <= 60)
|
|
||||||
{
|
|
||||||
m_state->fastHSpeed = value;
|
|
||||||
m_state->fastVSpeed = value;
|
|
||||||
}
|
|
||||||
else if (value < 5)
|
|
||||||
{
|
|
||||||
m_state->fastHSpeed = 5; m_state->fastVSpeed = 5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_state->fastHSpeed = 60; m_state->fastVSpeed = 60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize gliding travel speed from settings. Using default 25.");
|
|
||||||
if (m_state)
|
|
||||||
{
|
|
||||||
m_state->fastHSpeed = 25;
|
|
||||||
m_state->fastVSpeed = 25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse Delay speed (slow speed mapping)
|
|
||||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_GLIDE_DELAY_SPEED);
|
|
||||||
int value = static_cast<int>(jsonPropertiesObject.GetNamedNumber(JSON_KEY_VALUE));
|
|
||||||
if (value >= 5 && value <= 60)
|
|
||||||
{
|
|
||||||
m_state->slowHSpeed = value;
|
|
||||||
m_state->slowVSpeed = value;
|
|
||||||
}
|
|
||||||
else if (value < 5)
|
|
||||||
{
|
|
||||||
m_state->slowHSpeed = 5; m_state->slowVSpeed = 5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_state->slowHSpeed = 60; m_state->slowVSpeed = 60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::warn("Failed to initialize gliding delay speed from settings. Using default 5.");
|
|
||||||
if (m_state)
|
|
||||||
{
|
|
||||||
m_state->slowHSpeed = 5;
|
|
||||||
m_state->slowVSpeed = 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -740,6 +769,7 @@ private:
|
|||||||
Logger::info("Mouse Pointer Crosshairs settings are empty");
|
Logger::info("Mouse Pointer Crosshairs settings are empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default hotkeys if not configured
|
||||||
if (m_activationHotkey.key == 0)
|
if (m_activationHotkey.key == 0)
|
||||||
{
|
{
|
||||||
m_activationHotkey.win = true;
|
m_activationHotkey.win = true;
|
||||||
@@ -756,6 +786,7 @@ private:
|
|||||||
m_glidingHotkey.shift = false;
|
m_glidingHotkey.shift = false;
|
||||||
m_glidingHotkey.key = VK_OEM_PERIOD;
|
m_glidingHotkey.key = VK_OEM_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inclusiveCrosshairsSettings = inclusiveCrosshairsSettings;
|
m_inclusiveCrosshairsSettings = inclusiveCrosshairsSettings;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
[JsonPropertyName("crosshairs_border_size")]
|
[JsonPropertyName("crosshairs_border_size")]
|
||||||
public IntProperty CrosshairsBorderSize { get; set; }
|
public IntProperty CrosshairsBorderSize { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("crosshairs_orientation")]
|
||||||
|
public IntProperty CrosshairsOrientation { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("crosshairs_auto_hide")]
|
[JsonPropertyName("crosshairs_auto_hide")]
|
||||||
public BoolProperty CrosshairsAutoHide { get; set; }
|
public BoolProperty CrosshairsAutoHide { get; set; }
|
||||||
|
|
||||||
@@ -68,6 +71,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
CrosshairsThickness = new IntProperty(5);
|
CrosshairsThickness = new IntProperty(5);
|
||||||
CrosshairsBorderColor = new StringProperty("#FFFFFF");
|
CrosshairsBorderColor = new StringProperty("#FFFFFF");
|
||||||
CrosshairsBorderSize = new IntProperty(1);
|
CrosshairsBorderSize = new IntProperty(1);
|
||||||
|
CrosshairsOrientation = new IntProperty(0); // Default to both (0=Both, 1=Vertical, 2=Horizontal)
|
||||||
CrosshairsAutoHide = new BoolProperty(false);
|
CrosshairsAutoHide = new BoolProperty(false);
|
||||||
CrosshairsIsFixedLengthEnabled = new BoolProperty(false);
|
CrosshairsIsFixedLengthEnabled = new BoolProperty(false);
|
||||||
CrosshairsFixedLength = new IntProperty(1);
|
CrosshairsFixedLength = new IntProperty(1);
|
||||||
|
|||||||
@@ -162,7 +162,7 @@
|
|||||||
Severity="Informational"
|
Severity="Informational"
|
||||||
Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
|
Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
|
||||||
<InfoBar.ActionButton>
|
<InfoBar.ActionButton>
|
||||||
<HyperlinkButton x:Uid="OpenSettings" Click="OpenAnimationsSettings_Click" />
|
<HyperlinkButton x:Uid="OpenAnimationsSettings" Click="OpenAnimationsSettings_Click" />
|
||||||
</InfoBar.ActionButton>
|
</InfoBar.ActionButton>
|
||||||
</InfoBar>
|
</InfoBar>
|
||||||
<tkcontrols:SettingsExpander
|
<tkcontrols:SettingsExpander
|
||||||
@@ -355,6 +355,14 @@
|
|||||||
Value="{x:Bind ViewModel.MousePointerCrosshairsBorderSize, Mode=TwoWay}" />
|
Value="{x:Bind ViewModel.MousePointerCrosshairsBorderSize, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
|
|
||||||
|
<tkcontrols:SettingsCard Name="MouseUtilsMousePointerCrosshairsCrosshairsOrientation" x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation">
|
||||||
|
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.MousePointerCrosshairsOrientation, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Both" />
|
||||||
|
<ComboBoxItem x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Vertical" />
|
||||||
|
<ComboBoxItem x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Horizontal" />
|
||||||
|
</ComboBox>
|
||||||
|
</tkcontrols:SettingsCard>
|
||||||
|
|
||||||
<tkcontrols:SettingsCard ContentAlignment="Left">
|
<tkcontrols:SettingsCard ContentAlignment="Left">
|
||||||
<CheckBox x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide" IsChecked="{x:Bind ViewModel.MousePointerCrosshairsAutoHide, Mode=TwoWay}" />
|
<CheckBox x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide" IsChecked="{x:Bind ViewModel.MousePointerCrosshairsAutoHide, Mode=TwoWay}" />
|
||||||
</tkcontrols:SettingsCard>
|
</tkcontrols:SettingsCard>
|
||||||
|
|||||||
@@ -2892,6 +2892,18 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
|||||||
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength.Header" xml:space="preserve">
|
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength.Header" xml:space="preserve">
|
||||||
<value>Crosshairs fixed length (px)</value>
|
<value>Crosshairs fixed length (px)</value>
|
||||||
<comment>px = pixels</comment>
|
<comment>px = pixels</comment>
|
||||||
|
</data>
|
||||||
|
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation" xml:space="preserve">
|
||||||
|
<value>Crosshairs orientation</value>
|
||||||
|
</data>
|
||||||
|
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Both.Content" xml:space="preserve">
|
||||||
|
<value>Vertical and horizontal lines</value>
|
||||||
|
</data>
|
||||||
|
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Vertical.Content" xml:space="preserve">
|
||||||
|
<value>Vertical only</value>
|
||||||
|
</data>
|
||||||
|
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsOrientation_Horizontal.Content" xml:space="preserve">
|
||||||
|
<value>Horizontal only</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MouseUtils_GlidingCursor.Header" xml:space="preserve">
|
<data name="MouseUtils_GlidingCursor.Header" xml:space="preserve">
|
||||||
<value>Gliding cursor</value>
|
<value>Gliding cursor</value>
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
_mousePointerCrosshairsAutoHide = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value;
|
_mousePointerCrosshairsAutoHide = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value;
|
||||||
_mousePointerCrosshairsIsFixedLengthEnabled = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value;
|
_mousePointerCrosshairsIsFixedLengthEnabled = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value;
|
||||||
_mousePointerCrosshairsFixedLength = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value;
|
_mousePointerCrosshairsFixedLength = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value;
|
||||||
|
_mousePointerCrosshairsOrientation = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value;
|
||||||
_mousePointerCrosshairsAutoActivate = MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value;
|
_mousePointerCrosshairsAutoActivate = MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value;
|
||||||
|
|
||||||
int isEnabled = 0;
|
int isEnabled = 0;
|
||||||
@@ -869,6 +870,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int MousePointerCrosshairsOrientation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _mousePointerCrosshairsOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _mousePointerCrosshairsOrientation)
|
||||||
|
{
|
||||||
|
_mousePointerCrosshairsOrientation = value;
|
||||||
|
MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value = value;
|
||||||
|
NotifyMousePointerCrosshairsPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool MousePointerCrosshairsAutoActivate
|
public bool MousePointerCrosshairsAutoActivate
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -991,6 +1010,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
private bool _mousePointerCrosshairsAutoHide;
|
private bool _mousePointerCrosshairsAutoHide;
|
||||||
private bool _mousePointerCrosshairsIsFixedLengthEnabled;
|
private bool _mousePointerCrosshairsIsFixedLengthEnabled;
|
||||||
private int _mousePointerCrosshairsFixedLength;
|
private int _mousePointerCrosshairsFixedLength;
|
||||||
|
private int _mousePointerCrosshairsOrientation;
|
||||||
private bool _mousePointerCrosshairsAutoActivate;
|
private bool _mousePointerCrosshairsAutoActivate;
|
||||||
private bool _isAnimationEnabledBySystem;
|
private bool _isAnimationEnabledBySystem;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user