1 module ws.gui.inputField; 2 3 import 4 ws.event, 5 ws.io, 6 ws.time, 7 ws.math.math, 8 ws.gl.draw, 9 ws.gui.base, 10 ws.gui.text; 11 12 13 class InputField: Text { 14 15 bool hasFocus = false; 16 Event!string onEnter; 17 18 string error; 19 double errorTime; 20 bool blockChar; 21 22 this(){ 23 super(); 24 setCursor(Mouse.cursor.text); 25 onEnter = new Event!string; 26 } 27 28 override void onKeyboard(dchar c){ 29 if(hasFocus && !blockChar){ 30 text ~= c; 31 blockChar = false; 32 } 33 } 34 35 override void onKeyboard(Keyboard.key key, bool pressed){ 36 if(!pressed) 37 return; 38 blockChar = true; 39 switch(key){ 40 case Keyboard.backspace: 41 if(text.cursor.prev){ 42 auto toDelete = text.cursor.prev; 43 text.cursor.prev = toDelete.prev; 44 text.remove(toDelete); 45 text.update(text.cursor.prev); 46 } 47 break; 48 49 case Keyboard.del: 50 if(text.cursor.next){ 51 auto toDelete = text.cursor.next; 52 text.cursor.next = toDelete.next; 53 text.remove(toDelete); 54 text.update(text.cursor.prev); 55 } 56 break; 57 58 case Keyboard.enter: 59 try 60 onEnter(text.toString()); 61 catch(InputException e){ 62 error = e.msg; 63 errorTime = now; 64 } 65 break; 66 67 case Keyboard.right: 68 if(Keyboard.get(Keyboard.control)) 69 while(text.cursor.next && text.cursor.next.get().c != ' ') 70 ++text.cursor; 71 else 72 ++text.cursor; 73 break; 74 75 case Keyboard.left: 76 if(Keyboard.get(Keyboard.control)) 77 while(text.cursor.prev && text.cursor.prev.get().c != ' ') 78 --text.cursor; 79 else 80 --text.cursor; 81 break; 82 83 default: 84 blockChar = false; 85 break; 86 } 87 88 } 89 90 91 override void onKeyboardFocus(bool hasFocus){ 92 this.hasFocus = hasFocus; 93 } 94 95 96 override void onDraw(){ 97 super.onDraw(); 98 auto color = style.fg.normal; 99 if(hasFocus){ 100 Draw.setColor(color[0], color[1], color[2], color[3]*clamp!float(sin(now*PI*2) + 0.5, 0, 1)); 101 if(!text.cursor.prev) 102 Draw.line(pos[0] + 4, pos[1] + 3, pos[0] + 4, pos[1] + size[1]-2); 103 else { 104 auto lpos = 105 pos.a + text.cursor.prev.get().pos 106 + [text.cursor.prev.get().glyph.advance+2, -2]; 107 draw.line(lpos, lpos.a + [0, size[1]-4]); 108 } 109 } 110 auto t = now; 111 if(errorTime+2 > t){ 112 auto alpha = clamp!float(errorTime+2 - t, 0, 1)/1; 113 Draw.setColor(1,0,0,alpha); 114 Draw.rect(pos, size); 115 Draw.setFont(font); 116 Draw.setColor(1,1,1,alpha); 117 Draw.text(pos.a + [2, cast(int)(font.size*0.6)], error); 118 } 119 } 120 121 122 } 123 124 125 class InputException: Exception { 126 InputField text; 127 this(InputField t, string msg, string file = __FILE__, size_t line = __LINE__){ 128 text = t; 129 super(msg, null, file, line); 130 } 131 this(InputField t, string msg, Exception cause, string file = __FILE__, size_t line = __LINE__){ 132 text = t; 133 super(msg, cause, file, line); 134 } 135 }