win32.bmx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  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.Win32MaxGUIEx
  23. Import "common.bmx"
  24. Rem
  25. bbdoc:
  26. End Rem
  27. Type TWindowsScintillaTextArea Extends TWindowsTextArea
  28. 'Field _hwnd: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. Method Create:TWindowsGadget(group:TGadget, style:Int, txt:String)
  44. Local parent:Byte Ptr=group.query(QUERY_HWND_CLIENT)
  45. Local hwnd:Byte Ptr = bmx_mgta_scintilla_getsci(parent)
  46. Register GADGET_TEXTAREA,hwnd
  47. SetShape(0, 0, ClientWidth(group), ClientHeight(group))
  48. SetShow(True)
  49. Sensitize()
  50. Return Self
  51. End Method
  52. Method WndProc:Byte Ptr(hwnd:Byte Ptr,msg:UInt,wp:WParam,lp:LParam)
  53. Local event:TEvent
  54. Select msg
  55. 'Case WM_MOUSEWHEEL
  56. ' If (Long(wp)&MK_CONTROL) Then SendMessageW _hwnd, EM_SETZOOM, 0, 0
  57. Case WM_KEYDOWN
  58. If eventfilter<>Null
  59. event=CreateEvent(EVENT_KEYDOWN,Self,Int(wp),keymods())
  60. If Not eventfilter(event,context) Return True
  61. EndIf
  62. Case WM_KILLFOCUS
  63. PostGuiEvent EVENT_GADGETLOSTFOCUS
  64. Case WM_CHAR
  65. Local mods:Int = keymods()
  66. If (mods & MODIFIER_CONTROL And Not (mods & MODIFIER_OPTION)) Then
  67. Return 1
  68. End If
  69. If eventfilter<>Null
  70. event=CreateEvent(EVENT_KEYCHAR,Self,Int(wp),mods)
  71. If Not eventfilter(event,context) Return True
  72. EndIf
  73. End Select
  74. Return Super.WndProc(hwnd,msg,wp,lp)
  75. EndMethod
  76. Method OnNotify(wp:WParam,lp:LParam)
  77. Local nmhdrPtr:Byte Ptr
  78. Local event:TEvent
  79. Super.OnNotify(wp,lp) 'Tooltip
  80. bmx_mgta_scintilla_notifcation_update(notification, Byte Ptr(lp))
  81. Select notification.code
  82. Case SCN_UPDATEUI
  83. If notification.updated & SC_UPDATE_SELECTION Then
  84. PostGuiEvent(EVENT_GADGETSELECT, Self)
  85. End If
  86. Case SCN_MODIFIED
  87. If notification.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT) Then
  88. If Not ignoreChange Then
  89. PostGuiEvent(EVENT_GADGETSELECT, Self)
  90. PostGuiEvent(EVENT_GADGETACTION, Self)
  91. End If
  92. ignoreChange = False
  93. If notification.modificationType & SC_MOD_DELETETEXT Then
  94. bmx_mgta_scintilla_resetscrollwidth(_hwnd)
  95. End If
  96. bmx_mgta_scintilla_setlinedigits(_hwnd, Varptr lineDigits, showLineNumbers)
  97. End If
  98. End Select
  99. End Method
  100. Method GetText:String()
  101. Return bmx_mgta_scintilla_gettext(_hwnd)
  102. End Method
  103. Rem
  104. bbdoc: Sets the text.
  105. End Rem
  106. Method SetText(txt:String)
  107. bmx_mgta_scintilla_settext(_hwnd, txt)
  108. End Method
  109. Method SetFont(font:TGuiFont)
  110. If font = Null Then
  111. Return
  112. End If
  113. _font = TWindowsFont(font)
  114. bmx_mgta_scintilla_setfont(_hwnd, font.name, font.size)
  115. ' set the margin size for line numbers
  116. bmx_mgta_scintilla_setlinedigits(_hwnd, Varptr lineDigits, showLineNumbers)
  117. SetTabs()
  118. End Method
  119. Rem
  120. bbdoc: Set the text area selection
  121. End Rem
  122. Method SetSelection(pos:Int, length:Int, units:Int)
  123. 'ignoreChange = True
  124. Local startPos:Int
  125. Local endPos:Int
  126. If length = 0 Then
  127. If units = TEXTAREA_LINES Then
  128. startPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos, True)
  129. endPos = startPos
  130. Else
  131. bmx_mgta_scintilla_startendfromchar(_hwnd, pos, length, startPos, endPos)
  132. End If
  133. Else
  134. If units = TEXTAREA_LINES Then
  135. startPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos, True)
  136. endPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos + length, True)
  137. Else ' must be TEXTAREA_CHARS
  138. bmx_mgta_scintilla_startendfromchar(_hwnd, pos, length, startPos, endPos)
  139. End If
  140. End If
  141. bmx_mgta_scintilla_setsel(_hwnd, startPos, endPos)
  142. PostGuiEvent(EVENT_GADGETSELECT, Self)
  143. ' scroll to the start of the selection
  144. 'bmx_mgta_scintilla_scrollcaret(_hwnd)
  145. End Method
  146. Method GetSelectionLength:Int(units:Int)
  147. Return bmx_mgta_scintilla_getselectionlength(_hwnd, units)
  148. End Method
  149. Method SetMargins(leftmargin:Int)
  150. bmx_mgta_scintilla_setmarginleft(_hwnd, leftmargin)
  151. End Method
  152. Method CharX:Int(char:Int)
  153. ' TODO
  154. EndMethod
  155. Method CharY:Int(char:Int)
  156. ' TODO
  157. EndMethod
  158. Method AddText(Text:String)
  159. ignoreChange = True
  160. bmx_mgta_scintilla_appendtext(_hwnd, Text)
  161. bmx_mgta_scintilla_scrolltoend(_hwnd)
  162. End Method
  163. Method ReplaceText(pos:Int, length:Int, Text:String, units:Int)
  164. ignoreChange = True
  165. If length = TEXTAREA_ALL Then
  166. SetText(Text)
  167. Else
  168. Local startPos:Int
  169. Local endPos:Int
  170. If units = TEXTAREA_LINES Then
  171. startPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos, True)
  172. endPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos + length, True)
  173. Else ' must be TEXTAREA_CHARS
  174. bmx_mgta_scintilla_startendfromchar(_hwnd, pos, length, startPos, endPos)
  175. End If
  176. bmx_mgta_scintilla_settargetstart(_hwnd, startPos)
  177. bmx_mgta_scintilla_settargetend(_hwnd, endPos)
  178. ' insert new text
  179. Local textPtr:Byte Ptr = Text.ToUTF8String()
  180. bmx_mgta_scintilla_replacetarget(_hwnd, textPtr)
  181. MemFree(textPtr)
  182. End If
  183. End Method
  184. Method SetColor(r:Int, g:Int, b:Int)
  185. bmx_mgta_scintilla_stylesetback(_hwnd, r | g Shl 8 | b Shl 16)
  186. End Method
  187. Method SetTextColor(r:Int, g:Int, b:Int)
  188. ' set style 0 color (should be main text style)
  189. bmx_mgta_scintilla_stylesetfore(_hwnd, 0, r | g Shl 8 | b Shl 16)
  190. End Method
  191. Method SetStyle(r:Int, g:Int, b:Int, flags:Int, pos:Int, length:Int, units:Int)
  192. ' Build a style string
  193. Local s:Int = r Shl 24 | g Shl 16 | b Shl 8 | (flags & $ff)
  194. Local style:Int = lastStyle
  195. If s <> lastStyleValue Then
  196. Local styleText:String = String(s)
  197. Local st:String = String(styleMap.ValueForKey(styleText))
  198. If Not st Then
  199. ' is there already an entry for this one?
  200. If styles[styleIndex] Then
  201. ' remove it from the map
  202. styleMap.Remove(String(styles[styleIndex]))
  203. End If
  204. styles[styleIndex] = s
  205. styleMap.Insert(styleText, Chr(styleIndex + 65))
  206. style = styleIndex
  207. styleIndex :+ 1
  208. If styleIndex > 31 Then
  209. styleIndex = 0
  210. End If
  211. ' create the styling
  212. bmx_mgta_scintilla_stylesetfore(_hwnd, style, r | g Shl 8 | b Shl 16)
  213. If flags & TEXTFORMAT_ITALIC Then
  214. bmx_mgta_scintilla_stylesetitalic(_hwnd, style, True)
  215. Else
  216. bmx_mgta_scintilla_stylesetitalic(_hwnd, style, False)
  217. End If
  218. If flags & TEXTFORMAT_BOLD Then
  219. bmx_mgta_scintilla_stylesetbold(_hwnd, style, True)
  220. Else
  221. bmx_mgta_scintilla_stylesetbold(_hwnd, style, False)
  222. End If
  223. If flags & TEXTFORMAT_UNDERLINE Then
  224. bmx_mgta_scintilla_stylesetunderline(_hwnd, style, True)
  225. Else
  226. bmx_mgta_scintilla_stylesetunderline(_hwnd, style, False)
  227. End If
  228. Else
  229. style = Asc(st) - 65
  230. End If
  231. lastStyle = style
  232. lastStyleValue = s
  233. End If
  234. applyStyle(pos, length, units, style)
  235. End Method
  236. Method applyStyle(pos:Int, length:Int, units:Int, style:Int)
  237. Local startPos:Int
  238. Local realLength:Int
  239. If units = TEXTAREA_LINES Then
  240. startPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos, True)
  241. realLength = bmx_mgta_scintilla_positionfromline(_hwnd, pos + length, True) - startPos
  242. Else ' must be TEXTAREA_CHARS
  243. Local endPos:Int
  244. bmx_mgta_scintilla_startendfromchar(_hwnd, pos, length, startPos, endPos)
  245. realLength = endPos - startPos
  246. End If
  247. bmx_mgta_scintilla_startstyling(_hwnd, startPos)
  248. bmx_mgta_scintilla_setstyling(_hwnd, realLength, style)
  249. End Method
  250. Method AreaText:String(pos:Int, length:Int, units:Int)
  251. Local startPos:Int
  252. Local endPos:Int
  253. If units = TEXTAREA_LINES Then
  254. startPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos, True)
  255. endPos = bmx_mgta_scintilla_positionfromline(_hwnd, pos + length, True)
  256. Else ' must be TEXTAREA_CHARS
  257. bmx_mgta_scintilla_startendfromchar(_hwnd, pos, length, startPos, endPos)
  258. End If
  259. Return bmx_mgta_scintilla_gettextrange(_hwnd, startPos, endPos)
  260. End Method
  261. Method AreaLen:Int(units:Int)
  262. If units = TEXTAREA_LINES Then
  263. Return bmx_mgta_scintilla_getlinecount(_hwnd)
  264. Else
  265. Return bmx_mgta_scintilla_getlength(_hwnd)
  266. End If
  267. End Method
  268. Method GetCursorPos:Int(units:Int)
  269. If units = TEXTAREA_LINES Then
  270. Return bmx_mgta_scintilla_getcurrentline(_hwnd)
  271. Else
  272. Return bmx_mgta_scintilla_getcurrentpos(_hwnd)
  273. End If
  274. End Method
  275. Method SetTabs(tabWidth:Int = -1)
  276. If tabWidth >= 0 Then
  277. tabPixelWidth = tabWidth
  278. Else
  279. tabWidth = tabPixelWidth
  280. End If
  281. ' convert from pixels to characters
  282. If _font Then
  283. tabWidth = tabWidth / _font.CharWidth(32)
  284. Else
  285. tabWidth = 4
  286. End If
  287. bmx_mgta_scintilla_settabwidth(_hwnd, tabWidth)
  288. End Method
  289. Method Activate(cmd:Int)
  290. Super.Activate(cmd)
  291. Select cmd
  292. Case ACTIVATE_CUT
  293. bmx_mgta_scintilla_cut(_hwnd)
  294. Case ACTIVATE_COPY
  295. bmx_mgta_scintilla_copy(_hwnd)
  296. Case ACTIVATE_PASTE
  297. bmx_mgta_scintilla_paste(_hwnd)
  298. End Select
  299. End Method
  300. Method CharAt:Int(line:Int)
  301. Return bmx_mgta_scintilla_positionfromline(_hwnd, line, False)
  302. End Method
  303. Method LineAt:Int(index:Int)
  304. Return bmx_mgta_scintilla_linefromposition(_hwnd, index)
  305. End Method
  306. Method SetCaretWidth(width:Int)
  307. bmx_mgta_scintilla_setcaretwidth(_hwnd, width)
  308. End Method
  309. Method SetCaretColor(r:Int, g:Int, b:Int)
  310. bmx_mgta_scintilla_setcaretcolor(_hwnd, r, g, b)
  311. End Method
  312. Method Class()
  313. Return GADGET_TEXTAREA
  314. EndMethod
  315. Method HasUndoRedo:Int()
  316. Return True
  317. End Method
  318. Method EnableUndoRedo(enable:Int)
  319. bmx_mgta_scintilla_enableundoredo(_hwnd, enable)
  320. End Method
  321. Method UndoRedoEnabled:Int()
  322. Return bmx_mgta_scintilla_undoredoenabled(_hwnd)
  323. End Method
  324. Method Undo()
  325. bmx_mgta_scintilla_undo(_hwnd)
  326. End Method
  327. Method Redo()
  328. bmx_mgta_scintilla_redo(_hwnd)
  329. End Method
  330. Method CanUndo:Int()
  331. Return bmx_mgta_scintilla_canundo(_hwnd)
  332. End Method
  333. Method CanRedo:Int()
  334. Return bmx_mgta_scintilla_canredo(_hwnd)
  335. End Method
  336. Method ClearUndoRedo()
  337. bmx_mgta_scintilla_clearundoredo(_hwnd)
  338. End Method
  339. Method HasHighlighting:Int()
  340. Return True
  341. End Method
  342. Method SetHighlightLanguage(lang:String)
  343. bmx_mgta_scintilla_sethighlightlanguage(_hwnd, lang)
  344. End Method
  345. Method SetHighlightKeywords(index:Int, keywords:String)
  346. bmx_mgta_scintilla_sethighlightkeywords(_hwnd, index, keywords)
  347. End Method
  348. Method SetHighlightStyle(index:Int, flags:Int, red:Int, green:Int, blue:Int)
  349. bmx_mgta_scintilla_sethighlightstyle(_hwnd, index, flags, red | green Shl 8 | blue Shl 16)
  350. End Method
  351. Method HighLight()
  352. bmx_mgta_scintilla_highlight(_hwnd)
  353. End Method
  354. Method ClearHighlightStyles(br:Int, bg:Int, bb:Int, fr:Int, fg:Int, fb:Int)
  355. bmx_mgta_scintilla_clearhighlightstyles(_hwnd, br | bg Shl 8 | bb Shl 16, fr | fg Shl 8 | fb Shl 16)
  356. End Method
  357. Method HasLineNumbers:Int()
  358. Return True
  359. End Method
  360. Method SetLineNumberBackColor(r:Int, g:Int, b:Int)
  361. bmx_mgta_scintilla_setlinenumberbackcolor(_hwnd, r | g Shl 8 | b Shl 16)
  362. End Method
  363. Method SetLineNumberForeColor(r:Int, g:Int, b:Int)
  364. bmx_mgta_scintilla_setlinenumberforecolor(_hwnd, r | g Shl 8 | b Shl 16)
  365. End Method
  366. Method SetLineNumberEnable(enabled:Int)
  367. showLineNumbers = enabled
  368. bmx_mgta_scintilla_setlinedigits(_hwnd, Varptr lineDigits, showLineNumbers)
  369. End Method
  370. Method SetCaretLineVisible(enabled:Int)
  371. bmx_mgta_scintilla_setcaretlinevisible(_hwnd, enabled)
  372. End Method
  373. Method GetCaretLineVisible:Int()
  374. Return bmx_mgta_scintilla_getcaretlinevisible(_hwnd)
  375. End Method
  376. Method SetCaretLineBackgroundColor(r:Int, g:Int, b:Int, a:Int)
  377. bmx_mgta_scintilla_setcaretlineback(_hwnd, r, g, b, a)
  378. End Method
  379. Method GetCaretLineBackgroundColor:Int()
  380. Return bmx_mgta_scintilla_getcaretlineback(_hwnd)
  381. End Method
  382. Method HasCharEventSupressionFixup:Int()
  383. Return True
  384. End Method
  385. Method HasBlockIndent:Int()
  386. Return True
  387. End Method
  388. Method BeginUndoAction()
  389. bmx_mgta_scintilla_beginundoaction(_hwnd)
  390. End Method
  391. Method EndUndoAction()
  392. bmx_mgta_scintilla_endundoaction(_hwnd)
  393. End Method
  394. Method HasBracketMatching:Int()
  395. Return True
  396. End Method
  397. Method SetBracketMatchingColor(r:Int, g:Int, b:Int, flags:Int)
  398. bmx_mgta_scintilla_setbracketmatchingcolor(_hwnd, r, g, b, flags)
  399. End Method
  400. Method MatchBrackets()
  401. bmx_mgta_scintilla_matchbrackets(_hwnd)
  402. End Method
  403. End Type
  404. ' scintilla text area driver
  405. Type TWindowsScintillaTextAreaDriver Extends TWindowsTextAreaDriver
  406. Function CreateTextArea:TWindowsGadget(group:TGadget, style:Int, Text:String)
  407. Return New TWindowsScintillaTextArea.Create(group, style, Text)
  408. End Function
  409. End Type
  410. windowsmaxguiex_textarea = New TWindowsScintillaTextAreaDriver
  411. Private
  412. Function KeyMods()
  413. Local mods
  414. If GetKeyState(VK_SHIFT)&$8000 mods:|MODIFIER_SHIFT
  415. If GetKeyState(VK_CONTROL)&$8000 mods:|MODIFIER_CONTROL
  416. If GetKeyState(VK_MENU)&$8000 mods:|MODIFIER_OPTION
  417. If GetKeyState(VK_LWIN)&$8000 Or GetKeyState(VK_RWIN)&$8000 mods:|MODIFIER_SYSTEM
  418. Return mods
  419. EndFunction