tk.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright 2018 visualfc. All rights reserved.
  2. package tk
  3. import (
  4. "fmt"
  5. "log"
  6. "runtime"
  7. "github.com/visualfc/atk/tk/interp"
  8. )
  9. var (
  10. tkHasInit bool
  11. tkWindowInitAutoHide bool
  12. mainInterp *interp.Interp
  13. rootWindow *Window
  14. fnErrorHandle func(error) = func(err error) {
  15. log.Println(err)
  16. }
  17. )
  18. func Init() error {
  19. return InitEx(true, "", "")
  20. }
  21. func InitEx(tk_window_init_hide bool, tcl_library string, tk_library string) (err error) {
  22. mainInterp, err = interp.NewInterp()
  23. if err != nil {
  24. dumpError(err)
  25. return err
  26. }
  27. err = mainInterp.InitTcl(tcl_library)
  28. if err != nil {
  29. dumpError(err)
  30. return err
  31. }
  32. err = mainInterp.InitTk(tk_library)
  33. if err != nil {
  34. dumpError(err)
  35. return err
  36. }
  37. tkWindowInitAutoHide = tk_window_init_hide
  38. //hide console for macOS bundle
  39. mainInterp.Eval("if {[info commands console] == \"console\"} {console hide}")
  40. for _, fn := range init_func_list {
  41. fn()
  42. }
  43. rootWindow = &Window{}
  44. rootWindow.Attach(".")
  45. if tkWindowInitAutoHide {
  46. rootWindow.Hide()
  47. }
  48. //hide wish menu on macos
  49. rootWindow.SetMenu(NewMenu(nil))
  50. tkHasInit = true
  51. return nil
  52. }
  53. var (
  54. init_func_list []func()
  55. )
  56. func registerInit(fn func()) {
  57. init_func_list = append(init_func_list, fn)
  58. }
  59. func SetErrorHandle(fn func(error)) {
  60. fnErrorHandle = fn
  61. }
  62. func MainInterp() *interp.Interp {
  63. return mainInterp
  64. }
  65. func TclVersion() (ver string) {
  66. return mainInterp.TclVersion()
  67. }
  68. func TkVersion() (ver string) {
  69. return mainInterp.TkVersion()
  70. }
  71. func TclLibary() (path string) {
  72. path, _ = evalAsString("set tcl_library")
  73. return
  74. }
  75. func TkLibrary() (path string) {
  76. path, _ = evalAsString("set tk_library")
  77. return
  78. }
  79. func init() {
  80. runtime.LockOSThread()
  81. }
  82. func MainLoop(fn func()) error {
  83. if !tkHasInit {
  84. err := Init()
  85. if err != nil {
  86. dumpError(err)
  87. return err
  88. }
  89. }
  90. interp.MainLoop(fn)
  91. return nil
  92. }
  93. func Async(fn func()) {
  94. interp.Async(fn)
  95. }
  96. func Update() {
  97. eval("update")
  98. }
  99. func Quit() {
  100. Async(func() {
  101. DestroyWidget(rootWindow)
  102. })
  103. }
  104. func eval(script string) error {
  105. err := mainInterp.Eval(script)
  106. if err != nil {
  107. dumpError(fmt.Errorf("script: %q, error: %q", script, err))
  108. }
  109. return err
  110. }
  111. func evalEx(script string, dump bool) error {
  112. err := mainInterp.Eval(script)
  113. if dump && err != nil {
  114. dumpError(err)
  115. }
  116. return err
  117. }
  118. func evalAsString(script string) (string, error) {
  119. r, err := mainInterp.EvalAsString(script)
  120. if err != nil {
  121. dumpError(err)
  122. }
  123. return r, err
  124. }
  125. func evalAsStringEx(script string, dump bool) (string, error) {
  126. r, err := mainInterp.EvalAsString(script)
  127. if dump && err != nil {
  128. dumpError(err)
  129. }
  130. return r, err
  131. }
  132. func evalAsInt(script string) (int, error) {
  133. r, err := mainInterp.EvalAsInt(script)
  134. if err != nil {
  135. dumpError(err)
  136. }
  137. return r, err
  138. }
  139. func evalAsIntEx(script string, dump bool) (int, error) {
  140. r, err := mainInterp.EvalAsInt(script)
  141. if dump && err != nil {
  142. dumpError(err)
  143. }
  144. return r, err
  145. }
  146. func evalAsUint(script string) (uint, error) {
  147. r, err := mainInterp.EvalAsUint(script)
  148. if err != nil {
  149. dumpError(err)
  150. }
  151. return r, err
  152. }
  153. func evalAsUintEx(script string, dump bool) (uint, error) {
  154. r, err := mainInterp.EvalAsUint(script)
  155. if dump && err != nil {
  156. dumpError(err)
  157. }
  158. return r, err
  159. }
  160. func evalAsFloat64(script string) (float64, error) {
  161. r, err := mainInterp.EvalAsFloat64(script)
  162. if err != nil {
  163. dumpError(err)
  164. }
  165. return r, err
  166. }
  167. func evalAsFloat64Ex(script string, dump bool) (float64, error) {
  168. r, err := mainInterp.EvalAsFloat64(script)
  169. if dump && err != nil {
  170. dumpError(err)
  171. }
  172. return r, err
  173. }
  174. func evalAsBool(script string) (bool, error) {
  175. r, err := mainInterp.EvalAsBool(script)
  176. if err != nil {
  177. dumpError(err)
  178. }
  179. return r, err
  180. }
  181. func evalAsBoolEx(script string, dump bool) (bool, error) {
  182. r, err := mainInterp.EvalAsBool(script)
  183. if dump && err != nil {
  184. dumpError(err)
  185. }
  186. return r, err
  187. }
  188. func evalAsStringList(script string) ([]string, error) {
  189. r, err := mainInterp.EvalAsStringList(script)
  190. if err != nil {
  191. dumpError(err)
  192. }
  193. return r, err
  194. }
  195. func evalAsStringListEx(script string, dump bool) ([]string, error) {
  196. r, err := mainInterp.EvalAsStringList(script)
  197. if dump && err != nil {
  198. dumpError(err)
  199. }
  200. return r, err
  201. }
  202. func evalAsIntList(script string) ([]int, error) {
  203. r, err := mainInterp.EvalAsIntList(script)
  204. if err != nil {
  205. dumpError(err)
  206. }
  207. return r, err
  208. }
  209. func evalAsIntListEx(script string, dump bool) ([]int, error) {
  210. r, err := mainInterp.EvalAsIntList(script)
  211. if dump && err != nil {
  212. dumpError(err)
  213. }
  214. return r, err
  215. }
  216. func dumpError(err error) {
  217. if fnErrorHandle != nil {
  218. fnErrorHandle(fmt.Errorf("%v", err))
  219. }
  220. }
  221. func setObjText(obj string, text string) {
  222. mainInterp.SetStringVar(obj, text, false)
  223. }
  224. func setObjTextList(obj string, list []string) {
  225. mainInterp.SetStringList(obj, list, false)
  226. }