Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/frontend/StarBaseScriptPane.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-07-02 17:19:54 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-07-02 17:19:54 +1000
commit2386a9534289baf73ce299f33e110f612ff55e38 (patch)
tree19dca601d4bb7fa0bae23944485ad87024a034ef /source/frontend/StarBaseScriptPane.cpp
parent73841ee041b8b52f5fde16dc272228704697bcb8 (diff)
Input Binding support
Diffstat (limited to 'source/frontend/StarBaseScriptPane.cpp')
-rw-r--r--source/frontend/StarBaseScriptPane.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/source/frontend/StarBaseScriptPane.cpp b/source/frontend/StarBaseScriptPane.cpp
new file mode 100644
index 0000000..a174622
--- /dev/null
+++ b/source/frontend/StarBaseScriptPane.cpp
@@ -0,0 +1,183 @@
+#include "StarBaseScriptPane.hpp"
+#include "StarRoot.hpp"
+#include "StarAssets.hpp"
+#include "StarGuiReader.hpp"
+#include "StarJsonExtra.hpp"
+#include "StarConfigLuaBindings.hpp"
+#include "StarLuaGameConverters.hpp"
+#include "StarWidgetLuaBindings.hpp"
+#include "StarCanvasWidget.hpp"
+#include "StarItemTooltip.hpp"
+#include "StarItemGridWidget.hpp"
+#include "StarSimpleTooltip.hpp"
+#include "StarImageWidget.hpp"
+
+namespace Star {
+
+BaseScriptPane::BaseScriptPane(Json config) : Pane() {
+ auto& root = Root::singleton();
+ auto assets = root.assets();
+
+ if (config.type() == Json::Type::Object && config.contains("baseConfig")) {
+ auto baseConfig = assets->fetchJson(config.getString("baseConfig"));
+ m_config = jsonMerge(baseConfig, config);
+ } else {
+ m_config = assets->fetchJson(config);
+ }
+ m_reader.registerCallback("close", [this](Widget*) { dismiss(); });
+
+ for (auto const& callbackName : jsonToStringList(m_config.get("scriptWidgetCallbacks", JsonArray{}))) {
+ m_reader.registerCallback(callbackName, [this, callbackName](Widget* widget) {
+ m_script.invoke(callbackName, widget->name(), widget->data());
+ });
+ }
+
+ m_reader.construct(assets->fetchJson(m_config.get("gui")), this);
+
+ for (auto pair : m_config.getObject("canvasClickCallbacks", {}))
+ m_canvasClickCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
+ for (auto pair : m_config.getObject("canvasKeyCallbacks", {}))
+ m_canvasKeyCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
+
+ m_script.setScripts(jsonToStringList(m_config.get("scripts", JsonArray())));
+ m_script.setUpdateDelta(m_config.getUInt("scriptDelta", 1));
+
+ m_callbacksAdded = false;
+}
+
+void BaseScriptPane::show() {
+ Pane::show();
+}
+
+void BaseScriptPane::displayed() {
+ Pane::displayed();
+ if (!m_callbacksAdded) {
+ m_script.addCallbacks("pane", makePaneCallbacks());
+ m_script.addCallbacks("widget", LuaBindings::makeWidgetCallbacks(this, &m_reader));
+ m_script.addCallbacks("config", LuaBindings::makeConfigCallbacks( [this](String const& name, Json const& def) {
+ return m_config.query(name, def);
+ }));
+ m_callbacksAdded = true;
+ }
+ m_script.init();
+ m_script.invoke("displayed");
+}
+
+void BaseScriptPane::dismissed() {
+ Pane::dismissed();
+ m_script.invoke("dismissed");
+ m_script.uninit();
+}
+
+void BaseScriptPane::tick() {
+ Pane::tick();
+
+ for (auto p : m_canvasClickCallbacks) {
+ for (auto const& clickEvent : p.first->pullClickEvents())
+ m_script.invoke(p.second, jsonFromVec2I(clickEvent.position), (uint8_t)clickEvent.button, clickEvent.buttonDown);
+ }
+ for (auto p : m_canvasKeyCallbacks) {
+ for (auto const& keyEvent : p.first->pullKeyEvents())
+ m_script.invoke(p.second, (int)keyEvent.key, keyEvent.keyDown);
+ }
+
+ m_playingSounds.filter([](pair<String, AudioInstancePtr> const& p) {
+ return p.second->finished() == false;
+ });
+
+ m_script.update(m_script.updateDt());
+}
+
+bool BaseScriptPane::sendEvent(InputEvent const& event) {
+ // Intercept GuiClose before the canvas child so GuiClose always closes
+ // BaseScriptPanes without having to support it in the script.
+ if (context()->actions(event).contains(InterfaceAction::GuiClose)) {
+ dismiss();
+ return true;
+ }
+
+ return Pane::sendEvent(event);
+}
+
+PanePtr BaseScriptPane::createTooltip(Vec2I const& screenPosition) {
+ auto result = m_script.invoke<Json>("createTooltip", screenPosition);
+ if (result && !result.value().isNull()) {
+ if (result->type() == Json::Type::String) {
+ return SimpleTooltipBuilder::buildTooltip(result->toString());
+ } else {
+ PanePtr tooltip = make_shared<Pane>();
+ m_reader.construct(*result, tooltip.get());
+ return tooltip;
+ }
+ } else {
+ ItemPtr item;
+ if (auto child = getChildAt(screenPosition)) {
+ if (auto itemSlot = as<ItemSlotWidget>(child))
+ item = itemSlot->item();
+ if (auto itemGrid = as<ItemGridWidget>(child))
+ item = itemGrid->itemAt(screenPosition);
+ }
+ if (item)
+ return ItemTooltipBuilder::buildItemTooltip(item);
+ return {};
+ }
+}
+
+Maybe<String> BaseScriptPane::cursorOverride(Vec2I const& screenPosition) {
+ auto result = m_script.invoke<Maybe<String>>("cursorOverride", screenPosition);
+ if (result)
+ return *result;
+ else
+ return {};
+}
+
+LuaCallbacks BaseScriptPane::makePaneCallbacks() {
+ LuaCallbacks callbacks;
+
+ callbacks.registerCallback("dismiss", [this]() { dismiss(); });
+
+ callbacks.registerCallback("playSound",
+ [this](String const& audio, Maybe<int> loops, Maybe<float> volume) {
+ auto assets = Root::singleton().assets();
+ auto config = Root::singleton().configuration();
+ auto audioInstance = make_shared<AudioInstance>(*assets->audio(audio));
+ audioInstance->setVolume(volume.value(1.0));
+ audioInstance->setLoops(loops.value(0));
+ auto& guiContext = GuiContext::singleton();
+ guiContext.playAudio(audioInstance);
+ m_playingSounds.append({audio, move(audioInstance)});
+ });
+
+ callbacks.registerCallback("stopAllSounds", [this](String const& audio) {
+ m_playingSounds.filter([audio](pair<String, AudioInstancePtr> const& p) {
+ if (p.first == audio) {
+ p.second->stop();
+ return false;
+ }
+ return true;
+ });
+ });
+
+ callbacks.registerCallback("setTitle", [this](String const& title, String const& subTitle) {
+ setTitleString(title, subTitle);
+ });
+
+ callbacks.registerCallback("setTitleIcon", [this](String const& image) {
+ if (auto icon = as<ImageWidget>(titleIcon()))
+ icon->setImage(image);
+ });
+
+ callbacks.registerCallback("addWidget", [this](Json const& newWidgetConfig, Maybe<String> const& newWidgetName) {
+ String name = newWidgetName.value(strf("{}", Random::randu64()));
+ WidgetPtr newWidget = m_reader.makeSingle(name, newWidgetConfig);
+ this->addChild(name, newWidget);
+ });
+
+ callbacks.registerCallback("removeWidget", [this](String const& widgetName) {
+ this->removeChild(widgetName);
+ });
+
+ return callbacks;
+}
+
+}