hedgewars/uChat.pas
branchui-scaling
changeset 13385 ec1491bb5acc
parent 13077 c213645ff848
child 13386 72bbccf9a715
--- a/hedgewars/uChat.pas	Fri Apr 27 11:19:23 2018 -0400
+++ b/hedgewars/uChat.pas	Tue May 15 16:55:37 2018 +0200
@@ -35,7 +35,7 @@
 procedure TextInput(var event: TSDL_TextInputEvent);
 
 implementation
-uses uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils;
+uses uConsts, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils, uStore, Math;
 
 const MaxStrIndex = 27;
       MaxInputStrLen = 200;
@@ -93,8 +93,14 @@
             );
 
 
-const Padding  = 2;
-      ClHeight = 2 * Padding + 16; // font height
+const PaddingFactor = (1/6); // relative to font size
+
+var Padding, ClHeight: integer;
+    LastChatScaleValue, LastUIScaleValue: real;
+    SkipNextInput: boolean;
+
+procedure UpdateInputLinePrefix(); forward;
+procedure UpdateCursorCoords(); forward;
 
 // relevant for UTF-8 handling
 function IsFirstCharByte(c: char): boolean; inline;
@@ -113,26 +119,95 @@
     selectedPos:= -1;
 end;
 
+procedure AdjustToUIScale();
+var fntSize: integer;
+begin
+    // don't do anything if no change
+    if (ChatScaleValue = LastChatScaleValue) and (UIScaleValue = LastUIScaleValue) then
+        exit;
+
+    LastChatScaleValue:= ChatScaleValue;
+    LastUIScaleValue:= UIScaleValue;
+
+    // determine font size - note: +0.1 to because I don't trust float inaccuracy combined with floor
+    fntSize:= max(1, floor(UIScaleValue * ChatScaleValue * Fontz[fnt16].Height + 0.1));
+
+    if Fontz[fntChat].Height <> fntSize then
+        begin
+        // adjust associated heights
+        Fontz[fntChat].Height:= fntSize;
+        Fontz[CJKfntChat].Height:= fntSize;
+        // reload if initialized already
+        if Fontz[fntChat].Handle <> nil then
+            LoadFont(fntChat);
+        if Fontz[CJKfntChat].Handle <> nil then
+            LoadFont(CJKfntChat);
+        end;
+
+    // adjust line height etc.
+    Padding:= max(1, floor(PaddingFactor * fntSize + 0.1));
+    ClHeight:= 2 * Padding + fntSize;
+
+    // clear cache of already rendered lines
+    ReloadLines();
+    UpdateInputLinePrefix();
+    UpdateCursorCoords();
+end;
+
+procedure ChatSizeInc();
+begin
+// TODO cChatMinScaleLevel, cChatSizeDelta (probably half of cZoomDelta)
+// TODO always - effectively -- increase font by 1px?
+if ChatScaleValue < cMinZoomLevel then
+    begin
+    ChatScaleValue:= ChatScaleValue + cZoomDelta;
+    AdjustToUIScale();
+    end;
+end;
+
+procedure ChatSizeDec();
+begin
+// TODO cChatMaxScaleLevel, cChatSizeDelta (probably half of cZoomDelta)
+// TODO always - effectively -- increase font by 1px?
+if ChatScaleValue > cMaxZoomLevel then
+    begin
+    ChatScaleValue:= ChatScaleValue - cZoomDelta;
+    AdjustToUIScale();
+    end;
+end;
+
+procedure chatSizeReset();
+begin
+ChatScaleValue:= cDefaultChatScaleLevel;
+AdjustToUIScale();
+end;
+
+function GetChatFont(str: shortstring): THWFONT;
+begin
+    GetChatFont:= CheckCJKFont(ansistring(str), fntChat);
+end;
+
 procedure UpdateCursorCoords();
 var font: THWFont;
     str : shortstring;
     coff, soff: LongInt;
 begin
+    AdjustToUIScale();
+
     if cursorPos = selectedPos then
         ResetSelection();
 
     // calculate cursor offset
 
     str:= InputStr.s;
-    font:= CheckCJKFont(ansistring(str), fnt16);
+    font:= GetChatFont(str);
 
     // get only substring before cursor to determine length
     // SetLength(str, cursorPos); // makes pas2c unhappy
     str[0]:= char(cursorPos);
     // get render size of text
     TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @coff, nil);
-
-    cursorX:= 2 + coff;
+    cursorX:= Padding + coff;
 
     // calculate selection width on screen
     if selectedPos >= 0 then
@@ -170,7 +245,7 @@
 
 FreeAndNilTexture(cl.Tex);
 
-font:= CheckCJKFont(ansistring(str), fnt16);
+font:= GetChatFont(str);
 
 // get render size of text
 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @cl.Width, nil);
@@ -199,7 +274,7 @@
 if strSurface <> nil then tmpSurface:= SDL_ConvertSurface(strSurface, resSurface^.format, 0);
 SDL_FreeSurface(strSurface);
 //SDL_UpperBlit(strSurface, nil, resSurface, @dstrect);
-if tmpSurface <> nil then copyToXY(tmpSurface, resSurface, Padding, Padding);
+if tmpSurface <> nil then copyToXY(tmpSurface, resSurface, Padding, 2);
 SDL_FreeSurface(tmpSurface);
 
 cl.Tex:= Surface2Tex(resSurface, false);
@@ -244,8 +319,8 @@
 procedure ReloadLines;
 var i: LongWord;
 begin
-    if InputStr.s <> '' then
-        SetLine(InputStr, InputStr.s, true);
+    // also reload empty input line (as chat size/scaling might have changed)
+    //if InputStr.s <> '' then SetLine(InputStr, InputStr.s, true); for i:= 0 to MaxStrIndex do
     for i:= 0 to MaxStrIndex do
         if Strs[i].s <> '' then
             begin
@@ -293,6 +368,8 @@
     selRect: TSDL_Rect;
     c: char;
 begin
+AdjustToUIScale();
+
 ChatReady:= true; // maybe move to somewhere else?
 
 if ChatHidden and (not showAll) then
@@ -323,12 +400,12 @@
         begin
         // draw cursor
         if ((RealTicks - LastKeyPressTick) and 512) < 256 then
-            DrawLineOnScreen(left + cursorX, top + 2, left + cursorX, top + ClHeight - 2, 2.0, $00, $FF, $FF, $FF);
+            DrawLineOnScreen(left + cursorX, top + Padding, left + cursorX, top + ClHeight - Padding, 2.0, $00, $FF, $FF, $FF);
         end
     else // draw selection
         begin
-        selRect.y:= top + 2;
-        selRect.h:= clHeight - 4;
+        selRect.y:= top + Padding;
+        selRect.h:= clHeight - 2 * Padding;
         if selectionDx < 0 then
             begin
             selRect.x:= left + cursorX + selectionDx;
@@ -972,7 +1049,7 @@
             // ignore me!!!
             end;
         // TODO: figure out how to determine those keys better
-        SDL_SCANCODE_a:
+        SDL_SCANCODE_b:
             begin
             // select all
             if ctrlonly then
@@ -1008,6 +1085,33 @@
                 DeleteSelected();
                 end
             end;
+            // make chat bigger
+        SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_EQUALS:
+            begin
+            if ctrl then
+                begin
+                ChatSizeInc();
+                SkipNextInput:= true;
+                end;
+            end;
+            // make chat smaller
+        SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_MINUS:
+            begin
+            if ctrl then
+                begin
+                ChatSizeDec();
+                SkipNextInput:= true;
+                end;
+            end;
+            // revert chat size to default
+        SDL_SCANCODE_KP_0, SDL_SCANCODE_0:
+            begin
+            if ctrl then
+                begin
+                ChatSizeReset();
+                SkipNextInput:= true;
+                end;
+            end;
         end;
 end;
 
@@ -1016,16 +1120,25 @@
     l: byte;
     isl: integer;
 begin
+    if SkipNextInput then
+        begin
+        SkipNextInput:= false;
+        exit;
+        end;
+
     DeleteSelected();
 
+    s:= '';
     l:= 0;
     // fetch all bytes of character/input
     while event.text[l] <> #0 do
         begin
-        s[l + 1]:= event.text[l];
-        inc(l)
+        if Length(s) < 255 then
+            begin
+            s[l + 1]:= event.text[l];
+            inc(l)
+            end
         end;
-
     if l > 0 then
         begin
         isl:= Length(InputStr.s);
@@ -1141,6 +1254,10 @@
     ChatHidden:= false;
     firstDraw:= true;
 
+    LastChatScaleValue:= 0;
+    LastUIScaleValue:= 0;
+    SkipNextInput:= true;
+
     InputLinePrefix.Tex:= nil;
     UpdateInputLinePrefix();
     inputStr.s:= '';