@@ -17,8 +17,10 @@ aligment(_aligment),
1717textColor(_color),
1818font(window.createFontCopy(Fonts::Main, _height)) {
1919 // Setting rects
20- rect = {0 , window.getHeight ()*_Y-_height/2 -1 , 0 , 0 };
21- caretRect = {0 , window.getHeight ()*_Y-_height/2 -1 , 2 , _height*1 .3f };
20+ rect = {0 , window.getHeight ()*_Y-_height/2 , 0 , 0 };
21+ caretRect = {0 , window.getHeight ()*_Y-_height/2 , 2 , 0 };
22+ inversedRectDest.y = window.getHeight ()*_Y-_height/2 ;
23+ inversedRectSrc.y = 0 ;
2224
2325 // Copying text to caret
2426 length = strlen (_text);
@@ -28,104 +30,88 @@ font(window.createFontCopy(Fonts::Main, _height)) {
2830 // Creating first texture, if there was any text
2931 if (length) {
3032 updateTexture ();
33+ } else {
34+ // Create empty texture
35+ texture = window.createTexture (font, " 1" , textColor);
36+ inverseTexture = window.createTexture (font, " 1" , textColor);
3137 }
38+ // Setting height of text
39+ inversedRectDest.h = inversedRectSrc.h = caretRect.h = rect.h = texture->h ;
3240}
3341
3442template <unsigned bufferSize>
3543GUI::TypeField<bufferSize>::~TypeField () {
3644 // Clearing rest texture
3745 SDL_DestroyTexture (texture);
46+ SDL_DestroyTexture (inverseTexture);
3847
3948 // Clearing font
4049 TTF_CloseFont (font);
4150}
4251
43- // Creating new texture
4452template <unsigned bufferSize>
4553void GUI::TypeField<bufferSize>::updateTexture() {
46- // Clearing previous
47- if (texture) {
48- SDL_DestroyTexture (texture);
49- }
50-
5154 // Checking, if string exsist
5255 if (length) {
53- // Creating main surface from all text
54- SDL_Surface* mainSurface = TTF_RenderText_Shaded (font, buffer, length, textColor, WHITE);
55-
56- // Inversing selected part of text, if need
57- if (selectLength) {
58- SDL_Surface* inverseSurface = nullptr ;
59- SDL_Rect inverseRect = {0 , 0 , 0 , 0 };
60-
61- if (selectLength > 0 ) {
62- if (caret == 0 ) {
63- inverseRect.x = 0 ;
64- } else {
65- TTF_GetStringSize (font, buffer, caret, &inverseRect.x , nullptr );
66- }
67- inverseSurface = TTF_RenderText_Shaded (font, buffer + caret, selectLength, textColor, GREY);
68- } else {
69- if (-selectLength == caret) {
70- inverseRect.x = 0 ;
71- } else {
72- TTF_GetStringSize (font, buffer, caret + selectLength, &inverseRect.x , nullptr );
73- }
74- inverseSurface = TTF_RenderText_Shaded (font, buffer + caret + selectLength, -selectLength, textColor, GREY);
75- }
76- // Blitting inverse suface on main
77- inverseRect.w = inverseSurface->w ;
78- inverseRect.h = inverseSurface->h ;
79-
80- // Filling area with black color
81- SDL_BlitSurface (inverseSurface, NULL , mainSurface, &inverseRect);
82- SDL_DestroySurface (inverseSurface);
56+ // Clearing previous
57+ if (texture) {
58+ SDL_DestroyTexture (texture);
59+ SDL_DestroyTexture (inverseTexture);
8360 }
84- // Updating texture
61+
62+ // Creating main text texture
63+ SDL_Surface* mainSurface = TTF_RenderText_Shaded (font, buffer, length, textColor, WHITE);
8564 texture = window.createTextureAndFree (mainSurface);
86- SDL_DestroySurface (mainSurface);
65+
66+ // Create inversed text texture
67+ SDL_Surface* inversedSurface = TTF_RenderText_Shaded (font, buffer, length, WHITE, textColor);
68+ inverseTexture = window.createTextureAndFree (inversedSurface);
8769
8870 // Resetting place of text with saving aligment
8971 rect.w = texture->w ;
90- rect.h = texture->h ;
9172 rect.x = SDL_floorf (posX - rect.w * (unsigned )aligment / 2 );
92-
93- // Update caret place
94- if (caret) {
95- int caretX = 0 ;
96- TTF_GetStringSize (font, buffer, caret, &caretX, nullptr );
97- caretRect.x = rect.x + caretX - 1 ;
98- } else {
99- caretRect.x = rect.x - 1 ;
100- }
73+ updateSelected ();
10174 } else {
10275 caretRect.x = posX - 1 ;
10376 }
10477}
10578
106-
107- // Select last letter to create writing symbol
10879template <unsigned bufferSize>
109- void GUI::TypeField<bufferSize>::select(float _mouseX) {
110- // Resetting swapping caret
111- showCaret = true ;
112- selectLength = 0 ;
113-
114- // Getting current mouse position at text
115- if (length) {
116- TTF_MeasureString (font, buffer, length, _mouseX-rect.x , NULL , &caret);
80+ void GUI::TypeField<bufferSize>::updateSelected() {
81+ // Update caret place
82+ if (caret) {
83+ int caretX = 0 ;
84+ TTF_GetStringSize (font, buffer, caret, &caretX, nullptr );
85+ caretRect.x = rect.x + caretX - 1 ;
11786 } else {
118- caret = 0 ;
87+ caretRect. x = rect. x - 1 ;
11988 }
12089
121- // Showing caret
122- updateTexture ();
123-
124- // Starting using keyboard
125- window.startTextInput ();
90+ // Inversing selected part of text, if need
91+ if (selectLength) {
92+ // Getting start position and length of selected part
93+ int startPosition, length;
94+ if (selectLength > 0 ) {
95+ if (caret == 0 ) {
96+ startPosition = 0 ;
97+ } else {
98+ TTF_GetStringSize (font, buffer, caret, &startPosition, nullptr );
99+ }
100+ TTF_GetStringSize (font, buffer+caret, selectLength, &length, nullptr );
101+ } else {
102+ if (-selectLength == caret) {
103+ startPosition = 0 ;
104+ } else {
105+ TTF_GetStringSize (font, buffer, caret + selectLength, &startPosition, nullptr );
106+ }
107+ TTF_GetStringSize (font, buffer+caret+selectLength, -selectLength, &length, nullptr );
108+ }
109+ inversedRectSrc.x = startPosition;
110+ inversedRectDest.x = inversedRectSrc.x + rect.x ;
111+ inversedRectDest.w = inversedRectSrc.w = length;
112+ }
126113}
127114
128- // Write need string to buffer with ability to clear source
129115template <unsigned bufferSize>
130116void GUI::TypeField<bufferSize>::writeString(const char * _str) {
131117 if (selected) {
@@ -157,7 +143,6 @@ void GUI::TypeField<bufferSize>::writeString(const char* _str) {
157143 }
158144}
159145
160- // Getting clippboard content
161146template <unsigned bufferSize>
162147void GUI::TypeField<bufferSize>::writeClipboard() {
163148 // Getting and writing clipboard to caret
@@ -166,7 +151,6 @@ void GUI::TypeField<bufferSize>::writeClipboard() {
166151 SDL_free (clippboard);
167152}
168153
169- // Copying selected text to clipboard
170154template <unsigned bufferSize>
171155void GUI::TypeField<bufferSize>::copyToClipboard() {
172156 if (selectLength) {
@@ -199,7 +183,6 @@ void GUI::TypeField<bufferSize>::deleteSelected() {
199183 }
200184}
201185
202- // Getting press of need KeyCode
203186template <unsigned bufferSize>
204187void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
205188 // Checking, if box selected
@@ -252,7 +235,8 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
252235 }
253236 selectLength = 0 ;
254237 }
255- break ;
238+ updateSelected ();
239+ return ;
256240
257241 case SDLK_RIGHT:
258242 if (keyMods & SDL_KMOD_SHIFT) {
@@ -270,7 +254,8 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
270254 }
271255 selectLength = 0 ;
272256 }
273- break ;
257+ updateSelected ();
258+ return ;
274259
275260 // Special keys for faster caret move
276261 case SDLK_END:
@@ -281,7 +266,8 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
281266 selectLength = 0 ;
282267 }
283268 caret = length;
284- break ;
269+ updateSelected ();
270+ return ;
285271
286272 case SDLK_HOME:
287273 case SDLK_PAGEUP:
@@ -291,7 +277,8 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
291277 selectLength = 0 ;
292278 }
293279 caret = 0 ;
294- break ;
280+ updateSelected ();
281+ return ;
295282
296283 // Clipboard
297284 case SDLK_PASTE:
@@ -310,19 +297,25 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
310297 case SDLK_V:
311298 if (keyMods & SDL_KMOD_CTRL) {
312299 writeClipboard ();
300+ } else {
301+ return ;
313302 }
314303 break ;
315304
316305 case SDLK_C:
317306 if (keyMods & SDL_KMOD_CTRL) {
318307 copyToClipboard ();
308+ } else {
309+ return ;
319310 }
320311 break ;
321312
322313 case SDLK_X:
323314 if (keyMods & SDL_KMOD_CTRL) {
324315 copyToClipboard ();
325316 deleteSelected ();
317+ } else {
318+ return ;
326319 }
327320 break ;
328321
@@ -341,23 +334,27 @@ void GUI::TypeField<bufferSize>::type(SDL_Keycode _code) {
341334 updateTexture ();
342335}
343336
344-
345337template <unsigned bufferSize>
346- bool GUI::TypeField<bufferSize>::click(const Mouse mouse) {
347- if (in (mouse)) {
338+ bool GUI::TypeField<bufferSize>::click(const Mouse _mouse) {
339+ if (in (_mouse)) {
340+ // Resetting values
348341 pressed = true ;
342+ showCaret = true ;
343+ selectLength = 0 ;
349344 if (!selected) {
345+ // Starting using keyboard
346+ window.startTextInput ();
350347 selected = true ;
351- select (mouse.getX ());
352- } else {
353- // Stoping entering any letters
354- window.stopTextInput ();
348+ }
355349
356- // Clearing caret
357- showCaret = false ;
358- selectLength = 0 ;
359- select (mouse.getX ());
350+ // Getting current mouse position at text
351+ if (length) {
352+ TTF_MeasureString (font, buffer, length, _mouse.getX ()-rect.x , NULL , &caret);
353+ } else {
354+ caret = 0 ;
360355 }
356+ // Showing caret
357+ updateSelected ();
361358 return false ;
362359 } else if (selected) {
363360 // Resetting selection
@@ -371,7 +368,7 @@ bool GUI::TypeField<bufferSize>::click(const Mouse mouse) {
371368 showCaret = false ;
372369 selectLength = 0 ;
373370
374- updateTexture ();
371+ updateSelected ();
375372
376373 // Return, that finish text input
377374 return true ;
@@ -395,7 +392,7 @@ void GUI::TypeField<bufferSize>::update(float _mouseX) {
395392 }
396393 selectLength += caret - measure;
397394 caret = measure;
398- updateTexture ();
395+ updateSelected ();
399396 }
400397 if (selected && getTime () > needSwapCaret) {
401398 // Inversing show state
@@ -408,8 +405,15 @@ void GUI::TypeField<bufferSize>::update(float _mouseX) {
408405
409406template <unsigned bufferSize>
410407void GUI::TypeField<bufferSize>::blit() const {
411- // Rendering text
412- window.blit (texture, rect);
408+ // Rendering main text
409+ if (length) {
410+ window.blit (texture, rect);
411+ }
412+
413+ // Rendering selection text (as reversed)
414+ if (selectLength) {
415+ window.blit (inverseTexture, &inversedRectDest, &inversedRectSrc);
416+ }
413417
414418 // Rendering caret
415419 if (showCaret) {
0 commit comments