My mirror of the Barnard terminal client for Mumble.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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