package widgets import ( "ArinDash/util" "context" "image" "time" "github.com/mum4k/termdash/cell" "github.com/mum4k/termdash/terminal/terminalapi" "github.com/mum4k/termdash/widgetapi" "github.com/mum4k/termdash/widgets/segmentdisplay" ) type RollingSegmentDisplayOptions struct { UpdateText <-chan string } func RollingSegmentDisplay(options RollingSegmentDisplayOptions) RollingSegmentDisplayOptions { widgetOptions["RollingSegmentDisplayOptions"] = createRollingSegmentDisplay return RollingSegmentDisplayOptions{ UpdateText: options.UpdateText, } } func createRollingSegmentDisplay(ctx context.Context, t terminalapi.Terminal, opt interface{}) widgetapi.Widget { options, ok := opt.(RollingSegmentDisplayOptions) if !ok { panic("invalid options type") } segmentDisplayWidget := util.PanicOnErrorWithResult(segmentdisplay.New()) colors := []cell.Color{ cell.ColorNumber(33), cell.ColorRed, cell.ColorYellow, cell.ColorNumber(33), cell.ColorGreen, cell.ColorRed, cell.ColorGreen, cell.ColorRed, } textVal := "ArinDash" step := 0 go util.Periodic(ctx, util.RedrawInterval, func() error { ticker := time.NewTicker(500 * time.Millisecond) defer ticker.Stop() capacity := 0 termSize := t.Size() for { select { case <-ticker.C: if capacity == 0 { capacity = segmentDisplayWidget.Capacity() } if t.Size().Eq(image.Point{}) || !t.Size().Eq(termSize) { termSize = t.Size() capacity = segmentDisplayWidget.Capacity() } state := TextState(textVal, capacity, step) var chunks []*segmentdisplay.TextChunk for i := 0; i < capacity; i++ { if i >= len(state) { break } color := colors[i%len(colors)] chunks = append(chunks, segmentdisplay.NewChunk( string(state[i]), segmentdisplay.WriteCellOpts(cell.FgColor(color)), )) } if len(chunks) == 0 { continue } if err := segmentDisplayWidget.Write(chunks); err != nil { panic(err) } step++ case t := <-options.UpdateText: textVal = t segmentDisplayWidget.Reset() step = 0 case <-ctx.Done(): return nil } } }) return segmentDisplayWidget } func TextState(text string, capacity, step int) []rune { if capacity == 0 { return nil } var state []rune for i := 0; i < capacity; i++ { state = append(state, ' ') } state = append(state, []rune(text)...) step = step % len(state) return append(state[step:], state[:step]...) }