My mirror of the Barnard terminal client for Mumble.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

157 wiersze
2.8 KiB

  1. package uiterm
  2. import (
  3. "strings"
  4. "github.com/nsf/termbox-go"
  5. )
  6. type Textview struct {
  7. Lines []string
  8. CurrentLine int
  9. Fg, Bg Attribute
  10. parsedLines []string
  11. ui *Ui
  12. x0, y0, x1, y1 int
  13. }
  14. func (t *Textview) uiInitialize(ui *Ui) {
  15. t.ui = ui
  16. }
  17. func (t *Textview) uiSetActive(active bool) {
  18. }
  19. func (t *Textview) uiSetBounds(x0, y0, x1, y1 int) {
  20. t.x0 = x0
  21. t.y0 = y0
  22. t.x1 = x1
  23. t.y1 = y1
  24. t.updateParsedLines()
  25. t.uiDraw()
  26. }
  27. func (t *Textview) ScrollUp() {
  28. if newLine := t.CurrentLine + 1; newLine < len(t.parsedLines) {
  29. t.CurrentLine = newLine
  30. }
  31. t.uiDraw()
  32. }
  33. func (t *Textview) ScrollDown() {
  34. if newLine := t.CurrentLine - 1; newLine >= 0 {
  35. t.CurrentLine = newLine
  36. }
  37. t.uiDraw()
  38. }
  39. func (t *Textview) ScrollTop() {
  40. if newLine := len(t.parsedLines) - 1; newLine > 0 {
  41. t.CurrentLine = newLine
  42. } else {
  43. t.CurrentLine = 0
  44. }
  45. t.uiDraw()
  46. }
  47. func (t *Textview) ScrollBottom() {
  48. t.CurrentLine = 0
  49. t.uiDraw()
  50. }
  51. func (t *Textview) updateParsedLines() {
  52. width := t.x1 - t.x0 - 3
  53. if t.Lines == nil || width <= 0 {
  54. t.parsedLines = nil
  55. return
  56. }
  57. parsed := make([]string, 0, len(t.Lines))
  58. for _, line := range t.Lines {
  59. current := ""
  60. chars := 0
  61. reader := strings.NewReader(line)
  62. for {
  63. if chars >= width {
  64. parsed = append(parsed, current)
  65. chars = 0
  66. current = ""
  67. }
  68. if reader.Len() <= 0 {
  69. if chars > 0 {
  70. parsed = append(parsed, current)
  71. }
  72. break
  73. }
  74. if ch, _, err := reader.ReadRune(); err == nil {
  75. current = current + string(ch)
  76. chars++
  77. }
  78. }
  79. }
  80. t.parsedLines = parsed
  81. }
  82. func (t *Textview) AddLine(line string) {
  83. t.Lines = append(t.Lines, line)
  84. t.updateParsedLines()
  85. t.uiDraw()
  86. }
  87. func (t *Textview) Clear() {
  88. t.Lines = nil
  89. t.CurrentLine = 0
  90. t.parsedLines = nil
  91. t.uiDraw()
  92. }
  93. func (t *Textview) uiDraw() {
  94. t.ui.beginDraw()
  95. defer t.ui.endDraw()
  96. var reader *strings.Reader
  97. line := len(t.parsedLines) - 1 - t.CurrentLine
  98. if line < 0 {
  99. line = 0
  100. }
  101. totalLines := len(t.parsedLines)
  102. if totalLines == 0 {
  103. totalLines = 1
  104. }
  105. currentScrollLine := t.y1 - 1 - int((float32(t.CurrentLine)/float32(totalLines))*float32(t.y1-t.y0))
  106. for y := t.y1 - 1; y >= t.y0; y-- {
  107. if t.parsedLines != nil && line >= 0 {
  108. reader = strings.NewReader(t.parsedLines[line])
  109. } else {
  110. reader = nil
  111. }
  112. for x := t.x0; x < t.x1; x++ {
  113. var chr rune = ' '
  114. if x == t.x1-1 { // scrollbar
  115. if y == currentScrollLine {
  116. chr = '█'
  117. } else {
  118. chr = '░'
  119. }
  120. } else if x < t.x1-3 {
  121. if reader != nil {
  122. if ch, _, err := reader.ReadRune(); err == nil {
  123. chr = ch
  124. }
  125. }
  126. }
  127. termbox.SetCell(x, y, chr, termbox.Attribute(t.Fg), termbox.Attribute(t.Bg))
  128. }
  129. line--
  130. }
  131. }
  132. func (t *Textview) uiKeyEvent(mod Modifier, key Key) {
  133. }
  134. func (t *Textview) uiCharacterEvent(chr rune) {
  135. }