1 module pixelperfectengine.concrete.popup.popuptextinput; 2 3 public import pixelperfectengine.concrete.popup.base; 4 5 /** 6 * Text input in pop-up fashion. 7 */ 8 public class PopUpTextInput : PopUpElement, TextInputListener { 9 protected bool enableEdit, insert; 10 protected size_t cursorPos; 11 protected int horizTextOffset, select; 12 public void delegate(Event ev) onTextInput; 13 14 public this(string source, Text text, Coordinate position){ 15 this.source = source; 16 this.text = text; 17 this.position = position; 18 enableEdit = true; 19 output = new BitmapDrawer(position.width, position.height); 20 inputhandler.startTextInput(this, false, position); 21 } 22 public override void draw(){ 23 StyleSheet ss = getStyleSheet(); 24 const Box mainPos = Box(0,0,position.width - 1, position.height - 1); 25 output.drawFilledBox(mainPos, ss.getColor("window")); 26 output.drawBox(mainPos, ss.getColor("windowascent")); 27 const int textPadding = getStyleSheet.drawParameters["TextSpacingSides"]; 28 Coordinate textPos = Coordinate(textPadding,(position.height / 2) - (text.font.size / 2) , 29 position.width,position.height - textPadding); 30 31 const int y = text.font.size; 32 //if(x > textPos.width ) xOffset = horizTextOffset; 33 //draw cursor 34 if(enableEdit) { 35 const int x0 = text.getWidth(0,cursorPos) + textPadding - horizTextOffset; 36 if(!insert){ 37 //output.drawLine(x0, x0, 2, 2 + y, getStyleSheet().getColor("selection")); 38 output.drawLine(Point(x0, 2), Point(x0, 2 + y), ss.getColor("selection")); 39 }else{ 40 const int x1 = cursorPos == text.charLength ? text.font.chars(' ').xadvance : 41 text.getWidth(cursorPos,cursorPos + 1); 42 //output.drawFilledRectangle(x0, x1 + x0, 2, 2 + y, getStyleSheet().getColor("selection")); 43 output.drawFilledBox(Box(x0, 2, x1, 2 + y), ss.getColor("selection")); 44 } 45 } 46 47 48 output.drawSingleLineText(textPos, text, horizTextOffset); 49 //parent.drawUpdate(this); 50 if(onDraw !is null){ 51 onDraw(); 52 } 53 } 54 private void deleteCharacter(size_t n){ 55 text.removeChar(n); 56 } 57 public void textInputEvent(uint timestamp, uint windowID, dstring text){ 58 for(int j ; j < text.length ; j++){ 59 this.text.insertChar(cursorPos++, text[j]); 60 } 61 const int textPadding = getStyleSheet().drawParameters["TextSpacingSides"]; 62 const Coordinate textPos = Coordinate(textPadding,(position.height / 2) - (this.text.font.size / 2) , 63 position.width,position.height - textPadding); 64 const int x = this.text.getWidth(), cursorPixelPos = this.text.getWidth(0, cursorPos); 65 if(x > textPos.width) { 66 if(cursorPos == this.text.text.length) { 67 horizTextOffset = x - textPos.width; 68 } else if(cursorPixelPos < horizTextOffset) { //Test for whether the cursor would fall out from the current text area 69 horizTextOffset = cursorPixelPos; 70 } else if(cursorPixelPos > horizTextOffset + textPos.width) { 71 horizTextOffset = horizTextOffset + textPos.width; 72 } 73 } 74 draw(); 75 } 76 /** 77 * Passes text editing events to the target, alongside with a window ID and a timestamp. 78 */ 79 public void textEditingEvent(uint timestamp, uint windowID, dstring text, int start, int length) { 80 for (int i ; i < length ; i++) { 81 this.text.overwriteChar(start + i, text[i]); 82 } 83 cursorPos = start + length; 84 } 85 /** 86 * Passes text input key events to the target, e.g. cursor keys. 87 */ 88 public void textInputKeyEvent(uint timestamp, uint windowID, TextInputKey key, ushort modifier = 0){ 89 switch(key){ 90 case TextInputKey.Escape: 91 inputhandler.stopTextInput(); 92 break; 93 case TextInputKey.Enter: 94 inputhandler.stopTextInput(); 95 //invokeActionEvent(new Event(source, null, null, null, text, text.length, EventType.TEXTINPUT)); 96 if(onTextInput !is null) 97 onTextInput(new Event(this, text, EventType.TextInput, SourceType.PopUpElement)); 98 break; 99 case TextInputKey.Backspace: 100 if(cursorPos > 0){ 101 deleteCharacter(cursorPos - 1); 102 cursorPos--; 103 draw(); 104 } 105 break; 106 case TextInputKey.Delete: 107 deleteCharacter(cursorPos); 108 draw(); 109 break; 110 case TextInputKey.CursorLeft: 111 if(cursorPos > 0){ 112 --cursorPos; 113 draw(); 114 } 115 break; 116 case TextInputKey.CursorRight: 117 if(cursorPos < text.charLength){ 118 ++cursorPos; 119 draw(); 120 } 121 break; 122 case TextInputKey.Insert: 123 insert = !insert; 124 draw(); 125 break; 126 case TextInputKey.Home: 127 cursorPos = 0; 128 draw(); 129 break; 130 case TextInputKey.End: 131 cursorPos = text.charLength; 132 draw(); 133 break; 134 default: 135 break; 136 137 } 138 } 139 public void dropTextInput(){ 140 parent.endPopUpSession(this); 141 142 } 143 public void initTextInput() { 144 } 145 }