Add generic selection popup to editor

Add `CEditor::ShowPopupSelection` to show a generic selection popup.

This popups shows a message and buttons for all entries in a `std::set`. Exactly one entry can be selected and the selection will be available to the caller in the given `SSelectionPopupContext`.
This commit is contained in:
Robert Müller 2022-11-05 14:16:00 +01:00
parent 896dd4ecd4
commit 812a884c06
2 changed files with 55 additions and 3 deletions

View file

@ -3,9 +3,6 @@
#ifndef GAME_EDITOR_EDITOR_H
#define GAME_EDITOR_EDITOR_H
#include <string>
#include <vector>
#include <base/system.h>
#include <game/client/render.h>
@ -19,6 +16,9 @@
#include "auto_map.h"
#include <chrono>
#include <set>
#include <string>
#include <vector>
using namespace std::chrono_literals;
@ -1112,6 +1112,21 @@ public:
static int PopupMessage(CEditor *pEditor, CUIRect View, void *pContext);
void ShowPopupMessage(float X, float Y, SMessagePopupContext *pContext);
struct SSelectionPopupContext
{
static constexpr float POPUP_MAX_WIDTH = 300.0f;
static constexpr float POPUP_FONT_SIZE = 10.0f;
static constexpr float POPUP_ENTRY_HEIGHT = 12.0f;
static constexpr float POPUP_ENTRY_SPACING = 5.0f;
char m_aMessage[256];
std::set<std::string> m_Entries;
const std::string *m_pSelection;
SSelectionPopupContext();
};
static int PopupSelection(CEditor *pEditor, CUIRect View, void *pContext);
void ShowPopupSelection(float X, float Y, SSelectionPopupContext *pContext);
static void CallbackOpenMap(const char *pFileName, int StorageType, void *pUser);
static void CallbackAppendMap(const char *pFileName, int StorageType, void *pUser);
static void CallbackSaveMap(const char *pFileName, int StorageType, void *pUser);

View file

@ -1901,3 +1901,40 @@ void CEditor::ShowPopupMessage(float X, float Y, SMessagePopupContext *pContext)
const int LineCount = TextRender()->TextLineCount(nullptr, SMessagePopupContext::POPUP_FONT_SIZE, pContext->m_aMessage, TextWidth);
UiInvokePopupMenu(pContext, 0, X, Y, TextWidth + 10.0f, LineCount * SMessagePopupContext::POPUP_FONT_SIZE + 10.0f, PopupMessage, pContext);
}
CEditor::SSelectionPopupContext::SSelectionPopupContext()
{
m_pSelection = nullptr;
}
int CEditor::PopupSelection(CEditor *pEditor, CUIRect View, void *pContext)
{
SSelectionPopupContext *pSelectionPopup = static_cast<SSelectionPopupContext *>(pContext);
CUIRect Slot;
const int LineCount = pEditor->TextRender()->TextLineCount(nullptr, SSelectionPopupContext::POPUP_FONT_SIZE, pSelectionPopup->m_aMessage, SSelectionPopupContext::POPUP_MAX_WIDTH);
View.HSplitTop(LineCount * SSelectionPopupContext::POPUP_FONT_SIZE, &Slot, &View);
CTextCursor Cursor;
pEditor->TextRender()->SetCursor(&Cursor, Slot.x, Slot.y, SSelectionPopupContext::POPUP_FONT_SIZE, TEXTFLAG_RENDER);
Cursor.m_LineWidth = Slot.w;
pEditor->TextRender()->TextEx(&Cursor, pSelectionPopup->m_aMessage, -1);
for(const auto &Entry : pSelectionPopup->m_Entries)
{
View.HSplitTop(SSelectionPopupContext::POPUP_ENTRY_SPACING, nullptr, &View);
View.HSplitTop(SSelectionPopupContext::POPUP_ENTRY_HEIGHT, &Slot, &View);
if(pEditor->DoButton_MenuItem(&Entry, Entry.c_str(), 0, &Slot, 0, nullptr))
pSelectionPopup->m_pSelection = &Entry;
}
return pSelectionPopup->m_pSelection == nullptr ? 0 : 1;
}
void CEditor::ShowPopupSelection(float X, float Y, SSelectionPopupContext *pContext)
{
const int LineCount = TextRender()->TextLineCount(nullptr, SSelectionPopupContext::POPUP_FONT_SIZE, pContext->m_aMessage, SSelectionPopupContext::POPUP_MAX_WIDTH);
const float PopupHeight = LineCount * SSelectionPopupContext::POPUP_FONT_SIZE + pContext->m_Entries.size() * (SSelectionPopupContext::POPUP_ENTRY_HEIGHT + SSelectionPopupContext::POPUP_ENTRY_SPACING) + 10.0f;
pContext->m_pSelection = nullptr;
UiInvokePopupMenu(pContext, 0, X, Y, SSelectionPopupContext::POPUP_MAX_WIDTH + 10.0f, PopupHeight, PopupSelection, pContext);
}