Skip to content

Commit 5dff9f8

Browse files
Change Grip renderer to use predefined shape.
1 parent e93336b commit 5dff9f8

File tree

2 files changed

+52
-31
lines changed

2 files changed

+52
-31
lines changed

src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripRenderer.cs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.ComponentModel;
55
using System.Drawing;
6+
using System.Drawing.Drawing2D;
67
using System.Drawing.Imaging;
78
using System.Drawing.Text;
89
using System.Windows.Forms.Layout;
@@ -1028,66 +1029,83 @@ private protected void OnRenderStatusStripSizingGrip(
10281029
return;
10291030
}
10301031

1031-
Graphics g = eArgs.Graphics;
1032-
1033-
// we have a set of stock rectangles. Translate them over to where the grip is to be drawn
1034-
// for the white set, then translate them up and right one pixel for the grey.
1035-
10361032
if (eArgs.ToolStrip is not StatusStrip statusStrip)
10371033
{
10381034
return;
10391035
}
10401036

10411037
Rectangle sizeGripBounds = statusStrip.SizeGripBounds;
1042-
10431038
if (LayoutUtils.IsZeroWidthOrHeight(sizeGripBounds))
10441039
{
10451040
return;
10461041
}
10471042

1048-
Rectangle[] whiteRectangles = new Rectangle[s_baseSizeGripRectangles.Length];
1049-
Rectangle[] greyRectangles = new Rectangle[s_baseSizeGripRectangles.Length];
1043+
Graphics g = eArgs.Graphics;
10501044

1051-
for (int i = 0; i < s_baseSizeGripRectangles.Length; i++)
1045+
// Use device DPI for scaling
1046+
float dpiScale = 1.0f;
1047+
1048+
if (statusStrip.DeviceDpi > 0 && ScaleHelper.IsThreadPerMonitorV2Aware)
10521049
{
1053-
Rectangle baseRect = s_baseSizeGripRectangles[i];
1050+
dpiScale = statusStrip.DeviceDpi / 96f;
1051+
}
10541052

1055-
if (statusStrip.RightToLeft == RightToLeft.Yes)
1056-
{
1057-
baseRect.X = sizeGripBounds.Width - baseRect.X - baseRect.Width;
1058-
}
1053+
// Scale the base rectangles for the grip dots
1054+
Rectangle[] scaledRects = new Rectangle[s_baseSizeGripRectangles.Length];
10591055

1060-
// Height of pyramid (10px) + 2px padding from bottom.
1061-
baseRect.Offset(
1062-
x: sizeGripBounds.X,
1063-
y: sizeGripBounds.Bottom - 12);
1056+
for (int i = 0; i < s_baseSizeGripRectangles.Length; i++)
1057+
{
1058+
Rectangle r = s_baseSizeGripRectangles[i];
10641059

1065-
whiteRectangles[i] = baseRect;
1060+
scaledRects[i] = new Rectangle(
1061+
(int)(r.X * dpiScale),
1062+
(int)(r.Y * dpiScale),
1063+
Math.Max((int)(r.Width * dpiScale), 2),
1064+
Math.Max((int)(r.Height * dpiScale), 2));
1065+
}
10661066

1067-
int offset = -1 + GetCornerOffset(statusStrip);
1067+
SmoothingMode oldSmoothing = g.SmoothingMode;
1068+
g.SmoothingMode = SmoothingMode.AntiAlias;
10681069

1070+
int cornerOffset = GetCornerOffset(statusStrip);
1071+
1072+
// Draw the grip dots, bottom-right aligned (mirrored for RTL)
1073+
foreach (Rectangle dotRect in scaledRects)
1074+
{
1075+
Rectangle actualRect;
10691076
if (statusStrip.RightToLeft == RightToLeft.Yes)
10701077
{
1071-
baseRect.Offset(1, -1 - offset);
1078+
actualRect = new Rectangle(
1079+
sizeGripBounds.Left + cornerOffset + dotRect.X,
1080+
sizeGripBounds.Bottom - cornerOffset - dotRect.Y - dotRect.Height,
1081+
dotRect.Width,
1082+
dotRect.Height);
10721083
}
10731084
else
10741085
{
1075-
baseRect.Offset(-1, -1 - offset);
1086+
actualRect = new Rectangle(
1087+
sizeGripBounds.Right - cornerOffset - dotRect.X - dotRect.Width,
1088+
sizeGripBounds.Bottom - cornerOffset - dotRect.Y - dotRect.Height,
1089+
dotRect.Width,
1090+
dotRect.Height);
10761091
}
10771092

1078-
greyRectangles[i] = baseRect;
1093+
// Highlight dot (top-left)
1094+
Rectangle highlightRect = actualRect;
1095+
highlightRect.Offset(-1, -1);
1096+
g.FillEllipse(highLightBrush, highlightRect);
1097+
1098+
// Shadow dot (bottom-right)
1099+
Rectangle shadowRect = actualRect;
1100+
shadowRect.Offset(1, 1);
1101+
g.FillEllipse(shadowBrush, shadowRect);
10791102
}
10801103

1081-
g.FillRectangles(highLightBrush, whiteRectangles);
1082-
g.FillRectangles(shadowBrush, greyRectangles);
1104+
g.SmoothingMode = oldSmoothing;
10831105

1084-
// We need to compensate for the rounded Window corners from Windows 11 on.
10851106
static int GetCornerOffset(StatusStrip statusStrip)
10861107
{
1087-
// If we're on Windows 11, offset slightly to avoid hitting rounded corners,
1088-
// _if_ we are at all dealing with rounded corners.
10891108
int cornerOffset = 0;
1090-
10911109
if (Environment.OSVersion.Version >= new Version(10, 0, 22000)
10921110
&& statusStrip.FindForm() is Form f)
10931111
{

src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripSystemDarkModeRenderer.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,11 @@ protected override void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e
677677
{
678678
ArgumentNullException.ThrowIfNull(e);
679679

680-
using var highLightBrush = GetDarkModeBrush(SystemColors.ButtonHighlight);
681-
using var shadowBrush = GetDarkModeBrush(SystemColors.ButtonShadow);
680+
// Color choice here is not a mistake. The shadow effect in dark mode is
681+
// not made of the complementary "colors" of light mode. That doesn't give
682+
// enough contrast for an effect to actually spot.
683+
using var highLightBrush = GetDarkModeBrush(SystemColors.ButtonShadow);
684+
using var shadowBrush = GetDarkModeBrush(SystemColors.GrayText);
682685

683686
OnRenderStatusStripSizingGrip(
684687
eArgs: e,

0 commit comments

Comments
 (0)