My mirror of the Barnard terminal client for Mumble.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package uiterm
  2. import (
  3. "errors"
  4. "sync/atomic"
  5. "github.com/nsf/termbox-go"
  6. )
  7. type KeyListener func(ui *Ui, key Key)
  8. type UiManager interface {
  9. OnUiInitialize(ui *Ui)
  10. OnUiResize(ui *Ui, width, height int)
  11. }
  12. type Ui struct {
  13. Fg, Bg Attribute
  14. close chan bool
  15. manager UiManager
  16. drawCount int32
  17. elements map[string]*uiElement
  18. activeElement *uiElement
  19. keyListeners map[Key][]KeyListener
  20. }
  21. type uiElement struct {
  22. Name string
  23. X0, Y0, X1, Y1 int
  24. View View
  25. }
  26. func New(manager UiManager) *Ui {
  27. ui := &Ui{
  28. close: make(chan bool, 10),
  29. elements: make(map[string]*uiElement),
  30. manager: manager,
  31. keyListeners: make(map[Key][]KeyListener),
  32. }
  33. return ui
  34. }
  35. func (ui *Ui) Close() {
  36. if termbox.IsInit {
  37. ui.close <- true
  38. }
  39. }
  40. func (ui *Ui) Refresh() {
  41. if termbox.IsInit {
  42. ui.beginDraw()
  43. defer ui.endDraw()
  44. termbox.Clear(termbox.Attribute(ui.Fg), termbox.Attribute(ui.Bg))
  45. termbox.HideCursor()
  46. for _, element := range ui.elements {
  47. element.View.uiDraw()
  48. }
  49. }
  50. }
  51. func (ui *Ui) beginDraw() {
  52. atomic.AddInt32(&ui.drawCount, 1)
  53. }
  54. func (ui *Ui) endDraw() {
  55. if count := atomic.AddInt32(&ui.drawCount, -1); count == 0 {
  56. termbox.Flush()
  57. }
  58. }
  59. func (ui *Ui) Active() string {
  60. return ui.activeElement.Name
  61. }
  62. func (ui *Ui) SetActive(name string) {
  63. element, _ := ui.elements[name]
  64. if ui.activeElement != nil {
  65. ui.activeElement.View.uiSetActive(false)
  66. }
  67. ui.activeElement = element
  68. if element != nil {
  69. element.View.uiSetActive(true)
  70. }
  71. ui.Refresh()
  72. }
  73. func (ui *Ui) Run() error {
  74. if termbox.IsInit {
  75. return nil
  76. }
  77. if err := termbox.Init(); err != nil {
  78. return nil
  79. }
  80. defer termbox.Close()
  81. termbox.SetInputMode(termbox.InputAlt)
  82. events := make(chan termbox.Event)
  83. go func() {
  84. for {
  85. events <- termbox.PollEvent()
  86. }
  87. }()
  88. ui.manager.OnUiInitialize(ui)
  89. width, height := termbox.Size()
  90. ui.manager.OnUiResize(ui, width, height)
  91. ui.Refresh()
  92. for {
  93. select {
  94. case <-ui.close:
  95. return nil
  96. case event := <-events:
  97. switch event.Type {
  98. case termbox.EventResize:
  99. ui.manager.OnUiResize(ui, event.Width, event.Height)
  100. ui.Refresh()
  101. case termbox.EventKey:
  102. if event.Ch != 0 {
  103. ui.onCharacterEvent(event.Ch)
  104. } else {
  105. ui.onKeyEvent(Modifier(event.Mod), Key(event.Key))
  106. }
  107. }
  108. }
  109. }
  110. }
  111. func (ui *Ui) onCharacterEvent(ch rune) {
  112. if ui.activeElement != nil {
  113. ui.activeElement.View.uiCharacterEvent(ch)
  114. }
  115. }
  116. func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
  117. if ui.keyListeners[key] != nil {
  118. for _, listener := range ui.keyListeners[key] {
  119. listener(ui, key)
  120. }
  121. }
  122. if ui.activeElement != nil {
  123. ui.activeElement.View.uiKeyEvent(mod, key)
  124. }
  125. }
  126. func (ui *Ui) Add(name string, view View) error {
  127. if _, ok := ui.elements[name]; ok {
  128. return errors.New("view already exists")
  129. }
  130. ui.elements[name] = &uiElement{
  131. Name: name,
  132. View: view,
  133. }
  134. view.uiInitialize(ui)
  135. return nil
  136. }
  137. func (ui *Ui) SetBounds(name string, x0, y0, x1, y1 int) error {
  138. element, ok := ui.elements[name]
  139. if !ok {
  140. return errors.New("view does not exist")
  141. }
  142. element.X0, element.Y0, element.X1, element.Y1 = x0, y0, x1, y1
  143. element.View.uiSetBounds(x0, y0, x1, y1)
  144. return nil
  145. }
  146. func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {
  147. ui.keyListeners[key] = append(ui.keyListeners[key], listener)
  148. }