外观
Context menu(上下文菜单)
ContextMenu 给一个元素一个系统菜单,在被右键点击元素处(macOS 上为 Control 单击)打开;当它或其内部的元素拥有焦点时按下菜单键或 Shift+F10, 则在其下方打开。这个函数在菜单打开时构建菜单项,并在选中某一项之后的那 一帧再次运行,届时它的 Chosen 会上报选中:
go
row.ContextMenu(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.Submenu("Move to", func(m *ui.Menu) {
for _, f := range app.folders {
if m.Item(f.name).Chosen() {
moveTo, moved = f, i
}
}
})
m.Separator()
if m.Item("Delete").Disabled(note.locked).Chosen() {
deleted = i
}
})这个函数在元素构建时运行,位于构建各行的循环中:一个把该行从笔记中移除的 选择,如移动或删除它,会被记下来,以便在循环结束后进行更改(参见 视图)。
菜单项
Item(label)添加一个菜单项;Chosen报告它是否被选中。Checked(on)在其旁显示一个对勾,用于选择该项会切换的设置;Radio(on)将其显示为一组中选择一个设置的一项,当 on 为 true 时标记为被选中的那个。Disabled(d)将其置灰:它不能被选中。Shortcut(mods, key)在其旁显示一个按键,作为执行相同操作的快捷键。它 只显示按键:用上下文或元素上的Shortcut来处理它。Separator()在菜单项组之间添加一条线,Submenu(label, build)添加一个 打开子菜单的菜单项,子菜单由build填充。
由哪个元素响应
最内层带菜单的元素获得点击,比如位于带另一个菜单的行之内、带有自己菜单的 行内按钮。文本输入框带有其平台文本字段的编辑命令,可选中 的文本带有复制和全选。在输入框、文本或 Selectable 容器上的 ContextMenu 会替换那个菜单,EditItems 则把这些命令加入你自己的菜单, 作用于被点击的文字,就像聊天消息的文字在复制之上提供回复:
go
message.Selectable().ContextMenu(func(m *ui.Menu) {
if m.Item("Reply").Chosen() {
app.reply(msg)
}
m.Separator()
m.EditItems()
})同样的菜单在带 Element.Menu 的按钮下方打开:参见 菜单按钮。在测试中,tt.RightClick 打开上下文菜单, tt.Menu 列出它,tt.ChooseMenuItem 从中选择。
在窗口内绘制
PopoverMenu 接受同样的函数,由 MyGo 以主题的外观在窗口内绘制菜单,作为 一个弹出面板,用于系统本来会显示自己菜单的场合:在应用自己 设计的弹出面板和按钮旁边,系统菜单往往是那个看起来格格不入的。
go
card.PopoverMenu(func(m *ui.Menu) {
if m.Item("Play Next").Chosen() {
app.playNext(album)
}
if m.Item("Pinned").Checked(album.pinned).Chosen() {
album.pinned = !album.pinned
}
m.Submenu("Sort by", func(m *ui.Menu) {
for _, by := range []string{"Title", "Artist", "Year"} {
if m.Item(by).Radio(app.sort == by).Chosen() {
app.sort = by
}
}
})
m.Separator()
if m.Item("Remove").Shortcut(0, ui.KeyDelete).Disabled(album.locked).Chosen() {
app.remove(album)
}
})它像系统菜单一样打开:在元素被右键点击处,或在菜单键或 Shift+F10 之后于 其下方打开,在该点之后,或当窗口没有空间时在其之前,并随窗口滚动跟随元素。 它在打开时获得焦点,在关闭时把焦点交还给之前拥有它的元素,并具有系统菜单的 按键:
- 上和下在菜单项间移动,跳过分隔线和被禁用的项,并且循环;Home 和 End 前往 第一个和最后一个,键入菜单项的首字母会前往该项。
- 右打开该项的子菜单,左关闭它,从右到左时相反;指针 移到该项上时也会打开子菜单。
- Enter 和空格选择该项,如同点击;Escape 先关闭最上层的子菜单,再关闭菜单, Tab 关闭菜单。
- 菜单外的按下会关闭菜单,并继续传给指针下的内容。
它的菜单项在标签后显示它们的 Shortcut,被 Checked 或 Radio 标记的项 旁带有对勾或圆点。辅助技术看到的是由菜单项、复选框项和单选项组成的菜单, 无论是否勾选,与它看到系统菜单时一样。
绘制菜单的菜单项是元素:在测试中,tt.RightClick 打开它,tt.HasText 找到它的菜单项,tt.Click 选择一个,而 tt.Menu 只列出系统的菜单。
PopoverMenuButton 以这种方式绘制 菜单按钮的菜单,在其按钮下方,并接受 同样的函数:一行的右键点击和它的 ⋯ 按钮可以共用一个菜单,绘制得一模一样。