Skip to content

Commit

Permalink
Merge ddnet#6834
Browse files Browse the repository at this point in the history
6834: Support showing multiple different error messages in editor r=def- a=Robyt3

Previously the same message popup context was used for all error messages. While multiple message popups could be opened at the same time, the message would always be the same for all, as the same buffer was used for all popups.

This is fixed by creating and destroying the message popup contexts dynamically, so there can be any number of message popups with different messages. Additionally, if a popup with an identical message is already open, it will first be closed and then reopened at the new position, to prevent duplicate message popups.

## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <[email protected]>
  • Loading branch information
bors[bot] and Robyt3 authored Jul 11, 2023
2 parents b9c3d78 + fcd219b commit c8eae4c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/game/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions src/game/editor/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <chrono>
#include <deque>
#include <map>
#include <string>
#include <vector>

Expand Down Expand Up @@ -890,6 +891,14 @@ class CEditor : public IEditor
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<const char *, CUI::SMessagePopupContext *, SStringKeyComparator> m_PopupMessageContexts;
void ShowFileDialogError(const char *pFormat, ...)
GNUC_ATTRIBUTE((format(printf, 2, 3)));

Expand All @@ -902,6 +911,7 @@ class CEditor : public IEditor

void RenderPressedKeys(CUIRect View);
void RenderSavingIndicator(CUIRect View);
void FreeDynamicPopupMenus();
void RenderMousePointer();

void ResetMenuBackgroundPositions();
Expand Down

0 comments on commit c8eae4c

Please sign in to comment.