外观
Menu button(菜单按钮)
ui.MenuButton 创建一个显示标签和箭头的按钮,它会在其下方打开一个系统 菜单,就像系统的弹出按钮一样:当指针按下它时,或在它拥有键盘焦点时按 Enter、空格或下方向键。这个函数在菜单打开时构建菜单项,并在选中某一项 之后的那一帧再次运行,届时它的 Chosen 会上报选中:
go
ui.MenuButton(c, "Sort by", func(m *ui.Menu) {
for _, by := range []string{"Name", "Date", "Size"} {
if m.Item(by).Checked(app.sort == by).Chosen() {
app.sort = by
}
}
})菜单项
菜单使用的菜单项与上下文菜单相同:Item,带 Checked、Radio、Disabled 和 Shortcut,Separator 和 Submenu。
任意按钮
Element.Menu 可以把同样的菜单给任意按钮,比如一个只显示图标的按钮:
go
ui.Button(c, "").Label("More").Children(func() { ui.Icon(c, dots) }).Menu(func(m *ui.Menu) {
if m.Item("Duplicate").Chosen() {
app.duplicate()
}
if m.Item("Delete").Chosen() {
app.delete()
}
})在工具栏中,菜单按钮在被悬停之前不显示自己的外观。
在窗口内绘制
ui.PopoverMenuButton 接受同样的函数,由 MyGo 以主题的外观在窗口内绘制 菜单,就像 PopoverMenu 绘制上下文 菜单一样,用于系统本来会显示自己菜单的场合:在应用自己设计的弹出面板和 按钮旁边,系统菜单往往是那个看起来格格不入的,而右键绘制的菜单和 ⋯ 按钮 的系统菜单并排在一起,看起来像两个菜单。Element.PopoverMenuButton 把 这样的菜单给任意按钮,如同 Element.Menu 一样,并接受与 PopoverMenu 相同的函数,所以一个函数可以两者通用:
go
menu := func(m *ui.Menu) {
if m.Item("Rename").Shortcut(0, ui.KeyF2).Chosen() {
app.renaming = i
}
if m.Item("Pinned").Checked(note.pinned).Chosen() {
note.pinned = !note.pinned
}
m.Separator()
if m.Item("Delete").Disabled(note.locked).Chosen() {
app.delete(i)
}
}
row.PopoverMenu(menu)
row.Children(func() {
ui.Text(c, note.title).Grow(1)
ui.Button(c, "").Label("More").Children(func() { ui.Icon(c, dots) }).PopoverMenuButton(menu)
})它像系统菜单一样打开:当指针按下按钮时,或在按钮拥有焦点时按 Enter、空格 或下方向键:在按钮下方、与其起始端对齐,或当窗口没有空间时在其上方。再次 按下按钮会将其关闭。它具有 PopoverMenu 的按键、焦点和外观:它在打开时 获得焦点,若由键盘打开则焦点落在其第一个菜单项上,并在关闭时把焦点交还给 按钮;上、下、Home、End 和键入文字在其菜单项间移动,右和左打开与关闭子 菜单,Enter 和空格选择,Escape、Tab 和菜单外的按下将其关闭。选择会像 PopoverMenu 一样上报 Chosen。
辅助技术看到的是菜单按钮(其菜单显示时处于展开状态),以及带有菜单项、 复选框项和单选项的菜单,与它看到系统菜单时一样。在工具栏的溢出菜单中, 选择该按钮会在溢出按钮下方打开其绘制的菜单。
绘制菜单的菜单项是元素:在测试中,对按钮执行 tt.Click 会打开它, tt.HasText 找到它的菜单项,tt.Click 选择一个,而 tt.Menu 只列出系统 的菜单。
无障碍
辅助技术看到的是一个菜单按钮:macOS 上是 AXMenuButton,Linux 上是带 菜单的按压式按钮,Windows 上是可以展开的按钮。