Files

216 lines
5.0 KiB
Go

package projectsettings
import (
"strings"
"aego/core/mathx"
es "aego/engine/settings"
"aego/engine/settings/settingsui"
"aego/schema"
"aego/ui/core"
"aego/ui/widgets"
)
const narrowRegistry = 380
type ownerPage struct {
owner string
title string
}
func (p *Panel) projectOwners() []ownerPage {
st := p.d.Settings
if st == nil {
return nil
}
var out []ownerPage
st.Each(func(_ es.Key, d *es.Desc) {
if !d.Flags.Has(es.Project) {
return
}
for _, o := range out {
if o.owner == d.Owner {
return
}
}
title := d.Category
if title == "" {
title = d.Owner
}
out = append(out, ownerPage{owner: d.Owner, title: title})
})
return out
}
func (p *Panel) hasDefaults(owner string) bool {
for _, o := range p.projectOwners() {
if o.owner == owner {
return true
}
}
return false
}
func (p *Panel) tabs(ui *core.Context, id string) int {
row := ui.Cursor().Next(0)
w := min(140, row.W/2-2)
for i, label := range [2]string{"Settings", "Defaults"} {
on := p.tab[id] == i
if widgets.ToggleButton(ui, core.IDSeq(ui.ID("tab"), i), mathx.Rect{X: row.X + float32(i)*(w+4), Y: row.Y, W: w, H: row.H}, label, &on) {
p.tab[id] = i
}
}
return p.tab[id]
}
func (p *Panel) drawDefaults(ui *core.Context, owner string) bool {
st := p.d.Settings
if st == nil {
return false
}
widgets.LabelWrapped(ui, "Starting values of player settings. Players change them in the game settings; this page sets what a new player gets.", true)
widgets.Separator(ui)
changed := false
value := func(k es.Key) schema.Value {
if v, ok := p.proj[k]; ok {
return v
}
return st.Desc(k).Default
}
put := func(k es.Key, v schema.Value) {
if es.Equal(v, st.Desc(k).Default) {
delete(p.proj, k)
} else {
p.proj[k] = v
}
changed = true
}
st.Each(func(k es.Key, d *es.Desc) {
if d.Owner != owner || !d.Flags.Has(es.Project) || settingsui.Paired(st, k) {
return
}
ui.PushID(d.ID)
v := value(k)
if m := settingsui.Partner(st, k); m != 0 {
mv := value(m)
vc, mc := p.ed.Pair(ui, st, k, &v, m, &mv)
if vc {
put(k, v)
}
if mc {
put(m, mv)
}
} else if p.ed.Field(ui, st, k, &v) {
put(k, v)
}
ui.PopID()
})
return changed
}
func sourceColor(th *core.Theme, l es.Layer) mathx.Color {
switch l {
case es.LayerProject:
return th.Text
case es.LayerUser:
return th.Accent
case es.LayerSession:
return th.Warn
}
return th.TextDim
}
func (p *Panel) drawRegistry(ui *core.Context) bool {
st := p.d.Settings
th := &ui.Theme
widgets.SearchField(ui, ui.ID("filter"), ui.Cursor().Next(0), &p.filter)
q := strings.ToLower(strings.TrimSpace(p.filter))
srcW := ui.TextSize("session").X + 16
cell := func(r mathx.Rect, s string, col mathx.Color) {
ui.Text(widgets.Elide(ui, s, r.W-8), mathx.Vec2{X: r.X + 4, Y: ui.TextY(r)}, col)
}
split := func(r mathx.Rect) (mathx.Rect, mathx.Rect, mathx.Rect) {
rest := max(0, r.W-srcW)
nameW := rest * 0.55
return mathx.Rect{X: r.X, Y: r.Y, W: nameW, H: r.H},
mathx.Rect{X: r.X + nameW, Y: r.Y, W: rest - nameW, H: r.H},
mathx.Rect{X: r.X + rest, Y: r.Y, W: srcW, H: r.H}
}
hr := ui.Cursor().Next(0)
a, b, c := split(hr)
cell(a, "Setting", th.TextDim)
if hr.W >= narrowRegistry {
cell(b, "Value", th.TextDim)
}
cell(c, "Source", th.TextDim)
owner, shown := "", 0
st.Each(func(k es.Key, d *es.Desc) {
label := d.Label()
if q != "" && !strings.Contains(strings.ToLower(d.ID), q) && !strings.Contains(strings.ToLower(label), q) && !strings.Contains(strings.ToLower(d.Category), q) {
return
}
if d.Owner != owner {
owner = d.Owner
if shown > 0 {
ui.Cursor().Next(4)
}
widgets.Label(ui, inspectTitle(owner))
}
shown++
r := ui.Cursor().Next(0)
stacked := r.W < narrowRegistry
if stacked {
r.H += th.RowHeight - 4
ui.Cursor().Y += th.RowHeight - 4
}
id := core.IDSeq(ui.ID("reg"), int(k))
if ui.MouseOver(id, r) {
ui.RoundRect(r, th.Radius.Menu, th.WidgetHot)
}
if ui.Flash != "" && strings.EqualFold(ui.Flash, label) {
if k := 1 - float32(ui.Time-ui.FlashAt)/2; k > 0 {
fc := th.Accent
fc.A = 0.28 * k
ui.RoundRect(r, th.Radius.Menu, fc)
}
if !ui.FlashSeen {
ui.FlashY, ui.FlashSeen = r.Y, true
}
}
line := mathx.Rect{X: r.X, Y: r.Y, W: r.W, H: th.RowHeight}
a, b, c := split(line)
src := st.Source(k)
val := st.Format(k)
if val == "" {
val = "—"
}
if stacked {
a.W = line.W - srcW
cell(a, label, th.Text)
cell(mathx.Rect{X: r.X + 10, Y: r.Y + th.RowHeight - 4, W: r.W - 10, H: th.RowHeight}, val, th.TextDim)
} else {
cell(a, label, th.Text)
cell(b, val, th.Text)
}
badge := mathx.Rect{X: c.X + 2, Y: line.Y + 3, W: c.W - 4, H: line.H - 6}
if src != es.LayerDefault {
bg := sourceColor(th, src)
bg.A = 0.18
ui.RoundRect(badge, th.Radius.Button, bg)
}
ui.TextIn(badge, src.String(), sourceColor(th, src), core.AlignCenter)
widgets.Tooltip(ui, id, d.ID)
})
if shown == 0 {
widgets.LabelDim(ui, "No setting matches")
}
return false
}
func inspectTitle(owner string) string {
if owner == "" {
return ""
}
return strings.ToUpper(owner[:1]) + owner[1:]
}