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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/opensb/client.config.patch2
-rw-r--r--assets/opensb/interface/voicechat/indicator/back.pngbin0 -> 611 bytes
-rw-r--r--assets/opensb/interface/voicechat/indicator/front.pngbin0 -> 1526 bytes
-rw-r--r--assets/opensb/interface/voicechat/indicator/front_muted.pngbin0 -> 1620 bytes
-rw-r--r--assets/opensb/scripts/universeClient/opensb.lua29
-rw-r--r--assets/opensb/scripts/universeClient/opensb/voice_manager.lua216
-rw-r--r--source/client/StarClientApplication.cpp1
-rw-r--r--source/frontend/StarInterfaceLuaBindings.cpp5
-rw-r--r--source/frontend/StarMainInterface.cpp26
-rw-r--r--source/frontend/StarMainInterface.hpp4
-rw-r--r--source/game/StarUniverseClient.cpp32
-rw-r--r--source/game/StarUniverseClient.hpp11
-rw-r--r--source/windowing/StarCanvasWidget.cpp11
-rw-r--r--source/windowing/StarGuiContext.cpp10
-rw-r--r--source/windowing/StarGuiContext.hpp1
-rw-r--r--source/windowing/StarWidgetLuaBindings.cpp9
16 files changed, 333 insertions, 24 deletions
diff --git a/assets/opensb/client.config.patch b/assets/opensb/client.config.patch
index 88bf328..e0d5687 100644
--- a/assets/opensb/client.config.patch
+++ b/assets/opensb/client.config.patch
@@ -1,4 +1,6 @@
{
+ "universeScriptContexts" : { "opensb" : ["/scripts/universeClient/opensb.lua"] },
+
// Disables scissoring and letterboxing on vanilla and modded warp cinematics
"warpCinematicBase" : {
"scissor" : false,
diff --git a/assets/opensb/interface/voicechat/indicator/back.png b/assets/opensb/interface/voicechat/indicator/back.png
new file mode 100644
index 0000000..869ed1c
--- /dev/null
+++ b/assets/opensb/interface/voicechat/indicator/back.png
Binary files differ
diff --git a/assets/opensb/interface/voicechat/indicator/front.png b/assets/opensb/interface/voicechat/indicator/front.png
new file mode 100644
index 0000000..ff32e38
--- /dev/null
+++ b/assets/opensb/interface/voicechat/indicator/front.png
Binary files differ
diff --git a/assets/opensb/interface/voicechat/indicator/front_muted.png b/assets/opensb/interface/voicechat/indicator/front_muted.png
new file mode 100644
index 0000000..be18587
--- /dev/null
+++ b/assets/opensb/interface/voicechat/indicator/front_muted.png
Binary files differ
diff --git a/assets/opensb/scripts/universeClient/opensb.lua b/assets/opensb/scripts/universeClient/opensb.lua
new file mode 100644
index 0000000..c1b4dea
--- /dev/null
+++ b/assets/opensb/scripts/universeClient/opensb.lua
@@ -0,0 +1,29 @@
+submodules = {}
+
+require "/scripts/universeClient/opensb/voice_manager.lua"
+
+local submodules, type = submodules, type
+local function call(func, ...)
+ if type(func) == "function" then
+ return func(...)
+ end
+end
+
+function init(...)
+ script.setUpdateDelta(1)
+ for i, module in pairs(submodules) do
+ call(module.init, ...)
+ end
+end
+
+function update(...)
+ for i, module in pairs(submodules) do
+ call(module.update, ...)
+ end
+end
+
+function uninit(...)
+ for i, module in pairs(submodules) do
+ call(module.uninit, ...)
+ end
+end \ No newline at end of file
diff --git a/assets/opensb/scripts/universeClient/opensb/voice_manager.lua b/assets/opensb/scripts/universeClient/opensb/voice_manager.lua
new file mode 100644
index 0000000..c07a8c2
--- /dev/null
+++ b/assets/opensb/scripts/universeClient/opensb/voice_manager.lua
@@ -0,0 +1,216 @@
+-- Manages the voice HUD indicators and click-to-mute/unmute.
+
+local fmt = string.format
+local sqrt = math.sqrt
+
+local module = {}
+submodules.voice_manager = module
+
+--constants
+local INDICATOR_PATH = "/interface/voicechat/indicator/"
+local BACK_INDICATOR_IMAGE = INDICATOR_PATH .. "back.png"
+local FRONT_INDICATOR_IMAGE = INDICATOR_PATH .. "front.png"
+local FRONT_MUTED_INDICATOR_IMAGE = INDICATOR_PATH .. "front_muted.png"
+local INDICATOR_SIZE = {300, 48}
+local LINE_PADDING = 12
+local LINE_WIDTH = 296
+local LINE_WIDTH_PADDED = LINE_WIDTH - LINE_PADDING
+local LINE_COLOR = {50, 210, 255, 255}
+local FONT_DIRECTIVES = "?border=1;333;3337?border=1;333;3330"
+local NAME_PREFIX = "^noshadow,white,set;"
+
+local canvas
+
+local linePaddingDrawable = {
+ image = BACK_INDICATOR_IMAGE,
+ position = {0, 0},
+ color = LINE_COLOR,
+ centered = false
+}
+
+local function getLinePadding(a, b)
+ linePaddingDrawable.image = BACK_INDICATOR_IMAGE .. fmt("?crop=%i;%i;%i;%i?fade=fff;1", a, 0, b, INDICATOR_SIZE[2])
+ linePaddingDrawable.position[1] = a
+ return linePaddingDrawable;
+end
+
+local lineDrawable = {
+ line = {{LINE_PADDING, 24}, {10, 24}},
+ width = 48,
+ color = LINE_COLOR
+}
+
+local function drawTheLine(pos, value)
+ local width = math.floor((LINE_WIDTH * value) + 0.5)
+ LINE_COLOR[4] = 255 * math.min(1, sqrt(width / 350))
+ if width > 0 then
+ canvas:drawDrawable(getLinePadding(0, math.min(12, width)), pos)
+ if width > 12 then
+ lineDrawable.line[2][1] = math.min(width, LINE_WIDTH_PADDED)
+ canvas:drawDrawable(lineDrawable, pos)
+ if width > LINE_WIDTH_PADDED then
+ canvas:drawDrawable(getLinePadding(LINE_WIDTH_PADDED, width), pos)
+ end
+ end
+ end
+end
+
+local drawable = {
+ image = BACK_INDICATOR_IMAGE,
+ centered = false
+}
+
+local textPositioning = {
+ position = {0, 0},
+ horizontalAnchor = "left",
+ verticalAnchor = "mid"
+}
+
+local hoveredSpeaker = nil
+local hoveredSpeakerIndex = 1
+local hoveredSpeakerPosition = {0, 0}
+local function mouseOverSpeaker(mouse, pos, expand)
+ expand = tonumber(expand) or 0
+ return (mouse[1] > pos[1] - expand and mouse[1] < pos[1] + 300 + expand)
+ and (mouse[2] > pos[2] - expand and mouse[2] < pos[2] + 48 + expand)
+end
+
+local function drawSpeakerBar(mouse, pos, speaker, i)
+ drawable.image = BACK_INDICATOR_IMAGE
+ canvas:drawDrawable(drawable, pos)
+ drawTheLine(pos, 1 - math.sqrt(math.min(1, math.max(0, speaker.loudness / -50))))
+ local hovering = not speaker.isLocal and mouseOverSpeaker(mouse, pos)
+
+ textPositioning.position = {pos[1] + 49, pos[2] + 24}
+ textPositioning.horizontalAnchor = "left"
+ local text = NAME_PREFIX ..
+ (hovering and (speaker.muted and "^#31d2f7;Unmute^reset; " or "^#f43030;Mute^reset; ") or "")
+ .. speaker.name
+ canvas:drawText(text, textPositioning, 16, nil, nil, nil, FONT_DIRECTIVES)
+ drawable.image = speaker.muted and FRONT_MUTED_INDICATOR_IMAGE or FRONT_INDICATOR_IMAGE
+ canvas:drawDrawable(drawable, pos)
+
+ if hovering then
+ hoveredSpeaker = speaker
+ hoveredSpeakerIndex = i
+ hoveredSpeakerPosition = pos
+ --if input.key("LShift") then
+ -- textPositioning.position = {pos[1] + 288, pos[2] + 24}
+ -- textPositioning.horizontalAnchor = "right"
+ -- canvas:drawText("^#fff7;" .. tostring(speaker.speakerId), textPositioning, 16, nil, nil, nil, FONT_DIRECTIVES)
+ --end
+--
+ --if input.mouseDown("MouseLeft") then
+ -- local muted = not voice.muted(speaker.speakerId)
+ -- interface.queueMessage((muted and "^#f43030;Muted^reset; " or "^#31d2f7;Unmuted^reset; ") .. speaker.name, 4, 0.5)
+ -- voice.setMuted(speaker.speakerId, muted)
+ --end
+ end
+end
+local speakersTime = {}
+
+local function simulateSpeakers()
+ local speakers = {}
+ for i = 2, 5 + math.floor((math.sin(os.clock()) * 4) + .5) do
+ speakers[i] = {
+ speakerId = i,
+ entityId = -65536 * i,
+ name = "Player " .. i,
+ loudness = -48 + 48 * math.sin(os.clock() + (i * 0.5)),
+ muted = false
+ }
+ end
+ return speakers
+end
+
+local function drawIndicators()
+ canvas:clear()
+ local screenSize = canvas:size()
+ local mousePosition = canvas:mousePosition()
+ sb.setLogMap("mousePosition", sb.printJson(mousePosition))
+ local basePos = {screenSize[1] - 350, 50}
+
+ -- sort it ourselves for now
+ local speakersRemaining, speakersSorted = {}, {}
+ local hoveredSpeakerId = nil
+ if hoveredSpeaker then
+ if not mouseOverSpeaker(mousePosition, hoveredSpeakerPosition, 16) then
+ hoveredSpeaker = nil
+ else
+ hoveredSpeakerId = hoveredSpeaker.speakerId
+ end
+ end
+
+ --local speakers = voice.speakers()
+ local speakers = { -- just testing before implementing voice lua functions
+ {
+ speakerId = 1,
+ entityId = -65536,
+ loudness = -96 + math.random() * 96,
+ muted = false,
+ name = "theres a pipe bomb up my ass"
+ }
+ }
+
+ local sortI = 0
+ local now = os.clock()
+ for i, speaker in pairs(speakers) do
+ local speakerId = speaker.speakerId
+ speakersRemaining[speakerId] = true
+ local t = speakersTime[speakerId]
+ if not t then
+ t = now
+ speakersTime[speakerId] = t
+ end
+ speaker.startTime = t
+ if speakerId == hoveredSpeakerId then
+ hoveredSpeaker = speaker
+ else
+ sortI = sortI + 1
+ speakersSorted[sortI] = speaker
+ end
+ end
+
+ for i, v in pairs(speakersTime) do
+ if not speakersRemaining[i] then
+ speakersTime[i] = nil
+ end
+ end
+
+ table.sort(speakersSorted, function(a, b)
+ if a.startTime == b.startTime then
+ return a.speakerId < b.speakerId
+ else
+ return a.startTime < b.startTime
+ end
+ end)
+
+ if hoveredSpeaker then
+ local len = #speakersSorted
+ if hoveredSpeakerIndex > len then
+ for i = len + 1, hoveredSpeakerIndex - 1 do
+ speakersSorted[i] = false
+ end
+ speakersSorted[hoveredSpeakerIndex] = hoveredSpeaker
+ else
+ table.insert(speakersSorted, hoveredSpeakerIndex, hoveredSpeaker)
+ end
+ end
+
+ for i, v in pairs(speakersSorted) do
+ if v then
+ local entityId = v.entityId
+ local loudness = v.loudness
+ local pos = {basePos[1], basePos[2] + (i - 1) * 52}
+ drawSpeakerBar(mousePosition, pos, v, i)
+ end
+ end
+end
+
+function module.init()
+ canvas = interface.bindCanvas("voice", true)
+end
+
+function module.update()
+ drawIndicators()
+end \ No newline at end of file
diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp
index f7ab21b..9de1642 100644
--- a/source/client/StarClientApplication.cpp
+++ b/source/client/StarClientApplication.cpp
@@ -614,6 +614,7 @@ void ClientApplication::changeState(MainAppState newState) {
m_worldPainter = make_shared<WorldPainter>();
m_mainInterface = make_shared<MainInterface>(m_universeClient, m_worldPainter, m_cinematicOverlay);
m_universeClient->setLuaCallbacks("interface", LuaBindings::makeInterfaceCallbacks(m_mainInterface.get()));
+ m_universeClient->startLua();
m_mainMixer->setWorldPainter(m_worldPainter);
diff --git a/source/frontend/StarInterfaceLuaBindings.cpp b/source/frontend/StarInterfaceLuaBindings.cpp
index 14b2e7c..d5e0960 100644
--- a/source/frontend/StarInterfaceLuaBindings.cpp
+++ b/source/frontend/StarInterfaceLuaBindings.cpp
@@ -27,6 +27,11 @@ LuaCallbacks LuaBindings::makeInterfaceCallbacks(MainInterface* mainInterface) {
return GuiContext::singleton().interfaceScale();
});
+ callbacks.registerCallback("queueMessage", [mainInterface](String const& message, Maybe<float> cooldown, Maybe<float> springState) {
+ mainInterface->queueMessage(message, cooldown, springState.value(0));
+ });
+
+
return callbacks;
}
diff --git a/source/frontend/StarMainInterface.cpp b/source/frontend/StarMainInterface.cpp
index 9f335b6..0dc3a01 100644
--- a/source/frontend/StarMainInterface.cpp
+++ b/source/frontend/StarMainInterface.cpp
@@ -62,8 +62,8 @@ namespace Star {
GuiMessage::GuiMessage() : message(), cooldown(), springState() {}
-GuiMessage::GuiMessage(String const& message, float cooldown)
- : message(message), cooldown(cooldown), springState(0) {}
+GuiMessage::GuiMessage(String const& message, float cooldown, float spring)
+ : message(message), cooldown(cooldown), springState(spring) {}
MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter, CinematicPtr cinematicOverlay) {
m_state = Running;
@@ -369,6 +369,9 @@ bool MainInterface::handleInputEvent(InputEvent const& event) {
player->endTrigger();
}
+ for (auto& pair : m_canvases)
+ pair.second->sendEvent(event);
+
return true;
}
@@ -863,11 +866,15 @@ void MainInterface::doChat(String const& chat, bool addToHistory) {
m_chat->addHistory(chat);
}
-void MainInterface::queueMessage(String const& message) {
- auto guiMessage = make_shared<GuiMessage>(message, m_config->messageTime);
+void MainInterface::queueMessage(String const& message, Maybe<float> cooldown, float spring) {
+ auto guiMessage = make_shared<GuiMessage>(message, cooldown.value(m_config->messageTime), spring);
m_messages.append(guiMessage);
}
+void MainInterface::queueMessage(String const& message) {
+ queueMessage(message, m_config->messageTime, 0.0f);
+}
+
void MainInterface::queueJoinRequest(pair<String, RpcPromiseKeeper<P2PJoinRequestReply>> request)
{
m_queuedJoinRequests.push_back(request);
@@ -927,18 +934,21 @@ void MainInterface::warpTo(WarpAction const& warpAction) {
}
CanvasWidgetPtr MainInterface::fetchCanvas(String const& canvasName, bool ignoreInterfaceScale) {
+ CanvasWidgetPtr canvas;
+
if (auto canvasPtr = m_canvases.ptr(canvasName))
- return *canvasPtr;
+ canvas = *canvasPtr;
else {
- CanvasWidgetPtr canvas = m_canvases.emplace(canvasName, make_shared<CanvasWidget>()).first->second;
+ m_canvases.emplace(canvasName, canvas = make_shared<CanvasWidget>());
canvas->setPosition(Vec2I());
if (ignoreInterfaceScale)
canvas->setSize(Vec2I(m_guiContext->windowSize()));
else
canvas->setSize(Vec2I(m_guiContext->windowInterfaceSize()));
- canvas->setIgnoreInterfaceScale(ignoreInterfaceScale);
- return canvas;
}
+
+ canvas->setIgnoreInterfaceScale(ignoreInterfaceScale);
+ return canvas;
}
PanePtr MainInterface::createEscapeDialog() {
diff --git a/source/frontend/StarMainInterface.hpp b/source/frontend/StarMainInterface.hpp
index d96779d..9cf2342 100644
--- a/source/frontend/StarMainInterface.hpp
+++ b/source/frontend/StarMainInterface.hpp
@@ -49,7 +49,7 @@ STAR_CLASS(MainInterface);
struct GuiMessage {
GuiMessage();
- GuiMessage(String const& message, float cooldown);
+ GuiMessage(String const& message, float cooldown, float spring = 0);
String message;
float cooldown;
@@ -105,7 +105,9 @@ public:
void doChat(String const& chat, bool addToHistory);
+ void queueMessage(String const& message, Maybe<float> cooldown, float spring);
void queueMessage(String const& message);
+
void queueItemPickupText(ItemPtr const& item);
void queueJoinRequest(pair<String, RpcPromiseKeeper<P2PJoinRequestReply>> request);
diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp
index 1622518..bc1b0b9 100644
--- a/source/game/StarUniverseClient.cpp
+++ b/source/game/StarUniverseClient.cpp
@@ -30,6 +30,7 @@ UniverseClient::UniverseClient(PlayerStoragePtr playerStorage, StatisticsPtr sta
m_playerStorage = move(playerStorage);
m_statistics = move(statistics);
m_pause = false;
+ m_luaRoot = make_shared<LuaRoot>();
reset();
}
@@ -86,7 +87,7 @@ Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowA
return String(strf("Join failed! Server does not support connections with protocol version {}", StarProtocolVersion));
connection.pushSingle(make_shared<ClientConnectPacket>(Root::singleton().assets()->digest(), allowAssetsMismatch, m_mainPlayer->uuid(), m_mainPlayer->name(),
- m_mainPlayer->species(), m_playerStorage->loadShipData(m_mainPlayer->uuid()), ShipUpgrades(m_mainPlayer->shipUpgrades()),
+ m_mainPlayer->species(), m_playerStorage->loadShipData(m_mainPlayer->uuid()), m_mainPlayer->shipUpgrades(),
m_mainPlayer->log()->introComplete(), account));
connection.sendAll(timeout);
@@ -219,8 +220,11 @@ void UniverseClient::update() {
m_statistics->update();
- if (!m_pause)
+ if (!m_pause) {
m_worldClient->update();
+ for (auto& p : m_scriptContexts)
+ p.second->update();
+ }
m_connection->push(m_worldClient->getOutgoingPackets());
if (!m_pause)
@@ -444,6 +448,28 @@ void UniverseClient::setLuaCallbacks(String const& groupName, LuaCallbacks const
m_worldClient->setLuaCallbacks(groupName, callbacks);
}
+void UniverseClient::startLua() {
+ auto assets = Root::singleton().assets();
+ for (auto& p : assets->json("/client.config:universeScriptContexts").toObject()) {
+ auto scriptComponent = make_shared<ScriptComponent>();
+ scriptComponent->setLuaRoot(m_luaRoot);
+ scriptComponent->setScripts(jsonToStringList(p.second.toArray()));
+
+ for (auto& pair : m_luaCallbacks)
+ scriptComponent->addCallbacks(pair.first, pair.second);
+
+ m_scriptContexts.set(p.first, scriptComponent);
+ scriptComponent->init();
+ }
+}
+
+void UniverseClient::stopLua() {
+ for (auto& p : m_scriptContexts)
+ p.second->uninit();
+
+ m_scriptContexts.clear();
+}
+
ClockConstPtr UniverseClient::universeClock() const {
return m_universeClock;
}
@@ -539,6 +565,8 @@ void UniverseClient::handlePackets(List<PacketPtr> const& packets) {
}
void UniverseClient::reset() {
+ stopLua();
+
m_universeClock.reset();
m_worldClient.reset();
m_celestialDatabase.reset();
diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp
index b26f2df..daad481 100644
--- a/source/game/StarUniverseClient.hpp
+++ b/source/game/StarUniverseClient.hpp
@@ -10,6 +10,7 @@
#include "StarAiTypes.hpp"
#include "StarSky.hpp"
#include "StarUniverseConnection.hpp"
+#include "StarLuaComponents.hpp"
namespace Star {
@@ -29,8 +30,8 @@ STAR_CLASS(CelestialDatabase);
STAR_CLASS(JsonRpcInterface);
STAR_CLASS(TeamClient);
STAR_CLASS(QuestManager);
-
STAR_CLASS(UniverseClient);
+STAR_CLASS(LuaRoot);
class UniverseClient {
public:
@@ -86,6 +87,8 @@ public:
uint16_t maxPlayers();
void setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks);
+ void startLua();
+ void stopLua();
ClockConstPtr universeClock() const;
CelestialLogConstPtr celestialLog() const;
@@ -141,6 +144,12 @@ private:
List<ChatReceivedMessage> m_pendingMessages;
Maybe<String> m_disconnectReason;
+
+ LuaRootPtr m_luaRoot;
+
+ typedef LuaUpdatableComponent<LuaBaseComponent> ScriptComponent;
+ typedef shared_ptr<ScriptComponent> ScriptComponentPtr;
+ StringMap<ScriptComponentPtr> m_scriptContexts;
};
}
diff --git a/source/windowing/StarCanvasWidget.cpp b/source/windowing/StarCanvasWidget.cpp
index ed2e30f..a0eeb7d 100644
--- a/source/windowing/StarCanvasWidget.cpp
+++ b/source/windowing/StarCanvasWidget.cpp
@@ -88,20 +88,21 @@ bool CanvasWidget::sendEvent(InputEvent const& event) {
return false;
auto& context = GuiContext::singleton();
+ int interfaceScale = m_ignoreInterfaceScale ? 1 : context.interfaceScale();
if (auto mouseButtonDown = event.ptr<MouseButtonDownEvent>()) {
- if (inMember(*context.mousePosition(event)) && m_captureMouse) {
- m_clickEvents.append({*context.mousePosition(event) - screenPosition(), mouseButtonDown->mouseButton, true});
+ if (inMember(*context.mousePosition(event, interfaceScale)) && m_captureMouse) {
+ m_clickEvents.append({*context.mousePosition(event, interfaceScale) - screenPosition(), mouseButtonDown->mouseButton, true});
m_clickEvents.limitSizeBack(MaximumEventBuffer);
return true;
}
} else if (auto mouseButtonUp = event.ptr<MouseButtonUpEvent>()) {
if (m_captureMouse) {
- m_clickEvents.append({*context.mousePosition(event) - screenPosition(), mouseButtonUp->mouseButton, false});
+ m_clickEvents.append({*context.mousePosition(event, interfaceScale) - screenPosition(), mouseButtonUp->mouseButton, false});
m_clickEvents.limitSizeBack(MaximumEventBuffer);
return true;
}
} else if (event.is<MouseMoveEvent>()) {
- m_mousePosition = *context.mousePosition(event) - screenPosition();
+ m_mousePosition = *context.mousePosition(event, interfaceScale) - screenPosition();
return false;
} else if (auto keyDown = event.ptr<KeyDownEvent>()) {
if (m_captureKeyboard) {
@@ -258,7 +259,7 @@ void CanvasWidget::renderTriangles(Vec2F const& renderingOffset, List<tuple<Vec2
void CanvasWidget::renderText(Vec2F const& renderingOffset, String const& s, TextPositioning const& position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing, String const& font, String const& directives) {
auto& context = GuiContext::singleton();
context.setFontProcessingDirectives(directives);
- context.setFontSize(fontSize);
+ context.setFontSize(fontSize, m_ignoreInterfaceScale ? 1 : context.interfaceScale());
context.setFontColor(color);
context.setFontMode(mode);
context.setFont(font);
diff --git a/source/windowing/StarGuiContext.cpp b/source/windowing/StarGuiContext.cpp
index 2d649c5..73713d1 100644
--- a/source/windowing/StarGuiContext.cpp
+++ b/source/windowing/StarGuiContext.cpp
@@ -98,9 +98,9 @@ void GuiContext::setInterfaceScale(int interfaceScale) {
m_interfaceScale = interfaceScale;
}
-Maybe<Vec2I> GuiContext::mousePosition(InputEvent const& event) const {
- auto getInterfacePosition = [this](Vec2I pos) {
- return Vec2I(pos) / interfaceScale();
+Maybe<Vec2I> GuiContext::mousePosition(InputEvent const& event, int pixelRatio) const {
+ auto getInterfacePosition = [pixelRatio](Vec2I pos) {
+ return Vec2I(pos) / pixelRatio;
};
if (auto mouseMoveEvent = event.ptr<MouseMoveEvent>())
@@ -115,6 +115,10 @@ Maybe<Vec2I> GuiContext::mousePosition(InputEvent const& event) const {
return {};
}
+Maybe<Vec2I> GuiContext::mousePosition(InputEvent const& event) const {
+ return mousePosition(event, interfaceScale());
+}
+
Set<InterfaceAction> GuiContext::actions(InputEvent const& event) const {
return m_keyBindings.actions(event);
}
diff --git a/source/windowing/StarGuiContext.hpp b/source/windowing/StarGuiContext.hpp
index 1d6ed46..8e689ee 100644
--- a/source/windowing/StarGuiContext.hpp
+++ b/source/windowing/StarGuiContext.hpp
@@ -50,6 +50,7 @@ public:
int interfaceScale() const;
void setInterfaceScale(int interfaceScale);
+ Maybe<Vec2I> mousePosition(InputEvent const& event, int pixelRatio) const;
Maybe<Vec2I> mousePosition(InputEvent const& event) const;
Set<InterfaceAction> actions(InputEvent const& event) const;
diff --git a/source/windowing/StarWidgetLuaBindings.cpp b/source/windowing/StarWidgetLuaBindings.cpp
index 46f1ac8..f69bd53 100644
--- a/source/windowing/StarWidgetLuaBindings.cpp
+++ b/source/windowing/StarWidgetLuaBindings.cpp
@@ -25,13 +25,14 @@ LuaMethods<CanvasWidgetPtr> LuaUserDataMethods<CanvasWidgetPtr>::make() {
methods.registerMethodWithSignature<void, CanvasWidgetPtr>("clear", mem_fn(&CanvasWidget::clear));
- methods.registerMethod("drawDrawable", [](CanvasWidgetPtr canvasWidget, Drawable drawable) {
- canvasWidget->drawDrawable(move(drawable), Vec2F());
+ methods.registerMethod("drawDrawable", [](CanvasWidgetPtr canvasWidget, Drawable drawable, Maybe<Vec2F> screenPos) {
+ canvasWidget->drawDrawable(move(drawable), screenPos.value(Vec2F()));
});
- methods.registerMethod("drawDrawables", [](CanvasWidgetPtr canvasWidget, List<Drawable> drawables) {
+ methods.registerMethod("drawDrawables", [](CanvasWidgetPtr canvasWidget, List<Drawable> drawables, Maybe<Vec2F> screenPos) {
+ Vec2F pos = screenPos.value(Vec2F());
for (auto& drawable : drawables)
- canvasWidget->drawDrawable(move(drawable), Vec2F());
+ canvasWidget->drawDrawable(move(drawable), pos);
});
methods.registerMethod("drawImage",