widget.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2018 visualfc. All rights reserved.
  2. package tk
  3. import (
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. )
  8. type Widget interface {
  9. Id() string
  10. Info() *WidgetInfo
  11. Type() WidgetType
  12. TypeName() string
  13. Parent() Widget
  14. Children() []Widget
  15. IsValid() bool
  16. Destroy() error
  17. DestroyChildren() error
  18. // attribute
  19. NativeAttribute(key string) (value string)
  20. SetNativeAttribute(key string, value string) error
  21. SetAttributes(attributes ...*WidgetAttr) error
  22. // event
  23. BindEvent(event string, fn func(*Event)) error
  24. BindKeyEvent(fn func(e *KeyEvent)) error
  25. BindKeyEventEx(fnPress func(e *KeyEvent), fnRelease func(e *KeyEvent)) error
  26. BindInfo() []string
  27. ClearBind(event string) error
  28. // grab
  29. SetGrab() error
  30. ReleaseGrab() error
  31. IsGrab() bool
  32. // focus
  33. SetFocus() error
  34. IsFocus() bool
  35. Lower(below Widget) error
  36. Raise(above Widget) error
  37. }
  38. var (
  39. globalWidgetMap = make(map[string]Widget)
  40. )
  41. func IsNilInterface(w Widget) bool {
  42. if w == nil {
  43. return true
  44. }
  45. return reflect.ValueOf(w).IsNil()
  46. }
  47. func RegisterWidget(w Widget) {
  48. if IsNilInterface(w) {
  49. return
  50. }
  51. globalWidgetMap[w.Id()] = w
  52. }
  53. func FindWidget(id string) Widget {
  54. return globalWidgetMap[id]
  55. }
  56. func LookupWidget(id string) (w Widget, ok bool) {
  57. w, ok = globalWidgetMap[id]
  58. return
  59. }
  60. func ParentOfWidget(w Widget) Widget {
  61. if IsNilInterface(w) {
  62. return nil
  63. }
  64. id := w.Id()
  65. if id == "." {
  66. return nil
  67. }
  68. pos := strings.LastIndex(id, ".")
  69. if pos == -1 {
  70. return nil
  71. } else if pos == 0 {
  72. return rootWindow
  73. }
  74. return globalWidgetMap[id[:pos]]
  75. }
  76. func ChildrenOfWidget(w Widget) (list []Widget) {
  77. if IsNilInterface(w) {
  78. return nil
  79. }
  80. id := w.Id()
  81. if id == "." {
  82. for k, v := range globalWidgetMap {
  83. if strings.HasPrefix(k, id) {
  84. if k == "." {
  85. continue
  86. } else if strings.Index(k[1:], ".") >= 0 {
  87. continue
  88. }
  89. list = append(list, v)
  90. }
  91. }
  92. } else {
  93. id = id + "."
  94. offset := len(id)
  95. for k, v := range globalWidgetMap {
  96. if strings.HasPrefix(k, id) {
  97. if strings.Index(k[offset:], ".") >= 0 {
  98. continue
  99. }
  100. list = append(list, v)
  101. }
  102. }
  103. }
  104. return
  105. }
  106. func removeWidget(id string) {
  107. if id == "." {
  108. globalWidgetMap = make(map[string]Widget)
  109. } else {
  110. delete(globalWidgetMap, id)
  111. id = id + "."
  112. var list []string
  113. for k, _ := range globalWidgetMap {
  114. if strings.HasPrefix(k, id) {
  115. list = append(list, k)
  116. }
  117. }
  118. for _, k := range list {
  119. delete(globalWidgetMap, k)
  120. }
  121. }
  122. }
  123. func IsValidWidget(w Widget) bool {
  124. if IsNilInterface(w) {
  125. return false
  126. }
  127. _, ok := globalWidgetMap[w.Id()]
  128. return ok
  129. }
  130. func DestroyWidget(w Widget) error {
  131. if !IsValidWidget(w) {
  132. return ErrInvalid
  133. }
  134. id := w.Id()
  135. eval(fmt.Sprintf("destroy %v", id))
  136. removeWidget(id)
  137. return nil
  138. }
  139. func dumpWidgetHelp(w Widget, offset string, space string, ar *[]string) {
  140. s := fmt.Sprintf("%v%v", space, w)
  141. *ar = append(*ar, s)
  142. for _, child := range w.Children() {
  143. dumpWidgetHelp(child, offset, space+offset, ar)
  144. }
  145. }
  146. func DumpWidget(w Widget) string {
  147. return DumpWidgetEx(w, "\t")
  148. }
  149. func DumpWidgetEx(w Widget, offset string) string {
  150. var ar []string
  151. dumpWidgetHelp(w, offset, "", &ar)
  152. return strings.Join(ar, "\n")
  153. }