WIP: allow changing chat size ui-scaling
authorsheepluva
Tue, 15 May 2018 16:55:37 +0200
branchui-scaling
changeset 13390 ec1491bb5acc
parent 13351 e461deddc942
child 13391 72bbccf9a715
WIP: allow changing chat size Press Ctrl+, Ctrl- and Ctrl0 while in chat
hedgewars/uChat.pas
hedgewars/uConsts.pas
hedgewars/uStore.pas
hedgewars/uTypes.pas
hedgewars/uVariables.pas
--- 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:= '';
--- a/hedgewars/uConsts.pas	Fri Apr 27 11:19:23 2018 -0400
+++ b/hedgewars/uConsts.pas	Tue May 15 16:55:37 2018 +0200
@@ -194,6 +194,8 @@
 
     // do not change this value
     cDefaultZoomLevel = 2.0;
+    cDefaultChatScaleLevel = 1.0;
+    cDefaultUIScaleLevel = 1.0;
 
     // game flags
     gfAny                = $FFFFFFFF;
--- a/hedgewars/uStore.pas	Fri Apr 27 11:19:23 2018 -0400
+++ b/hedgewars/uStore.pas	Tue May 15 16:55:37 2018 +0200
@@ -33,6 +33,7 @@
 function makeHealthBarTexture(w, h, Color: Longword): PTexture;
 procedure AddProgress;
 procedure FinishProgress;
+procedure LoadFont(font: THWFont);
 function  LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
 
 // loads an image from the games data files
@@ -355,23 +356,35 @@
             end
 end;
 
-procedure LoadFonts();
+procedure LoadFont(font: THWFont);
 var s: shortstring;
-    fi: THWFont;
+begin
+    with Fontz[font] do
+        begin
+        if Handle <> nil then
+            begin
+            TTF_CloseFont(Handle);
+            Handle:= nil;
+            end;
+        s:= cPathz[ptFonts] + '/' + Name;
+        WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
+        Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
+        if SDLCheck(Handle <> nil, 'TTF_OpenFontRW', true) then exit;
+        TTF_SetFontStyle(Handle, style);
+        WriteLnToConsole(msgOK)
+        end;
+end;
+
+procedure LoadFonts();
+var fi: THWFont;
 begin
 AddFileLog('LoadFonts();');
 
 if (not cOnlyStats) then
     for fi:= Low(THWFont) to High(THWFont) do
-        with Fontz[fi] do
-            begin
-            s:= cPathz[ptFonts] + '/' + Name;
-            WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
-            Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
-            if SDLCheck(Handle <> nil, 'TTF_OpenFontRW', true) then exit;
-            TTF_SetFontStyle(Handle, style);
-            WriteLnToConsole(msgOK)
-            end;
+        begin
+        LoadFont(fi);
+        end;
 end;
 
 procedure StoreLoad(reload: boolean);
--- a/hedgewars/uTypes.pas	Fri Apr 27 11:19:23 2018 -0400
+++ b/hedgewars/uTypes.pas	Tue May 15 16:55:37 2018 +0200
@@ -168,7 +168,7 @@
     // Different kind of crates that e.g. hedgehogs can pick up
     TCrateType = (HealthCrate, AmmoCrate, UtilityCrate);
 
-    THWFont = (fnt16, fntBig, fntSmall {$IFNDEF MOBILE}, CJKfnt16, CJKfntBig, CJKfntSmall{$ENDIF});
+    THWFont = (fnt16, fntBig, fntSmall, fntChat {$IFNDEF MOBILE}, CJKfnt16, CJKfntBig, CJKfntSmall, CJKfntChat{$ENDIF});
 
     TCapGroup = (capgrpGameState, capgrpAmmoinfo, capgrpVolume,
             capgrpMessage, capgrpMessage2, capgrpAmmostate);
--- a/hedgewars/uVariables.pas	Fri Apr 27 11:19:23 2018 -0400
+++ b/hedgewars/uVariables.pas	Tue May 15 16:55:37 2018 +0200
@@ -127,6 +127,8 @@
     cPrevTagsMask    : byte;
     zoom             : GLfloat;
     ZoomValue        : GLfloat;
+    ChatScaleValue   : real;
+    UIScaleValue     : real;
 
     cWaterLine       : LongInt;
     cGearScrEdgesDist: LongInt;
@@ -238,6 +240,8 @@
 
     // for tracking the limits of the visible grid based on cScaleFactor
     ViewLeftX, ViewRightX, ViewBottomY, ViewTopY, ViewWidth, ViewHeight: LongInt;
+    // for tracking the limits of the visible UI space based on cUIScaleFactor
+    UIWidth, UIHeight: LongInt;
 
     // for debugging the view limits visually
     cViewLimitsDebug: boolean;
@@ -324,6 +328,10 @@
             (Handle: nil;
             Height: 10*HDPIScaleFactor;
             style: TTF_STYLE_NORMAL;
+            Name: 'DejaVuSans-Bold.ttf'),
+            (Handle: nil; // fntChat
+            Height: 12*HDPIScaleFactor;
+            style: TTF_STYLE_NORMAL;
             Name: 'DejaVuSans-Bold.ttf')
             {$IFNDEF MOBILE}, // remove chinese fonts for now
             (Handle: nil;
@@ -337,6 +345,10 @@
             (Handle: nil;
             Height: 10*HDPIScaleFactor;
             style: TTF_STYLE_NORMAL;
+            Name: 'wqy-zenhei.ttc'),
+            (Handle: nil; // CJKfntChat
+            Height: 12*HDPIScaleFactor;
+            style: TTF_STYLE_NORMAL;
             Name: 'wqy-zenhei.ttc')
             {$ENDIF}
             );
@@ -2525,6 +2537,7 @@
     SyncTexture,
     ConfirmTexture: PTexture;
     cScaleFactor: GLfloat;
+    cUIScaleFactor: float;
     cStereoDepth: GLfloat;
     SupportNPOTT: Boolean;
     Step: LongInt;
@@ -2822,6 +2835,8 @@
     GameState       := Low(TGameState);
     zoom            := cDefaultZoomLevel;
     ZoomValue       := cDefaultZoomLevel;
+    ChatScaleValue  := cDefaultChatScaleLevel;
+    UIScaleValue    := cDefaultUIScaleLevel;
     WeaponTooltipTex:= nil;
     cLaserSighting  := false;
     cLaserSightingSniper := false;