// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED.
// THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License.
// LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License")
// YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License.
// YOU MAY OBTAIN A COPY OF THE LICENSE AT
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
// DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
// LIMITATIONS UNDER THE License.
// GITEE: https://gitee.com/antdui/AntdUI
// GITHUB: https://github.com/AntdUI/AntdUI
// CSDN: https://blog.csdn.net/v_132
// QQ: 17379620
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Windows.Forms;
namespace AntdUI
{
///
/// Message 全局提示
///
/// 全局展示操作反馈信息。
public static class Message
{
///
/// 成功提示
///
/// 窗口
/// 提示内容
/// 字体
/// 自动关闭时间(秒)0等于不关闭
public static void success(Form form, string text, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.Success, font, autoClose));
}
///
/// 信息提示
///
/// 窗口
/// 提示内容
/// 字体
/// 自动关闭时间(秒)0等于不关闭
public static void info(Form form, string text, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.Info, font, autoClose));
}
///
/// 警告提示
///
/// 窗口
/// 提示内容
/// 字体
/// 自动关闭时间(秒)0等于不关闭
public static void warn(Form form, string text, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.Warn, font, autoClose));
}
///
/// 失败提示
///
/// 窗口
/// 提示内容
/// 字体
/// 自动关闭时间(秒)0等于不关闭
public static void error(Form form, string text, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.Error, font, autoClose));
}
///
/// 加载提示
///
/// 窗口
/// 提示内容
/// 耗时任务
/// 字体
/// 自动关闭时间(秒)0等于不关闭
public static void loading(Form form, string text, Action call, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.None, font, autoClose) { Call = call });
}
public static void open(Form form, string text, Font? font = null, int? autoClose = null)
{
open(new Config(form, text, TType.None, font, autoClose));
}
///
/// Message 全局提示
///
/// 配置
public static void open(this Config config) => MsgQueue.Add(config);
///
/// 关闭全部
///
public static void close_all()
{
var close_list = new System.Collections.Generic.List(10);
foreach (var it in ILayeredFormAnimate.list)
{
foreach (var item in it.Value)
{
if (item is MessageFrm message) close_list.Add(message);
}
}
if (close_list.Count == 0) return;
foreach (var it in close_list) it.CloseMe(false);
}
///
/// 关闭指定id
///
public static void close_id(string id)
{
MsgQueue.volley.Add("M" + id);
var close_list = new System.Collections.Generic.List();
foreach (var it in ILayeredFormAnimate.list)
{
foreach (var item in it.Value)
{
if (item is MessageFrm message && message.config.ID == id) close_list.Add(message);
}
}
if (close_list.Count == 0) return;
foreach (var it in close_list) it.CloseMe(false);
}
///
/// 配置
///
public class Config
{
public Config(Form _form, string _text, TType _icon)
{
Form = _form;
Text = _text;
Icon = _icon;
}
public Config(Form _form, string _text, TType _icon, Font? _font)
{
Form = _form;
Font = _font;
Text = _text;
Icon = _icon;
}
public Config(Form _form, string _text, TType _icon, Font? _font, int? autoClose)
{
Form = _form;
Font = _font;
Text = _text;
Icon = _icon;
if (autoClose.HasValue) AutoClose = autoClose.Value;
}
///
/// ID
///
public string? ID { get; set; }
///
/// 所属窗口
///
public Form Form { get; set; }
///
/// 文本
///
public string Text { get; set; }
///
/// 图标
///
public TType Icon { get; set; }
///
/// 加载回调
///
public Action? Call { get; set; }
///
/// 字体
///
public Font? Font { get; set; }
///
/// 圆角
///
public int Radius { get; set; } = 6;
///
/// 自动关闭时间(秒)0等于不关闭
///
public int AutoClose { get; set; } = 6;
///
/// 方向
///
public TAlignFrom Align { get; set; } = TAlignFrom.Top;
///
/// 边距
///
public Size Padding { get; set; } = new Size(12, 9);
///
/// 弹出在窗口
///
public bool ShowInWindow { get; set; } = false;
public void OK(string text)
{
Icon = TType.Success;
Text = text;
Refresh();
}
public void Error(string text)
{
Icon = TType.Error;
Text = text;
Refresh();
}
public void Warn(string text)
{
Icon = TType.Warn;
Text = text;
Refresh();
}
public void Info(string text)
{
Icon = TType.Info;
Text = text;
Refresh();
}
internal Action? refresh;
public void Refresh()
{
refresh?.Invoke();
}
}
}
internal class MessageFrm : ILayeredFormAnimate
{
internal Message.Config config;
int shadow_size = 10;
public MessageFrm(Message.Config _config)
{
config = _config;
config.Form.SetTopMost(Handle);
shadow_size = (int)(shadow_size * Config.Dpi);
loading = _config.Call != null;
if (config.Font != null) Font = config.Font;
else if (Config.Font != null) Font = Config.Font;
else Font = config.Form.Font;
Icon = config.Form.Icon;
Helper.GDI(g =>
{
SetSize(RenderMeasure(g, shadow_size));
});
}
internal override TAlignFrom Align => config.Align;
internal override bool ActiveAnimation => false;
bool loading = false, loadingend = true;
int AnimationLoadingValue = 0;
ITask? ThreadLoading = null;
public bool IInit()
{
if (SetPosition(config.Form, config.ShowInWindow || Config.ShowInWindowByMessage)) return true;
if (loading)
{
ThreadLoading = new ITask(this, i =>
{
AnimationLoadingValue = i;
Print();
return loading;
}, 20, 360, 10);
}
loadingend = false;
ITask.Run(() =>
{
if (config.Call != null)
{
config.refresh += () =>
{
if (IRefresh())
{
loadingend = true;
return;
}
};
try
{
config.Call(config);
}
catch { }
loading = false;
ThreadLoading?.Dispose();
if (IRefresh())
{
loadingend = true;
return;
}
}
}, () =>
{
loadingend = true;
if (config.AutoClose > 0)
{
Thread.Sleep(config.AutoClose * 1000);
CloseMe(true);
}
else CloseMe(true);
});
PlayAnimation();
return false;
}
bool IRefresh()
{
var oldw = TargetRect.Width;
if (IsHandleCreated)
{
Helper.GDI(g =>
{
SetSize(RenderMeasure(g, shadow_size));
});
DisposeAnimation();
SetPositionCenter(oldw);
return false;
}
else return true;
}
protected override void OnMouseClick(MouseEventArgs e)
{
if (loadingend) CloseMe(false);
base.OnMouseClick(e);
}
#region 渲染
readonly StringFormat s_f_left = Helper.SF_ALL(lr: StringAlignment.Near);
public override Bitmap PrintBit()
{
var rect = TargetRectXY;
var rect_read = rect.PaddingRect(Padding, shadow_size);
Bitmap original_bmp = new Bitmap(rect.Width, rect.Height);
using (var g = Graphics.FromImage(original_bmp).High())
{
using (var path = DrawShadow(g, rect, rect_read))
{
using (var brush = new SolidBrush(Style.Db.BgElevated))
{
g.FillPath(brush, path);
}
}
if (loading)
{
using (var brush = new Pen(Style.Db.Fill, 3F))
{
g.DrawEllipse(brush, rect_loading);
}
using (var brush = new Pen(Style.Db.Primary, 3F))
{
brush.StartCap = brush.EndCap = LineCap.Round;
g.DrawArc(brush, rect_loading, AnimationLoadingValue, 100);
}
}
else if (config.Icon != TType.None) g.PaintIcons(config.Icon, rect_icon);
using (var brush = new SolidBrush(Style.Db.TextBase))
{
g.DrawStr(config.Text, Font, brush, rect_txt, s_f_left);
}
}
return original_bmp;
}
Bitmap? shadow_temp = null;
///
/// 绘制阴影
///
/// GDI
/// 客户区域
/// 真实区域
GraphicsPath DrawShadow(Graphics g, Rectangle rect_client, RectangleF rect_read)
{
var path = rect_read.RoundPath((int)(config.Radius * Config.Dpi));
if (Config.ShadowEnabled)
{
if (shadow_temp == null || (shadow_temp.Width != rect_client.Width || shadow_temp.Height != rect_client.Height))
{
shadow_temp?.Dispose();
shadow_temp = path.PaintShadow(rect_client.Width, rect_client.Height);
}
g.DrawImage(shadow_temp, rect_client, 0.2F);
}
return path;
}
Rectangle rect_icon, rect_loading, rect_txt;
Size RenderMeasure(Graphics g, int shadow)
{
int shadow2 = shadow * 2;
float dpi = Config.Dpi;
var size = g.MeasureString(config.Text, Font, 10000, s_f_left).Size();
int paddingx = (int)(config.Padding.Width * dpi), paddingy = (int)(config.Padding.Height * dpi),
sp = (int)(8 * dpi), height = size.Height + paddingy * 2;
if (loading)
{
int icon_size = (int)(size.Height * .86F);
rect_icon = new Rectangle(shadow + paddingx, shadow + (height - icon_size) / 2, icon_size, icon_size);
rect_txt = new Rectangle(rect_icon.Right + sp, shadow, size.Width, height);
int loading_size = (int)(icon_size * .86F);
rect_loading = new Rectangle(rect_icon.X + (rect_icon.Width - loading_size) / 2, rect_icon.Y + (rect_icon.Height - loading_size) / 2, loading_size, loading_size);
return new Size(size.Width + icon_size + sp + paddingx * 2 + shadow2, height + shadow2);
}
else if (config.Icon == TType.None)
{
rect_txt = new Rectangle(shadow + paddingx, shadow, size.Width, height);
return new Size(size.Width + paddingx * 2 + shadow2, height + shadow2);
}
else
{
int icon_size = (int)(size.Height * .86F);
rect_icon = new Rectangle(shadow + paddingx, shadow + (height - icon_size) / 2, icon_size, icon_size);
rect_txt = new Rectangle(rect_icon.Right + sp, shadow, size.Width, height);
return new Size(size.Width + icon_size + sp + paddingx * 2 + shadow2, height + shadow2);
}
}
#endregion
protected override void Dispose(bool disposing)
{
ThreadLoading?.Dispose();
base.Dispose(disposing);
}
}
}