#include "UI.h" #pragma push_macro("byte") #pragma push_macro("GetNextSibling") #pragma push_macro("GetFirstChild") #undef byte #undef GetNextSibling #undef GetFirstChild #include "UIScene_MessageBox.h" #include "RmlManager.h" #include "../../Windows64/KeyboardMouseInput.h" #include #include #pragma pop_macro("GetFirstChild") #pragma pop_macro("GetNextSibling") #pragma pop_macro("byte") extern KeyboardMouseInput g_KBMInput; UIScene_MessageBox::UIScene_MessageBox(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) , m_document(nullptr) , m_buttonCount(0) , m_Func(nullptr) , m_lpParam(nullptr) { MessageBoxInfo *param = static_cast(initData); m_Func = param->Func; m_lpParam = param->lpParam; m_buttonCount = param->uiOptionC; Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx) { app.DebugPrintf("[RmlMsgBox] No RmlUi context available\n"); return; } m_document = ctx->LoadDocument("MessageBox.rml"); if (!m_document) { app.DebugPrintf("[RmlMsgBox] Failed to load MessageBox.rml\n"); return; } app.DebugPrintf("[RmlMsgBox] Document loaded OK\n"); m_document->GetElementById("button0")->AddEventListener(Rml::EventId::Click, this); m_document->GetElementById("button1")->AddEventListener(Rml::EventId::Click, this); m_document->GetElementById("button2")->AddEventListener(Rml::EventId::Click, this); m_document->GetElementById("button3")->AddEventListener(Rml::EventId::Click, this); wstring titleText = app.GetString(param->uiTitle); wstring descText = app.GetString(param->uiText); auto* titleEl = m_document->GetElementById("title"); auto* descEl = m_document->GetElementById("description"); Rml::String titleUtf8(titleText.begin(), titleText.end()); Rml::String descUtf8(descText.begin(), descText.end()); if (titleEl) titleEl->SetInnerRML(titleUtf8); if (descEl) descEl->SetInnerRML(descUtf8); int buttonIndex = 0; Rml::Element* buttons[4] = { m_document->GetElementById("button0"), m_document->GetElementById("button1"), m_document->GetElementById("button2"), m_document->GetElementById("button3") }; for (int i = 0; i < 4; i++) { if (buttons[i]) buttons[i]->SetProperty("display", "none"); } if (m_buttonCount > 3 && buttons[0]) { wstring label = app.GetString(param->uiOptionA[buttonIndex]); buttons[0]->SetInnerRML(Rml::String(label.begin(), label.end())); buttons[0]->SetProperty("display", "block"); ++buttonIndex; } if (m_buttonCount > 2 && buttons[1]) { wstring label = app.GetString(param->uiOptionA[buttonIndex]); buttons[1]->SetInnerRML(Rml::String(label.begin(), label.end())); buttons[1]->SetProperty("display", "block"); ++buttonIndex; } if (m_buttonCount > 1 && buttons[2]) { wstring label = app.GetString(param->uiOptionA[buttonIndex]); buttons[2]->SetInnerRML(Rml::String(label.begin(), label.end())); buttons[2]->SetProperty("display", "block"); ++buttonIndex; } if (buttons[3]) { wstring label = app.GetString(param->uiOptionA[buttonIndex]); buttons[3]->SetInnerRML(Rml::String(label.begin(), label.end())); buttons[3]->SetProperty("display", "block"); } int focusButton = param->dwFocusButton; if (focusButton >= 0 && focusButton < 4 && buttons[focusButton]) buttons[focusButton]->Focus(); m_document->Show(); parentLayer->addComponent(iPad, eUIComponent_MenuBackground); } UIScene_MessageBox::~UIScene_MessageBox() { if (m_document) { m_document->GetElementById("button0")->RemoveEventListener(Rml::EventId::Click, this); m_document->GetElementById("button1")->RemoveEventListener(Rml::EventId::Click, this); m_document->GetElementById("button2")->RemoveEventListener(Rml::EventId::Click, this); m_document->GetElementById("button3")->RemoveEventListener(Rml::EventId::Click, this); m_document->Close(); m_document = nullptr; } m_parentLayer->removeComponent(eUIComponent_MenuBackground); } void UIScene_MessageBox::gainFocus() { if (!bHasFocus && stealsFocus()) { bHasFocus = true; updateTooltips(); updateComponents(); handleGainFocus(m_bFocussedOnce); if (bHasFocus) m_bFocussedOnce = true; if (m_document) m_document->Show(); } } void UIScene_MessageBox::handleLoseFocus() { if (m_document) m_document->Hide(); } void UIScene_MessageBox::reloadMovie(bool force) { } void UIScene_MessageBox::tick() { m_hasTickedOnce = true; UIScene::tick(); Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx || !bHasFocus) return; ctx->ProcessMouseMove(g_KBMInput.GetMouseX(), g_KBMInput.GetMouseY(), 0); if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT)) ctx->ProcessMouseButtonDown(0, 0); if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_LEFT)) ctx->ProcessMouseButtonUp(0, 0); if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_RIGHT)) ctx->ProcessMouseButtonDown(1, 0); if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_RIGHT)) ctx->ProcessMouseButtonUp(1, 0); int wheelDelta = g_KBMInput.GetMouseWheel(); if (wheelDelta != 0) ctx->ProcessMouseWheel(wheelDelta / -120, 0); ctx->Update(); } void UIScene_MessageBox::render(S32 width, S32 height, C4JRender::eViewportType viewport) { } void UIScene_MessageBox::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) { Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx) return; if (!pressed) return; switch (key) { case ACTION_MENU_UP: ctx->ProcessKeyDown(Rml::Input::KI_UP, 0); handled = true; break; case ACTION_MENU_DOWN: ctx->ProcessKeyDown(Rml::Input::KI_DOWN, 0); handled = true; break; case ACTION_MENU_OK: if (g_KBMInput.IsKeyPressed(VK_RETURN)) { ctx->ProcessKeyDown(Rml::Input::KI_RETURN, 0); handled = true; } break; case ACTION_MENU_CANCEL: { C4JStorage::EMessageResult result = C4JStorage::EMessage_Cancelled; int( *tmpFunc)(LPVOID,int,const C4JStorage::EMessageResult) = m_Func; LPVOID tmpParam = m_lpParam; int tmpPad = m_iPad; navigateBack(); if (tmpFunc) tmpFunc(tmpParam, tmpPad, result); handled = true; break; } default: break; } } bool UIScene_MessageBox::hasFocus(int iPad) { if (m_iPad == 255) return bHasFocus; else if (ProfileManager.IsSignedIn(m_iPad)) return bHasFocus && (iPad == m_iPad); else return bHasFocus; } void UIScene_MessageBox::ProcessEvent(Rml::Event& event) { const Rml::String& id = event.GetCurrentElement()->GetId(); if (event == Rml::EventId::Click) { if (id == "button0") OnButtonClicked(0); else if (id == "button1") OnButtonClicked(1); else if (id == "button2") OnButtonClicked(2); else if (id == "button3") OnButtonClicked(3); } } void UIScene_MessageBox::OnButtonClicked(int buttonIndex) { C4JStorage::EMessageResult result = C4JStorage::EMessage_Cancelled; switch (buttonIndex) { case 0: result = C4JStorage::EMessage_ResultAccept; break; case 1: result = C4JStorage::EMessage_ResultDecline; break; case 2: result = C4JStorage::EMessage_ResultThirdOption; break; case 3: result = C4JStorage::EMessage_ResultFourthOption; break; } ui.PlayUISFX(eSFX_Press); int( *tmpFunc)(LPVOID,int,const C4JStorage::EMessageResult) = m_Func; LPVOID tmpParam = m_lpParam; int tmpPad = m_iPad; navigateBack(); if (tmpFunc) tmpFunc(tmpParam, tmpPad, result); } void UIScene_MessageBox::navigateBack() { UIScene::navigateBack(); }