Input: binds can now make the clipboard available while held, config option to always allow
This commit is contained in:
parent
dd52188e53
commit
d95eac3164
@ -543,8 +543,9 @@ void ClientApplication::changeState(MainAppState newState) {
|
|||||||
m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks());
|
m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks());
|
||||||
m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks());
|
m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks());
|
||||||
m_universeClient->setLuaCallbacks("camera", LuaBindings::makeCameraCallbacks(&m_worldPainter->camera()));
|
m_universeClient->setLuaCallbacks("camera", LuaBindings::makeCameraCallbacks(&m_worldPainter->camera()));
|
||||||
if (!m_root->configuration()->get("safeScripts").toBool())
|
|
||||||
m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController()));
|
Json alwaysAllow = m_root->configuration()->getPath("safe.alwaysAllowClipboard");
|
||||||
|
m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController(), alwaysAllow && alwaysAllow.toBool()));
|
||||||
|
|
||||||
auto heldScriptPanes = make_shared<List<MainInterface::ScriptPaneInfo>>();
|
auto heldScriptPanes = make_shared<List<MainInterface::ScriptPaneInfo>>();
|
||||||
|
|
||||||
|
@ -1,21 +1,35 @@
|
|||||||
#include "StarClipboardLuaBindings.hpp"
|
#include "StarClipboardLuaBindings.hpp"
|
||||||
#include "StarLuaConverters.hpp"
|
#include "StarLuaConverters.hpp"
|
||||||
|
#include "StarInput.hpp"
|
||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
LuaCallbacks LuaBindings::makeClipboardCallbacks(ApplicationControllerPtr appController) {
|
LuaCallbacks LuaBindings::makeClipboardCallbacks(ApplicationControllerPtr appController, bool alwaysAllow) {
|
||||||
LuaCallbacks callbacks;
|
LuaCallbacks callbacks;
|
||||||
|
|
||||||
callbacks.registerCallback("hasText", [appController]() -> bool {
|
auto available = [alwaysAllow]() { return alwaysAllow || Input::singleton().getTag("clipboard") > 0; };
|
||||||
return appController->hasClipboard();
|
|
||||||
|
callbacks.registerCallback("available", [=]() -> bool {
|
||||||
|
return available();
|
||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallback("getText", [appController]() -> Maybe<String> {
|
callbacks.registerCallback("hasText", [=]() -> bool {
|
||||||
return appController->getClipboard();
|
return available() && appController->hasClipboard();
|
||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallback("setText", [appController](String const& text) {
|
callbacks.registerCallback("getText", [=]() -> Maybe<String> {
|
||||||
appController->setClipboard(text);
|
if (!available())
|
||||||
|
return {};
|
||||||
|
else
|
||||||
|
return appController->getClipboard();
|
||||||
|
});
|
||||||
|
|
||||||
|
callbacks.registerCallback("setText", [=](String const& text) -> bool {
|
||||||
|
if (available()) {
|
||||||
|
appController->setClipboard(text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return callbacks;
|
return callbacks;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
namespace LuaBindings {
|
namespace LuaBindings {
|
||||||
LuaCallbacks makeClipboardCallbacks(ApplicationControllerPtr appController);
|
LuaCallbacks makeClipboardCallbacks(ApplicationControllerPtr appController, bool alwaysAllow);
|
||||||
}
|
}
|
||||||
|
|
||||||
}// namespace Star
|
}// namespace Star
|
||||||
|
@ -223,7 +223,7 @@ Input::BindEntry::BindEntry(String entryId, Json const& config, BindCategory con
|
|||||||
category = &parentCategory;
|
category = &parentCategory;
|
||||||
id = entryId;
|
id = entryId;
|
||||||
name = config.getString("name", id);
|
name = config.getString("name", id);
|
||||||
|
tags = jsonToStringList(config.get("tags", JsonArray()));
|
||||||
for (Json const& jBind : config.getArray("default", {})) {
|
for (Json const& jBind : config.getArray("default", {})) {
|
||||||
try
|
try
|
||||||
{ defaultBinds.emplace_back(bindFromJson(jBind)); }
|
{ defaultBinds.emplace_back(bindFromJson(jBind)); }
|
||||||
@ -342,6 +342,15 @@ Input::InputState* Input::bindStatePtr(String const& categoryId, String const& b
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Input::InputState& Input::addBindState(BindEntry const* bindEntry) {
|
||||||
|
auto insertion = m_bindStates.insert(bindEntry, InputState());
|
||||||
|
if (insertion.second) {
|
||||||
|
for (auto& tag : bindEntry->tags)
|
||||||
|
++m_activeTags[tag];
|
||||||
|
}
|
||||||
|
return insertion.first->second;
|
||||||
|
}
|
||||||
|
|
||||||
Input* Input::s_singleton;
|
Input* Input::s_singleton;
|
||||||
|
|
||||||
Input* Input::singletonPtr() {
|
Input* Input::singletonPtr() {
|
||||||
@ -393,7 +402,19 @@ void Input::reset() {
|
|||||||
eraseWhere(m_keyStates, eraseCond);
|
eraseWhere(m_keyStates, eraseCond);
|
||||||
eraseWhere(m_mouseStates, eraseCond);
|
eraseWhere(m_mouseStates, eraseCond);
|
||||||
eraseWhere(m_controllerStates, eraseCond);
|
eraseWhere(m_controllerStates, eraseCond);
|
||||||
eraseWhere(m_bindStates, eraseCond);
|
eraseWhere(m_bindStates, [&](auto& p) {
|
||||||
|
if (p.second.held)
|
||||||
|
p.second.reset();
|
||||||
|
else {
|
||||||
|
for (auto& tag : p.first->tags) {
|
||||||
|
auto find = m_activeTags.find(tag);
|
||||||
|
if (find != m_activeTags.end() && !--find->second)
|
||||||
|
m_activeTags.erase(find);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::update() {
|
void Input::update() {
|
||||||
@ -415,7 +436,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
|
|||||||
|
|
||||||
if (auto binds = m_bindMappings.ptr(keyDown->key)) {
|
if (auto binds = m_bindMappings.ptr(keyDown->key)) {
|
||||||
for (auto bind : filterBindEntries(*binds, keyDown->mods))
|
for (auto bind : filterBindEntries(*binds, keyDown->mods))
|
||||||
m_bindStates[bind].press();
|
addBindState(bind).press();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,7 +468,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
|
|||||||
|
|
||||||
if (auto binds = m_bindMappings.ptr(mouseDown->mouseButton)) {
|
if (auto binds = m_bindMappings.ptr(mouseDown->mouseButton)) {
|
||||||
for (auto bind : filterBindEntries(*binds, m_pressedMods))
|
for (auto bind : filterBindEntries(*binds, m_pressedMods))
|
||||||
m_bindStates[bind].press();
|
addBindState(bind).press();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,7 +496,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) {
|
|||||||
|
|
||||||
if (auto binds = m_bindMappings.ptr(controllerDown->controllerButton)) {
|
if (auto binds = m_bindMappings.ptr(controllerDown->controllerButton)) {
|
||||||
for (auto bind : filterBindEntries(*binds, m_pressedMods))
|
for (auto bind : filterBindEntries(*binds, m_pressedMods))
|
||||||
m_bindStates[bind].press();
|
addBindState(bind).press();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -650,4 +671,8 @@ void Input::setBinds(String const& categoryId, String const& bindId, Json const&
|
|||||||
entry.updated();
|
entry.updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Input::getTag(String const& tag) {
|
||||||
|
return m_activeTags.maybe(tag).value(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -61,6 +61,8 @@ public:
|
|||||||
String name;
|
String name;
|
||||||
// The category this entry belongs to.
|
// The category this entry belongs to.
|
||||||
BindCategory const* category;
|
BindCategory const* category;
|
||||||
|
// Associated string tags that become active when this bind is pressed.
|
||||||
|
StringList tags;
|
||||||
|
|
||||||
// The default binds.
|
// The default binds.
|
||||||
List<Bind> defaultBinds;
|
List<Bind> defaultBinds;
|
||||||
@ -176,6 +178,8 @@ public:
|
|||||||
void setBinds(String const& categoryId, String const& bindId, Json const& binds);
|
void setBinds(String const& categoryId, String const& bindId, Json const& binds);
|
||||||
Json getDefaultBinds(String const& categoryId, String const& bindId);
|
Json getDefaultBinds(String const& categoryId, String const& bindId);
|
||||||
Json getBinds(String const& categoryId, String const& bindId);
|
Json getBinds(String const& categoryId, String const& bindId);
|
||||||
|
unsigned getTag(String const& tag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
List<BindEntry*> filterBindEntries(List<BindRef> const& binds, KeyMod mods) const;
|
List<BindEntry*> filterBindEntries(List<BindRef> const& binds, KeyMod mods) const;
|
||||||
|
|
||||||
@ -184,6 +188,8 @@ private:
|
|||||||
|
|
||||||
InputState* bindStatePtr(String const& categoryId, String const& bindId);
|
InputState* bindStatePtr(String const& categoryId, String const& bindId);
|
||||||
|
|
||||||
|
InputState& addBindState(BindEntry const* bindEntry);
|
||||||
|
|
||||||
static Input* s_singleton;
|
static Input* s_singleton;
|
||||||
|
|
||||||
// Regenerated on reload.
|
// Regenerated on reload.
|
||||||
@ -203,6 +209,7 @@ private:
|
|||||||
HashMap<ControllerButton, ControllerInputState> m_controllerStates;
|
HashMap<ControllerButton, ControllerInputState> m_controllerStates;
|
||||||
//Bind states
|
//Bind states
|
||||||
HashMap<BindEntry const*, InputState> m_bindStates;
|
HashMap<BindEntry const*, InputState> m_bindStates;
|
||||||
|
StringMap<unsigned> m_activeTags;
|
||||||
|
|
||||||
KeyMod m_pressedMods;
|
KeyMod m_pressedMods;
|
||||||
bool m_textInputActive;
|
bool m_textInputActive;
|
||||||
|
@ -53,6 +53,7 @@ LuaCallbacks LuaBindings::makeInputCallbacks() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallbackWithSignature<Vec2I>("mousePosition", bind(mem_fn(&Input::mousePosition), input));
|
callbacks.registerCallbackWithSignature<Vec2I>("mousePosition", bind(mem_fn(&Input::mousePosition), input));
|
||||||
|
callbacks.registerCallbackWithSignature<unsigned, String>("getTag", bind(mem_fn(&Input::getTag), input, _1));
|
||||||
|
|
||||||
return callbacks;
|
return callbacks;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallback("setConfiguration", [root](String const& key, Json const& value) {
|
callbacks.registerCallback("setConfiguration", [root](String const& key, Json const& value) {
|
||||||
if (key == "safeScripts")
|
if (key == "safeScripts" || key == "safe")
|
||||||
throw StarException(strf("Cannot set {}", key));
|
throw StarException(strf("Cannot set {}", key));
|
||||||
else
|
else
|
||||||
root->configuration()->set(key, value);
|
root->configuration()->set(key, value);
|
||||||
@ -245,7 +245,7 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
callbacks.registerCallback("setConfigurationPath", [root](String const& path, Json const& value) {
|
callbacks.registerCallback("setConfigurationPath", [root](String const& path, Json const& value) {
|
||||||
if (path.empty() || path.beginsWith("safeScripts"))
|
if (path.empty() || path.beginsWith("safeScripts") || path.splitAny("[].").get(0) == "safe")
|
||||||
throw ConfigurationException(strf("cannot set {}", path));
|
throw ConfigurationException(strf("cannot set {}", path));
|
||||||
else
|
else
|
||||||
root->configuration()->setPath(path, value);
|
root->configuration()->setPath(path, value);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user