package main
import (
"go/ast"
"go/token"
"strconv"
"strings"
"gioui.org/widget"
"golang.org/x/tools/go/packages"
)
type iconData struct {
Name string
Data []byte
Icon *widget.Icon
}
func loadIcons() (map[string][]iconData, error) {
cfg := &packages.Config{Mode: packages.NeedName |
packages.NeedImports | packages.NeedDeps |
packages.NeedTypes | packages.NeedTypesSizes |
packages.NeedSyntax | packages.NeedTypesInfo,
}
pkgs, err := packages.Load(cfg, "golang.org/x/exp/shiny/materialdesign/icons")
if err != nil {
return nil, err
}
pkgIcons := pkgs[0]
res := make(map[string][]iconData)
for _, f := range pkgIcons.Syntax {
for _, decl := range f.Decls {
switch d := decl.(type) {
case *ast.GenDecl:
if d.Tok != token.VAR {
continue
}
spec := d.Specs[0]
v := spec.(*ast.ValueSpec)
bytes := v.Values[0].(*ast.CompositeLit).Elts
data := iconData{
Name: v.Names[0].Name,
Data: make([]byte, len(bytes)),
}
for i, elt := range bytes {
e := elt.(*ast.BasicLit)
b, err := strconv.ParseInt(e.Value, 0, 64)
if err != nil {
return nil, err
}
data.Data[i] = byte(b)
}
data.Icon, err = widget.NewIcon(data.Data)
if err != nil {
return nil, err
}
key, name := icName(data.Name)
data.Name = name
res[key] = append(res[key], data)
}
}
}
return res, nil
}
func icName(s string) (parent, name string) {
switch {
case strings.HasPrefix(s, "AV"):
parent = "AV"
name = s
default:
for i, c := range s[1:] {
if '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' {
i++
parent = s[:i]
name = s[i:]
break
}
}
}
return
}