diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 969cdf436..12f390b1c 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -5252,13 +5252,27 @@ void CEditor::InvokeFileDialog(int StorageType, int FileType, const char *pTitle void CEditor::ShowFileDialogError(const char *pFormat, ...) { - static CUI::SMessagePopupContext s_MessagePopupContext; - s_MessagePopupContext.ErrorColor(); + char aMessage[1024]; va_list VarArgs; va_start(VarArgs, pFormat); - str_format_v(s_MessagePopupContext.m_aMessage, sizeof(s_MessagePopupContext.m_aMessage), pFormat, VarArgs); + str_format_v(aMessage, sizeof(aMessage), pFormat, VarArgs); va_end(VarArgs); - UI()->ShowPopupMessage(UI()->MouseX(), UI()->MouseY(), &s_MessagePopupContext); + + auto ContextIterator = m_PopupMessageContexts.find(aMessage); + CUI::SMessagePopupContext *pContext; + if(ContextIterator != m_PopupMessageContexts.end()) + { + pContext = ContextIterator->second; + UI()->ClosePopupMenu(pContext); + } + else + { + pContext = new CUI::SMessagePopupContext(); + pContext->ErrorColor(); + str_copy(pContext->m_aMessage, aMessage); + m_PopupMessageContexts[pContext->m_aMessage] = pContext; + } + UI()->ShowPopupMessage(UI()->MouseX(), UI()->MouseY(), pContext); } void CEditor::RenderModebar(CUIRect View) @@ -6504,6 +6518,7 @@ void CEditor::Render() // Popup menus must be rendered before the statusbar, because UI elements in // popup menus can set tooltips, which are rendered in the status bar. UI()->RenderPopupMenus(); + FreeDynamicPopupMenus(); if(m_GuiActive) RenderStatusbar(StatusBar); @@ -6544,6 +6559,22 @@ void CEditor::RenderSavingIndicator(CUIRect View) UI()->DoLabel(&Label, "Saving…", 24.0f, TEXTALIGN_BR); } +void CEditor::FreeDynamicPopupMenus() +{ + auto Iterator = m_PopupMessageContexts.begin(); + while(Iterator != m_PopupMessageContexts.end()) + { + if(!UI()->IsPopupOpen(Iterator->second)) + { + CUI::SMessagePopupContext *pContext = Iterator->second; + Iterator = m_PopupMessageContexts.erase(Iterator); + delete pContext; + } + else + ++Iterator; + } +} + void CEditor::RenderMousePointer() { if(!m_ShowMousePointer) diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 640dbcbef..d9ab9e35d 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -890,6 +891,14 @@ public: void InvokeFileDialog(int StorageType, int FileType, const char *pTitle, const char *pButtonText, const char *pBasepath, const char *pDefaultName, bool (*pfnFunc)(const char *pFilename, int StorageType, void *pUser), void *pUser); + struct SStringKeyComparator + { + bool operator()(char const *pLhs, char const *pRhs) const + { + return str_comp(pLhs, pRhs) < 0; + } + }; + std::map m_PopupMessageContexts; void ShowFileDialogError(const char *pFormat, ...) GNUC_ATTRIBUTE((format(printf, 2, 3))); @@ -902,6 +911,7 @@ public: void RenderPressedKeys(CUIRect View); void RenderSavingIndicator(CUIRect View); + void FreeDynamicPopupMenus(); void RenderMousePointer(); void ResetMenuBackgroundPositions();