TextInput.hx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. package h2d;
  2. import hxd.Key in K;
  3. private typedef TextHistoryElement = { t : String, c : Int, sel : { start : Int, length : Int } };
  4. /**
  5. A skinnable text input handler.
  6. Supports text selection, keyboard cursor navigation, as well as basic hotkeys: `Ctrl + Z`, `Ctrl + Y` for undo and redo and `Ctrl + A` to select all text.
  7. **/
  8. class TextInput extends Text {
  9. /**
  10. Current position of the input cursor.
  11. When TextInput is not focused value is -1.
  12. **/
  13. public var cursorIndex : Int = -1;
  14. /**
  15. The Tile used to render the input cursor.
  16. **/
  17. public var cursorTile : h2d.Tile;
  18. /**
  19. The Tile used to render the background for selected text.
  20. When rendering, this Tile is stretched horizontally to fill entire selection area.
  21. **/
  22. public var selectionTile : h2d.Tile;
  23. /**
  24. The blinking interval of the cursor in seconds.
  25. **/
  26. public var cursorBlinkTime = 0.5;
  27. /**
  28. Maximum input width.
  29. Contrary to `Text.maxWidth` does not cause a word-wrap, but also masks out contents that are outside the max width.
  30. **/
  31. public var inputWidth : Null<Int>;
  32. /**
  33. Whether the text input allows multiple lines.
  34. **/
  35. public var multiline: Bool = false;
  36. /**
  37. If not null, represents current text selection range.
  38. **/
  39. public var selectionRange : { start : Int, length : Int };
  40. /**
  41. When disabled, user would not be able to edit the input text (selection is still available).
  42. **/
  43. public var canEdit = true;
  44. /**
  45. If set, TextInput will render provided color as a background to text interactive area.
  46. **/
  47. public var backgroundColor(get, set) : Null<Int>;
  48. /**
  49. When disabled, showSoftwareKeyboard will not be called.
  50. **/
  51. public var useSoftwareKeyboard : Bool = true;
  52. public static dynamic function showSoftwareKeyboard(target:TextInput) {}
  53. public static dynamic function hideSoftwareKeyboard(target:TextInput) {}
  54. var interactive : h2d.Interactive;
  55. var cursorText : String;
  56. var cursorX : Float;
  57. var cursorXIndex : Int;
  58. var cursorY : Float;
  59. var cursorYIndex : Int;
  60. var cursorBlink = 0.;
  61. var cursorScroll = 0;
  62. var scrollX = 0.;
  63. var selectionPos : Float;
  64. var selectionSize : Float;
  65. var undo : Array<TextHistoryElement> = [];
  66. var redo : Array<TextHistoryElement> = [];
  67. var lastChange = 0.;
  68. var lastClick = 0.;
  69. var maxHistorySize = 100;
  70. /**
  71. Create a new TextInput instance.
  72. @param font The font used to render the text.
  73. @param parent An optional parent `h2d.Object` instance to which TextInput adds itself if set.
  74. **/
  75. public function new(font, ?parent) {
  76. super(font, parent);
  77. interactive = new h2d.Interactive(0, 0);
  78. interactive.cursor = TextInput;
  79. interactive.onPush = function(e:hxd.Event) {
  80. onPush(e);
  81. if( !e.cancel && e.button == 0 ) {
  82. if( !interactive.hasFocus() ) {
  83. e.kind = EFocus;
  84. onFocus(e);
  85. e.kind = EPush;
  86. if( e.cancel ) return;
  87. interactive.focus();
  88. }
  89. cursorBlink = 0;
  90. var startIndex = textPos(e.relX, e.relY);
  91. cursorIndex = startIndex;
  92. selectionRange = null;
  93. var pt = new h2d.col.Point();
  94. var scene = getScene();
  95. if( scene == null ) return; // was removed
  96. scene.startCapture(function(e) {
  97. pt.x = e.relX;
  98. pt.y = e.relY;
  99. globalToLocal(pt);
  100. var index = textPos(pt.x, pt.y);
  101. if( index == startIndex )
  102. selectionRange = null;
  103. else if( index < startIndex )
  104. selectionRange = { start : index, length : startIndex - index };
  105. else
  106. selectionRange = { start : startIndex, length : index - startIndex };
  107. selectionSize = 0;
  108. cursorIndex = index;
  109. if( e.kind == ERelease || getScene() != scene )
  110. scene.stopCapture();
  111. });
  112. }
  113. };
  114. interactive.onKeyDown = function(e:hxd.Event) {
  115. onKeyDown(e);
  116. handleKey(e);
  117. };
  118. interactive.onTextInput = function(e:hxd.Event) {
  119. onTextInput(e);
  120. handleKey(e);
  121. };
  122. interactive.onFocus = function(e) {
  123. onFocus(e);
  124. if ( useSoftwareKeyboard && canEdit )
  125. showSoftwareKeyboard(this);
  126. }
  127. interactive.onFocusLost = function(e) {
  128. cursorIndex = -1;
  129. selectionRange = null;
  130. hideSoftwareKeyboard(this);
  131. onFocusLost(e);
  132. };
  133. interactive.onClick = function(e) {
  134. onClick(e);
  135. if( e.cancel ) return;
  136. var t = haxe.Timer.stamp();
  137. // double click to select all
  138. if( t - lastClick < 0.3 && text.length != 0 ) {
  139. selectionRange = { start : 0, length : text.length };
  140. selectionSize = 0;
  141. cursorIndex = text.length;
  142. }
  143. lastClick = t;
  144. };
  145. interactive.onKeyUp = function(e) onKeyUp(e);
  146. interactive.onRelease = function(e) onRelease(e);
  147. interactive.onKeyUp = function(e) onKeyUp(e);
  148. interactive.onMove = function(e) onMove(e);
  149. interactive.onOver = function(e) onOver(e);
  150. interactive.onOut = function(e) onOut(e);
  151. interactive.cursor = TextInput;
  152. addChildAt(interactive, 0);
  153. }
  154. override function constraintSize(width:Float, height:Float) {
  155. // disable (don't allow multiline textinput for now)
  156. }
  157. function handleKey( e : hxd.Event ) {
  158. if( e.cancel || cursorIndex < 0 )
  159. return;
  160. var oldIndex = cursorIndex;
  161. var oldText = text;
  162. switch( e.keyCode ) {
  163. case K.UP if( multiline ):
  164. moveCursorVertically(-1);
  165. case K.DOWN if( multiline ):
  166. moveCursorVertically(1);
  167. case K.LEFT if (K.isDown(K.CTRL)):
  168. cursorIndex = getWordStart();
  169. case K.LEFT:
  170. if( cursorIndex > 0 )
  171. cursorIndex--;
  172. case K.RIGHT if (K.isDown(K.CTRL)):
  173. cursorIndex = getWordEnd();
  174. case K.RIGHT:
  175. if( cursorIndex < text.length )
  176. cursorIndex++;
  177. case K.HOME:
  178. if( multiline ) {
  179. var currentLine = getCurrentLine();
  180. cursorIndex = currentLine.startIndex;
  181. } else cursorIndex = 0;
  182. case K.END:
  183. if( multiline ) {
  184. var currentLine = getCurrentLine();
  185. cursorIndex = currentLine.startIndex + currentLine.value.length - 1;
  186. } else cursorIndex = text.length;
  187. case K.BACKSPACE, K.DELETE if( selectionRange != null ):
  188. if( !canEdit ) return;
  189. beforeChange();
  190. cutSelection();
  191. onChange();
  192. case K.DELETE:
  193. if( cursorIndex < text.length && canEdit ) {
  194. beforeChange();
  195. var end = K.isDown(K.CTRL) ? getWordEnd() : cursorIndex + 1;
  196. text = text.substr(0, cursorIndex) + text.substr(end);
  197. onChange();
  198. }
  199. case K.BACKSPACE:
  200. if( cursorIndex > 0 && canEdit ) {
  201. beforeChange();
  202. var end = cursorIndex;
  203. cursorIndex = K.isDown(K.CTRL) ? getWordStart() : cursorIndex - 1;
  204. text = text.substr(0, cursorIndex) + text.substr(end);
  205. onChange();
  206. }
  207. case K.ESCAPE:
  208. cursorIndex = -1;
  209. interactive.blur();
  210. return;
  211. case K.ENTER, K.NUMPAD_ENTER:
  212. if(!multiline) {
  213. cursorIndex = -1;
  214. interactive.blur();
  215. return;
  216. } else {
  217. beforeChange();
  218. if( selectionRange != null )
  219. cutSelection();
  220. text = text.substr(0, cursorIndex) + '\n' + text.substr(cursorIndex);
  221. cursorIndex++;
  222. onChange();
  223. }
  224. case K.Z if( K.isDown(K.CTRL) ):
  225. if( undo.length > 0 && canEdit ) {
  226. redo.push(curHistoryState());
  227. setState(undo.pop());
  228. onChange();
  229. }
  230. return;
  231. case K.Y if( K.isDown(K.CTRL) ):
  232. if( redo.length > 0 && canEdit ) {
  233. undo.push(curHistoryState());
  234. setState(redo.pop());
  235. onChange();
  236. }
  237. return;
  238. case K.A if (K.isDown(K.CTRL)):
  239. if (text != "") {
  240. cursorIndex = text.length;
  241. selectionRange = {start: 0, length: text.length};
  242. selectionSize = 0;
  243. }
  244. return;
  245. case K.C if (K.isDown(K.CTRL)):
  246. if( text != "" && selectionRange != null ) {
  247. hxd.System.setClipboardText(text.substr(selectionRange.start, selectionRange.length));
  248. }
  249. case K.X if (K.isDown(K.CTRL)):
  250. if( text != "" && selectionRange != null ) {
  251. if(hxd.System.setClipboardText(text.substr(selectionRange.start, selectionRange.length))) {
  252. if( !canEdit ) return;
  253. beforeChange();
  254. cutSelection();
  255. onChange();
  256. }
  257. }
  258. case K.V if (K.isDown(K.CTRL)):
  259. if( !canEdit ) return;
  260. var t = hxd.System.getClipboardText();
  261. if( t != null && t.length > 0 ) {
  262. beforeChange();
  263. if( selectionRange != null )
  264. cutSelection();
  265. text = text.substr(0, cursorIndex) + t + text.substr(cursorIndex);
  266. cursorIndex += t.length;
  267. onChange();
  268. }
  269. default:
  270. if( e.kind == EKeyDown )
  271. return;
  272. if( e.charCode != 0 && canEdit ) {
  273. if( !font.hasChar(e.charCode) ) return; // don't allow chars not supported by font
  274. beforeChange();
  275. if( selectionRange != null )
  276. cutSelection();
  277. text = text.substr(0, cursorIndex) + String.fromCharCode(e.charCode) + text.substr(cursorIndex);
  278. cursorIndex++;
  279. onChange();
  280. }
  281. }
  282. cursorBlink = 0.;
  283. if( K.isDown(K.SHIFT) && text == oldText ) {
  284. if( cursorIndex == oldIndex ) return;
  285. if( selectionRange == null )
  286. selectionRange = oldIndex < cursorIndex ? { start : oldIndex, length : cursorIndex - oldIndex } : { start : cursorIndex, length : oldIndex - cursorIndex };
  287. else if( oldIndex == selectionRange.start ) {
  288. selectionRange.length += oldIndex - cursorIndex;
  289. selectionRange.start = cursorIndex;
  290. } else
  291. selectionRange.length += cursorIndex - oldIndex;
  292. if( selectionRange.length == 0 )
  293. selectionRange = null;
  294. else if( selectionRange.length < 0 ) {
  295. selectionRange.start += selectionRange.length;
  296. selectionRange.length = -selectionRange.length;
  297. }
  298. selectionSize = 0;
  299. } else
  300. selectionRange = null;
  301. }
  302. function cutSelection() {
  303. if(selectionRange == null) return false;
  304. cursorIndex = selectionRange.start;
  305. var end = cursorIndex + selectionRange.length;
  306. text = text.substr(0, cursorIndex) + text.substr(end);
  307. selectionRange = null;
  308. return true;
  309. }
  310. function getWordEnd() {
  311. var len = text.length;
  312. if (cursorIndex >= len) {
  313. return cursorIndex;
  314. }
  315. var charset = hxd.Charset.getDefault();
  316. var ret = cursorIndex;
  317. while (ret < len && charset.isSpace(StringTools.fastCodeAt(text, ret))) ret++;
  318. while (ret < len && !charset.isSpace(StringTools.fastCodeAt(text, ret))) ret++;
  319. return ret;
  320. }
  321. function getWordStart() {
  322. if (cursorIndex <= 0) {
  323. return cursorIndex;
  324. }
  325. var charset = hxd.Charset.getDefault();
  326. var ret = cursorIndex;
  327. while (ret > 0 && charset.isSpace(StringTools.fastCodeAt(text, ret - 1))) ret--;
  328. while (ret > 0 && !charset.isSpace(StringTools.fastCodeAt(text, ret - 1))) ret--;
  329. return ret;
  330. }
  331. function moveCursorVertically(yDiff: Int){
  332. if( !multiline || yDiff == 0)
  333. return;
  334. var lines = [];
  335. var cursorLineIndex = -1, currLineIndex = 0, currIndex = 0;
  336. for( line in getAllLines() ) {
  337. lines.push( { line: line, startIndex: currIndex } );
  338. var prevIndex = currIndex;
  339. currIndex += line.length;
  340. if( cursorIndex > prevIndex && cursorIndex < currIndex )
  341. cursorLineIndex = currLineIndex;
  342. currLineIndex++;
  343. }
  344. if (cursorLineIndex == -1)
  345. return;
  346. var destinationIndex = hxd.Math.iclamp(cursorLineIndex + yDiff, 0, lines.length);
  347. if (destinationIndex == cursorLineIndex)
  348. return;
  349. var current = lines[cursorLineIndex];
  350. var xOffset = 0.;
  351. var prevCC: Null<Int> = null;
  352. var cI = 0;
  353. while( current.startIndex + cI < cursorIndex) {
  354. var cc = current.line.charCodeAt(cI);
  355. var c = font.getChar(cc);
  356. xOffset += c.width + c.getKerningOffset(prevCC) + letterSpacing;
  357. prevCC = cc;
  358. cI++;
  359. }
  360. var destination = lines[destinationIndex];
  361. var currOffset = 0.;
  362. prevCC = null;
  363. for( cI in 0...destination.line.length ) {
  364. var cc = destination.line.charCodeAt(cI);
  365. var c = font.getChar(cc);
  366. var newCurrOffset = currOffset + c.width + c.getKerningOffset(prevCC) + letterSpacing;
  367. if( newCurrOffset > xOffset ) {
  368. cursorIndex = destination.startIndex + cI + 1;
  369. if( xOffset - currOffset < newCurrOffset - xOffset )
  370. cursorIndex--;
  371. return;
  372. }
  373. currOffset = newCurrOffset;
  374. prevCC = cc;
  375. }
  376. cursorIndex = destination.startIndex + destination.line.length;
  377. }
  378. function setState(h:TextHistoryElement) {
  379. text = h.t;
  380. cursorIndex = h.c;
  381. selectionRange = h.sel;
  382. if( selectionRange != null )
  383. cursorIndex = selectionRange.start + selectionRange.length;
  384. }
  385. function curHistoryState() : TextHistoryElement {
  386. return { t : text, c : cursorIndex, sel : selectionRange == null ? null : { start : selectionRange.start, length : selectionRange.length } };
  387. }
  388. function beforeChange() {
  389. var t = haxe.Timer.stamp();
  390. if( t - lastChange < 1 ) {
  391. lastChange = t;
  392. return;
  393. }
  394. lastChange = t;
  395. undo.push(curHistoryState());
  396. redo = [];
  397. while( undo.length > maxHistorySize ) undo.shift();
  398. }
  399. function getAllLines() {
  400. var lines = this.text.split('\n');
  401. var finalLines : Array<String> = [];
  402. for(l in lines) {
  403. var splitText = splitText(l).split('\n');
  404. finalLines = finalLines.concat(splitText);
  405. }
  406. for(i in 0...finalLines.length) {
  407. finalLines[i] += '\n';
  408. }
  409. return finalLines;
  410. }
  411. function getCurrentLine() : {value: String, startIndex: Int} {
  412. var lines = getAllLines();
  413. var currIndex = 0;
  414. for( i in 0...lines.length ) {
  415. var newCurrIndex = currIndex + lines[i].length;
  416. if( cursorIndex < newCurrIndex )
  417. return { value: lines[i], startIndex: currIndex };
  418. currIndex = newCurrIndex;
  419. }
  420. return { value: '', startIndex: -1 };
  421. }
  422. function getCursorXOffset() {
  423. var lines = getAllLines();
  424. var offset = cursorIndex;
  425. var currLine = getCurrentLine().value;
  426. var currIndex = 0;
  427. for(i in 0...lines.length) {
  428. currIndex += lines[i].length;
  429. if(cursorIndex < currIndex) {
  430. break;
  431. } else {
  432. offset -= lines[i].length;
  433. }
  434. }
  435. return calcTextWidth(currLine.substr(0, offset));
  436. }
  437. function getCursorYOffset() {
  438. // return 0.0;
  439. var lines = getAllLines();
  440. var currIndex = 0;
  441. var lineNum = 0;
  442. for(i in 0...lines.length) {
  443. currIndex += lines[i].length;
  444. if(cursorIndex < currIndex) {
  445. lineNum = i;
  446. break;
  447. }
  448. }
  449. return lineNum * font.lineHeight;
  450. }
  451. /**
  452. Returns a String representing currently selected text area or `null` if no text is selected.
  453. **/
  454. public function getSelectedText() : String {
  455. return selectionRange == null ? null : text.substr(selectionRange.start, selectionRange.length);
  456. }
  457. override function set_text(t:String) {
  458. super.set_text(t);
  459. if( cursorIndex > t.length ) cursorIndex = t.length;
  460. return t;
  461. }
  462. override function set_font(f) {
  463. super.set_font(f);
  464. cursorTile = h2d.Tile.fromColor(0xFFFFFF, 1, font.size);
  465. cursorTile.dy = 2;
  466. selectionTile = h2d.Tile.fromColor(0x3399FF, 0, hxd.Math.ceil(font.lineHeight));
  467. return f;
  468. }
  469. override function initGlyphs(text:String, rebuild = true):Void {
  470. super.initGlyphs(text, rebuild);
  471. if( rebuild ) {
  472. this.calcWidth += cursorTile.width; // cursor end pos
  473. if( inputWidth != null && this.calcWidth > inputWidth ) this.calcWidth = inputWidth;
  474. }
  475. }
  476. function textPos( x : Float, y : Float ) {
  477. x += scrollX;
  478. var lineIndex = Math.floor(y / font.lineHeight);
  479. var lines = getAllLines();
  480. lineIndex = hxd.Math.iclamp(lineIndex, 0, lines.length - 1);
  481. var selectedLine = lines[lineIndex];
  482. var pos = 0;
  483. for(i in 0...lineIndex) {
  484. pos += lines[i].length;
  485. }
  486. var linePos = 0;
  487. while( linePos < selectedLine.length ) {
  488. if( calcTextWidth(selectedLine.substr(0,linePos+1)) > x ) {
  489. pos++;
  490. break;
  491. }
  492. pos++;
  493. linePos++;
  494. }
  495. return pos - 1;
  496. }
  497. override function sync(ctx) {
  498. var lines = getAllLines();
  499. interactive.width = (inputWidth != null ? inputWidth : maxWidth != null ? Math.ceil(maxWidth) : textWidth);
  500. interactive.height = font.lineHeight * lines.length;
  501. super.sync(ctx);
  502. }
  503. override function draw(ctx:RenderContext) {
  504. if( inputWidth != null ) {
  505. var h = localToGlobal(new h2d.col.Point(inputWidth, font.lineHeight));
  506. ctx.clipRenderZone(absX, absY, h.x - absX, h.y - absY);
  507. }
  508. if( cursorIndex >= 0 && (text != cursorText || cursorIndex != cursorXIndex) ) {
  509. if( cursorIndex > text.length ) cursorIndex = text.length;
  510. cursorText = text;
  511. cursorXIndex = cursorIndex;
  512. cursorX = getCursorXOffset();
  513. cursorY = getCursorYOffset();
  514. if( inputWidth != null && cursorX - scrollX >= inputWidth )
  515. scrollX = cursorX - inputWidth + 1;
  516. else if( cursorX < scrollX && cursorIndex > 0 )
  517. scrollX = cursorX - hxd.Math.imin(inputWidth, Std.int(cursorX));
  518. else if( cursorX < scrollX )
  519. scrollX = cursorX;
  520. }
  521. absX -= scrollX * matA;
  522. absY -= scrollX * matC;
  523. if( selectionRange != null ) {
  524. var lines = getAllLines();
  525. var lineOffset = 0;
  526. for(i in 0...lines.length) {
  527. var line = lines[i];
  528. var selEnd = line.length;
  529. if(selectionRange.start > lineOffset + line.length || selectionRange.start + selectionRange.length < lineOffset) {
  530. lineOffset += line.length;
  531. continue;
  532. }
  533. var selStart = Math.floor(Math.max(0, selectionRange.start - lineOffset));
  534. var selEnd = Math.floor(Math.min(line.length - selStart, selectionRange.length + selectionRange.start - lineOffset - selStart));
  535. selectionPos = calcTextWidth(line.substr(0, selStart));
  536. selectionSize = calcTextWidth(line.substr(selStart, selEnd));
  537. if( selectionRange.start + selectionRange.length == text.length ) selectionSize += cursorTile.width; // last pixel
  538. selectionTile.dx += selectionPos;
  539. selectionTile.dy += i * font.lineHeight;
  540. selectionTile.width += selectionSize;
  541. emitTile(ctx, selectionTile);
  542. selectionTile.dx -= selectionPos;
  543. selectionTile.dy -= i * font.lineHeight;
  544. selectionTile.width -= selectionSize;
  545. lineOffset += line.length;
  546. }
  547. }
  548. super.draw(ctx);
  549. absX += scrollX * matA;
  550. absY += scrollX * matC;
  551. if( cursorIndex >= 0 ) {
  552. cursorBlink += ctx.elapsedTime;
  553. if( cursorBlink % (cursorBlinkTime * 2) < cursorBlinkTime ) {
  554. cursorTile.dx += cursorX - scrollX;
  555. cursorTile.dy += cursorY;
  556. emitTile(ctx, cursorTile);
  557. cursorTile.dx -= cursorX - scrollX;
  558. cursorTile.dy -= cursorY;
  559. }
  560. }
  561. if( inputWidth != null )
  562. ctx.popRenderZone();
  563. }
  564. /**
  565. Sets focus on this `TextInput`.
  566. **/
  567. public function focus() {
  568. interactive.focus();
  569. if( cursorIndex < 0 ) {
  570. cursorIndex = 0;
  571. if( text != "" ) selectionRange = { start : 0, length : text.length };
  572. }
  573. }
  574. /**
  575. Checks if TextInput is currently focused.
  576. **/
  577. public function hasFocus() {
  578. return interactive.hasFocus();
  579. }
  580. /**
  581. Delegate of underlying `Interactive.onOut`.
  582. **/
  583. public dynamic function onOut(e:hxd.Event) {
  584. }
  585. /**
  586. Delegate of underlying `Interactive.onOver`.
  587. **/
  588. public dynamic function onOver(e:hxd.Event) {
  589. }
  590. /**
  591. Delegate of underlying `Interactive.onMove`.
  592. **/
  593. public dynamic function onMove(e:hxd.Event) {
  594. }
  595. /**
  596. Delegate of underlying `Interactive.onClick`.
  597. **/
  598. public dynamic function onClick(e:hxd.Event) {
  599. }
  600. /**
  601. Delegate of underlying `Interactive.onPush`.
  602. **/
  603. public dynamic function onPush(e:hxd.Event) {
  604. }
  605. /**
  606. Delegate of underlying `Interactive.onRelease`.
  607. **/
  608. public dynamic function onRelease(e:hxd.Event) {
  609. }
  610. /**
  611. Delegate of underlying `Interactive.onKeyDown`.
  612. **/
  613. public dynamic function onKeyDown(e:hxd.Event) {
  614. }
  615. /**
  616. Delegate of underlying `Interactive.onKeyUp`.
  617. **/
  618. public dynamic function onKeyUp(e:hxd.Event) {
  619. }
  620. /**
  621. Delegate of underlying `Interactive.onTextInput`.
  622. **/
  623. public dynamic function onTextInput(e:hxd.Event) {
  624. }
  625. /**
  626. Delegate of underlying `Interactive.onFocus`.
  627. **/
  628. public dynamic function onFocus(e:hxd.Event) {
  629. }
  630. /**
  631. Delegate of underlying `Interactive.onFocusLost`.
  632. **/
  633. public dynamic function onFocusLost(e:hxd.Event) {
  634. }
  635. /**
  636. Sent when user modifies TextInput contents.
  637. **/
  638. public dynamic function onChange() {
  639. }
  640. override function drawRec(ctx:RenderContext) {
  641. var old = interactive.visible;
  642. var oldC = interactive.parentContainer;
  643. // workaround @:bypassAccessor not working by setting parentContainer=null
  644. // prevent domkit style to be updated
  645. interactive.parentContainer = null;
  646. interactive.visible = false;
  647. interactive.parentContainer = oldC;
  648. interactive.draw(ctx);
  649. super.drawRec(ctx);
  650. interactive.parentContainer = null;
  651. interactive.visible = old;
  652. interactive.parentContainer = oldC;
  653. }
  654. function get_backgroundColor() return interactive.backgroundColor;
  655. function set_backgroundColor(v) return interactive.backgroundColor = v;
  656. }