From b9294516fc65f7a172ae119e20865b70c43c19c0 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 19 Sep 2019 16:55:28 +0300 Subject: SL-6109 Implement keybindings --- indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/indra_constants.h | 10 +++ indra/llcommon/llkeybind.cpp | 147 +++++++++++++++++++++++++++++++++++++++ indra/llcommon/llkeybind.h | 70 +++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 indra/llcommon/llkeybind.cpp create mode 100644 indra/llcommon/llkeybind.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index af41b9e460..7e52a620db 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -73,6 +73,7 @@ set(llcommon_SOURCE_FILES llinitparam.cpp llinitdestroyclass.cpp llinstancetracker.cpp + llkeybind.cpp llleap.cpp llleaplistener.cpp llliveappconfig.cpp @@ -183,6 +184,7 @@ set(llcommon_HEADER_FILES llinitdestroyclass.h llinitparam.h llinstancetracker.h + llkeybind.h llkeythrottle.h llleap.h llleaplistener.h diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index e7b0e0ef8e..f8c0232660 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -54,6 +54,16 @@ enum ETerrainBrushType E_LANDBRUSH_INVALID = 6 }; +enum EMouseClickType{ + CLICK_NONE = -1, + CLICK_LEFT = 0, + CLICK_MIDDLE, + CLICK_RIGHT, + CLICK_BUTTON4, + CLICK_BUTTON5, + CLICK_DOUBLELEFT +}; + // keys // Bit masks for various keyboard modifier keys. const MASK MASK_NONE = 0x0000; diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp new file mode 100644 index 0000000000..f227c0a1a5 --- /dev/null +++ b/indra/llcommon/llkeybind.cpp @@ -0,0 +1,147 @@ +/** + * @file llkeybind.cpp + * @brief Information about key combinations. + * + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, 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 "linden_common.h" + +#include "llkeybind.h" + +#include "llsd.h" +#include "llsdutil.h" + +LLKeyData::LLKeyData() + : mMouse(CLICK_NONE), mKey(KEY_NONE), mMask(MASK_NONE) +{ +} + +LLKeyData::LLKeyData(const LLSD &key_data) +{ + mMouse = (EMouseClickType)key_data["mouse"].asInteger(); + mKey = key_data["key"].asInteger(); + mMask = key_data["mask"].asInteger(); +} + +LLSD LLKeyData::asLLSD() const +{ + LLSD data; + data["mouse"] = (LLSD::Integer)mMouse; + data["key"] = (LLSD::Integer)mKey; + data["mask"] = (LLSD::Integer)mMask; + return data; +} + +bool LLKeyData::isEmpty() const +{ + return mMouse == CLICK_NONE && mKey == KEY_NONE && mMask == MASK_NONE; +} + +void LLKeyData::reset() +{ + mMouse = CLICK_NONE; + mKey = KEY_NONE; + mMask = MASK_NONE; +} + +LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) +{ + mMouse = rhs.mMouse; + mKey = rhs.mKey; + mMask = rhs.mMask; + return *this; +} + +// LLKeyBind + +LLKeyBind::LLKeyBind(const LLSD &key_bind) +{ + if (key_bind.has("DataPrimary")) + { + mDataPrimary = LLKeyData(key_bind["DataPrimary"]); + } + if (key_bind.has("DataSecondary")) + { + mDataSecondary = LLKeyData(key_bind["DataSecondary"]); + } +} + +bool LLKeyBind::operator==(const LLKeyBind& rhs) +{ + if (mDataPrimary.mMouse != rhs.mDataPrimary.mMouse) return false; + if (mDataPrimary.mKey != rhs.mDataPrimary.mKey) return false; + if (mDataPrimary.mMask != rhs.mDataPrimary.mMask) return false; + if (mDataSecondary.mMouse != rhs.mDataSecondary.mMouse) return false; + if (mDataSecondary.mKey != rhs.mDataSecondary.mKey) return false; + if (mDataSecondary.mMask != rhs.mDataSecondary.mMask) return false; + return true; +} + +bool LLKeyBind::empty() +{ + if (mDataPrimary.mMouse != CLICK_NONE) return false; + if (mDataPrimary.mKey != KEY_NONE) return false; + if (mDataPrimary.mMask != MASK_NONE) return false; + if (mDataSecondary.mMouse != CLICK_NONE) return false; + if (mDataSecondary.mKey != KEY_NONE) return false; + if (mDataSecondary.mMask != MASK_NONE) return false; + return false; +} + +LLSD LLKeyBind::asLLSD() const +{ + LLSD data; + if (!mDataPrimary.isEmpty()) + { + data["DataPrimary"] = mDataPrimary.asLLSD(); + } + if (!mDataSecondary.isEmpty()) + { + data["DataSecondary"] = mDataSecondary.asLLSD(); + } + return data; +} + +bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const +{ + if (mDataPrimary.mKey == key && mDataPrimary.mMask == mask && mDataPrimary.mMouse == mouse) + { + return true; + } + if (mDataSecondary.mKey == key && mDataSecondary.mMask == mask && mDataSecondary.mMouse == mouse) + { + return true; + } + return false; +} + +bool LLKeyBind::canHandleKey(KEY key, MASK mask) const +{ + return canHandle(CLICK_NONE, key, mask); +} + +bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const +{ + return canHandle(mouse, KEY_NONE, mask); +} + diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h new file mode 100644 index 0000000000..4fe622fb79 --- /dev/null +++ b/indra/llcommon/llkeybind.h @@ -0,0 +1,70 @@ +/** + * @file llkeybind.h + * @brief Information about key combinations. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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_KEYBIND_H +#define LL_KEYBIND_H + +#include "indra_constants.h" + +// KeyData - single key combination (mouse/mask/keyboard) +class LL_COMMON_API LLKeyData +{ +public: + LLKeyData(); + LLKeyData(const LLSD &key_data); + + LLSD asLLSD() const; + bool isEmpty() const; + void reset(); + LLKeyData& operator=(const LLKeyData& rhs); + + EMouseClickType mMouse; + KEY mKey; + MASK mMask; +}; + +// One function can bind to multiple Key options +class LLKeyBind +{ +public: + LLKeyBind() {} + LLKeyBind(const LLSD &key_bind); + + bool operator==(const LLKeyBind& rhs); + bool empty(); + + LLSD asLLSD() const; + + bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const; + bool canHandleKey(KEY key, MASK mask) const; + bool canHandleMouse(EMouseClickType mouse, MASK mask) const; + + LLKeyData mDataPrimary; + LLKeyData mDataSecondary; +}; + + +#endif // LL_KEYBIND_H -- cgit v1.2.3 From 4df05c5a8995158922c7b7aacfef442ac8ae6fdd Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 17 Sep 2019 21:36:59 +0300 Subject: SL-6109 Keyaboard support ready --- indra/llcommon/llkeybind.cpp | 180 ++++++++++++++++++++++++++++++++++++------- indra/llcommon/llkeybind.h | 23 +++++- 2 files changed, 171 insertions(+), 32 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index f227c0a1a5..765084bbf6 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -36,6 +36,11 @@ LLKeyData::LLKeyData() { } +LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask) +: mMouse(mouse), mKey(key), mMask(mask) +{ +} + LLKeyData::LLKeyData(const LLSD &key_data) { mMouse = (EMouseClickType)key_data["mouse"].asInteger(); @@ -72,65 +77,100 @@ LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) return *this; } +bool LLKeyData::operator==(const LLKeyData& rhs) +{ + if (mMouse != rhs.mMouse) return false; + if (mKey != rhs.mKey) return false; + if (mMask != rhs.mMask) return false; + return true; +} + +bool LLKeyData::operator!=(const LLKeyData& rhs) +{ + if (mMouse != rhs.mMouse) return true; + if (mKey != rhs.mKey) return true; + if (mMask != rhs.mMask) return true; + return false; +} + // LLKeyBind LLKeyBind::LLKeyBind(const LLSD &key_bind) { - if (key_bind.has("DataPrimary")) - { - mDataPrimary = LLKeyData(key_bind["DataPrimary"]); - } - if (key_bind.has("DataSecondary")) + if (key_bind.isArray()) { - mDataSecondary = LLKeyData(key_bind["DataSecondary"]); + for (LLSD::array_const_iterator data = key_bind.beginArray(), endLists = key_bind.endArray(); + data != endLists; + data++ + ) + { + mData.push_back(LLKeyData(*data)); + } } } bool LLKeyBind::operator==(const LLKeyBind& rhs) { - if (mDataPrimary.mMouse != rhs.mDataPrimary.mMouse) return false; - if (mDataPrimary.mKey != rhs.mDataPrimary.mKey) return false; - if (mDataPrimary.mMask != rhs.mDataPrimary.mMask) return false; - if (mDataSecondary.mMouse != rhs.mDataSecondary.mMouse) return false; - if (mDataSecondary.mKey != rhs.mDataSecondary.mKey) return false; - if (mDataSecondary.mMask != rhs.mDataSecondary.mMask) return false; + U32 size = mData.size(); + if (size != rhs.mData.size()) return false; + + for (U32 i = 0; i < size; i++) + { + if (mData[i] != rhs.mData[i]) return false; + } + return true; } -bool LLKeyBind::empty() +bool LLKeyBind::operator!=(const LLKeyBind& rhs) { - if (mDataPrimary.mMouse != CLICK_NONE) return false; - if (mDataPrimary.mKey != KEY_NONE) return false; - if (mDataPrimary.mMask != MASK_NONE) return false; - if (mDataSecondary.mMouse != CLICK_NONE) return false; - if (mDataSecondary.mKey != KEY_NONE) return false; - if (mDataSecondary.mMask != MASK_NONE) return false; + U32 size = mData.size(); + if (size != rhs.mData.size()) return true; + + for (U32 i = 0; i < size; i++) + { + if (mData[i] != rhs.mData[i]) return true; + } + return false; } -LLSD LLKeyBind::asLLSD() const +bool LLKeyBind::isEmpty() const { - LLSD data; - if (!mDataPrimary.isEmpty()) + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) { - data["DataPrimary"] = mDataPrimary.asLLSD(); + if (!iter->isEmpty()) return false; } - if (!mDataSecondary.isEmpty()) + return true; +} + +LLSD LLKeyBind::asLLSD() const +{ + LLSD data; + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) { - data["DataSecondary"] = mDataSecondary.asLLSD(); + if (!iter->isEmpty()) + { + data.append(iter->asLLSD()); + } } return data; } bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const { - if (mDataPrimary.mKey == key && mDataPrimary.mMask == mask && mDataPrimary.mMouse == mouse) + if (mouse == CLICK_NONE && key == KEY_NONE) { - return true; + // assume placeholder + return false; } - if (mDataSecondary.mKey == key && mDataSecondary.mMask == mask && mDataSecondary.mMouse == mouse) + + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) { - return true; + if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + { + return true; + } } return false; } @@ -145,3 +185,85 @@ bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const return canHandle(mouse, KEY_NONE, mask); } +bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask) +{ + if (!canHandle(mouse, key, mask)) + { + mData.push_back(LLKeyData(mouse, key, mask)); + return true; + } + return false; +} + +bool LLKeyBind::addKeyData(const LLKeyData& data) +{ + if (!canHandle(data.mMouse, data.mKey, data.mMask)) + { + mData.push_back(data); + return true; + } + return false; +} + +void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index) +{ + if (mouse != CLICK_NONE && key != KEY_NONE && mask != MASK_NONE) + { + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + { + if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + { + mData.erase(iter); + break; + } + } + } + if (mData.size() > index) + { + mData[index] = LLKeyData(mouse, key, mask); + } + else + { + mData.push_back(LLKeyData(mouse, key, mask)); + } +} + +void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) +{ + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + { + if (iter->mKey == data.mKey && iter->mMask == data.mMask && iter->mMouse == data.mMouse) + { + mData.erase(iter); + break; + } + } + if (mData.size() > index) + { + mData[index] = data; + } + else + { + mData.push_back(data); + } +} + +bool LLKeyBind::hasKeyData(U32 index) const +{ + return mData.size() > index; +} + +LLKeyData LLKeyBind::getKeyData(U32 index) const +{ + if (mData.size() > index) + { + return mData[index]; + } + return LLKeyData(); +} + +U32 LLKeyBind::getDataCount() +{ + return mData.size(); +} + diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 4fe622fb79..481949f275 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -34,12 +34,16 @@ class LL_COMMON_API LLKeyData { public: LLKeyData(); + LLKeyData(EMouseClickType mouse, KEY key, MASK mask); LLKeyData(const LLSD &key_data); LLSD asLLSD() const; bool isEmpty() const; + bool empty() const { return isEmpty(); }; void reset(); LLKeyData& operator=(const LLKeyData& rhs); + bool operator==(const LLKeyData& rhs); + bool operator!=(const LLKeyData& rhs); EMouseClickType mMouse; KEY mKey; @@ -54,7 +58,9 @@ public: LLKeyBind(const LLSD &key_bind); bool operator==(const LLKeyBind& rhs); - bool empty(); + bool operator!=(const LLKeyBind& rhs); + bool isEmpty() const; + bool empty() const { return isEmpty(); }; LLSD asLLSD() const; @@ -62,8 +68,19 @@ public: bool canHandleKey(KEY key, MASK mask) const; bool canHandleMouse(EMouseClickType mouse, MASK mask) const; - LLKeyData mDataPrimary; - LLKeyData mDataSecondary; + // these methods enshure there will be no repeats + bool addKeyData(EMouseClickType mouse, KEY key, MASK mask); + bool addKeyData(const LLKeyData& data); + void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index); + void replaceKeyData(const LLKeyData& data, U32 index); + bool hasKeyData(U32 index) const; + void clear() { mData.clear(); }; + LLKeyData getKeyData(U32 index) const; + U32 getDataCount(); + +private: + typedef std::vector data_vector_t; + data_vector_t mData; }; -- cgit v1.2.3 From c60b929fbb615f8d73f7bf42849b5628bf0f8f7a Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 25 Sep 2019 17:54:36 +0300 Subject: SL-6109 Mouse support ready --- indra/llcommon/indra_constants.h | 3 +- indra/llcommon/llkeybind.cpp | 152 +++++++++++++++++++++++++++++++++------ indra/llcommon/llkeybind.h | 13 +++- 3 files changed, 142 insertions(+), 26 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index f8c0232660..10b98f49aa 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -61,7 +61,8 @@ enum EMouseClickType{ CLICK_RIGHT, CLICK_BUTTON4, CLICK_BUTTON5, - CLICK_DOUBLELEFT + CLICK_DOUBLELEFT, + CLICK_COUNT // 'size', CLICK_NONE does not counts }; // keys diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 765084bbf6..0eca289d4b 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -32,20 +32,59 @@ #include "llsdutil.h" LLKeyData::LLKeyData() - : mMouse(CLICK_NONE), mKey(KEY_NONE), mMask(MASK_NONE) + : + mMouse(CLICK_NONE), + mKey(KEY_NONE), + mMask(MASK_NONE), + mIgnoreMasks(false) { } LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask) -: mMouse(mouse), mKey(key), mMask(mask) + : + mMouse(mouse), + mKey(key), + mMask(mask), + mIgnoreMasks(false) +{ +} + +LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask) + : + mMouse(mouse), + mKey(key), + mMask(MASK_NONE), + mIgnoreMasks(ignore_mask) +{ +} + +LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) + : + mMouse(mouse), + mKey(key), + mMask(mask), + mIgnoreMasks(ignore_mask) { } LLKeyData::LLKeyData(const LLSD &key_data) { - mMouse = (EMouseClickType)key_data["mouse"].asInteger(); - mKey = key_data["key"].asInteger(); - mMask = key_data["mask"].asInteger(); + if (key_data.has("mouse")) + { + mMouse = (EMouseClickType)key_data["mouse"].asInteger(); + } + if (key_data.has("key")) + { + mKey = key_data["key"].asInteger(); + } + if (key_data.has("ignore_accelerators")) + { + mIgnoreMasks = key_data["ignore_accelerators"]; + } + if (key_data.has("mask")) + { + mMask = key_data["mask"].asInteger(); + } } LLSD LLKeyData::asLLSD() const @@ -53,13 +92,20 @@ LLSD LLKeyData::asLLSD() const LLSD data; data["mouse"] = (LLSD::Integer)mMouse; data["key"] = (LLSD::Integer)mKey; - data["mask"] = (LLSD::Integer)mMask; + if (mIgnoreMasks) + { + data["ignore_accelerators"] = (LLSD::Boolean)mIgnoreMasks; + } + else + { + data["mask"] = (LLSD::Integer)mMask; + } return data; } bool LLKeyData::isEmpty() const { - return mMouse == CLICK_NONE && mKey == KEY_NONE && mMask == MASK_NONE; + return mMouse == CLICK_NONE && mKey == KEY_NONE; } void LLKeyData::reset() @@ -67,6 +113,7 @@ void LLKeyData::reset() mMouse = CLICK_NONE; mKey = KEY_NONE; mMask = MASK_NONE; + mIgnoreMasks = false; } LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) @@ -74,6 +121,7 @@ LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) mMouse = rhs.mMouse; mKey = rhs.mKey; mMask = rhs.mMask; + mIgnoreMasks = rhs.mIgnoreMasks; return *this; } @@ -82,6 +130,7 @@ bool LLKeyData::operator==(const LLKeyData& rhs) if (mMouse != rhs.mMouse) return false; if (mKey != rhs.mKey) return false; if (mMask != rhs.mMask) return false; + if (mIgnoreMasks != rhs.mIgnoreMasks) return false; return true; } @@ -90,6 +139,29 @@ bool LLKeyData::operator!=(const LLKeyData& rhs) if (mMouse != rhs.mMouse) return true; if (mKey != rhs.mKey) return true; if (mMask != rhs.mMask) return true; + if (mIgnoreMasks != rhs.mIgnoreMasks) return true; + return false; +} + +bool LLKeyData::canHandle(const LLKeyData& data) const +{ + if (data.mKey == mKey + && data.mMouse == mMouse + && (mIgnoreMasks || data.mMask == mMask)) + { + return true; + } + return false; +} + +bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const +{ + if (mouse == mMouse + && key == mKey + && (mIgnoreMasks || mask == mMask)) + { + return true; + } return false; } @@ -167,7 +239,7 @@ bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) { - if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + if (iter->canHandle(mouse, key, mask)) { return true; } @@ -185,11 +257,34 @@ bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const return canHandle(mouse, KEY_NONE, mask); } -bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask) +bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const +{ + if (mouse != CLICK_NONE || key != KEY_NONE) + { + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + { + if (iter->mKey == key + && iter->mMask == mask + && iter->mMouse == mouse + && iter->mIgnoreMasks == ignore) + { + return true; + } + } + } + return false; +} + +bool LLKeyBind::hasKeyData(const LLKeyData& data) const { - if (!canHandle(mouse, key, mask)) + return hasKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); +} + +bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) +{ + if (!hasKeyData(mouse, key, mask, ignore)) { - mData.push_back(LLKeyData(mouse, key, mask)); + mData.push_back(LLKeyData(mouse, key, mask, ignore)); return true; } return false; @@ -197,7 +292,7 @@ bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask) bool LLKeyBind::addKeyData(const LLKeyData& data) { - if (!canHandle(data.mMouse, data.mKey, data.mMask)) + if (!hasKeyData(data)) { mData.push_back(data); return true; @@ -205,37 +300,48 @@ bool LLKeyBind::addKeyData(const LLKeyData& data) return false; } -void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index) +void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index) { - if (mouse != CLICK_NONE && key != KEY_NONE && mask != MASK_NONE) + if (mouse != CLICK_NONE || key != KEY_NONE ) { - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + // if both click and key are none, we are inserting a placeholder, we don't want to reset anything + // otherwise reset identical key + for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) { - if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + if (iter->mKey == key + && iter->mMouse == mouse + && iter->mIgnoreMasks == ignore + && (iter->mIgnoreMasks || iter->mMask == mask)) { - mData.erase(iter); + iter->reset(); break; } } } if (mData.size() > index) { - mData[index] = LLKeyData(mouse, key, mask); + mData[index] = LLKeyData(mouse, key, mask, ignore); } else { - mData.push_back(LLKeyData(mouse, key, mask)); + mData.push_back(LLKeyData(mouse, key, mask, ignore)); } } void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) { - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + if (!data.isEmpty()) { - if (iter->mKey == data.mKey && iter->mMask == data.mMask && iter->mMouse == data.mMouse) + for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) { - mData.erase(iter); - break; + if (iter->mKey == data.mKey + && iter->mMouse == data.mMouse + && iter->mIgnoreMasks == data.mIgnoreMasks + && (iter->mIgnoreMasks || iter->mMask == data.mMask)) + { + iter->reset(); + break; + } } } if (mData.size() > index) diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 481949f275..25179a57f3 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -35,6 +35,8 @@ class LL_COMMON_API LLKeyData public: LLKeyData(); LLKeyData(EMouseClickType mouse, KEY key, MASK mask); + LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask); + LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask); LLKeyData(const LLSD &key_data); LLSD asLLSD() const; @@ -45,9 +47,13 @@ public: bool operator==(const LLKeyData& rhs); bool operator!=(const LLKeyData& rhs); + bool canHandle(const LLKeyData& data) const; + bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const; + EMouseClickType mMouse; KEY mKey; MASK mMask; + bool mIgnoreMasks; }; // One function can bind to multiple Key options @@ -68,10 +74,13 @@ public: bool canHandleKey(KEY key, MASK mask) const; bool canHandleMouse(EMouseClickType mouse, MASK mask) const; + bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; + bool LLKeyBind::hasKeyData(const LLKeyData& data) const; + // these methods enshure there will be no repeats - bool addKeyData(EMouseClickType mouse, KEY key, MASK mask); + bool addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore); bool addKeyData(const LLKeyData& data); - void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index); + void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index); void replaceKeyData(const LLKeyData& data, U32 index); bool hasKeyData(U32 index) const; void clear() { mData.clear(); }; -- cgit v1.2.3 From 2532a2ee9ee9003e2c6b72f8da19979a9e3dd2f6 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 26 Sep 2019 22:28:18 +0300 Subject: SL-6109 Conflict resolution --- indra/llcommon/llkeybind.cpp | 76 ++++++++++++++++++++++++++++++++++---------- indra/llcommon/llkeybind.h | 19 ++++++++--- 2 files changed, 73 insertions(+), 22 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 0eca289d4b..ff88a9c9aa 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -218,13 +218,17 @@ bool LLKeyBind::isEmpty() const LLSD LLKeyBind::asLLSD() const { + S32 last = mData.size() - 1; + while (mData[last].empty()) + { + last--; + } + LLSD data; - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + for (S32 i = 0; i <= last; ++i) { - if (!iter->isEmpty()) - { - data.append(iter->asLLSD()); - } + // append even if empty to not affect visual representation + data.append(mData[i].asLLSD()); } return data; } @@ -280,6 +284,43 @@ bool LLKeyBind::hasKeyData(const LLKeyData& data) const return hasKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); } +bool LLKeyBind::hasKeyData(U32 index) const +{ + return mData.size() > index; +} + +S32 LLKeyBind::findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const +{ + if (mouse != CLICK_NONE || key != KEY_NONE) + { + for (S32 i = 0; i < mData.size(); ++i) + { + if (mData[i].mKey == key + && mData[i].mMask == mask + && mData[i].mMouse == mouse + && mData[i].mIgnoreMasks == ignore) + { + return i; + } + } + } + return -1; +} + +S32 LLKeyBind::findKeyData(const LLKeyData& data) const +{ + return findKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); +} + +LLKeyData LLKeyBind::getKeyData(U32 index) const +{ + if (mData.size() > index) + { + return mData[index]; + } + return LLKeyData(); +} + bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) { if (!hasKeyData(mouse, key, mask, ignore)) @@ -344,28 +385,29 @@ void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) } } } - if (mData.size() > index) + if (mData.size() <= index) { - mData[index] = data; - } - else - { - mData.push_back(data); + mData.resize(index + 1); } + mData[index] = data; } -bool LLKeyBind::hasKeyData(U32 index) const +void LLKeyBind::resetKeyData(S32 index) { - return mData.size() > index; + if (mData.size() > index) + { + mData[index].reset(); + } } -LLKeyData LLKeyBind::getKeyData(U32 index) const +void LLKeyBind::trimEmpty() { - if (mData.size() > index) + S32 last = mData.size() - 1; + while (last >= 0 && mData[last].empty()) { - return mData[index]; + mData.erase(mData.begin() + last); + last--; } - return LLKeyData(); } U32 LLKeyBind::getDataCount() diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 25179a57f3..39cb668aac 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -74,17 +74,26 @@ public: bool canHandleKey(KEY key, MASK mask) const; bool canHandleMouse(EMouseClickType mouse, MASK mask) const; - bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; - bool LLKeyBind::hasKeyData(const LLKeyData& data) const; + // contains specified combination + bool hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; + bool hasKeyData(const LLKeyData& data) const; + bool hasKeyData(U32 index) const; + + // index of contained LLKeyData + S32 findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; + S32 findKeyData(const LLKeyData& data) const; + + LLKeyData getKeyData(U32 index) const; // these methods enshure there will be no repeats bool addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore); bool addKeyData(const LLKeyData& data); void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index); void replaceKeyData(const LLKeyData& data, U32 index); - bool hasKeyData(U32 index) const; - void clear() { mData.clear(); }; - LLKeyData getKeyData(U32 index) const; + void resetKeyData(S32 index); + void clear() { mData.clear(); } + // if there any empty LLKeyData in the end of the array, remove them + void trimEmpty(); U32 getDataCount(); private: -- cgit v1.2.3 From e211372923bed31e632bc9825913d3d57cdc2d52 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 3 Oct 2019 22:45:29 +0300 Subject: SL-6109 Remade 'ignore' list processing, renamed and reformed keybindings --- indra/llcommon/llkeybind.cpp | 9 +++------ indra/llcommon/llkeybind.h | 3 ++- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index ff88a9c9aa..46a3230240 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -92,14 +92,11 @@ LLSD LLKeyData::asLLSD() const LLSD data; data["mouse"] = (LLSD::Integer)mMouse; data["key"] = (LLSD::Integer)mKey; + data["mask"] = (LLSD::Integer)mMask; if (mIgnoreMasks) { data["ignore_accelerators"] = (LLSD::Boolean)mIgnoreMasks; } - else - { - data["mask"] = (LLSD::Integer)mMask; - } return data; } @@ -147,7 +144,7 @@ bool LLKeyData::canHandle(const LLKeyData& data) const { if (data.mKey == mKey && data.mMouse == mMouse - && (mIgnoreMasks || data.mMask == mMask)) + && ((mIgnoreMasks && (data.mMask & mMask) == data.mMask) || data.mMask == mMask)) { return true; } @@ -158,7 +155,7 @@ bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const { if (mouse == mMouse && key == mKey - && (mIgnoreMasks || mask == mMask)) + && ((mIgnoreMasks && (mask & mMask) == mask) || mask == mMask)) { return true; } diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 39cb668aac..ad0ebec67c 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -53,7 +53,8 @@ public: EMouseClickType mMouse; KEY mKey; MASK mMask; - bool mIgnoreMasks; + // Either to expect exact match or ignore not expected masks + bool mIgnoreMasks; }; // One function can bind to multiple Key options -- cgit v1.2.3 From 5568018bd20a43c30caca0c6288e63bfae29a2e3 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Sun, 10 Nov 2019 19:06:03 +0200 Subject: SL-6109 Better key and table localization support and fix for key-replacing --- indra/llcommon/llkeybind.cpp | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 46a3230240..ecfc289cb3 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -340,43 +340,24 @@ bool LLKeyBind::addKeyData(const LLKeyData& data) void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index) { - if (mouse != CLICK_NONE || key != KEY_NONE ) - { - // if both click and key are none, we are inserting a placeholder, we don't want to reset anything - // otherwise reset identical key - for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) - { - if (iter->mKey == key - && iter->mMouse == mouse - && iter->mIgnoreMasks == ignore - && (iter->mIgnoreMasks || iter->mMask == mask)) - { - iter->reset(); - break; - } - } - } - if (mData.size() > index) - { - mData[index] = LLKeyData(mouse, key, mask, ignore); - } - else - { - mData.push_back(LLKeyData(mouse, key, mask, ignore)); - } + replaceKeyData(LLKeyData(mouse, key, mask, ignore), index); } void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) { if (!data.isEmpty()) { + // if both click and key are none (isEmpty()), we are inserting a placeholder, we don't want to reset anything + // otherwise reset identical key for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) { if (iter->mKey == data.mKey && iter->mMouse == data.mMouse && iter->mIgnoreMasks == data.mIgnoreMasks - && (iter->mIgnoreMasks || iter->mMask == data.mMask)) + && iter->mMask == data.mMask) { + // Replacing only fully equal combinations even in case 'ignore' is set + // Reason: Simplicity and user might decide to do a 'move' command as W and Shift+Ctrl+W, and 'run' as Shift+W iter->reset(); break; } -- cgit v1.2.3 From 6092e2ffab9ec76bdd8821e188db9cb785456eee Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 15 Jun 2020 18:13:46 +0300 Subject: SL-13418 Added converter from old mouse binding settings to new ones --- indra/llcommon/llkeybind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index ad0ebec67c..c6b4bd970f 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -53,7 +53,7 @@ public: EMouseClickType mMouse; KEY mKey; MASK mMask; - // Either to expect exact match or ignore not expected masks + // Either to expect exact match or ignore not expected masks as long as expected mask-bit is present bool mIgnoreMasks; }; -- cgit v1.2.3 From 7e0254ecd5923a488e69036c256a05890193524c Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 28 Nov 2019 17:09:34 +0200 Subject: SL-6109 Fixed issue with llcontrols ignoring left mouse button with masks --- indra/llcommon/llkeybind.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index ecfc289cb3..38696c2258 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -144,7 +144,7 @@ bool LLKeyData::canHandle(const LLKeyData& data) const { if (data.mKey == mKey && data.mMouse == mMouse - && ((mIgnoreMasks && (data.mMask & mMask) == data.mMask) || data.mMask == mMask)) + && ((mIgnoreMasks && (data.mMask & mMask) == mMask) || data.mMask == mMask)) { return true; } @@ -155,7 +155,7 @@ bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const { if (mouse == mMouse && key == mKey - && ((mIgnoreMasks && (mask & mMask) == mask) || mask == mMask)) + && ((mIgnoreMasks && (mask & mMask) == mMask) || mask == mMask)) { return true; } -- cgit v1.2.3