package main import ( "fmt" "strings" "github.com/cqroot/prompt/constants" "github.com/cqroot/prompt/multichoose" ) // Scrolling theme for cqroot/prompt. Allows items to be scrolled through // using the arrow keys. // // choices is a list of strings to display. // cursor is the index of the currently selected item. // isSelected is a function that returns true if the item at the given index func ThemeScroll(choices []string, cursor int, isSelected multichoose.IsSelected) string { s := strings.Builder{} s.WriteString("\n") lenChoices := len(choices) index := cursor limit := 10 start := 0 end := limit // Create a slice of items to display if lenChoices > limit { if index < limit/2 { end = limit } else if index >= limit/2 && index <= lenChoices-limit/2 { start = index - limit/2 end = index + limit/2 index = limit / 2 } else { start = lenChoices - limit end = lenChoices index = limit - (lenChoices - index) } } // Loop through the slice and display each item. // We will determine if the item is selected or not by calling isSelected // with the index of the item, but since we're only displaying a slice of // the items we need to offset the index. for i, choice := range choices[start:end] { // offset represents the index of the item in the original list offset := i + start // Check if the item is the one at the cursor's location isCursor := index == i // Render item according to its state (selected + cursor / selected / normal) if isSelected(offset) { if isCursor { s.WriteString(constants.DefaultSelectedItemStyle.Render(fmt.Sprintf("[x] %s", choice))) } else { s.WriteString(constants.DefaultItemStyle.Render(fmt.Sprintf("[x] %s", choice))) } } else { if isCursor { s.WriteString(constants.DefaultSelectedItemStyle.Render(fmt.Sprintf("[•] %s", choice))) } else { s.WriteString(constants.DefaultItemStyle.Render(fmt.Sprintf("[ ] %s", choice))) } } s.WriteString("\n") } return s.String() }