diff --git a/src/gui/dialogues/InformationMessage.cpp b/src/gui/dialogues/InformationMessage.cpp index 20d283bee..21abc4692 100644 --- a/src/gui/dialogues/InformationMessage.cpp +++ b/src/gui/dialogues/InformationMessage.cpp @@ -8,8 +8,9 @@ #include "graphics/Graphics.h" -InformationMessage::InformationMessage(String title, String message, bool large): - ui::Window(ui::Point(-1, -1), ui::Point(200, 35)) +InformationMessage::InformationMessage(String title, String message, bool large, DismissCallback callback_): + ui::Window(ui::Point(-1, -1), ui::Point(200, 35)), + callback(callback_) { if (large) //Maybe also use this large mode for changelogs eventually, or have it as a customizable size? { @@ -61,6 +62,8 @@ InformationMessage::InformationMessage(String title, String message, bool large) okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); okayButton->SetActionCallback({ [this] { CloseActiveWindow(); + if (callback.dismiss) + callback.dismiss(); SelfDestruct(); //TODO: Fix component disposal } }); AddComponent(okayButton); diff --git a/src/gui/dialogues/InformationMessage.h b/src/gui/dialogues/InformationMessage.h index 12a440432..964276dad 100644 --- a/src/gui/dialogues/InformationMessage.h +++ b/src/gui/dialogues/InformationMessage.h @@ -3,8 +3,15 @@ class InformationMessage : public ui::Window { + struct DismissCallback + { + std::function dismiss; + }; + + DismissCallback callback; + public: - InformationMessage(String title, String message, bool large); + InformationMessage(String title, String message, bool large, DismissCallback callback_ = {}); virtual ~InformationMessage() = default; void OnDraw() override; diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index be23d81cb..3d4bdecf8 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -11,10 +11,6 @@ #include "simulation/gravity/Gravity.h" #include "simulation/Simulation.h" #include "simulation/SimulationData.h" -#include "gui/dialogues/ConfirmPrompt.h" -#include "gui/dialogues/ErrorMessage.h" -#include "gui/dialogues/InformationMessage.h" -#include "gui/dialogues/TextPrompt.h" #include "gui/game/GameController.h" #include "gui/game/GameModel.h" #include "gui/interface/Engine.h" @@ -264,8 +260,7 @@ void luacon_hook(lua_State * l, lua_Debug * ar) auto *luacon_ci = static_cast(commandInterface); if (ar->event == LUA_HOOKCOUNT && Platform::GetTime() - luacon_ci->luaExecutionStart > 3000) { - if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop")) - luaL_error(l, "Error: Script not responding"); + luaL_error(l, "Error: Script not responding"); luacon_ci->luaExecutionStart = Platform::GetTime(); } } @@ -303,13 +298,6 @@ int luatpt_getelement(lua_State *l) return 1; } -int luatpt_error(lua_State* l) -{ - String errorMessage = tpt_lua_optString(l, 1, "Error text"); - ErrorMessage::Blocking("Error", errorMessage); - return 0; -} - int luatpt_drawtext(lua_State* l) { int textx, texty, textred, textgreen, textblue, textalpha; @@ -1038,38 +1026,6 @@ int luatpt_delete(lua_State* l) return luaL_error(l,"Invalid coordinates or particle ID"); } -int luatpt_input(lua_State* l) -{ - String title = tpt_lua_optString(l, 1, "Title"); - String prompt = tpt_lua_optString(l, 2, "Enter some text:"); - String text = tpt_lua_optString(l, 3, ""); - String shadow = tpt_lua_optString(l, 4, ""); - - String result = TextPrompt::Blocking(title, prompt, text, shadow, false); - - tpt_lua_pushString(l, result); - return 1; -} - -int luatpt_message_box(lua_State* l) -{ - String title = tpt_lua_optString(l, 1, "Title"); - String message = tpt_lua_optString(l, 2, "Message"); - int large = lua_toboolean(l, 3); - new InformationMessage(title, message, large); - return 0; -} - -int luatpt_confirm(lua_State *l) -{ - String title = tpt_lua_optString(l, 1, "Title"); - String message = tpt_lua_optString(l, 2, "Message"); - String buttonText = tpt_lua_optString(l, 3, "Confirm"); - bool ret = ConfirmPrompt::Blocking(title, message, buttonText); - lua_pushboolean(l, ret ? 1 : 0); - return 1; -} - int luatpt_get_numOfParts(lua_State* l) { lua_pushinteger(l, luacon_sim->NUM_PARTS); diff --git a/src/lua/LuaScriptHelper.h b/src/lua/LuaScriptHelper.h index 43c9b3819..35f2e1b24 100644 --- a/src/lua/LuaScriptHelper.h +++ b/src/lua/LuaScriptHelper.h @@ -49,7 +49,6 @@ int luacon_transitionwrite(lua_State* l); //tpt. api int luatpt_getelement(lua_State *l); -int luatpt_error(lua_State* l); int luatpt_drawtext(lua_State* l); int luatpt_create(lua_State* l); @@ -96,9 +95,6 @@ int luatpt_textwidth(lua_State* l); int luatpt_get_name(lua_State* l); int luatpt_delete(lua_State* l); -int luatpt_input(lua_State* l); -int luatpt_message_box(lua_State* l); -int luatpt_confirm(lua_State* l); int luatpt_get_numOfParts(lua_State* l); int luatpt_start_getPartIndex(lua_State* l); int luatpt_next_getPartIndex(lua_State* l); diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index 7c4e75274..c637858bf 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -38,6 +38,10 @@ #include "simulation/SaveRenderer.h" #include "simulation/Snapshot.h" +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/dialogues/InformationMessage.h" +#include "gui/dialogues/TextPrompt.h" #include "gui/interface/Window.h" #include "gui/interface/Engine.h" #include "gui/game/GameView.h" @@ -345,9 +349,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): {"textwidth", &luatpt_textwidth}, {"get_name", &luatpt_get_name}, {"delete", &luatpt_delete}, - {"input", &luatpt_input}, - {"message_box", &luatpt_message_box}, - {"confirm", &luatpt_confirm}, {"get_numOfParts", &luatpt_get_numOfParts}, {"start_getPartIndex", &luatpt_start_getPartIndex}, {"next_getPartIndex", &luatpt_next_getPartIndex}, @@ -360,7 +361,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): {"num_menus", &luatpt_num_menus}, {"decorations_enable", &luatpt_decorations_enable}, {"display_mode", &luatpt_cmode_set}, - {"throw_error", &luatpt_error}, {"heat", &luatpt_heat}, {"setfire", &luatpt_setfire}, {"setdebug", &luatpt_setdebug}, @@ -660,7 +660,124 @@ int LuaScriptInterface::tpt_newIndex(lua_State *l) return 0; } -//// Begin Interface API +static int beginMessageBox(lua_State* l) +{ + String title = tpt_lua_optString(l, 1, "Title"); + String message = tpt_lua_optString(l, 2, "Message"); + int large = lua_toboolean(l, 3); + auto *luacon_ci = static_cast(commandInterface); + auto cb = std::make_shared(luacon_ci->l); // * Bind to main lua state (might be different from l). + cb->Assign(l, 4); + new InformationMessage(title, message, large, { [cb]() { + auto *luacon_ci = static_cast(commandInterface); + auto l = luacon_ci->l; + cb->Push(l); + if (lua_isfunction(l, -1)) + { + if (lua_pcall(l, 0, 0, 0)) + { + luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); + } + } + else + { + lua_pop(l, 1); + } + } }); + return 0; +} + +static int beginThrowError(lua_State* l) +{ + String errorMessage = tpt_lua_optString(l, 1, "Error text"); + auto *luacon_ci = static_cast(commandInterface); + auto cb = std::make_shared(luacon_ci->l); // * Bind to main lua state (might be different from l). + cb->Assign(l, 2); + new ErrorMessage("Error", errorMessage, { [cb]() { + auto *luacon_ci = static_cast(commandInterface); + auto l = luacon_ci->l; + cb->Push(l); + if (lua_isfunction(l, -1)) + { + if (lua_pcall(l, 0, 0, 0)) + { + luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); + } + } + else + { + lua_pop(l, 1); + } + } }); + return 0; +} + +static int beginInput(lua_State* l) +{ + String title = tpt_lua_optString(l, 1, "Title"); + String prompt = tpt_lua_optString(l, 2, "Enter some text:"); + String text = tpt_lua_optString(l, 3, ""); + String shadow = tpt_lua_optString(l, 4, ""); + auto *luacon_ci = static_cast(commandInterface); + auto cb = std::make_shared(luacon_ci->l); // * Bind to main lua state (might be different from l). + cb->Assign(l, 5); + auto handle = [cb](const String &input) { + auto *luacon_ci = static_cast(commandInterface); + auto l = luacon_ci->l; + cb->Push(l); + if (lua_isfunction(l, -1)) + { + tpt_lua_pushString(l, input); + if (lua_pcall(l, 1, 0, 0)) + { + luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); + } + } + else + { + lua_pop(l, 1); + } + }; + new TextPrompt(title, prompt, text, shadow, false, { [handle](const String &input) { + handle(input); + }, [handle]() { + handle({}); // * Has always returned empty string >_> + } }); + return 0; +} + +static int beginConfirm(lua_State *l) +{ + String title = tpt_lua_optString(l, 1, "Title"); + String message = tpt_lua_optString(l, 2, "Message"); + String buttonText = tpt_lua_optString(l, 3, "Confirm"); + auto *luacon_ci = static_cast(commandInterface); + auto cb = std::make_shared(luacon_ci->l); // * Bind to main lua state (might be different from l). + cb->Assign(l, 4); + auto handle = [cb](int result) { + auto *luacon_ci = static_cast(commandInterface); + auto l = luacon_ci->l; + cb->Push(l); + if (lua_isfunction(l, -1)) + { + lua_pushboolean(l, result); + if (lua_pcall(l, 1, 0, 0)) + { + luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); + } + } + else + { + lua_pop(l, 1); + } + }; + new ConfirmPrompt(title, message, { [handle]() { + handle(1); + }, [handle]() { + handle(0); + } }, buttonText); + return 0; +} void LuaScriptInterface::initInterfaceAPI() { @@ -672,6 +789,10 @@ void LuaScriptInterface::initInterfaceAPI() {"grabTextInput", interface_grabTextInput}, {"dropTextInput", interface_dropTextInput}, {"textInputRect", interface_textInputRect}, + {"beginInput", beginInput}, + {"beginMessageBox", beginMessageBox}, + {"beginConfirm", beginConfirm}, + {"beginThrowError", beginThrowError}, {NULL, NULL} }; luaL_register(l, "interface", interfaceAPIMethods); @@ -4431,8 +4552,9 @@ void LuaScriptInterface::OnTick() new ErrorMessage("Script download", ByteString(http::StatusText(ret)).FromUtf8()); return; } - if (Platform::FileExists(scriptDownloadFilename) && scriptDownloadConfirmPrompt && !ConfirmPrompt::Blocking("File already exists, overwrite?", scriptDownloadFilename.FromUtf8(), "Overwrite")) + if (Platform::FileExists(scriptDownloadFilename)) { + new ErrorMessage("Script download", "File already exists"); return; } if (!Platform::WriteFile(std::vector(scriptData.begin(), scriptData.end()), scriptDownloadFilename)) @@ -4885,7 +5007,6 @@ int LuaScriptInterface::luatpt_getscript(lua_State* l) int scriptID = luaL_checkinteger(l, 1); auto filename = tpt_lua_checkByteString(l, 2); bool runScript = luaL_optint(l, 3, 0); - int confirmPrompt = luaL_optint(l, 4, 1); if (luacon_ci->scriptDownload) { @@ -4894,16 +5015,11 @@ int LuaScriptInterface::luatpt_getscript(lua_State* l) } ByteString url = ByteString::Build(SCHEME, "starcatcher.us/scripts/main.lua?get=", scriptID); - if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", url.FromUtf8(), "Install")) - { - return 0; - } luacon_ci->scriptDownload = std::make_unique(url); luacon_ci->scriptDownload->Start(); luacon_ci->scriptDownloadFilename = filename; luacon_ci->scriptDownloadRunScript = runScript; - luacon_ci->scriptDownloadConfirmPrompt = confirmPrompt; luacon_controller->HideConsole(); return 0; diff --git a/src/lua/LuaScriptInterface.h b/src/lua/LuaScriptInterface.h index dcc1fe5e6..957d3e7fa 100644 --- a/src/lua/LuaScriptInterface.h +++ b/src/lua/LuaScriptInterface.h @@ -31,7 +31,6 @@ class LuaScriptInterface: public TPTScriptInterface std::unique_ptr scriptDownload; ByteString scriptDownloadFilename; bool scriptDownloadRunScript; - bool scriptDownloadConfirmPrompt; int luacon_mousex, luacon_mousey, luacon_mousebutton; ByteString luacon_selectedl, luacon_selectedr, luacon_selectedalt, luacon_selectedreplace;