vise/go/render/size.go

103 lines
2.1 KiB
Go

package render
import (
"bytes"
"fmt"
"log"
"strings"
)
type Sizer struct {
outputSize uint32
menuSize uint16
memberSizes map[string]uint16
totalMemberSize uint32
crsrs []uint32
sink string
}
func NewSizer(outputSize uint32) *Sizer {
return &Sizer{
outputSize: outputSize,
memberSizes: make(map[string]uint16),
}
}
func(szr *Sizer) WithMenuSize(menuSize uint16) *Sizer {
szr.menuSize = menuSize
return szr
}
func(szr *Sizer) Set(key string, size uint16) error {
var ok bool
_, ok = szr.memberSizes[key]
if ok {
return fmt.Errorf("already have key %s", key)
}
szr.memberSizes[key] = size
if size == 0 {
szr.sink = key
}
szr.totalMemberSize += uint32(size)
return nil
}
func(szr *Sizer) Check(s string) (uint32, bool) {
log.Printf("sizercheck %s", s)
l := uint32(len(s))
if szr.outputSize > 0 {
if l > szr.outputSize {
log.Printf("sizer check fails with length %v: %s", l, szr)
return 0, false
}
l = szr.outputSize - l
}
return l, true
}
func(szr *Sizer) String() string {
var diff uint32
if szr.outputSize > 0 {
diff = szr.outputSize - szr.totalMemberSize - uint32(szr.menuSize)
}
return fmt.Sprintf("output: %v, member: %v, menu: %v, diff: %v", szr.outputSize, szr.totalMemberSize, szr.menuSize, diff)
}
func(szr *Sizer) Size(s string) (uint16, error) {
r, ok := szr.memberSizes[s]
if !ok {
return 0, fmt.Errorf("unknown member: %s", s)
}
return r, nil
}
func(szr *Sizer) AddCursor(c uint32) {
log.Printf("added cursor: %v", c)
szr.crsrs = append(szr.crsrs, c)
}
func(szr *Sizer) GetAt(values map[string]string, idx uint16) (map[string]string, error) {
if szr.sink == "" {
return values, nil
}
outValues := make(map[string]string)
for k, v := range values {
if szr.sink == k {
if idx >= uint16(len(szr.crsrs)) {
return nil, fmt.Errorf("no more values in index")
}
c := szr.crsrs[idx]
v = v[c:]
nl := strings.Index(v, "\n")
log.Printf("k %v v %v c %v nl %v", k, v, c, nl)
if nl > 0 {
v = v[:nl]
}
b := bytes.ReplaceAll([]byte(v), []byte{0x00}, []byte{0x0a})
v = string(b)
}
outValues[k] = v
}
return outValues, nil
}