Files
aego/ui/widgets/menu.go
T

148 lines
3.6 KiB
Go

package widgets
import (
"aego/core/mathx"
"aego/ui/core"
)
type MenuBar struct {
c *core.Context
r mathx.Rect
x float32
}
func BeginMenuBar(c *core.Context, r mathx.Rect) MenuBar {
th := &c.Theme
c.Rect(r, th.BarBg)
c.Rect(mathx.Rect{X: r.X, Y: r.Y + r.H - 1, W: r.W, H: 1}, th.BarBorder)
return MenuBar{c: c, r: r, x: r.X + 4}
}
func (m *MenuBar) X() float32 {
return m.x
}
func (m *MenuBar) Menu(label string, width float32) bool {
c := m.c
th := &c.Theme
id := c.ID("menu/" + label)
w := c.TextSize(label).X + 2*th.Padding + 4
br := mathx.Rect{X: m.x, Y: m.r.Y, W: w, H: m.r.H}
m.x += w
open := c.PopupOpen(id)
at := mathx.Vec2{X: br.X, Y: br.Y + br.H}
if c.Pressed(id, br) {
c.CloseAllPopups()
if !open {
c.OpenPopup(id, at)
}
} else if !open && c.AnyPopup() && c.Hovered(id) {
c.CloseAllPopups()
c.OpenPopup(id, at)
}
if c.PopupOpen(id) || c.Hovered(id) {
c.RoundRect(mathx.Rect{X: br.X, Y: br.Y + 3, W: br.W, H: br.H - 6}, th.Radius.Menu, th.ButtonHover)
}
c.TextIn(br, label, th.Text, core.AlignCenter)
return c.BeginPopup(id, width)
}
func (m *MenuBar) EndMenu() {
m.c.EndPopup()
}
func MenuItem(c *core.Context, label, shortcut string, enabled, checked bool) bool {
return Entry(c, Item{Label: label, Shortcut: shortcut, Enabled: enabled, Checked: checked})
}
func MenuItemIcon(c *core.Context, label, shortcut, icon string, enabled, checked bool) bool {
return Entry(c, Item{Label: label, Shortcut: shortcut, Icon: icon, Enabled: enabled, Checked: checked})
}
func SubMenu(c *core.Context, label string, width float32) bool {
return SubMenuIcon(c, label, "", width)
}
func SubMenuIcon(c *core.Context, label, icon string, width float32) bool {
th := &c.Theme
r := c.Cursor().Next(0)
c.FitPopup(26 + c.TextSize(label).X + r.H + 8)
id := c.ID("sub/" + label)
hot := c.MouseOver(id, r)
open := c.PopupOpen(id)
if hot && !open {
c.CloseChildren()
c.OpenPopup(id, mathx.Vec2{X: r.X + r.W + th.Padding, Y: r.Y - th.Padding})
open = true
}
if hot || open {
c.RoundRect(r, th.Radius.Menu, th.Selection)
}
if HasIcon(c, icon) {
IconAt(c, mathx.Rect{X: r.X + 4, Y: r.Y + (r.H-16)/2, W: 16, H: 16}, icon, th.TextDim)
}
c.Text(label, mathx.Vec2{X: r.X + 26, Y: c.TextY(r)}, th.Text)
Chevron(c, mathx.Rect{X: r.X + r.W - r.H, Y: r.Y, W: r.H, H: r.H}, false, th.TextDim)
return c.BeginPopup(id, width)
}
func EndSubMenu(c *core.Context) {
c.EndPopup()
}
const tipDelay = 0.6
type Item struct {
Label string
Shortcut string
Icon string
Tip string
Enabled bool
Checked bool
}
func HasIcon(c *core.Context, id string) bool {
return id != "" && c.Icons != nil && c.Icons.Has(id)
}
func Entry(c *core.Context, it Item) bool {
th := &c.Theme
r := c.Cursor().Next(0)
need := 26 + c.TextSize(it.Label).X + 8
if it.Shortcut != "" {
need += 24 + c.TextSize(it.Shortcut).X
}
c.FitPopup(need)
id := c.ID("item/" + it.Label)
clicked := false
if it.Enabled {
clicked = c.Clicked(id, r)
if c.Hot() == id {
c.CloseChildren()
c.RoundRect(r, th.Radius.Menu, th.Selection)
}
} else {
c.MouseOver(id, r)
}
col, tint := th.Text, th.TextDim
if !it.Enabled {
col, tint = th.TextDisabled, th.TextDisabled
}
box := mathx.Rect{X: r.X + 4, Y: r.Y + (r.H-16)/2, W: 16, H: 16}
switch {
case it.Checked:
CheckMark(c, box, th.Accent)
case HasIcon(c, it.Icon):
IconAt(c, box, it.Icon, tint)
}
c.Text(it.Label, mathx.Vec2{X: r.X + 26, Y: c.TextY(r)}, col)
if it.Shortcut != "" {
c.TextIn(r, it.Shortcut, th.TextDim, core.AlignRight)
}
TooltipAfter(c, id, it.Tip, tipDelay)
if clicked {
c.CloseAllPopups()
}
return clicked
}