Add Marquee decorator for long message scrolling - #126
Conversation
|
Implementation assumes that (string width = bytes width), therefore it's going to fail with non Latin strings. Try it for example with |
|
@vbauerster Da, I know what you mean, I noticed that issue too. After opened this PR and some investigation of mpb source code, I found the I implement this feature in my project like this (https://github.com/DeathKing/pico/blob/master/cmd/pdf2image/bar.go#L14-L28): bar.movFor this specific implementation, the API requires a getter function to obtain the text for display, which may not suitable for most case, a I'd like to know your opinion about this feature. |
|
Try this?🤔 func Marquee(t string, ws int, divider string, wcc ...decor.WC) decor.Decorator {
var count int
var f = func(s decor.Statistics) string {
length := runewidth.StringWidth(t + divider)
if runewidth.StringWidth(t) < ws {
return runewidth.FillRight(t, ws)
}
text := t + divider
var msg string
if count-ws > length {
msg = TruncateLeft(Truncate(text, count+ws), ws)
} else {
msg = TruncateLeft(Truncate(text, count+ws), count)
}
if count+ws > length {
msg += Truncate(text, count+ws-length)
}
count++
if count+ws >= len(t)+len(divider)-1 {
count = 0
}
return runewidth.FillRight(msg, ws)
}
return decor.Any(f, wcc...)
}
func Truncate(s string, size int) string {
return runewidth.Truncate(s, size, "")
}
func TruncateLeft(s string, size int) string {
return runewidth.TruncateLeft(s, size, "")
} |
Solaris-star
left a comment
There was a problem hiding this comment.
Nice idea — a scrolling marquee decorator for long filenames in progress bars.
A few things to address:
-
Byte-level scrolling breaks multi-byte UTF-8:
bytes := []byte(text)and indexing by byte offset will split multi-byte characters (CJK, emoji, accented chars), producing garbled output. Consider[]runeinstead, or usegithub.com/mattn/go-runewidth(already a dependency) for display-width-aware scrolling. -
No wrap-around: when
start + i >= len(bytes)the remaining window is padded with spaces. A true marquee wraps around so the text scrolls continuously. Something likebuf[i] = bytes[(start+i) % uint(len(bytes))]would fix this. -
countincrements on every render call, not on a timer. Since mpb re-renders at ~10fps by default, the scroll speed is tied to the render rate. This is probably fine but worth documenting. -
Example
go.modpins mpb v8.3.0 — should use areplacedirective pointing to../..like the other examples do, so it builds against the local checkout. -
The example uses deprecated
rand.New(rand.NewSource(...))— minor, but the other examples in the repo use the same pattern so this is consistent at least.
The core Marquee function is clean. With the UTF-8 and wrap-around fixes this would be a welcome addition to the decorator library.
|
I'm ok with updated PR. |
Add Marquee decorator that scrolls text from right to
left, it is useful when displaying long messages. The codes are not carefully written, modifications are welcomed.