From 72d68cbc078cf2c1b9dc3ff81c2c1965f5d6f8c5 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 12 Mar 2024 16:48:49 +0200 Subject: Initial implementation of LLLuaFloater --- indra/llui/CMakeLists.txt | 2 + indra/llui/llfloater.cpp | 4 + indra/llui/llfloater.h | 3 + indra/llui/llfloaterreglistener.cpp | 15 ++++ indra/llui/llfloaterreglistener.h | 2 + indra/llui/llluafloater.cpp | 162 ++++++++++++++++++++++++++++++++++++ indra/llui/llluafloater.h | 52 ++++++++++++ 7 files changed, 240 insertions(+) create mode 100644 indra/llui/llluafloater.cpp create mode 100644 indra/llui/llluafloater.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a0314cb5f2..69e1b57245 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -49,6 +49,7 @@ set(llui_SOURCE_FILES lllineeditor.cpp llloadingindicator.cpp lllocalcliprect.cpp + llluafloater.cpp llmenubutton.cpp llmenugl.cpp llmodaldialog.cpp @@ -164,6 +165,7 @@ set(llui_HEADER_FILES lllineeditor.h llloadingindicator.h lllocalcliprect.h + llluafloater.h llmenubutton.h llmenugl.h llmodaldialog.h diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index de3de53569..b9b69b5a33 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -3623,6 +3623,10 @@ void LLFloater::applyRelativePosition() translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY); } +bool LLFloater::isDefaultBtnName(const std::string& name) +{ + return (std::find(std::begin(sButtonNames), std::end(sButtonNames), name) != std::end(sButtonNames)); +} LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater) : coord_t((S32)x, (S32)y) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 88f9e77777..9d49c4538e 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -372,6 +372,9 @@ public: void enableResizeCtrls(bool enable, bool width = true, bool height = true); bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); } + + static bool isDefaultBtnName(const std::string& name); + protected: void applyControlsAndPosition(LLFloater* other); diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp index 7525b8cab3..6fee688121 100644 --- a/indra/llui/llfloaterreglistener.cpp +++ b/indra/llui/llfloaterreglistener.cpp @@ -37,6 +37,7 @@ #include "llfloaterreg.h" #include "llfloater.h" #include "llbutton.h" +#include "llluafloater.h" LLFloaterRegListener::LLFloaterRegListener(): LLEventAPI("LLFloaterReg", @@ -72,6 +73,15 @@ LLFloaterRegListener::LLFloaterRegListener(): "Simulate clicking the named [\"button\"] in the visible floater named in [\"name\"]", &LLFloaterRegListener::clickButton, requiredNameButton); + + LLSD requiredParams; + requiredParams["xml_path"] = LLSD(); + requiredParams["command_pump"] = LLSD(); + requiredParams["reqid"] = LLSD(); + add("showLuaFloater", + "Open the new floater using XML file specified in [\"xml_path\"]" + "with ID in [\"reqid\"], which sends UI events to even pump specified in [\"command_pump\"]", + &LLFloaterRegListener::showLuaFloater, requiredParams); } void LLFloaterRegListener::getBuildMap(const LLSD& event) const @@ -154,3 +164,8 @@ void LLFloaterRegListener::clickButton(const LLSD& event) const LLEventPumps::instance().obtain(replyPump).post(reply); } } + +void LLFloaterRegListener::showLuaFloater(const LLSD &event) const +{ + LLLuaFloater::showLuaFloater(event); +} diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h index 24311a2dfa..2d58303aa0 100644 --- a/indra/llui/llfloaterreglistener.h +++ b/indra/llui/llfloaterreglistener.h @@ -49,6 +49,8 @@ private: void toggleInstance(const LLSD& event) const; void instanceVisible(const LLSD& event) const; void clickButton(const LLSD& event) const; + + void showLuaFloater(const LLSD &event) const; }; #endif /* ! defined(LL_LLFLOATERREGLISTENER_H) */ diff --git a/indra/llui/llluafloater.cpp b/indra/llui/llluafloater.cpp new file mode 100644 index 0000000000..3507c907a0 --- /dev/null +++ b/indra/llui/llluafloater.cpp @@ -0,0 +1,162 @@ +/** + * @file llluafloater.cpp + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * + */ + +#include "llluafloater.h" + +#include +#include "llevents.h" + +#include "llcheckboxctrl.h" +#include "llcombobox.h" + +const std::string LISTENER_NAME("LLLuaFloater"); + +LLLuaFloater::LLLuaFloater(const LLSD &key) : + LLFloater(key), + mCommandPumpName(key["command_pump"].asString()), + mDispatcher("LLLuaFloater", "action"), + mReqID(key) +{ + mListenerPumpName = LLUUID::generateNewID().asString(); + + mBoundListener = LLEventPumps::instance().obtain(mListenerPumpName).listen(LISTENER_NAME, [this](const LLSD &event) + { + if (event.has("action")) + { + mDispatcher.try_call(event); + } + else + { + LL_WARNS("LuaFloater") << "Unknown message: " << event << LL_ENDL; + } + return false; + }); + + LLSD requiredParams; + requiredParams["ctrl_name"] = LLSD(); + requiredParams["value"] = LLSD(); + mDispatcher.add("set_enabled", "", [this](const LLSD &event) + { + LLUICtrl *ctrl = getChild(event["ctrl_name"].asString()); + if(ctrl) + { + ctrl->setEnabled(event["value"].asBoolean()); + } + }, requiredParams); + mDispatcher.add("set_visible", "", [this](const LLSD &event) + { + LLUICtrl *ctrl = getChild(event["ctrl_name"].asString()); + if(ctrl) + { + ctrl->setVisible(event["value"].asBoolean()); + } + }, requiredParams); + mDispatcher.add("set_value", "", [this](const LLSD &event) + { + LLUICtrl *ctrl = getChild(event["ctrl_name"].asString()); + if(ctrl) + { + ctrl->setValue(event["value"]); + } + }, requiredParams); + + requiredParams = LLSD().with("value", LLSD()); + mDispatcher.add("set_title", "", [this](const LLSD &event) + { + setTitle(event["value"].asString()); + }); +} + +BOOL LLLuaFloater::postBuild() +{ + child_list_t::const_iterator iter = getChildList()->begin(); + child_list_t::const_iterator end = getChildList()->end(); + for (; iter != end; ++iter) + { + LLView *view = *iter; + if (!view) continue; + + LLSD data; + data["ctrl_name"] = view->getName(); + data["event"] = "click"; + + LLButton* btn = dynamic_cast(view); + if (btn && !isDefaultBtnName(btn->getName())) + { + data["ctrl_type"] = "LLButton"; + btn->setCommitCallback([this, data](LLUICtrl *ctrl, const LLSD ¶m) { post(data); }); + } + LLCheckBoxCtrl* check = dynamic_cast(view); + if (check) + { + data["ctrl_type"] = "LLCheckBoxCtrl"; + check->setCommitCallback([this, data](LLUICtrl *ctrl, const LLSD ¶m) + { + LLSD event(data); + event["value"] = ctrl->getValue(); + post(event); + }); + } + LLComboBox *combo = dynamic_cast(view); + if (combo) + { + data["ctrl_type"] = "LLComboBox"; + combo->setCommitCallback([this, data](LLUICtrl* ctrl, const LLSD ¶m) + { + LLSD event(data); + event["value"] = dynamic_cast(ctrl)->getValue(); + post(event); + }); + } + } + + post(LLSD().with("command_name", mListenerPumpName).with("event", "post_build")); + + return true; +} + +void LLLuaFloater::onClose(bool app_quitting) +{ + post(LLSD().with("event", "floater_close")); +} + +void LLLuaFloater::post(const LLSD &data) +{ + LLSD stamped_data(data); + mReqID.stamp(stamped_data); + LLEventPumps::instance().obtain(mCommandPumpName).post(stamped_data); +} + +void LLLuaFloater::showLuaFloater(const LLSD &data) +{ + std::filesystem::path fs_path(data["xml_path"].asString()); + + LLLuaFloater *floater = new LLLuaFloater(data); + floater->buildFromFile(fs_path.lexically_normal().string()); + floater->openFloater(floater->getKey()); +} + + diff --git a/indra/llui/llluafloater.h b/indra/llui/llluafloater.h new file mode 100644 index 0000000000..0b7e86746a --- /dev/null +++ b/indra/llui/llluafloater.h @@ -0,0 +1,52 @@ +/** + * @file llluafloater.h + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLLUAFLOATER_H +#define LL_LLLUAFLOATER_H + +#include "llfloater.h" +#include "lleventdispatcher.h" +#include "llevents.h" + +class LLLuaFloater : public LLFloater +{ +public: + LLLuaFloater(const LLSD &key); + BOOL postBuild(); + + void onClose(bool app_quitting); + + void post(const LLSD &data); + static void showLuaFloater(const LLSD &data); + +private: + LLReqID mReqID; + LLEventDispatcher mDispatcher; + LLTempBoundListener mBoundListener; + + std::string mListenerPumpName; + std::string mCommandPumpName; +}; +#endif -- cgit v1.2.3