162 lines
5.4 KiB
C++
162 lines
5.4 KiB
C++
#include "ui/wherigo_dialog.h"
|
|
#include "lua/media_manager.h"
|
|
#include "lua/game_engine.h"
|
|
|
|
#include <wx/sizer.h>
|
|
#include <wx/stattext.h>
|
|
#include <wx/statbmp.h>
|
|
#include <wx/button.h>
|
|
#include <wx/log.h>
|
|
#include <wx/mstream.h>
|
|
#include <wx/image.h>
|
|
|
|
namespace wherigo {
|
|
|
|
WherigoMessageDialog::WherigoMessageDialog(wxWindow *parent, const wxString &text,
|
|
const wxString &title,
|
|
const std::vector<wxString> &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<int>(800 * contentScaleFactor);
|
|
int maxHeight = static_cast<int>(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<void(int)> callback) {
|
|
WherigoMessageDialog dlg(nullptr, text, title);
|
|
dlg.ShowModal();
|
|
|
|
if (callback) {
|
|
callback(dlg.getSelectedButton());
|
|
}
|
|
}
|
|
|
|
void WherigoDialogRunner::showDialog(const std::vector<DialogEntry> &entries,
|
|
std::function<void(int)> callback) {
|
|
for (size_t i = 0; i < entries.size(); i++) {
|
|
const auto &entry = entries[i];
|
|
|
|
std::vector<wxString> 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
|
|
|