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 row1Y = 10;
|
||||||
const int controlHeight = 32;
|
const int controlHeight = 32;
|
||||||
const int filterHeight = 33;
|
const int filterHeight = 33;
|
||||||
const int buttonHeight = 37;
|
const int buttonHeight = 34;
|
||||||
const int rowGap = 14;
|
const int rowGap = 14;
|
||||||
const int row2Y = row1Y + buttonHeight + rowGap;
|
const int row2Y = row1Y + buttonHeight + rowGap;
|
||||||
const int commentWidth = 200;
|
const int commentWidth = 200;
|
||||||
@ -126,11 +126,11 @@ namespace Электронная_Фармация.UserControls
|
|||||||
x = pad;
|
x = pad;
|
||||||
txtGoodFromOrders.SetBounds(x, row2Y, 220, controlHeight);
|
txtGoodFromOrders.SetBounds(x, row2Y, 220, controlHeight);
|
||||||
x = txtGoodFromOrders.Right + gap;
|
x = txtGoodFromOrders.Right + gap;
|
||||||
btnClearGoodSearch.SetBounds(x, row2Y, 32, controlHeight + 3);
|
btnClearGoodSearch.SetBounds(x, row2Y, 32, controlHeight);
|
||||||
x = btnClearGoodSearch.Right + gap;
|
x = btnClearGoodSearch.Right + gap;
|
||||||
txtOrderNumberFilter.SetBounds(x, row2Y, 220, controlHeight);
|
txtOrderNumberFilter.SetBounds(x, row2Y, 220, controlHeight);
|
||||||
x = txtOrderNumberFilter.Right + gap;
|
x = txtOrderNumberFilter.Right + gap;
|
||||||
btnClearOrderNumberFilter.SetBounds(x, row2Y, 32, controlHeight + 3);
|
btnClearOrderNumberFilter.SetBounds(x, row2Y, 32, controlHeight);
|
||||||
x = btnClearOrderNumberFilter.Right + gap;
|
x = btnClearOrderNumberFilter.Right + gap;
|
||||||
|
|
||||||
btnAddComment.SetBounds(x, row2Y, commentWidth, buttonHeight);
|
btnAddComment.SetBounds(x, row2Y, commentWidth, buttonHeight);
|
||||||
|
|||||||
@ -52,9 +52,9 @@ namespace Электронная_Фармация.UserControls
|
|||||||
Tag = "chrome-child";
|
Tag = "chrome-child";
|
||||||
|
|
||||||
btnDeleteGood.Height = 34;
|
btnDeleteGood.Height = 34;
|
||||||
btnClearSearchInPriceList.Height = 35;
|
btnClearSearchInPriceList.Height = 32;
|
||||||
txtSearchGoodNameInPriceList.Height = 32;
|
txtSearchGoodNameInPriceList.Height = 32;
|
||||||
btnClearSupplierFilter.Height = 35;
|
btnClearSupplierFilter.Height = 32;
|
||||||
|
|
||||||
panel1.SizeChanged += (_, __) => LayoutMarkupRow();
|
panel1.SizeChanged += (_, __) => LayoutMarkupRow();
|
||||||
LayoutMarkupRow();
|
LayoutMarkupRow();
|
||||||
|
|||||||
@ -94,13 +94,29 @@ namespace Elfisa.UI.Controls
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentColor = Parent?.BackColor ?? ThemeManager.Colors.ToolbarBackground;
|
using (var brush = new SolidBrush(ResolveChromeBackground()))
|
||||||
using (var brush = new SolidBrush(parentColor))
|
|
||||||
{
|
{
|
||||||
pevent.Graphics.FillRectangle(brush, ClientRectangle);
|
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()
|
public ModernButton()
|
||||||
{
|
{
|
||||||
SetStyle(ControlStyles.AllPaintingInWmPaint |
|
SetStyle(ControlStyles.AllPaintingInWmPaint |
|
||||||
@ -135,6 +151,12 @@ namespace Elfisa.UI.Controls
|
|||||||
? new Font(theme.FontSemibold14.FontFamily, 10f, FontStyle.Bold)
|
? new Font(theme.FontSemibold14.FontFamily, 10f, FontStyle.Bold)
|
||||||
: new Font("Segoe UI Semibold", 10f, FontStyle.Bold);
|
: new Font("Segoe UI Semibold", 10f, FontStyle.Bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SkillGradientButtonPaint.UsesGradient(_buttonStyle, _compactIconMode) && !_headerNavMode && !_topNavMode)
|
||||||
|
{
|
||||||
|
BackColor = ResolveChromeBackground();
|
||||||
|
}
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +262,11 @@ namespace Elfisa.UI.Controls
|
|||||||
|
|
||||||
if (usesGradient && !_topNavMode && !_sidebarMode)
|
if (usesGradient && !_topNavMode && !_sidebarMode)
|
||||||
{
|
{
|
||||||
|
using (var bgBrush = new SolidBrush(ResolveChromeBackground()))
|
||||||
|
{
|
||||||
|
g.FillRectangle(bgBrush, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
SkillGradientButtonPaint.Paint(
|
SkillGradientButtonPaint.Paint(
|
||||||
g,
|
g,
|
||||||
bounds,
|
bounds,
|
||||||
|
|||||||
@ -60,9 +60,7 @@ namespace Elfisa.UI.Controls
|
|||||||
button.AllowTextEllipsis = false;
|
button.AllowTextEllipsis = false;
|
||||||
button.Font = ActionFont;
|
button.Font = ActionFont;
|
||||||
button.Padding = new Padding(16, 6, 16, 6);
|
button.Padding = new Padding(16, 6, 16, 6);
|
||||||
var height = style == ModernButtonStyle.Primary || style == ModernButtonStyle.Danger
|
var height = DefaultHeight;
|
||||||
? DefaultHeight + 3
|
|
||||||
: DefaultHeight;
|
|
||||||
button.Height = Math.Max(button.Height, height);
|
button.Height = Math.Max(button.Height, height);
|
||||||
|
|
||||||
FitToText(button, height);
|
FitToText(button, height);
|
||||||
@ -85,8 +83,8 @@ namespace Elfisa.UI.Controls
|
|||||||
button.Font = new Font("Segoe UI Semibold", 13f, FontStyle.Bold);
|
button.Font = new Font("Segoe UI Semibold", 13f, FontStyle.Bold);
|
||||||
button.IconGlyph = null;
|
button.IconGlyph = null;
|
||||||
button.AllowTextEllipsis = false;
|
button.AllowTextEllipsis = false;
|
||||||
button.MinimumSize = new Size(ClearSize, ClearSize + 3);
|
button.MinimumSize = new Size(ClearSize, ClearSize);
|
||||||
button.Size = new Size(ClearSize, ClearSize + 3);
|
button.Size = new Size(ClearSize, ClearSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FitToText(ModernButton button, int height = DefaultHeight)
|
public static void FitToText(ModernButton button, int height = DefaultHeight)
|
||||||
|
|||||||
@ -5,42 +5,18 @@ using Elfisa.UI.Controls;
|
|||||||
namespace Elfisa.UI.Helpers
|
namespace Elfisa.UI.Helpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Градиент и тень из skill winforms-modern-buttons для ModernButton.
|
/// Градиент из skill winforms-modern-buttons для ModernButton (без тяжёлой тени — она давала артефакты на toolbar).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class SkillGradientButtonPaint
|
internal static class SkillGradientButtonPaint
|
||||||
{
|
{
|
||||||
private static readonly Color ShadowBase = Color.FromArgb(60, 0, 0, 0);
|
|
||||||
|
|
||||||
public static bool UsesGradient(ModernButtonStyle style, bool compactIconMode)
|
public static bool UsesGradient(ModernButtonStyle style, bool compactIconMode)
|
||||||
{
|
{
|
||||||
return style == ModernButtonStyle.Primary
|
return style == ModernButtonStyle.Primary || style == ModernButtonStyle.Danger;
|
||||||
|| style == ModernButtonStyle.Danger
|
|
||||||
|| (compactIconMode && style == ModernButtonStyle.Danger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetCornerRadius(ModernButtonStyle style, bool compactIconMode)
|
public static int GetCornerRadius(ModernButtonStyle style, bool compactIconMode)
|
||||||
{
|
{
|
||||||
if (compactIconMode)
|
return compactIconMode ? 6 : style == ModernButtonStyle.Primary ? 10 : 8;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GetGradient(
|
public static void GetGradient(
|
||||||
@ -71,7 +47,6 @@ namespace Elfisa.UI.Helpers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primary preset from skill
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
{
|
{
|
||||||
top = Color.FromArgb(25, 70, 160);
|
top = Color.FromArgb(25, 70, 160);
|
||||||
@ -98,13 +73,14 @@ namespace Elfisa.UI.Helpers
|
|||||||
bool pressed,
|
bool pressed,
|
||||||
bool enabled)
|
bool enabled)
|
||||||
{
|
{
|
||||||
var shadowDepth = GetShadowDepth(style, compactIconMode, enabled);
|
|
||||||
var radius = GetCornerRadius(style, compactIconMode);
|
var radius = GetCornerRadius(style, compactIconMode);
|
||||||
var buttonRect = new Rectangle(
|
var buttonRect = new Rectangle(
|
||||||
clientRect.X,
|
clientRect.X,
|
||||||
clientRect.Y,
|
clientRect.Y,
|
||||||
clientRect.Width - 1,
|
clientRect.Width - 1,
|
||||||
clientRect.Height - 1 - shadowDepth);
|
clientRect.Height - 1);
|
||||||
|
|
||||||
|
g.SetClip(clientRect);
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
{
|
{
|
||||||
@ -116,44 +92,38 @@ namespace Elfisa.UI.Helpers
|
|||||||
return;
|
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);
|
g.FillPath(shadowBrush, shadowPath);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var faceRect = new Rectangle(buttonRect.X, buttonRect.Y, buttonRect.Width, buttonRect.Height - 1);
|
||||||
GetGradient(style, hover, pressed, out var top, out var bottom);
|
GetGradient(style, hover, pressed, out var top, out var bottom);
|
||||||
|
|
||||||
using (var path = GraphicsExtensions.CreateRoundedRectangle(buttonRect, radius))
|
using (var path = GraphicsExtensions.CreateRoundedRectangle(faceRect, radius))
|
||||||
using (var brush = new LinearGradientBrush(buttonRect, top, bottom, LinearGradientMode.Vertical))
|
using (var brush = new LinearGradientBrush(faceRect, top, bottom, LinearGradientMode.Vertical))
|
||||||
{
|
{
|
||||||
g.FillPath(brush, path);
|
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)
|
public static Rectangle GetContentRect(Rectangle clientRect, ModernButtonStyle style, bool compactIconMode, bool enabled)
|
||||||
{
|
{
|
||||||
var shadowDepth = GetShadowDepth(style, compactIconMode, enabled);
|
|
||||||
return new Rectangle(
|
return new Rectangle(
|
||||||
clientRect.X,
|
clientRect.X,
|
||||||
clientRect.Y,
|
clientRect.Y,
|
||||||
clientRect.Width - 1,
|
clientRect.Width - 1,
|
||||||
clientRect.Height - 1 - shadowDepth);
|
clientRect.Height - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user