]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Scoreboard: limit width of field titles and show too long titles compressed. Max...
authorterencehill <piuntn@gmail.com>
Mon, 1 Apr 2024 16:36:02 +0000 (18:36 +0200)
committerterencehill <piuntn@gmail.com>
Wed, 3 Apr 2024 13:36:03 +0000 (15:36 +0200)
_hud_common.cfg
qcsrc/client/command/cl_cmd.qh
qcsrc/client/hud/panel/scoreboard.qc

index 95f1e9758b0f10c48e20d3100e3adc23673e1172..954ffbd80885cc3774160376b614e13e3b943b06 100644 (file)
@@ -142,6 +142,7 @@ seta hud_panel_scoreboard_spectators_showping 1 "show ping of spectators"
 seta hud_panel_scoreboard_spectators_aligned 0 "align spectators in columns"
 seta hud_panel_scoreboard_spectators_position 1 "spectator list position (0 = before accuracy and itemstats, 1 = before rankings, 2 = after rankings, 3 = after map stats)"
 seta hud_panel_scoreboard_minwidth 0.6 "minimum width of the scoreboard"
+seta hud_panel_scoreboard_table_fieldtitle_maxwidth 0.07 "max width of a field title; if the title is longer it will be shown compressed"
 seta hud_panel_scoreboard_team_size_position 0 "where to show the team size (0 = do not show, 1 = left of scoreboard, 2 = right of scoreboard), will move team scores to the other side if necessary"
 seta hud_panel_scoreboard_ping_best 0 "use best_color for this ping"
 seta hud_panel_scoreboard_ping_medium 70 "use medium_color for this ping"
index 725baa408e9c0c47dd748a596e26a751e1b05683..13434ec05c995f4129dd5e5a9bdbff8d3b00e5e3 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-void Cmd_Scoreboard_SetFields(int);
+void Cmd_Scoreboard_SetFields(int argc);
 void Cmd_Scoreboard_Help();
 void ConsoleCommand_macro_init();
 
index de5a0d80956e638bd3913546414c03471efe8bc9..ade633c22e82d0ad817057eb976e3068d8dbb646 100644 (file)
@@ -43,10 +43,12 @@ const int MAX_SBT_FIELDS = MAX_SCORE;
 PlayerScoreField sbt_field[MAX_SBT_FIELDS + 1];
 float sbt_field_size[MAX_SBT_FIELDS + 1];
 string sbt_field_title[MAX_SBT_FIELDS + 1];
+float sbt_field_title_condense_factor[MAX_SBT_FIELDS + 1];
+float sbt_field_title_width[MAX_SBT_FIELDS + 1];
 int sbt_num_fields;
+float sbt_field_title_maxwidth;
 
 string autocvar_hud_fontsize;
-string hud_fontsize_str;
 float max_namesize;
 
 float sbt_bg_alpha;
@@ -75,6 +77,7 @@ float autocvar_hud_panel_scoreboard_table_bg_alpha = 0;
 float autocvar_hud_panel_scoreboard_table_bg_scale = 0.25;
 float autocvar_hud_panel_scoreboard_table_fg_alpha = 0.9;
 float autocvar_hud_panel_scoreboard_table_fg_alpha_self = 1;
+float autocvar_hud_panel_scoreboard_table_fieldtitle_maxwidth = 0.07;
 bool autocvar_hud_panel_scoreboard_table_highlight = true;
 float autocvar_hud_panel_scoreboard_table_highlight_alpha = 0.2;
 float autocvar_hud_panel_scoreboard_table_highlight_alpha_self = 0.4;
@@ -839,7 +842,6 @@ void Cmd_Scoreboard_SetFields(int argc)
 
                str = strtolower(str);
                strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(str));
-               sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
 
                PlayerScoreField j;
                switch(str)
@@ -870,7 +872,6 @@ void Cmd_Scoreboard_SetFields(int argc)
                                        LOG_INFOF("^1Error:^7 Unknown score field: '%s'", str);
 
                                strfree(sbt_field_title[sbt_num_fields]);
-                               sbt_field_size[sbt_num_fields] = 0;
                                continue;
 
                                LABEL(found)
@@ -903,7 +904,6 @@ void Cmd_Scoreboard_SetFields(int argc)
                        for(i = sbt_num_fields; i > 0; --i)
                        {
                                sbt_field_title[i] = sbt_field_title[i-1];
-                               sbt_field_size[i] = sbt_field_size[i-1];
                                sbt_field[i] = sbt_field[i-1];
                        }
                        sbt_field_title[0] = strzone(TranslateScoresLabel("name"));
@@ -917,12 +917,10 @@ void Cmd_Scoreboard_SetFields(int argc)
                                for(i = sbt_num_fields; i > 1; --i)
                                {
                                        sbt_field_title[i] = sbt_field_title[i-1];
-                                       sbt_field_size[i] = sbt_field_size[i-1];
                                        sbt_field[i] = sbt_field[i-1];
                                }
                                sbt_field_title[1] = strzone("|");
                                sbt_field[1] = SP_SEPARATOR;
-                               sbt_field_size[1] = stringwidth("|", false, hud_fontsize);
                                ++sbt_num_fields;
                                LOG_INFO("fixed missing field '|'");
                        }
@@ -930,7 +928,6 @@ void Cmd_Scoreboard_SetFields(int argc)
                else if(!have_separator)
                {
                        strcpy(sbt_field_title[sbt_num_fields], "|");
-                       sbt_field_size[sbt_num_fields] = stringwidth("|", false, hud_fontsize);
                        sbt_field[sbt_num_fields] = SP_SEPARATOR;
                        ++sbt_num_fields;
                        LOG_INFO("fixed missing field '|'");
@@ -938,7 +935,6 @@ void Cmd_Scoreboard_SetFields(int argc)
                if(!have_secondary)
                {
                        strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(scores_label(ps_secondary)));
-                       sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
                        sbt_field[sbt_num_fields] = ps_secondary;
                        ++sbt_num_fields;
                        LOG_INFOF("fixed missing field '%s'", scores_label(ps_secondary));
@@ -946,7 +942,6 @@ void Cmd_Scoreboard_SetFields(int argc)
                if(!have_primary)
                {
                        strcpy(sbt_field_title[sbt_num_fields], TranslateScoresLabel(scores_label(ps_primary)));
-                       sbt_field_size[sbt_num_fields] = stringwidth(sbt_field_title[sbt_num_fields], false, hud_fontsize);
                        sbt_field[sbt_num_fields] = ps_primary;
                        ++sbt_num_fields;
                        LOG_INFOF("fixed missing field '%s'", scores_label(ps_primary));
@@ -954,6 +949,7 @@ void Cmd_Scoreboard_SetFields(int argc)
        }
 
        sbt_field[sbt_num_fields] = SP_END;
+       sbt_field_size[0] = 0; // tells Scoreboard_Draw to initialize all field sizes
 }
 
 string Scoreboard_AddPlayerId(string pl_name, entity pl)
@@ -1165,7 +1161,7 @@ float sbt_fixcolumnwidth_len;
 float sbt_fixcolumnwidth_iconlen;
 float sbt_fixcolumnwidth_marginlen;
 
-string Scoreboard_FixColumnWidth(int i, string str)
+string Scoreboard_FixColumnWidth(int i, string str, bool init)
 {
        TC(int, i);
        float f;
@@ -1205,6 +1201,9 @@ string Scoreboard_FixColumnWidth(int i, string str)
        else
                sbt_fixcolumnwidth_marginlen = 0;
 
+       if (init)
+               sbt_field_title_width[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
+
        if(sbt_field[i] == SP_NAME) // name gets all remaining space
        {
                int j;
@@ -1213,33 +1212,59 @@ string Scoreboard_FixColumnWidth(int i, string str)
                        if(j != i)
                                if (sbt_field[i] != SP_SEPARATOR)
                                        remaining_space += sbt_field_size[j] + hud_fontsize.x;
-               sbt_field_size[i] = panel_size.x - remaining_space;
+               sbt_field_size[i] = max(sbt_field_title_width[i], panel_size.x - remaining_space);
 
                if (sbt_fixcolumnwidth_iconlen != 0)
                        remaining_space += sbt_fixcolumnwidth_marginlen + sbt_fixcolumnwidth_iconlen * hud_fontsize.x;
-               float namesize = panel_size.x - remaining_space;
+               float namesize = max(sbt_field_title_width[i], panel_size.x - remaining_space);
                str = textShortenToWidth(str, namesize, hud_fontsize, stringwidth_colors);
                sbt_fixcolumnwidth_len = stringwidth(str, true, hud_fontsize);
 
-               max_namesize = vid_conwidth - remaining_space;
+               max_namesize = max(sbt_field_title_width[i], vid_conwidth - remaining_space);
        }
        else
+       {
+               if (init)
+               {
+                       sbt_field_size[i] = sbt_field_title_width[i];
+                       if (sbt_field_size[i] && sbt_field_size[i] > sbt_field_title_maxwidth)
+                               sbt_field_size[i] = sbt_field_title_maxwidth;
+               }
                sbt_fixcolumnwidth_len = stringwidth(str, false, hud_fontsize);
+       }
 
        f = sbt_fixcolumnwidth_len + sbt_fixcolumnwidth_marginlen + sbt_fixcolumnwidth_iconlen * hud_fontsize.x;
        if(sbt_field_size[i] < f)
                sbt_field_size[i] = f;
 
+       sbt_field_title_condense_factor[i] = 0;
+       if (sbt_field_title_width[i] > sbt_field_size[i])
+       {
+               float real_maxwidth = sbt_field_size[i];
+               if (sbt_field_title_width[i] > sbt_field_title_maxwidth)
+                       real_maxwidth = max(sbt_field_size[i], sbt_field_title_maxwidth);
+               sbt_field_title_condense_factor[i] = real_maxwidth / sbt_field_title_width[i];
+       }
+
        return str;
 }
 
 void Scoreboard_initFieldSizes()
 {
+       int name_index = 0;
        for(int i = 0; i < sbt_num_fields; ++i)
        {
-               sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
-               Scoreboard_FixColumnWidth(i, "");
+               if (sbt_field[i] == SP_NAME)
+               {
+                       name_index = i;
+                       continue;
+               }
+
+               Scoreboard_FixColumnWidth(i, "", true);
        }
+
+       // update name field size in the end as it takes remaining space
+       Scoreboard_FixColumnWidth(name_index, "", true);
 }
 
 vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
@@ -1258,7 +1283,15 @@ vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
                if (sbt_highlight)
                        if (i % 2)
                                drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+               vector prev_drawfontscale = drawfontscale;
+               if (sbt_field_title_condense_factor[i])
+                       drawfontscale.x *= sbt_field_title_condense_factor[i];
                drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
+               if (sbt_field_title_condense_factor[i])
+               {
+                       drawfontscale.x *= sbt_field_title_condense_factor[i];
+                       drawfontscale = prev_drawfontscale;
+               }
                pos.x += column_dim.x;
        }
        if(sbt_field[i] == SP_SEPARATOR)
@@ -1278,8 +1311,21 @@ vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
                                        drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
                                }
 
-                       text_offset.x = sbt_field_size[i] - stringwidth(sbt_field_title[i], false, hud_fontsize);
+                       vector prev_drawfontscale = drawfontscale;
+                       float titlewidth = stringwidth(sbt_field_title[i], false, hud_fontsize);
+                       if (sbt_field_title_condense_factor[i])
+                       {
+                               drawfontscale.x *= sbt_field_title_condense_factor[i];
+                               text_offset.x = sbt_field_size[i] - titlewidth * sbt_field_title_condense_factor[i];
+                       }
+                       else
+                               text_offset.x = sbt_field_size[i] - titlewidth;
                        drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
+                       if (sbt_field_title_condense_factor[i])
+                       {
+                               drawfontscale.x *= sbt_field_title_condense_factor[i];
+                               drawfontscale = prev_drawfontscale;
+                       }
                        pos.x -= hud_fontsize.x;
                }
        }
@@ -1331,7 +1377,7 @@ void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, i
                        continue;
                }
                str = Scoreboard_GetField(pl, field, autocvar_hud_panel_scoreboard_scores_per_round);
-               str = Scoreboard_FixColumnWidth(i, str);
+               str = Scoreboard_FixColumnWidth(i, str, false);
 
                pos.x += sbt_field_size[i] + hud_fontsize.x;
 
@@ -1367,7 +1413,7 @@ void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, i
                        }
 
                        str = Scoreboard_GetField(pl, field, autocvar_hud_panel_scoreboard_scores_per_round);
-                       str = Scoreboard_FixColumnWidth(i, str);
+                       str = Scoreboard_FixColumnWidth(i, str, false);
 
                        if(field == SP_NAME) {
                                tmp.x = sbt_fixcolumnwidth_len; // left or right aligned? let's put it right...
@@ -2240,6 +2286,8 @@ string Scoreboard_Fraglimit_Draw(float limit, bool is_leadlimit)
 
 void Scoreboard_Draw()
 {
+       bool sb_init_field_sizes = false;
+
        if(!autocvar__hud_configure)
        {
                if(!hud_draw_maximized) return;
@@ -2255,11 +2303,21 @@ void Scoreboard_Draw()
                                scoreboard_fade_alpha = min(1, scoreboard_fade_alpha + frametime * scoreboard_fadeinspeed);
                        else
                                scoreboard_fade_alpha = 1;
+
+                       static string hud_fontsize_str;
                        if(hud_fontsize_str != autocvar_hud_fontsize)
                        {
                                hud_fontsize = HUD_GetFontsize("hud_fontsize");
-                               Scoreboard_initFieldSizes();
                                strcpy(hud_fontsize_str, autocvar_hud_fontsize);
+                               sb_init_field_sizes = true;
+                       }
+
+                       static float scoreboard_table_fieldtitle_maxwidth_prev;
+                       if (scoreboard_table_fieldtitle_maxwidth_prev != autocvar_hud_panel_scoreboard_table_fieldtitle_maxwidth)
+                       {
+                               scoreboard_table_fieldtitle_maxwidth_prev = autocvar_hud_panel_scoreboard_table_fieldtitle_maxwidth;
+                               sbt_field_title_maxwidth = vid_conwidth * max(0.01, autocvar_hud_panel_scoreboard_table_fieldtitle_maxwidth);
+                               sb_init_field_sizes = true;
                        }
                }
                else {
@@ -2309,6 +2367,10 @@ void Scoreboard_Draw()
        panel_pos.x = scoreboard_left;
        panel_size.x = fixed_scoreboard_width;
 
+       // field sizes can be initialized now after panel_size.x calculation
+       if (!sbt_field_size[0] || sb_init_field_sizes)
+               Scoreboard_initFieldSizes();
+
        Scoreboard_UpdatePlayerTeams();
 
        scoreboard_top = panel_pos.y;