[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:
Epp-code
2023-07-19 07:24:47 -07:00
committed by GitHub
parent e44d63451f
commit 1f44085e41
7 changed files with 149 additions and 17 deletions

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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>