diff options
-rw-r--r-- | minetest.conf.example | 4 | ||||
-rw-r--r-- | src/client/keycode.cpp | 9 | ||||
-rw-r--r-- | src/client/keycode.h | 3 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 1 | ||||
-rw-r--r-- | src/gui/guiChatConsole.cpp | 67 | ||||
-rw-r--r-- | src/gui/guiChatConsole.h | 6 |
6 files changed, 87 insertions, 3 deletions
diff --git a/minetest.conf.example b/minetest.conf.example index 814e34e43..524ef6334 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -24,6 +24,10 @@ # type: string # chat_weblink_color = 8888FF +# If clickable_chat_weblinks is enabled, specify the keys held down to treat left-click as middle-click. +# type: string (comma-delimited) +# chat_weblink_ctrl_keys = KEY_LCONTROL,KEY_RCONTROL,KEY_CONTROL + # If enabled, you can place blocks at the position (feet + eye level) where you stand. # This is helpful when working with nodeboxes in small areas. # type: bool diff --git a/src/client/keycode.cpp b/src/client/keycode.cpp index ce5214f54..08aff43ce 100644 --- a/src/client/keycode.cpp +++ b/src/client/keycode.cpp @@ -386,3 +386,12 @@ irr::EKEY_CODE keyname_to_keycode(const char *name) { return lookup_keyname(name).Key; } + +irr::EKEY_CODE keyname_to_keycode_safemode(const char *name) +{ + try { + return lookup_keyname(name).Key; + } catch (UnknownKeycode &e) { + return irr::KEY_KEY_CODES_COUNT; + } +} diff --git a/src/client/keycode.h b/src/client/keycode.h index 7036705d1..cb3114099 100644 --- a/src/client/keycode.h +++ b/src/client/keycode.h @@ -65,3 +65,6 @@ KeyPress getKeySetting(const char *settingname); void clearKeyCache(); irr::EKEY_CODE keyname_to_keycode(const char *name); + +// Now with internal exception handling. return irr::KEY_KEY_CODES_COUNT on fail +irr::EKEY_CODE keyname_to_keycode_safemode(const char *name); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index c59b93e88..132e31d2b 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -284,6 +284,7 @@ void set_default_settings() settings->setDefault("joystick_deadzone", "2048"); settings->setDefault("clickable_chat_weblinks", "false"); settings->setDefault("chat_weblink_color", "8888FF"); + settings->setDefault("chat_weblink_ctrl_keys", "KEY_LCONTROL,KEY_RCONTROL,KEY_CONTROL"); // Main menu settings->setDefault("main_menu_path", ""); diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index f5336e3ad..08d26efc2 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -90,8 +90,19 @@ GUIChatConsole::GUIChatConsole( // set default cursor options setCursor(true, true, 2.0, 0.1); - + m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks"); + if(m_cache_clickable_chat_weblinks) + { + std::string ctrlkeystoparse = g_settings->get("chat_weblink_ctrl_keys"); + if(setupChatClickCtrlKeys(ctrlkeystoparse) == 0) + { + // if fail then try again w hardcoded string + g_logger.log(LL_WARNING, "Failed to parse chat_weblink_ctrl_keys. Using hardcoded default."); + ctrlkeystoparse = "KEY_CONTROL,KEY_LCONTROL,KEY_RCONTROL"; + setupChatClickCtrlKeys(ctrlkeystoparse); + } + } } GUIChatConsole::~GUIChatConsole() @@ -412,7 +423,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) if(event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown) { // CTRL up - if(event.KeyInput.Key == KEY_LCONTROL || event.KeyInput.Key == KEY_RCONTROL || !event.KeyInput.Control) + if(isInCtrlKeys(event.KeyInput.Key) || !event.KeyInput.Control) { isctrldown = false; } @@ -420,7 +431,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) else if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown) { // CTRL down - if(event.KeyInput.Key == KEY_LCONTROL || event.KeyInput.Key == KEY_RCONTROL || event.KeyInput.Control) + if(isInCtrlKeys(event.KeyInput.Key) || event.KeyInput.Control) { isctrldown = true; } @@ -669,3 +680,53 @@ void GUIChatConsole::setVisible(bool visible) } } +// Return how many "ctrl" keycodes successfully found in string, or 0 on fail +int GUIChatConsole::setupChatClickCtrlKeys(std::string inputline) +{ + m_cache_chat_weblink_ctrl_keys.clear(); + + irr::EKEY_CODE kc; + std::string stemp; + size_t startpos = 0, endpos = 0; + while(startpos < inputline.size()) + { + // Foreach delimited string, + endpos = inputline.find(',', startpos); + endpos = std::min(endpos, inputline.find(' ', startpos)); + // Ignore space/comma + if(endpos == startpos) + { + ++endpos; + } + // Ignore consecutive space/comma + else if(endpos - startpos > 1) + { + // If valid keycode, add it to cached list + stemp = inputline.substr(startpos, endpos - startpos); + kc = keyname_to_keycode_safemode(stemp.c_str()); + if(kc != irr::KEY_KEY_CODES_COUNT) + { + m_cache_chat_weblink_ctrl_keys.push_back(kc); + } + else + { + stemp = "Ignoring unknown keycode '" + stemp + "' for chat_weblink_ctrl_keys, check your conf"; + g_logger.log(LL_WARNING, stemp); + } + } + startpos = endpos; + } + + return m_cache_chat_weblink_ctrl_keys.size(); +} + +bool GUIChatConsole::isInCtrlKeys(const irr::EKEY_CODE& kc) +{ + // To avoid including <algorithm> + for(size_t i=0; i<m_cache_chat_weblink_ctrl_keys.size(); ++i) + { + if(m_cache_chat_weblink_ctrl_keys.at(i) == kc) + return true; + } + return false; +} diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 501bf50cb..058b78f28 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -82,6 +82,10 @@ private: void drawText(); void drawPrompt(); + // Parse conf and populate "ctrl" keys for clickable chat + int setupChatClickCtrlKeys(std::string inputline); + bool isInCtrlKeys(const irr::EKEY_CODE& kc); + private: ChatBackend* m_chat_backend; Client* m_client; @@ -127,4 +131,6 @@ private: // Enable clickable chat weblinks bool m_cache_clickable_chat_weblinks; + // Set of "control" keys for weblink mouseclicks + std::vector<irr::EKEY_CODE> m_cache_chat_weblink_ctrl_keys; }; |