local mainWindow = GUI:Win_Create("MenuWindow", 0, 0, 0, 0, false, false, true, false, false, false, 1)
-- 一级菜单配置(调整位置,留出二级菜单空间)
local primaryMenus = {
{x = 50, y = 400, width = 100, height = 40, text = "菜单1"},
{x = 50, y = 350, width = 100,
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-02-27 01:31:06 |
👁️ 阅读: 15
```lua
-- 垂直二级菜单模块
local VerticalMenuSystem = {}
-- 存储所有菜单数据
local menuData = {
mainWindow = nil,
primaryButtons = {},
secondaryPanels = {},
menuPositions = {},
currentExpandedMenu = nil
}
-- 创建菜单系统
function VerticalMenuSystem.Create(parentWindow)
if GUI:Win_IsNull(parentWindow) then
SL:print("错误:父窗口为空")
return
end
menuData.mainWindow = parentWindow
-- 创建一级菜单配置
local primaryMenus = {
{x = 50, y = 400, width = 100, height = 40, text = "菜单1"},
{x = 50, y = 350, width = 100, height = 40, text = "菜单2"},
{x = 50, y = 300, width = 100, height = 40, text = "菜单3"},
{x = 50, y = 250, width = 100, height = 40, text = "菜单4"},
{x = 50, y = 200, width = 100, height = 40, text = "菜单5"}
}
-- 创建二级菜单配置
local secondaryMenus = {
{
{x = 50, y = 360, width = 100, height = 30, text = "子项1-1"},
{x = 50, y = 330, width = 100, height = 30, text = "子项1-2"},
{x = 50, y = 300, width = 100, height = 30, text = "子项1-3"}
},
{
{x = 50, y = 310, width = 100, height = 30, text = "子项2-1"},
{x = 50, y = 280, width = 100, height = 30, text = "子项2-2"},
{x = 50, y = 250, width = 100, height = 30, text = "子项2-3"}
},
{
{x = 50, y = 260, width = 100, height = 30, text = "子项3-1"},
{x = 50, y = 230, width = 100, height = 30, text = "子项3-2"},
{x = 50, y = 200, width = 100, height = 30, text = "子项3-3"}
},
{
{x = 50, y = 210, width = 100, height = 30, text = "子项4-1"},
{x = 50, y = 180, width = 100, height = 30, text = "子项4-2"},
{x = 50, y = 150, width = 100, height = 30, text = "子项4-3"}
},
{
{x = 50, y = 160, width = 100, height = 30, text = "子项5-1"},
{x = 50, y = 130, width = 100, height = 30, text = "子项5-2"},
{x = 50, y = 100, width = 100, height = 30, text = "子项5-3"}
}
}
-- 创建一级菜单
for i, config in ipairs(primaryMenus) do
local btn = GUI:Button_Create(menuData.mainWindow, "primary_"..i, config.x, config.y, "res/public/1900000612.png")
GUI:Button_setTitleText(btn, config.text)
GUI:setContentSize(btn, config.width, config.height)
-- 存储菜单位置信息
menuData.menuPositions[i] = {
primaryY = config.y,
secondaryY = {}
}
for j, secConfig in ipairs(secondaryMenus[i]) do
menuData.menuPositions[i].secondaryY[j] = secConfig.y
end
-- 创建二级菜单容器
local secondaryContainer = GUI:Layout_Create(menuData.mainWindow, "secondary_"..i, 0, 0, 0, 0, false)
GUI:setVisible(secondaryContainer, false)
-- 创建二级菜单项
local secondaryItems = {}
for j, secConfig in ipairs(secondaryMenus[i]) do
local item = GUI:Button_Create(secondaryContainer, "item_"..i.."_"..j, secConfig.x, secConfig.y, "res/public/1900000612.png")
GUI:Button_setTitleText(item, secConfig.text)
GUI:setContentSize(item, secConfig.width, secConfig.height)
GUI:setVisible(item, false)
GUI:setOpacity(item, 0)
secondaryItems[j] = item
end
menuData.secondaryPanels[i] = {
container = secondaryContainer,
items = secondaryItems,
isExpanded = false,
itemCount = #secondaryMenus[i]
}
-- 一级菜单点击事件
GUI:addOnClickEvent(btn, function()
VerticalMenuSystem.ToggleMenu(i)
end)
menuData.primaryButtons[i] = btn
end
-- 添加背景
local bg = GUI:Image_Create(menuData.mainWindow, "bg", 0, 0, "res/public_win32/1900000610.png")
GUI:setLocalZOrder(bg, -1)
SL:print("垂直二级菜单系统创建完成!")
end
-- 计算菜单移动距离
function VerticalMenuSystem.GetMenuMoveDistance(menuIndex)
local panel = menuData.secondaryPanels[menuIndex]
return panel.itemCount * 35
end
-- 移动其他菜单(展开时)
function VerticalMenuSystem.MoveOtherMenusDown(startIndex, distance)
for i = startIndex + 1, #menuData.primaryButtons do
local btn = menuData.primaryButtons[i]
local currentPos = GUI:getPosition(btn)
local targetY = currentPos.y - distance
GUI:runAction(btn, GUI:ActionMoveTo(0.3, currentPos.x, targetY))
local panel = menuData.secondaryPanels[i]
if panel and panel.isExpanded then
for _, item in ipairs(panel.items) do
local itemPos = GUI:getPosition(item)
GUI:runAction(item, GUI:ActionMoveTo(0.3, itemPos.x, itemPos.y - distance))
end
end
end
end
-- 移动其他菜单(收回时)
function VerticalMenuSystem.MoveOtherMenusUp(startIndex, distance)
for i = startIndex + 1, #menuData.primaryButtons do
local btn = menuData.primaryButtons[i]
local currentPos = GUI:getPosition(btn)
local targetY = currentPos.y + distance
GUI:runAction(btn, GUI:ActionMoveTo(0.3, currentPos.x, targetY))
local panel = menuData.secondaryPanels[i]
if panel and panel.isExpanded then
for _, item in ipairs(panel.items) do
local itemPos = GUI:getPosition(item)
GUI:runAction(item, GUI:ActionMoveTo(0.3, itemPos.x, itemPos.y + distance))
end
end
end
end
-- 展开菜单动画
function VerticalMenuSystem.ExpandMenu(menuIndex)
local panel = menuData.secondaryPanels[menuIndex]
local moveDistance = VerticalMenuSystem.GetMenuMoveDistance(menuIndex)
VerticalMenuSystem.MoveOtherMenusDown(menuIndex, moveDistance)
GUI:setVisible(panel.container, true)
for i = #panel.items, 1, -1 do
local item = panel.items[i]
GUI:setVisible(item, true)
local targetY = menuData.menuPositions[menuIndex].secondaryY[i]
local initialY = targetY + 20
GUI:setPosition(item, menuData.menuPositions[menuIndex].primaryY, initialY)
GUI:setOpacity(item, 0)
local delay = (i - 1) * 0.1
local moveAction = GUI:ActionMoveTo(0.3, menuData.menuPositions[menuIndex].primaryY, targetY)
local fadeAction = GUI:ActionFadeTo(0.3, 255)
local sequence = GUI:ActionSequence(
GUI:DelayTime(delay),
GUI:ActionSpawn(moveAction, fadeAction)
)
GUI:runAction(item, sequence)
end
panel.isExpanded = true
menuData.currentExpandedMenu = menuIndex
end
-- 收回菜单动画
function VerticalMenuSystem.CollapseMenu(menuIndex)
local panel = menuData.secondaryPanels[menuIndex]
local moveDistance = VerticalMenuSystem.GetMenuMoveDistance(menuIndex)
VerticalMenuSystem.MoveOtherMenusUp(menuIndex, moveDistance)
for i = 1, #panel.items do
local item = panel.items[i]
local delay = (i - 1) * 0.1
local currentPos = GUI:getPosition(item)
local moveAction = GUI:ActionMoveTo(0.3, currentPos.x, currentPos.y + 20)
local fadeAction = GUI:ActionFadeTo(0.3, 0)
local sequence = GUI:ActionSequence(
GUI:DelayTime(delay),
GUI:ActionSpawn(moveAction, fadeAction),
GUI:CallFunc(function()
GUI:setVisible(item, false)
GUI:setOpacity(item, 255)
end)
)
GUI:runAction(item, sequence)
end
SL:ScheduleOnce(function()
if panel.isExpanded then
GUI:setVisible(panel.container, false)
panel.isExpanded = false
if menuData.currentExpandedMenu == menuIndex then
menuData.currentExpandedMenu = nil
end
end
end, 0.35)
end
-- 切换菜单显示/隐藏
function VerticalMenuSystem.ToggleMenu(menuIndex)
local panel = menuData.secondaryPanels[menuIndex]
if panel.isExpanded then
VerticalMenuSystem.CollapseMenu(menuIndex)
else
if menuData.currentExpandedMenu and menuData.currentExpandedMenu ~= menuIndex then
VerticalMenuSystem.CollapseMenu(menuData.currentExpandedMenu)
end
VerticalMenuSystem.ExpandMenu(menuIndex)
end
end
-- 销毁菜单系统
function VerticalMenuSystem.Destroy()
for i, btn in ipairs(menuData.primaryButtons) do
GUI:removeFromParent(btn)
end
for i, panel in ipairs(menuData.secondaryPanels) do
for j, item in ipairs(panel.items) do
GUI:removeFromParent(item)
end
GUI:removeFromParent(panel.container)
end
menuData = {
mainWindow = nil,
primaryButtons = {},
secondaryPanels = {},
menuPositions = {},
currentExpandedMenu = nil
}
SL:print("垂直二级菜单系统已销毁")
end
-- 使用示例:
-- 1. 创建窗口
-- local mainWindow = GUI:Win_Create("MenuWindow", 0, 0, 0, 0, false, false, true, false, false, false, 1)
--
-- 2. 创建菜单系统
-- VerticalMenuSystem.Create(mainWindow)
--
-- 3. 切换菜单(可在其他地方调用)
-- VerticalMenuSystem.ToggleMenu(1) -- 展开/收回第一个菜单
--
-- 4. 销毁菜单
-- VerticalMenuSystem.Destroy()
return VerticalMenuSystem
```
封装好的模块可以直接调用,使用方法在代码末尾有示例说明。模块包含了创建、展开/收回、销毁等完整功能,使用时只需要调用`VerticalMenuSystem.Create(父窗口)`即可。
← 返回问答库