My mirror of the Barnard terminal client for Mumble.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 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. }