linuxgtk.bmx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. ' Copyright (c) 2014-2020 Bruce A Henderson
  2. '
  3. ' Permission is hereby granted, free of charge, to any person obtaining a copy
  4. ' of this software and associated documentation files (the "Software"), to deal
  5. ' in the Software without restriction, including without limitation the rights
  6. ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. ' copies of the Software, and to permit persons to whom the Software is
  8. ' furnished to do so, subject to the following conditions:
  9. '
  10. ' The above copyright notice and this permission notice shall be included in
  11. ' all copies or substantial portions of the Software.
  12. '
  13. ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. ' THE SOFTWARE.
  20. '
  21. Strict
  22. Import MaxGUI.GTK3MaxGUI
  23. Import "common.bmx"
  24. Rem
  25. bbdoc:
  26. End Rem
  27. Type TGTKScintillaTextArea Extends TGTKTextArea
  28. Field sciPtr:Byte Ptr
  29. Field sciId:Int
  30. Field styleMap:TMap = New TMap
  31. Field styles:Int[] = New Int[31]
  32. Field styleIndex:Int = 0
  33. Field lastStyleValue:Int = -1
  34. Field lastStyle:Int
  35. Global sci_id_count:Int = 0
  36. Field ignoreChange:Int
  37. Field tabPixelWidth:Int
  38. Field lineDigits:Int
  39. Field showLineNumbers:Int = True
  40. ' holder for the latest notification
  41. ' keep one in the type rather than locally in the callback function so we don't have to create a new object for every notification
  42. Field notification:TSCNotification = New TSCNotification
  43. Function CreateTextArea:TGTKTextArea(x:Int, y:Int, w:Int, h:Int, label:String, group:TGadget, style:Int)
  44. Local this:TGTKScintillaTextArea = New TGTKScintillaTextArea
  45. this.initTextArea(x, y, w, h, label, group, style)
  46. Return this
  47. End Function
  48. Method initTextArea(x:Int, y:Int, w:Int, h:Int, label:String, group:TGadget, style:Int)
  49. parent = group
  50. sciId = sci_id_count
  51. handle = scintilla_new()
  52. sciPtr = bmx_mgta_scintilla_getsci(handle, sciId)
  53. ' increment internal counter
  54. sci_id_count :+ 1
  55. gtk_widget_show(handle)
  56. gtk_layout_put(TGTKContainer(parent).container, handle, x, y)
  57. gtk_widget_set_size_request(handle, w, Max(h,0))
  58. addConnection("sci-notify", g_signal_cbsci(handle, "sci-notify", OnSciNotify, Self, Destroy, 0))
  59. addConnection("button-press-event", g_signal_cb3(handle, "button-press-event", OnMouseDown, Self, Destroy, 0))
  60. addConnection("button-release-event", g_signal_cb3(handle, "button-release-event", OnMouseUp, Self, Destroy, 0))
  61. addConnection("key-press-event", g_signal_cb3(handle, "key-press-event", OnKeyDown, Self, Destroy, 0))
  62. ' set some default monospaced font
  63. SetFont(LookupGuiFont(GUIFONT_MONOSPACED))
  64. End Method
  65. Function OnMouseDown:Int(widget:Byte Ptr, event:Byte Ptr, obj:Object)
  66. Local x:Double, y:Double, button:Int
  67. bmx_gtk3maxgui_gdkeventbutton(event, Varptr x, Varptr y, Varptr button)
  68. If button = 3 Then ' right mouse button
  69. ' ignore this... see MouseUp for menu event!
  70. Return True
  71. End If
  72. PostGuiEvent(EVENT_GADGETSELECT, TGadget(obj))
  73. End Function
  74. Rem
  75. bbdoc: Callback for mouse button release
  76. End Rem
  77. Function OnMouseUp:Int(widget:Byte Ptr, event:Byte Ptr, obj:Object)
  78. Local x:Double, y:Double, button:Int
  79. bmx_gtk3maxgui_gdkeventbutton(event, Varptr x, Varptr y, Varptr button)
  80. If button = 3 Then ' right mouse button
  81. PostGuiEvent(EVENT_GADGETMENU, TGadget(obj),,,Int(x),Int(y))
  82. Return True
  83. End If
  84. PostGuiEvent(EVENT_GADGETSELECT, TGadget(obj))
  85. End Function
  86. Method GetText:String()
  87. Return bmx_mgta_scintilla_gettext(sciPtr)
  88. End Method
  89. Rem
  90. bbdoc: Sets the text.
  91. End Rem
  92. Method SetText(txt:String)
  93. bmx_mgta_scintilla_settext(sciPtr, txt)
  94. End Method
  95. Method SetFont(font:TGuiFont)
  96. If font = Null Then
  97. Return
  98. End If
  99. _font = font
  100. bmx_mgta_scintilla_setfont(sciPtr, font.name, font.size)
  101. ' set the margin size for line numbers
  102. bmx_mgta_scintilla_setlinedigits(sciPtr, Varptr lineDigits, showLineNumbers)
  103. SetTabs()
  104. End Method
  105. Rem
  106. bbdoc: Set the text area selection
  107. End Rem
  108. Method SetSelection(pos:Int, length:Int, units:Int)
  109. 'ignoreChange = True
  110. Local startPos:Int
  111. Local endPos:Int
  112. If length = 0 Then
  113. If units = TEXTAREA_LINES Then
  114. startPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos, True)
  115. endPos = startPos
  116. Else
  117. bmx_mgta_scintilla_startendfromchar(sciPtr, pos, length, startPos, endPos)
  118. End If
  119. Else
  120. If units = TEXTAREA_LINES Then
  121. startPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos, True)
  122. endPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos + length, True)
  123. Else ' must be TEXTAREA_CHARS
  124. bmx_mgta_scintilla_startendfromchar(sciPtr, pos, length, startPos, endPos)
  125. End If
  126. End If
  127. bmx_mgta_scintilla_setsel(sciPtr, startPos, endPos)
  128. PostGuiEvent(EVENT_GADGETSELECT, Self)
  129. ' scroll to the start of the selection
  130. ' bmx_mgta_scintilla_scrollcaret(sciPtr)
  131. End Method
  132. Method GetSelectionLength:Int(units:Int)
  133. Return bmx_mgta_scintilla_getselectionlength(sciPtr, units)
  134. End Method
  135. Method SetMargins(leftmargin:Int)
  136. bmx_mgta_scintilla_setmarginleft(sciPtr, leftmargin)
  137. End Method
  138. Method CharX:Int(char:Int)
  139. ' TODO
  140. EndMethod
  141. Method CharY:Int(char:Int)
  142. ' TODO
  143. EndMethod
  144. Method AddText(Text:String)
  145. ignoreChange = True
  146. bmx_mgta_scintilla_appendtext(sciPtr, Text)
  147. ?bmxng
  148. IWrappedSystemDriver(SystemDriver()).GetDriver().Poll()
  149. ?Not bmxng
  150. brl.System.Driver.Poll() ' update events, before scrolling to the end...
  151. ?
  152. bmx_mgta_scintilla_scrolltoend(sciPtr)
  153. End Method
  154. Method ReplaceText(pos:Int, length:Int, Text:String, units:Int)
  155. ignoreChange = True
  156. If length = TEXTAREA_ALL Then
  157. SetText(Text)
  158. Else
  159. Local startPos:Int
  160. Local endPos:Int
  161. If units = TEXTAREA_LINES Then
  162. startPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos, True)
  163. endPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos + length, True)
  164. Else ' must be TEXTAREA_CHARS
  165. bmx_mgta_scintilla_startendfromchar(sciPtr, pos, length, startPos, endPos)
  166. End If
  167. bmx_mgta_scintilla_settargetstart(sciPtr, startPos)
  168. bmx_mgta_scintilla_settargetend(sciPtr, endPos)
  169. ' insert new text
  170. Local textPtr:Byte Ptr = Text.ToUTF8String()
  171. bmx_mgta_scintilla_replacetarget(sciPtr, textPtr)
  172. MemFree(textPtr)
  173. End If
  174. End Method
  175. Method SetColor(r:Int, g:Int, b:Int)
  176. bmx_mgta_scintilla_stylesetback(sciPtr, r | g Shl 8 | b Shl 16)
  177. End Method
  178. Method SetTextColor(r:Int, g:Int, b:Int)
  179. ' set style 0 color (should be main text style)
  180. bmx_mgta_scintilla_stylesetfore(sciPtr, 0, r | g Shl 8 | b Shl 16)
  181. End Method
  182. Method SetStyle(r:Int, g:Int, b:Int, flags:Int, pos:Int, length:Int, units:Int)
  183. ' Build a style string
  184. Local s:Int = r Shl 24 | g Shl 16 | b Shl 8 | (flags & $ff)
  185. Local style:Int = lastStyle
  186. If s <> lastStyleValue Then
  187. Local styleText:String = String(s)
  188. Local st:String = String(styleMap.ValueForKey(styleText))
  189. If Not st Then
  190. ' is there already an entry for this one?
  191. If styles[styleIndex] Then
  192. ' remove it from the map
  193. styleMap.Remove(String(styles[styleIndex]))
  194. End If
  195. styles[styleIndex] = s
  196. styleMap.Insert(styleText, Chr(styleIndex + 65))
  197. style = styleIndex
  198. styleIndex :+ 1
  199. If styleIndex > 31 Then
  200. styleIndex = 0
  201. End If
  202. ' create the styling
  203. bmx_mgta_scintilla_stylesetfore(sciPtr, style, r | g Shl 8 | b Shl 16)
  204. If flags & TEXTFORMAT_ITALIC Then
  205. bmx_mgta_scintilla_stylesetitalic(sciPtr, style, True)
  206. Else
  207. bmx_mgta_scintilla_stylesetitalic(sciPtr, style, False)
  208. End If
  209. If flags & TEXTFORMAT_BOLD Then
  210. bmx_mgta_scintilla_stylesetbold(sciPtr, style, True)
  211. Else
  212. bmx_mgta_scintilla_stylesetbold(sciPtr, style, False)
  213. End If
  214. If flags & TEXTFORMAT_UNDERLINE Then
  215. bmx_mgta_scintilla_stylesetunderline(sciPtr, style, True)
  216. Else
  217. bmx_mgta_scintilla_stylesetunderline(sciPtr, style, False)
  218. End If
  219. Else
  220. style = Asc(st) - 65
  221. End If
  222. lastStyle = style
  223. lastStyleValue = s
  224. End If
  225. applyStyle(pos, length, units, style)
  226. End Method
  227. Method applyStyle(pos:Int, length:Int, units:Int, style:Int)
  228. Local startPos:Int
  229. Local realLength:Int
  230. If units = TEXTAREA_LINES Then
  231. startPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos, True)
  232. realLength = bmx_mgta_scintilla_positionfromline(sciPtr, pos + length, True) - startPos
  233. Else ' must be TEXTAREA_CHARS
  234. Local endPos:Int
  235. bmx_mgta_scintilla_startendfromchar(sciPtr, pos, length, startPos, endPos)
  236. realLength = endPos - startPos
  237. End If
  238. bmx_mgta_scintilla_startstyling(sciPtr, startPos)
  239. bmx_mgta_scintilla_setstyling(sciPtr, realLength, style)
  240. End Method
  241. Method AreaText:String(pos:Int, length:Int, units:Int)
  242. Local startPos:Int
  243. Local endPos:Int
  244. If units = TEXTAREA_LINES Then
  245. startPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos, True)
  246. endPos = bmx_mgta_scintilla_positionfromline(sciPtr, pos + length, True)
  247. Else ' must be TEXTAREA_CHARS
  248. bmx_mgta_scintilla_startendfromchar(sciPtr, pos, length, startPos, endPos)
  249. End If
  250. Return bmx_mgta_scintilla_gettextrange(sciPtr, startPos, endPos)
  251. End Method
  252. Method AreaLen:Int(units:Int)
  253. If units = TEXTAREA_LINES Then
  254. Return bmx_mgta_scintilla_getlinecount(sciPtr)
  255. Else
  256. Return bmx_mgta_scintilla_getlength(sciPtr)
  257. End If
  258. End Method
  259. Method GetCursorPos:Int(units:Int)
  260. If units = TEXTAREA_LINES Then
  261. Return bmx_mgta_scintilla_getcurrentline(sciPtr)
  262. Else
  263. Return bmx_mgta_scintilla_getcurrentpos(sciPtr)
  264. End If
  265. End Method
  266. Method SetTabs(tabWidth:Int = -1)
  267. If tabWidth >= 0 Then
  268. tabPixelWidth = tabWidth
  269. Else
  270. tabWidth = tabPixelWidth
  271. End If
  272. ' convert from pixels to characters
  273. If _font Then
  274. tabWidth = tabWidth / _font.CharWidth(32)
  275. Else
  276. tabWidth = 4
  277. End If
  278. bmx_mgta_scintilla_settabwidth(sciPtr, tabWidth)
  279. End Method
  280. Method Activate(cmd:Int)
  281. Super.Activate(cmd)
  282. Select cmd
  283. Case ACTIVATE_CUT
  284. bmx_mgta_scintilla_cut(sciPtr)
  285. Case ACTIVATE_COPY
  286. bmx_mgta_scintilla_copy(sciPtr)
  287. Case ACTIVATE_PASTE
  288. bmx_mgta_scintilla_paste(sciPtr)
  289. End Select
  290. End Method
  291. Method CharAt:Int(line:Int)
  292. Return bmx_mgta_scintilla_positionfromline(sciPtr, line, False)
  293. End Method
  294. Method LineAt:Int(index:Int)
  295. Return bmx_mgta_scintilla_linefromposition(sciPtr, index)
  296. End Method
  297. Function OnSciNotify(widget:Byte Ptr, id:Int, notificationPtr:Byte Ptr, obj:Object)
  298. Local ta:TGTKScintillaTextArea = TGTKScintillaTextArea(obj)
  299. bmx_mgta_scintilla_notifcation_update(ta.notification, notificationPtr)
  300. Select ta.notification.code
  301. Case SCN_UPDATEUI
  302. If ta.notification.updated & SC_UPDATE_SELECTION Then
  303. PostGuiEvent(EVENT_GADGETSELECT, TGadget(obj))
  304. End If
  305. Case SCN_MODIFIED
  306. If ta.notification.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT) Then
  307. If Not ta.ignoreChange Then
  308. PostGuiEvent(EVENT_GADGETSELECT, TGadget(obj))
  309. PostGuiEvent(EVENT_GADGETACTION, TGadget(obj))
  310. End If
  311. ta.ignoreChange = False
  312. If ta.notification.modificationType & SC_MOD_DELETETEXT Then
  313. bmx_mgta_scintilla_resetscrollwidth(ta.sciPtr)
  314. End If
  315. bmx_mgta_scintilla_setlinedigits(ta.sciPtr, Varptr ta.lineDigits, ta.showLineNumbers)
  316. End If
  317. End Select
  318. End Function
  319. Method SetCaretWidth(width:Int)
  320. bmx_mgta_scintilla_setcaretwidth(sciPtr, width)
  321. End Method
  322. Method SetCaretColor(r:Int, g:Int, b:Int)
  323. bmx_mgta_scintilla_setcaretcolor(sciPtr, r, g, b)
  324. End Method
  325. Method HasUndoRedo:Int()
  326. Return True
  327. End Method
  328. Method EnableUndoRedo(enable:Int)
  329. bmx_mgta_scintilla_enableundoredo(sciPtr, enable)
  330. End Method
  331. Method UndoRedoEnabled:Int()
  332. Return bmx_mgta_scintilla_undoredoenabled(sciPtr)
  333. End Method
  334. Method Undo()
  335. bmx_mgta_scintilla_undo(sciPtr)
  336. End Method
  337. Method Redo()
  338. bmx_mgta_scintilla_redo(sciPtr)
  339. End Method
  340. Method CanUndo:Int()
  341. Return bmx_mgta_scintilla_canundo(sciPtr)
  342. End Method
  343. Method CanRedo:Int()
  344. Return bmx_mgta_scintilla_canredo(sciPtr)
  345. End Method
  346. Method ClearUndoRedo()
  347. bmx_mgta_scintilla_clearundoredo(sciPtr)
  348. End Method
  349. Method HasHighlighting:Int()
  350. Return True
  351. End Method
  352. Method SetHighlightLanguage(lang:String)
  353. bmx_mgta_scintilla_sethighlightlanguage(sciPtr, lang)
  354. End Method
  355. Method SetHighlightKeywords(index:Int, keywords:String)
  356. bmx_mgta_scintilla_sethighlightkeywords(sciPtr, index, keywords)
  357. End Method
  358. Method SetHighlightStyle(index:Int, flags:Int, red:Int, green:Int, blue:Int)
  359. bmx_mgta_scintilla_sethighlightstyle(sciPtr, index, flags, red | green Shl 8 | blue Shl 16)
  360. End Method
  361. Method HighLight()
  362. bmx_mgta_scintilla_highlight(sciPtr)
  363. End Method
  364. Method ClearHighlightStyles(br:Int, bg:Int, bb:Int, fr:Int, fg:Int, fb:Int)
  365. bmx_mgta_scintilla_clearhighlightstyles(sciPtr, br | bg Shl 8 | bb Shl 16, fr | fg Shl 8 | fb Shl 16)
  366. End Method
  367. Method HasLineNumbers:Int()
  368. Return True
  369. End Method
  370. Method SetLineNumberBackColor(r:Int, g:Int, b:Int)
  371. bmx_mgta_scintilla_setlinenumberbackcolor(sciPtr, r | g Shl 8 | b Shl 16)
  372. End Method
  373. Method SetLineNumberForeColor(r:Int, g:Int, b:Int)
  374. bmx_mgta_scintilla_setlinenumberforecolor(sciPtr, r | g Shl 8 | b Shl 16)
  375. End Method
  376. Method SetLineNumberEnable(enabled:Int)
  377. showLineNumbers = enabled
  378. bmx_mgta_scintilla_setlinedigits(sciPtr, Varptr lineDigits, showLineNumbers)
  379. End Method
  380. Method SetCaretLineVisible(enabled:Int)
  381. bmx_mgta_scintilla_setcaretlinevisible(sciPtr, enabled)
  382. End Method
  383. Method GetCaretLineVisible:Int()
  384. Return bmx_mgta_scintilla_getcaretlinevisible(sciPtr)
  385. End Method
  386. Method SetCaretLineBackgroundColor(r:Int, g:Int, b:Int, a:Int)
  387. bmx_mgta_scintilla_setcaretlineback(sciPtr, r, g, b, a)
  388. End Method
  389. Method GetCaretLineBackgroundColor:Int()
  390. Return bmx_mgta_scintilla_getcaretlineback(sciPtr)
  391. End Method
  392. Method HasBlockIndent:Int()
  393. Return True
  394. End Method
  395. Method BeginUndoAction()
  396. bmx_mgta_scintilla_beginundoaction(sciPtr)
  397. End Method
  398. Method EndUndoAction()
  399. bmx_mgta_scintilla_endundoaction(sciPtr)
  400. End Method
  401. Method HasBracketMatching:Int()
  402. Return True
  403. End Method
  404. Method SetBracketMatchingColor(r:Int, g:Int, b:Int, flags:Int)
  405. bmx_mgta_scintilla_setbracketmatchingcolor(sciPtr, r, g, b, flags)
  406. End Method
  407. Method MatchBrackets()
  408. bmx_mgta_scintilla_matchbrackets(sciPtr)
  409. End Method
  410. End Type
  411. ' scintilla text area driver
  412. Type TGTKScintillaTextAreaDriver Extends TGTKTextAreaDriver
  413. Function CreateTextArea:TGTKTextArea(x:Int, y:Int, w:Int, h:Int, label:String, group:TGadget, style:Int)
  414. Return TGTKScintillaTextArea.CreateTextArea(x, y, w, h, label, group, style)
  415. End Function
  416. End Type
  417. gtk3maxgui_textarea = New TGTKScintillaTextAreaDriver