line.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package door
  2. import (
  3. "unicode"
  4. )
  5. /*
  6. door.Line - Display a line of text
  7. Example:
  8. var basicLine door.Line = {Text: "Welcome",
  9. DefaultColor: door.Color("BRIGHT YELLOW"),
  10. }
  11. d.Write(basicLine.Output() + door.Reset + door.CRNL)
  12. This outputs Welcome in Bright/Bold Yellow.
  13. Example Render:
  14. var renderAlphaDigit func(string) string = func(text string) string {
  15. var r door.Render{Text: text}
  16. var alpha string = door.ColorText("BOLD YELLOW")
  17. var digit string = door.ColorText("BOLD GREEN")
  18. var other string = door.Reset
  19. for _, letter := range text {
  20. if unicode.IsAlpha(letter) {
  21. r.Append(alpha, 1)
  22. } else {
  23. if unicode.IsDigit(letter) {
  24. r.Append(digit, 1)
  25. } else {
  26. r.Append(other, 1)
  27. }
  28. }
  29. }
  30. return r.Result
  31. }
  32. var renderLine door.Line = {Text: "Render - 12345",
  33. RenderF: renderAlphaDigit,
  34. }
  35. d.Write(renderLine.Output() + door.Reset + door.CRNL)
  36. This outputs "Render" in Yellow, "12345" in Green, and " - " in White.
  37. Example Update:
  38. var updateTime() string {
  39. var now time.Time = time.Now()
  40. var result string = now.Format("3:04:05 PM")
  41. return result
  42. }
  43. var timeLine door.Line = {Text: updateTime(),
  44. UpdateF: updateTime,
  45. }
  46. d.Write(timeLine.Output() + door.CRNL)
  47. time.Sleep(time.Second)
  48. // Check timeLine for update
  49. if timeLine.Update() {
  50. // Yes, there's an update to the time, output it.
  51. d.Write(timeLine.Output() + door.CRNL)
  52. }
  53. if timeLine.Update() {
  54. // This isn't called. There were no changes.
  55. d.Write(timeLine.Output() + door.CRNL)
  56. }
  57. This outputs the Current time in 12 hour format. It pauses for a second,
  58. and outputs the new time.
  59. */
  60. type Line struct {
  61. Text string // Text to be displayed
  62. DefaultColor string // Default Color to use
  63. RenderF func(string) string // Render function (displays string with colors)
  64. UpdateF func() string // Update function updates the text
  65. }
  66. /*
  67. Line Update - This calls the UpdateF if present.
  68. Returns true if the line has been updated, and there's an Update function.
  69. */
  70. func (l *Line) Update() bool {
  71. if l.UpdateF == nil {
  72. return false
  73. }
  74. var NewText string = l.UpdateF()
  75. if NewText != l.Text {
  76. l.Text = NewText
  77. return true
  78. }
  79. return false
  80. }
  81. /*
  82. Line Output - returns a string with ANSI Color codes.
  83. If there is no RenderF, we use the DefaultColor. Otherwise we pass the text
  84. to RenderF and return what it returns.
  85. */
  86. func (l *Line) Output() string {
  87. if l.RenderF == nil {
  88. return l.DefaultColor + l.Text
  89. } else {
  90. return l.RenderF(l.Text)
  91. }
  92. }
  93. /*
  94. door.Render - Helper for Line RenderF (Render Function)
  95. Example:
  96. // RenderStatus - KEY_COLOR[key] COLON_COLOR[:] VALUE_COLOR[value]
  97. func RenderStatus(text string) string {
  98. var r door.Render = Render{Line: text}
  99. var bool inValue = false
  100. var key string = door.ColorText("BLUE")
  101. var colon string = door.ColorText("BRIGHT WHITE")
  102. var value string = door.ColorText("MAGENTA")
  103. for _, letter := range text {
  104. if letter == ':' {
  105. r.Append(colon, 1)
  106. inValue = true
  107. } else {
  108. if inValue {
  109. r.Append(value, 1)
  110. } else {
  111. r.Append(key, 1)
  112. }
  113. }
  114. }
  115. return r.Result
  116. }
  117. */
  118. type Render struct {
  119. Line string // Original Text
  120. Result string // Output Result
  121. Pos int // Current Position
  122. LastColor string // LastColor code sent
  123. }
  124. /*
  125. Render.Append - Output len number of characters in the color.
  126. This uses Render.LastColor to tell if we've already sent that color before.
  127. */
  128. func (r *Render) Append(color string, len int) {
  129. if color != r.LastColor {
  130. r.LastColor = color
  131. r.Result += color
  132. }
  133. if Unicode {
  134. // Treat unicode as []rune.
  135. r.Result += string([]rune(r.Line)[r.Pos : r.Pos+len])
  136. } else {
  137. r.Result += r.Line[r.Pos : r.Pos+len]
  138. }
  139. r.Pos += len
  140. }
  141. // RenderBlueYellow - Uppercase is Bold Blue, everything else is Yellow.
  142. // This is an example of using the door.Render routines.
  143. func RenderBlueYellow(text string) string {
  144. var r Render = Render{Line: text}
  145. var blue string = ColorText("BOLD BLUE")
  146. var yellow string = ColorText("BOLD YELLOW")
  147. for _, letter := range text {
  148. if unicode.IsUpper(letter) {
  149. r.Append(blue, 1)
  150. } else {
  151. r.Append(yellow, 1)
  152. }
  153. }
  154. return r.Result
  155. }