My mirror of the Barnard terminal client for Mumble.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package uiterm
  2. import (
  3. "strings"
  4. "github.com/nsf/termbox-go"
  5. )
  6. type TreeItem interface {
  7. TreeItemStyle(fg, bg Attribute, active bool) (Attribute, Attribute)
  8. String() string
  9. }
  10. type renderedTreeItem struct {
  11. //String string
  12. Level int
  13. Item TreeItem
  14. }
  15. type Tree struct {
  16. Fg Attribute
  17. Bg Attribute
  18. Generator func(item TreeItem) []TreeItem
  19. Listener func(ui *Ui, tree *Tree, item TreeItem)
  20. lines []renderedTreeItem
  21. activeLine int
  22. ui *Ui
  23. active bool
  24. x0, y0, x1, y1 int
  25. }
  26. func bounded(i, lower, upper int) int {
  27. if i < lower {
  28. return lower
  29. }
  30. if i > upper {
  31. return upper
  32. }
  33. return i
  34. }
  35. func (t *Tree) uiInitialize(ui *Ui) {
  36. t.ui = ui
  37. }
  38. func (t *Tree) uiSetActive(active bool) {
  39. t.active = active
  40. t.uiDraw()
  41. }
  42. func (t *Tree) uiSetBounds(x0, y0, x1, y1 int) {
  43. t.x0 = x0
  44. t.y0 = y0
  45. t.x1 = x1
  46. t.y1 = y1
  47. t.uiDraw()
  48. }
  49. func (t *Tree) Rebuild() {
  50. if t.Generator == nil {
  51. t.lines = []renderedTreeItem{}
  52. return
  53. }
  54. lines := []renderedTreeItem{}
  55. for _, item := range t.Generator(nil) {
  56. children := t.rebuild_rec(item, 0)
  57. if children != nil {
  58. lines = append(lines, children...)
  59. }
  60. }
  61. t.lines = lines
  62. t.activeLine = bounded(t.activeLine, 0, len(t.lines)-1)
  63. t.uiDraw()
  64. }
  65. func (t *Tree) rebuild_rec(parent TreeItem, level int) []renderedTreeItem {
  66. if parent == nil {
  67. return nil
  68. }
  69. lines := []renderedTreeItem{
  70. renderedTreeItem{
  71. Level: level,
  72. Item: parent,
  73. },
  74. }
  75. for _, item := range t.Generator(parent) {
  76. children := t.rebuild_rec(item, level+1)
  77. if children != nil {
  78. lines = append(lines, children...)
  79. }
  80. }
  81. return lines
  82. }
  83. func (t *Tree) uiDraw() {
  84. t.ui.beginDraw()
  85. defer t.ui.endDraw()
  86. if t.lines == nil {
  87. t.Rebuild()
  88. }
  89. line := 0
  90. for y := t.y0; y < t.y1; y++ {
  91. var reader *strings.Reader
  92. var item TreeItem
  93. level := 0
  94. if line < len(t.lines) {
  95. item = t.lines[line].Item
  96. level = t.lines[line].Level
  97. reader = strings.NewReader(item.String())
  98. }
  99. for x := t.x0; x < t.x1; x++ {
  100. var chr rune = ' '
  101. fg := t.Fg
  102. bg := t.Bg
  103. dx := x - t.x0
  104. dy := y - t.y0
  105. if reader != nil && level*2 <= dx {
  106. if ch, _, err := reader.ReadRune(); err == nil {
  107. chr = ch
  108. fg, bg = item.TreeItemStyle(fg, bg, t.active && t.activeLine == dy)
  109. }
  110. }
  111. termbox.SetCell(x, y, chr, termbox.Attribute(fg), termbox.Attribute(bg))
  112. }
  113. line++
  114. }
  115. }
  116. func (t *Tree) uiKeyEvent(mod Modifier, key Key) {
  117. switch key {
  118. case KeyArrowUp:
  119. t.activeLine = bounded(t.activeLine-1, 0, len(t.lines)-1)
  120. case KeyArrowDown:
  121. t.activeLine = bounded(t.activeLine+1, 0, len(t.lines)-1)
  122. case KeyEnter:
  123. if t.Listener != nil && t.activeLine >= 0 && t.activeLine < len(t.lines) {
  124. t.Listener(t.ui, t, t.lines[t.activeLine].Item)
  125. }
  126. }
  127. t.uiDraw()
  128. }
  129. func (t *Tree) uiCharacterEvent(ch rune) {
  130. }