33 procedure SendHogSpeech(s: shortstring); |
33 procedure SendHogSpeech(s: shortstring); |
34 procedure CopyToClipboard(var newContent: shortstring); |
34 procedure CopyToClipboard(var newContent: shortstring); |
35 procedure TextInput(var event: TSDL_TextInputEvent); |
35 procedure TextInput(var event: TSDL_TextInputEvent); |
36 |
36 |
37 implementation |
37 implementation |
38 uses uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils, uLocale |
38 uses uConsts, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils, uStore, uLocale |
39 {$IFDEF USE_VIDEO_RECORDING}, uVideoRec{$ENDIF}; |
39 {$IFDEF USE_VIDEO_RECORDING}, uVideoRec{$ENDIF}; |
40 |
40 |
41 const MaxStrIndex = 27; |
41 const MaxStrIndex = 27; |
42 MaxInputStrLen = 200; |
42 MaxInputStrLen = 200; |
43 |
43 |
92 (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'), |
92 (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'), |
93 (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr') |
93 (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr') |
94 ); |
94 ); |
95 |
95 |
96 |
96 |
97 const Padding = 2; |
97 const PaddingFactor = 0.125; // relative to font size in pixels |
98 ClHeight = 2 * Padding + 16; // font height |
98 |
|
99 var Padding, ClHeight: integer; |
|
100 LastChatScaleValue, LastUIScaleValue: real; |
|
101 SkipNextInput: boolean; |
|
102 |
|
103 procedure UpdateInputLinePrefix(); forward; |
|
104 procedure UpdateCursorCoords(); forward; |
99 |
105 |
100 // relevant for UTF-8 handling |
106 // relevant for UTF-8 handling |
101 function IsFirstCharByte(c: char): boolean; inline; |
107 function IsFirstCharByte(c: char): boolean; inline; |
102 begin |
108 begin |
103 // based on https://en.wikipedia.org/wiki/UTF-8#Description |
109 // based on https://en.wikipedia.org/wiki/UTF-8#Description |
110 end; |
116 end; |
111 |
117 |
112 procedure ResetSelection(); |
118 procedure ResetSelection(); |
113 begin |
119 begin |
114 selectedPos:= -1; |
120 selectedPos:= -1; |
|
121 end; |
|
122 |
|
123 procedure AdjustToUIScale(); |
|
124 var fntSize, fntSizePx: integer; |
|
125 begin |
|
126 // don't do anything if no change |
|
127 if (ChatScaleValue = LastChatScaleValue) and (UIScaleValue = LastUIScaleValue) then |
|
128 exit; |
|
129 |
|
130 LastChatScaleValue:= ChatScaleValue; |
|
131 LastUIScaleValue:= UIScaleValue; |
|
132 |
|
133 fntSize:= max(1, round(UIScaleValue * ChatScaleValue * cBaseChatFontHeight)); |
|
134 |
|
135 if Fontz[fntChat].Height <> fntSize then |
|
136 begin |
|
137 // adjust associated heights |
|
138 Fontz[fntChat].Height:= fntSize; |
|
139 Fontz[CJKfntChat].Height:= fntSize; |
|
140 // reload if initialized already |
|
141 if Fontz[fntChat].Handle <> nil then |
|
142 LoadFont(fntChat); |
|
143 if Fontz[CJKfntChat].Handle <> nil then |
|
144 LoadFont(CJKfntChat); |
|
145 end; |
|
146 |
|
147 // adjust line height etc. |
|
148 fntSizePx:= round(cFontPxToPtRatio * fntSize); |
|
149 Padding:= max(1, round(PaddingFactor * fntSizePx)); |
|
150 |
|
151 ClHeight:= 2 * Padding + fntSizePx; |
|
152 |
|
153 // clear cache of already rendered lines |
|
154 ReloadLines(); |
|
155 UpdateInputLinePrefix(); |
|
156 UpdateCursorCoords(); |
|
157 end; |
|
158 |
|
159 procedure ChatSizeInc(pxprecise: boolean); |
|
160 var fntSize: integer; |
|
161 begin |
|
162 if pxprecise then |
|
163 begin |
|
164 fntSize:= Fontz[fntChat].Height; |
|
165 inc(fntSize); |
|
166 ChatScaleValue:= 1.0 * fntSize / cBaseChatFontHeight; |
|
167 end |
|
168 else |
|
169 ChatScaleValue:= ChatScaleValue * (1.0 + cChatScaleRelDelta); |
|
170 if ChatScaleValue > cMaxChatScaleValue then |
|
171 ChatScaleValue:= cMaxChatScaleValue; |
|
172 AdjustToUIScale(); |
|
173 end; |
|
174 |
|
175 procedure ChatSizeDec(pxprecise: boolean); |
|
176 var fntSize: integer; |
|
177 begin |
|
178 if pxprecise then |
|
179 begin |
|
180 fntSize:= Fontz[fntChat].Height; |
|
181 dec(fntSize); |
|
182 ChatScaleValue:= 1.0 * fntSize / cBaseChatFontHeight; |
|
183 end |
|
184 else |
|
185 ChatScaleValue:= ChatScaleValue / (1.0 + cChatScaleRelDelta); |
|
186 if ChatScaleValue < cMinChatScaleValue then |
|
187 ChatScaleValue:= cMinChatScaleValue; |
|
188 AdjustToUIScale(); |
|
189 end; |
|
190 |
|
191 procedure chatSizeReset(); |
|
192 begin |
|
193 ChatScaleValue:= cDefaultChatScale; |
|
194 AdjustToUIScale(); |
|
195 end; |
|
196 |
|
197 function GetChatFont(str: shortstring): THWFONT; |
|
198 begin |
|
199 GetChatFont:= CheckCJKFont(ansistring(str), fntChat); |
115 end; |
200 end; |
116 |
201 |
117 procedure UpdateCursorCoords(); |
202 procedure UpdateCursorCoords(); |
118 var font: THWFont; |
203 var font: THWFont; |
119 str : shortstring; |
204 str : shortstring; |
120 coff, soff: LongInt; |
205 coff, soff: LongInt; |
121 begin |
206 begin |
|
207 AdjustToUIScale(); |
|
208 |
122 if cursorPos = selectedPos then |
209 if cursorPos = selectedPos then |
123 ResetSelection(); |
210 ResetSelection(); |
124 |
211 |
125 // calculate cursor offset |
212 // calculate cursor offset |
126 |
213 |
127 str:= InputStr.s; |
214 str:= InputStr.s; |
128 font:= CheckCJKFont(ansistring(str), fnt16); |
215 font:= GetChatFont(str); |
129 |
216 |
130 // get only substring before cursor to determine length |
217 // get only substring before cursor to determine length |
131 // SetLength(str, cursorPos); // makes pas2c unhappy |
218 // SetLength(str, cursorPos); // makes pas2c unhappy |
132 str[0]:= char(cursorPos); |
219 str[0]:= char(cursorPos); |
133 // get render size of text |
220 // get render size of text |
134 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @coff, nil); |
221 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @coff, nil); |
135 |
222 cursorX:= Padding + coff; |
136 cursorX:= 2 + coff; |
|
137 |
223 |
138 // calculate selection width on screen |
224 // calculate selection width on screen |
139 if selectedPos >= 0 then |
225 if selectedPos >= 0 then |
140 begin |
226 begin |
141 if selectedPos > cursorPos then |
227 if selectedPos > cursorPos then |
169 shadowint = $80 shl AShift; |
255 shadowint = $80 shl AShift; |
170 begin |
256 begin |
171 |
257 |
172 FreeAndNilTexture(cl.Tex); |
258 FreeAndNilTexture(cl.Tex); |
173 |
259 |
174 font:= CheckCJKFont(ansistring(str), fnt16); |
260 font:= GetChatFont(str); |
175 |
261 |
176 // get render size of text |
262 // get render size of text |
177 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @cl.Width, nil); |
263 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @cl.Width, nil); |
178 |
264 |
179 // calculate and save size |
265 // calculate and save size |
243 |
329 |
244 // For uStore texture recreation |
330 // For uStore texture recreation |
245 procedure ReloadLines; |
331 procedure ReloadLines; |
246 var i: LongWord; |
332 var i: LongWord; |
247 begin |
333 begin |
248 if InputStr.s <> '' then |
334 // also reload empty input line (as chat size/scaling might have changed) |
249 SetLine(InputStr, InputStr.s, true); |
335 //if InputStr.s <> '' then |
|
336 SetLine(InputStr, InputStr.s, true); |
250 for i:= 0 to MaxStrIndex do |
337 for i:= 0 to MaxStrIndex do |
251 if Strs[i].s <> '' then |
338 if Strs[i].s <> '' then |
252 begin |
339 begin |
253 RenderChatLineTex(Strs[i], Strs[i].s); |
340 RenderChatLineTex(Strs[i], Strs[i].s); |
254 end; |
341 end; |
327 |
416 |
328 if selectedPos < 0 then |
417 if selectedPos < 0 then |
329 begin |
418 begin |
330 // draw cursor |
419 // draw cursor |
331 if ((RealTicks - LastKeyPressTick) and 512) < 256 then |
420 if ((RealTicks - LastKeyPressTick) and 512) < 256 then |
332 DrawLineOnScreen(left + cursorX, top + 2, left + cursorX, top + ClHeight - 2, 2.0, $00, $FF, $FF, $FF); |
421 DrawLineOnScreen(left + cursorX, top + Padding, left + cursorX, top + ClHeight - Padding, max(2, round(UIScaleValue * ChatScaleValue * 2.0)), $00, $FF, $FF, $FF); |
333 end |
422 end |
334 else // draw selection |
423 else // draw selection |
335 begin |
424 begin |
336 selRect.y:= top + 2; |
425 selRect.y:= top + Padding; |
337 selRect.h:= clHeight - 4; |
426 selRect.h:= clHeight - 2 * Padding; |
338 if selectionDx < 0 then |
427 if selectionDx < 0 then |
339 begin |
428 begin |
340 selRect.x:= left + cursorX + selectionDx; |
429 selRect.x:= left + cursorX + selectionDx; |
341 selRect.w:= -selectionDx; |
430 selRect.w:= -selectionDx; |
342 end |
431 end |
1102 begin |
1191 begin |
1103 CopySelectionToClipboard(); |
1192 CopySelectionToClipboard(); |
1104 DeleteSelected(); |
1193 DeleteSelected(); |
1105 end |
1194 end |
1106 end; |
1195 end; |
|
1196 // make chat bigger |
|
1197 SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_EQUALS: |
|
1198 begin |
|
1199 if ctrl then |
|
1200 begin |
|
1201 ChatSizeInc(selMode); |
|
1202 SkipNextInput:= true; |
|
1203 end; |
|
1204 end; |
|
1205 // make chat smaller |
|
1206 SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_MINUS: |
|
1207 begin |
|
1208 if ctrl then |
|
1209 begin |
|
1210 ChatSizeDec(selMode); |
|
1211 SkipNextInput:= true; |
|
1212 end; |
|
1213 end; |
|
1214 // revert chat size to default |
|
1215 SDL_SCANCODE_KP_0, SDL_SCANCODE_0: |
|
1216 begin |
|
1217 if ctrl then |
|
1218 begin |
|
1219 ChatSizeReset(); |
|
1220 SkipNextInput:= true; |
|
1221 end; |
|
1222 end; |
1107 end; |
1223 end; |
1108 end; |
1224 end; |
1109 |
1225 |
1110 procedure TextInput(var event: TSDL_TextInputEvent); |
1226 procedure TextInput(var event: TSDL_TextInputEvent); |
1111 var s: shortstring; |
1227 var s: shortstring; |
1112 l: byte; |
1228 l: byte; |
1113 isl: integer; |
1229 isl: integer; |
1114 begin |
1230 begin |
|
1231 if SkipNextInput then |
|
1232 begin |
|
1233 SkipNextInput:= false; |
|
1234 exit; |
|
1235 end; |
|
1236 |
1115 DeleteSelected(); |
1237 DeleteSelected(); |
1116 |
1238 |
|
1239 s:= ''; |
1117 l:= 0; |
1240 l:= 0; |
1118 // fetch all bytes of character/input |
1241 // fetch all bytes of character/input |
1119 while event.text[l] <> #0 do |
1242 while event.text[l] <> #0 do |
1120 begin |
1243 begin |
1121 s[l + 1]:= event.text[l]; |
1244 if Length(s) < 255 then |
1122 inc(l) |
1245 begin |
1123 end; |
1246 s[l + 1]:= event.text[l]; |
1124 |
1247 inc(l) |
|
1248 end |
|
1249 end; |
1125 if l > 0 then |
1250 if l > 0 then |
1126 begin |
1251 begin |
1127 isl:= Length(InputStr.s); |
1252 isl:= Length(InputStr.s); |
1128 // check if user is typing a redundant closing hog-speech quotation mark |
1253 // check if user is typing a redundant closing hog-speech quotation mark |
1129 if (l = 1) and (isl >= 2) and (cursorPos = isl - 1) and charIsForHogSpeech(s[1]) |
1254 if (l = 1) and (isl >= 2) and (cursorPos = isl - 1) and charIsForHogSpeech(s[1]) |