mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[MousePointerCrosshairs]Added a fixed length option (#27471)
* #19638 Added the option to Mouse Crosshairs to fix the lengths of the crosshairs. Some discussion about design in the issue but currently implemented as a configuration toggle and separate length input. * Fixed crosshairs fixed lengthed enabled not being read on view model initialization
This commit is contained in:
@@ -77,6 +77,8 @@ private:
|
||||
int m_crosshairs_radius = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS;
|
||||
int m_crosshairs_thickness = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS;
|
||||
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;
|
||||
int m_crosshairs_fixed_length = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
||||
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;
|
||||
};
|
||||
@@ -214,27 +216,47 @@ void InclusiveCrosshairs::UpdateCrosshairsPosition()
|
||||
|
||||
// Crosshair position should receive a minor adjustment for odd values to prevent anti-aliasing due to half pixels, while still looking like it's centered around the mouse pointer.
|
||||
float halfPixelAdjustment = m_crosshairs_thickness % 2 == 1 ? 0.5f : 0.0f;
|
||||
float borderSizePadding = m_crosshairs_border_size * 2.f;
|
||||
|
||||
// Position crosshairs components around the mouse pointer.
|
||||
m_left_crosshairs_border.Offset({ ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
m_left_crosshairs_border.Size({ ptCursor.x - ptMonitorUpperLeft.x - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2, m_crosshairs_thickness + m_crosshairs_border_size * 2.f });
|
||||
m_left_crosshairs.Offset({ ptCursor.x - m_crosshairs_radius + halfPixelAdjustment * 2.f, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
m_left_crosshairs.Size({ ptCursor.x - ptMonitorUpperLeft.x - m_crosshairs_radius + halfPixelAdjustment * 2, static_cast<float>(m_crosshairs_thickness) });
|
||||
{
|
||||
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 leftCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : leftCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||
m_left_crosshairs_border.Offset({ ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2.f, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
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.Size({ leftCrosshairsLength, static_cast<float>(m_crosshairs_thickness) });
|
||||
}
|
||||
|
||||
m_right_crosshairs_border.Offset({ static_cast<float>(ptCursor.x) + m_crosshairs_radius - m_crosshairs_border_size, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
m_right_crosshairs_border.Size({ static_cast<float>(ptMonitorBottomRight.x) - ptCursor.x - m_crosshairs_radius + m_crosshairs_border_size, m_crosshairs_thickness + m_crosshairs_border_size * 2.f });
|
||||
m_right_crosshairs.Offset({ static_cast<float>(ptCursor.x) + m_crosshairs_radius, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
m_right_crosshairs.Size({ static_cast<float>(ptMonitorBottomRight.x) - ptCursor.x - m_crosshairs_radius, static_cast<float>(m_crosshairs_thickness) });
|
||||
{
|
||||
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 rightCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : rightCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||
m_right_crosshairs_border.Offset({ static_cast<float>(ptCursor.x) + m_crosshairs_radius - m_crosshairs_border_size, ptCursor.y + halfPixelAdjustment, .0f });
|
||||
m_right_crosshairs_border.Size({ rightCrosshairsBorderLength, m_crosshairs_thickness + borderSizePadding });
|
||||
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_top_crosshairs_border.Offset({ ptCursor.x + halfPixelAdjustment, ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2, .0f });
|
||||
m_top_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2.f, ptCursor.y - ptMonitorUpperLeft.y - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2 });
|
||||
m_top_crosshairs.Offset({ ptCursor.x + halfPixelAdjustment, ptCursor.y - m_crosshairs_radius + halfPixelAdjustment * 2, .0f });
|
||||
m_top_crosshairs.Size({ static_cast<float>(m_crosshairs_thickness), ptCursor.y - ptMonitorUpperLeft.y - m_crosshairs_radius + halfPixelAdjustment * 2 });
|
||||
{
|
||||
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 topCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : topCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||
m_top_crosshairs_border.Offset({ ptCursor.x + halfPixelAdjustment, ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size + halfPixelAdjustment * 2.f, .0f });
|
||||
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.Size({ static_cast<float>(m_crosshairs_thickness), topCrosshairsLength });
|
||||
}
|
||||
|
||||
m_bottom_crosshairs_border.Offset({ ptCursor.x + halfPixelAdjustment, static_cast<float>(ptCursor.y) + m_crosshairs_radius - m_crosshairs_border_size, .0f });
|
||||
m_bottom_crosshairs_border.Size({ m_crosshairs_thickness + m_crosshairs_border_size * 2.f, static_cast<float>(ptMonitorBottomRight.y) - ptCursor.y - m_crosshairs_radius + m_crosshairs_border_size });
|
||||
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), 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 bottomCrosshairsBorderLength = m_crosshairs_is_fixed_length_enabled ? m_crosshairs_fixed_length + borderSizePadding : bottomCrosshairsFullScreenLength + m_crosshairs_border_size;
|
||||
m_bottom_crosshairs_border.Offset({ ptCursor.x + halfPixelAdjustment, static_cast<float>(ptCursor.y) + m_crosshairs_radius - m_crosshairs_border_size, .0f });
|
||||
m_bottom_crosshairs_border.Size({ m_crosshairs_thickness + borderSizePadding, bottomCrosshairsBorderLength });
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK InclusiveCrosshairs::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept
|
||||
@@ -303,6 +325,8 @@ void InclusiveCrosshairs::ApplySettings(InclusiveCrosshairsSettings& settings, b
|
||||
m_crosshairs_border_size = settings.crosshairsBorderSize;
|
||||
bool autoHideChanged = m_crosshairs_auto_hide != settings.crosshairsAutoHide;
|
||||
m_crosshairs_auto_hide = settings.crosshairsAutoHide;
|
||||
m_crosshairs_is_fixed_length_enabled = settings.crosshairsIsFixedLengthEnabled;
|
||||
m_crosshairs_fixed_length = settings.crosshairsFixedLength;
|
||||
|
||||
if (applyToRunTimeObjects)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,8 @@ constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_RADIUS = 20;
|
||||
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_THICKNESS = 5;
|
||||
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE = 1;
|
||||
constexpr bool INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE = false;
|
||||
constexpr bool INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED = false;
|
||||
constexpr int INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH = 1;
|
||||
|
||||
struct InclusiveCrosshairsSettings
|
||||
{
|
||||
@@ -18,6 +20,8 @@ struct InclusiveCrosshairsSettings
|
||||
int crosshairsOpacity = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_OPACITY;
|
||||
int crosshairsBorderSize = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_BORDER_SIZE;
|
||||
bool crosshairsAutoHide = INCLUSIVE_MOUSE_DEFAULT_AUTO_HIDE;
|
||||
bool crosshairsIsFixedLengthEnabled = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_IS_FIXED_LENGTH_ENABLED;
|
||||
int crosshairsFixedLength = INCLUSIVE_MOUSE_DEFAULT_CROSSHAIRS_FIXED_LENGTH;
|
||||
};
|
||||
|
||||
int InclusiveCrosshairsMain(HINSTANCE hinst, InclusiveCrosshairsSettings& settings);
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace
|
||||
const wchar_t JSON_KEY_CROSSHAIRS_BORDER_COLOR[] = L"crosshairs_border_color";
|
||||
const wchar_t JSON_KEY_CROSSHAIRS_BORDER_SIZE[] = L"crosshairs_border_size";
|
||||
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_FIXED_LENGTH[] = L"crosshairs_fixed_length";
|
||||
}
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
@@ -341,6 +343,35 @@ public:
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Logger::warn("Failed to initialize fixed length from settings. Will use default value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -34,6 +34,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("crosshairs_auto_hide")]
|
||||
public BoolProperty CrosshairsAutoHide { get; set; }
|
||||
|
||||
[JsonPropertyName("crosshairs_is_fixed_length_enabled")]
|
||||
public BoolProperty CrosshairsIsFixedLengthEnabled { get; set; }
|
||||
|
||||
[JsonPropertyName("crosshairs_fixed_length")]
|
||||
public IntProperty CrosshairsFixedLength { get; set; }
|
||||
|
||||
public MousePointerCrosshairsProperties()
|
||||
{
|
||||
ActivationShortcut = DefaultActivationShortcut;
|
||||
@@ -44,6 +50,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
CrosshairsBorderColor = new StringProperty("#FFFFFF");
|
||||
CrosshairsBorderSize = new IntProperty(1);
|
||||
CrosshairsAutoHide = new BoolProperty(false);
|
||||
CrosshairsIsFixedLengthEnabled = new BoolProperty(false);
|
||||
CrosshairsFixedLength = new IntProperty(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2662,6 +2662,13 @@ From there, simply click on one of the supported files in the File Explorer and
|
||||
<value>Crosshairs border size (px)</value>
|
||||
<comment>px = pixels</comment>
|
||||
</data>
|
||||
<data name="MouseUtils_MousePointerCrosshairs_IsCrosshairsFixedLengthEnabled.Header" xml:space="preserve">
|
||||
<value>Fix crosshairs length</value>
|
||||
</data>
|
||||
<data name="MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength.Header" xml:space="preserve">
|
||||
<value>Crosshairs fixed length (px)</value>
|
||||
<comment>px = pixels</comment>
|
||||
</data>
|
||||
<data name="FancyZones_Radio_Custom_Colors.Content" xml:space="preserve">
|
||||
<value>Custom colors</value>
|
||||
</data>
|
||||
|
||||
@@ -107,6 +107,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_mousePointerCrosshairsThickness = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value;
|
||||
_mousePointerCrosshairsBorderSize = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value;
|
||||
_mousePointerCrosshairsAutoHide = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value;
|
||||
_mousePointerCrosshairsIsFixedLengthEnabled = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value;
|
||||
_mousePointerCrosshairsFixedLength = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value;
|
||||
|
||||
// set the callback functions value to handle outgoing IPC message.
|
||||
SendConfigMSG = ipcMSGCallBackFunc;
|
||||
@@ -811,6 +813,42 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool MousePointerCrosshairsIsFixedLengthEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mousePointerCrosshairsIsFixedLengthEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _mousePointerCrosshairsIsFixedLengthEnabled)
|
||||
{
|
||||
_mousePointerCrosshairsIsFixedLengthEnabled = value;
|
||||
MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value = value;
|
||||
NotifyMousePointerCrosshairsPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int MousePointerCrosshairsFixedLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mousePointerCrosshairsFixedLength;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _mousePointerCrosshairsFixedLength)
|
||||
{
|
||||
_mousePointerCrosshairsFixedLength = value;
|
||||
MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value = value;
|
||||
NotifyMousePointerCrosshairsPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyMousePointerCrosshairsPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
@@ -870,5 +908,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private string _mousePointerCrosshairsBorderColor;
|
||||
private int _mousePointerCrosshairsBorderSize;
|
||||
private bool _mousePointerCrosshairsAutoHide;
|
||||
private bool _mousePointerCrosshairsIsFixedLengthEnabled;
|
||||
private int _mousePointerCrosshairsFixedLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,6 +388,24 @@
|
||||
x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide"
|
||||
IsChecked="{x:Bind ViewModel.MousePointerCrosshairsAutoHide, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_IsCrosshairsFixedLengthEnabled">
|
||||
<ToggleSwitch
|
||||
x:Uid="ToggleSwitch"
|
||||
IsOn="{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=TwoWay}" />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard
|
||||
x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength"
|
||||
IsEnabled="{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=OneWay}">
|
||||
<NumberBox
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
LargeChange="10"
|
||||
Minimum="1"
|
||||
SmallChange="1"
|
||||
SpinButtonPlacementMode="Compact"
|
||||
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsFixedLength}" />
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.Items>
|
||||
</labs:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
|
||||
Reference in New Issue
Block a user