text.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. // Copyright 2018 visualfc. All rights reserved.
  2. package tk
  3. import (
  4. "fmt"
  5. "strings"
  6. )
  7. // Create and manipulate 'text' hypertext editing widgets
  8. type Text struct {
  9. BaseWidget
  10. xscrollcommand *CommandEx
  11. yscrollcommand *CommandEx
  12. }
  13. func NewText(parent Widget, attributes ...*WidgetAttr) *Text {
  14. theme := checkInitUseTheme(attributes)
  15. iid := makeNamedWidgetId(parent, "atk_text")
  16. info := CreateWidgetInfo(iid, WidgetTypeText, theme, attributes)
  17. if info == nil {
  18. return nil
  19. }
  20. w := &Text{}
  21. w.id = iid
  22. w.info = info
  23. RegisterWidget(w)
  24. return w
  25. }
  26. func (w *Text) Attach(id string) error {
  27. info, err := CheckWidgetInfo(id, WidgetTypeText)
  28. if err != nil {
  29. return err
  30. }
  31. w.id = id
  32. w.info = info
  33. RegisterWidget(w)
  34. return nil
  35. }
  36. func (w *Text) SetBackground(color string) error {
  37. setObjText("atk_tmp_text", color)
  38. return eval(fmt.Sprintf("%v configure -background $atk_tmp_text", w.id))
  39. }
  40. func (w *Text) Background() string {
  41. r, _ := evalAsString(fmt.Sprintf("%v cget -background", w.id))
  42. return r
  43. }
  44. func (w *Text) SetBorderWidth(width int) error {
  45. return eval(fmt.Sprintf("%v configure -borderwidth {%v}", w.id, width))
  46. }
  47. func (w *Text) BorderWidth() int {
  48. r, _ := evalAsInt(fmt.Sprintf("%v cget -borderwidth", w.id))
  49. return r
  50. }
  51. func (w *Text) SetFont(font Font) error {
  52. if font == nil {
  53. return ErrInvalid
  54. }
  55. return eval(fmt.Sprintf("%v configure -font {%v}", w.id, font.Id()))
  56. }
  57. func (w *Text) Font() Font {
  58. r, err := evalAsString(fmt.Sprintf("%v cget -font", w.id))
  59. return parserFontResult(r, err)
  60. }
  61. func (w *Text) SetForeground(color string) error {
  62. setObjText("atk_tmp_text", color)
  63. return eval(fmt.Sprintf("%v configure -foreground $atk_tmp_text", w.id))
  64. }
  65. func (w *Text) Foreground() string {
  66. r, _ := evalAsString(fmt.Sprintf("%v cget -foreground", w.id))
  67. return r
  68. }
  69. func (w *Text) SetHighlightBackground(color string) error {
  70. setObjText("atk_tmp_text", color)
  71. return eval(fmt.Sprintf("%v configure -highlightbackground $atk_tmp_text", w.id))
  72. }
  73. func (w *Text) HighlightBackground() string {
  74. r, _ := evalAsString(fmt.Sprintf("%v cget -highlightbackground", w.id))
  75. return r
  76. }
  77. func (w *Text) SetHighlightColor(color string) error {
  78. setObjText("atk_tmp_text", color)
  79. return eval(fmt.Sprintf("%v configure -highlightcolor $atk_tmp_text", w.id))
  80. }
  81. func (w *Text) HighlightColor() string {
  82. r, _ := evalAsString(fmt.Sprintf("%v cget -highlightcolor", w.id))
  83. return r
  84. }
  85. func (w *Text) SetHighlightthickness(width int) error {
  86. return eval(fmt.Sprintf("%v configure -highlightthickness {%v}", w.id, width))
  87. }
  88. func (w *Text) Highlightthickness() int {
  89. r, _ := evalAsInt(fmt.Sprintf("%v cget -highlightthickness", w.id))
  90. return r
  91. }
  92. func (w *Text) SetInsertBackground(color string) error {
  93. setObjText("atk_tmp_text", color)
  94. return eval(fmt.Sprintf("%v configure -insertbackground $atk_tmp_text", w.id))
  95. }
  96. func (w *Text) InsertBackground() string {
  97. r, _ := evalAsString(fmt.Sprintf("%v cget -insertbackground", w.id))
  98. return r
  99. }
  100. func (w *Text) SetInsertBorderWidth(width int) error {
  101. return eval(fmt.Sprintf("%v configure -insertborderwidth {%v}", w.id, width))
  102. }
  103. func (w *Text) InsertBorderWidth() int {
  104. r, _ := evalAsInt(fmt.Sprintf("%v cget -insertborderwidth", w.id))
  105. return r
  106. }
  107. func (w *Text) SetInsertOffTime(offtime int) error {
  108. return eval(fmt.Sprintf("%v configure -insertofftime {%v}", w.id, offtime))
  109. }
  110. func (w *Text) InsertOffTime() int {
  111. r, _ := evalAsInt(fmt.Sprintf("%v cget -insertofftime", w.id))
  112. return r
  113. }
  114. func (w *Text) SetInsertOnTime(ontime int) error {
  115. return eval(fmt.Sprintf("%v configure -insertontime {%v}", w.id, ontime))
  116. }
  117. func (w *Text) InsertOnTime() int {
  118. r, _ := evalAsInt(fmt.Sprintf("%v cget -insertontime", w.id))
  119. return r
  120. }
  121. func (w *Text) SetInsertWidth(width int) error {
  122. return eval(fmt.Sprintf("%v configure -insertwidth {%v}", w.id, width))
  123. }
  124. func (w *Text) InsertWidth() int {
  125. r, _ := evalAsInt(fmt.Sprintf("%v cget -insertwidth", w.id))
  126. return r
  127. }
  128. func (w *Text) SetPaddingN(padx int, pady int) error {
  129. if w.info.IsTtk {
  130. return eval(fmt.Sprintf("%v configure -padding {%v %v}", w.id, padx, pady))
  131. }
  132. return eval(fmt.Sprintf("%v configure -padx {%v} -pady {%v}", w.id, padx, pady))
  133. }
  134. func (w *Text) PaddingN() (int, int) {
  135. var r string
  136. var err error
  137. if w.info.IsTtk {
  138. r, err = evalAsString(fmt.Sprintf("%v cget -padding", w.id))
  139. } else {
  140. r1, _ := evalAsString(fmt.Sprintf("%v cget -padx", w.id))
  141. r2, _ := evalAsString(fmt.Sprintf("%v cget -pady", w.id))
  142. r = r1 + " " + r2
  143. }
  144. return parserPaddingResult(r, err)
  145. }
  146. func (w *Text) SetPadding(pad Pad) error {
  147. return w.SetPaddingN(pad.X, pad.Y)
  148. }
  149. func (w *Text) Padding() Pad {
  150. x, y := w.PaddingN()
  151. return Pad{x, y}
  152. }
  153. func (w *Text) SetReliefStyle(relief ReliefStyle) error {
  154. return eval(fmt.Sprintf("%v configure -relief {%v}", w.id, relief))
  155. }
  156. func (w *Text) ReliefStyle() ReliefStyle {
  157. r, err := evalAsString(fmt.Sprintf("%v cget -relief", w.id))
  158. return parserReliefStyleResult(r, err)
  159. }
  160. func (w *Text) SetSelectBackground(color string) error {
  161. setObjText("atk_tmp_text", color)
  162. return eval(fmt.Sprintf("%v configure -selectbackground $atk_tmp_text", w.id))
  163. }
  164. func (w *Text) SelectBackground() string {
  165. r, _ := evalAsString(fmt.Sprintf("%v cget -selectbackground", w.id))
  166. return r
  167. }
  168. func (w *Text) SetSelectborderwidth(width int) error {
  169. return eval(fmt.Sprintf("%v configure -selectborderwidth {%v}", w.id, width))
  170. }
  171. func (w *Text) Selectborderwidth() int {
  172. r, _ := evalAsInt(fmt.Sprintf("%v cget -selectborderwidth", w.id))
  173. return r
  174. }
  175. func (w *Text) SetSelectforeground(color string) error {
  176. setObjText("atk_tmp_text", color)
  177. return eval(fmt.Sprintf("%v configure -selectforeground $atk_tmp_text", w.id))
  178. }
  179. func (w *Text) Selectforeground() string {
  180. r, _ := evalAsString(fmt.Sprintf("%v cget -selectforeground", w.id))
  181. return r
  182. }
  183. func (w *Text) SetInactiveSelectBackground(color string) error {
  184. setObjText("atk_tmp_text", color)
  185. return eval(fmt.Sprintf("%v configure -inactiveselectbackground $atk_tmp_text", w.id))
  186. }
  187. func (w *Text) InactiveSelectBackground() string {
  188. r, _ := evalAsString(fmt.Sprintf("%v cget -inactiveselectbackground", w.id))
  189. return r
  190. }
  191. func (w *Text) SetTakeFocus(takefocus bool) error {
  192. return eval(fmt.Sprintf("%v configure -takefocus {%v}", w.id, boolToInt(takefocus)))
  193. }
  194. func (w *Text) IsTakeFocus() bool {
  195. r, _ := evalAsBool(fmt.Sprintf("%v cget -takefocus", w.id))
  196. return r
  197. }
  198. func (w *Text) SetAutoSeparatorsOnUndo(autoseparators bool) error {
  199. return eval(fmt.Sprintf("%v configure -autoseparators {%v}", w.id, boolToInt(autoseparators)))
  200. }
  201. func (w *Text) IsAutoSeparatorsOnUndo() bool {
  202. r, _ := evalAsBool(fmt.Sprintf("%v cget -autoseparators", w.id))
  203. return r
  204. }
  205. func (w *Text) SetBlockCursor(blockcursor bool) error {
  206. return eval(fmt.Sprintf("%v configure -blockcursor {%v}", w.id, boolToInt(blockcursor)))
  207. }
  208. func (w *Text) IsBlockCursor() bool {
  209. r, _ := evalAsBool(fmt.Sprintf("%v cget -blockcursor", w.id))
  210. return r
  211. }
  212. func (w *Text) SetStartLine(startline int) error {
  213. return eval(fmt.Sprintf("%v configure -startline {%v}", w.id, startline))
  214. }
  215. func (w *Text) StartLine() int {
  216. r, _ := evalAsInt(fmt.Sprintf("%v cget -startline", w.id))
  217. return r
  218. }
  219. func (w *Text) SetEndLine(endline int) error {
  220. return eval(fmt.Sprintf("%v configure -endline {%v}", w.id, endline))
  221. }
  222. func (w *Text) EndLine() int {
  223. r, _ := evalAsInt(fmt.Sprintf("%v cget -endline", w.id))
  224. return r
  225. }
  226. func (w *Text) SetWidth(width int) error {
  227. return eval(fmt.Sprintf("%v configure -width {%v}", w.id, width))
  228. }
  229. func (w *Text) Width() int {
  230. r, _ := evalAsInt(fmt.Sprintf("%v cget -width", w.id))
  231. return r
  232. }
  233. func (w *Text) SetHeight(height int) error {
  234. return eval(fmt.Sprintf("%v configure -height {%v}", w.id, height))
  235. }
  236. func (w *Text) Height() int {
  237. r, _ := evalAsInt(fmt.Sprintf("%v cget -height", w.id))
  238. return r
  239. }
  240. func (w *Text) SetInsertUnfocussed(style DisplyCursor) error {
  241. if !mainInterp.SupportTk86() {
  242. return ErrUnsupport
  243. }
  244. return eval(fmt.Sprintf("%v configure -insertunfocussed {%v}", w.id, style))
  245. }
  246. func (w *Text) InsertUnfocussed() DisplyCursor {
  247. if !mainInterp.SupportTk86() {
  248. return DisplyCursorHollow
  249. }
  250. r, err := evalAsString(fmt.Sprintf("%v cget -insertunfocussed", w.id))
  251. return parserDisplyCursorResult(r, err)
  252. }
  253. func (w *Text) SetMaxUndo(maxundo int) error {
  254. return eval(fmt.Sprintf("%v configure -maxundo {%v}", w.id, maxundo))
  255. }
  256. func (w *Text) MaxUndo() int {
  257. r, _ := evalAsInt(fmt.Sprintf("%v cget -maxundo", w.id))
  258. return r
  259. }
  260. func (w *Text) SetLineAboveSpace(spacing int) error {
  261. return eval(fmt.Sprintf("%v configure -spacing1 {%v}", w.id, spacing))
  262. }
  263. func (w *Text) LineAboveSpace() int {
  264. r, _ := evalAsInt(fmt.Sprintf("%v cget -spacing1", w.id))
  265. return r
  266. }
  267. func (w *Text) SetLineWrapSpace(spacing int) error {
  268. return eval(fmt.Sprintf("%v configure -spacing2 {%v}", w.id, spacing))
  269. }
  270. func (w *Text) LineWrapSpace() int {
  271. r, _ := evalAsInt(fmt.Sprintf("%v cget -spacing2", w.id))
  272. return r
  273. }
  274. func (w *Text) SetLineBelowSpace(spacing int) error {
  275. return eval(fmt.Sprintf("%v configure -spacing3 {%v}", w.id, spacing))
  276. }
  277. func (w *Text) LineBelowSpace() int {
  278. r, _ := evalAsInt(fmt.Sprintf("%v cget -spacing3", w.id))
  279. return r
  280. }
  281. func (w *Text) SetLineWrap(wrap LineWrapMode) error {
  282. return eval(fmt.Sprintf("%v configure -wrap {%v}", w.id, wrap))
  283. }
  284. func (w *Text) LineWrap() LineWrapMode {
  285. r, err := evalAsString(fmt.Sprintf("%v cget -wrap", w.id))
  286. return parserLineWrapModeResult(r, err)
  287. }
  288. func (w *Text) SetEnableUndo(undo bool) error {
  289. return eval(fmt.Sprintf("%v configure -undo {%v}", w.id, boolToInt(undo)))
  290. }
  291. func (w *Text) IsEnableUndo() bool {
  292. r, _ := evalAsBool(fmt.Sprintf("%v cget -undo", w.id))
  293. return r
  294. }
  295. func (w *Text) SetReadOnly(b bool) error {
  296. var script string
  297. if b {
  298. script = fmt.Sprintf("%v configure -state disable", w.id)
  299. } else {
  300. script = fmt.Sprintf("%v configure -state normal", w.id)
  301. }
  302. return eval(script)
  303. }
  304. func (w *Text) IsReadOnly() bool {
  305. r, _ := evalAsString(fmt.Sprintf("%v cget -state", w.id))
  306. return r != "normal"
  307. }
  308. type TextIndex struct {
  309. index string
  310. }
  311. func (t TextIndex) String() string {
  312. return t.index
  313. }
  314. func (w *Text) TextLength() int {
  315. r, _ := evalAsInt(fmt.Sprintf("%v count -chars 1.0 end", w.id))
  316. return r
  317. }
  318. func (w *Text) PlainText() string {
  319. r, _ := evalAsString(fmt.Sprintf("%v get 1.0 end", w.id))
  320. return r
  321. }
  322. func (w *Text) LineCount() int {
  323. r, _ := evalAsInt(fmt.Sprintf("%v count -lines 1.0 end", w.id))
  324. return r
  325. }
  326. func (w *Text) InsertText(pos int, text string) error {
  327. setObjText("atk_text_insert", text)
  328. return eval(fmt.Sprintf("%v insert {0.0 + %v chars} $atk_text_insert", w.id, pos))
  329. }
  330. func (w *Text) AppendText(text string) error {
  331. setObjText("atk_text_insert", text)
  332. return eval(fmt.Sprintf("%v insert end $atk_text_insert", w.id))
  333. }
  334. func (w *Text) Length() int {
  335. r, _ := evalAsInt(fmt.Sprintf("%v index end", w.id))
  336. return r
  337. }
  338. func (w *Text) Clear() error {
  339. return eval(fmt.Sprintf("%v delete 1.0 end", w.id))
  340. }
  341. func (w *Text) SetText(text string) error {
  342. setObjText("atk_text_insert", text)
  343. return eval(fmt.Sprintf("%v delete 1.0 end\n%v insert end $atk_text_insert", w.id, w.id))
  344. }
  345. func (w *Text) SetTabSize(size int) error {
  346. return eval(fmt.Sprintf("%v configure -tabs %v", w.id, size))
  347. }
  348. func (w *Text) SetXViewArgs(args []string) error {
  349. return eval(fmt.Sprintf("%v xview %v", w.id, strings.Join(args, " ")))
  350. }
  351. func (w *Text) SetYViewArgs(args []string) error {
  352. return eval(fmt.Sprintf("%v yview %v", w.id, strings.Join(args, " ")))
  353. }
  354. func (w *Text) OnXScrollEx(fn func([]string) error) error {
  355. if fn == nil {
  356. return ErrInvalid
  357. }
  358. if w.xscrollcommand == nil {
  359. w.xscrollcommand = &CommandEx{}
  360. bindCommandEx(w.id, "xscrollcommand", w.xscrollcommand.Invoke)
  361. }
  362. w.xscrollcommand.Bind(fn)
  363. return nil
  364. }
  365. func (w *Text) OnYScrollEx(fn func([]string) error) error {
  366. if fn == nil {
  367. return ErrInvalid
  368. }
  369. if w.yscrollcommand == nil {
  370. w.yscrollcommand = &CommandEx{}
  371. bindCommandEx(w.id, "yscrollcommand", w.yscrollcommand.Invoke)
  372. }
  373. w.yscrollcommand.Bind(fn)
  374. return nil
  375. }
  376. func (w *Text) BindXScrollBar(bar *ScrollBar) error {
  377. if !IsValidWidget(bar) {
  378. return ErrInvalid
  379. }
  380. w.OnXScrollEx(bar.SetScrollArgs)
  381. bar.OnCommandEx(w.SetXViewArgs)
  382. return nil
  383. }
  384. func (w *Text) BindYScrollBar(bar *ScrollBar) error {
  385. if !IsValidWidget(bar) {
  386. return ErrInvalid
  387. }
  388. w.OnYScrollEx(bar.SetScrollArgs)
  389. bar.OnCommandEx(w.SetYViewArgs)
  390. return nil
  391. }
  392. type TextEx struct {
  393. *ScrollLayout
  394. *Text
  395. }
  396. func NewTextEx(parent Widget, attributs ...*WidgetAttr) *TextEx {
  397. w := &TextEx{}
  398. w.ScrollLayout = NewScrollLayout(parent)
  399. w.Text = NewText(parent, attributs...)
  400. w.SetWidget(w.Text)
  401. w.Text.BindXScrollBar(w.XScrollBar)
  402. w.Text.BindYScrollBar(w.YScrollBar)
  403. RegisterWidget(w)
  404. return w
  405. }
  406. func TextAttrBackground(color string) *WidgetAttr {
  407. return &WidgetAttr{"background", color}
  408. }
  409. func TextAttrBorderWidth(width int) *WidgetAttr {
  410. return &WidgetAttr{"borderwidth", width}
  411. }
  412. func TextAttrFont(font Font) *WidgetAttr {
  413. if font == nil {
  414. return nil
  415. }
  416. return &WidgetAttr{"font", font.Id()}
  417. }
  418. func TextAttrForeground(color string) *WidgetAttr {
  419. return &WidgetAttr{"foreground", color}
  420. }
  421. func TextAttrHighlightBackground(color string) *WidgetAttr {
  422. return &WidgetAttr{"highlightbackground", color}
  423. }
  424. func TextAttrHighlightColor(color string) *WidgetAttr {
  425. return &WidgetAttr{"highlightcolor", color}
  426. }
  427. func TextAttrHighlightthickness(width int) *WidgetAttr {
  428. return &WidgetAttr{"highlightthickness", width}
  429. }
  430. func TextAttrInsertBackground(color string) *WidgetAttr {
  431. return &WidgetAttr{"insertbackground", color}
  432. }
  433. func TextAttrInsertBorderWidth(width int) *WidgetAttr {
  434. return &WidgetAttr{"insertborderwidth", width}
  435. }
  436. func TextAttrInsertOffTime(offtime int) *WidgetAttr {
  437. return &WidgetAttr{"insertofftime", offtime}
  438. }
  439. func TextAttrInsertOnTime(ontime int) *WidgetAttr {
  440. return &WidgetAttr{"insertontime", ontime}
  441. }
  442. func TextAttrInsertWidth(width int) *WidgetAttr {
  443. return &WidgetAttr{"insertwidth", width}
  444. }
  445. func TextAttrPadding(padding Pad) *WidgetAttr {
  446. return &WidgetAttr{"padding", padding}
  447. }
  448. func TextAttrReliefStyle(relief ReliefStyle) *WidgetAttr {
  449. return &WidgetAttr{"relief", relief}
  450. }
  451. func TextAttrSelectBackground(color string) *WidgetAttr {
  452. return &WidgetAttr{"selectbackground", color}
  453. }
  454. func TextAttrSelectborderwidth(width int) *WidgetAttr {
  455. return &WidgetAttr{"selectborderwidth", width}
  456. }
  457. func TextAttrSelectforeground(color string) *WidgetAttr {
  458. return &WidgetAttr{"selectforeground", color}
  459. }
  460. func TextAttrInactiveSelectBackground(color string) *WidgetAttr {
  461. return &WidgetAttr{"inactiveselectbackground", color}
  462. }
  463. func TextAttrTakeFocus(takefocus bool) *WidgetAttr {
  464. return &WidgetAttr{"takefocus", boolToInt(takefocus)}
  465. }
  466. func TextAttrAutoSeparatorsOnUndo(autoseparators bool) *WidgetAttr {
  467. return &WidgetAttr{"autoseparators", boolToInt(autoseparators)}
  468. }
  469. func TextAttrBlockCursor(blockcursor bool) *WidgetAttr {
  470. return &WidgetAttr{"blockcursor", boolToInt(blockcursor)}
  471. }
  472. func TextAttrStartLine(startline int) *WidgetAttr {
  473. return &WidgetAttr{"startline", startline}
  474. }
  475. func TextAttrEndLine(endline int) *WidgetAttr {
  476. return &WidgetAttr{"endline", endline}
  477. }
  478. func TextAttrWidth(width int) *WidgetAttr {
  479. return &WidgetAttr{"width", width}
  480. }
  481. func TextAttrHeight(height int) *WidgetAttr {
  482. return &WidgetAttr{"height", height}
  483. }
  484. func TextAttrInsertUnfocussed(style DisplyCursor) *WidgetAttr {
  485. if !mainInterp.SupportTk86() {
  486. return nil
  487. }
  488. return &WidgetAttr{"insertunfocussed", style}
  489. }
  490. func TextAttrMaxUndo(maxundo int) *WidgetAttr {
  491. return &WidgetAttr{"maxundo", maxundo}
  492. }
  493. func TextAttrLineAboveSpace(spacing int) *WidgetAttr {
  494. return &WidgetAttr{"spacing1", spacing}
  495. }
  496. func TextAttrLineWrapSpace(spacing int) *WidgetAttr {
  497. return &WidgetAttr{"spacing2", spacing}
  498. }
  499. func TextAttrLineBelowSpace(spacing int) *WidgetAttr {
  500. return &WidgetAttr{"spacing3", spacing}
  501. }
  502. func TextAttrLineWrap(wrap LineWrapMode) *WidgetAttr {
  503. return &WidgetAttr{"wrap", wrap}
  504. }
  505. func TextAttrEnableUndo(undo bool) *WidgetAttr {
  506. return &WidgetAttr{"undo", boolToInt(undo)}
  507. }