Add button to reload entities background, improve DDNet menu layout

Add a button to manually reload the entities background map instead of automatically reloading it when it's changed. As the background map was only reloaded every 10 seconds, sometimes changing the background map quickly had no effect.

Improve the layout of the DDNet settings menu. Align labels and UI elements and reduce unused empty space.
This commit is contained in:
Robert Müller 2023-07-28 23:31:17 +02:00
parent 7c1a667486
commit 6633e9af1d
5 changed files with 121 additions and 136 deletions

View file

@ -20,7 +20,6 @@ CBackground::CBackground(int MapType, bool OnlineOnly) :
m_pBackgroundImages = m_pImages;
m_Loaded = false;
m_aMapName[0] = '\0';
m_LastLoad = 0;
}
CBackground::~CBackground()
@ -47,9 +46,6 @@ void CBackground::OnInit()
void CBackground::LoadBackground()
{
if(time_get() - m_LastLoad < 10 * time_freq())
return;
if(m_Loaded && m_pMap == m_pBackgroundMap)
m_pMap->Unload();
@ -58,53 +54,49 @@ void CBackground::LoadBackground()
m_pLayers = m_pBackgroundLayers;
m_pImages = m_pBackgroundImages;
bool NeedImageLoading = false;
str_copy(m_aMapName, g_Config.m_ClBackgroundEntities);
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "maps/%s", g_Config.m_ClBackgroundEntities);
if(str_comp(g_Config.m_ClBackgroundEntities, CURRENT_MAP) == 0)
if(g_Config.m_ClBackgroundEntities[0] != '\0')
{
m_pMap = Kernel()->RequestInterface<IEngineMap>();
if(m_pMap->IsLoaded())
bool NeedImageLoading = false;
char aBuf[IO_MAX_PATH_LENGTH];
str_format(aBuf, sizeof(aBuf), "maps/%s", g_Config.m_ClBackgroundEntities);
if(str_comp(g_Config.m_ClBackgroundEntities, CURRENT_MAP) == 0)
{
m_pLayers = GameClient()->Layers();
m_pImages = &GameClient()->m_MapImages;
m_pMap = Kernel()->RequestInterface<IEngineMap>();
if(m_pMap->IsLoaded())
{
m_pLayers = GameClient()->Layers();
m_pImages = &GameClient()->m_MapImages;
m_Loaded = true;
}
}
else if(m_pMap->Load(aBuf))
{
m_pLayers->InitBackground(m_pMap);
NeedImageLoading = true;
m_Loaded = true;
}
}
else if(m_pMap->Load(aBuf))
{
m_pLayers->InitBackground(m_pMap);
NeedImageLoading = true;
m_Loaded = true;
}
if(m_Loaded)
{
CMapLayers::OnMapLoad();
if(NeedImageLoading)
m_pImages->LoadBackground(m_pLayers, m_pMap);
if(m_Loaded)
{
CMapLayers::OnMapLoad();
if(NeedImageLoading)
m_pImages->LoadBackground(m_pLayers, m_pMap);
}
}
m_LastLoad = time_get();
}
void CBackground::OnMapLoad()
{
if(str_comp(g_Config.m_ClBackgroundEntities, CURRENT_MAP) == 0 || str_comp(g_Config.m_ClBackgroundEntities, m_aMapName))
{
m_LastLoad = 0;
LoadBackground();
}
}
void CBackground::OnRender()
{
//probably not the best place for this
if(g_Config.m_ClBackgroundEntities[0] != '\0' && str_comp(g_Config.m_ClBackgroundEntities, m_aMapName))
LoadBackground();
if(!m_Loaded)
return;

View file

@ -25,9 +25,6 @@ protected:
bool m_Loaded;
char m_aMapName[MAX_MAP_LENGTH];
//to avoid spam when in menu
int64_t m_LastLoad;
//to avoid memory leak when switching to %current%
CBackgroundEngineMap *m_pBackgroundMap;
CLayers *m_pBackgroundLayers;
@ -45,6 +42,7 @@ public:
virtual void OnRender() override;
void LoadBackground();
const char *MapName() const { return m_aMapName; }
};
#endif

View file

@ -307,8 +307,6 @@ void CMenuBackground::LoadMenuBackground(bool HasDayHint, bool HasNightHint)
}
}
}
m_LastLoad = time_get();
}
}

View file

@ -376,7 +376,7 @@ ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float Lin
Section.VSplitLeft(5.0f, nullptr, &Section);
}
Section.VSplitMid(&Label, &Section, Section.h);
Section.VSplitMid(&Label, &Section, 4.0f);
Section.VSplitRight(60.0f, &Section, &ResetButton);
Section.VSplitRight(8.0f, &Section, nullptr);
Section.VSplitRight(Section.h, &Section, &ColorPickerButton);
@ -386,7 +386,7 @@ ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float Lin
ColorHSLA PickedColor = DoButton_ColorPicker(&ColorPickerButton, pColorValue, Alpha);
ResetButton.HMargin(2.0f, &ResetButton);
if(DoButton_Menu(pResetID, Localize("Reset"), 0, &ResetButton, nullptr, IGraphics::CORNER_ALL, 8.0f, 0.0f, vec4(1, 1, 1, 0.5f), vec4(1, 1, 1, 0.25f)))
if(DoButton_Menu(pResetID, Localize("Reset"), 0, &ResetButton, nullptr, IGraphics::CORNER_ALL, 4.0f, 0.1f, vec4(1, 1, 1, 0.5f), vec4(1, 1, 1, 0.25f)))
{
*pColorValue = color_cast<ColorHSLA>(DefaultColor).Pack(Alpha);
}

View file

@ -2022,6 +2022,7 @@ void CMenus::RenderSettings(CUIRect MainView)
}
MainView.Margin(10.0f, &MainView);
RestartWarning.VMargin(10.0f, &RestartWarning);
if(g_Config.m_UiSettingsPage == SETTINGS_LANGUAGE)
{
@ -2949,16 +2950,21 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView)
void CMenus::RenderSettingsDDNet(CUIRect MainView)
{
CUIRect Button, Left, Right, LeftLeft, Demo, Gameplay, Miscellaneous, Label, Background;
CUIRect Button, Left, Right, LeftLeft, Label;
MainView.HSplitTop(100.0f, &Demo, &MainView);
#if defined(CONF_AUTOUPDATE)
CUIRect UpdaterRect;
MainView.HSplitBottom(20.0f, &MainView, &UpdaterRect);
MainView.HSplitBottom(5.0f, &MainView, nullptr);
#endif
// demo
CUIRect Demo;
MainView.HSplitTop(110.0f, &Demo, &MainView);
Demo.HSplitTop(30.0f, &Label, &Demo);
UI()->DoLabel(&Label, Localize("Demo"), 20.0f, TEXTALIGN_ML);
Demo.Margin(5.0f, &Demo);
Demo.VSplitMid(&Left, &Right);
Left.VSplitRight(5.0f, &Left, 0);
Right.VMargin(5.0f, &Right);
Demo.HSplitTop(5.0f, nullptr, &Demo);
Demo.VSplitMid(&Left, &Right, 20.0f);
Left.HSplitTop(20.0f, &Button, &Left);
if(DoButton_CheckBox(&g_Config.m_ClAutoRaceRecord, Localize("Save the best demo of each race"), g_Config.m_ClAutoRaceRecord, &Button))
@ -2966,29 +2972,26 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
g_Config.m_ClAutoRaceRecord ^= 1;
}
Left.HSplitTop(20.0f, &Button, &Left);
if(DoButton_CheckBox(&g_Config.m_ClReplays, Localize("Enable replays"), g_Config.m_ClReplays, &Button))
{
Left.HSplitTop(20.0f, &Button, &Left);
if(DoButton_CheckBox(&g_Config.m_ClReplays, Localize("Enable replays"), g_Config.m_ClReplays, &Button))
g_Config.m_ClReplays ^= 1;
if(!g_Config.m_ClReplays)
{
g_Config.m_ClReplays ^= 1;
if(!g_Config.m_ClReplays)
{
// stop recording and remove the tmp demo file
Client()->DemoRecorder_Stop(RECORDER_REPLAYS, true);
}
else
{
// start recording
Client()->DemoRecorder_HandleAutoStart();
}
// stop recording and remove the tmp demo file
Client()->DemoRecorder_Stop(RECORDER_REPLAYS, true);
}
else
{
// start recording
Client()->DemoRecorder_HandleAutoStart();
}
Left.HSplitTop(20.0f, &Button, &Left);
if(g_Config.m_ClReplays)
UI()->DoScrollbarOption(&g_Config.m_ClReplayLength, &g_Config.m_ClReplayLength, &Button, Localize("Default length"), 10, 600, &CUI::ms_LinearScrollbarScale, CUI::SCROLLBAR_OPTION_NOCLAMPVALUE);
}
Left.HSplitTop(20.0f, &Button, &Left);
if(g_Config.m_ClReplays)
UI()->DoScrollbarOption(&g_Config.m_ClReplayLength, &g_Config.m_ClReplayLength, &Button, Localize("Default length"), 10, 600, &CUI::ms_LinearScrollbarScale, CUI::SCROLLBAR_OPTION_NOCLAMPVALUE);
Right.HSplitTop(20.0f, &Button, &Right);
if(DoButton_CheckBox(&g_Config.m_ClRaceGhost, Localize("Ghost"), g_Config.m_ClRaceGhost, &Button))
{
@ -3011,42 +3014,35 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
}
}
MainView.HSplitTop(330.0f, &Gameplay, &MainView);
// gameplay
CUIRect Gameplay;
MainView.HSplitTop(150.0f, &Gameplay, &MainView);
Gameplay.HSplitTop(30.0f, &Label, &Gameplay);
UI()->DoLabel(&Label, Localize("Gameplay"), 20.0f, TEXTALIGN_ML);
Gameplay.Margin(5.0f, &Gameplay);
Gameplay.VSplitMid(&Left, &Right);
Left.VSplitRight(5.0f, &Left, 0);
Right.VMargin(5.0f, &Right);
Gameplay.HSplitTop(5.0f, nullptr, &Gameplay);
Gameplay.VSplitMid(&Left, &Right, 20.0f);
{
Left.HSplitTop(20.0f, &Button, &Left);
UI()->DoScrollbarOption(&g_Config.m_ClOverlayEntities, &g_Config.m_ClOverlayEntities, &Button, Localize("Overlay entities"), 0, 100);
}
Left.HSplitTop(20.0f, &Button, &Left);
UI()->DoScrollbarOption(&g_Config.m_ClOverlayEntities, &g_Config.m_ClOverlayEntities, &Button, Localize("Overlay entities"), 0, 100);
{
Left.HSplitTop(20.0f, &Button, &Left);
Button.VSplitMid(&LeftLeft, &Button);
Left.HSplitTop(20.0f, &Button, &Left);
Button.VSplitMid(&LeftLeft, &Button);
if(DoButton_CheckBox(&g_Config.m_ClTextEntities, Localize("Show text entities"), g_Config.m_ClTextEntities, &LeftLeft))
g_Config.m_ClTextEntities ^= 1;
if(DoButton_CheckBox(&g_Config.m_ClTextEntities, Localize("Show text entities"), g_Config.m_ClTextEntities, &LeftLeft))
g_Config.m_ClTextEntities ^= 1;
if(g_Config.m_ClTextEntities)
UI()->DoScrollbarOption(&g_Config.m_ClTextEntitiesSize, &g_Config.m_ClTextEntitiesSize, &Button, Localize("Size"), 0, 100);
}
if(g_Config.m_ClTextEntities)
UI()->DoScrollbarOption(&g_Config.m_ClTextEntitiesSize, &g_Config.m_ClTextEntitiesSize, &Button, Localize("Size"), 0, 100);
{
Left.HSplitTop(20.0f, &Button, &Left);
Button.VSplitMid(&LeftLeft, &Button);
Left.HSplitTop(20.0f, &Button, &Left);
Button.VSplitMid(&LeftLeft, &Button);
if(DoButton_CheckBox(&g_Config.m_ClShowOthers, Localize("Show others"), g_Config.m_ClShowOthers == SHOW_OTHERS_ON, &LeftLeft))
g_Config.m_ClShowOthers = g_Config.m_ClShowOthers != SHOW_OTHERS_ON ? SHOW_OTHERS_ON : SHOW_OTHERS_OFF;
if(DoButton_CheckBox(&g_Config.m_ClShowOthers, Localize("Show others"), g_Config.m_ClShowOthers == SHOW_OTHERS_ON, &LeftLeft))
g_Config.m_ClShowOthers = g_Config.m_ClShowOthers != SHOW_OTHERS_ON ? SHOW_OTHERS_ON : SHOW_OTHERS_OFF;
UI()->DoScrollbarOption(&g_Config.m_ClShowOthersAlpha, &g_Config.m_ClShowOthersAlpha, &Button, Localize("Opacity"), 0, 100);
UI()->DoScrollbarOption(&g_Config.m_ClShowOthersAlpha, &g_Config.m_ClShowOthersAlpha, &Button, Localize("Opacity"), 0, 100);
GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClShowOthersAlpha, &Button, Localize("Adjust the opacity of entities belonging to other teams, such as tees and nameplates"));
}
GameClient()->m_Tooltips.DoToolTip(&g_Config.m_ClShowOthersAlpha, &Button, Localize("Adjust the opacity of entities belonging to other teams, such as tees and nameplates"));
Left.HSplitTop(20.0f, &Button, &Left);
static int s_ShowOwnTeamID = 0;
@ -3092,42 +3088,40 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
g_Config.m_ClAntiPingGrenade ^= 1;
}
}
else
{
Right.HSplitTop(60.0f, 0, &Right);
}
Right.HSplitTop(40.0f, 0, &Right);
CUIRect Background, Miscellaneous;
MainView.VSplitMid(&Background, &Miscellaneous, 20.0f);
Left.HSplitTop(5.0f, &Button, &Left);
Left.VSplitRight(10.0f, &Left, 0x0);
Right.VSplitLeft(10.0f, 0x0, &Right);
Left.HSplitTop(25.0f, 0x0, &Left);
CUIRect TempLabel;
Left.HSplitTop(25.0f, &TempLabel, &Left);
Left.HSplitTop(5.0f, 0x0, &Left);
UI()->DoLabel(&TempLabel, Localize("Background"), 20.0f, TEXTALIGN_ML);
Right.HSplitTop(25.0f, &TempLabel, &Right);
Right.HSplitTop(5.0f, 0x0, &Miscellaneous);
UI()->DoLabel(&TempLabel, Localize("Miscellaneous"), 20.0f, TEXTALIGN_ML);
// background
Background.HSplitTop(30.0f, &Label, &Background);
Background.HSplitTop(5.0f, nullptr, &Background);
UI()->DoLabel(&Label, Localize("Background"), 20.0f, TEXTALIGN_ML);
static CButtonContainer s_ResetID2;
ColorRGBA GreyDefault(0.5f, 0.5f, 0.5f, 1);
DoLine_ColorPicker(&s_ResetID2, 25.0f, 13.0f, 5.0f, &Left, Localize("Entities Background color"), &g_Config.m_ClBackgroundEntitiesColor, GreyDefault, false);
DoLine_ColorPicker(&s_ResetID2, 25.0f, 13.0f, 5.0f, &Background, Localize("Entities Background color"), &g_Config.m_ClBackgroundEntitiesColor, GreyDefault, false);
CUIRect EditBox;
Background.HSplitTop(20.0f, &Label, &Background);
Background.HSplitTop(2.0f, nullptr, &Background);
Label.VSplitLeft(100.0f, &Label, &EditBox);
EditBox.VSplitRight(100.0f, &EditBox, &Button);
EditBox.VSplitRight(5.0f, &EditBox, nullptr);
Left.VSplitLeft(5.0f, 0x0, &Left);
Left.HSplitTop(25.0f, &Background, &Left);
Background.HSplitTop(20.0f, &Background, 0);
Background.VSplitLeft(100.0f, &Label, &TempLabel);
UI()->DoLabel(&Label, Localize("Map"), 14.0f, TEXTALIGN_ML);
static CLineInput s_BackgroundEntitiesInput(g_Config.m_ClBackgroundEntities, sizeof(g_Config.m_ClBackgroundEntities));
UI()->DoEditBox(&s_BackgroundEntitiesInput, &TempLabel, 14.0f);
Left.HSplitTop(20.0f, &Button, &Left);
bool UseCurrentMap = str_comp(g_Config.m_ClBackgroundEntities, CURRENT_MAP) == 0;
static CLineInput s_BackgroundEntitiesInput(g_Config.m_ClBackgroundEntities, sizeof(g_Config.m_ClBackgroundEntities));
UI()->DoEditBox(&s_BackgroundEntitiesInput, &EditBox, 14.0f);
static CButtonContainer s_BackgroundEntitiesReloadButton;
if(DoButton_Menu(&s_BackgroundEntitiesReloadButton, Localize("Reload"), 0, &Button))
{
if(str_comp(g_Config.m_ClBackgroundEntities, m_pClient->m_BackGround.MapName()) != 0)
m_pClient->m_BackGround.LoadBackground();
}
Background.HSplitTop(20.0f, &Button, &Background);
const bool UseCurrentMap = str_comp(g_Config.m_ClBackgroundEntities, CURRENT_MAP) == 0;
static int s_UseCurrentMapID = 0;
if(DoButton_CheckBox(&s_UseCurrentMapID, Localize("Use current map as background"), UseCurrentMap, &Button))
{
@ -3135,38 +3129,44 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
g_Config.m_ClBackgroundEntities[0] = '\0';
else
str_copy(g_Config.m_ClBackgroundEntities, CURRENT_MAP);
m_pClient->m_BackGround.LoadBackground();
}
Left.HSplitTop(20.0f, &Button, &Left);
Background.HSplitTop(20.0f, &Button, &Background);
if(DoButton_CheckBox(&g_Config.m_ClBackgroundShowTilesLayers, Localize("Show tiles layers from BG map"), g_Config.m_ClBackgroundShowTilesLayers, &Button))
g_Config.m_ClBackgroundShowTilesLayers ^= 1;
// miscellaneous
Miscellaneous.HSplitTop(30.0f, &Label, &Miscellaneous);
Miscellaneous.HSplitTop(5.0f, nullptr, &Miscellaneous);
UI()->DoLabel(&Label, Localize("Miscellaneous"), 20.0f, TEXTALIGN_ML);
static CButtonContainer s_ResetID1;
Miscellaneous.HSplitTop(25.0f, &Button, &Right);
Miscellaneous.HSplitTop(25.0f, &Button, &Miscellaneous);
DoLine_ColorPicker(&s_ResetID1, 25.0f, 13.0f, 5.0f, &Button, Localize("Regular Background Color"), &g_Config.m_ClBackgroundColor, GreyDefault, false);
static CButtonContainer s_ButtonTimeout;
Right.HSplitTop(10.0f, 0x0, &Right);
Right.HSplitTop(20.0f, &Button, &Right);
Miscellaneous.HSplitTop(10.0f, nullptr, &Miscellaneous);
Miscellaneous.HSplitTop(20.0f, &Button, &Miscellaneous);
if(DoButton_Menu(&s_ButtonTimeout, Localize("New random timeout code"), 0, &Button))
{
Client()->GenerateTimeoutSeed();
}
Right.HSplitTop(5.0f, 0, &Right);
Right.HSplitTop(20.0f, &Label, &Right);
Label.VSplitLeft(5.0f, 0, &Label);
Miscellaneous.HSplitTop(5.0f, nullptr, &Miscellaneous);
Miscellaneous.HSplitTop(20.0f, &Label, &Miscellaneous);
Miscellaneous.HSplitTop(2.0f, nullptr, &Miscellaneous);
UI()->DoLabel(&Label, Localize("Run on join"), 14.0f, TEXTALIGN_ML);
Right.HSplitTop(20.0f, &Button, &Right);
Button.VSplitLeft(5.0f, 0, &Button);
Miscellaneous.HSplitTop(20.0f, &Button, &Miscellaneous);
static CLineInput s_RunOnJoinInput(g_Config.m_ClRunOnJoin, sizeof(g_Config.m_ClRunOnJoin));
s_RunOnJoinInput.SetEmptyText(Localize("Chat command (e.g. showall 1)"));
UI()->DoEditBox(&s_RunOnJoinInput, &Button, 14.0f);
#if defined(CONF_FAMILY_WINDOWS)
static CButtonContainer s_ButtonUnregisterShell;
Right.HSplitTop(10.0f, nullptr, &Right);
Right.HSplitTop(20.0f, &Button, &Right);
Miscellaneous.HSplitTop(10.0f, nullptr, &Miscellaneous);
Miscellaneous.HSplitTop(20.0f, &Button, &Miscellaneous);
if(DoButton_Menu(&s_ButtonUnregisterShell, Localize("Unregister protocol and file extensions"), 0, &Button))
{
Client()->ShellUnregister();
@ -3176,9 +3176,6 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
// Updater
#if defined(CONF_AUTOUPDATE)
{
MainView.VSplitMid(&Left, &Right);
Left.w += 20.0f;
Left.HSplitBottom(20.0f, 0x0, &Label);
bool NeedUpdate = str_comp(Client()->LatestVersion(), "0");
int State = Updater()->GetCurrentState();
@ -3187,8 +3184,8 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
if(NeedUpdate && State <= IUpdater::CLEAN)
{
str_format(aBuf, sizeof(aBuf), Localize("DDNet %s is available:"), Client()->LatestVersion());
Label.VSplitLeft(TextRender()->TextWidth(14.0f, aBuf, -1, -1.0f) + 10.0f, &Label, &Button);
Button.VSplitLeft(100.0f, &Button, 0);
UpdaterRect.VSplitLeft(TextRender()->TextWidth(14.0f, aBuf, -1, -1.0f) + 10.0f, &UpdaterRect, &Button);
Button.VSplitLeft(100.0f, &Button, nullptr);
static CButtonContainer s_ButtonUpdate;
if(DoButton_Menu(&s_ButtonUpdate, Localize("Update now"), 0, &Button))
{
@ -3205,15 +3202,15 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView)
else
{
str_format(aBuf, sizeof(aBuf), Localize("No updates available"));
Label.VSplitLeft(TextRender()->TextWidth(14.0f, aBuf, -1, -1.0f) + 10.0f, &Label, &Button);
Button.VSplitLeft(100.0f, &Button, 0);
UpdaterRect.VSplitLeft(TextRender()->TextWidth(14.0f, aBuf, -1, -1.0f) + 10.0f, &UpdaterRect, &Button);
Button.VSplitLeft(100.0f, &Button, nullptr);
static CButtonContainer s_ButtonUpdate;
if(DoButton_Menu(&s_ButtonUpdate, Localize("Check now"), 0, &Button))
{
Client()->RequestDDNetInfo();
}
}
UI()->DoLabel(&Label, aBuf, 14.0f, TEXTALIGN_ML);
UI()->DoLabel(&UpdaterRect, aBuf, 14.0f, TEXTALIGN_ML);
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
}
#endif