111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package site
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"aego/scene/sceneio"
|
|
)
|
|
|
|
func (b *builder) sceneTree(src, root string) string {
|
|
nodes, err := sceneio.Outline([]byte(src))
|
|
if err != nil || len(nodes) == 0 {
|
|
return ""
|
|
}
|
|
count := 0
|
|
var walk func([]sceneio.OutlineNode)
|
|
walk = func(list []sceneio.OutlineNode) {
|
|
for _, n := range list {
|
|
count++
|
|
walk(n.Children)
|
|
}
|
|
}
|
|
walk(nodes)
|
|
var c strings.Builder
|
|
label := strconv.Itoa(count) + " nodes"
|
|
if count == 1 {
|
|
label = "1 node"
|
|
}
|
|
c.WriteString(`<details class="scene-tree"><summary>` + b.icon(root, "file.scene", "") + `<span>Scene</span><span class="count">` + label + `</span>` + b.icon(root, "ui.chevron_right", "chev") + `</summary><div class="st-body">`)
|
|
b.treeNodes(&c, nodes, root)
|
|
c.WriteString("</div></details>\n")
|
|
return c.String()
|
|
}
|
|
|
|
func (b *builder) treeNodes(c *strings.Builder, nodes []sceneio.OutlineNode, root string) {
|
|
for _, n := range nodes {
|
|
name := n.Name
|
|
if name == "" {
|
|
name = "Node"
|
|
}
|
|
c.WriteString(`<div class="st-node"><div class="st-head">` + b.icon(root, "node.empty", "") + esc(name))
|
|
if !n.Enabled {
|
|
c.WriteString(` <span class="note">disabled</span>`)
|
|
}
|
|
c.WriteString(`</div>`)
|
|
for _, blk := range n.Blocks {
|
|
b.treeBlock(c, n.ID, blk, root)
|
|
}
|
|
if len(n.Children) > 0 {
|
|
c.WriteString(`<div class="st-children">`)
|
|
b.treeNodes(c, n.Children, root)
|
|
c.WriteString(`</div>`)
|
|
}
|
|
c.WriteString("</div>")
|
|
}
|
|
}
|
|
|
|
func (b *builder) treeBlock(c *strings.Builder, node string, blk sceneio.OutlineBlock, root string) {
|
|
id, title, icon := blk.Type, blk.Type, "code.block"
|
|
switch blk.Kind {
|
|
case "transform":
|
|
id, title, icon = "engine.Transform", "Transform", "cat.transform"
|
|
case "component":
|
|
if e, ok := b.byID[id]; ok {
|
|
title, icon = e.Title, b.entryIcon(e)
|
|
}
|
|
case "script":
|
|
icon = "file.script"
|
|
}
|
|
c.WriteString(`<div class="st-comp">`)
|
|
head := b.icon(root, icon, "") + esc(title)
|
|
if u, ok := b.urls[id]; ok {
|
|
c.WriteString(`<a class="st-ctitle" href="` + esc(root+u) + `">` + head + `</a>`)
|
|
} else {
|
|
c.WriteString(`<span class="st-ctitle">` + head + `</span>`)
|
|
}
|
|
c.WriteString(`<div class="st-fields">`)
|
|
for _, f := range blk.Fields {
|
|
fe := b.fieldEntry(id, f.Name)
|
|
name, typ := esc(f.Name), ""
|
|
if fe != nil {
|
|
if u, ok := b.urls[fe.ID]; ok {
|
|
name = `<a href="` + esc(root+u) + `">` + name + `</a>`
|
|
}
|
|
if fe.Field != nil {
|
|
typ = fe.Field.Type
|
|
for _, n := range fe.Field.Notes {
|
|
if strings.HasPrefix(n, "one of:") {
|
|
typ = "enum"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
val := esc(f.Value)
|
|
if f.Kind == "color" {
|
|
val = `<i class="sw" style="background:` + esc(f.Value) + `"></i>` + val
|
|
}
|
|
c.WriteString(`<span class="k">` + name + `</span><span class="t">` + esc(typ) + `</span><span class="v" data-k="` + esc(sceneio.OutlineKey(node, blk, f.Name)) + `" data-kind="` + f.Kind + `">` + val + `</span>`)
|
|
}
|
|
c.WriteString("</div></div>")
|
|
}
|
|
|
|
func (b *builder) fieldEntry(owner, name string) *Entry {
|
|
for _, k := range b.kids[owner] {
|
|
if i := strings.LastIndexByte(k, '.'); i >= 0 && strings.EqualFold(k[i+1:], name) {
|
|
return b.byID[k]
|
|
}
|
|
}
|
|
return nil
|
|
}
|