Skip to content

Commit 94ef520

Browse files
Standardize color names for DarkMode colors.
1 parent 6d4ea1a commit 94ef520

File tree

5 files changed

+306
-213
lines changed

5 files changed

+306
-213
lines changed

src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeRendererBase.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,11 @@ public void RenderButton(
7373
GetTextColor(state, isDefault),
7474
false);
7575

76-
DrawFocusIndicator(graphics, bounds, isDefault);
77-
78-
// if (focused && showFocusCues)
79-
// {
80-
// // Draw focus indicator for other styles
81-
// renderer.DrawFocusIndicator(graphics, contentBounds, isDefault);
82-
// }
76+
if (focused && showFocusCues)
77+
{
78+
// Draw focus indicator for other styles
79+
DrawFocusIndicator(graphics, bounds, isDefault);
80+
}
8381
}
8482

8583
public abstract Rectangle DrawButtonBackground(Graphics graphics, Rectangle bounds, PushButtonState state, bool isDefault);

src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/FlatButtonDarkModeRenderer.cs

Lines changed: 68 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -4,146 +4,114 @@
44
using System.Drawing;
55
using System.Drawing.Drawing2D;
66
using System.Windows.Forms.VisualStyles;
7+
using static System.Windows.Forms.DarkModeButtonColors;
78

89
namespace System.Windows.Forms;
910

1011
/// <summary>
11-
/// Provides methods for rendering a button with Flat FlatStyle in dark mode.
12+
/// Flat‑style button renderer that, for the moment, mimics the Win32/Dark‑mode
13+
/// renderer bit‑for‑bit so that we can switch implementations without any
14+
/// visual delta. Once the design team decides on a new look we can diverge
15+
/// again.
1216
/// </summary>
13-
internal class FlatButtonDarkModeRenderer : ButtonDarkModeRendererBase
17+
internal sealed class FlatButtonDarkModeRenderer : ButtonDarkModeRendererBase
1418
{
15-
// UI constants
16-
private const int FocusIndicatorInflate = -2;
17-
private const int BorderThicknessDefault = 2;
18-
private const int BorderThicknessNormal = 1;
19-
private const int FlatEdgeRoundingAngle = 8;
19+
private const int FocusIndicatorInflate = -3;
20+
private const int CornerRadius = 6;
21+
private static readonly Size s_corner = new(CornerRadius, CornerRadius);
2022

21-
private static readonly Size s_flatEdgeRoundingAngleSize =
22-
new(FlatEdgeRoundingAngle, FlatEdgeRoundingAngle);
23+
private protected override Padding PaddingCore { get; } = new(0);
2324

24-
private protected override Padding PaddingCore { get; } = new Padding(0);
25-
26-
/// <summary>
27-
/// Draws button background with flat styling (no rounded corners).
28-
/// </summary>
29-
public override Rectangle DrawButtonBackground(Graphics graphics, Rectangle bounds, PushButtonState state, bool isDefault)
25+
public override Rectangle DrawButtonBackground(
26+
Graphics graphics, Rectangle bounds, PushButtonState state, bool isDefault)
3027
{
31-
// Get appropriate background color based on state
32-
Color backColor = GetBackgroundColor(state, isDefault);
33-
34-
// Fill the background using cached brush
35-
using var brush = backColor.GetCachedSolidBrushScope();
36-
graphics.FillRectangle(brush, bounds);
28+
// fill background
29+
using var back = GetBackgroundColor(state, isDefault).GetCachedSolidBrushScope();
30+
graphics.FillRectangle(back, bounds);
3731

38-
// Draw border if needed
32+
// draw border identical to Win32
3933
DrawButtonBorder(graphics, bounds, state, isDefault);
4034

41-
// Return content bounds (area inside the button for text/image)
42-
return bounds;
35+
// return inner content area (border + 1 px system padding)
36+
return Rectangle.Inflate(bounds, -3, -3);
4337
}
4438

45-
/// <summary>
46-
/// Draws a focus rectangle with dotted lines inside the button.
47-
/// </summary>
48-
public override void DrawFocusIndicator(Graphics graphics, Rectangle contentBounds, bool isDefault)
39+
public override void DrawFocusIndicator(Graphics g, Rectangle contentBounds, bool isDefault)
4940
{
50-
// Create a slightly smaller rectangle for the focus indicator
51-
Rectangle focusRect = Rectangle.Inflate(contentBounds, FocusIndicatorInflate, FocusIndicatorInflate);
41+
Rectangle focus = Rectangle.Inflate(contentBounds, FocusIndicatorInflate, FocusIndicatorInflate);
5242

53-
// Create dotted pen with appropriate color
54-
Color focusColor = isDefault
55-
? DarkModeButtonColors.DefaultFocusIndicatorColor
56-
: DarkModeButtonColors.FocusIndicatorColor;
57-
58-
// Custom pen needed for DashStyle - can't use cached version
59-
using var focusPen = new Pen(focusColor)
60-
{
61-
DashStyle = DashStyle.Dot
62-
};
43+
Color focusBackColor = isDefault
44+
? DefaultColors.AcceptFocusIndicatorBackColor
45+
: DefaultColors.FocusIndicatorBackColor;
6346

64-
// Draw the focus rectangle (no rounded corners)
65-
graphics.DrawRectangle(focusPen, focusRect);
47+
ControlPaint.DrawFocusRectangle(
48+
g,
49+
focus,
50+
DefaultColors.FocusBorderColor,
51+
focusBackColor);
6652
}
6753

68-
/// <summary>
69-
/// Gets the text color appropriate for the button state and type.
70-
/// </summary>
7154
public override Color GetTextColor(PushButtonState state, bool isDefault) =>
7255
state == PushButtonState.Disabled
73-
? DarkModeButtonColors.DisabledTextColor
56+
? DefaultColors.DisabledTextColor
7457
: isDefault
75-
? DarkModeButtonColors.DefaultTextColor
76-
: DarkModeButtonColors.NormalTextColor;
58+
? DefaultColors.AcceptButtonTextColor
59+
: DefaultColors.NormalTextColor;
7760

78-
/// <summary>
79-
/// Gets the background color appropriate for the button state and type.
80-
/// </summary>
8161
private static Color GetBackgroundColor(PushButtonState state, bool isDefault) =>
8262
isDefault
8363
? state switch
8464
{
85-
PushButtonState.Normal => DarkModeButtonColors.DefaultBackgroundColor,
86-
PushButtonState.Hot => DarkModeButtonColors.DefaultHoverBackgroundColor,
87-
PushButtonState.Pressed => DarkModeButtonColors.DefaultPressedBackgroundColor,
88-
PushButtonState.Disabled => DarkModeButtonColors.DefaultDisabledBackgroundColor,
89-
_ => DarkModeButtonColors.DefaultBackgroundColor
65+
PushButtonState.Normal => DefaultColors.StandardBackColor,
66+
PushButtonState.Hot => DefaultColors.HoverBackColor,
67+
PushButtonState.Pressed => DefaultColors.PressedBackColor,
68+
PushButtonState.Disabled => DefaultColors.DisabledBackColor,
69+
_ => DefaultColors.StandardBackColor
9070
}
9171
: state switch
9272
{
93-
PushButtonState.Normal => DarkModeButtonColors.NormalBackgroundColor,
94-
PushButtonState.Hot => DarkModeButtonColors.HoverBackgroundColor,
95-
PushButtonState.Pressed => DarkModeButtonColors.PressedBackgroundColor,
96-
PushButtonState.Disabled => DarkModeButtonColors.DisabledBackgroundColor,
97-
_ => DarkModeButtonColors.NormalBackgroundColor
73+
PushButtonState.Normal => DefaultColors.StandardBackColor,
74+
PushButtonState.Hot => DefaultColors.HoverBackColor,
75+
PushButtonState.Pressed => DefaultColors.PressedBackColor,
76+
PushButtonState.Disabled => DefaultColors.DisabledBackColor,
77+
_ => DefaultColors.StandardBackColor
9878
};
9979

100-
/// <summary>
101-
/// Draws the button border based on the current state.
102-
/// </summary>
103-
private static void DrawButtonBorder(Graphics graphics, Rectangle bounds, PushButtonState state, bool isDefault)
80+
private static void DrawButtonBorder(Graphics g, Rectangle bounds, PushButtonState state, bool isDefault)
10481
{
105-
// For flat style, we need to create a GraphicsPath for the rectangle
106-
using GraphicsPath path = new();
107-
path.AddRoundedRectangle(bounds, s_flatEdgeRoundingAngleSize);
108-
109-
// Skip border drawing for disabled state
110-
if (state == PushButtonState.Disabled)
111-
{
112-
IButtonRenderer.DrawButtonBorder(
113-
graphics,
114-
path,
115-
DarkModeButtonColors.DisabledBorderLightColor,
116-
1);
117-
118-
return;
119-
}
82+
g.SmoothingMode = SmoothingMode.AntiAlias;
12083

121-
Color borderColor;
84+
// Win32 draws its stroke fully *inside* the control → inset by 1 px
85+
Rectangle outer = Rectangle.Inflate(bounds, -1, -1);
12286

123-
int thickness = isDefault
124-
? BorderThicknessDefault
125-
: BorderThicknessNormal;
87+
DrawSingleBorder(g, outer, GetBorderColor(state));
12688

127-
// For pressed state, draw a darker border
128-
if (state == PushButtonState.Pressed)
89+
// Default button gets a second 1‑px border one pixel further inside
90+
if (isDefault)
12991
{
130-
borderColor = isDefault
131-
? DarkModeButtonColors.PressedSingleBorderColor
132-
: DarkModeButtonColors.DefaultFocusIndicatorColor;
133-
134-
IButtonRenderer.DrawButtonBorder(graphics, path, borderColor, thickness);
135-
136-
return;
92+
Rectangle inner = Rectangle.Inflate(outer, -1, -1);
93+
DrawSingleBorder(g, inner, DefaultColors.AcceptFocusIndicatorBackColor);
13794
}
95+
}
13896

139-
// For other states, draw a border with appropriate thickness
140-
// For pressed state, draw a darker border
141-
borderColor = isDefault
142-
? DarkModeButtonColors.DefaultSingleBorderColor
143-
: DarkModeButtonColors.SingleBorderColor;
97+
private static void DrawSingleBorder(Graphics g, Rectangle rect, Color color)
98+
{
99+
g.SmoothingMode = SmoothingMode.AntiAlias;
144100

145-
IButtonRenderer.DrawButtonBorder(graphics, path, borderColor, thickness);
101+
using var path = new GraphicsPath();
102+
path.AddRoundedRectangle(rect, s_corner);
146103

147-
return;
104+
// a 1‑px stroke, aligned *inside*, is exactly what Win32 draws
105+
using var pen = new Pen(color) { Alignment = PenAlignment.Inset };
106+
g.DrawPath(pen, path);
148107
}
108+
109+
private static Color GetBorderColor(PushButtonState state) =>
110+
state switch
111+
{
112+
PushButtonState.Pressed => DefaultColors.PressedSingleBorderColor,
113+
PushButtonState.Hot => DefaultColors.SingleBorderColor,
114+
PushButtonState.Disabled => DefaultColors.DisabledBorderLightColor,
115+
_ => DefaultColors.SingleBorderColor,
116+
};
149117
}

0 commit comments

Comments
 (0)