123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- package door
- import (
- "log"
- "strings"
- "unicode"
- )
- /*
- door.Line - Display a line of text
- Example:
- var basicLine door.Line = {Text: "Welcome",
- DefaultColor: door.Color("BRIGHT YELLOW"),
- }
- d.Write(basicLine.Output() + door.Reset + door.CRNL)
- This outputs Welcome in Bright/Bold Yellow.
- Example Render:
- var renderAlphaDigit ColorRender = func(text string) string {
- var r door.Render{Text: text}
- var alpha string = door.ColorText("BOLD YELLOW")
- var digit string = door.ColorText("BOLD GREEN")
- var other string = door.Reset
- for _, letter := range text {
- if unicode.IsAlpha(letter) {
- r.Append(alpha, 1)
- } else {
- if unicode.IsDigit(letter) {
- r.Append(digit, 1)
- } else {
- r.Append(other, 1)
- }
- }
- }
- return r.Result
- }
- var renderLine door.Line = {Text: "Render - 12345",
- RenderF: renderAlphaDigit,
- }
- d.Write(renderLine.Output() + door.Reset + door.CRNL)
- This outputs "Render" in Yellow, "12345" in Green, and " - " in White.
- Example Update:
- var updateTime() string {
- var now time.Time = time.Now()
- var result string = now.Format("3:04:05 PM")
- return result
- }
- var timeLine door.Line = {Text: updateTime(),
- UpdateF: updateTime,
- }
- d.Write(timeLine.Output() + door.CRNL)
- time.Sleep(time.Second)
- // Check timeLine for update
- if timeLine.Update() {
- // Yes, there's an update to the time, output it.
- d.Write(timeLine.Output() + door.CRNL)
- }
- if timeLine.Update() {
- // This isn't called. There were no changes.
- d.Write(timeLine.Output() + door.CRNL)
- }
- This outputs the Current time in 12 hour format. It pauses for a second,
- and outputs the new time.
- */
- /*
- Line of text to display.
- */
- type Line struct {
- Text string // Text to be displayed
- DefaultColor string // Default Color to use
- RenderF ColorRender // Render function (displays string with colors)
- UpdateF Updater // Update function updates the text
- Width int // Line length
- }
- /*
- Line Update - This calls the UpdateF if present.
- Returns true if the line has been updated, and there's an Update function.
- */
- func (l *Line) Update() bool {
- if l.UpdateF == nil {
- return false
- }
- var NewText string = l.UpdateF()
- l.LineLength(&NewText)
- if NewText != l.Text {
- l.Text = NewText
- return true
- }
- return false
- }
- // If a line Width has been set, make sure we match it.
- func (l *Line) LineLength(text *string) {
- if l.Width == 0 {
- return
- }
- var length int = StringLen(*text)
- /*
- if Unicode {
- length = len([]rune(*text))
- } else {
- length = len([]byte(*text))
- }
- */
- if length > l.Width {
- log.Printf("ERROR: Line Width %d: Have %d\n", l.Width, length)
- } else {
- *text += strings.Repeat(" ", l.Width-length)
- }
- }
- /*
- Line Output - returns a string with ANSI Color codes.
- If there is no RenderF, we use the DefaultColor. Otherwise we pass the text
- to RenderF and return what it returns.
- */
- func (l *Line) Output() string {
- if l.UpdateF == nil {
- l.LineLength(&l.Text)
- }
- if l.RenderF == nil {
- return l.DefaultColor + l.Text
- } else {
- return l.RenderF(l.Text)
- }
- }
- /*
- door.Render - Helper for Line RenderF (Render Function)
- Example:
- // RenderStatus - KEY_COLOR[key] COLON_COLOR[:] VALUE_COLOR[value]
- func RenderStatus(text string) string {
- var r door.Render = Render{Line: text}
- var bool inValue = false
- var key string = door.ColorText("BLUE")
- var colon string = door.ColorText("BRIGHT WHITE")
- var value string = door.ColorText("MAGENTA")
- for _, letter := range text {
- if letter == ':' {
- r.Append(colon, 1)
- inValue = true
- } else {
- if inValue {
- r.Append(value, 1)
- } else {
- r.Append(key, 1)
- }
- }
- }
- return r.Result
- }
- */
- type Render struct {
- Line string // Original Text
- Result string // Output Result
- Pos int // Current Position
- LastColor string // LastColor code sent
- }
- /*
- Render.Append - Output len number of characters in the color.
- This uses Render.LastColor to tell if we've already sent that color before.
- */
- func (r *Render) Append(color string, len int) {
- if color != r.LastColor {
- r.LastColor = color
- r.Result += color
- }
- if Unicode {
- // Treat unicode as []rune.
- r.Result += string([]rune(r.Line)[r.Pos : r.Pos+len])
- } else {
- r.Result += r.Line[r.Pos : r.Pos+len]
- }
- r.Pos += len
- }
- // RenderBlueYellow - Uppercase is Bold Blue, everything else is Yellow.
- // This is an example of using the door.Render routines.
- func RenderBlueYellowOld(text string) string {
- var r Render = Render{Line: text}
- var blue string = ColorText("BOLD BLUE")
- var yellow string = ColorText("BOLD YELLOW")
- for _, letter := range text {
- if unicode.IsUpper(letter) {
- r.Append(blue, 1)
- } else {
- r.Append(yellow, 1)
- }
- }
- return r.Result
- }
- /*
- var RenderPool = sync.Pool{
- New: func() any {
- return new(strings.Builder)
- },
- }
- */
- // Render is the old way of doing things...
- // Using strings.Builder ...
- func RenderBlueYellow(text string) string {
- var output strings.Builder
- // var output = RenderPool.Get().(*strings.Builder)
- // output.Reset()
- var blue string = ColorText("BOLD BLUE")
- var yellow string = ColorText("BOLD YELLOW")
- var last *string
- for _, letter := range text {
- if unicode.IsUpper(letter) {
- if last != &blue {
- output.WriteString(blue)
- last = &blue
- }
- } else {
- if last != &yellow {
- output.WriteString(yellow)
- last = &yellow
- }
- }
- output.WriteRune(letter)
- }
- // var result = output.String()
- // RenderPool.Put(output)
- // return result
- return output.String()
- }
|