import win.ui;
import dotNet.AntdUI;
import dotNet;
dotNet.import("System.Net");
dotNet.import("System.Drawing");
dotNet.import("System.Windows.Forms");
/*DSG{{*/
var winform = win.form(text="AntdUI Panel";right=920;bottom=660;bgcolor=0xF5F7FA)
winform.add(
host={cls="custom";left=20;top=20;right=900;bottom=640;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
// ==========================================================
// 说明:
// 1. 本示例参考 https://ant.design/components/overview-cn/ 的组件总览卡片。
// ==========================================================
// ---------- 颜色 ----------
var rootBack = 0xFFF5F7FA;
var cardBack = 0xFFFFFFFF;
var cardHoverBack = 0xFFF7FAFF;
var cardBorder = 0xFFE8E8E8;
var cardHoverBorder = 0xFF1677FF;
var titleColor = 0xFF222222;
var titleHoverColor = 0xFF1677FF;
var splitColor = 0xFFE8E8E8;
var splitDrawingColor = System.Drawing.Color.FromArgb(232,232,232);
// ---------- 字体 ----------
var fontTitle = System.Drawing.Font("Microsoft YaHei",10,System.Drawing.FontStyle.Bold);
var fontHeader = System.Drawing.Font("Microsoft YaHei",12,System.Drawing.FontStyle.Bold);
// ---------- 根容器 ----------
var root = AntdUI.Panel(winform.host);
root.Dock = System.Windows.Forms.DockStyle.Fill;
root.Back = rootBack;
root.BackColor = rootBack;
root.Radius = 0;
root.BorderWidth = 0;
// 标题区域:用 FlowPanel 让 header 和 tag 自动横向排列
var headerFlow = AntdUI.FlowPanel();
root.Controls.Add(headerFlow);
headerFlow.Location = System.Drawing.Point(10,10);
headerFlow.Size = System.Drawing.Size(820,36);
headerFlow.BackColor = rootBack;
headerFlow.Gap = 6;
headerFlow.Padding = System.Windows.Forms.Padding(0,0,0,0);
// 标题
var header = AntdUI.Label();
header.Text = "AntdUI";
header.Font = fontHeader;
header.ForeColor = titleColor;
header.BackColor = rootBack;
header.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
header.AutoSize = true;
// 标题后面的数量 Tag
var headerTag = AntdUI.Tag();
headerTag.Size = System.Drawing.Size(40,24);
headerTag.Text = "12";
headerTag.Type = AntdUI.TTypeMini.Default;
headerTag.Font = System.Drawing.Font("Microsoft YaHei UI",9,System.Drawing.FontStyle.Regular);
headerTag.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
headerFlow.Controls.Add(headerTag);
headerFlow.Controls.Add(header);
// 自动排列卡片的面板
var flow = AntdUI.FlowPanel();
root.Controls.Add(flow);
flow.Location = System.Drawing.Point(0,48);
flow.Size = System.Drawing.Size(860,560);
flow.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
flow.BackColor = rootBack;
flow.AutoScroll = true;
flow.Gap = 18;
flow.Padding = System.Windows.Forms.Padding(8,8,8,8);
flow.Align = AntdUI.TAlignFlow.Left
// ---------- SVG 下载与缓存 ----------
var svgCache = {};
// AntdUI.ImageSvg 更适合接收以 <svg ...> 开始的 SVG 片段。
// ant.design 的原始资源常带 XML 声明 / title,这里统一去掉。
var normalizeSvg = function(svg){
svg = string.replace(svg,`^\s*\<\?xml[^\>]*\>\s*`,"");
svg = string.replace(svg,`\<title\>.*?\</title\>\s*`,"");
return svg;
}
var getSvg = function(url){
if(svgCache[url]) return svgCache[url];
var wc = System.Net.WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
var svg = normalizeSvg(wc.DownloadString(url));
wc.Dispose();
svgCache[url] = svg;
return svg;
}
// ---------- 鼠标是否仍在控件矩形内 ----------
var isMouseInControl = function(ctrl){
var pt = ctrl.PointToClient(System.Windows.Forms.Control.MousePosition);
return pt.X >= 0 && pt.Y >= 0 && pt.X < ctrl.Width && pt.Y < ctrl.Height;
}
// ---------- 卡片状态 ----------
var setCardState = function(cardObj,hover){
var bg = hover ? cardHoverBack : cardBack;
cardObj.card.BorderColor = hover ? cardHoverBorder : cardBorder;
cardObj.title.ForeColor = hover ? titleHoverColor : titleColor;
cardObj.card.Invalidate();
cardObj.title.Invalidate();
cardObj.divider.Invalidate();
cardObj.imageBox.Invalidate();
}
var bindCardHover = function(cardObj,ctrl){
ctrl.MouseEnter = function(sender,e){
setCardState(cardObj,true);
}
ctrl.MouseLeave = function(sender,e){
// 鼠标从 Panel 移到内部 Label / Divider / Avatar 时,父控件可能触发 MouseLeave。
// 延迟一下再判断鼠标是否仍在整个 card 区域内,避免 hover 状态闪烁。
thread.delay(1);
if(!isMouseInControl(cardObj.card)){
setCardState(cardObj,false);
}
}
}
// ---------- 创建卡片 ----------
var createCard = function(item){
var card = AntdUI.Panel();
flow.Controls.Add(card);
card.Size = System.Drawing.Size(300,300);
card.Radius = 8;
card.BorderWidth = 1;
card.BorderColor = cardBorder;
// Panel.Back 是实际填充色;BackColor 使用父背景色,可避免圆角外侧白角。
card.Back = cardBack;
card.BackColor = rootBack;
card.Shadow = 0;
card.ShadowOffsetY = 4;
card.ShadowColor = System.Drawing.Color.FromArgb(255,0,0,0);
card.ShadowOpacity = 0.10;
card.ShadowOpacityHover = 0.22;
card.ShadowOpacityAnimation = true;
card.Cursor = System.Windows.Forms.Cursors.Hand;
// 顶部标签,左对齐。
var title = AntdUI.Label();
card.Controls.Add(title);
title.Location = System.Drawing.Point(32,16);
title.Size = System.Drawing.Size(240,34);
title.Text = item.name ++ " " ++ item.cn;
title.Font = fontTitle;
title.ForeColor = titleColor;
title.BackColor = cardBack;
title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
title.AutoEllipsis = true;
title.Cursor = System.Windows.Forms.Cursors.Hand;
// 标题下方分割线。使用 WinForms Panel 做 1px 线,更接近网页卡片。
var divider = System.Windows.Forms.Panel();
card.Controls.Add(divider);
divider.Location = System.Drawing.Point(16,58);
divider.Size = System.Drawing.Size(268,1);
divider.BackColor = splitDrawingColor;
divider.Cursor = System.Windows.Forms.Cursors.Hand;
// SVG 展示区。Avatar 原生支持 ImageSvg,不需要手动转换 Bitmap。
var imageBox = AntdUI.Avatar();
card.Controls.Add(imageBox);
imageBox.Location = System.Drawing.Point(60,92);
imageBox.Size = System.Drawing.Size(180,160);
imageBox.BackColor = cardBack;
imageBox.Radius = 0;
imageBox.Round = false;
imageBox.ImageFit = AntdUI.TFit.Contain;
imageBox.ImageSvg = getSvg(item.url);
imageBox.Cursor = System.Windows.Forms.Cursors.Hand;
var cardObj = {
card = card;
title = title;
divider = divider;
imageBox = imageBox;
}
bindCardHover(cardObj,card);
bindCardHover(cardObj,title);
bindCardHover(cardObj,divider);
bindCardHover(cardObj,imageBox);
var clickHandler = function(sender,e){
AntdUI.Message.info(
AntdUI.Target(card),
"已点击:" ++ item.name ++ " / " ++ item.cn,
fontTitle,
3
);
}
card.Click = clickHandler;
title.Click = clickHandler;
divider.Click = clickHandler;
imageBox.Click = clickHandler;
return cardObj;
}
// ---------- 官方组件图 URL,来自 ant.design/components/overview-cn ----------
var items = [
{name="Button";cn="按钮";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*7va7RKs3YzIAAAAAAAAAAAAADrJ8AQ/original"},
{name="FloatButton";cn="悬浮按钮";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*tXAoQqyr-ioAAAAAAAAAAAAADrJ8AQ/original"},
{name="Icon";cn="图标";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*PdAYS7anRpoAAAAAAAAAAAAADrJ8AQ/original"},
{name="Typography";cn="排版";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*MLt3R6m9huoAAAAAAAAAAAAADrJ8AQ/original"},
{name="Divider";cn="分割线";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*7sMiTbzvaDoAAAAAAAAAAAAADrJ8AQ/original"},
{name="Flex";cn="弹性布局";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*SMzgSJZE_AwAAAAAAAAAAAAADrJ8AQ/original"},
{name="Grid";cn="栅格";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*mfJeS6cqZrEAAAAAAAAAAAAADrJ8AQ/original"},
{name="Layout";cn="布局";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*4i58ToAcxaYAAAAAAAAAAAAADrJ8AQ/original"},
{name="Space";cn="间距";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*ZiJ3SbOH9SUAAAAAAAAAAAAADrJ8AQ/original"},
{name="Tabs";cn="标签页";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*72NDQqXkyOEAAAAAAAAAAAAADrJ8AQ/original"},
{name="Table";cn="表格";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*3yz3QqMlShYAAAAAAAAAAAAADrJ8AQ/original"},
{name="Form";cn="表单";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-lcdS5Qm1bsAAAAAAAAAAAAADrJ8AQ/original"}
];
// ---------- 批量创建 ----------
flow.SuspendLayout();
for(i,item in items){
createCard(item);
}
flow.ResumeLayout(true);
winform.onClose = function(){
fontTitle.Dispose();
fontHeader.Dispose();
}
winform.show();
win.loopMessage();