feat(ui): add Node.TextInt and Node.Masked
- commit
- 008e36d0ffd4f5ab386943b9c2192b9bdd736624
- author
- brice · · 2026-10-01 16:30 UTC
- parent
- e1768ca
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +32 -0
M internal/ui/controls.go +32 -0
| @@ -3,6 +3,7 @@ package ui | |||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | 5 | "github.com/bnema/nefergui/internal/edit" | |
| 6 | + | "strconv" | |
| 6 | 7 | "strings" | |
| 7 | 8 | ) | |
| 8 | 9 | ||
| @@ -231,3 +232,34 @@ func (n Node) Heading(text string, options ...HeadingOption) { | |||
| 231 | 232 | } | |
| 232 | 233 | } | |
| 233 | 234 | } | |
| 235 | + | ||
| 236 | + | // TextInt shows prefix followed by v in decimal without fmt boxing. It builds | |
| 237 | + | // the text in a stack buffer, so the only allocation is the final string. | |
| 238 | + | func (n Node) TextInt(prefix string, v int64, options ...ContainerOption) { | |
| 239 | + | child := n.child("text", "", options) | |
| 240 | + | if !child.valid() { | |
| 241 | + | return | |
| 242 | + | } | |
| 243 | + | var stack [64]byte | |
| 244 | + | buf := append(stack[:0], prefix...) | |
| 245 | + | buf = strconv.AppendInt(buf, v, 10) | |
| 246 | + | child.element.text = string(buf) | |
| 247 | + | } | |
| 248 | + | ||
| 249 | + | // maskBullets backs Masked for common counts without allocating. | |
| 250 | + | var maskBullets = strings.Repeat("•", 256) | |
| 251 | + | ||
| 252 | + | // Masked shows count bullet glyphs and stores no value, for a secret held | |
| 253 | + | // outside the view (a password field fed from an external buffer). A negative | |
| 254 | + | // count shows nothing. | |
| 255 | + | func (n Node) Masked(count int, options ...ContainerOption) { | |
| 256 | + | child := n.child("text", "", options) | |
| 257 | + | if !child.valid() || count <= 0 { | |
| 258 | + | return | |
| 259 | + | } | |
| 260 | + | if count <= 256 { | |
| 261 | + | child.element.text = maskBullets[:count*len("•")] | |
| 262 | + | return | |
| 263 | + | } | |
| 264 | + | child.element.text = strings.Repeat("•", count) | |
| 265 | + | } | |
| @@ -3,6 +3,7 @@ package ui | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | "github.com/bnema/nefergui/internal/edit" | 5 | "github.com/bnema/nefergui/internal/edit" | ||
| 6 | + | "strconv" | |||
| 6 | "strings" | 7 | "strings" | ||
| 7 | ) | 8 | ) | ||
| 8 | 9 | ||||
| @@ -231,3 +232,34 @@ func (n Node) Heading(text string, options ...HeadingOption) { | |||||
| 231 | } | 232 | } | ||
| 232 | } | 233 | } | ||
| 233 | } | 234 | } | ||
| 235 | + | ||||
| 236 | + | // TextInt shows prefix followed by v in decimal without fmt boxing. It builds | |||
| 237 | + | // the text in a stack buffer, so the only allocation is the final string. | |||
| 238 | + | func (n Node) TextInt(prefix string, v int64, options ...ContainerOption) { | |||
| 239 | + | child := n.child("text", "", options) | |||
| 240 | + | if !child.valid() { | |||
| 241 | + | return | |||
| 242 | + | } | |||
| 243 | + | var stack [64]byte | |||
| 244 | + | buf := append(stack[:0], prefix...) | |||
| 245 | + | buf = strconv.AppendInt(buf, v, 10) | |||
| 246 | + | child.element.text = string(buf) | |||
| 247 | + | } | |||
| 248 | + | ||||
| 249 | + | // maskBullets backs Masked for common counts without allocating. | |||
| 250 | + | var maskBullets = strings.Repeat("•", 256) | |||
| 251 | + | ||||
| 252 | + | // Masked shows count bullet glyphs and stores no value, for a secret held | |||
| 253 | + | // outside the view (a password field fed from an external buffer). A negative | |||
| 254 | + | // count shows nothing. | |||
| 255 | + | func (n Node) Masked(count int, options ...ContainerOption) { | |||
| 256 | + | child := n.child("text", "", options) | |||
| 257 | + | if !child.valid() || count <= 0 { | |||
| 258 | + | return | |||
| 259 | + | } | |||
| 260 | + | if count <= 256 { | |||
| 261 | + | child.element.text = maskBullets[:count*len("•")] | |||
| 262 | + | return | |||
| 263 | + | } | |||
| 264 | + | child.element.text = strings.Repeat("•", count) | |||
| 265 | + | } | |||