@@ -60,27 +60,27 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
6060
6161 var selected = selectable && focused ;
6262 if (autoAlpha ) {
63- if (selectable ) {
63+ if (selectable ) {
6464 alpha = label .alpha = 1 ;
6565 } else {
6666 alpha = label .alpha = 0.4 ;
6767 }
6868 }
6969
7070 var off = multiline ? 4 : ((bHeight - label .height ) / 2 );
71- label .follow (this , label .autoSize ? (bWidth - label .textField .width )/ 2 : 4 , off );
71+ label .follow (this , label .autoSize ? (bWidth - label .textField .width ) / 2 : 4 , off );
7272 framesOffset = (selected ? 18 : (hovered ? 9 : 0 ));
7373 @:privateAccess {
7474 if (selected ) {
7575 __wasFocused = true ;
7676 caretSpr .alpha = (FlxG .game .ticks % 666 ) >= 333 ? 1 : 0 ;
7777
78- var curPos = switch (position ) {
78+ var curPos = switch (position ) {
7979 case 0 :
8080 FlxPoint .get (0 , 0 );
8181 default :
8282 if (position >= label .text .length ) {
83- label .textField .__getCharBoundaries (label .text .length - 1 , cacheRect );
83+ label .textField .__getCharBoundaries (label .text .length - 1 , cacheRect );
8484 FlxPoint .get (cacheRect .x + cacheRect .width , cacheRect .y );
8585 } else {
8686 label .textField .__getCharBoundaries (position , cacheRect );
@@ -100,60 +100,160 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
100100 }
101101 }
102102
103+ private static var seperators : Array <String > = [
104+ " " , " \n " , " \t " , " \r " , " -" , " _" , " =" , " +" , " /" , " \\ " , " |" , " ," , " ." , " ;" , " :" , " !" , " ?" , " @" , " #" , " $" , " %" , " ^" , " &" , " *" , " (" , " )" , " [" , " ]" , " {" ,
105+ " }" ,
106+ ];
107+
108+ public inline static function isSeperator (char : String ): Bool
109+ return seperators .contains (char );
110+
111+ public inline static function findWholeWord (text : String , pos : Int , ? isDelete : Bool = false ): Null <Array <Int >> {
112+ if (text .length == 0 )
113+ return null ;
114+
115+ var start = pos ;
116+ var end = pos ;
117+
118+ while (! isDelete && start > 0 && ! isSeperator (text .charAt (start - 1 )))
119+ start -- ;
120+
121+ while (end < text .length && ! isSeperator (text .charAt (end )))
122+ end ++ ;
123+
124+ if (end == pos && isSeperator (text .charAt (end - 1 )))
125+ start -- ;
126+
127+ return [start , end ];
128+ }
129+
103130 public function onKeyDown (e : KeyCode , modifier : KeyModifier ) {
104- switch (e ) {
131+ switch (e ) {
105132 case RETURN :
106133 focused = false ;
107- if (onChange != null ) onChange (label .text );
134+ if (onChange != null )
135+ onChange (label .text );
108136 case LEFT :
137+ if (modifier .ctrlKey ) {
138+ if (position == 0 )
139+ return ;
140+
141+ var wordBounds = findWholeWord (label .text , position );
142+ if (wordBounds != null ) {
143+ position = position == wordBounds [0 ] ? wordBounds [0 ] - 1 : wordBounds [0 ];
144+ } else {
145+ position = 0 ;
146+ }
147+
148+ return ;
149+ }
150+
109151 changeSelection (- 1 );
110152 case RIGHT :
153+ if (modifier .ctrlKey ) {
154+ if (position == label .text .length )
155+ return ;
156+
157+ var wordBounds = findWholeWord (label .text , position );
158+ if (wordBounds != null ) {
159+ position = position == wordBounds [1 ] ? wordBounds [1 ] + 1 : wordBounds [1 ];
160+ } else {
161+ position = label .text .length ;
162+ }
163+
164+ return ;
165+ }
166+
111167 changeSelection (1 );
112168 case BACKSPACE :
113169 FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_TEXTREMOVE_SOUND ));
170+
171+ if (modifier .ctrlKey ) {
172+ var wordBounds = findWholeWord (label .text , position );
173+ if (wordBounds != null ) {
174+ label .text = label .text .substr (0 , wordBounds [0 ]) + label .text .substr (wordBounds [1 ]);
175+ position = wordBounds [0 ];
176+ }
177+ return ;
178+ }
179+
114180 if (position > 0 ) {
115- label .text = label .text .substr (0 , position - 1 ) + label .text .substr (position );
181+ label .text = label .text .substr (0 , position - 1 ) + label .text .substr (position );
116182 changeSelection (- 1 );
117183 }
184+ case DELETE :
185+ FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_TEXTREMOVE_SOUND ));
186+
187+ if (modifier .ctrlKey ) {
188+ var wordBounds = findWholeWord (label .text , position , true );
189+ if (wordBounds != null ) {
190+ label .text = label .text .substr (0 , wordBounds [0 ]) + label .text .substr (wordBounds [1 ]);
191+ position = wordBounds [0 ];
192+ }
193+ return ;
194+ }
195+
196+ if (position < label .text .length ) {
197+ label .text = label .text .substr (0 , position ) + label .text .substr (position + 1 );
198+ }
118199 case HOME :
119200 position = 0 ;
120201 case END :
121202 position = label .text .length ;
122203 case V :
123- FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_TEXTTYPE_SOUND ));
204+ FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_PASTE_SOUND ));
124205 // Hey lj here, fixed copying because before we checked if the modifier was left or right ctrl
125206 // but somehow it gave a int outside of the KeyModifier's range :sob:
126207 // apparently there is a boolean that just checks for you. yw :D
127208
128209 // if we are not holding ctrl, ignore
129- if (! modifier .ctrlKey ) return ;
210+ if (! modifier .ctrlKey )
211+ return ;
130212 // we pasting
131213 var data : String = Clipboard .generalClipboard .getData (TEXT_FORMAT );
132- if (data != null ) onTextInput (data );
214+ if (data != null )
215+ onTextInput (data );
133216 case C :
134- FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_TEXTTYPE_SOUND ));
217+ FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_COPY_SOUND ));
135218 // if we are not holding ctrl, ignore
136- if (! modifier .ctrlKey ) return ;
219+ if (! modifier .ctrlKey )
220+ return ;
137221
138222 // copying
139223 Clipboard .generalClipboard .setData (TEXT_FORMAT , label .text );
224+ case X :
225+ FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_CUT_SOUND ));
226+
227+ // if we are not holding ctrl, ignore
228+ if (! modifier .ctrlKey )
229+ return ;
230+
231+ // cutting
232+ Clipboard .generalClipboard .setData (TEXT_FORMAT , label .text );
233+ position = 0 ;
234+ label .text = " " ;
140235 default :
236+ if (modifier .ctrlKey || modifier .altKey || modifier .shiftKey )
237+ return ;
238+
141239 FlxG .sound .play (Paths .sound (Flags .DEFAULT_EDITOR_TEXTTYPE_SOUND ));
142240 }
143241 }
144242
145243 public function changeSelection (change : Int ) {
146- position = FlxMath .wrap (position + change , 0 , label .text .length );
244+ position = Std . int ( FlxMath .bound (position + change , 0 , label .text .length ) );
147245 }
246+
148247 public function onKeyUp (e : KeyCode , modifier : KeyModifier ) {}
149248
150249 public function onTextInput (text : String ): Void {
151250 label .text = label .text .substr (0 , position ) + text + label .text .substr (position );
152251 position + = text .length ;
153252 }
253+
154254 // untested, but this should be a fix for if the text wont type
155255 public function onTextEdit (text : String , start : Int , end : Int ): Void {
156256 label .text = label .text .substr (0 , position ) + text + label .text .substr (position );
157257 position + = text .length ;
158258 }
159- }
259+ }
0 commit comments