Fix gradient button paint artifacts and WrapMode crash on .NET Framework.
Use toolbar-themed background fill, lighter shadow, and remove invalid LinearGradientBrush.WrapMode that caused OnPaint failures. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
1ccb2b33cf
commit
a9fd467b5d
@ -91,7 +91,7 @@ namespace Электронная_Фармация.UserControls
|
||||
const int row1Y = 10;
|
||||
const int controlHeight = 32;
|
||||
const int filterHeight = 33;
|
||||
const int buttonHeight = 37;
|
||||
const int buttonHeight = 34;
|
||||
const int rowGap = 14;
|
||||
const int row2Y = row1Y + buttonHeight + rowGap;
|
||||
const int commentWidth = 200;
|
||||
@ -126,11 +126,11 @@ namespace Электронная_Фармация.UserControls
|
||||
x = pad;
|
||||
txtGoodFromOrders.SetBounds(x, row2Y, 220, controlHeight);
|
||||
x = txtGoodFromOrders.Right + gap;
|
||||
btnClearGoodSearch.SetBounds(x, row2Y, 32, controlHeight + 3);
|
||||
btnClearGoodSearch.SetBounds(x, row2Y, 32, controlHeight);
|
||||
x = btnClearGoodSearch.Right + gap;
|
||||
txtOrderNumberFilter.SetBounds(x, row2Y, 220, controlHeight);
|
||||
x = txtOrderNumberFilter.Right + gap;
|
||||
btnClearOrderNumberFilter.SetBounds(x, row2Y, 32, controlHeight + 3);
|
||||
btnClearOrderNumberFilter.SetBounds(x, row2Y, 32, controlHeight);
|
||||
x = btnClearOrderNumberFilter.Right + gap;
|
||||
|
||||
btnAddComment.SetBounds(x, row2Y, commentWidth, buttonHeight);
|
||||
|
||||
@ -52,9 +52,9 @@ namespace Электронная_Фармация.UserControls
|
||||
Tag = "chrome-child";
|
||||
|
||||
btnDeleteGood.Height = 34;
|
||||
btnClearSearchInPriceList.Height = 35;
|
||||
btnClearSearchInPriceList.Height = 32;
|
||||
txtSearchGoodNameInPriceList.Height = 32;
|
||||
btnClearSupplierFilter.Height = 35;
|
||||
btnClearSupplierFilter.Height = 32;
|
||||
|
||||
panel1.SizeChanged += (_, __) => LayoutMarkupRow();
|
||||
LayoutMarkupRow();
|
||||
|
||||
@ -94,13 +94,29 @@ namespace Elfisa.UI.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
var parentColor = Parent?.BackColor ?? ThemeManager.Colors.ToolbarBackground;
|
||||
using (var brush = new SolidBrush(parentColor))
|
||||
using (var brush = new SolidBrush(ResolveChromeBackground()))
|
||||
{
|
||||
pevent.Graphics.FillRectangle(brush, ClientRectangle);
|
||||
}
|
||||
}
|
||||
|
||||
private Color ResolveChromeBackground()
|
||||
{
|
||||
var theme = _theme ?? ThemeManager.Colors;
|
||||
var parentTag = Parent?.Tag as string;
|
||||
if (parentTag == "toolbar")
|
||||
{
|
||||
return theme.ToolbarBackground;
|
||||
}
|
||||
|
||||
if (parentTag == "chrome-child" || parentTag == "status-footer")
|
||||
{
|
||||
return theme.BackgroundSecondary;
|
||||
}
|
||||
|
||||
return Parent?.BackColor ?? theme.ToolbarBackground;
|
||||
}
|
||||
|
||||
public ModernButton()
|
||||
{
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint |
|
||||
@ -135,6 +151,12 @@ namespace Elfisa.UI.Controls
|
||||
? new Font(theme.FontSemibold14.FontFamily, 10f, FontStyle.Bold)
|
||||
: new Font("Segoe UI Semibold", 10f, FontStyle.Bold);
|
||||
}
|
||||
|
||||
if (SkillGradientButtonPaint.UsesGradient(_buttonStyle, _compactIconMode) && !_headerNavMode && !_topNavMode)
|
||||
{
|
||||
BackColor = ResolveChromeBackground();
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@ -240,6 +262,11 @@ namespace Elfisa.UI.Controls
|
||||
|
||||
if (usesGradient && !_topNavMode && !_sidebarMode)
|
||||
{
|
||||
using (var bgBrush = new SolidBrush(ResolveChromeBackground()))
|
||||
{
|
||||
g.FillRectangle(bgBrush, bounds);
|
||||
}
|
||||
|
||||
SkillGradientButtonPaint.Paint(
|
||||
g,
|
||||
bounds,
|
||||
|
||||
@ -60,9 +60,7 @@ namespace Elfisa.UI.Controls
|
||||
button.AllowTextEllipsis = false;
|
||||
button.Font = ActionFont;
|
||||
button.Padding = new Padding(16, 6, 16, 6);
|
||||
var height = style == ModernButtonStyle.Primary || style == ModernButtonStyle.Danger
|
||||
? DefaultHeight + 3
|
||||
: DefaultHeight;
|
||||
var height = DefaultHeight;
|
||||
button.Height = Math.Max(button.Height, height);
|
||||
|
||||
FitToText(button, height);
|
||||
@ -85,8 +83,8 @@ namespace Elfisa.UI.Controls
|
||||
button.Font = new Font("Segoe UI Semibold", 13f, FontStyle.Bold);
|
||||
button.IconGlyph = null;
|
||||
button.AllowTextEllipsis = false;
|
||||
button.MinimumSize = new Size(ClearSize, ClearSize + 3);
|
||||
button.Size = new Size(ClearSize, ClearSize + 3);
|
||||
button.MinimumSize = new Size(ClearSize, ClearSize);
|
||||
button.Size = new Size(ClearSize, ClearSize);
|
||||
}
|
||||
|
||||
public static void FitToText(ModernButton button, int height = DefaultHeight)
|
||||
|
||||
@ -5,42 +5,18 @@ using Elfisa.UI.Controls;
|
||||
namespace Elfisa.UI.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Градиент и тень из skill winforms-modern-buttons для ModernButton.
|
||||
/// Градиент из skill winforms-modern-buttons для ModernButton (без тяжёлой тени — она давала артефакты на toolbar).
|
||||
/// </summary>
|
||||
internal static class SkillGradientButtonPaint
|
||||
{
|
||||
private static readonly Color ShadowBase = Color.FromArgb(60, 0, 0, 0);
|
||||
|
||||
public static bool UsesGradient(ModernButtonStyle style, bool compactIconMode)
|
||||
{
|
||||
return style == ModernButtonStyle.Primary
|
||||
|| style == ModernButtonStyle.Danger
|
||||
|| (compactIconMode && style == ModernButtonStyle.Danger);
|
||||
return style == ModernButtonStyle.Primary || style == ModernButtonStyle.Danger;
|
||||
}
|
||||
|
||||
public static int GetCornerRadius(ModernButtonStyle style, bool compactIconMode)
|
||||
{
|
||||
if (compactIconMode)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
return style == ModernButtonStyle.Primary ? 12 : 8;
|
||||
}
|
||||
|
||||
public static int GetShadowDepth(ModernButtonStyle style, bool compactIconMode, bool enabled)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (compactIconMode)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
return style == ModernButtonStyle.Primary ? 5 : 4;
|
||||
return compactIconMode ? 6 : style == ModernButtonStyle.Primary ? 10 : 8;
|
||||
}
|
||||
|
||||
public static void GetGradient(
|
||||
@ -71,7 +47,6 @@ namespace Elfisa.UI.Helpers
|
||||
return;
|
||||
}
|
||||
|
||||
// Primary preset from skill
|
||||
if (pressed)
|
||||
{
|
||||
top = Color.FromArgb(25, 70, 160);
|
||||
@ -98,13 +73,14 @@ namespace Elfisa.UI.Helpers
|
||||
bool pressed,
|
||||
bool enabled)
|
||||
{
|
||||
var shadowDepth = GetShadowDepth(style, compactIconMode, enabled);
|
||||
var radius = GetCornerRadius(style, compactIconMode);
|
||||
var buttonRect = new Rectangle(
|
||||
clientRect.X,
|
||||
clientRect.Y,
|
||||
clientRect.Width - 1,
|
||||
clientRect.Height - 1 - shadowDepth);
|
||||
clientRect.Height - 1);
|
||||
|
||||
g.SetClip(clientRect);
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
@ -116,44 +92,38 @@ namespace Elfisa.UI.Helpers
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = shadowDepth; i > 0; i--)
|
||||
// Лёгкая тень — один слой, без чёрной полосы снизу
|
||||
var shadowRect = new Rectangle(buttonRect.X, buttonRect.Y + 1, buttonRect.Width, buttonRect.Height);
|
||||
using (var shadowPath = GraphicsExtensions.CreateRoundedRectangle(shadowRect, radius))
|
||||
using (var shadowBrush = new SolidBrush(Color.FromArgb(28, 0, 0, 0)))
|
||||
{
|
||||
var alpha = ShadowBase.A * i / (shadowDepth * 3);
|
||||
using (var shadowBrush = new SolidBrush(Color.FromArgb(alpha, ShadowBase)))
|
||||
using (var shadowPath = GraphicsExtensions.CreateRoundedRectangle(
|
||||
new Rectangle(
|
||||
clientRect.X + i,
|
||||
buttonRect.Y + i + 1,
|
||||
buttonRect.Width - i,
|
||||
buttonRect.Height - 1),
|
||||
radius))
|
||||
{
|
||||
g.FillPath(shadowBrush, shadowPath);
|
||||
}
|
||||
g.FillPath(shadowBrush, shadowPath);
|
||||
}
|
||||
|
||||
var faceRect = new Rectangle(buttonRect.X, buttonRect.Y, buttonRect.Width, buttonRect.Height - 1);
|
||||
GetGradient(style, hover, pressed, out var top, out var bottom);
|
||||
|
||||
using (var path = GraphicsExtensions.CreateRoundedRectangle(buttonRect, radius))
|
||||
using (var brush = new LinearGradientBrush(buttonRect, top, bottom, LinearGradientMode.Vertical))
|
||||
using (var path = GraphicsExtensions.CreateRoundedRectangle(faceRect, radius))
|
||||
using (var brush = new LinearGradientBrush(faceRect, top, bottom, LinearGradientMode.Vertical))
|
||||
{
|
||||
g.FillPath(brush, path);
|
||||
|
||||
using (var highlightPen = new Pen(Color.FromArgb(40, Color.White), 1f))
|
||||
using (var highlightPen = new Pen(Color.FromArgb(36, Color.White), 1f))
|
||||
{
|
||||
g.DrawArc(highlightPen, buttonRect.X, buttonRect.Y, radius * 2, radius * 2, 180, 90);
|
||||
g.DrawArc(highlightPen, faceRect.X, faceRect.Y, radius * 2, radius * 2, 180, 90);
|
||||
}
|
||||
}
|
||||
|
||||
g.ResetClip();
|
||||
}
|
||||
|
||||
public static Rectangle GetContentRect(Rectangle clientRect, ModernButtonStyle style, bool compactIconMode, bool enabled)
|
||||
{
|
||||
var shadowDepth = GetShadowDepth(style, compactIconMode, enabled);
|
||||
return new Rectangle(
|
||||
clientRect.X,
|
||||
clientRect.Y,
|
||||
clientRect.Width - 1,
|
||||
clientRect.Height - 1 - shadowDepth);
|
||||
clientRect.Height - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user