import win.ui;
import dotNet.AntdUI;
import dotNet;
/*DSG{{*/
var winform = win.form(text="AntdUI Menu";right=960;bottom=650;bgcolor=0xF0F0F0;border="thin")
winform.add(
custom_base={cls="custom";left=0;top=0;right=962;bottom=652;ah=1;aw=1;db=1;disabled=1;dl=1;dr=1;dt=1;hide=1;z=1};
custom_breadcrumb={cls="custom";left=234;top=0;right=962;bottom=50;bgcolor=0xFFFFFF;dl=1;dr=1;dt=1;z=4};
custom_content={cls="custom";left=234;top=52;right=962;bottom=652;bgcolor=0xFFFFFF;db=1;dl=1;dr=1;dt=1;z=5};
custom_sidebar_logo={cls="custom";left=0;top=0;right=232;bottom=62;bgcolor=0xFFFFFF;dl=1;dt=1;z=2};
custom_sidebar_menu={cls="custom";left=0;top=64;right=232;bottom=652;bgcolor=0xFFFFFF;db=1;dl=1;dt=1;z=3}
)
/*}}*/
// ---------- AntdUI 容器 ----------
var baseForm = AntdUI.BaseForm();
baseForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
baseForm.Dock = System.Windows.Forms.DockStyle.Fill;
dotNet.setParent(baseForm, winform.custom_base);
// ---------- 字体 ----------
var fontLogo = System.Drawing.Font("Microsoft YaHei", 16, System.Drawing.FontStyle.Bold);
var fontTitle = System.Drawing.Font("Microsoft YaHei", 14, System.Drawing.FontStyle.Bold);
var fontNormal = System.Drawing.Font("Microsoft YaHei", 10);
var fontTip = System.Drawing.Font("Microsoft YaHei", 9);
// ---------- 简化 SVG 图标 ----------
var svgDashboard = '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M128 512 512 160l384 352h-96v352H576V640H448v224H224V512z"/></svg>';
var svgSettings = '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M512 320a192 192 0 1 0 0 384 192 192 0 0 0 0-384zm0-192 64 128 144 24 24 144 128 64-128 64-24 144-144 24-64 128-64-128-144-24-24-144-128-64 128-64 24-144 144-24z"/></svg>';
var svgContent = '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M224 128h576v768H224zM320 256h384v64H320zm0 160h384v64H320zm0 160h256v64H320z"/></svg>';
// ============================================================
// 侧边栏 Logo
// ============================================================
var lblLogo = AntdUI.Label(winform.custom_sidebar_logo);
lblLogo.Text = "AntdUI Admin";
lblLogo.Font = fontLogo;
lblLogo.ForeColor = 0xFF1890FF;
lblLogo.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// ============================================================
// 左侧 Menu
// ============================================================
var menu = AntdUI.Menu(winform.custom_sidebar_menu);
menu.Mode = AntdUI.TMenuMode.Inline;
menu.Font = fontNormal;
// --- Dashboard ---
var mDashboard = AntdUI.MenuItem("Dashboard");
mDashboard.IconSvg = svgDashboard;
mDashboard.Tag = "Dashboard";
menu.Items.Add(mDashboard);
var mOverview = AntdUI.MenuItem("Overview");
mOverview.Tag = "Dashboard/Overview";
mDashboard.Sub.Add(mOverview);
var mAnalytics = AntdUI.MenuItem("Analytics");
mAnalytics.Tag = "Dashboard/Analytics";
mDashboard.Sub.Add(mAnalytics);
// --- Settings ---
var mSettings = AntdUI.MenuItem("Settings");
mSettings.IconSvg = svgSettings;
mSettings.Tag = "Settings";
menu.Items.Add(mSettings);
var mProfile = AntdUI.MenuItem("Profile");
mProfile.Tag = "Settings/Profile";
mSettings.Sub.Add(mProfile);
var mEditProfile = AntdUI.MenuItem("Edit Profile");
mEditProfile.Tag = "Settings/Profile/Edit Profile";
mProfile.Sub.Add(mEditProfile);
var mChangeAvatar = AntdUI.MenuItem("Change Avatar");
mChangeAvatar.Tag = "Settings/Profile/Change Avatar";
mProfile.Sub.Add(mChangeAvatar);
// --- Content ---
var mContent = AntdUI.MenuItem("Content");
mContent.IconSvg = svgContent;
mContent.Tag = "Content";
menu.Items.Add(mContent);
var mPosts = AntdUI.MenuItem("Posts");
mPosts.Tag = "Content/Posts";
mContent.Sub.Add(mPosts);
var mAllPosts = AntdUI.MenuItem("All Posts");
mAllPosts.Tag = "Content/Posts/All Posts";
mPosts.Sub.Add(mAllPosts);
var mAddNew = AntdUI.MenuItem("Add New");
mAddNew.Tag = "Content/Posts/Add New";
mPosts.Sub.Add(mAddNew);
var mCategories = AntdUI.MenuItem("Categories");
mCategories.Tag = "Content/Posts/Categories";
mPosts.Sub.Add(mCategories);
// ============================================================
// 右侧面包屑
// ============================================================
var bread = AntdUI.Breadcrumb(winform.custom_breadcrumb);
bread.Separator = "/";
bread.ForeActive = 0xFF1890FF;
bread.Font = fontNormal;
var biHome = AntdUI.BreadcrumbItem();
biHome.Text = "Home";
bread.Items.Add(biHome);
// ============================================================
// 右侧内容区 — Tabs(Card 风格,支持关闭)
// ============================================================
var tabs = AntdUI.Tabs();
tabs.Dock = System.Windows.Forms.DockStyle.Fill;
tabs.Font = fontNormal;
tabs.Type = AntdUI.TabType.Card;
tabs.Style.Closable = true;
dotNet.setParent(tabs, winform.custom_content);
// 统一生成 TabPage 唯一键。
// 重点:用十六进制编码路径,避免 /、空格等字符影响 .NET Control.Name。
var makeTabName = function(tag){
return "tab_" ++ string.hex(tostring(tag));
};
// 根据菜单 tag 判断页面类型
var getPageType = function(tag){
var parts = string.split(tostring(tag), "/");
var first = parts[1];
if(first == "Dashboard") return 1;
if(first == "Settings") return 2;
if(first == "Content") return 3;
return 1;
};
// 更新面包屑
var updateBreadcrumb = function(pathArray){
bread.Items.Clear();
for(i=1;#pathArray;1){
var bi = AntdUI.BreadcrumbItem();
bi.Text = pathArray[i];
bread.Items.Add(bi);
}
};
// 在当前真实存在的 tabs.Pages 中按 Name 查找。
// 这是本示例最关键的函数:
// 1. 不用 openTabs 缓存表,避免关闭后留下旧引用。
// 2. 不用 Text 查找,因为不同菜单可能同名。
// 3. 不主要依赖 Tag 比较,避免 .NET object/string 互操作细节。
var findTabPageByTag = function(tag){
var tabName = makeTabName(tag);
var cnt = tabs.Pages.Count; // 预计算 count
for(i=0; cnt-1; 1){
var page = tabs.Pages.Item(i); // ✅ 圆括号调用 Item(i)
if(page && page.Name == tabName){
return page;
}
}
return null;
};
// 在当前标签页中创建演示内容
var addDemoContent = function(page, pathArray, pageType){
var pathStr = string.join(pathArray, " / ");
var title = pathArray[#pathArray];
var lbl = AntdUI.Label();
lbl.Text = title;
lbl.Font = fontTitle;
lbl.ForeColor = 0xFF1890FF;
lbl.SetBounds(40, 40, 500, 40);
page.Controls.Add(lbl);
var lblPath = AntdUI.Label();
lblPath.Text = "Path: " + pathStr;
lblPath.Font = fontTip;
lblPath.ForeColor = 0xFF888888;
lblPath.SetBounds(40, 90, 650, 24);
page.Controls.Add(lblPath);
if(pageType == 1){
var input = AntdUI.Input();
input.PlaceholderText = "Enter something for " + title;
input.Font = fontNormal;
input.SetBounds(40, 140, 340, 42);
page.Controls.Add(input);
var btn = AntdUI.Button();
btn.Text = "Submit";
btn.Type = AntdUI.TTypeMini.Primary;
btn.Font = fontNormal;
btn.SetBounds(40, 200, 120, 40);
page.Controls.Add(btn);
var lblResult = AntdUI.Label();
lblResult.Text = "Result will appear here";
lblResult.Font = fontTip;
lblResult.ForeColor = 0xFFAAAAAA;
lblResult.SetBounds(180, 200, 450, 40);
lblResult.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
page.Controls.Add(lblResult);
btn.Click = function(s, e){
var val = input.Text;
if(val && #val){
lblResult.Text = "✓ Submitted: " + val;
lblResult.ForeColor = 0xFF52C41A;
AntdUI.Message.success(baseForm, title + " — " + val);
} else {
lblResult.Text = "✗ Please enter some text first";
lblResult.ForeColor = 0xFFFF4D4F;
}
};
}
elseif(pageType == 2){
var alert = AntdUI.Alert();
alert.Text = "这是一个 Settings 配置页面,下方可输入多行备注信息。";
alert.Icon = AntdUI.TType.Success;
alert.SetBounds(40, 140, 640, 45);
page.Controls.Add(alert);
var inputMulti = AntdUI.Input();
inputMulti.Multiline = true;
inputMulti.PlaceholderText = "请输入多行备注...";
inputMulti.Font = fontNormal;
inputMulti.SetBounds(40, 200, 640, 130);
page.Controls.Add(inputMulti);
var btn = AntdUI.Button();
btn.Text = "保存备注";
btn.Type = AntdUI.TTypeMini.Primary;
btn.Font = fontNormal;
btn.SetBounds(40, 345, 130, 40);
page.Controls.Add(btn);
var lblResult = AntdUI.Label();
lblResult.Text = "备注内容将会显示在这里";
lblResult.Font = fontTip;
lblResult.ForeColor = 0xFFAAAAAA;
lblResult.SetBounds(180, 345, 500, 40);
lblResult.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
page.Controls.Add(lblResult);
btn.Click = function(s, e){
var val = inputMulti.Text;
if(val && #val){
lblResult.Text = "✓ 备注已保存,长度: " ++ #val;
lblResult.ForeColor = 0xFF52C41A;
AntdUI.Message.success(baseForm, title + " — 备注保存成功");
} else {
lblResult.Text = "✗ 备注不能为空";
lblResult.ForeColor = 0xFFFF4D4F;
}
};
}
elseif(pageType == 3){
var chkPublish = AntdUI.Checkbox();
chkPublish.Text = "发布文章";
chkPublish.Font = fontNormal;
chkPublish.Checked = true;
chkPublish.SetBounds(40, 140, 200, 30);
page.Controls.Add(chkPublish);
var chkNotify = AntdUI.Checkbox();
chkNotify.Text = "发送通知";
chkNotify.Font = fontNormal;
chkNotify.Checked = false;
chkNotify.SetBounds(40, 180, 200, 30);
page.Controls.Add(chkNotify);
var btn = AntdUI.Button();
btn.Text = "执行操作";
btn.Type = AntdUI.TTypeMini.Primary;
btn.Font = fontNormal;
btn.SetBounds(40, 230, 130, 40);
page.Controls.Add(btn);
var lblResult = AntdUI.Label();
lblResult.Text = "操作结果将显示在这里";
lblResult.Font = fontTip;
lblResult.ForeColor = 0xFFAAAAAA;
lblResult.SetBounds(180, 230, 500, 40);
lblResult.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
page.Controls.Add(lblResult);
btn.Click = function(s, e){
var publish = chkPublish.Checked;
var notify = chkNotify.Checked;
var msg = "";
if(publish && notify) msg = "已发布文章并发送通知";
elseif(publish) msg = "已发布文章(未通知)";
elseif(notify) msg = "已发送通知(未发布)";
else msg = "未执行任何操作";
lblResult.Text = "✓ " + msg;
lblResult.ForeColor = 0xFF52C41A;
AntdUI.Message.info(baseForm, title + " — " + msg);
};
}
var lblHint = AntdUI.Label();
lblHint.Text = "说明:重复点击左侧同一叶子菜单,应只激活当前标签页,不应重复新建。";
lblHint.Font = fontTip;
lblHint.ForeColor = 0xFFCCCCCC;
lblHint.SetBounds(40, 430, 680, 24);
page.Controls.Add(lblHint);
};
var openOrSwitchTab = function(tag, pathArray){
tag = tostring(tag);
var page = findTabPageByTag(tag);
if(page){
tabs.SelectedTab = page;
return page;
}
page = AntdUI.TabPage();
page.Text = pathArray[#pathArray];
page.Name = makeTabName(tag);
page.Tag = tag;
addDemoContent(page, pathArray, getPageType(tag));
tabs.Pages.Add(page);
tabs.SelectedTab = page;
return page;
};
// ============================================================
// 联动逻辑
// ============================================================
// Menu → Tabs + Breadcrumb
menu.SelectChanged = function(sender, e){
var item = e.Value;
if(!item || !item.Tag) return;
var tag = tostring(item.Tag);
var path = string.split(tag, "/");
// 仅叶子节点创建/激活标签页。
if(item.Sub.Count == 0){
openOrSwitchTab(tag, path);
}
updateBreadcrumb(path);
};
// Tabs 切换 → 同步面包屑
tabs.SelectedIndexChanged = function(sender, e){
var page = sender.SelectedTab;
if(!page || !page.Tag) return;
var path = string.split(tostring(page.Tag), "/");
updateBreadcrumb(path);
};
// Breadcrumb 点击 → Message 提示
bread.ItemClick = function(sender, e){
var item = e.getItem();
if(item){
AntdUI.Message.success(baseForm, "You clicked breadcrumb: «" + item.Text + "»");
}
};
// ---------- 释放 ----------
winform.onClose = function(){
fontLogo.Dispose();
fontTitle.Dispose();
fontNormal.Dispose();
fontTip.Dispose();
};
winform.show();
win.loopMessage();