☀️ Table CellButton 新增 Loading、修复 ImagePreview 设计器异常

This commit is contained in:
Tom
2025-11-20 15:30:03 +08:00
parent e0c4212768
commit 6aac8c155f
6 changed files with 251 additions and 95 deletions

View File

@@ -173,35 +173,103 @@ namespace AntdUI
protected virtual void OnButtonClick(ImagePreviewItem item, string id, object? tag) => ButtonClick?.Invoke(this, new ImagePreviewButtonEventArgs(item, id, tag));
Size btnSize = new Size(42, 46);
/// <summary>
/// 按钮大小
/// </summary>
[Description("按钮大小"), Category("外观"), DefaultValue(typeof(Size), "42, 46")]
public int[] BtnSize { get; set; } = new int[] { 42, 46 };
public Size BtnSize
{
get => btnSize;
set
{
btnSize = value;
if (IsHandleCreated)
{
SizeChange(ClientRectangle);
Invalidate();
}
}
}
int btnIconSize = 18;
/// <summary>
/// 按钮图标大小
/// </summary>
[Description("按钮图标大小"), Category("外观"), DefaultValue(18)]
public int BtnIconSize { get; set; } = 18;
public int BtnIconSize
{
get => btnIconSize;
set
{
if (btnIconSize == value) return;
btnIconSize = value;
if (IsHandleCreated)
{
SizeChange(ClientRectangle);
Invalidate();
}
}
}
int btnLRSize = 40;
/// <summary>
/// 左右按钮大小
/// </summary>
[Description("左右按钮大小"), Category("外观"), DefaultValue(40)]
public int BtnLRSize { get; set; } = 40;
public int BtnLRSize
{
get => btnLRSize;
set
{
if (btnLRSize == value) return;
btnLRSize = value;
if (IsHandleCreated)
{
SizeChange(ClientRectangle);
Invalidate();
}
}
}
int containerPadding = 24;
/// <summary>
/// 容器边距
/// </summary>
[Description("容器边距"), Category("外观"), DefaultValue(24)]
public int ContainerPadding { get; set; } = 24;
public int ContainerPadding
{
get => containerPadding;
set
{
if (containerPadding == value) return;
containerPadding = value;
if (IsHandleCreated)
{
SizeChange(ClientRectangle);
Invalidate();
}
}
}
Size btnPadding = new Size(12, 32);
/// <summary>
/// 按钮边距
/// </summary>
[Description("按钮边距"), Category("外观"), DefaultValue(typeof(Size), "12, 32")]
public int[] BtnPadding { get; set; } = new int[] { 12, 32 };
public Size BtnPadding
{
get => btnPadding;
set
{
btnPadding = value;
if (IsHandleCreated)
{
SizeChange(ClientRectangle);
Invalidate();
}
}
}
void InitBtns()
{
@@ -380,78 +448,82 @@ namespace AntdUI
{
autoDpi = true;
if (items == null) return;
int index = selectIndex;
var it = items[index];
if (it.Img == null)
try
{
if (it.Call != null)
int index = selectIndex;
var it = items[index];
if (it.Img == null)
{
imgtmp?.Dispose();
Img = it.Call(index, it);
if (Img == null)
if (it.Call != null)
{
imgtmp?.Dispose();
Img = it.Call(index, it);
if (Img == null)
{
if (r) Invalidate();
return;
}
ImgSize = Img.Size;
FillScaleImg();
if (r) Invalidate();
return;
}
else if (it.CallProg != null)
{
LoadingProgressStr = null;
_value = -1F;
Loading = true;
DateTime now = DateTime.Now, now2 = DateTime.Now;
ITask.Run(() =>
{
var img = it.CallProg(index, it, (prog, progstr) =>
{
LoadingProgressStr = progstr;
LoadingProgress = prog;
});
now2 = DateTime.Now;
if (selectIndex == SelectIndex)
{
if (img == null)
{
Img?.Dispose();
Img = null;
return;
}
LoadingProgressStr = null;
imgtmp?.Dispose();
Img = img;
ImgSize = Img.Size;
FillScaleImg();
}
else img?.Dispose();
}, () =>
{
if (selectIndex == SelectIndex)
{
Loading = false;
if ((now2 - now).TotalMilliseconds < 100)
{
Thread.Sleep(100);
if (selectIndex == SelectIndex) Invalidate();
}
}
});
}
else
{
Img = null;
if (r) Invalidate();
}
}
else
{
Img = it.Img;
ImgSize = Img.Size;
FillScaleImg();
if (r) Invalidate();
}
else if (it.CallProg != null)
{
LoadingProgressStr = null;
_value = -1F;
Loading = true;
DateTime now = DateTime.Now, now2 = DateTime.Now;
ITask.Run(() =>
{
var img = it.CallProg(index, it, (prog, progstr) =>
{
LoadingProgressStr = progstr;
LoadingProgress = prog;
});
now2 = DateTime.Now;
if (selectIndex == SelectIndex)
{
if (img == null)
{
Img?.Dispose();
Img = null;
return;
}
LoadingProgressStr = null;
imgtmp?.Dispose();
Img = img;
ImgSize = Img.Size;
FillScaleImg();
}
else img?.Dispose();
}, () =>
{
if (selectIndex == SelectIndex)
{
Loading = false;
if ((now2 - now).TotalMilliseconds < 100)
{
Thread.Sleep(100);
if (selectIndex == SelectIndex) Invalidate();
}
}
});
}
else
{
Img = null;
if (r) Invalidate();
}
}
else
{
Img = it.Img;
ImgSize = Img.Size;
FillScaleImg();
if (r) Invalidate();
}
catch { }
}
#region
@@ -670,8 +742,8 @@ namespace AntdUI
void SizeChange(Rectangle rect)
{
int btn_height = (int)(BtnSize[1] * Config.Dpi), lr_size = (int)(BtnLRSize * Config.Dpi), btn_width = (int)(BtnSize[0] * Config.Dpi),
padding = (int)(ContainerPadding * Config.Dpi), padding_lr = (int)(BtnPadding[0] * Config.Dpi), padding_buttom = (int)(BtnPadding[1] * Config.Dpi),
int btn_height = (int)(BtnSize.Height * Config.Dpi), lr_size = (int)(BtnLRSize * Config.Dpi), btn_width = (int)(BtnSize.Width * Config.Dpi),
padding = (int)(ContainerPadding * Config.Dpi), padding_lr = (int)(BtnPadding.Width * Config.Dpi), padding_buttom = (int)(BtnPadding.Height * Config.Dpi),
icon_size = (int)(BtnIconSize * Config.Dpi);
if (PageSize > 1)
@@ -695,11 +767,7 @@ namespace AntdUI
}
}
Rectangle GetCentered(Rectangle rect, int size)
{
int xy = (rect.Width - size) / 2;
return new Rectangle(rect.X + xy, rect.Y + xy, size, size);
}
Rectangle GetCentered(Rectangle rect, int size) => new Rectangle(rect.X + (rect.Width - size) / 2, rect.Y + (rect.Height - size) / 2, size, size);
#endregion

View File

@@ -156,7 +156,7 @@ namespace AntdUI
/// <summary>
/// 按钮大小
/// </summary>
public int[] BtnSize { get; set; } = new int[] { 42, 46 };
public Size BtnSize { get; set; } = new Size(42, 46);
/// <summary>
/// 按钮图标大小
@@ -176,7 +176,7 @@ namespace AntdUI
/// <summary>
/// 按钮边距
/// </summary>
public int[] BtnPadding { get; set; } = new int[] { 12, 32 };
public Size BtnPadding { get; set; } = new Size(12, 32);
/// <summary>
/// 自定义按钮
@@ -222,12 +222,12 @@ namespace AntdUI
}
public Config SetBtnSize(int w, int h)
{
BtnSize = new int[] { w, h };
BtnSize = new Size(w, h);
return this;
}
public Config SetBtnSize(int value)
{
BtnSize = new int[] { value, value };
BtnSize = new Size(value, value);
return this;
}
public Config SetBtnIconSize(int value)
@@ -247,12 +247,12 @@ namespace AntdUI
}
public Config SetBtnPadding(int w, int h)
{
BtnPadding = new int[] { w, h };
BtnPadding = new Size(w, h);
return this;
}
public Config SetBtnPadding(int value)
{
BtnPadding = new int[] { value, value };
BtnPadding = new Size(value, value);
return this;
}
public Config SetBtns(params Btn[] value)

View File

@@ -54,7 +54,7 @@ namespace AntdUI
else
{
var size = g.MeasureText(Text ?? Config.NullText, font);
bool has_icon = HasIcon;
bool has_icon = HasIcon || loading;
if (has_icon || ShowArrow)
{
if (has_icon && (IconPosition == TAlignMini.Top || IconPosition == TAlignMini.Bottom))
@@ -214,6 +214,12 @@ namespace AntdUI
}
}
#region
ITask? ThreadLoading;
#endregion
#endregion
}
}

View File

@@ -364,6 +364,50 @@ namespace AntdUI
/// </summary>
public int? Gap { get; set; }
#region
bool loading = false;
internal int AnimationLoadingValue = 0;
int AnimationLoadingWaveValue = 0;
/// <summary>
/// 加载状态
/// </summary>
public bool Loading
{
get => loading;
set
{
if (loading == value) return;
loading = value;
ThreadLoading?.Dispose();
OnPropertyChanged(true);
if (loading)
{
AnimationClickValue = 0;
ThreadLoading = new ITask(PARENT.PARENT, i =>
{
AnimationLoadingWaveValue += 1;
if (AnimationLoadingWaveValue > 100) AnimationLoadingWaveValue = 0;
AnimationLoadingValue = i;
OnPropertyChanged();
return loading;
}, 10, 360, 6, () => OnPropertyChanged(true));
}
}
}
/// <summary>
/// 加载响应点击
/// </summary>
public bool LoadingRespondClick { get; set; }
/// <summary>
/// 加载进度
/// </summary>
public float LoadingValue { get; set; } = 0.3F;
#endregion
#endregion
#region
@@ -516,6 +560,17 @@ namespace AntdUI
return this;
}
public CellButton SetLoading(bool value = true)
{
loading = value;
return this;
}
public CellButton SetLoadingValue(float value = -1F)
{
LoadingValue = value;
return this;
}
#endregion
}
}

View File

@@ -291,35 +291,66 @@ namespace AntdUI
}
static void PaintButton(Canvas g, Font font, CellButton btn, Color color, Rectangle rect_read)
{
bool has_loading = btn.Loading && btn.LoadingValue > -1;
if (string.IsNullOrEmpty(btn.Text))
{
var font_size = g.MeasureString(Config.NullText, font);
//没有文字
var rect = PaintButtonImageRectCenter(btn, font_size, rect_read);
if (PaintButtonImageNoText(g, btn, color, rect) && btn.ShowArrow)
if (has_loading)
{
int size = (int)(font_size.Height * btn.IconRatio);
var rect_arrow = new Rectangle(rect_read.X + (rect_read.Width - size) / 2, rect_read.Y + (rect_read.Height - size) / 2, size, size);
PaintButtonTextArrow(g, btn, rect_arrow, color);
float loading_size = rect_read.Height * 0.06F;
using (var brush = new Pen(color, loading_size))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect, btn.AnimationLoadingValue, btn.LoadingValue * 360F);
}
}
else
{
if (PaintButtonImageNoText(g, btn, color, rect) && btn.ShowArrow)
{
int size = (int)(font_size.Height * btn.IconRatio);
var rect_arrow = new Rectangle(rect_read.X + (rect_read.Width - size) / 2, rect_read.Y + (rect_read.Height - size) / 2, size, size);
PaintButtonTextArrow(g, btn, rect_arrow, color);
}
}
}
else
{
var font_size = MeasureText(g, btn.Text, font, rect_read, out int txt_height, out bool textLine);
bool has_left = btn.HasIcon, has_right = btn.ShowArrow;
bool has_left = has_loading || btn.HasIcon, has_right = btn.ShowArrow;
Rectangle rect_text;
if (has_left || has_right)
{
if (has_left && has_right)
{
rect_text = Button.RectAlignLR(g, txt_height, textLine, font, btn.IconPosition, btn.IconRatio, btn.IconGap, font_size, rect_read, out var rect_l, out var rect_r);
PaintButtonPaintImage(g, btn, color, rect_l);
if (has_loading)
{
float loading_size = rect_l.Height * .14F;
using (var brush = new Pen(color, loading_size))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_l, btn.AnimationLoadingValue, btn.LoadingValue * 360F);
}
}
else PaintButtonPaintImage(g, btn, color, rect_l);
PaintButtonTextArrow(g, btn, rect_r, color);
}
else if (has_left)
{
rect_text = Button.RectAlignL(g, txt_height, textLine, false, font, btn.IconPosition, btn.IconRatio, btn.IconGap, font_size, rect_read, out var rect_l);
PaintButtonPaintImage(g, btn, color, rect_l);
if (has_loading)
{
float loading_size = rect_l.Height * .14F;
using (var brush = new Pen(color, loading_size))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_l, btn.AnimationLoadingValue, btn.LoadingValue * 360F);
}
}
else PaintButtonPaintImage(g, btn, color, rect_l);
}
else
{

View File

@@ -635,8 +635,8 @@ namespace AntdUI
if (config == null) return;
var rect_target = TargetRectXY;
rect_read = HasBor ? new Rectangle(Bor, 0, rect_target.Width - Bor * 2, rect_target.Height - Bor) : rect_target;
int btn_height = (int)(config.BtnSize[1] * Config.Dpi), lr_size = (int)(config.BtnLRSize * Config.Dpi), btn_width = (int)(config.BtnSize[0] * Config.Dpi),
padding = (int)(config.ContainerPadding * Config.Dpi), padding_lr = (int)(config.BtnPadding[0] * Config.Dpi), padding_buttom = (int)(config.BtnPadding[1] * Config.Dpi),
int btn_height = (int)(config.BtnSize.Height * Config.Dpi), lr_size = (int)(config.BtnLRSize * Config.Dpi), btn_width = (int)(config.BtnSize.Width * Config.Dpi),
padding = (int)(config.ContainerPadding * Config.Dpi), padding_lr = (int)(config.BtnPadding.Width * Config.Dpi), padding_buttom = (int)(config.BtnPadding.Height * Config.Dpi),
icon_size = (int)(config.BtnIconSize * Config.Dpi);
rect_close = new Rectangle(rect_read.Right - padding_buttom - btn_width, rect_read.Y + padding_buttom, btn_width, btn_width);
rect_close_icon = GetCentered(rect_close, icon_size);
@@ -662,11 +662,7 @@ namespace AntdUI
}
}
Rectangle GetCentered(Rectangle rect, int size)
{
int xy = (rect.Width - size) / 2;
return new Rectangle(rect.X + xy, rect.Y + xy, size, size);
}
Rectangle GetCentered(Rectangle rect, int size) => new Rectangle(rect.X + (rect.Width - size) / 2, rect.Y + (rect.Height - size) / 2, size, size);
#endregion