From 812a884c06ec51132d297ffe82923a91201ddb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 5 Nov 2022 14:16:00 +0100 Subject: [PATCH] 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`. --- src/game/editor/editor.h | 21 ++++++++++++++++++--- src/game/editor/popups.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 9db87855b..4a1bd0795 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -3,9 +3,6 @@ #ifndef GAME_EDITOR_EDITOR_H #define GAME_EDITOR_EDITOR_H -#include -#include - #include #include @@ -19,6 +16,9 @@ #include "auto_map.h" #include +#include +#include +#include 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 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); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index fe001b64a..981e19187 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -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(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); +}