#include "ui/wherigo_dialog.h" #include "lua/media_manager.h" #include "lua/game_engine.h" #include #include #include #include #include #include #include namespace wherigo { WherigoMessageDialog::WherigoMessageDialog(wxWindow *parent, const wxString &text, const wxString &title, const std::vector &buttons, const wxString &mediaName) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { auto *sizer = new wxBoxSizer(wxVERTICAL); // Media/Image (if provided) if (!mediaName.IsEmpty()) { auto mediaData = MediaManager::getInstance().getMediaByName(mediaName.ToStdString()); if (!mediaData.empty()) { wxMemoryInputStream stream(mediaData.data(), mediaData.size()); wxImage image(stream); if (image.IsOk()) { // Get screen DPI for scaling wxWindow* topWindow = wxTheApp->GetTopWindow(); double contentScaleFactor = 1.0; if (topWindow) { contentScaleFactor = topWindow->GetContentScaleFactor(); } // Scale image - doubled size from original (800x600 instead of 400x300) // Adjust for DPI/Retina displays int maxWidth = static_cast(800 * contentScaleFactor); int maxHeight = static_cast(600 * contentScaleFactor); if (image.GetWidth() > maxWidth || image.GetHeight() > maxHeight) { double scaleX = (double)maxWidth / image.GetWidth(); double scaleY = (double)maxHeight / image.GetHeight(); double scale = std::min(scaleX, scaleY); image.Rescale(image.GetWidth() * scale, image.GetHeight() * scale, wxIMAGE_QUALITY_HIGH); } wxBitmap bitmap(image); auto *imageCtrl = new wxStaticBitmap(this, wxID_ANY, bitmap); sizer->Add(imageCtrl, 0, wxALL | wxALIGN_CENTER, 10); } else { wxLogDebug("Failed to load image: %s", mediaName); auto *mediaLabel = new wxStaticText(this, wxID_ANY, wxString::Format("[Media: %s]", mediaName)); mediaLabel->SetForegroundColour(*wxLIGHT_GREY); sizer->Add(mediaLabel, 0, wxALL | wxALIGN_CENTER, 10); } } else { wxLogDebug("No media data for: %s", mediaName); auto *mediaLabel = new wxStaticText(this, wxID_ANY, wxString::Format("[Media: %s]", mediaName)); mediaLabel->SetForegroundColour(*wxLIGHT_GREY); sizer->Add(mediaLabel, 0, wxALL | wxALIGN_CENTER, 10); } } // Text (only show if not just a placeholder like ".") if (!text.IsEmpty() && text != ".") { auto *textCtrl = new wxStaticText(this, wxID_ANY, text); textCtrl->Wrap(800); // Also doubled wrap width sizer->Add(textCtrl, 1, wxALL | wxEXPAND, 15); } else if (mediaName.IsEmpty()) { // No media and empty/placeholder text - show something auto *textCtrl = new wxStaticText(this, wxID_ANY, text); textCtrl->Wrap(800); // Also doubled wrap width sizer->Add(textCtrl, 1, wxALL | wxEXPAND, 15); } // Buttons auto *buttonSizer = new wxBoxSizer(wxHORIZONTAL); if (buttons.empty()) { auto *okButton = new wxButton(this, wxID_OK, "OK"); buttonSizer->Add(okButton, 0, wxALL, 5); okButton->Bind(wxEVT_BUTTON, &WherigoMessageDialog::onButton, this); } else { for (size_t i = 0; i < buttons.size(); i++) { auto *btn = new wxButton(this, 1000 + i, buttons[i]); buttonSizer->Add(btn, 0, wxALL, 5); btn->Bind(wxEVT_BUTTON, &WherigoMessageDialog::onButton, this); } } sizer->Add(buttonSizer, 0, wxALIGN_CENTER | wxBOTTOM, 10); SetSizerAndFit(sizer); SetMinSize(wxSize(600, 300)); // Doubled from 300x150 CenterOnParent(); } void WherigoMessageDialog::onButton(wxCommandEvent &event) { int id = event.GetId(); if (id == wxID_OK) { m_selectedButton = 0; } else { m_selectedButton = id - 1000; } EndModal(wxID_OK); } WherigoDialogRunner& WherigoDialogRunner::getInstance() { static WherigoDialogRunner instance; return instance; } void WherigoDialogRunner::showMessageBox(const wxString &text, const wxString &title, std::function callback) { WherigoMessageDialog dlg(nullptr, text, title); dlg.ShowModal(); if (callback) { callback(dlg.getSelectedButton()); } } void WherigoDialogRunner::showDialog(const std::vector &entries, std::function callback) { for (size_t i = 0; i < entries.size(); i++) { const auto &entry = entries[i]; std::vector buttons; for (const auto &btn : entry.buttons) { buttons.push_back(wxString::FromUTF8(btn)); } if (buttons.empty() && i < entries.size() - 1) { buttons.push_back("Weiter"); } else if (buttons.empty()) { buttons.push_back("OK"); } WherigoMessageDialog dlg(nullptr, wxString::FromUTF8(entry.text), "Wherigo", buttons, wxString::FromUTF8(entry.mediaName)); dlg.ShowModal(); // For the last entry, call the callback with the selected button if (i == entries.size() - 1 && callback) { callback(dlg.getSelectedButton()); } } // Notify game state change after dialog sequence completes GameEngine::getInstance().notifyStateChanged(); } } // namespace wherigo