hedgewars/uChat.pas
changeset 10844 953d85b7d529
parent 10843 5c2ef0507971
child 10845 1dbd50690951
equal deleted inserted replaced
10843:5c2ef0507971 10844:953d85b7d529
   576     end
   576     end
   577 else
   577 else
   578     ResetSelection();
   578     ResetSelection();
   579 end;
   579 end;
   580 
   580 
       
   581 type TCharSkip = ( none, wspace, numalpha, special );
       
   582 
       
   583 function GetInputCharSkipClass(index: LongInt): TCharSkip;
       
   584 var  c: char;
       
   585 begin
       
   586     // multi-byte chars counts as letter
       
   587     if (index > 1) and (InputStrL[index] <> index - 1) then
       
   588         exit(numalpha);
       
   589 
       
   590     c:= InputStr.s[index];
       
   591 
       
   592     // non-ascii counts as letter
       
   593     if c > #127 then
       
   594         exit(numalpha);
       
   595 
       
   596     // low-ascii whitespaces and DEL
       
   597     if (c < #33) or (c = #127) then
       
   598         exit(wspace);
       
   599 
       
   600     // low-ascii special chars
       
   601     if c < #48 then
       
   602         exit(special);
       
   603 
       
   604     // digits
       
   605     if c < #58 then
       
   606         exit(numalpha);
       
   607 
       
   608     // make c upper-case
       
   609     if c > #96 then
       
   610         c:= char(byte(c) - 32);
       
   611 
       
   612     // letters
       
   613     if (c > #64) and (c < #90) then
       
   614         exit(numalpha);
       
   615 
       
   616     // remaining ascii are special chars
       
   617     exit(special);
       
   618 end;
       
   619 
       
   620 // skip from word to word, similar to Qt
       
   621 procedure skipInputChars(skip: TCharSkip; backwards: boolean);
       
   622 begin
       
   623 if backwards then
       
   624     begin
       
   625     // skip trailing whitespace, similar to Qt
       
   626     while (skip = wspace) and (cursorPos > 0) do
       
   627         begin
       
   628         skip:= GetInputCharSkipClass(cursorPos);
       
   629         if skip = wspace then
       
   630             cursorPos:= InputStrL[cursorPos];
       
   631         end;
       
   632     // skip same-type chars
       
   633     while (cursorPos > 0) and (GetInputCharSkipClass(cursorPos) = skip) do
       
   634         cursorPos:= InputStrL[cursorPos];
       
   635     end
       
   636 else
       
   637     begin
       
   638     // skip same-type chars
       
   639     while cursorPos < Length(InputStr.s) do
       
   640         begin
       
   641         DoCursorStepForward();
       
   642         if (GetInputCharSkipClass(cursorPos) <> skip) then
       
   643             begin
       
   644             // go back 1 char
       
   645             cursorPos:= InputStrL[cursorPos];
       
   646             break;
       
   647             end;
       
   648         end;
       
   649     // skip trailing whitespace, similar to Qt
       
   650     while cursorPos < Length(InputStr.s) do
       
   651         begin
       
   652         DoCursorStepForward();
       
   653         if (GetInputCharSkipClass(cursorPos) <> wspace) then
       
   654             begin
       
   655             // go back 1 char
       
   656             cursorPos:= InputStrL[cursorPos];
       
   657             break;
       
   658             end;
       
   659         end;
       
   660     end;
       
   661 end;
       
   662 
   581 procedure KeyPressChat(Key, Sym: Longword; Modifier: Word);
   663 procedure KeyPressChat(Key, Sym: Longword; Modifier: Word);
   582 const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0);
   664 const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0);
   583 var i, btw, index: integer;
   665 var i, btw, index: integer;
   584     utf8: shortstring;
   666     utf8: shortstring;
   585     action, selMode, ctrl: boolean;
   667     action, selMode, ctrl: boolean;
       
   668     skip: TCharSkip;
   586 begin
   669 begin
   587     LastKeyPressTick:= RealTicks;
   670     LastKeyPressTick:= RealTicks;
   588     action:= true;
   671     action:= true;
   589 
   672 
   590     selMode:= (modifier and (KMOD_LSHIFT or KMOD_RSHIFT)) <> 0;
   673     selMode:= (modifier and (KMOD_LSHIFT or KMOD_RSHIFT)) <> 0;
   591     ctrl:= (modifier and (KMOD_LCTRL or KMOD_RCTRL)) <> 0;
   674     ctrl:= (modifier and (KMOD_LCTRL or KMOD_RCTRL)) <> 0;
       
   675     skip:= none;
   592 
   676 
   593     case Sym of
   677     case Sym of
   594         SDLK_BACKSPACE:
   678         SDLK_BACKSPACE:
   595             begin
   679             begin
   596             if selectedPos < 0 then
   680             if selectedPos < 0 then
   678             end;
   762             end;
   679         SDLK_LEFT:
   763         SDLK_LEFT:
   680             begin
   764             begin
   681             if cursorPos > 0 then
   765             if cursorPos > 0 then
   682                 begin
   766                 begin
       
   767 
       
   768                 if ctrl then
       
   769                     skip:= GetInputCharSkipClass(cursorPos);
       
   770 
   683                 if selMode or (selectedPos < 0) then
   771                 if selMode or (selectedPos < 0) then
   684                     begin
   772                     begin
   685                     HandleSelection(selMode);
   773                     HandleSelection(selMode);
   686                     // go to end of previous utf8-char
   774                     // go to end of previous utf8-char
   687                     cursorPos:= InputStrL[cursorPos];
   775                     cursorPos:= InputStrL[cursorPos];
   689                 else // if we're leaving selection mode, jump to its left end
   777                 else // if we're leaving selection mode, jump to its left end
   690                     begin
   778                     begin
   691                     cursorPos:= min(cursorPos, selectedPos);
   779                     cursorPos:= min(cursorPos, selectedPos);
   692                     ResetSelection();
   780                     ResetSelection();
   693                     end;
   781                     end;
       
   782 
       
   783                 if ctrl then
       
   784                     skipInputChars(skip, true);
       
   785 
   694                 UpdateCursorCoords();
   786                 UpdateCursorCoords();
   695                 end;
   787                 end;
   696             end;
   788             end;
   697         SDLK_RIGHT:
   789         SDLK_RIGHT:
   698             begin
   790             begin
   699             if cursorPos < Length(InputStr.s) then
   791             if cursorPos < Length(InputStr.s) then
   700                 begin
   792                 begin
       
   793 
   701                 if selMode or (selectedPos < 0) then
   794                 if selMode or (selectedPos < 0) then
   702                     begin
   795                     begin
   703                     HandleSelection(selMode);
   796                     HandleSelection(selMode);
   704                     DoCursorStepForward();
   797                     DoCursorStepForward();
   705                     end
   798                     end
   706                 else // if we're leaving selection mode, jump to its right end
   799                 else // if we're leaving selection mode, jump to its right end
   707                     begin
   800                     begin
   708                     cursorPos:= max(cursorPos, selectedPos);
   801                     cursorPos:= max(cursorPos, selectedPos);
   709                     ResetSelection();
   802                     ResetSelection();
   710                     end;
   803                     end;
       
   804 
       
   805                 if ctrl then
       
   806                     skipInputChars(GetInputCharSkipClass(cursorPos), false);
       
   807 
   711                 UpdateCursorCoords();
   808                 UpdateCursorCoords();
   712                 end;
   809                 end;
   713             end;
   810             end;
   714         SDLK_PAGEUP, SDLK_PAGEDOWN:
   811         SDLK_PAGEUP, SDLK_PAGEDOWN:
   715             begin
   812             begin