diff --git a/.gitignore b/.gitignore index 627d5951a6..399b833ba2 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ indra/web/doc/asset-upload/plugins/verify-texture installed.xml libraries tarfile_tmp +trivial_change_force_build web/config.* web/locale.* web/secondlife.com.* diff --git a/autobuild.xml b/autobuild.xml index 6353cb271e..9a040ce61c 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -826,9 +826,9 @@ archive hash - 23aeaf23e7db2484a1850017141860dd + 350866eec6be17ffc265904b91dcfe6b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/34069/283470/dullahan-1.1.1320_3.3626.1895.g7001d56-darwin64-525361.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60900/572290/dullahan-1.7.0.202005311125_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-543086.tar.bz2 name darwin64 @@ -850,9 +850,9 @@ archive hash - 43c03679c3847754b407532efe5d4392 + aa4faf9ef9057362d63f8d57092506b3 url - http://downloads.phoenixviewer.com/dullahan-1.7.0.202005292352_81.3.10_gb223419_chromium-81.0.4044.138-windows-201512310.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60902/572301/dullahan-1.7.0.202005311828_81.3.10_gb223419_chromium-81.0.4044.138-windows-543086.tar.bz2 name windows @@ -862,16 +862,16 @@ archive hash - 13574736220c05de847980f851f42827 + 6e29ea2ccdad80dcf1b5dc974932c1f6 url - http://downloads.phoenixviewer.com/dullahan-1.7.0.202005292352_81.3.10_gb223419_chromium-81.0.4044.138-windows64-201512301.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60901/572302/dullahan-1.7.0.202005311828_81.3.10_gb223419_chromium-81.0.4044.138-windows64-543086.tar.bz2 name windows64 version - 1.1.1320_3.3626.1895.g7001d56 + 1.7.0.202005311828_81.3.10_gb223419_chromium-81.0.4044.138 elfio diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index c41ee1e93d..4b8f65b09b 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -193,6 +193,7 @@ if (LINUX) # linking can be very memory-hungry, especially the final viewer link #set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory -Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../lib' -Wl,--exclude-libs,ALL") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-keep-memory -Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../lib' -Wl,--exclude-libs,ALL") endif (NOT USESYSTEMLIBS) set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d893082cfb..c8c13d291e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -73,7 +73,6 @@ set(llcommon_SOURCE_FILES llinitparam.cpp llinitdestroyclass.cpp llinstancetracker.cpp - llkeybind.cpp llleap.cpp llleaplistener.cpp llliveappconfig.cpp @@ -184,7 +183,6 @@ 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 937f1a5501..65a937570f 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -57,17 +57,6 @@ enum ETerrainBrushType E_LANDBRUSH_INVALID = 6 }; -enum EMouseClickType{ - CLICK_NONE = -1, - CLICK_LEFT = 0, - CLICK_MIDDLE, - CLICK_RIGHT, - CLICK_BUTTON4, - CLICK_BUTTON5, - CLICK_DOUBLELEFT, - CLICK_COUNT // 'size', CLICK_NONE does not counts -}; - // keys // Bit masks for various keyboard modifier keys. const MASK MASK_NONE = 0x0000; diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 447c0fb31f..34a65d6cd5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -36,6 +36,12 @@ #include "llpreprocessor.h" #include +// Supress some false positives of PVS Studio. +// They are misleading as there is opossibly a pointr taken behid the array and that pointer is passed down. But it's never dereferenced. +//-V:llassert_always:557 +//-V:lllog_site_args_:557 +// + const int LL_ERR_NOERR = 0; // Define one of these for different error levels in release... diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp deleted file mode 100644 index 38696c2258..0000000000 --- a/indra/llcommon/llkeybind.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/** - * @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), - mIgnoreMasks(false) -{ -} - -LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK 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) -{ - 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 -{ - 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; - } - return data; -} - -bool LLKeyData::isEmpty() const -{ - return mMouse == CLICK_NONE && mKey == KEY_NONE; -} - -void LLKeyData::reset() -{ - mMouse = CLICK_NONE; - mKey = KEY_NONE; - mMask = MASK_NONE; - mIgnoreMasks = false; -} - -LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) -{ - mMouse = rhs.mMouse; - mKey = rhs.mKey; - mMask = rhs.mMask; - mIgnoreMasks = rhs.mIgnoreMasks; - 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; - if (mIgnoreMasks != rhs.mIgnoreMasks) 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; - 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) == mMask) || 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) == mMask) || mask == mMask)) - { - return true; - } - return false; -} - -// LLKeyBind - -LLKeyBind::LLKeyBind(const LLSD &key_bind) -{ - if (key_bind.isArray()) - { - 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) -{ - 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::operator!=(const LLKeyBind& rhs) -{ - 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; -} - -bool LLKeyBind::isEmpty() const -{ - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) - { - if (!iter->isEmpty()) return false; - } - return true; -} - -LLSD LLKeyBind::asLLSD() const -{ - S32 last = mData.size() - 1; - while (mData[last].empty()) - { - last--; - } - - LLSD data; - for (S32 i = 0; i <= last; ++i) - { - // append even if empty to not affect visual representation - data.append(mData[i].asLLSD()); - } - return data; -} - -bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const -{ - if (mouse == CLICK_NONE && key == KEY_NONE) - { - // assume placeholder - return false; - } - - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) - { - if (iter->canHandle(mouse, key, mask)) - { - 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); -} - -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 -{ - 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)) - { - mData.push_back(LLKeyData(mouse, key, mask, ignore)); - return true; - } - return false; -} - -bool LLKeyBind::addKeyData(const LLKeyData& data) -{ - if (!hasKeyData(data)) - { - mData.push_back(data); - return true; - } - return false; -} - -void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index) -{ - 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->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; - } - } - } - if (mData.size() <= index) - { - mData.resize(index + 1); - } - mData[index] = data; -} - -void LLKeyBind::resetKeyData(S32 index) -{ - if (mData.size() > index) - { - mData[index].reset(); - } -} - -void LLKeyBind::trimEmpty() -{ - S32 last = mData.size() - 1; - while (last >= 0 && mData[last].empty()) - { - mData.erase(mData.begin() + last); - last--; - } -} - -U32 LLKeyBind::getDataCount() -{ - return mData.size(); -} - diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h deleted file mode 100644 index 7dc2aff4cb..0000000000 --- a/indra/llcommon/llkeybind.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @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(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; - 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); - - bool canHandle(const LLKeyData& data) const; - bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const; - - EMouseClickType mMouse; - KEY mKey; - MASK mMask; - // Either to expect exact match or to make sure mMask is inclused and ignore not expected masks - bool mIgnoreMasks; -}; - -// One function can bind to multiple Key options -class LLKeyBind -{ -public: - LLKeyBind() {} - LLKeyBind(const LLSD &key_bind); - - bool operator==(const LLKeyBind& rhs); - bool operator!=(const LLKeyBind& rhs); - bool isEmpty() const; - bool empty() const { return isEmpty(); }; - - 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; - - // 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); - 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: - typedef std::vector data_vector_t; - data_vector_t mData; -}; - - -#endif // LL_KEYBIND_H diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 517f68b14a..b6319c5532 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -40,7 +40,7 @@ namespace const LLUUID IMG_HALO("12149143-f599-91a7-77ac-b52a3c0f59cd"); } -namespace { +//namespace { LLQuaternion convert_azimuth_and_altitude_to_quat(F32 azimuth, F32 altitude) { F32 sinTheta = sin(azimuth); @@ -64,7 +64,7 @@ namespace { return quat; } -} +//} static LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment"); static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_SKYVALUES("Recalculate Sky"); diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index 4938273d5b..61feecc3ee 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -115,6 +115,9 @@ class LLVector3d friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b +// [RLVa:KB] - RlvBehaviourModifierCompMin/Max + friend bool operator<(const LLVector3 &a, const LLVector3 &b); // Return a < b +// [/RLVa:KB] friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b @@ -395,6 +398,17 @@ inline bool operator!=(const LLVector3d& a, const LLVector3d& b) ||(a.mdV[2] != b.mdV[2])); } +// [RLVa:KB] - RlvBehaviourModifierCompMin/Max +inline bool operator<(const LLVector3d& lhs, const LLVector3d& rhs) +{ + return (lhs.mdV[0] < rhs.mdV[0] + || (lhs.mdV[0] == rhs.mdV[0] + && (lhs.mdV[1] < rhs.mdV[1] + || ((lhs.mdV[1] == rhs.mdV[1]) + && lhs.mdV[2] < rhs.mdV[2])))); +} +// [/RLVa:KB] + inline const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b) { a.mdV[0] += b.mdV[0]; diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 9a54ccce54..0d4f0385ef 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -119,10 +119,6 @@ LLAvatarNameCache::LLAvatarNameCache() mUsePeopleAPI = true; -// [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c - mForceDisplayNames = false; -// [/RLVa:KB] - sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders()); sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); @@ -742,12 +738,12 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(cons // [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c bool LLAvatarNameCache::getForceDisplayNames() { - return mForceDisplayNames; + return mRlvForceDisplayNames; } void LLAvatarNameCache::setForceDisplayNames(bool force) { - mForceDisplayNames = force; + mRlvForceDisplayNames = force; if ( (!LLAvatarName::useDisplayNames()) && (force) ) { LLAvatarName::setUseDisplayNames(true); diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index c04bad870d..c8f1dc3fde 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -163,6 +163,11 @@ private: // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). bool mUsePeopleAPI; +// [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c + // RLVa override for display names + bool mRlvForceDisplayNames = false; +// [/RLVa:KB] + // Base lookup URL for name service. // On simulator, loaded from indra.xml // On viewer, usually a simulator capability (at People API team's request) @@ -191,10 +196,6 @@ private: // Time when unrefreshed cached names were checked last. F64 mLastExpireCheck; - -// [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c - bool mForceDisplayNames; -// [/RLVa:KB] }; // Parse a cache-control header to get the max-age delta-seconds. diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index b35105508e..14fd3e5522 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1148,6 +1148,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mDebugMessageLevel = message.getValue("message_level"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_DEBUG_MESSAGE); } + else if (message_name == "tooltip_text") + { + mHoverText = message.getValue("tooltip"); + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index f7ef234ad5..cf668c9ed8 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -266,9 +266,10 @@ void LLModel::normalizeVolumeFaces() scale.splat(1.f); scale.div(size); - LLVector4a inv_scale(1.f); - inv_scale.div(scale); - +// BUG-228952 - bad vertex normal scaling on mesh asset import + // LLVector4a inv_scale(1.f); + // inv_scale.div(scale); +// for (U32 i = 0; i < mVolumeFaces.size(); ++i) { LLVolumeFace& face = mVolumeFaces[i]; @@ -294,7 +295,10 @@ void LLModel::normalizeVolumeFaces() pos[j].mul(scale); if (norm && !norm[j].equals3(LLVector4a::getZero())) { - norm[j].mul(inv_scale); +// BUG-228952 - bad vertex normal scaling on mesh asset import + // norm[j].mul(inv_scale); + norm[j].mul(scale); +// norm[j].normalize3(); } } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b31fb2d6ef..ce3aab8c2b 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -698,6 +698,14 @@ void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVect // { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + + // FIRE-29679 trap empty calls that cause crashes when rezzing in OpenSim. + if(pos == nullptr || indicesp == nullptr ) + { + LL_WARNS() << "Called drawElements with null pos or null indices" << LL_ENDL; + return; + } + // // Crash fix due to invalid calls to drawElements by Drake Arconis if (num_vertices <= 0) diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index e727f1fc5b..7ff3fac205 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -223,12 +223,6 @@ LLSD LLMenuItemGL::getValue() const return getLabel(); } -//virtual -bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const -{ - return (mAcceleratorKey == key) && (mAcceleratorMask == mask); -} - //virtual BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { @@ -290,13 +284,13 @@ BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask) // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list -BOOL LLMenuItemGL::addToAcceleratorList(std::list *listp) +BOOL LLMenuItemGL::addToAcceleratorList(std::list *listp) { - LLMenuKeyboardBinding *accelerator = NULL; + LLKeyBinding *accelerator = NULL; if (mAcceleratorKey != KEY_NONE) { - std::list::iterator list_it; + std::list::iterator list_it; for (list_it = listp->begin(); list_it != listp->end(); ++list_it) { accelerator = *list_it; @@ -320,7 +314,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list *list } if (!accelerator) { - accelerator = new LLMenuKeyboardBinding; + accelerator = new LLKeyBinding; if (accelerator) { accelerator->mKey = mAcceleratorKey; @@ -1044,11 +1038,6 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } -bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const -{ - return getBranch() && getBranch()->hasAccelerator(key, mask); -} - BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) { return getBranch() && getBranch()->handleAcceleratorKey(key, mask); @@ -1056,7 +1045,7 @@ BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list -BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list *listp) +BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list *listp) { LLMenuGL* branch = getBranch(); if (!branch) @@ -3061,27 +3050,6 @@ void LLMenuGL::updateParent(LLView* parentp) } } -bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const -{ - if (key == KEY_NONE) - { - return false; - } - // Note: checking this way because mAccelerators seems to be broken - // mAccelerators probably needs to be cleaned up or fixed - // It was used for dupplicate accelerator avoidance. - item_list_t::const_iterator item_iter; - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) - { - LLMenuItemGL* itemp = *item_iter; - if (itemp->hasAccelerator(key, mask)) - { - return true; - } - } - return false; -} - BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) { // don't handle if not enabled diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 6d0c3659d7..e86aea1ebf 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -42,13 +42,6 @@ extern S32 MENU_BAR_HEIGHT; extern S32 MENU_BAR_WIDTH; -class LLMenuKeyboardBinding -{ -public: - KEY mKey; - MASK mMask; -}; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemGL // @@ -99,7 +92,6 @@ public: /*virtual*/ void setValue(const LLSD& value); /*virtual*/ LLSD getValue() const; - virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); } @@ -118,7 +110,7 @@ public: virtual void setBriefItem(BOOL brief); virtual BOOL isBriefItem() const; - virtual BOOL addToAcceleratorList(std::list *listp); + virtual BOOL addToAcceleratorList(std::list *listp); void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; } @@ -445,8 +437,7 @@ public: /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); - - virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; + virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const; @@ -642,11 +633,10 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); - virtual bool hasAccelerator(const KEY &key, const MASK &mask) const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); // check if we've used these accelerators already - virtual BOOL addToAcceleratorList(std::list *listp); + virtual BOOL addToAcceleratorList(std::list *listp); // called to rebuild the draw label virtual void buildDrawLabel( void ); @@ -816,7 +806,7 @@ private: void checkMenuTrigger(); - std::list mAccelerators; + std::list mAccelerators; BOOL mAltKeyTrigger; }; diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 13839da400..8000efad0e 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -50,10 +50,6 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_ { cell = new LLScrollListDate(cell_p); } - else if (cell_p.type() == "icontext") - { - cell = new LLScrollListIconText(cell_p); - } else // default is "text" { cell = new LLScrollListText(cell_p); @@ -172,7 +168,7 @@ U32 LLScrollListText::sCount = 0; LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) : LLScrollListCell(p), - mText(p.label.isProvided() ? p.label() : p.value().asString()), + mText(p.value().asString()), mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), @@ -196,7 +192,7 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) void LLScrollListText::highlightText(S32 offset, S32 num_chars) { mHighlightOffset = offset; - mHighlightCount = llmax(0, num_chars); + mHighlightCount = num_chars; } //virtual @@ -296,12 +292,11 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col if (mHighlightCount > 0) { - // Highlight text S32 left = 0; switch(mFontAlignment) { case LLFontGL::LEFT: - left = mFont->getWidth(mText.getString(), 1, mHighlightOffset); + left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); break; case LLFontGL::RIGHT: left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); @@ -324,7 +319,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col switch(mFontAlignment) { case LLFontGL::LEFT: - start_x = 1.f; + start_x = 0.f; break; case LLFontGL::RIGHT: start_x = (F32)getWidth(); @@ -440,139 +435,3 @@ const LLSD LLScrollListDate::getValue() const { return mDate; } - -// -// LLScrollListIconText -// -LLScrollListIconText::LLScrollListIconText(const LLScrollListCell::Params& p) - : LLScrollListText(p), - mIcon(p.value().isUUID() ? LLUI::getUIImageByID(p.value().asUUID()) : LLUI::getUIImage(p.value().asString())), - mPad(4) -{ - mTextWidth = getWidth() - mPad /*padding*/ - mFont->getLineHeight(); -} - -LLScrollListIconText::~LLScrollListIconText() -{ -} - -const LLSD LLScrollListIconText::getValue() const -{ - if (mIcon.isNull()) - { - return LLStringUtil::null; - } - return mIcon->getName(); -} - -void LLScrollListIconText::setValue(const LLSD& value) -{ - if (value.isUUID()) - { - // don't use default image specified by LLUUID::null, use no image in that case - LLUUID image_id = value.asUUID(); - mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL); - } - else - { - std::string value_string = value.asString(); - if (LLUUID::validate(value_string)) - { - setValue(LLUUID(value_string)); - } - else if (!value_string.empty()) - { - mIcon = LLUI::getUIImage(value.asString()); - } - else - { - mIcon = NULL; - } - } -} - -void LLScrollListIconText::setWidth(S32 width) -{ - LLScrollListCell::setWidth(width); - // Assume that iamge height and width is identical to font height and width - mTextWidth = width - mPad /*padding*/ - mFont->getLineHeight(); -} - - -void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - LLColor4 display_color; - if (mUseColor) - { - display_color = mColor; - } - else - { - display_color = color; - } - - S32 icon_height = mFont->getLineHeight(); - S32 icon_space = mIcon ? (icon_height + mPad) : 0; - - if (mHighlightCount > 0) - { - S32 left = 0; - switch (mFontAlignment) - { - case LLFontGL::LEFT: - left = mFont->getWidth(mText.getString(), icon_space + 1, mHighlightOffset); - break; - case LLFontGL::RIGHT: - left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX) - icon_space; - break; - case LLFontGL::HCENTER: - left = (getWidth() - mFont->getWidth(mText.getString()) - icon_space) / 2; - break; - } - LLRect highlight_rect(left - 2, - mFont->getLineHeight() + 1, - left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, - 1); - mRoundedRectImage->draw(highlight_rect, highlight_color); - } - - // Try to draw the entire string - F32 right_x; - U32 string_chars = mText.length(); - F32 start_text_x = 0.f; - S32 start_icon_x = 0; - switch (mFontAlignment) - { - case LLFontGL::LEFT: - start_text_x = icon_space + 1; - start_icon_x = 1; - break; - case LLFontGL::RIGHT: - start_text_x = (F32)getWidth(); - start_icon_x = getWidth() - mFont->getWidth(mText.getString()) - icon_space; - break; - case LLFontGL::HCENTER: - F32 center = (F32)getWidth()* 0.5f; - start_text_x = center + ((F32)icon_space * 0.5f); - start_icon_x = center - (((F32)icon_space + mFont->getWidth(mText.getString())) * 0.5f); - break; - } - mFont->render(mText.getWString(), 0, - start_text_x, 0.f, - display_color, - mFontAlignment, - LLFontGL::BOTTOM, - 0, - LLFontGL::NO_SHADOW, - string_chars, - getTextWidth(), - &right_x, - TRUE); - - if (mIcon) - { - mIcon->draw(start_icon_x, 0, icon_height, icon_height, mColor); - } -} - - diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 19576fb247..d625ebddcc 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -59,8 +59,7 @@ public: visible; Optional userdata; - Optional value; // state of checkbox, icon id/name, date - Optional label; // description or text + Optional value; Optional tool_tip; Optional font; @@ -76,7 +75,6 @@ public: enabled("enabled", true), visible("visible", true), value("value"), - label("label"), tool_tip("tool_tip", ""), font("font", LLFontGL::getFontSansSerifSmall()), font_color("font_color", LLColor4::black), @@ -154,12 +152,11 @@ public: void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style); -protected: +private: LLUIString mText; S32 mTextWidth; const LLFontGL* mFont; LLColor4 mColor; - LLColor4 mHighlightColor; U8 mUseColor; LLFontGL::HAlign mFontAlignment; BOOL mVisible; @@ -172,7 +169,7 @@ protected: }; /* - * Cell displaying an image. AT the moment, this is specifically UI image + * Cell displaying an image. */ class LLScrollListIcon : public LLScrollListCell { @@ -226,26 +223,4 @@ private: LLDate mDate; }; -/* -* Cell displaying icon and text. -*/ - -class LLScrollListIconText : public LLScrollListText -{ -public: - LLScrollListIconText(const LLScrollListCell::Params& p); - /*virtual*/ ~LLScrollListIconText(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; - /*virtual*/ const LLSD getValue() const; - /*virtual*/ void setValue(const LLSD& value); - - - S32 getIconWidth() const; - /*virtual*/ void setWidth(S32 width);/* { LLScrollListCell::setWidth(width); mTextWidth = width - ; }*/ - -private: - LLPointer mIcon; - S32 mPad; -}; - #endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3f85255885..3d7afdb1a7 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -117,13 +117,6 @@ struct SortScrollListItem // LLScrollListCtrl //--------------------------------------------------------------------------- -void LLScrollListCtrl::SelectionTypeNames::declareValues() -{ - declare("row", LLScrollListCtrl::ROW); - declare("cell", LLScrollListCtrl::CELL); - declare("header", LLScrollListCtrl::HEADER); -} - LLScrollListCtrl::Contents::Contents() : columns("column"), rows("row") @@ -137,10 +130,8 @@ LLScrollListCtrl::Params::Params() has_border("draw_border"), draw_heading("draw_heading"), search_column("search_column", 0), - selection_type("selection_type", ROW), sort_column("sort_column", -1), sort_ascending("sort_ascending", true), - can_sort("can_sort", true), persist_sort_order("persist_sort_order", false), // Persists sort order of scroll lists primary_sort_only("primary_sort_only", false), // Option to only sort by one column mouse_wheel_opaque("mouse_wheel_opaque", false), @@ -177,10 +168,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mCommitOnKeyboardMovement(p.commit_on_keyboard_movement), mCommitOnSelectionChange(false), mSelectionChanged(false), - mSelectionType(p.selection_type), mNeedsScroll(false), mCanSelect(true), - mCanSort(p.can_sort), mColumnsDirty(false), mMaxItemCount(INT_MAX), mBorderThickness( 2 ), @@ -920,15 +909,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { if (!itemp->getSelected()) { - switch (mSelectionType) - { - case CELL: - selectItem(itemp, 0); - break; - case HEADER: - case ROW: - selectItem(itemp, -1); - } + selectItem(itemp); } success = TRUE; mOriginalSelection = 0; @@ -995,8 +976,7 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) { if( itemp->getEnabled() ) { - // TODO: support range selection for cells - selectItem(itemp, -1, FALSE); + selectItem(itemp, FALSE); success = TRUE; } } @@ -1122,14 +1102,10 @@ void LLScrollListCtrl::clearHighlightedItems() void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index) { - if (mHighlightedItem != target_index) - { - if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size()) - { - mItemList[mHighlightedItem]->setHoverCell(-1); - } - mHighlightedItem = target_index; - } + if (mHighlightedItem != target_index) + { + mHighlightedItem = target_index; + } } S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) @@ -1144,8 +1120,7 @@ S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) { if (item->getEnabled() && (item->getUUID() == (*iditr))) { - // TODO: support multiple selection for cells - selectItem(item, -1, FALSE); + selectItem(item,FALSE); ++count; break; } @@ -1224,7 +1199,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) { if (prev_item) { - selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection); + selectItem(prev_item, !extend_selection); } else { @@ -1268,7 +1243,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) { if (next_item) { - selectItem(next_item, cur_item->getSelectedCell(), !extend_selection); + selectItem(next_item, !extend_selection); } else { @@ -1347,7 +1322,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen bool found = NULL != item; if(found) { - selectItem(item, -1); + selectItem(item); } if (mCommitOnSelectionChange) @@ -1422,7 +1397,7 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; if (select) { - selectItem(item, -1); + selectItem(item); found = TRUE; break; } @@ -1473,7 +1448,7 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre // find offset of matching text (might have leading whitespace) S32 offset = item_label.find(target_trimmed); cellp->highlightText(offset, target_trimmed.size()); - selectItem(item, -1); + selectItem(item); found = TRUE; break; } @@ -1552,7 +1527,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected) { if (selected) { - selectItem(item, -1); + selectItem(item); } else { @@ -1634,7 +1609,7 @@ void LLScrollListCtrl::drawItems() S32 max_columns = 0; - LLColor4 highlight_color = LLColor4::white; // ex: text inside cells + LLColor4 highlight_color = LLColor4::white; static LLUICachedControl type_ahead_timeout ("TypeAheadTimeout", 0); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout(), 0.4f, 0.f); @@ -1686,8 +1661,7 @@ void LLScrollListCtrl::drawItems() max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; - LLColor4 hover_color(LLColor4::transparent); - LLColor4 select_color(LLColor4::transparent); + LLColor4 bg_color(LLColor4::transparent); if( mScrollLines <= line && line < mScrollLines + num_page_lines ) { @@ -1696,45 +1670,45 @@ void LLScrollListCtrl::drawItems() { if(item->getHighlighted()) // if it's highlighted, average the colors { - select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f); + bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f); } else // otherwise just select-highlight it { - select_color = mBgSelectedColor.get(); + bg_color = mBgSelectedColor.get(); } fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get()); } - if (mHighlightedItem == line && mCanSelect) + else if (mHighlightedItem == line && mCanSelect) { if(item->getHighlighted()) // if it's highlighted, average the colors { - hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f); + bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f); } else // otherwise just hover-highlight it { - hover_color = mHoveredColor.get(); + bg_color = mHoveredColor.get(); } } else if (item->getHighlighted()) { - hover_color = mHighlightedColor.get(); + bg_color = mHighlightedColor.get(); } else { // Why no stripes in single columns? This should be decided by the skin. -Zi if (mDrawStripes && (line % 2 == 0)) // && (max_columns > 1)) { - hover_color = mBgStripeColor.get(); + bg_color = mBgStripeColor.get(); } } if (!item->getEnabled()) { - hover_color = mBgReadOnlyColor.get(); + bg_color = mBgReadOnlyColor.get(); } - item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding); + item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding); cur_y -= mLineHeight; } @@ -1910,7 +1884,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if (mLastSelected == NULL) { - selectItem(hit_item, getColumnIndexFromOffset(x)); + selectItem(hit_item); } else { @@ -1940,7 +1914,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) // Fix for FS-specific people list (radar) if (item == hit_item || item == lastSelected) { - selectItem(item, getColumnIndexFromOffset(x), FALSE); + selectItem(item, FALSE); selecting = !selecting; if (hit_item == lastSelected) { @@ -1950,7 +1924,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) } if (selecting) { - selectItem(item, getColumnIndexFromOffset(x), FALSE); + selectItem(item, FALSE); } } } @@ -1965,7 +1939,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable)) { - selectItem(hit_item, getColumnIndexFromOffset(x), FALSE); + selectItem(hit_item, FALSE); } else { @@ -1979,12 +1953,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) else { deselectAllItems(TRUE); - selectItem(hit_item, getColumnIndexFromOffset(x)); + selectItem(hit_item); } } else { - selectItem(hit_item, getColumnIndexFromOffset(x)); + selectItem(hit_item); } selection_changed = mSelectionChanged; @@ -2391,29 +2365,8 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) { LLScrollListItem* item = hitItem(x, y); if (item) - { - mouseOverHighlightNthItem(getItemIndex(item)); - switch (mSelectionType) - { - case CELL: - item->setHoverCell(getColumnIndexFromOffset(x)); - break; - case HEADER: - { - S32 cell = getColumnIndexFromOffset(x); - if (cell > 0) - { - item->setHoverCell(cell); - } - else - { - item->setHoverCell(-1); - } - break; - } - case ROW: - break; - } + { + mouseOverHighlightNthItem(getItemIndex(item)); } else { @@ -2461,52 +2414,6 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) handled = TRUE; } break; - case KEY_LEFT: - if (mAllowKeyboardMovement || hasFocus()) - { - // TODO: support multi-select - LLScrollListItem *item = getFirstSelected(); - S32 cell = item->getSelectedCell(); - switch (mSelectionType) - { - case CELL: - if (cell < mColumns.size()) cell++; - break; - case HEADER: - if (cell == -1) cell = 1; - else if (cell > 1 && cell < mColumns.size()) cell++; // skip header - break; - case ROW: - cell = -1; - break; - } - item->setSelectedCell(cell); - handled = TRUE; - } - break; - case KEY_RIGHT: - if (mAllowKeyboardMovement || hasFocus()) - { - // TODO: support multi-select - LLScrollListItem *item = getFirstSelected(); - S32 cell = item->getSelectedCell(); - switch (mSelectionType) - { - case CELL: - if (cell >= 0) cell--; - break; - case HEADER: - if (cell > 1) cell--; - else if (cell == 1) cell = -1; // skip header - break; - case ROW: - cell = -1; - break; - } - item->setSelectedCell(cell); - handled = TRUE; - } - break; case KEY_PAGE_UP: if (mAllowKeyboardMovement || hasFocus()) { @@ -2686,7 +2593,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { - selectItem(item, -1); + selectItem(item); mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2738,7 +2645,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const return TRUE; } -void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item) +void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item) { if (!itemp) return; @@ -2757,18 +2664,6 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select deselectAllItems(TRUE); } itemp->setSelected(TRUE); - switch (mSelectionType) - { - case CELL: - itemp->setSelectedCell(cell); - break; - case HEADER: - itemp->setSelectedCell(cell <= 0 ? -1 : cell); - break; - case ROW: - itemp->setSelectedCell(-1); - break; - } mLastSelected = itemp; mSelectionChanged = true; } @@ -3036,7 +2931,7 @@ void LLScrollListCtrl::selectAll() LLScrollListItem *itemp = *iter; if( itemp->getEnabled() ) { - selectItem(itemp, -1, FALSE); + selectItem(itemp, FALSE); } } @@ -3213,8 +3108,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata) LLScrollListCtrl *parent = info->mParentCtrl; if (!parent) return; - if (!parent->mCanSort) return; - S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; @@ -3579,7 +3472,7 @@ void LLScrollListCtrl::setFilterString(const std::string& str) { if (!isFiltered(*iter)) { - selectItem(*iter, -1); + selectItem(*iter); break; } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index ad595cbaa6..40eaa4e9d4 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -54,18 +54,6 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface { public: - typedef enum e_selection_type - { - ROW, // default - CELL, // does not support multi-selection - HEADER, // when pointing to cells in column 0 will highlight whole row, otherwise cell, no multi-select - } ESelectionType; - - struct SelectionTypeNames : public LLInitParam::TypeValuesHelper - { - static void declareValues(); - }; - struct Contents : public LLInitParam::Block { Multiple columns; @@ -111,8 +99,6 @@ public: commit_on_keyboard_movement, mouse_wheel_opaque; - Optional selection_type; - // display flags Optional has_border, draw_heading, @@ -129,8 +115,7 @@ public: // sort and search behavior Optional search_column, sort_column; - Optional sort_ascending, - can_sort; // whether user is allowed to sort + Optional sort_ascending; Optional persist_sort_order; // Persists sort order of scroll lists Optional primary_sort_only; // Option to only sort by one column @@ -474,7 +459,7 @@ private: void updateLineHeightInsert(LLScrollListItem* item); void reportInvalidInput(); BOOL isRepeatedChars(const LLWString& string) const; - void selectItem(LLScrollListItem* itemp, S32 cell, BOOL single_select = TRUE); + void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE); void deselectItem(LLScrollListItem* itemp); void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); @@ -502,11 +487,9 @@ private: bool mCommitOnKeyboardMovement; bool mCommitOnSelectionChange; bool mSelectionChanged; - ESelectionType mSelectionType; bool mNeedsScroll; bool mMouseWheelOpaque; bool mCanSelect; - bool mCanSort; // Whether user is allowed to sort bool mDisplayColumnHeaders; bool mColumnsDirty; bool mColumnWidthsDirty; diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index 51c615dd00..df22c88afb 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -40,8 +40,6 @@ LLScrollListItem::LLScrollListItem( const Params& p ) : mSelected(FALSE), mHighlighted(FALSE), - mHoverIndex(-1), - mSelectedIndex(-1), mEnabled(p.enabled), mUserdata(p.userdata), mItemValue(p.value) @@ -55,28 +53,6 @@ LLScrollListItem::~LLScrollListItem() mColumns.clear(); } -void LLScrollListItem::setSelected(BOOL b) -{ - mSelected = b; - mSelectedIndex = -1; -} - -void LLScrollListItem::setHighlighted(BOOL b) -{ - mHighlighted = b; - mHoverIndex = -1; -} - -void LLScrollListItem::setHoverCell(S32 cell) -{ - mHoverIndex = cell; -} - -void LLScrollListItem::setSelectedCell(S32 cell) -{ - mSelectedIndex = cell; -} - void LLScrollListItem::addColumn(const LLScrollListCell::Params& p) { mColumns.push_back(LLScrollListCell::create(p)); @@ -144,21 +120,12 @@ std::string LLScrollListItem::getContentsCSV() const } -void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& hover_color, const LLColor4& select_color, const LLColor4& highlight_color, S32 column_padding) +void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) { // draw background rect gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLRect bg_rect = rect; - if (mSelectedIndex < 0 && getSelected()) - { - // Whole item is highlighted/selected - gl_rect_2d(bg_rect, select_color); - } - else if (mHoverIndex < 0) - { - // Whole item is highlighted/selected - gl_rect_2d(bg_rect, hover_color); - } + gl_rect_2d( bg_rect, bg_color ); S32 cur_x = rect.mLeft; S32 num_cols = getNumColumns(); @@ -174,25 +141,6 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const { LLUI::translate((F32) cur_x, (F32) rect.mBottom); - if (mSelectedIndex == cur_col) - { - // select specific cell - LLRect highlight_rect(0, - cell->getHeight(), - cell->getWidth(), - 0); - gl_rect_2d(highlight_rect, select_color); - } - else if (mHoverIndex == cur_col) - { - // highlight specific cell - LLRect highlight_rect(0, - cell->getHeight(), - cell->getWidth() , - 0); - gl_rect_2d(highlight_rect, hover_color); - } - cell->draw( fg_color, highlight_color ); } LLUI::popMatrix(); diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index d2c3dd7721..13655b5873 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -77,21 +77,15 @@ public: virtual ~LLScrollListItem(); - void setSelected( BOOL b ); + void setSelected( BOOL b ) { mSelected = b; } BOOL getSelected() const { return mSelected; } void setEnabled( BOOL b ) { mEnabled = b; } BOOL getEnabled() const { return mEnabled; } - void setHighlighted( BOOL b ); + void setHighlighted( BOOL b ) { mHighlighted = b; } BOOL getHighlighted() const { return mHighlighted; } - void setSelectedCell( S32 cell ); - S32 getSelectedCell() const { return mSelectedIndex; } - - void setHoverCell( S32 cell ); - S32 getHoverCell() const { return mHoverIndex; } - void setUserdata( void* userdata ) { mUserdata = userdata; } void* getUserdata() const { return mUserdata; } @@ -113,21 +107,14 @@ public: std::string getContentsCSV() const; - virtual void draw(const LLRect& rect, - const LLColor4& fg_color, - const LLColor4& hover_color, // highlight/hover selection of whole item or cell - const LLColor4& select_color, // highlight/hover selection of whole item or cell - const LLColor4& highlight_color, // highlights contents of cells (ex: text) - S32 column_padding); + virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); protected: LLScrollListItem( const Params& ); private: BOOL mSelected; - BOOL mHighlighted; - S32 mHoverIndex; - S32 mSelectedIndex; + BOOL mHighlighted; BOOL mEnabled; void* mUserdata; LLSD mItemValue; diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 5404ac50e5..f6f6c3931c 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -327,7 +327,7 @@ BOOL LLKeyboard::keyFromString(const std::string& str, KEY *key) // static -std::string LLKeyboard::stringFromKey(KEY key, bool translate) +std::string LLKeyboard::stringFromKey(KEY key) { std::string res = get_if_there(sKeysToNames, key, std::string()); if (res.empty()) @@ -338,60 +338,16 @@ std::string LLKeyboard::stringFromKey(KEY key, bool translate) res = std::string(buffer); } - if (translate) + LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; + if (trans != NULL) { - LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; - if (trans != NULL) - { - res = trans(res.c_str()); - } + res = trans(res.c_str()); } return res; } -//static -std::string LLKeyboard::stringFromAccelerator(MASK accel_mask) -{ - std::string res; - LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; - - if (trans == NULL) - { - LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL; - return res; - } - - // Append any masks -#ifdef LL_DARWIN - // Standard Mac names for modifier keys in menu equivalents - // We could use the symbol characters, but they only exist in certain fonts. - if (accel_mask & MASK_CONTROL) - { - if (accel_mask & MASK_MAC_CONTROL) - { - res.append(trans("accel-mac-control")); - } - else - { - res.append(trans("accel-mac-command")); // Symbol would be "\xE2\x8C\x98" - } - } - if (accel_mask & MASK_ALT) - res.append(trans("accel-mac-option")); // Symbol would be "\xE2\x8C\xA5" - if (accel_mask & MASK_SHIFT) - res.append(trans("accel-mac-shift")); // Symbol would be "\xE2\x8C\xA7" -#else - if (accel_mask & MASK_CONTROL) - res.append(trans("accel-win-control")); - if (accel_mask & MASK_ALT) - res.append(trans("accel-win-alt")); - if (accel_mask & MASK_SHIFT) - res.append(trans("accel-win-shift")); -#endif - return res; -} //static std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key ) { @@ -403,7 +359,41 @@ std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key ) return res; } - res.append(stringFromAccelerator(accel_mask)); + LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; + + if( trans == NULL ) + { + LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL; + return res; + } + + // Append any masks +#ifdef LL_DARWIN + // Standard Mac names for modifier keys in menu equivalents + // We could use the symbol characters, but they only exist in certain fonts. + if( accel_mask & MASK_CONTROL ) + { + if ( accel_mask & MASK_MAC_CONTROL ) + { + res.append( trans("accel-mac-control") ); + } + else + { + res.append( trans("accel-mac-command") ); // Symbol would be "\xE2\x8C\x98" + } + } + if( accel_mask & MASK_ALT ) + res.append( trans("accel-mac-option") ); // Symbol would be "\xE2\x8C\xA5" + if( accel_mask & MASK_SHIFT ) + res.append( trans("accel-mac-shift") ); // Symbol would be "\xE2\x8C\xA7" +#else + if( accel_mask & MASK_CONTROL ) + res.append( trans("accel-win-control") ); + if( accel_mask & MASK_ALT ) + res.append( trans("accel-win-alt") ); + if( accel_mask & MASK_SHIFT ) + res.append( trans("accel-win-shift") ); +#endif std::string key_string = LLKeyboard::stringFromKey(key); if ((accel_mask & MASK_NORMALKEYS) && (key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+')) diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 36bd8bcbed..6f2dc87317 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -38,10 +38,10 @@ enum EKeystate { KEYSTATE_DOWN, KEYSTATE_LEVEL, - KEYSTATE_UP + KEYSTATE_UP }; -typedef boost::function LLKeyFunc; +typedef boost::function LLKeyFunc; typedef std::string (LLKeyStringTranslatorFunc)(const char *label); enum EKeyboardInsertMode @@ -50,6 +50,15 @@ enum EKeyboardInsertMode LL_KIM_OVERWRITE }; +class LLKeyBinding +{ +public: + KEY mKey; + MASK mMask; +// const char *mName; // unused + LLKeyFunc mFunction; +}; + class LLWindowCallbacks; class LLKeyboard @@ -94,8 +103,7 @@ public: static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure static BOOL keyFromString(const std::string& str, KEY *key); // False on failure - static std::string stringFromKey(KEY key, bool translate = true); - static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"... + static std::string stringFromKey(KEY key); static std::string stringFromAccelerator( MASK accel_mask, KEY key ); void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp index e41ebd42f3..d5fa65fe4b 100644 --- a/indra/llwindow/llmousehandler.cpp +++ b/indra/llwindow/llmousehandler.cpp @@ -27,7 +27,7 @@ #include "llmousehandler.h" //virtual -BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) +BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down) { BOOL handled = FALSE; if (down) diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h index d221dd117c..1dcd0348d8 100644 --- a/indra/llwindow/llmousehandler.h +++ b/indra/llwindow/llmousehandler.h @@ -29,7 +29,6 @@ #include "linden_common.h" #include "llrect.h" -#include "indra_constants.h" // Mostly-abstract interface. // Intended for use via multiple inheritance. @@ -47,7 +46,16 @@ public: SHOW_ALWAYS, } EShowToolTip; - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); + typedef enum { + CLICK_LEFT, + CLICK_MIDDLE, + CLICK_RIGHT, + CLICK_BUTTON4, + CLICK_BUTTON5, + CLICK_DOUBLELEFT + } EClickType; + + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b43b2aca06..067afae489 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -717,6 +717,7 @@ LLWindowWin32::~LLWindowWin32() void LLWindowWin32::show() { + LL_DEBUGS("Window") << "Setting window to show" << LL_ENDL; ShowWindow(mWindowHandle, SW_SHOW); SetForegroundWindow(mWindowHandle); SetFocus(mWindowHandle); @@ -1129,6 +1130,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO mPostQuit = FALSE; // create window + LL_DEBUGS("Window") << "Creating window with X: " << window_rect.left + << " Y: " << window_rect.top + << " Width: " << (window_rect.right - window_rect.left) + << " Height: " << (window_rect.bottom - window_rect.top) + << " Fullscreen: " << mFullscreen + << LL_ENDL; DestroyWindow(mWindowHandle); mWindowHandle = CreateWindowEx(dw_ex_style, mWindowClassName, diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ee8f72daf1..36875876c9 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -63,6 +63,7 @@ private: void onConsoleMessageCallback(std::string message, std::string source, int line); void onStatusMessageCallback(std::string value); void onTitleChangeCallback(std::string title); + void onTooltipCallback(std::string text); void onLoadStartCallback(); void onRequestExitCallback(); void onLoadEndCallback(int httpStatusCode); @@ -72,6 +73,7 @@ private: bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); void onCursorChangedCallback(dullahan::ECursorType type); const std::vector onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default); + bool onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text); void postDebugMessage(const std::string& msg); void authResponse(LLPluginMessage &message); @@ -88,6 +90,8 @@ private: bool mPluginsEnabled; bool mJavascriptEnabled; bool mDisableGPU; + bool mDisableNetworkService; + bool mUseMockKeyChain; std::string mUserAgentSubtring; std::string mAuthUsername; std::string mAuthPassword; @@ -96,7 +100,6 @@ private: bool mCanCopy; bool mCanPaste; std::string mCachePath; - std::string mCookiePath; std::string mCefLogFile; bool mCefLogVerbose; std::vector mPickedFiles; @@ -120,6 +123,8 @@ MediaPluginBase(host_send_func, host_user_data) mPluginsEnabled = false; mJavascriptEnabled = true; mDisableGPU = false; + mDisableNetworkService = true; + mUseMockKeyChain = true; mUserAgentSubtring = ""; mAuthUsername = ""; mAuthPassword = ""; @@ -128,7 +133,6 @@ MediaPluginBase(host_send_func, host_user_data) mCanCopy = false; mCanPaste = false; mCachePath = ""; - mCookiePath = ""; mCefLogFile = ""; mCefLogVerbose = false; mPickedFiles.clear(); @@ -209,6 +213,12 @@ void MediaPluginCEF::onTitleChangeCallback(std::string title) sendMessage(message); } +void MediaPluginCEF::onTooltipCallback(std::string text) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "tooltip_text"); + message.setValue("tooltip", text); + sendMessage(message); +} //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::onLoadStartCallback() @@ -356,6 +366,14 @@ const std::vector MediaPluginCEF::onFileDialog(dullahan::EFileDialo return std::vector(); } +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginCEF::onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text) +{ + // return true indicates we suppress the JavaScript alert UI entirely + return true; +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type) @@ -432,6 +450,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mCEFLib->update(); + mVolumeCatcher.pump(); + // this seems bad but unless the state changes (it won't until we figure out // how to get CEF to tell us if copy/cut/paste is available) then this function // will return immediately @@ -492,6 +512,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1)); mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1)); + mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1)); mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this)); mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1)); mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2)); @@ -501,17 +522,19 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1)); mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this)); - + mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + dullahan::dullahan_settings settings; settings.accept_language_list = mHostLanguage; settings.background_color = 0xffffffff; settings.cache_enabled = true; settings.cache_path = mCachePath; -#if (DULLAHAN_VERSION_MAJOR*100+DULLAHAN_VERSION_MINOR) < 106 - settings.cookie_store_path = mCookiePath; -#endif settings.cookies_enabled = mCookiesEnabled; settings.disable_gpu = mDisableGPU; +#if LL_DARWIN + settings.disable_network_service = mDisableNetworkService; + settings.use_mock_keychain = mUseMockKeyChain; +#endif settings.flash_enabled = mPluginsEnabled; settings.flip_mouse_y = false; settings.flip_pixels_y = true; @@ -570,7 +593,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) std::string user_data_path_cookies = message_in.getValue("cookies_path"); mCachePath = user_data_path_cache + "cef_cache"; - mCookiePath = user_data_path_cookies + "cef_cookies"; mCefLogFile = message_in.getValue("cef_log_file"); mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log"); } @@ -670,10 +692,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (message_name == "scroll_event") { // Mouse coordinates for cef to be able to scroll 'containers' -#if (DULLAHAN_VERSION_MAJOR*100+DULLAHAN_VERSION_MINOR) >= 106 S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); -#endif + // Wheel's clicks S32 delta_x = message_in.getValueS32("clicks_x"); S32 delta_y = message_in.getValueS32("clicks_y"); @@ -681,11 +702,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) delta_x *= -scaling_factor; delta_y *= -scaling_factor; -#if (DULLAHAN_VERSION_MAJOR*100+DULLAHAN_VERSION_MINOR) >= 106 mCEFLib->mouseWheel(x, y, delta_x, delta_y); -#else - mCEFLib->mouseWheel(delta_x, delta_y); -#endif } else if (message_name == "text_event") { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b245185421..f64ed58663 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -488,7 +488,6 @@ set(viewer_SOURCE_FILES llinventoryobserver.cpp llinventorypanel.cpp lljoystickbutton.cpp - llkeyconflict.cpp lllandmarkactions.cpp lllandmarklist.cpp lllegacyatmospherics.cpp @@ -669,7 +668,6 @@ set(viewer_SOURCE_FILES llsecapi.cpp llsechandler_basic.cpp llselectmgr.cpp - llsetkeybinddialog.cpp llsettingspicker.cpp llsettingsvo.cpp llshareavatarhandler.cpp @@ -776,7 +774,7 @@ set(viewer_SOURCE_FILES llviewerjointattachment.cpp llviewerjointmesh.cpp llviewerjoystick.cpp - llviewerinput.cpp + llviewerkeyboard.cpp llviewerlayer.cpp llviewermedia.cpp llviewermedia_streamingaudio.cpp @@ -852,6 +850,7 @@ set(viewer_SOURCE_FILES qtoolalign.cpp quickprefs.cpp rlvactions.cpp + rlvenvironment.cpp rlvhandler.cpp rlvhelper.cpp rlvcommon.cpp @@ -1256,7 +1255,6 @@ set(viewer_HEADER_FILES llinventoryobserver.h llinventorypanel.h lljoystickbutton.h - llkeyconflict.h lllandmarkactions.h lllandmarklist.h lllightconstants.h @@ -1427,7 +1425,6 @@ set(viewer_HEADER_FILES llsecapi.h llsechandler_basic.h llselectmgr.h - llsetkeybinddialog.h llsettingspicker.h llsettingsvo.h llsidepanelappearance.h @@ -1536,7 +1533,7 @@ set(viewer_HEADER_FILES llviewerjointattachment.h llviewerjointmesh.h llviewerjoystick.h - llviewerinput.h + llviewerkeyboard.h llviewerlayer.h llviewermedia.h llviewermediafocus.h @@ -1611,6 +1608,7 @@ set(viewer_HEADER_FILES pieslice.h pipeline.h rlvactions.h + rlvenvironment.h rlvdefines.h rlvhandler.h rlvhelper.h @@ -2035,7 +2033,8 @@ set(viewer_APPSETTINGS_FILES app_settings/growl_notifications.xml app_settings/high_graphics.xml app_settings/ignorable_dialogs.xml - app_settings/key_bindings.xml + app_settings/keys.xml + app_settings/keys_azerty.xml app_settings/keywords.ini app_settings/keywords_lsl_default.xml app_settings/logcontrol.xml diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 49df80bfeb..7d765dabde 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.4 +6.4.5 diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index 37123fc828..424af81590 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -1910,11 +1910,6 @@ BOOL AOEngine::importNotecard(const LLInventoryItem* item) if (item->getAssetUUID().notNull()) { mImportSet = new AOSet(item->getParentUUID()); - if (!mImportSet) - { - LLNotificationsUtil::add("AOImportCreateSetFailed", LLSD()); - return FALSE; - } mImportSet->setName(item->getName()); LLUUID* newUUID = new LLUUID(item->getAssetUUID()); diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index b28a6f4679..ec4458ee66 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -631,6 +631,8 @@ tooltip_ref="Command_Environments_Tooltip" execute_function="Floater.ToggleOrBringToFront" execute_parameters="my_environments" + is_enabled_function="RLV.EnableIfNot" + is_enabled_parameters="setenv" is_running_function="Floater.IsOpen" is_running_parameters="my_environments" /> diff --git a/indra/newview/app_settings/grids.xml b/indra/newview/app_settings/grids.xml index 467f24c86b..187d532449 100644 --- a/indra/newview/app_settings/grids.xml +++ b/indra/newview/app_settings/grids.xml @@ -1,77 +1,137 @@ - cc.opensimulator.org:8002 - - LastModified - 2019-12-09T10:00:00.00Z - gatekeeper - cc.opensimulator.org:8002 - gridname - OpenSim Community Conference - gridnick - opensimcc - helperuri - http://cc.opensimulator.org/helper/ - login_identifier_types - - agent - account - - loginpage - http://cc.opensimulator.org:8005/wifi/welcome.html - loginuri - - http://cc.opensimulator.org:8002/ - - name - cc.opensimulator.org:8002 - password - http://cc.opensimulator.org:8005/wifi/forgotpassword - platform - OpenSim - register - http://cc.opensimulator.org:8005/wifi/user/account - slurl_base - hop://cc.opensimulator.org:8002/ - - grid.virtualife.cloud:8002 + alternatemetaverse.com:8002 LastModified - 2019-12-04T10:50:32.55Z - about - http://www.virtualife.cloud - gatekeeper - grid.virtualife.cloud:8002 + 2020-06-02T11:41:00.95Z gridname - virtualife world + Alternate Metaverse gridnick - Virtualife world + AMV login_identifier_types agent account loginpage - http://www.virtualife.cloud/index.php?option=com_opensim + https://alternatemetaverse.com/splash loginuri - http://grid.virtualife.cloud:8002/ + http://alternatemetaverse.com:8002 name - grid.virtualife.cloud:8002 + alternatemetaverse.com:8002 + platform + OpenSim + slurl_base + hop://alternatemetaverse.com:8002/ + + astralia.eu:8002 + + LastModified + 2020-06-02T11:43:19.89Z + gatekeeper + astralia.eu:8002 + gridname + astralia + gridnick + astralia + helperuri + http://astralia.eu//currency/helper/landtool.php + login_identifier_types + + agent + account + + loginpage + http://astralia.eu + loginuri + + http://astralia.eu:8002/ + + name + astralia.eu:8002 + platform + OpenSim + slurl_base + hop://astralia.eu:8002/ + + cc.opensimulator.org:8002 + + LastModified + 2019-12-09T10:00:00Z + gatekeeper + cc.opensimulator.org:8002 + gridname + OpenSim Community Conference + gridnick + opensimcc + helperuri + http://cc.opensimulator.org/helper/ + login_identifier_types + + agent + account + + loginpage + http://cc.opensimulator.org:8005/wifi/welcome.html + loginuri + + http://cc.opensimulator.org:8002/ + + name + cc.opensimulator.org:8002 password - http://grid.virtualife.cloud:8002/wifi/forgotpassword + http://cc.opensimulator.org:8005/wifi/forgotpassword platform OpenSim register - http://grid.virtualife.cloud:8002/wifi/user/account + http://cc.opensimulator.org:8005/wifi/user/account slurl_base - hop://grid.virtualife.cloud:8002/ + hop://cc.opensimulator.org:8002/ + + craft-world.org:8002 + + LastModified + 2020-06-02T14:23:31.86Z + about + https://www.craft-world.org/ + gatekeeper + craft-world.org:8002 + gridname + Craft World + gridnick + craft + help + https://www.craft-world.org/page/en/support.php + helperuri + http://webapp.craft-world.org/economy/ + login_identifier_types + + agent + account + + loginpage + https://www.craft-world.org/loginscreen.php + loginuri + + http://craft-world.org:8002/ + + name + craft-world.org:8002 + password + https://www.craft-world.org/page/en/avatar-tools.php + platform + OpenSim + register + https://www.craft-world.org/page/en/register-an-avatar.php + slurl_base + hop://craft-world.org:8002/ discoverygrid.net:8002 LastModified - 2019-12-04T10:46:23.59Z + 2020-04-24T12:06:59.18Z about https://discoverygrid.net/about.php gatekeeper @@ -106,77 +166,586 @@ slurl_base hop://discoverygrid.net:8002/ - grid.alifevirtual.com:8002 + fireandicegrid.net:8002 LastModified - 2019-12-04T10:42:24.54Z + 2020-06-02T11:41:59.83Z about - http://www.alifevirtual.com/ + http://fireandicegrid.net + gatekeeper + fireandicegrid.net:8002 gridname - Alife Virtual + Fire And Ice Grid gridnick - AV + FireAndIceGrid help - http://www.alifevirtual.com/ + http://fireandicegrid.net helperuri - http://www.alifevirtual.com/helper/ + http://fireandicegrid.net login_identifier_types agent account loginpage - http://www.alifevirtual.com/welcome.php + http://fireandicegrid.net loginuri - http://www.alifevirtual.com:8002/ + http://fireandicegrid.net:8002/ name - grid.alifevirtual.com:8002 + fireandicegrid.net:8002 password - http://www.alifevirtual.com/ + http://fireandicegrid.net:8002/wifi platform OpenSim register - http://www.alifevirtual.com/ + http://fireandicegrid.net:8002/wifi slurl_base - hop://grid.alifevirtual.com:8002/ + hop://fireandicegrid.net:8002/ - login.main.mobiusgrid.us:8002 + gaynations.org:7002 + DEPRECATED + TRUE + login_identifier_types + + agent + account + LastModified - 2019-12-04T10:41:18.60Z + 2020-06-02T11:41:00.95Z + name + gaynations.org:7002 + + goto.theencoreescape.com:8002 + + DirectoryFee + 0 + LastModified + 2020-04-24T17:00:50.92Z + SendGridInfoToViewerOnLogin + true about - https://mobiusgrid.us/index.php/about/about-us + http://theencoreescape.com/ + gatekeeper + goto.theencoreescape.com:8002 gridname - Mobius Grid + The Encore Escape gridnick - Mobius + EncoreEscape help - https://mobiusgrid.us/index.php/community/forum + http://theencoreescape.com/ helperuri - https://mobiusgrid.us/components/com_opensim/ + http://money.theencoreescape.com/ login_identifier_types agent account loginpage - https://mobiusgrid.us/index.php?option=com_opensim + http://splash.theencoreescape.com/ loginuri - http://login.main.mobiusgrid.us + http://goto.theencoreescape.com:8002/ name - login.main.mobiusgrid.us:8002 + goto.theencoreescape.com:8002 password - https://mobiusgrid.us/index.php/join-us?view=reset + http://theencoreescape.com/ platform OpenSim register - https://mobiusgrid.us/index.php/join-us + http://theencoreescape.com/ + search + http://search.theencoreescape.com/query.php slurl_base - hop://login.main.mobiusgrid.us:8002/ + hop://goto.theencoreescape.com:8002/ + + grid.3rdrockgrid.com:8002 + + LastModified + 2012-08-03T15:32:54.31Z + about + http://3rdrockgrid.com/ + gridname + 3RD Rock Grid + gridnick + 3RG + help + http://3rdrockgrid.com/ + helperuri + http://grid.3rdrockgrid.com/3rg_money/ + login_identifier_types + + agent + account + + loginpage + http://grid.3rdrockgrid.com/3rg_login/ + loginuri + + http://grid.3rdrockgrid.com:8002/ + + name + grid.3rdrockgrid.com:8002 + password + http://3rdrockgrid.com/ + register + http://3rdrockgrid.com/ + slurl_base + hop://grid.3rdrockgrid.com:8002/ + + + grid.avacon.org:8002 + + LastModified + 2020-06-02T12:01:35.02Z + gatekeeper + grid.avacon.org:8002 + gridname + AvaCon Grid + gridnick + avacon + helperuri + http://grid.avacon.org/helper/ + login_identifier_types + + agent + account + + loginpage + http://grid.avacon.org:8005/wifi/welcome.html + loginuri + + http://grid.avacon.org:8002/ + + name + grid.avacon.org:8002 + password + http://grid.avacon.org:8005/wifi/forgotpassword + platform + OpenSim + register + http://grid.avacon.org:8005/wifi/user/account + slurl_base + hop://grid.avacon.org:8002/ + + grid.kitely.com:8002 + + LastModified + 2014-03-20T12:30:00Z + gatekeeper + grid.kitely.com:8002 + gridname + Kitely + gridnick + kitely + helperuri + http://grid.kitely.com:8002/ + login_identifier_types + + agent + account + + loginpage + http://www.kitely.com/viewer_login + loginuri + + http://grid.kitely.com:8002/ + + name + grid.kitely.com:8002 + platform + OpenSim + slurl_base + hop://grid.kitely.com:8002/ + + grid.virtualife.cloud:8002 + + LastModified + 2019-12-04T10:50:32.55Z + about + http://www.virtualife.cloud + gatekeeper + grid.virtualife.cloud:8002 + gridname + virtualife world + gridnick + Virtualife world + login_identifier_types + + agent + account + + loginpage + http://www.virtualife.cloud/index.php?option=com_opensim + loginuri + + http://grid.virtualife.cloud:8002/ + + name + grid.virtualife.cloud:8002 + password + http://grid.virtualife.cloud:8002/wifi/forgotpassword + platform + OpenSim + register + http://grid.virtualife.cloud:8002/wifi/user/account + slurl_base + hop://grid.virtualife.cloud:8002/ + + grid01.from-ne.com:8002 + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + login_identifier_types + + agent + account + + name + grid01.from-ne.com:8002 + + hypergrid.org:8002 + + LastModified + 2013-04-02T01:01:24.65Z + about + http://www.hypergrid.org/metropolis/wiki + gatekeeper + hypergrid.org:8002 + gridname + Metropolis Metaversum + gridnick + Metropolis + help + http://metropolis.hypergrid.org/forum + helperuri + http://metropolis.hypergrid.org/currency/helper/ + login_identifier_types + + agent + account + + loginpage + http://metropolis.hypergrid.org + loginuri + + http://hypergrid.org:8002/ + + name + hypergrid.org:8002 + password + http://metropolis.hypergrid.org/password.php + platform + OpenSim + register + http://www.hypergrid.org/metropolis/metro_rg.php + slurl_base + hop://hypergrid.org:8002/ + + islandoasisgrid.biz:8002 + + LastModified + 2013-01-21T20:10:35.17Z + about + http://www.islandoasis.biz/GridStats.aspx + gridname + Island Oasis + gridnick + Island_Oasis + help + http://www.islandoasis.biz/Support.aspx + helperuri + http://islandoasisgrid:8020/OsCurrency/ + login_identifier_types + + agent + account + + loginpage + http://www.islandoasis.biz/welcome.aspx + loginuri + + http://islandoasisgrid.biz:8002/ + + name + islandoasisgrid.biz:8002 + password + http://www.islandoasis.biz/Login.aspx + platform + OpenSim + register + http://www.islandoasis.biz/verification.aspx + slurl_base + hop://islandoasisgrid.biz:8002/ + + lfgrid.com:8002 + + LastModified + 2013-03-18T21:51:17.62Z + about + http://lfgrid.com/about/ + gatekeeper + lfgrid.com:8002 + gridname + Littlefield Grid + gridnick + LFgrid + help + http://lfgrid.com/help + helperuri + http://lfgrid.com/services/ + login_identifier_types + + agent + account + + loginpage + http://www.lfgrid.com/splash/index.php + loginuri + + http://lfgrid.com:8002/ + + name + lfgrid.com:8002 + password + http://lfgrid.com:8002/wifi/forgotpassword + platform + OpenSim + register + http://lfgrid.com:8002/wifi/user/account/ + slurl_base + hop://lfgrid.com:8002/ + + login.aviworlds.com:8002 + + DirectoryFee + 0 + LastModified + 2020-06-02T11:41:55.32Z + SendGridInfoToViewerOnLogin + true + about + http://aviworlds.com + gatekeeper + login.aviworlds.com:8002 + gridname + AviWorlds + gridnick + Avi + help + http://aviworlds.com + helperuri + http://login.aviworlds.com/helper_scripts/helper/ + login_identifier_types + + agent + account + + loginpage + http://login.aviworlds.com/splash + loginuri + + http://login.aviworlds.com:8002/ + + name + login.aviworlds.com:8002 + password + http://login.aviworlds.com:8002/wifi/forgotpassword + platform + OpenSim + register + http://login.aviworlds.com:8002/wifi/user/account/ + search + http://login.aviworlds.com/ossearch/query.php + slurl_base + hop://login.aviworlds.com:8002/ + + login.digiworldz.com:8002 + + DirectoryFee + 0 + LastModified + 2015-07-24T13:19:44.27Z + SendGridInfoToViewerOnLogin + true + about + http://digiworldz.com/ + gatekeeper + login.digiworldz.com:8002 + gridname + DigiWorldZ Grid + gridnick + DWG + help + http://digiworldz.com/ + helperuri + http://money.digiworldz.com/ + login_identifier_types + + agent + account + + loginpage + http://splash.digiworldz.com/ + loginuri + + http://login.digiworldz.com:8002/ + + name + login.digiworldz.com:8002 + password + http://digiworldz.com/ + platform + OpenSim + register + http://digiworldz.com/ + search + http://search.digiworldz.com/query.php + slurl_base + hop://login.digiworldz.com:8002/ + + login.francogrid.org:80 + + LastModified + 2013-02-14T02:00:46.10Z + about + http://francogrid.org/ + gridname + FrancoGrid + gridnick + francogrid + help + http://francogrid.org/aide + helperuri + http://helper.main.francogrid.org/ + login_identifier_types + + agent + account + + loginpage + http://viewer.francogrid.org/ + loginuri + + http://login.francogrid.org/ + + name + login.francogrid.org:80 + password + http://francogrid.org/user/password + platform + OpenSim + register + http://francogrid.org/user/register + slurl_base + hop://login.francogrid.org:80/ + + login.greatcanadiangrid.ca:8002 + + DEPRECATED + TRUE + login_identifier_types + + agent + account + + LastModified + 2020-06-02T11:41:00.95Z + name + login.greatcanadiangrid.ca:8002 + + login.osgrid.org + + LastModified + 2019-04-19T21:15:00Z + about + http://www.osgrid.org/ + gatekeeper + hg.osgrid.org:80 + gridname + OSGrid + gridnick + osgrid + help + http://www.osgrid.org/ + helperuri + http://helper.osgrid.org/ + login_identifier_types + + agent + account + + loginpage + http://www.osgrid.org/splash/ + loginuri + + http://login.osgrid.org/ + + name + login.osgrid.org + password + http://www.osgrid.org/ + platform + + register + http://www.osgrid.org/ + slurl_base + hop://login.osgrid.org/ + web_profile_url + http://my.osgrid.org/?name=[AGENT_NAME] + + login.ufsgrid.com:8002 + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + login_identifier_types + + agent + account + + name + login.ufsgrid.com:8002 + + login.zetaworlds.com + + LastModified + 2020-06-02T12:39:31.19Z + about + https://zetaworlds.com/ + gridname + ZetaWorlds + gridnick + ZetaWorlds + helperuri + http://money.zetaworlds.com/ + login_identifier_types + + agent + account + + loginpage + http://zetaworlds.com/splash + loginuri + + https://login.zetaworlds.com/ + + name + login.zetaworlds.com + password + https://zetaworlds.com/user/forgot + platform + OpenSim + register + http://zetaworlds.com/user/register + slurl_base + hop://login.zetaworlds.com/ login.zonenations.com:8002 @@ -216,6 +785,49 @@ slurl_base hop://login.zonenations.com:8002/ + login.main.mobiusgrid.us:8002 + + LastModified + 2020-06-02T11:41:00.95Z + DEPRECATED + TRUE + name + login.main.mobiusgrid.us:8002 + + main.mobiusgrid.us + + LastModified + 2020-06-02T13:19:55.40Z + about + https://mobiusgrid.us/about + gridname + Mobius Grid + gridnick + Mobius + help + https://mobiusgrid.us/help + login_identifier_types + + agent + account + + loginpage + https://mobiusgrid.us/splash + loginuri + + http://login.main.mobiusgrid.us + + name + main.mobiusgrid.us + password + https://mobiusgrid.us/forgot + platform + OpenSim + register + https://mobiusgrid.us/join + slurl_base + hop://main.mobiusgrid.us/ + partydestinationgrid.com:8002 LastModified @@ -324,567 +936,6 @@ slurl_base hop://thekazgrid.com:8002/ - login.digiworldz.com:8002 - - DirectoryFee - 0 - LastModified - 2015-07-24T13:19:44.27Z - SendGridInfoToViewerOnLogin - true - about - http://digiworldz.com/ - gatekeeper - login.digiworldz.com:8002 - gridname - DigiWorldZ Grid - gridnick - DWG - help - http://digiworldz.com/ - helperuri - http://money.digiworldz.com/ - login_identifier_types - - agent - account - - loginpage - http://splash.digiworldz.com/ - loginuri - - http://login.digiworldz.com:8002/ - - name - login.digiworldz.com:8002 - password - http://digiworldz.com/ - platform - OpenSim - register - http://digiworldz.com/ - search - http://search.digiworldz.com/query.php - slurl_base - hop://login.digiworldz.com:8002/ - - login.greatcanadiangrid.ca:8002 - - DirectoryFee - 0 - LastModified - 2015-07-21T12:18:29.76Z - SendGridInfoToViewerOnLogin - true - about - http://greatcanadiangrid.ca/ - gatekeeper - login.greatcanadiangrid.ca:8002 - gridname - Great Canadian Grid! - gridnick - GCG - help - http://greatcanadiangrid.ca/ - helperuri - http://money.greatcanadiangrid.ca/ - login_identifier_types - - agent - account - - loginpage - http://www.greatcanadiangrid.ca/splash-page.html - loginuri - - http://login.greatcanadiangrid.ca:8002/ - - name - login.greatcanadiangrid.ca:8002 - password - http://greatcanadiangrid.ca/ - platform - OpenSim - register - http://greatcanadiangrid.ca/ - search - http://search.greatcanadiangrid.ca/query.php - slurl_base - hop://login.greatcanadiangrid.ca:8002/ - - craft-world.org:8002 - - LastModified - 2013-02-05T00:05:39.27Z - about - http://www.craft-world.org/ - gatekeeper - craft-world.org:8002 - gridname - Craft World - gridnick - craft - helperuri - http://webapp.craft-world.org/economy/ - login_identifier_types - - agent - account - - loginpage - http://craft-world.org/loginscreen.php - loginuri - - http://craft-world.org:8002/ - - name - craft-world.org:8002 - platform - OpenSim - register - http://www.craft-world.org/page/en/register-an-avatar.php - slurl_base - hop://craft-world.org:8002/ - - gaynations.org:7002 - - LastModified - 2012-12-05T04:58:55.72Z - about - http://gaynations.org/ - gridname - Gay Nations - gridnick - gay nations - helperuri - http://gaynations.org/helper - login_identifier_types - - agent - account - - loginpage - http://gaynations.org/splashpage - loginuri - - http://os.gaynations.org:7002/ - - name - gaynations.org:7002 - platform - OpenSim - slurl_base - hop://gaynations.org:7002/ - - grid.3rdrockgrid.com:8002 - - LastModified - 2012-08-03T15:32:54.31Z - about - http://3rdrockgrid.com/ - gridname - 3RD Rock Grid - gridnick - 3RG - help - http://3rdrockgrid.com/ - helperuri - http://grid.3rdrockgrid.com/3rg_money/ - login_identifier_types - - agent - account - - loginpage - http://grid.3rdrockgrid.com/3rg_login/ - loginuri - - http://grid.3rdrockgrid.com:8002/ - - name - grid.3rdrockgrid.com:8002 - password - http://3rdrockgrid.com/ - register - http://3rdrockgrid.com/ - slurl_base - hop://grid.3rdrockgrid.com:8002/ - - grid.avatarconnection.com:8002/ - - DEPRECATED - TRUE - name - grid.avatarconnection.com:8002/ - - grid.roleplayworlds.net:8002 - - DEPRECATED - TRUE - name - grid.roleplayworlds.net:8002 - - grid01.from-ne.com:8002 - - LastModified - 2012-08-03T15:36:53.60Z - about - http://www.youralternativelife.com - gridname - Your Alternative Life - gridnick - YAL - help - http://grid01.from-ne.com/tios/support/ - login_identifier_types - - agent - account - - loginpage - http://grid01.from-ne.com/tios/loginscreen3.php - loginuri - - http://grid01.from-ne.com:8002/ - - name - grid01.from-ne.com:8002 - password - http://grid01.from-ne.com/tios/support/resetpw.php - register - http://grid01.from-ne.com/tios/support/createnew.php - slurl_base - hop://grid01.from-ne.com:8002/ - - hypergrid.org:8002 - - LastModified - 2013-04-02T01:01:24.65Z - about - http://www.hypergrid.org/metropolis/wiki - gatekeeper - hypergrid.org:8002 - gridname - Metropolis Metaversum - gridnick - Metropolis - help - http://metropolis.hypergrid.org/forum - helperuri - http://metropolis.hypergrid.org/currency/helper/ - login_identifier_types - - agent - account - - loginpage - http://metropolis.hypergrid.org - loginuri - - http://hypergrid.org:8002/ - - name - hypergrid.org:8002 - password - http://metropolis.hypergrid.org/password.php - platform - OpenSim - register - http://www.hypergrid.org/metropolis/metro_rg.php - slurl_base - hop://hypergrid.org:8002/ - - inworldz.com:8002 - - LastModified - 2018-08-23T21:00:00.00Z - DEPRECATED - TRUE - name - inworldz.com:8002 - - islandoasisgrid.biz:8002 - - LastModified - 2013-01-21T20:10:35.17Z - about - http://www.islandoasis.biz/GridStats.aspx - gridname - Island Oasis - gridnick - Island_Oasis - help - http://www.islandoasis.biz/Support.aspx - helperuri - http://islandoasisgrid:8020/OsCurrency/ - login_identifier_types - - agent - account - - loginpage - http://www.islandoasis.biz/welcome.aspx - loginuri - - http://islandoasisgrid.biz:8002/ - - name - islandoasisgrid.biz:8002 - password - http://www.islandoasis.biz/Login.aspx - platform - OpenSim - register - http://www.islandoasis.biz/verification.aspx - slurl_base - hop://islandoasisgrid.biz:8002/ - - lfgrid.com:8002 - - LastModified - 2013-03-18T21:51:17.62Z - about - http://lfgrid.com/about/ - gatekeeper - lfgrid.com:8002 - gridname - Littlefield Grid - gridnick - LFgrid - help - http://lfgrid.com/help - helperuri - http://lfgrid.com/services/ - login_identifier_types - - agent - account - - loginpage - http://www.lfgrid.com/splash/index.php - loginuri - - http://lfgrid.com:8002/ - - name - lfgrid.com:8002 - password - http://lfgrid.com:8002/wifi/forgotpassword - platform - OpenSim - register - http://lfgrid.com:8002/wifi/user/account/ - slurl_base - hop://lfgrid.com:8002/ - - localhost:9000 - - LastModified - 2011-08-28T12:00:00Z - grid_login_id - localhost:9000 - gridname - localhost - gridnick - localhost - login_identifier_types - - agent - account - - loginpage - - loginuri - - http://localhost:9000 - - name - localhost:9000 - slurl_base - hop://localhost:9000/ - - login.aurorascape.com:8002 - - DEPRECATED - TRUE - name - login.aurorascape.com:8002 - - login.avination.com/ - - DEPRECATED - TRUE - name - login.avination.com/ - LastModified - 2018-02-28T15:36:26.43Z - - login.francogrid.org:80 - - LastModified - 2013-02-14T02:00:46.10Z - about - http://francogrid.org/ - gridname - FrancoGrid - gridnick - francogrid - help - http://francogrid.org/aide - helperuri - http://helper.main.francogrid.org/ - login_identifier_types - - agent - account - - loginpage - http://viewer.francogrid.org/ - loginuri - - http://login.francogrid.org/ - - name - login.francogrid.org:80 - password - http://francogrid.org/user/password - platform - OpenSim - register - http://francogrid.org/user/register - slurl_base - hop://login.francogrid.org:80/ - - login.danger.osgrid.org - - DEPRECATED - TRUE - name - login.danger.osgrid.org - - login.osgrid.org - - LastModified - 2019-04-19T21:15:00.00Z - about - http://www.osgrid.org/ - gatekeeper - hg.osgrid.org:80 - gridname - OSGrid - gridnick - osgrid - help - http://www.osgrid.org/ - helperuri - http://helper.osgrid.org/ - login_identifier_types - - agent - account - - loginpage - http://www.osgrid.org/splash/ - loginuri - - http://login.osgrid.org/ - - name - login.osgrid.org - password - http://www.osgrid.org/ - register - http://www.osgrid.org/ - slurl_base - hop://login.osgrid.org/ - web_profile_url - http://my.osgrid.org/?name=[AGENT_NAME] - - login.ufsgrid.com:8002 - - CurrencySymbol - OMC$ - DirectoryFee - 0 - LastModified - 2013-04-15T13:34:58.59Z - MaxGroups - 50 - RealCurrencySymbol - $ - SendGridInfoToViewerOnLogin - true - about - http://www.ufsgrid.com/ - gridname - UFSGrid - gridnick - UFSGrid - help - http://www.ufsgrid.com/support - helperuri - http://gridserv.ufsgrid.com/helper/ - login_identifier_types - - agent - account - - loginpage - http://www.ufsgrid.com/app/loginscreen/screen.php - loginuri - - http://login.ufsgrid.com:8002/ - - name - login.ufsgrid.com:8002 - password - http://www.ufsgrid.com/ufsgrid/lost-passwd - platform - OpenSim - register - http://www.ufsgrid.com/register - search - http://www.ufsgrid.com/app/search/worldsearch.php? - slurl_base - hop://login.ufsgrid.com:8002/ - - grid.kitely.com:8002 - - LastModified - 2014-03-20T12:30:00.00Z - gridname - Kitely - gridnick - kitely - login_identifier_types - - agent - account - - loginpage - http://www.kitely.com/viewer_login - loginuri - - http://grid.kitely.com:8002/ - - gatekeeper - grid.kitely.com:8002 - helperuri - http://grid.kitely.com:8002/ - name - grid.kitely.com:8002 - platform - OpenSim - slurl_base - hop://grid.kitely.com:8002/ - - reactiongrid.com:8008 - - DEPRECATED - TRUE - name - reactiongrid.com:8008 - util.aditi.lindenlab.com LastModified @@ -907,47 +958,155 @@ https://login.aditi.lindenlab.com/cgi-bin/login.cgi - name + name util.aditi.lindenlab.com - slurl_base + slurl_base secondlife://util.aditi.lindenlab.com/secondlife/ - system_grid + system_grid 1 - web_profile_url + web_profile_url https://my.aditi.lindenlab.com/ - util.agni.lindenlab.com + util.agni.lindenlab.com - LastModified + LastModified 2018-06-22T22:15:00Z - app_slurl_base + app_slurl_base secondlife:///app - favorite + favorite 1 - gridname + gridname Second Life - gridnick + gridnick agni helperuri - https://secondlife.com/helpers/ + https://secondlife.com/helpers/ + login_identifier_types + + agent + + loginpage + http://phoenixviewer.com/app/loginV3/ + loginuri + + https://login.agni.lindenlab.com/cgi-bin/login.cgi + + name + util.agni.lindenlab.com + slurl_base + http://maps.secondlife.com/secondlife/ + system_grid + 1 + web_profile_url + https://my.secondlife.com/ + + grid.alifevirtual.com:8002 + + DEPRECATED + TRUE + LastModified + 2020-04-04T10:42:24.54Z + name + grid.alifevirtual.com:8002 + + www.alifevirtual.com:8002 + + LastModified + 2020-05-30T09:41:01.73Z + about + http://www.alifevirtual.com/ + gridname + Alife Virtual + gridnick + AV + help + http://www.alifevirtual.com/ + helperuri + http://www.alifevirtual.com/helper/ login_identifier_types agent + account loginpage - http://phoenixviewer.com/app/loginV3/ + http://www.alifevirtual.com/welcome.php loginuri - https://login.agni.lindenlab.com/cgi-bin/login.cgi + http://www.alifevirtual.com:8002/ name - util.agni.lindenlab.com + www.alifevirtual.com:8002 + password + http://www.alifevirtual.com/ + platform + OpenSim + register + http://www.alifevirtual.com/ slurl_base - http://maps.secondlife.com/secondlife/ - system_grid - 1 - web_profile_url - https://my.secondlife.com/ + hop://www.alifevirtual.com:8002/ + + grid.avatarconnection.com:8002/ + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + name + grid.avatarconnection.com:8002/ + + grid.roleplayworlds.net:8002 + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + name + grid.roleplayworlds.net:8002 + + inworldz.com:8002 + + LastModified + 2018-08-23T21:00:00.00Z + DEPRECATED + TRUE + name + inworldz.com:8002 + + login.avination.com/ + + DEPRECATED + TRUE + name + login.avination.com/ + LastModified + 2018-02-28T15:36:26.43Z + + login.danger.osgrid.org + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + name + login.danger.osgrid.org + + reactiongrid.com:8008 + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + name + reactiongrid.com:8008 + + login.aurorascape.com:8002 + + DEPRECATED + TRUE + LastModified + 2020-06-02T11:41:00.95Z + name + login.aurorascape.com:8002 diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/keys.xml similarity index 64% rename from indra/newview/app_settings/key_bindings.xml rename to indra/newview/app_settings/keys.xml index dd74293644..a8037fec05 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/keys.xml @@ -28,12 +28,34 @@ + + + + + + + + - - + + + + + + + + + + + + + + + + @@ -42,10 +64,15 @@ + + + + + @@ -57,8 +84,13 @@ + + + + + @@ -67,12 +99,20 @@ + + + + + + + + @@ -99,14 +139,28 @@ + + + + + + + + + + + + + + @@ -125,10 +179,63 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -144,11 +251,15 @@ + + + + @@ -183,23 +294,23 @@ - - - + + + - - - + + + - - - + + + @@ -223,9 +334,6 @@ - - - @@ -251,7 +359,5 @@ - - - + \ No newline at end of file diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c506b2ad98..799a22cc94 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5557,7 +5557,7 @@ DoubleClickAutoPilot Comment - (Obsolete)Enable double-click auto pilot + Enable double-click auto pilot Persist 1 Type @@ -5568,13 +5568,13 @@ DoubleClickTeleport Comment - Enable double-click to teleport where allowed (afects minimap and people panel) + Enable double-click to teleport where allowed Persist 1 Type Boolean Value - 1 + 0 DoubleClickShowWorldMap @@ -10979,7 +10979,7 @@ Change of this parameter will affect the layout of buttons in notification toast PushToTalkButton Comment - (Obsolete)Which button or keyboard key is used for push-to-talk + Which button or keyboard key is used for push-to-talk Persist 1 Type @@ -11159,7 +11159,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type F32 Value - 0.125 + 0.02 MediaRollOffMin @@ -11170,7 +11170,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type F32 Value - 10.0 + 40.0 MediaRollOffMax @@ -11181,7 +11181,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type F32 Value - 30.0 + 80.0 RecentItemsSortOrder @@ -19805,7 +19805,7 @@ Change of this parameter will affect the layout of buttons in notification toast ClickToWalk Comment - (obsolete)Click in world to walk to location + Click in world to walk to location Persist 1 Type @@ -21041,6 +21041,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + FSUseAzertyKeyboardLayout + + Comment + Uses a keyboard layout suitable for keyboards with AZERTY layout. + Persist + 1 + Type + Boolean + Value + 0 + FSNameTagZOffsetCorrection Comment diff --git a/indra/newview/fscommon.cpp b/indra/newview/fscommon.cpp index d064dcdac6..a1bba035e0 100644 --- a/indra/newview/fscommon.cpp +++ b/indra/newview/fscommon.cpp @@ -85,6 +85,17 @@ bool is_irc_me_prefix(const std::string& text) return (prefix == "/me " || prefix == "/me'"); } +std::string unescape_name(const std::string& name) +{ + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_unescape(name.c_str(), name.size()); + std::string unescaped_name(curl_str); + curl_free(curl_str); + curl_str = NULL; + + return unescaped_name; +} + std::string FSCommon::applyAutoCloseOoc(std::string message) { if (!gSavedSettings.getBOOL("AutoCloseOOC")) diff --git a/indra/newview/fscommon.h b/indra/newview/fscommon.h index 5d00a2887c..be33ef6790 100644 --- a/indra/newview/fscommon.h +++ b/indra/newview/fscommon.h @@ -40,6 +40,7 @@ const F32 AVATAR_UNKNOWN_RANGE = -1.f; void report_to_nearby_chat(const std::string& message); std::string format_string(std::string text, const LLStringUtil::format_map_t& args); bool is_irc_me_prefix(const std::string& text); +std::string unescape_name(const std::string& name); namespace FSCommon { diff --git a/indra/newview/fsfloatervramusage.cpp b/indra/newview/fsfloatervramusage.cpp index f808a57a65..7f55295038 100644 --- a/indra/newview/fsfloatervramusage.cpp +++ b/indra/newview/fsfloatervramusage.cpp @@ -333,7 +333,7 @@ S32 FSFloaterVRAMUsage::calcVBOEntrySize( LLVertexBuffer *aVBO ) void FSFloaterVRAMUsage::onProperties( LLSelectNode const *aProps ) { - if( !aProps && !aProps->getObject() ) + if( !aProps || !aProps->getObject() ) return; LLUUID id = aProps->getObject()->getID(); diff --git a/indra/newview/fsnearbychathub.cpp b/indra/newview/fsnearbychathub.cpp index d28c08814f..fa08908cf5 100644 --- a/indra/newview/fsnearbychathub.cpp +++ b/indra/newview/fsnearbychathub.cpp @@ -42,7 +42,7 @@ #include "lllineeditor.h" #include "llspinctrl.h" #include "llviewercontrol.h" -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "llviewerstats.h" #include "llworld.h" #include "rlvactions.h" diff --git a/indra/newview/lggbeammaps.cpp b/indra/newview/lggbeammaps.cpp index 9ff3602757..c027275eea 100644 --- a/indra/newview/lggbeammaps.cpp +++ b/indra/newview/lggbeammaps.cpp @@ -13,6 +13,7 @@ #include "llviewerprecompiledheaders.h" +#include "fscommon.h" #include "lggbeammaps.h" #include "lggbeamscolors.h" #include "llagent.h" @@ -27,17 +28,6 @@ lggBeamMaps gLggBeamMaps; -std::string unescape_name(const std::string& name) -{ - // bugfix for SL-46920: preventing filenames that break stuff. - char * curl_str = curl_unescape(name.c_str(), name.size()); - std::string unescaped_name(curl_str); - curl_free(curl_str); - curl_str = NULL; - - return unescaped_name; -} - F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn) { while (valHUeIn < 0.0f) @@ -70,7 +60,7 @@ F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn) void hslToRgb(F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut) { - if (sValIn < 0.00001f) + if (sValIn < F_ALMOST_ZERO) { rValOut = lValIn; gValOut = lValIn; @@ -400,4 +390,3 @@ void lggBeamMaps::updateBeamChat(const LLVector3d& currentPos) } } } - diff --git a/indra/newview/lggbeamscolors.cpp b/indra/newview/lggbeamscolors.cpp index 0da2aa0b5f..78513dd73e 100644 --- a/indra/newview/lggbeamscolors.cpp +++ b/indra/newview/lggbeamscolors.cpp @@ -18,9 +18,6 @@ #include "llviewerprecompiledheaders.h" #include "lggbeamscolors.h" -#include "llfile.h" -#include "llsdserialize.h" - lggBeamsColors lggBeamsColors::fromLLSD(const LLSD& inputData) { lggBeamsColors toReturn; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 7095628e49..0bd8fbfa21 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -219,16 +219,21 @@ void LLAgentCamera::init() mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType"); - mCameraOffsetInitial = gSavedSettings.getControl("CameraOffsetRearView"); - mFocusOffsetInitial = gSavedSettings.getControl("FocusOffsetRearView"); -//// [RLVa:KB] - Checked: RLVa-2.0.0 -// mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("CameraOffsetRLVaView", LLVector3(mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO); -// mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true); -//// [/RLVa:KB] -//// [RLVa:KB] - Checked: RLVa-2.0.0 -// mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("FocusOffsetRLVaView", LLVector3(mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO); -// mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true); -//// [/RLVa:KB] +// mCameraOffsetInitial = gSavedSettings.getControl("CameraOffsetRearView"); +// mFocusOffsetInitial = gSavedSettings.getControl("FocusOffsetRearView"); +// [RLVa:KB] - @setcam_eyeoffset, @setcam_focusoffset and @setcam_eyeoffsetscale + mCameraOffsetInitialControl = gSavedSettings.getControl("CameraOffsetRearView"); + mFocusOffsetInitialControl = gSavedSettings.getControl("FocusOffsetRearView"); + if (RlvActions::isRlvEnabled()) + { + mRlvCameraOffsetInitialControl = gSavedSettings.declareVec3("CameraOffsetRLVaView", LLVector3::zero, "Declared in code", LLControlVariable::PERSIST_NO); + mRlvCameraOffsetInitialControl->setHiddenFromSettingsEditor(true); + mRlvCameraOffsetScaleControl = gSavedSettings.declareF32("CameraOffsetScaleRLVa", 0.0f, "Declared in code", LLControlVariable::PERSIST_NO); + mRlvCameraOffsetScaleControl->setHiddenFromSettingsEditor(true); + mRlvFocusOffsetInitialControl = gSavedSettings.declareVec3d("FocusOffsetRLVaView", LLVector3d::zero, "Declared in code", LLControlVariable::PERSIST_NO); + mRlvFocusOffsetInitialControl->setHiddenFromSettingsEditor(true); + } +// [/RLVa:KB] mCameraCollidePlane.clearVec(); mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); @@ -1026,7 +1031,10 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters) { if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) { - F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale")); +// [RLVa:KB] - @setcam_eyeoffsetscale + F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * getCameraOffsetScale()); +// [/RLVa:KB] +// F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale")); mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; @@ -1739,7 +1747,10 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset() agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); } - focus_offset = convert_from_llsd(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); +// focus_offset = convert_from_llsd(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); +// [RLVa:KB] - @setcam_focusoffset + focus_offset = getFocusOffsetInitial(); +// [/RLVa:KB] return focus_offset * agent_rot; } @@ -1880,7 +1891,10 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) } else { - local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); +// [RLVa:KB] - @setcam_eyeoffsetscale + local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * getCameraOffsetScale(); +// [/RLVa:KB] +// local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); // are we sitting down? if (isAgentAvatarValid() && gAgentAvatarp->getParent()) @@ -2076,7 +2090,10 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) // Check focus distance limits if ( (fCamOriginDistClamped) && (!fCamAvDistLocked) ) { - const LLVector3 offsetCameraLocal = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); +// const LLVector3 offsetCameraLocal = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); +// [RLVa:KB] - @setcam_eyeoffsetscale + const LLVector3 offsetCameraLocal = mCameraZoomFraction * getCameraOffsetInitial() * getCameraOffsetScale(); +// [/RLVa:KB] const LLVector3d offsetCamera(gAgent.getFrameAgent().rotateToAbsolute(offsetCameraLocal)); const LLVector3d posFocusCam = frame_center_global + head_offset + offsetCamera; if (clampCameraPosition(camera_position_global, posFocusCam, nCamOriginDistLimitMin, nCamOriginDistLimitMax)) @@ -2183,14 +2200,27 @@ bool LLAgentCamera::isJoystickCameraUsed() LLVector3 LLAgentCamera::getCameraOffsetInitial() { - return convert_from_llsd(mCameraOffsetInitial->get(), TYPE_VEC3, ""); +// [RLVa:KB] - @setcam_eyeoffset + return convert_from_llsd( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mCameraOffsetInitialControl->get() : mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, ""); +// [/RLVa:KB] +// return convert_from_llsd(mCameraOffsetInitial->get(), TYPE_VEC3, ""); } LLVector3d LLAgentCamera::getFocusOffsetInitial() { - return convert_from_llsd(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); +// [RLVa:KB] - @setcam_focusoffset + return convert_from_llsd( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mFocusOffsetInitialControl->get() : mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, ""); +// [/RLVa:KB] +// return convert_from_llsd(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); } +// [RLVa:KB] - @setcam_eyeoffsetscale +F32 LLAgentCamera::getCameraOffsetScale() const +{ + return gSavedSettings.getF32( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? "CameraOffsetScale" : "CameraOffsetScaleRLVa"); +} +// [/RLVa:KB] + // FIRE-23470: Fix camera controls zoom glitch //F32 LLAgentCamera::getCameraMaxZoomDistance() F32 LLAgentCamera::getCameraMaxZoomDistance(bool allow_disabled_constraints /* = false*/) @@ -2280,10 +2310,16 @@ void LLAgentCamera::handleScrollWheel(S32 clicks) F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec(); - F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); +// F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); +// [RLVa:KB] - @setcam_eyeoffsetscale + F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * getCameraOffsetScale()); +// [/RLVa:KB] current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); - cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); +// [RLVa:KB] - @setcam_eyeoffsetscale + cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * getCameraOffsetScale()); +// [/RLVa:KB] +// cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale")); } else { @@ -2635,22 +2671,27 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() void LLAgentCamera::switchCameraPreset(ECameraPreset preset) { -// [RLVa:KB] - Checked: RLVa-2.0.0 +// [RLVa:KB] - @setcam family if (RlvActions::isRlvEnabled()) { - // Don't allow changing away from the our view if an object is restricting it + // Don't allow changing away from our view if an object is restricting it if (RlvActions::isCameraPresetLocked()) preset = CAMERA_RLV_SETCAM_VIEW; - // Don't reset anything if our view is already current - if ( (CAMERA_RLV_SETCAM_VIEW == preset) && (CAMERA_RLV_SETCAM_VIEW == mCameraPreset) ) - return; - - // Reset our view when switching away - if (CAMERA_RLV_SETCAM_VIEW != preset) + if (CAMERA_RLV_SETCAM_VIEW == preset) { - //mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->resetToDefault(); - //mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->resetToDefault(); + if (CAMERA_RLV_SETCAM_VIEW == mCameraPreset) + { + // Don't reset anything if our view is already current + return; + } + else + { + // When switching to our view, copy the current values + mRlvCameraOffsetInitialControl->setDefaultValue(convert_to_llsd(getCameraOffsetInitial())); + mRlvFocusOffsetInitialControl->setDefaultValue(convert_to_llsd(getFocusOffsetInitial())); + mRlvCameraOffsetScaleControl->setDefaultValue(getCameraOffsetScale()); + } } } // [/RLVa:KB] diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 4d07929ad1..f40d2a2809 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -61,9 +61,9 @@ enum ECameraPreset /** Current view when a preset is saved */ CAMERA_PRESET_CUSTOM, -// [RLVa:KB] - Checked: RLVa-2.0.0 +// [RLVa:KB] - @setcam_eyeoffset and @setcam_focusoffset /* Used by RLVa */ - CAMERA_RLV_SETCAM_VIEW + CAMERA_RLV_SETCAM_VIEW, // [/RLVa:KB] }; @@ -116,9 +116,17 @@ private: // Preset //-------------------------------------------------------------------- public: +// [RLVa:KB] - @setcam family + /** Determines default camera offset scale depending on the current camera preset */ + ECameraPreset getCameraPreset() const { return mCameraPreset; } +// [/RLVa:KB] void switchCameraPreset(ECameraPreset preset); /** Determines default camera offset depending on the current camera preset */ LLVector3 getCameraOffsetInitial(); +// [RLVa:KB] - @setcam_eyeoffsetscale + /** Determines default camera offset scale depending on the current camera preset */ + F32 getCameraOffsetScale() const; +// [/RLVa:KB] /** Determines default focus offset depending on the current camera preset */ LLVector3d getFocusOffsetInitial(); @@ -140,10 +148,24 @@ private: ECameraPreset mCameraPreset; /** Initial camera offset */ - LLPointer mCameraOffsetInitial; +// LLPointer mCameraOffsetInitial; +// [RLVa:KB] - @setcam_eyeoffset + // Renamed to catch their uses + LLPointer mCameraOffsetInitialControl; + LLPointer mRlvCameraOffsetInitialControl; +// [/RLVa:KB] + +// [RLVa:KB] - @setcam_eyeoffsetscale + LLPointer mRlvCameraOffsetScaleControl; +// [/RLVa:KB] /** Initial focus offset */ - LLPointer mFocusOffsetInitial; +// LLPointer mFocusOffsetInitial; +// [RLVa:KB] - @setcam_focusoffset + // Renamed to catch their uses + LLPointer mFocusOffsetInitialControl; + LLPointer mRlvFocusOffsetInitialControl; +// [/RLVa:KB] LLQuaternion mInitSitRot; diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 1b95a32a58..5949981b0f 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -457,6 +457,11 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht AISUpdate::parseUUIDArray(result, "_created_categories", ids); } break; + case UPDATECATEGORY: + { + AISUpdate::parseUUIDArray(result, "_updated_categories", ids); + } + break; default: break; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index df12c90883..51b9dcb9f1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -144,7 +144,6 @@ #include "llcoros.h" #include "llexception.h" //#if !LL_LINUX -#include "cef/dullahan.h" #include "cef/dullahan_version.h" #include "vlc/libvlc_version.h" //#endif // LL_LINUX @@ -165,7 +164,7 @@ #include "llapr.h" #include -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "lllfsthread.h" #include "llworkerthread.h" #include "lltexturecache.h" @@ -1180,15 +1179,28 @@ bool LLAppViewer::init() gGLManager.getGLInfo(gDebugInfo); gGLManager.printGLInfoString(); - // Load User's bindings - std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml"); - if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file)) + // Load Default bindings + // Optional AZERTY keyboard layout + //std::string key_bindings_file = gDirUtilp->findFile("keys.xml", + std::string keyBindingFileName("keys.xml"); + if (gSavedSettings.getBOOL("FSUseAzertyKeyboardLayout")) { - // Failed to load custom bindings, try default ones - key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml"); - if (!gViewerInput.loadBindingsXML(key_bindings_file)) + keyBindingFileName = "keys_azerty.xml"; + } + std::string key_bindings_file = gDirUtilp->findFile(keyBindingFileName, + // + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), + gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); + + + if (!gViewerKeyboard.loadBindingsXML(key_bindings_file)) + { + std::string key_bindings_file = gDirUtilp->findFile("keys.ini", + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), + gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); + if (!gViewerKeyboard.loadBindings(key_bindings_file)) { - LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; + LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL; } } @@ -1689,7 +1701,6 @@ bool LLAppViewer::doFrame() { joystick->scanJoystick(); gKeyboard->scanKeyboard(); - gViewerInput.scanMouse(); // Chalice Yao's crouch toggle static LLCachedControl fsCrouchToggle(gSavedPerAccountSettings, "FSCrouchToggle"); static LLCachedControl fsCrouchToggleStatus(gSavedPerAccountSettings, "FSCrouchToggleStatus"); @@ -3859,12 +3870,16 @@ LLSD LLAppViewer::getViewerInfo() const cef_ver_codec << "."; cef_ver_codec << DULLAHAN_VERSION_MINOR; cef_ver_codec << "."; + cef_ver_codec << DULLAHAN_VERSION_POINT; + cef_ver_codec << "."; cef_ver_codec << DULLAHAN_VERSION_BUILD; - cef_ver_codec << " / CEF: "; + cef_ver_codec << std::endl; + cef_ver_codec << " CEF: "; cef_ver_codec << CEF_VERSION; - cef_ver_codec << " / Chromium: "; + cef_ver_codec << std::endl; + cef_ver_codec << " Chromium: "; cef_ver_codec << CHROME_VERSION_MAJOR; cef_ver_codec << "."; cef_ver_codec << CHROME_VERSION_MINOR; @@ -6269,6 +6284,10 @@ void LLAppViewer::disconnectViewer() LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false); // [/SL:KB] +// [RLVa:KB] - Checked: RLVa-2.3 (Housekeeping) + SUBSYSTEM_CLEANUP(RlvHandler); +// [/RLVa:KB] + gAgentWearables.cleanup(); gAgentCamera.cleanup(); // Also writes cached agent settings to gSavedSettings diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 342ee3ccf5..a850d1bbda 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -33,6 +33,7 @@ #include "llagent.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewerregion.h" +#include "llviewernetwork.h" // for LLGridManager #include "llwlhandlers.h" #include "lltrans.h" #include "lltrace.h" @@ -65,6 +66,12 @@ #include "llviewergenericmessage.h" #include "llexperiencelog.h" +// [RLVa:KB] - Checked: RLVa-2.4 (@setenv) +#include "rlvactions.h" +// [/RLVa:KB] +#include "fscommon.h" +#include "llviewernetwork.h" + //========================================================================= namespace { @@ -821,6 +828,70 @@ LLEnvironment::LLEnvironment(): mShowMoonBeacon(false) { } +// OpenSim legacy Windlight setting support +#ifdef OPENSIM +void LLEnvironment::loadLegacyPresets() +{ + std::string path_name; + std::vector folders = { LL_PATH_APP_SETTINGS, LL_PATH_USER_SETTINGS }; + for (auto & settings_path : folders) + { + path_name = gDirUtilp->getExpandedFilename(settings_path , "windlight", "skies", ""); + bool found = true; + + while (found) + { + std::string name; + found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name); + if (found) + { + name = name.erase(name.length() - 4); + mLegacySkies.push_back(unescape_name(name)); + LL_DEBUGS("WindlightCaps") << "Added Legacy Sky: " << unescape_name(name) << LL_ENDL; + } + } + + path_name = gDirUtilp->getExpandedFilename(settings_path, "windlight", "water", ""); + found = true; + + while (found) + { + std::string name; + found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name); + if (found) + { + name = name.erase(name.length() - 4); + mLegacyWater.push_back(unescape_name(name)); + LL_DEBUGS("WindlightCaps") << "Added Legacy Water: " << unescape_name(name) << LL_ENDL; + } + } + + path_name = gDirUtilp->getExpandedFilename(settings_path, "windlight", "days", ""); + found = true; + + while (found) + { + std::string name; + found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name); + if (found) + { + name = name.erase(name.length() - 4); + mLegacyDayCycles.push_back(unescape_name(name)); + LL_DEBUGS("WindlightCaps") << "Added Legacy Day Cycle: " << unescape_name(name) << LL_ENDL; + } + } + } +} + +void LLEnvironment::loadUserPrefs() +{ + // operate on members directly to avoid side effects + mWaterPresetName = gSavedSettings.getString("WaterPresetName"); + mSkyPresetName = gSavedSettings.getString("SkyPresetName"); + mDayCycleName = gSavedSettings.getString("DayCycleName"); +} +#endif //opensim +// void LLEnvironment::initSingleton() { @@ -833,6 +904,16 @@ void LLEnvironment::initSingleton() mEnvironments[ENV_DEFAULT] = mCurrentEnvironment; + // OpenSim legacy Windlight setting support +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim()) + { + loadLegacyPresets(); + loadUserPrefs(); + } +#endif + // + requestRegion(); gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); @@ -1057,6 +1138,13 @@ bool LLEnvironment::getIsMoonUp() const //------------------------------------------------------------------------- void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LLSettingsBase::Seconds transition, bool forced) { +// [RLVa:KB] - Checked: RLVa-2.4 (@setenv) + if ( (!RlvActions::canChangeEnvironment()) && (LLEnvironment::ENV_EDIT != env) ) + { + return; + } +// [/RLVa:KB] + mSelectedEnvironment = env; updateEnvironment(transition, forced); } @@ -1221,7 +1309,7 @@ void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, if (!settings || status) { LLSD args; - args["DESC"] = asset_id.asString(); + args["NAME"] = asset_id.asString();// fix the args to match the template. LLNotificationsUtil::add("FailedToFindSettings", args); return; } @@ -1367,12 +1455,12 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f { if (transition != TRANSITION_INSTANT) { - DayInstance::ptr_t trans = std::make_shared( - mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition); - - trans->animate(); - - mCurrentEnvironment = trans; + DayInstance::ptr_t trans = std::make_shared( + mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition); + + trans->animate(); + + mCurrentEnvironment = trans; } else { @@ -1618,8 +1706,14 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI if (!envinfo->mDayCycle) { clearEnvironment(ENV_PARCEL); - setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); - updateEnvironment(); +// opensim legacy windlight. Nothing we can do here as the default assets do not exist in OpenSim + LL_WARNS("ENVIRONMENT") << "No DayCycle specified - setting default" << LL_ENDL; + if(LLGridManager::getInstance()->isInSecondLife()) + { + setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); + updateEnvironment(); + } +// } else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER) || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL)) @@ -2152,10 +2246,14 @@ LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extractLeg pinfo->mDayHash = pinfo->mDayCycle->getHash(); pinfo->mAltitudes[0] = 0; - pinfo->mAltitudes[2] = 10001; - pinfo->mAltitudes[3] = 10002; - pinfo->mAltitudes[4] = 10003; - +// Fix typos that offset this by 1. Shoudl get fixed in a merge from the lab soon. + // pinfo->mAltitudes[2] = 10001; + // pinfo->mAltitudes[3] = 10002; + // pinfo->mAltitudes[4] = 10003; + pinfo->mAltitudes[1] = 10001; + pinfo->mAltitudes[2] = 10002; + pinfo->mAltitudes[3] = 10003; +// return pinfo; } @@ -2361,7 +2459,7 @@ void LLEnvironment::onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettin if (!settings || status) { LLSD args; - args["DESC"] = experience_id.asString(); + args["NAME"] = experience_id.asString();// fix the args to match the template. LLNotificationsUtil::add("FailedToFindSettings", args); return; } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 91c4b85135..bbd0adaca8 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -374,6 +374,20 @@ private: experience_overrides_t mExperienceOverrides; DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false); +// opensim windlight setting +#ifdef OPENSIM +public: + std::vector mLegacySkies; + std::vector mLegacyWater; + std::vector mLegacyDayCycles; + std::string mWaterPresetName; + std::string mSkyPresetName; + std::string mDayCycleName; +private: + void loadLegacyPresets(); + void loadUserPrefs(); +#endif +// void updateCloudScroll(); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index f5b5a096fa..e35acf1dd2 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -45,6 +45,9 @@ #include "llhints.h" #include "lltabcontainer.h" #include "llvoavatarself.h" +// [RLVa:KB] - @setcam +#include "rlvactions.h" +// [/RLVa:KB] static LLDefaultChildRegistry::Register r("panel_camera_item"); @@ -626,6 +629,13 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) /*static*/ void LLFloaterCamera::switchToPreset(const std::string& name) { +// [RLVa:KB] - @setcam family + if (RlvActions::isCameraPresetLocked()) + { + return; + } +// [/RLVa:KB] + sFreeCamera = false; clear_camera_tool(); if (PRESETS_REAR_VIEW == name) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 98914b4581..d4bf02920c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -81,9 +81,8 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llviewercamera.h" -#include "llviewereventrecorder.h" -#include "llviewermessage.h" #include "llviewerwindow.h" +#include "llviewermessage.h" #include "llviewershadermgr.h" #include "llviewerthrottle.h" #include "llvoavatarself.h" @@ -121,7 +120,6 @@ #include "llweb.h" // [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) #include "rlvactions.h" -#include "rlvhandler.h" // [/RLVa:KB] #include "lllogininstance.h" // to check if logged in yet @@ -173,9 +171,9 @@ char const* const VISIBILITY_DEFAULT = "default"; char const* const VISIBILITY_HIDDEN = "hidden"; //control value for middle mouse as talk2push button -//const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability -//const static std::string MOUSE_BUTTON_4_CV = "MouseButton4"; -//const static std::string MOUSE_BUTTON_5_CV = "MouseButton5"; +const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability +const static std::string MOUSE_BUTTON_4_CV = "MouseButton4"; +const static std::string MOUSE_BUTTON_5_CV = "MouseButton5"; /// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled @@ -208,6 +206,87 @@ struct LabelTable : public LLInitParam::Block {} }; +class LLVoiceSetKeyDialog : public LLModalDialog +{ +public: + LLVoiceSetKeyDialog(const LLSD& key); + ~LLVoiceSetKeyDialog(); + + /*virtual*/ BOOL postBuild(); + + void setParent(LLFloaterPreference* parent) { mParent = parent; } + + BOOL handleKeyHere(KEY key, MASK mask); + BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); + static void onCancel(void* user_data); + +private: + LLFloaterPreference* mParent; +}; + +LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key) + : LLModalDialog(key), + mParent(NULL) +{ +} + +//virtual +BOOL LLVoiceSetKeyDialog::postBuild() +{ + childSetAction("Cancel", onCancel, this); + getChild("Cancel")->setFocus(TRUE); + + gFocusMgr.setKeystrokesOnly(TRUE); + + return TRUE; +} + +LLVoiceSetKeyDialog::~LLVoiceSetKeyDialog() +{ +} + +BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask) +{ + BOOL result = TRUE; + + if (key == 'Q' && mask == MASK_CONTROL) + { + result = FALSE; + } + else if (mParent) + { + mParent->setKey(key); + } + closeFloater(); + return result; +} + +BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) +{ + BOOL result = FALSE; + if (down + && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5) + && mask == 0) + { + mParent->setMouse(clicktype); + result = TRUE; + closeFloater(); + } + else + { + result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down); + } + + return result; +} + +//static +void LLVoiceSetKeyDialog::onCancel(void* user_data) +{ + LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data; + self->closeFloater(); +} + // global functions @@ -389,6 +468,37 @@ bool callback_pick_debug_search(const LLSD& notification, const LLSD& response) } // +/*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option && floater ) + { + if ( floater ) + { + floater->setAllIgnored(); + // LLFirstUse::disableFirstUse(); + floater->buildPopupLists(); + } + } + return false; +} + +bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( 0 == option && floater ) + { + if ( floater ) + { + floater->resetAllIgnored(); + //LLFirstUse::resetFirstUse(); + floater->buildPopupLists(); + } + } + return false; +} +*/ + void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator) { numerator = 0; @@ -413,7 +523,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mGotPersonalInfo(false), mOriginalIMViaEmail(false), mLanguageChanged(false), - mAvatarDataInitialized(false) + mAvatarDataInitialized(false), + mClickActionDirty(false) { LLConversationLog::instance().addObserver(this); @@ -422,7 +533,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) static bool registered_dialog = false; if (!registered_dialog) { - LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); registered_dialog = true; } @@ -441,6 +552,9 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this)); // mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2)); // mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this)); + mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this)); + mCommitCallbackRegistrar.add("Pref.VoiceSetClearKey", boost::bind(&LLFloaterPreference::onClickClearKey, this)); // FIRE-3803: Clear voice toggle button + mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this)); // Handled centrally now // mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this)); mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this)); @@ -473,8 +587,10 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) sSkin = gSavedSettings.getString("SkinCurrent"); - gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); - gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); + mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this)); + + gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); + gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2)); gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2)); gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged, _2)); @@ -960,6 +1076,12 @@ void LLFloaterPreference::apply() saveAvatarProperties(); + if (mClickActionDirty) + { + updateClickActionSettings(); + mClickActionDirty = false; + } + // Fix resetting graphics preset on cancel; Save preset here because cancel() gets called in either way! saveGraphicsPreset(gSavedSettings.getString("PresetGraphicActive")); } @@ -994,6 +1116,12 @@ void LLFloaterPreference::cancel() // reverts any changes to current skin //gSavedSettings.setString("SkinCurrent", sSkin); + if (mClickActionDirty) + { + updateClickActionControls(); + mClickActionDirty = false; + } + LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance("prefs_proxy"); if (advanced_proxy_settings) { @@ -1101,6 +1229,9 @@ void LLFloaterPreference::onOpen(const LLSD& key) onChangeTextureFolder(); onChangeSoundFolder(); onChangeAnimationFolder(); + + // Load (double-)click to walk/teleport settings. + updateClickActionControls(); // Load UI Sounds tabs settings. updateUISoundsControls(); @@ -2067,7 +2198,7 @@ void LLFloaterPreference::refreshEnabledState() LLComboBox* ctrl_reflections = getChild("Reflections"); // [RLVa:KB] - Checked: 2013-05-11 (RLVa-1.4.9) - if (rlv_handler_t::isEnabled()) + if (RlvActions::isRlvEnabled()) { getChild("do_not_disturb_response")->setEnabled(!RlvActions::hasBehaviour(RLV_BHVR_SENDIM)); } @@ -2121,11 +2252,11 @@ void LLFloaterPreference::refreshEnabledState() LLCheckBoxCtrl* ctrl_wind_light = getChild("WindLightUseAtmosShaders"); LLSliderCtrl* sky = getChild("SkyMeshDetail"); -// ctrl_wind_light->setEnabled(TRUE); // [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-0.2.0a // "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n - ctrl_wind_light->setEnabled((!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ); + ctrl_wind_light->setEnabled( (RlvActions::canChangeEnvironment()) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders"))); // [/RLVa:KB] +// ctrl_wind_light->setEnabled(TRUE); sky->setEnabled(TRUE); @@ -2216,11 +2347,11 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLCheckBoxCtrl* ctrl_wind_light = getChild("WindLightUseAtmosShaders"); LLSliderCtrl* sky = getChild("SkyMeshDetail"); LLTextBox* sky_text = getChild("SkyMeshDetailText"); -// ctrl_wind_light->setEnabled(TRUE); // [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-0.2.0a - // "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n - ctrl_wind_light->setEnabled(((!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) ); + // "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n + ctrl_wind_light->setEnabled( (RlvActions::canChangeEnvironment()) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders"))); // [/RLVa:KB] +// ctrl_wind_light->setEnabled(TRUE); sky->setEnabled(TRUE); sky_text->setEnabled(TRUE); @@ -2637,6 +2768,79 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data) refresh(); } +void LLFloaterPreference::onClickSetKey() +{ + LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance("voice_set_key", LLSD(), TRUE); + if (dialog) + { + dialog->setParent(this); + } +} + +// FIRE-3803: Clear voice toggle button +void LLFloaterPreference::onClickClearKey() +{ + gSavedSettings.setString("PushToTalkButton", ""); +} +// + +void LLFloaterPreference::setKey(KEY key) +{ + getChild("modifier_combo")->setValue(LLKeyboard::stringFromKey(key)); + // update the control right away since we no longer wait for apply + getChild("modifier_combo")->onCommit(); +} + +void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click) +{ + std::string bt_name; + std::string ctrl_value; + switch (click) + { + case LLMouseHandler::CLICK_MIDDLE: + bt_name = "middle_mouse"; + ctrl_value = MIDDLE_MOUSE_CV; + break; + case LLMouseHandler::CLICK_BUTTON4: + bt_name = "button4_mouse"; + ctrl_value = MOUSE_BUTTON_4_CV; + break; + case LLMouseHandler::CLICK_BUTTON5: + bt_name = "button5_mouse"; + ctrl_value = MOUSE_BUTTON_5_CV; + break; + default: + break; + } + + if (!ctrl_value.empty()) + { + LLUICtrl* p2t_line_editor = getChild("modifier_combo"); + // We are using text control names for readability and compatibility with voice + p2t_line_editor->setControlValue(ctrl_value); + // Fix crash "Failed to find string middle_mouse in panel Media Voice tab loaded from file" + //LLPanel* advanced_preferences = dynamic_cast(p2t_line_editor->getParent()); + LLPanel* advanced_preferences = dynamic_cast(p2t_line_editor->getParent()->getParent()->getParent()); + // + if (advanced_preferences) + { + p2t_line_editor->setValue(advanced_preferences->getString(bt_name)); + } + } +} + +void LLFloaterPreference::onClickSetMiddleMouse() +{ + LLUICtrl* p2t_line_editor = getChild("modifier_combo"); + + // update the control right away since we no longer wait for apply + p2t_line_editor->setControlValue(MIDDLE_MOUSE_CV); + + //push2talk button "middle mouse" control value is in English, need to localize it for presentation + LLPanel* audioPanel=getChild("audio"); + p2t_line_editor->setValue(audioPanel->getString("middle_mouse")); +} + // Handled centrally now /* void LLFloaterPreference::onClickSetSounds() @@ -2656,6 +2860,18 @@ void LLFloaterPreference::onClickPreviewUISound(const LLSD& ui_sound_id) } // FIRE-8190: Preview function for "UI Sounds" Panel +/* +void LLFloaterPreference::onClickSkipDialogs() +{ + LLNotificationsUtil::add("SkipShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_skip_dialogs, _1, _2, this)); +} + +void LLFloaterPreference::onClickResetDialogs() +{ + LLNotificationsUtil::add("ResetShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_reset_dialogs, _1, _2, this)); +} + */ + void LLFloaterPreference::onClickEnablePopup() { LLScrollListCtrl& disabled_popups = getChildRef("disabled_popups"); @@ -3279,6 +3495,11 @@ void LLFloaterPreference::onClickAdvanced() } } +void LLFloaterPreference::onClickActionChange() +{ + mClickActionDirty = true; +} + void LLFloaterPreference::onClickPermsDefault() { LLFloaterReg::showInstance("perms_default"); @@ -3316,6 +3537,26 @@ void LLFloaterPreference::onLogChatHistorySaved() } } +void LLFloaterPreference::updateClickActionSettings() +{ + const int single_clk_action = getChild("single_click_action_combo")->getValue().asInteger(); + const int double_clk_action = getChild("double_click_action_combo")->getValue().asInteger(); + + gSavedSettings.setBOOL("ClickToWalk", single_clk_action == 1); + gSavedSettings.setBOOL("DoubleClickAutoPilot", double_clk_action == 1); + gSavedSettings.setBOOL("DoubleClickTeleport", double_clk_action == 2); +} + +void LLFloaterPreference::updateClickActionControls() +{ + const bool click_to_walk = gSavedSettings.getBOOL("ClickToWalk"); + const bool dbl_click_to_walk = gSavedSettings.getBOOL("DoubleClickAutoPilot"); + const bool dbl_click_to_teleport = gSavedSettings.getBOOL("DoubleClickTeleport"); + + getChild("single_click_action_combo")->setValue((int)click_to_walk); + getChild("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk); +} + // Load UI Sounds tabs settings void LLFloaterPreference::updateUISoundsControls() { @@ -3604,6 +3845,24 @@ BOOL LLPanelPreference::postBuild() getChild("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized)); } + //////////////////////PanelAdvanced /////////////////// + if (hasChild("modifier_combo", TRUE)) + { + //localizing if push2talk button is set to middle mouse + std::string modifier_value = getChild("modifier_combo")->getValue().asString(); + if (MIDDLE_MOUSE_CV == modifier_value) + { + getChild("modifier_combo")->setValue(getString("middle_mouse")); + } + else if (MOUSE_BUTTON_4_CV == modifier_value) + { + getChild("modifier_combo")->setValue(getString("button4_mouse")); + } + else if (MOUSE_BUTTON_5_CV == modifier_value) + { + getChild("modifier_combo")->setValue(getString("button5_mouse")); + } + } // Panel Setup (Network) -WoLf if (hasChild("connection_port_enabled")) { @@ -4249,373 +4508,6 @@ void LLPanelPreferenceGraphics::setHardwareDefaults() LLPanelPreference::setHardwareDefaults(); } -//------------------------LLPanelPreferenceControls-------------------------------- -static LLPanelInjector t_pref_contrls("panel_preference_controls"); - -LLPanelPreferenceControls::LLPanelPreferenceControls() - :LLPanelPreference(), - mEditingColumn(-1), - mEditingMode(0) -{ - // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'. - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i); - } -} - -LLPanelPreferenceControls::~LLPanelPreferenceControls() -{ -} - -BOOL LLPanelPreferenceControls::postBuild() -{ - // populate list of controls - pControlsTable = getChild("controls_list"); - pKeyModeBox = getChild("key_mode"); - - pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this)); - pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this)); - getChild("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this)); - - return TRUE; -} - -void LLPanelPreferenceControls::regenerateControls() -{ - mEditingMode = pKeyModeBox->getValue().asInteger(); - mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode); - populateControlTable(); -} - -void LLPanelPreferenceControls::populateControlTable() -{ - pControlsTable->clearRows(); - pControlsTable->clearColumns(); - - std::string filename; - switch ((LLKeyConflictHandler::ESourceMode)mEditingMode) - { - case LLKeyConflictHandler::MODE_THIRD_PERSON: - case LLKeyConflictHandler::MODE_FIRST_PERSON: - case LLKeyConflictHandler::MODE_EDIT_AVATAR: - case LLKeyConflictHandler::MODE_SITTING: - filename = "control_table_contents.xml"; - break; - default: - // 'saved settings' mode doesn't have UI or actual settings yet - LL_INFOS() << "Unimplemented mode" << LL_ENDL; - return; - } - - LLXMLNodePtr xmlNode; - LLScrollListCtrl::Contents contents; - if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode)) - { - LL_WARNS() << "Failed to load " << filename << LL_ENDL; - return; - } - LLXUIParser parser; - parser.readXUI(xmlNode, contents, filename); - - if (!contents.validateBlock()) - { - return; - } - - for (LLInitParam::ParamIterator::const_iterator col_it = contents.columns.begin(); - col_it != contents.columns.end(); - ++col_it) - { - pControlsTable->addColumn(*col_it); - } - - LLScrollListCell::Params cell_params; - // init basic cell params - cell_params.font = LLFontGL::getFontSansSerif(); - cell_params.font_halign = LLFontGL::LEFT; - cell_params.column = ""; - cell_params.value = ""; - - - for (LLInitParam::ParamIterator::const_iterator row_it = contents.rows.begin(); - row_it != contents.rows.end(); - ++row_it) - { - std::string control = row_it->value.getValue().asString(); - if (!control.empty() && control != "menu_separator") - { - // At the moment 4 collumns are hardcoded - LLScrollListItem::Params item_params(*row_it); - bool enabled = mConflictHandler[mEditingMode].canAssignControl(control); - item_params.enabled.setValue(enabled); - cell_params.column = "lst_ctrl1"; - cell_params.value = mConflictHandler[mEditingMode].getControlString(control, 0); - item_params.columns.add(cell_params); - cell_params.column = "lst_ctrl2"; - cell_params.value = mConflictHandler[mEditingMode].getControlString(control, 1); - item_params.columns.add(cell_params); - cell_params.column = "lst_ctrl3"; - cell_params.value = mConflictHandler[mEditingMode].getControlString(control, 2); - item_params.columns.add(cell_params); - pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM); - } - else - { - pControlsTable->addRow(*row_it, EAddPosition::ADD_BOTTOM); - } - } -} - -// Just a workaround to not care about first separator before headers (we can start from random header) -void LLPanelPreferenceControls::addSeparator() -{ - if (pControlsTable->getItemCount() > 0) - { - pControlsTable->addSeparator(EAddPosition::ADD_BOTTOM); - } -} - -void LLPanelPreferenceControls::updateTable() -{ - mEditingControl.clear(); - std::vector list = pControlsTable->getAllData(); - for (S32 i = 0; i < list.size(); ++i) - { - std::string control = list[i]->getValue(); - if (!control.empty()) - { - LLScrollListCell* cell = list[i]->getColumn(1); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0)); - cell = list[i]->getColumn(2); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 1)); - cell = list[i]->getColumn(3); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 2)); - } - } - pControlsTable->deselectAllItems(); -} - -void LLPanelPreferenceControls::apply() -{ - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - if (mConflictHandler[i].hasUnsavedChanges()) - { - mConflictHandler[i].saveToSettings(); - } - } -} - -void LLPanelPreferenceControls::cancel() -{ - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - if (mConflictHandler[i].hasUnsavedChanges()) - { - mConflictHandler[i].clear(); - } - } - pControlsTable->clear(); -} - -void LLPanelPreferenceControls::saveSettings() -{ - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - if (mConflictHandler[i].hasUnsavedChanges()) - { - mConflictHandler[i].saveToSettings(); - mConflictHandler[i].clear(); - } - } - - S32 mode = pKeyModeBox->getValue().asInteger(); - if (mConflictHandler[mode].empty()) - { - regenerateControls(); - } -} - -void LLPanelPreferenceControls::resetDirtyChilds() -{ - regenerateControls(); -} - -void LLPanelPreferenceControls::onListCommit() -{ - LLScrollListItem* item = pControlsTable->getFirstSelected(); - if (item == NULL) - { - return; - } - - std::string control = item->getValue(); - - if (control.empty()) - { - pControlsTable->deselectAllItems(); - return; - } - - if (!mConflictHandler[mEditingMode].canAssignControl(control)) - { - pControlsTable->deselectAllItems(); - return; - } - - S32 cell_ind = item->getSelectedCell(); - if (cell_ind <= 0) - { - pControlsTable->deselectAllItems(); - return; - } - - // List does not tell us what cell was clicked, so we have to figure it out manually, but - // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues, - // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next, - // use coordinates from hover to calculate cell - - LLScrollListCell* cell = item->getColumn(cell_ind); - if (cell) - { - LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance("keybind_dialog", LLSD()); - if (dialog) - { - mEditingControl = control; - mEditingColumn = cell_ind; - dialog->setParent(this, pControlsTable, DEFAULT_KEY_FILTER); - - LLFloater* root_floater = gFloaterView->getParentFloater(this); - if (root_floater) - root_floater->addDependentFloater(dialog); - dialog->openFloater(); - dialog->setFocus(TRUE); - } - } - else - { - pControlsTable->deselectAllItems(); - } -} - -void LLPanelPreferenceControls::onModeCommit() -{ - mEditingMode = pKeyModeBox->getValue().asInteger(); - if (mConflictHandler[mEditingMode].empty()) - { - // opening for first time - mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode); - } - populateControlTable(); -} - -void LLPanelPreferenceControls::onRestoreDefaultsBtn() -{ - LLNotificationsUtil::add("PreferenceControlsDefaults", LLSD(), LLSD(), boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsResponse, this, _1, _2)); -} - -void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: // All - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - mConflictHandler[i].resetToDefaults(); - // Apply changes to viewer as 'temporary' - mConflictHandler[i].saveToSettings(true); - } - - updateTable(); - break; - case 1: // Current - mConflictHandler[mEditingMode].resetToDefaults(); - // Apply changes to viewer as 'temporary' - mConflictHandler[mEditingMode].saveToSettings(true); - - updateTable(); - break; - case 2: // Cancel - default: - //exit; - break; - } -} - -// todo: copy onSetKeyBind to interface and inherit from interface -bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes) -{ - if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl)) - { - return true; - } - - if ( mEditingColumn > 0) - { - if (all_modes) - { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - if (mConflictHandler[i].empty()) - { - mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i); - } - mConflictHandler[i].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true); - // Apply changes to viewer as 'temporary' - mConflictHandler[i].saveToSettings(true); - } - } - else - { - mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true); - // Apply changes to viewer as 'temporary' - mConflictHandler[mEditingMode].saveToSettings(true); - } - } - - updateTable(); - return true; -} - -void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes) -{ - if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl)) - { - return; - } - - if (mEditingColumn > 0) - { - if (all_modes) - { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - if (mConflictHandler[i].empty()) - { - mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i); - } - mConflictHandler[i].resetToDefault(mEditingControl, mEditingColumn - 1); - // Apply changes to viewer as 'temporary' - mConflictHandler[i].saveToSettings(true); - } - } - else - { - mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1); - // Apply changes to viewer as 'temporary' - mConflictHandler[mEditingMode].saveToSettings(true); - } - } - updateTable(); -} - -void LLPanelPreferenceControls::onCancelKeyBind() -{ - pControlsTable->deselectAllItems(); -} - LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key) : LLFloater(key) { diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 76b76da81b..bde0b39898 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -37,8 +37,6 @@ #include "llavatarpropertiesprocessor.h" #include "llconversationlog.h" #include "llsearcheditor.h" -#include "llsetkeybinddialog.h" -#include "llkeyconflict.h" #include "llaudioengine.h" // Output device selection @@ -47,9 +45,7 @@ class LLPanelPreference; class LLPanelLCD; class LLPanelDebug; class LLMessageSystem; -class LLComboBox; class LLScrollListCtrl; -class LLScrollListCell; class LLSliderCtrl; class LLSD; class LLTextBox; @@ -148,6 +144,12 @@ protected: // callback for local lights toggle void onLocalLightsEnable(); + // callback for commit in the "Single click on land" and "Double click on land" comboboxes. + void onClickActionChange(); + // updates click/double-click action settings depending on controls values + void updateClickActionSettings(); + // updates click/double-click action controls depending on values from settings.xml + void updateClickActionControls(); // updates UI Sounds controls depending on values from settings.xml void updateUISoundsControls(); @@ -164,6 +166,7 @@ protected: // Group Notices and chiclets location setting conversion BOOL => S32 void onShowGroupNoticesTopRightChanged(); + public: // This function squirrels away the current values of the controls so that // cancel() can restore them. @@ -192,6 +195,11 @@ public: void onClickBrowseSettingsDir(); void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata); void onSelectSkin(); + void onClickSetKey(); + void onClickClearKey(); // FIRE-3803: Clear voice toggle button + void setKey(KEY key); + void setMouse(LLMouseHandler::EClickType click); + void onClickSetMiddleMouse(); // void onClickSetSounds(); // Handled centrally now void onClickPreviewUISound(const LLSD& ui_sound_id); // FIRE-8190: Preview function for "UI Sounds" Panel void setPreprocInclude(); @@ -278,6 +286,7 @@ private: static std::string sSkin; notifications_map mNotificationOptions; + bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user. bool mGotPersonalInfo; bool mOriginalIMViaEmail; bool mLanguageChanged; @@ -387,44 +396,6 @@ private: LOG_CLASS(LLPanelPreferenceGraphics); }; -class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResponderInterface -{ - LOG_CLASS(LLPanelPreferenceControls); -public: - LLPanelPreferenceControls(); - virtual ~LLPanelPreferenceControls(); - - BOOL postBuild(); - - void apply(); - void cancel(); - void saveSettings(); - void resetDirtyChilds(); - - void onListCommit(); - void onModeCommit(); - void onRestoreDefaultsBtn(); - void onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response); - /*virtual*/ bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes); - /*virtual*/ void onDefaultKeyBind(bool all_modes); - /*virtual*/ void onCancelKeyBind(); - -private: - // reloads settings, discards current changes, updates table - void regenerateControls(); - - void populateControlTable(); - void addSeparator(); - void updateTable(); - - LLScrollListCtrl* pControlsTable; - LLComboBox *pKeyModeBox; - LLKeyConflictHandler mConflictHandler[LLKeyConflictHandler::MODE_COUNT]; - std::string mEditingControl; - S32 mEditingColumn; - S32 mEditingMode; -}; - class LLFloaterPreferenceGraphicsAdvanced : public LLFloater { public: diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0b9e2fe354..62e36a40ac 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -751,7 +751,6 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, (message.length() > 3) && (RLV_CMD_PREFIX == message[0]) && (RlvHandler::instance().processIMQuery(from_id, message)) ) { // Eat the message and do nothing - return; } // [/RLVa:KB] // else if (offline == IM_ONLINE @@ -1737,7 +1736,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, // If we auto-accept the offer/request then this will override DnD status (but we'll still let the other party know later) bool fRlvAutoAccept = (rlv_handler_t::isEnabled()) && ( ((IM_LURE_USER == dialog) && (RlvActions::autoAcceptTeleportOffer(from_id))) || - ((IM_TELEPORT_REQUEST == dialog) && (RlvActions::autoAcceptTeleportRequest(from_id))) ); + ((IM_TELEPORT_REQUEST == dialog) && (RlvActions::autoAcceptTeleportRequest(from_id))) ); // [/RLVa:KB] if (is_muted) @@ -1822,7 +1821,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, if (rlv_handler_t::isEnabled()) { if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) || - ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) ) + ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) ) { RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLUREREQ_REMOTE)); if (is_do_not_disturb) @@ -1832,7 +1831,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, // Censor message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer/request and @showloc=n restricted if ( (!RlvActions::canReceiveIM(from_id)) || - ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (IM_LURE_USER == dialog || IM_TELEPORT_REQUEST == dialog)) ) + ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (IM_LURE_USER == dialog || IM_TELEPORT_REQUEST == dialog)) ) { message = RlvStrings::getString(RLV_STRING_HIDDEN); } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 205a9f286f..f5ada6e12e 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -386,7 +386,10 @@ void update_all_marketplace_count() return; } -void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) +//void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) +// [RLVa:KB] - Checked: RLVa-2.3 (Give-to-#RLV) +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name, LLPointer cb) +// [/RLVa:KB] { LLViewerInventoryCategory* cat; @@ -400,7 +403,10 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s LLSD updates; updates["name"] = new_name; - update_inventory_category(cat_id, updates, NULL); +// [RLVa:KB] - Checked: RLVa-2.3 (Give-to-#RLV) + update_inventory_category(cat_id, updates, cb); +// [/RLVa:KB] +// update_inventory_category(cat_id, updates, NULL); } void copy_inventory_category(LLInventoryModel* model, diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 8f6f8f802e..becdb9a63c 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -72,7 +72,10 @@ void update_marketplace_category(const LLUUID& cat_id, bool perform_consistency_ // Nudge all listing categories to signal that their marketplace status changed void update_all_marketplace_count(); -void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); +// [RLVa:KB] - Checked: RLVa-2.3 (Give-to-#RLV) +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name, LLPointer cb = nullptr); +// [/RLVa:KB] +//void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null, bool move_no_copy_items = false); diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp deleted file mode 100644 index a94836c59d..0000000000 --- a/indra/newview/llkeyconflict.cpp +++ /dev/null @@ -1,852 +0,0 @@ -/** - * @file llkeyconflict.cpp - * @brief - * - * $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$ - */ - -/* - * App-wide preferences. Note that these are not per-user, - * because we need to load many preferences before we have - * a login name. - */ - -#include "llviewerprecompiledheaders.h" - -#include "llkeyconflict.h" - -#include "llinitparam.h" -#include "llkeyboard.h" -#include "lltrans.h" -#include "llviewercontrol.h" -#include "llviewerinput.h" -#include "llviewermenu.h" -#include "llxuiparser.h" - -static const std::string saved_settings_key_controls[] = { "placeholder" }; // add settings from gSavedSettings here - -static const std::string filename_default = "key_bindings.xml"; -static const std::string filename_temporary = "key_bindings_tmp.xml"; // used to apply uncommited changes on the go. - -// LLKeyboard::stringFromMask is meant for UI and is OS dependent, -// so this class uses it's own version -std::string string_from_mask(MASK mask) -{ - std::string res; - if ((mask & MASK_CONTROL) != 0) - { - res = "CTL"; - } - if ((mask & MASK_ALT) != 0) - { - if (!res.empty()) res += "_"; - res += "ALT"; - } - if ((mask & MASK_SHIFT) != 0) - { - if (!res.empty()) res += "_"; - res += "SHIFT"; - } - - if (mask == MASK_NONE) - { - res = "NONE"; - } - return res; -} - -std::string string_from_mouse(EMouseClickType click, bool translate) -{ - std::string res; - switch (click) - { - case CLICK_LEFT: - res = "LMB"; - break; - case CLICK_MIDDLE: - res = "MMB"; - break; - case CLICK_RIGHT: - res = "RMB"; - break; - case CLICK_BUTTON4: - res = "MB4"; - break; - case CLICK_BUTTON5: - res = "MB5"; - break; - case CLICK_DOUBLELEFT: - res = "Double LMB"; - break; - default: - break; - } - - if (translate && !res.empty()) - { - res = LLTrans::getString(res); - } - return res; -} - -// LLKeyConflictHandler - -S32 LLKeyConflictHandler::sTemporaryFileUseCount = 0; - -LLKeyConflictHandler::LLKeyConflictHandler() -: mHasUnsavedChanges(false), - mUsesTemporaryFile(false), - mLoadMode(MODE_COUNT) -{ -} - -LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode) -: mHasUnsavedChanges(false), - mUsesTemporaryFile(false), - mLoadMode(mode) -{ - loadFromSettings(mode); -} - -LLKeyConflictHandler::~LLKeyConflictHandler() -{ - clearUnsavedChanges(); - // Note: does not reset bindings if temporary file was used -} - -bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask) -{ - return mControlsMap[control_name].canHandle(mouse_ind, key, mask); -} - -bool LLKeyConflictHandler::canHandleKey(const std::string &control_name, KEY key, MASK mask) -{ - return canHandleControl(control_name, CLICK_NONE, key, mask); -} - -bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask) -{ - return canHandleControl(control_name, mouse_ind, KEY_NONE, mask); -} - -bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask) -{ - return canHandleControl(control_name, (EMouseClickType)mouse_ind, KEY_NONE, mask); -} - -bool LLKeyConflictHandler::canAssignControl(const std::string &control_name) -{ - control_map_t::iterator iter = mControlsMap.find(control_name); - if (iter != mControlsMap.end()) - { - return iter->second.mAssignable; - } - // If we don't know this control means it wasn't assigned by user yet and thus is editable - return true; -} - -// static -bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask) -{ - if (key == KEY_NONE) - { - return false; - } - return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask)); -} - -// static -bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data) -{ - if (data.mMouse != CLICK_NONE || data.mKey == KEY_NONE) - { - return false; - } - return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask)); -} - -bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) -{ - if (control_name.empty()) - { - return false; - } - LLKeyConflict &type_data = mControlsMap[control_name]; - if (!type_data.mAssignable) - { - LL_ERRS() << "Error in code, user or system should not be able to change certain controls" << LL_ENDL; - } - LLKeyData data(mouse, key, mask, ignore_mask); - if (type_data.mKeyBind.getKeyData(index) == data) - { - return true; - } - if (isReservedByMenu(data)) - { - return false; - } - if (removeConflicts(data, type_data.mConflictMask)) - { - type_data.mKeyBind.replaceKeyData(data, index); - mHasUnsavedChanges = true; - return true; - } - // control already in use/blocked - return false; -} - -LLKeyData LLKeyConflictHandler::getControl(const std::string &control_name, U32 index) -{ - if (control_name.empty()) - { - return LLKeyData(); - } - return mControlsMap[control_name].getKeyData(index); -} - -// static -std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata) -{ - std::string result; - - if (keydata.mMask != MASK_NONE && keydata.mKey != KEY_NONE) - { - result = LLKeyboard::stringFromAccelerator(keydata.mMask, keydata.mKey); - } - else if (keydata.mKey != KEY_NONE) - { - result = LLKeyboard::stringFromKey(keydata.mKey); - } - else if (keydata.mMask != MASK_NONE) - { - result = LLKeyboard::stringFromAccelerator(keydata.mMask); - } - - result += string_from_mouse(keydata.mMouse, true); - - return result; -} - -std::string LLKeyConflictHandler::getControlString(const std::string &control_name, U32 index) -{ - if (control_name.empty()) - { - return ""; - } - return getStringFromKeyData(mControlsMap[control_name].getKeyData(index)); -} - -void LLKeyConflictHandler::loadFromControlSettings(const std::string &name) -{ - LLControlVariablePtr var = gSavedSettings.getControl(name); - if (var) - { - LLKeyBind bind(var->getValue()); - LLKeyConflict key(bind, true, 0); - mControlsMap[name] = key; - } -} - -void LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination) -{ - for (LLInitParam::ParamIterator::const_iterator it = keymode.bindings.begin(), - end_it = keymode.bindings.end(); - it != end_it; - ++it) - { - KEY key; - MASK mask; - EMouseClickType mouse = CLICK_NONE; - if (it->mouse.isProvided()) - { - LLViewerInput::mouseFromString(it->mouse.getValue(), &mouse); - } - if (it->key.getValue().empty()) - { - key = KEY_NONE; - } - else - { - LLKeyboard::keyFromString(it->key, &key); - } - LLKeyboard::maskFromString(it->mask, &mask); - // Note: it->command is also the name of UI element, howhever xml we are loading from - // might not know all the commands, so UI will have to know what to fill by its own - LLKeyConflict &type_data = (*destination)[it->command]; - type_data.mAssignable = true; - type_data.mKeyBind.addKeyData(mouse, key, mask, true); - } -} - -bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination) -{ - if (filename.empty()) - { - return false; - } - - bool res = false; - - LLViewerInput::Keys keys; - LLSimpleXUIParser parser; - - if (parser.readXUI(filename, keys) - && keys.validateBlock()) - { - switch (load_mode) - { - case MODE_FIRST_PERSON: - if (keys.first_person.isProvided()) - { - loadFromSettings(keys.first_person, destination); - res = true; - } - break; - case MODE_THIRD_PERSON: - if (keys.third_person.isProvided()) - { - loadFromSettings(keys.third_person, destination); - res = true; - } - break; - case MODE_EDIT_AVATAR: - if (keys.edit_avatar.isProvided()) - { - loadFromSettings(keys.edit_avatar, destination); - res = true; - } - break; - case MODE_SITTING: - if (keys.sitting.isProvided()) - { - loadFromSettings(keys.sitting, destination); - res = true; - } - break; - default: - LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL; - break; - } - } - return res; -} - -void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode) -{ - mControlsMap.clear(); - mDefaultsMap.clear(); - - // E.X. In case we need placeholder keys for conflict resolution. - generatePlaceholders(load_mode); - - if (load_mode == MODE_SAVED_SETTINGS) - { - // load settings clss knows about, but it also possible to load settings by name separately - const S32 size = std::extent::value; - for (U32 i = 0; i < size; i++) - { - loadFromControlSettings(saved_settings_key_controls[i]); - } - } - else - { - // load defaults - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default); - if (!loadFromSettings(load_mode, filename, &mDefaultsMap)) - { - LL_WARNS() << "Failed to load default settings, aborting" << LL_ENDL; - return; - } - - // load user's - filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default); - if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap)) - { - // mind placeholders - mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); - } - } - mLoadMode = load_mode; -} - -void LLKeyConflictHandler::saveToSettings(bool temporary) -{ - if (mControlsMap.empty()) - { - return; - } - - if (mLoadMode == MODE_SAVED_SETTINGS) - { - // Does not support 'temporary', preferences handle that themself - // so in case of saved settings we just do not clear mHasUnsavedChanges - control_map_t::iterator iter = mControlsMap.begin(); - control_map_t::iterator end = mControlsMap.end(); - - for (; iter != end; ++iter) - { - if (iter->first.empty()) - { - continue; - } - - LLKeyConflict &key = iter->second; - key.mKeyBind.trimEmpty(); - if (!key.mAssignable) - { - continue; - } - - if (gSavedSettings.controlExists(iter->first)) - { - gSavedSettings.setLLSD(iter->first, key.mKeyBind.asLLSD()); - } - else if (!key.mKeyBind.empty()) - { - // Note: this is currently not in use, might be better for load mechanics to ask for and retain control group - // otherwise settings loaded from other control groups will end in this one - LL_INFOS() << "Creating new keybinding " << iter->first << LL_ENDL; - gSavedSettings.declareLLSD(iter->first, key.mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS); - } - } - } - else - { - // Determine what file to load and load full copy of that file - std::string filename; - - if (temporary) - { - filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary); - if (!gDirUtilp->fileExists(filename)) - { - filename.clear(); - } - } - - if (filename.empty()) - { - filename = gDirUtilp->findFile(filename_default, - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), - gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - } - - LLViewerInput::Keys keys; - LLSimpleXUIParser parser; - - if (parser.readXUI(filename, keys) - && keys.validateBlock()) - { - // replace category we edited - - // mode is a HACK to correctly reset bindings without reparsing whole file and avoid doing - // own param container (which will face issues with inasseesible members of LLInitParam) - LLViewerInput::KeyMode mode; - LLViewerInput::KeyBinding binding; - - control_map_t::iterator iter = mControlsMap.begin(); - control_map_t::iterator end = mControlsMap.end(); - for (; iter != end; ++iter) - { - // By default xml have (had) up to 6 elements per function - // eventually it will be cleaned up and UI will only shows 3 per function, - // so make sure to cleanup. - // Also this helps in keeping file small. - iter->second.mKeyBind.trimEmpty(); - U32 size = iter->second.mKeyBind.getDataCount(); - for (U32 i = 0; i < size; ++i) - { - if (iter->first.empty()) - { - continue; - } - - LLKeyConflict &key = iter->second; - key.mKeyBind.trimEmpty(); - if (key.mKeyBind.empty() || !key.mAssignable) - { - continue; - } - - LLKeyData data = key.mKeyBind.getKeyData(i); - // Still write empty LLKeyData to make sure we will maintain UI position - if (data.mKey == KEY_NONE) - { - // Might be better idea to be consistent and use NONE. LLViewerInput can work with both cases - binding.key = ""; - } - else - { - binding.key = LLKeyboard::stringFromKey(data.mKey, false /*Do not localize*/); - } - binding.mask = string_from_mask(data.mMask); - if (data.mMouse == CLICK_NONE) - { - binding.mouse.setProvided(false); - } - else - { - // set() because 'optional', for compatibility purposes - // just copy old keys.xml and rename to key_bindings.xml, it should work - binding.mouse.set(string_from_mouse(data.mMouse, false), true); - } - binding.command = iter->first; - mode.bindings.add(binding); - } - } - - switch (mLoadMode) - { - case MODE_FIRST_PERSON: - if (keys.first_person.isProvided()) - { - keys.first_person.bindings.set(mode.bindings, true); - } - break; - case MODE_THIRD_PERSON: - if (keys.third_person.isProvided()) - { - keys.third_person.bindings.set(mode.bindings, true); - } - break; - case MODE_EDIT_AVATAR: - if (keys.edit_avatar.isProvided()) - { - keys.edit_avatar.bindings.set(mode.bindings, true); - } - break; - case MODE_SITTING: - if (keys.sitting.isProvided()) - { - keys.sitting.bindings.set(mode.bindings, true); - } - break; - default: - LL_ERRS() << "Not implememted mode " << mLoadMode << LL_ENDL; - break; - } - - if (temporary) - { - // write to temporary xml and use it for gViewerInput - filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary); - if (!mUsesTemporaryFile) - { - mUsesTemporaryFile = true; - sTemporaryFileUseCount++; - } - } - else - { - // write back to user's xml and use it for gViewerInput - filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default); - // Don't reset mUsesTemporaryFile, it will be reset at cleanup stage - } - - LLXMLNodePtr output_node = new LLXMLNode("keys", false); - LLXUIParser parser; - parser.writeXUI(output_node, keys); - - // Write the resulting XML to file - if (!output_node->isNull()) - { - LLFILE *fp = LLFile::fopen(filename, "w"); - if (fp != NULL) - { - LLXMLNode::writeHeaderToFile(fp); - output_node->writeToFile(fp); - fclose(fp); - } - } - // Now force a rebind for keyboard - if (gDirUtilp->fileExists(filename)) - { - // Ideally instead of rebinding immediately we should shedule - // the rebind since single file can have multiple handlers, - // one per mode, saving simultaneously. - // Or whatever uses LLKeyConflictHandler should control the process. - gViewerInput.loadBindingsXML(filename); - } - } - } - - if (!temporary) - { - // will remove any temporary file if there were any - clearUnsavedChanges(); - } -} - -LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index) -{ - if (control_name.empty()) - { - return LLKeyData(); - } - if (mLoadMode == MODE_SAVED_SETTINGS) - { - LLControlVariablePtr var = gSavedSettings.getControl(control_name); - if (var) - { - return LLKeyBind(var->getDefault()).getKeyData(index); - } - return LLKeyData(); - } - else - { - control_map_t::iterator iter = mDefaultsMap.find(control_name); - if (iter != mDefaultsMap.end()) - { - return iter->second.mKeyBind.getKeyData(index); - } - return LLKeyData(); - } -} - -void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 index) -{ - if (control_name.empty()) - { - return; - } - LLKeyData data = getDefaultControl(control_name, index); - - if (data != mControlsMap[control_name].getKeyData(index)) - { - // reset controls that might have been switched to our current control - removeConflicts(data, mControlsMap[control_name].mConflictMask); - mControlsMap[control_name].setKeyData(data, index); - } -} - -void LLKeyConflictHandler::resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts) -{ - if (control_name.empty()) - { - return; - } - if (mLoadMode == MODE_SAVED_SETTINGS) - { - LLControlVariablePtr var = gSavedSettings.getControl(control_name); - if (var) - { - LLKeyBind bind(var->getDefault()); - if (!ignore_conflicts) - { - for (S32 i = 0; i < bind.getDataCount(); ++i) - { - removeConflicts(bind.getKeyData(i), mControlsMap[control_name].mConflictMask); - } - } - mControlsMap[control_name].mKeyBind = bind; - } - else - { - mControlsMap[control_name].mKeyBind.clear(); - } - } - else - { - control_map_t::iterator iter = mDefaultsMap.find(control_name); - if (iter != mDefaultsMap.end()) - { - if (!ignore_conflicts) - { - for (S32 i = 0; i < iter->second.mKeyBind.getDataCount(); ++i) - { - removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_name].mConflictMask); - } - } - mControlsMap[control_name].mKeyBind = iter->second.mKeyBind; - } - else - { - mControlsMap[control_name].mKeyBind.clear(); - } - } -} - -void LLKeyConflictHandler::resetToDefault(const std::string &control_name) -{ - // reset specific binding without ignoring conflicts - resetToDefaultAndResolve(control_name, false); -} - -void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) -{ - if (mode == MODE_SAVED_SETTINGS) - { - control_map_t::iterator iter = mControlsMap.begin(); - control_map_t::iterator end = mControlsMap.end(); - - for (; iter != end; ++iter) - { - resetToDefaultAndResolve(iter->first, true); - } - } - else - { - mControlsMap.clear(); - generatePlaceholders(mode); - mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); - } - - mHasUnsavedChanges = true; -} - -void LLKeyConflictHandler::resetToDefaults() -{ - if (!empty()) - { - resetToDefaults(mLoadMode); - } - else - { - // not optimal since: - // 1. We are not sure that mLoadMode was set - // 2. We are not sure if there are any changes in comparison to default - // 3. We are loading 'current' only to replace it - // but it is reliable and works Todo: consider optimizing. - loadFromSettings(mLoadMode); - resetToDefaults(mLoadMode); - } -} - -void LLKeyConflictHandler::clear() -{ - if (clearUnsavedChanges()) - { - // temporary file was removed, this means we were using it and need to reload keyboard's bindings - resetKeyboardBindings(); - } - mControlsMap.clear(); - mDefaultsMap.clear(); -} - -// static -void LLKeyConflictHandler::resetKeyboardBindings() -{ - // Try to load User's bindings first - std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default); - if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file)) - { - // Failed to load custom bindings, try default ones - key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default); - if (!gViewerInput.loadBindingsXML(key_bindings_file)) - { - LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; - } - } -} - -void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) -{ - // These controls are meant to cause conflicts when user tries to assign same control somewhere else - // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks - /*registerTemporaryControl(CONTROL_RESERVED_MENU, CLICK_RIGHT, KEY_NONE, MASK_NONE, 0); - registerTemporaryControl(CONTROL_DELETE, CLICK_NONE, KEY_DELETE, MASK_NONE, 0);*/ -} - -bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) -{ - if (conlict_mask == CONFLICT_NOTHING) - { - // Can't conflict - return true; - } - std::map conflict_list; - control_map_t::iterator cntrl_iter = mControlsMap.begin(); - control_map_t::iterator cntrl_end = mControlsMap.end(); - for (; cntrl_iter != cntrl_end; ++cntrl_iter) - { - S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); - if (index >= 0 - && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING - && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) - { - if (cntrl_iter->second.mAssignable) - { - // Potentially we can have multiple conflict flags conflicting - // including unassignable keys. - // So record the conflict and find all others before doing any changes. - // Assume that there is only one conflict per bind - conflict_list[cntrl_iter->first] = index; - } - else - { - return false; - } - } - } - - std::map::iterator cnflct_iter = conflict_list.begin(); - std::map::iterator cnflct_end = conflict_list.end(); - for (; cnflct_iter != cnflct_end; ++cnflct_iter) - { - mControlsMap[cnflct_iter->first].mKeyBind.resetKeyData(cnflct_iter->second); - } - return true; -} - -void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask) -{ - LLKeyConflict *type_data = &mControlsMap[control_name]; - type_data->mAssignable = false; - type_data->mConflictMask = conflict_mask; - type_data->mKeyBind.addKeyData(mouse, key, mask, false); -} - -bool LLKeyConflictHandler::clearUnsavedChanges() -{ - bool result = false; - mHasUnsavedChanges = false; - - if (mUsesTemporaryFile) - { - mUsesTemporaryFile = false; - sTemporaryFileUseCount--; - if (!sTemporaryFileUseCount) - { - result = clearTemporaryFile(); - } - // else: might be usefull to overwrite content of temp file with defaults - // but at the moment there is no such need - } - return result; -} - -//static -bool LLKeyConflictHandler::clearTemporaryFile() -{ - // At the moment single file needs five handlers (one per mode), so doing this - // will remove file for all hadlers - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary); - if (gDirUtilp->fileExists(filename)) - { - LLFile::remove(filename); - return true; - } - return false; -} - diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h deleted file mode 100644 index 84730e4d4f..0000000000 --- a/indra/newview/llkeyconflict.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file llkeyconflict.h - * @brief - * - * $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$ - */ - -#ifndef LL_LLKEYCONFLICT_H -#define LL_LLKEYCONFLICT_H - -#include "llkeybind.h" -#include "llviewerinput.h" - - -class LLKeyConflict -{ -public: - LLKeyConflict() : mAssignable(true), mConflictMask(U32_MAX) {} //temporary assignable, don't forget to change once all keys are recorded - LLKeyConflict(bool assignable, U32 conflict_mask) - : mAssignable(assignable), mConflictMask(conflict_mask) {} - LLKeyConflict(const LLKeyBind &bind, bool assignable, U32 conflict_mask) - : mAssignable(assignable), mConflictMask(conflict_mask), mKeyBind(bind) {} - - LLKeyData getPrimaryKeyData() { return mKeyBind.getKeyData(0); } - LLKeyData getKeyData(U32 index) { return mKeyBind.getKeyData(index); } - void setPrimaryKeyData(const LLKeyData& data) { mKeyBind.replaceKeyData(data, 0); } - void setKeyData(const LLKeyData& data, U32 index) { mKeyBind.replaceKeyData(data, index); } - bool canHandle(EMouseClickType mouse, KEY key, MASK mask) { return mKeyBind.canHandle(mouse, key, mask); } - - LLKeyBind mKeyBind; - bool mAssignable; // whether user can change key or key simply acts as placeholder - U32 mConflictMask; -}; - -class LLKeyConflictHandler -{ -public: - - enum ESourceMode // partially repeats e_keyboard_mode - { - MODE_FIRST_PERSON, - MODE_THIRD_PERSON, - MODE_EDIT_AVATAR, - MODE_SITTING, - MODE_SAVED_SETTINGS, // for settings from saved settings - MODE_COUNT - }; - - const U32 CONFLICT_NOTHING = 0; - // at the moment this just means that key will conflict with everything that is identical - const U32 CONFLICT_ANY = U32_MAX; - - // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel) - - LLKeyConflictHandler(); - LLKeyConflictHandler(ESourceMode mode); - ~LLKeyConflictHandler(); - - bool canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask); - bool canHandleKey(const std::string &control_name, KEY key, MASK mask); - bool canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask); - bool canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask); //Just for convinience - bool canAssignControl(const std::string &control_name); - static bool isReservedByMenu(const KEY &key, const MASK &mask); - static bool isReservedByMenu(const LLKeyData &data); - bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts? - - LLKeyData getControl(const std::string &control_name, U32 data_index); - - // localized string - static std::string getStringFromKeyData(const LLKeyData& keydata); - std::string getControlString(const std::string &control_name, U32 data_index); - - // Load single control, overrides existing one if names match - void loadFromControlSettings(const std::string &name); - // Drops any changes loads controls with ones from 'saved settings' or from xml - void loadFromSettings(ESourceMode load_mode); - - // Saves settings to 'saved settings' or to xml - // If 'temporary' is set, function will save settings to temporary - // file and reload input bindings from temporary file. - // 'temporary' does not support gSavedSettings, those are handled - // by preferences, so 'temporary' is such case will simply not - // reset mHasUnsavedChanges - void saveToSettings(bool apply_temporary = false); - - LLKeyData getDefaultControl(const std::string &control_name, U32 data_index); - // Resets keybinding to default variant from 'saved settings' or xml - void resetToDefault(const std::string &control_name, U32 index); - void resetToDefault(const std::string &control_name); - // resets current mode to defaults - void resetToDefaults(); - - bool empty() { return mControlsMap.empty(); } - void clear(); - - // reloads bindings from last valid user's xml or from default xml - // to keyboard's handler - static void resetKeyboardBindings(); - - bool hasUnsavedChanges() { return mHasUnsavedChanges; } - void setLoadMode(ESourceMode mode) { mLoadMode = mode; } - ESourceMode getLoadMode() { return mLoadMode; } - -private: - void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts); - void resetToDefaults(ESourceMode mode); - - // at the moment these kind of control is not savable, but takes part will take part in conflict resolution - void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); - - typedef std::map control_map_t; - void loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination); - bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination); - void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values - // returns false in case user is trying to reuse control that can't be reassigned - bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask); - - // removes flags and removes temporary file, returns 'true' if file was removed - bool clearUnsavedChanges(); - // return true if there was a file to remove - static bool clearTemporaryFile(); - - control_map_t mControlsMap; - control_map_t mDefaultsMap; - bool mHasUnsavedChanges; - ESourceMode mLoadMode; - - // To implement 'apply immediately'+revert on cancel, class applies changes to temporary file - // but this only works for settings from keybndings files (key_bindings.xml) - // saved setting rely onto external mechanism of preferences floater - bool mUsesTemporaryFile; - static S32 sTemporaryFileUseCount; -}; - - -#endif // LL_LLKEYCONFLICT_H diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 9cbda7bbba..40f4bb9981 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2703,6 +2703,10 @@ void LLPanelObject::onCopyRot(const LLSD& data) void LLPanelObject::onPastePos(const LLSD& data) { if(!mHasPosClipboard) return; + if (mObject.isNull()) return; + + LLViewerRegion* regionp = mObject->getRegion(); + if (!regionp) return; //clamp pos on non-attachments, just keep the prims on the sim if (!mObject->isAttachment()) @@ -2710,8 +2714,8 @@ void LLPanelObject::onPastePos(const LLSD& data) // Aurora Sim //mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], 0.f, 256.f); //mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], 0.f, 256.f); - mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], 0.f, gAgent.getRegion()->getWidth()); - mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], 0.f, gAgent.getRegion()->getWidth()); + mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], 0.f, regionp->getWidth()); + mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], 0.f, regionp->getWidth()); // Aurora Sim //height will get properly clammed by sendPosition } diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 535ae1c37d..7b1fd81683 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -834,8 +834,32 @@ void LLPanelPrimMediaControls::draw() BOOL LLPanelPrimMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks) { - mInactivityTimer.start(); - return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); + mInactivityTimer.start(); + BOOL res = FALSE; + + // Unlike other mouse events, we need to handle scroll here otherwise + // it will be intercepted by camera and won't reach toolpie + if (LLViewerMediaFocus::getInstance()->isHoveringOverFocused()) + { + // either let toolpie handle this or expose mHoverPick.mUVCoords in some way + res = LLToolPie::getInstance()->handleScrollWheel(x, y, clicks); + } + + return res; +} + +BOOL LLPanelPrimMediaControls::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + mInactivityTimer.start(); + BOOL res = FALSE; + + if (LLViewerMediaFocus::getInstance()->isHoveringOverFocused()) + { + // either let toolpie handle this or expose mHoverPick.mUVCoords in some way + res = LLToolPie::getInstance()->handleScrollHWheel(x, y, clicks); + } + + return res; } BOOL LLPanelPrimMediaControls::handleMouseDown(S32 x, S32 y, MASK mask) diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 6256ce8411..86fc036553 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -48,6 +48,7 @@ public: /*virtual*/ BOOL postBuild(); virtual void draw(); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 67fc72e284..9feaab50e2 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -340,12 +340,12 @@ void LLPreviewNotecard::loadAsset() { editor->setEnabled(FALSE); getChildView("lock")->setVisible( TRUE); + getChildView("Edit")->setEnabled(FALSE); // Don't enable external editor button on no mod notecards. } if((allow_modify || is_owner) && !source_library) { getChildView("Delete")->setEnabled(TRUE); - getChildView("Edit")->setEnabled(FALSE); // Don't enable external editor button on no mod notecards. } } else diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 4994dd6500..2cf2d62dfc 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -463,7 +463,10 @@ void LLProgressView::initLogos() const S32 default_height = 28; const S32 default_pad = 15; - S32 icon_width, icon_height; + S32 icon_width; +#if defined(LL_FMODSTUDIO) || defined(LL_HAVOK) + S32 icon_height; +#endif // defined(LL_FMODSTUDIO) || defined(LL_HAVOK) // We don't know final screen rect yet, so we can't precalculate position fully LLTextBox *logos_label = getChild("logos_lbl"); diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp deleted file mode 100644 index 4eb76c9d89..0000000000 --- a/indra/newview/llsetkeybinddialog.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/** - * @file llsetkeybinddialog.cpp - * @brief LLSetKeyBindDialog class implementation. - * - * $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 "llviewerprecompiledheaders.h" - -#include "llsetkeybinddialog.h" - -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "lleventtimer.h" -#include "llfloaterreg.h" -#include "llfocusmgr.h" -#include "llkeyconflict.h" -#include "llviewercontrol.h" - -class LLSetKeyBindDialog::Updater : public LLEventTimer -{ -public: - - typedef boost::function callback_t; - - Updater(callback_t cb, F32 period, MASK mask) - :LLEventTimer(period), - mMask(mask), - mCallback(cb) - { - mEventTimer.start(); - } - - virtual ~Updater(){} - -protected: - BOOL tick() - { - mCallback(mMask); - // Deletes itseft after execution - return TRUE; - } - -private: - MASK mMask; - callback_t mCallback; -}; - -bool LLSetKeyBindDialog::sRecordKeys = false; - -LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key) - : LLModalDialog(key), - pParent(NULL), - mKeyFilterMask(DEFAULT_KEY_FILTER), - pUpdater(NULL), - mContextConeOpacity(0.f), - mContextConeInAlpha(0.f), - mContextConeOutAlpha(0.f), - mContextConeFadeTime(0.f) -{ - mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); - mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); - mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); -} - -LLSetKeyBindDialog::~LLSetKeyBindDialog() -{ -} - -//virtual -BOOL LLSetKeyBindDialog::postBuild() -{ - childSetAction("SetEmpty", onBlank, this); - childSetAction("Default", onDefault, this); - childSetAction("Cancel", onCancel, this); - getChild("Cancel")->setFocus(TRUE); - - pCheckBox = getChild("apply_all"); - pDesription = getChild("descritption"); - - gFocusMgr.setKeystrokesOnly(TRUE); - - return TRUE; -} - -//virtual -void LLSetKeyBindDialog::onOpen(const LLSD& data) -{ - sRecordKeys = true; - LLModalDialog::onOpen(data); -} - -//virtual -void LLSetKeyBindDialog::onClose(bool app_quiting) -{ - sRecordKeys = false; - if (pParent) - { - pParent->onCancelKeyBind(); - pParent = NULL; - } - if (pUpdater) - { - // Doubleclick timer has't fired, delete it - delete pUpdater; - pUpdater = NULL; - } - LLModalDialog::onClose(app_quiting); -} - -void LLSetKeyBindDialog::drawFrustum() -{ - static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); - drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha); -} - -//virtual -void LLSetKeyBindDialog::draw() -{ - drawFrustum(); - LLModalDialog::draw(); -} - -void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask) -{ - pParent = parent; - mFrustumOrigin = frustum_origin->getHandle(); - mKeyFilterMask = key_mask; - - std::string input; - if ((key_mask & ALLOW_MOUSE) != 0) - { - input = getString("mouse"); - } - if ((key_mask & ALLOW_KEYS) != 0) - { - if (!input.empty()) - { - input += ", "; - } - input += getString("keyboard"); - } - pDesription->setText(getString("basic_description")); - pDesription->setTextArg("[INPUT]", input); -} - -// static -bool LLSetKeyBindDialog::recordKey(KEY key, MASK mask) -{ - if (sRecordKeys) - { - LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance("keybind_dialog", LLSD()); - if (dialog && dialog->getVisible()) - { - return dialog->recordAndHandleKey(key, mask); - } - else - { - LL_WARNS() << "Key recording was set despite no open dialog" << LL_ENDL; - sRecordKeys = false; - } - } - return false; -} - -bool LLSetKeyBindDialog::recordAndHandleKey(KEY key, MASK mask) -{ - if ((key == 'Q' && mask == MASK_CONTROL) - || key == KEY_ESCAPE) - { - sRecordKeys = false; - closeFloater(); - return true; - } - - if (key == KEY_DELETE) - { - setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); - sRecordKeys = false; - closeFloater(); - return false; - } - - // forbidden keys - if (key == KEY_NONE - || key == KEY_RETURN - || key == KEY_BACKSPACE) - { - return false; - } - - if ((mKeyFilterMask & ALLOW_MASKS) == 0 - && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT)) - { - // mask by themself are not allowed - return false; - } - else if ((mKeyFilterMask & ALLOW_KEYS) == 0) - { - // basic keys not allowed - return false; - } - else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0) - { - // masked keys not allowed - return false; - } - - if (LLKeyConflictHandler::isReservedByMenu(key, mask)) - { - pDesription->setText(getString("reserved_by_menu")); - pDesription->setTextArg("[KEYSTR]", LLKeyboard::stringFromAccelerator(mask,key)); - return true; - } - - setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); - sRecordKeys = false; - closeFloater(); - return true; -} - -BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) -{ - BOOL result = FALSE; - if (!pParent) - { - // we already processed 'down' event, this is 'up', consume - closeFloater(); - result = TRUE; - } - if (!result && clicktype == CLICK_LEFT) - { - // try handling buttons first - if (down) - { - result = LLView::handleMouseDown(x, y, mask); - } - else - { - result = LLView::handleMouseUp(x, y, mask); - } - if (result) - { - setFocus(TRUE); - gFocusMgr.setKeystrokesOnly(TRUE); - } - // ignore selection related combinations - else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0) - { - // this can be a double click, wait a bit; - if (!pUpdater) - { - // Note: default doubleclick time is 500ms, but can stretch up to 5s - pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask); - result = TRUE; - } - } - } - - if (!result - && (clicktype != CLICK_LEFT) // subcases were handled above - && ((mKeyFilterMask & ALLOW_MOUSE) != 0) - && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported - && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection - { - setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); - result = TRUE; - if (!down) - { - // wait for 'up' event before closing - // alternative: set pUpdater - closeFloater(); - } - } - - return result; -} - -//static -void LLSetKeyBindDialog::onCancel(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onBlank(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - // tmp needs 'no key' button - self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onDefault(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - if (self->pParent) - { - self->pParent->onDefaultKeyBind(self->pCheckBox->getValue().asBoolean()); - self->pParent = NULL; - } - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - - // timer will delete itself after timeout - self->pUpdater = NULL; - - self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean()); - self->closeFloater(); -} - -void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes) -{ - if (pParent) - { - pParent->onSetKeyBind(click, key, mask, all_modes); - pParent = NULL; - } -} - diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h deleted file mode 100644 index 70190230e4..0000000000 --- a/indra/newview/llsetkeybinddialog.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file llsetkeybinddialog.h - * @brief LLSetKeyBindDialog class definition - * - * $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$ - */ - - -#ifndef LL_LLSETKEYBINDDIALOG_H -#define LL_LLSETKEYBINDDIALOG_H - -#include "llmodaldialog.h" - -class LLCheckBoxCtrl; -class LLTextBase; - -// Filters for LLSetKeyBindDialog -static const U32 ALLOW_MOUSE = 1; -static const U32 ALLOW_MASK_MOUSE = 2; -static const U32 ALLOW_KEYS = 4; //keyboard -static const U32 ALLOW_MASK_KEYS = 8; -static const U32 ALLOW_MASKS = 16; -static const U32 DEFAULT_KEY_FILTER = ALLOW_MOUSE | ALLOW_MASK_MOUSE | ALLOW_KEYS | ALLOW_MASK_KEYS; - - -class LLKeyBindResponderInterface -{ -public: - virtual ~LLKeyBindResponderInterface() {}; - - virtual void onCancelKeyBind() = 0; - virtual void onDefaultKeyBind(bool all_modes) = 0; - // returns true if parent failed to set key due to key being in use - virtual bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes) = 0; -}; - -class LLSetKeyBindDialog : public LLModalDialog -{ -public: - LLSetKeyBindDialog(const LLSD& key); - ~LLSetKeyBindDialog(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& data); - /*virtual*/ void onClose(bool app_quiting); - /*virtual*/ void draw(); - - void setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask = DEFAULT_KEY_FILTER); - - // Wrapper around recordAndHandleKey - // It does not record, it handles, but handleKey function is already in use - static bool recordKey(KEY key, MASK mask); - - BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); - static void onCancel(void* user_data); - static void onBlank(void* user_data); - static void onDefault(void* user_data); - static void onClickTimeout(void* user_data, MASK mask); - - class Updater; - -private: - bool recordAndHandleKey(KEY key, MASK mask); - void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes); - LLKeyBindResponderInterface *pParent; - LLCheckBoxCtrl *pCheckBox; - LLTextBase *pDesription; - - U32 mKeyFilterMask; - Updater *pUpdater; - - static bool sRecordKeys; // for convinience and not to check instance each time - - // drawFrustum -private: - void drawFrustum(); - - LLHandle mFrustumOrigin; - F32 mContextConeOpacity; - F32 mContextConeInAlpha; - F32 mContextConeOutAlpha; - F32 mContextConeFadeTime; -}; - - -#endif // LL_LLSETKEYBINDDIALOG_H diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 1e839a106f..844434681f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1005,7 +1005,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) } LLSpatialGroup* group = drawablep->getSpatialGroup(); - //llassert(group != NULL); + llassert(group != NULL); if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 553ba4831c..2299dc9c5f 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1251,6 +1251,7 @@ bool idle_startup() show_debug_menus(); // Hide the splash screen + LL_DEBUGS("AppInit") << "Hide the splash screen and show window" << LL_ENDL; LLSplashScreen::hide(); // Push our window frontmost gViewerWindow->getWindow()->show(); @@ -1258,9 +1259,12 @@ bool idle_startup() // DEV-16927. The following code removes errant keystrokes that happen while the window is being // first made visible. #ifdef _WIN32 + LL_DEBUGS("AppInit") << "Processing PeekMessage" << LL_ENDL; MSG msg; while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ) - { } + { + } + LL_DEBUGS("AppInit") << "PeekMessage processed" << LL_ENDL; #endif display_startup(); timeout.reset(); diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index 5235914c34..c5e31ff8e6 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -60,7 +60,7 @@ LLTool::~LLTool() } } -BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) +BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) { BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down); @@ -83,9 +83,9 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) LL_INFOS() << "LLTool left mouse down" << LL_ENDL; } // by default, didn't handle it - // AGENT_CONTROL_LBUTTON_DOWN is handled by scanMouse() and scanKey() // LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL; - return FALSE; + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + return TRUE; } BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask) @@ -95,8 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask) LL_INFOS() << "LLTool left mouse up" << LL_ENDL; } // by default, didn't handle it - // AGENT_CONTROL_LBUTTON_UP is handled by scanMouse() and scanKey() // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); return TRUE; } diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h index 41a38804ce..308983afda 100644 --- a/indra/newview/lltool.h +++ b/indra/newview/lltool.h @@ -49,7 +49,7 @@ public: virtual BOOL isView() const { return FALSE; } // Virtual functions inherited from LLMouseHandler - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 122180731d..76d2e3f9d2 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -39,7 +39,7 @@ #include "llagentcamera.h" #include "llbutton.h" #include "llviewercontrol.h" -#include "llviewerinput.h"// Mouse movement by Singularity +#include "llviewerkeyboard.h"// Mouse movement by Singularity #include "lldrawable.h" #include "lltooltip.h" #include "llhudmanager.h" diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 088b157a76..fc7658d48b 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -92,6 +92,7 @@ LLToolPie::LLToolPie() mMouseOutsideSlop( false ), mMouseSteerX(-1), mMouseSteerY(-1), + mBlockClickToWalk(false), mClickAction(0), mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ), mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ), @@ -99,7 +100,7 @@ LLToolPie::LLToolPie() { } -BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) +BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down) { BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down); @@ -186,8 +187,10 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mPick.mKeyMask = mask; mMouseButtonDown = true; + + handleLeftClickPick(); - return handleLeftClickPick(); + return TRUE; } // Spawn context menus on right mouse down so you can drag over and select @@ -218,14 +221,31 @@ BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask) return LLTool::handleRightMouseUp(x, y, mask); } +BOOL LLToolPie::handleScrollWheelAny(S32 x, S32 y, S32 clicks_x, S32 clicks_y) +{ + BOOL res = FALSE; + // mHoverPick should have updated on its own and we should have a face + // in LLViewerMediaFocus in case of media, so just reuse mHoverPick + if (mHoverPick.mUVCoords.mV[VX] >= 0.f && mHoverPick.mUVCoords.mV[VY] >= 0.f) + { + res = LLViewerMediaFocus::getInstance()->handleScrollWheel(mHoverPick.mUVCoords, clicks_x, clicks_y); + } + else + { + // this won't provide correct coordinates in case of object selection + res = LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks_x, clicks_y); + } + return res; +} + BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks) { - return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); + return handleScrollWheelAny(x, y, 0, clicks); } BOOL LLToolPie::handleScrollHWheel(S32 x, S32 y, S32 clicks) { - return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); + return handleScrollWheelAny(x, y, clicks, 0); } // True if you selected an object. @@ -397,6 +417,8 @@ BOOL LLToolPie::handleLeftClickPick() // put focus back "in world" if (gFocusMgr.getKeyboardFocus()) { + // don't click to walk on attempt to give focus to world + mBlockClickToWalk = true; gFocusMgr.setKeyboardFocus(NULL); } @@ -452,7 +474,10 @@ BOOL LLToolPie::handleLeftClickPick() } object = (LLViewerObject*)object->getParent(); } + // FIRE-15189: Fix ClickToWalk not allowing mouse-walk (behavior change) + //if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk")) if (object && object == gAgentAvatarp) + // { // we left clicked on avatar, switch to focus mode mMouseButtonDown = false; @@ -470,6 +495,7 @@ BOOL LLToolPie::handleLeftClickPick() // LLFirstUse::useLeftClickNoHit(); ///////// + // Eat the event return LLTool::handleMouseDown(x, y, mask); } @@ -581,113 +607,17 @@ void LLToolPie::resetSelection() mClickAction = 0; } -bool LLToolPie::walkToClickedLocation() +void LLToolPie::walkToClickedLocation() { - if (gAgent.getFlying() // don't auto-navigate while flying until that works - || !gAgentAvatarp - || gAgentAvatarp->isSitting()) - { - return false; - } + if(mAutoPilotDestination) { mAutoPilotDestination->markDead(); } + mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE); + mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal); + mAutoPilotDestination->setPixelSize(5); + mAutoPilotDestination->setColor(LLColor4U(170, 210, 190)); + mAutoPilotDestination->setDuration(3.f); - LLPickInfo saved_pick = mPick; - mPick = gViewerWindow->pickImmediate(mHoverPick.mMousePt.mX, mHoverPick.mMousePt.mY, - FALSE /* ignore transparent */, - FALSE /* ignore rigged */, - FALSE /* ignore particles */); - - if (mPick.mPickType == LLPickInfo::PICK_OBJECT) - { - if (mPick.getObject() && mPick.getObject()->isHUDAttachment()) - { - mPick = saved_pick; - return false; - } - } - - LLViewerObject* avatar_object = mPick.getObject(); - - // get pointer to avatar - while (avatar_object && !avatar_object->isAvatar()) - { - avatar_object = (LLViewerObject*)avatar_object->getParent(); - } - - if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) - { - const F64 SELF_CLICK_WALK_DISTANCE = 3.0; - // pretend we picked some point a bit in front of avatar - mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; - } - - if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || - (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero())) - { -// [RLVa:KB] - Checked: RLVa-2.0.0 - if (RlvActions::isRlvEnabled() && !RlvActions::canTeleportToLocal(mPick.mPosGlobal)) - { - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_AUTOPILOT); - mPick = saved_pick; - return false; - } -// [/RLVa:KB] - - gAgentCamera.setFocusOnAvatar(TRUE, TRUE); - - if (mAutoPilotDestination) { mAutoPilotDestination->markDead(); } - mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE); - mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal); - mAutoPilotDestination->setPixelSize(5); - mAutoPilotDestination->setColor(LLColor4U(170, 210, 190)); - mAutoPilotDestination->setDuration(3.f); - - LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; - gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE); - LLFirstUse::notMoving(false); - showVisualContextMenuEffect(); - return true; - } - else - { - LL_DEBUGS() << "walk target was " - << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero") - << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land") - << ", pick object was " << mPick.mObjectID - << LL_ENDL; - mPick = saved_pick; - return false; - } - return true; -} - -bool LLToolPie::teleportToClickedLocation() -{ - LLViewerObject* objp = mHoverPick.getObject(); - LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; - - bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment(); - bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND; - bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero(); - bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch()); - bool has_click_action = final_click_action(objp); - - if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action))) - { -// [RLVa:KB] - Checked: RLVa-2.0.0 - if (RlvActions::isRlvEnabled() && !RlvActions::canTeleportToLocal(mPick.mPosGlobal)) - { - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_AUTOPILOT); - return false; - } -// [/RLVa:KB] - LLVector3d pos = mHoverPick.mPosGlobal; - pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot(); - gAgent.teleportViaLocationLookAt(pos); - mPick = mHoverPick; - showVisualContextMenuEffect(); - return true; - } - return false; + LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; + gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE); } // When we get object properties after left-clicking on an object @@ -771,7 +701,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL; } else if (!mMouseOutsideSlop - && mMouseButtonDown) + && mMouseButtonDown + && gSavedSettings.getBOOL("ClickToWalk")) { S32 delta_x = x - mMouseDownX; S32 delta_y = y - mMouseDownY; @@ -869,10 +800,84 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) mDoubleClickTimer.reset(); } LLViewerObject* obj = mPick.getObject(); + U8 click_action = final_click_action(obj); + // let media have first pass at click + if (handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus()) + { + mBlockClickToWalk = true; + } stopCameraSteering(); mMouseButtonDown = false; + if (click_action == CLICK_ACTION_NONE // not doing 1-click action + && gSavedSettings.getBOOL("ClickToWalk") // click to walk enabled + && !gAgent.getFlying() // don't auto-navigate while flying until that works + && gAgentAvatarp + && !gAgentAvatarp->isSitting() + && !mBlockClickToWalk // another behavior hasn't cancelled click to walk + ) + { + // We may be doing click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore rigged */, + FALSE /* ignore particles */); + +// if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick +// && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land +// || mPick.mObjectID.notNull())) // or on an object +// [RLVa:KB] - Checked: RLVa-2.0.0 + bool fValidPick = (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick + && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land + || mPick.mObjectID.notNull())); // or on an object + + if ( (fValidPick) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTeleportToLocal(mPick.mPosGlobal)) ) + { + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_AUTOPILOT); + fValidPick = false; + } + + if (fValidPick) +// [/RLVa:KB] + { + + // handle special cases of steering picks + LLViewerObject* avatar_object = mPick.getObject(); + + // get pointer to avatar + while (avatar_object && !avatar_object->isAvatar()) + { + avatar_object = (LLViewerObject*)avatar_object->getParent(); + } + + if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) + { + const F64 SELF_CLICK_WALK_DISTANCE = 3.0; + // pretend we picked some point a bit in front of avatar + mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; + } + gAgentCamera.setFocusOnAvatar(TRUE, TRUE); + walkToClickedLocation(); + LLFirstUse::notMoving(false); + + return TRUE; + } + else + { + LL_DEBUGS("maint5901") << "walk target was " + << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero") + << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land") + << ", pick object was " << mPick.mObjectID + << LL_ENDL; + // we didn't click to walk, so restore the original target + mPick = savedPick; + } + } gViewerWindow->setCursor(UI_CURSOR_ARROW); if (hasMouseCapture()) { @@ -882,6 +887,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) LLToolMgr::getInstance()->clearTransientTool(); gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on + mBlockClickToWalk = false; return LLTool::handleMouseUp(x, y, mask); } @@ -907,13 +913,78 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } - if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f)) + if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f)) { mDoubleClickTimer.stop(); return FALSE; } mDoubleClickTimer.stop(); + if (gSavedSettings.getBOOL("DoubleClickAutoPilot")) + { + // We may be doing double click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore rigged */, + FALSE /* ignore particles */); + + if(mPick.mPickType == LLPickInfo::PICK_OBJECT) + { + if (mPick.getObject() && mPick.getObject()->isHUDAttachment()) + { + mPick = savedPick; + return FALSE; + } + } + +// if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || +// (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero())) +// [RLVa:KB] - Checked: RLVa-2.0.0 + bool fValidPick = ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || + (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero())); + + if ( (fValidPick) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTeleportToLocal(mPick.mPosGlobal)) ) + { + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_AUTOPILOT); + fValidPick = false; + } + + if (fValidPick) +// [/RLVa:KB] + { + walkToClickedLocation(); + return TRUE; + } + else + { + // restore the original pick for any other purpose + mPick = savedPick; + } + } + else if (gSavedSettings.getBOOL("DoubleClickTeleport")) + { + LLViewerObject* objp = mPick.getObject(); + LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; + + bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment(); + bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND; + bool pos_non_zero = !mPick.mPosGlobal.isExactlyZero(); + bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch()); + bool has_click_action = final_click_action(objp); + + if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action))) + { + LLVector3d pos = mPick.mPosGlobal; + pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot(); + gAgent.teleportViaLocationLookAt(pos); + return TRUE; + } + } + return FALSE; } @@ -1671,6 +1742,7 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info) void LLToolPie::handleSelect() { // tool is reselected when app gets focus, etc. + mBlockClickToWalk = true; } void LLToolPie::handleDeselect() @@ -1735,7 +1807,7 @@ void LLToolPie::stopCameraSteering() bool LLToolPie::inCameraSteerMode() { - return mMouseButtonDown && mMouseOutsideSlop; + return mMouseButtonDown && mMouseOutsideSlop && gSavedSettings.getBOOL("ClickToWalk"); } // true if x,y outside small box around start_x,start_y @@ -2319,6 +2391,7 @@ void LLToolPie::startCameraSteering() { LLFirstUse::notMoving(false); mMouseOutsideSlop = true; + mBlockClickToWalk = true; if (gAgentCamera.getFocusOnAvatar()) { diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index c18fb4e1d1..34640d7f9c 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -42,13 +42,14 @@ class LLToolPie : public LLTool, public LLSingleton public: // Virtual functions inherited from LLMouseHandler - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + BOOL handleScrollWheelAny(S32 x, S32 y, S32 clicks_x, S32 clicks_y); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleToolTip(S32 x, S32 y, MASK mask); @@ -70,8 +71,8 @@ public: LLViewerObject* getClickActionObject() { return mClickActionObject; } LLObjectSelection* getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; } void resetSelection(); - bool walkToClickedLocation(); - bool teleportToClickedLocation(); + void walkToClickedLocation(); + void blockClickToWalk() { mBlockClickToWalk = true; } void stopClickToWalk(); static void selectionPropertiesReceived(); @@ -120,6 +121,7 @@ private: LLPointer mAutoPilotDestination; LLPointer mMouseSteerGrabPoint; bool mClockwise; + bool mBlockClickToWalk; LLUUID mMediaMouseCaptureID; LLPickInfo mPick; LLPickInfo mHoverPick; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 1ca052e28f..0ec2df9831 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -79,6 +79,7 @@ #include "llslurl.h" #include "llstartup.h" // [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0) +#include "rlvactions.h" #include "rlvcommon.h" // [/RLVa:KB] @@ -98,7 +99,7 @@ #include "llnotificationsutil.h" #include "llpanelplaces.h" #include "llstatusbar.h" -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "NACLantispam.h" @@ -211,6 +212,15 @@ static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue) bool handleSetShaderChanged(const LLSD& newvalue) // { +// [RLVa:KB] - @setenv + if ( (!RlvActions::canChangeEnvironment()) && (LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")) && (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ) + { + gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); + return true; + } +// [/RLVa:KB] + + // changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache gBumpImageList.destroyGL(); gBumpImageList.restoreGL(); @@ -827,6 +837,23 @@ void handleUsernameFormatOptionChanged(const LLSD& newvalue) } // +// Allow instant change of keyboard layout +void handleKeyboardLayoutChanged(const LLSD& newvalue) +{ + std::string keyBindingFileName("keys.xml"); + if (newvalue.asBoolean()) + { + keyBindingFileName = "keys_azerty.xml"; + } + + std::string key_bindings_file = gDirUtilp->findFile(keyBindingFileName, + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), + gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); + + gViewerKeyboard.loadBindingsXML(key_bindings_file); +} +// + // Global online status toggle void handleGlobalOnlineStatusChanged(const LLSD& newvalue) { @@ -1170,6 +1197,8 @@ void settings_setup_listeners() gSavedSettings.getControl("FSNameTagShowLegacyUsernames")->getCommitSignal()->connect(boost::bind(&handleUsernameFormatOptionChanged, _2)); gSavedSettings.getControl("FSTrimLegacyNames")->getCommitSignal()->connect(boost::bind(&handleLegacyTrimOptionChanged, _2)); + gSavedSettings.getControl("FSUseAzertyKeyboardLayout")->getCommitSignal()->connect(boost::bind(&handleKeyboardLayoutChanged, _2)); + // [FS communication UI] gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2)); gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ecdb041ee0..40b2c68e85 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -279,6 +279,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (gWindowResized) { //skip render on frames where window has been resized + LL_DEBUGS("Window") << "Resizing window" << LL_ENDL; LL_RECORD_BLOCK_TIME(FTM_RESIZE_WINDOW); gGL.flush(); glClear(GL_COLOR_BUFFER_BIT); diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp deleted file mode 100644 index ac2cd799a5..0000000000 --- a/indra/newview/llviewerinput.cpp +++ /dev/null @@ -1,1619 +0,0 @@ -/** - * @file llviewerinput.cpp - * @brief LLViewerInput class implementation - * - * $LicenseInfo:firstyear=2005&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$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewerinput.h" - -#include "llappviewer.h" -#include "llfloaterreg.h" -#include "llmath.h" -#include "llagent.h" -#include "llagentcamera.h" -// [FS Communication UI] -// #include "llfloaterimnearbychat.h" -#include "fsnearbychathub.h" -#include "lllineeditor.h" -// [FS Communication UI] -#include "llfocusmgr.h" -#include "llkeybind.h" // LLKeyData -#include "llmorphview.h" -#include "llmoveview.h" -#include "lltoolfocus.h" -#include "lltoolpie.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llvoavatarself.h" -#include "llfloatercamera.h" -#include "llinitparam.h" -#include "llselectmgr.h" -#include "llfloaterwebcontent.h" -#include "fsfloatersearch.h" -#include "llvoiceclient.h" - -// -// Constants -// - -const F32 FLY_TIME = 0.5f; -const F32 FLY_FRAMES = 4; - -const F32 NUDGE_TIME = 0.25f; // in seconds -const S32 NUDGE_FRAMES = 2; -const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed - -const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true); - -struct LLKeyboardActionRegistry -: public LLRegistrySingleton, LLKeyboardActionRegistry> -{ - LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); -}; - -LLViewerInput gViewerInput; - -bool agent_jump( EKeystate s ) -{ - static BOOL first_fly_attempt(TRUE); - if (KEYSTATE_UP == s) - { - first_fly_attempt = TRUE; - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - // Chalice Yao's crouch toggle - if (gSavedPerAccountSettings.getBOOL("FSCrouchToggleStatus")) - { - gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", FALSE); - } - // - - if( time < FLY_TIME - || frame_count <= FLY_FRAMES - || gAgent.upGrabbed() - || !gSavedSettings.getBOOL("AutomaticFly")) - { - gAgent.moveUp(1); - } - else - { - gAgent.setFlying(TRUE, first_fly_attempt); - first_fly_attempt = FALSE; - gAgent.moveUp(1); - } - return true; -} - -bool agent_push_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - // Chalice Yao's crouch toggle - //gAgent.moveUp(-1); - else if (KEYSTATE_DOWN == s && !gAgent.getFlying() && !gAgentAvatarp->isSitting() && gSavedPerAccountSettings.getBOOL("FSCrouchToggle")) - { - if (gSavedPerAccountSettings.getBOOL("FSCrouchToggleStatus")) - { - gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", FALSE); - } - else - { - gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", TRUE); - gAgent.moveUp(-1); - } - } - else - { - gAgent.moveUp(-1); - } - // - return true; -} - -static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode) -{ -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) ) - gAgent.clearTempRun(); -// [/RLVa:KB] -// if (gAgent.mDoubleTapRunMode == mode && -// gAgent.getRunning() && -// !gAgent.getAlwaysRun()) -// { -// // Turn off temporary running. -// gAgent.clearRunning(); -// gAgent.sendWalkRun(gAgent.getRunning()); -// } -} - -static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode) -{ - if (KEYSTATE_UP == s) - { - // Note: in case shift is already released, slide left/right run - // will be released in agent_turn_left()/agent_turn_right() - agent_check_temporary_run(mode); - } - else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") && - KEYSTATE_DOWN == s && - !gAgent.getRunning()) - { - if (gAgent.mDoubleTapRunMode == mode && - gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME) - { - // Same walk-key was pushed again quickly; this is a - // double-tap so engage temporary running. -// gAgent.setRunning(); -// gAgent.sendWalkRun(gAgent.getRunning()); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.setTempRun(); -// [/RLVa:KB] - } - - // Pressing any walk-key resets the double-tap timer - gAgent.mDoubleTapRunTimer.reset(); - gAgent.mDoubleTapRunMode = mode; - } -} - -static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) -{ - agent_handle_doubletap_run(s, mode); - if (KEYSTATE_UP == s) return; - - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) - { - gAgent.moveAtNudge(direction); - } - else - { - gAgent.moveAt(direction); - } -} - -bool camera_move_forward( EKeystate s ); - -bool agent_push_forward( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_move_forward(s); - } - else - { - agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); - } - return true; -} - -bool camera_move_backward( EKeystate s ); - -bool agent_push_backward( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_move_backward(s); - } - else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook")) - { - gAgentCamera.changeCameraToThirdPerson(); - } - else - { - agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); - } - return true; -} - -static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) -{ - agent_handle_doubletap_run(s, mode); - if( KEYSTATE_UP == s ) return; - F32 time = gKeyboard->getCurKeyElapsedTime(); - S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); - - if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) - { - gAgent.moveLeftNudge(direction); - } - else - { - gAgent.moveLeft(direction); - } -} - - -bool agent_slide_left( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); - return true; -} - - -bool agent_slide_right( EKeystate s ) -{ - if(gAgent.isMovementLocked()) return true; - agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); - return true; -} - -bool camera_spin_around_cw( EKeystate s ); - -bool agent_turn_left(EKeystate s) -{ - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_spin_around_cw(s); - return true; - } - - if(gAgent.isMovementLocked()) return false; - - if (LLToolCamera::getInstance()->mouseSteerMode()) - { - agent_slide_left(s); - } - else - { - if (KEYSTATE_UP == s) - { - // Check temporary running. In case user released 'left' key with shift already released. - agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT); - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); - } - return true; -} - -bool camera_spin_around_ccw( EKeystate s ); - -bool agent_turn_right( EKeystate s ) -{ - //in free camera control mode we need to intercept keyboard events for avatar movements - if (LLFloaterCamera::inFreeCameraMode()) - { - camera_spin_around_ccw(s); - return true; - } - - if(gAgent.isMovementLocked()) return false; - - if (LLToolCamera::getInstance()->mouseSteerMode()) - { - agent_slide_right(s); - } - else - { - if (KEYSTATE_UP == s) - { - // Check temporary running. In case user released 'right' key with shift already released. - agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT); - return true; - } - F32 time = gKeyboard->getCurKeyElapsedTime(); - gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); - } - return true; -} - -bool agent_look_up( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgent.movePitch(-1); - //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); - return true; -} - - -bool agent_look_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgent.movePitch(1); - //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); - return true; -} - -bool agent_toggle_fly( EKeystate s ) -{ - // Only catch the edge - if (KEYSTATE_DOWN == s ) - { - LLAgent::toggleFlying(); - } - return true; -} - -F32 get_orbit_rate() -{ - F32 time = gKeyboard->getCurKeyElapsedTime(); - if( time < NUDGE_TIME ) - { - F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; - //LL_INFOS() << rate << LL_ENDL; - return rate; - } - else - { - return 1; - } -} - -bool camera_spin_around_ccw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - return true; -} - - -bool camera_spin_around_cw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - return true; -} - -bool camera_spin_around_ccw_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true; - if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) - { - //send keystrokes, but do not change camera - agent_turn_right(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.unlockView(); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_around_cw_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true; - if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) - { - //send keystrokes, but do not change camera - agent_turn_left(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.unlockView(); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_over( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - return true; -} - - -bool camera_spin_under( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - return true; -} - -bool camera_spin_over_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) - { - //send keystrokes, but do not change camera - agent_jump(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - } - return true; -} - - -bool camera_spin_under_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) - { - //send keystrokes, but do not change camera - agent_push_down(s); - } - else - { - //change camera but do not send keystrokes - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - } - return true; -} - -bool camera_move_forward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - return true; -} - - -bool camera_move_backward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - return true; -} - -bool camera_move_forward_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true; - if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) - { - agent_push_forward(s); - } - else - { - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - } - return true; -} - -bool camera_move_backward_sitting( EKeystate s ) -{ - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true; - - if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) - { - agent_push_backward(s); - } - else - { - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - } - return true; -} - -bool camera_pan_up( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanUpKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_down( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanDownKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_left( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanLeftKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_right( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanRightKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_in( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanInKey( get_orbit_rate() ); - return true; -} - -bool camera_pan_out( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setPanOutKey( get_orbit_rate() ); - return true; -} - -bool camera_move_forward_fast( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitInKey(2.5f); - return true; -} - -bool camera_move_backward_fast( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gAgentCamera.unlockView(); - gAgentCamera.setOrbitOutKey(2.5f); - return true; -} - - -bool edit_avatar_spin_ccw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); - //gMorphView->orbitLeft( get_orbit_rate() ); - return true; -} - - -bool edit_avatar_spin_cw( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitRightKey( get_orbit_rate() ); - //gMorphView->orbitRight( get_orbit_rate() ); - return true; -} - -bool edit_avatar_spin_over( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitUpKey( get_orbit_rate() ); - //gMorphView->orbitUp( get_orbit_rate() ); - return true; -} - - -bool edit_avatar_spin_under( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitDownKey( get_orbit_rate() ); - //gMorphView->orbitDown( get_orbit_rate() ); - return true; -} - -bool edit_avatar_move_forward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitInKey( get_orbit_rate() ); - //gMorphView->orbitIn(); - return true; -} - - -bool edit_avatar_move_backward( EKeystate s ) -{ - if( KEYSTATE_UP == s ) return true; - gMorphView->setCameraDrivenByKeys( TRUE ); - gAgentCamera.setOrbitOutKey( get_orbit_rate() ); - //gMorphView->orbitOut(); - return true; -} - -bool stop_moving( EKeystate s ) -{ - if( KEYSTATE_DOWN != s ) return true; - // stop agent - gAgent.setControlFlags(AGENT_CONTROL_STOP); - - // cancel autopilot - gAgent.stopAutoPilot(); - return true; -} - -bool start_chat( EKeystate s ) -{ - if (LLAppViewer::instance()->quitRequested()) - { - return true; // can't talk, gotta go, kthxbye! - } - if (KEYSTATE_DOWN != s) return true; - - // start chat - // [FS Communication UI] - //LLFloaterIMNearbyChat::startChat(NULL); - FSNearbyChat::instance().showDefaultChatBar(TRUE); - // [FS Communication UI] - return true; -} - -bool start_gesture( EKeystate s ) -{ - // If avatar is pointing at something, don't start gesture. - // This works around the bug with Shared Media prims. - if (gAgentCamera.mPointAtObject) - { - return true; - } - - // FIRE-4167: Don't start gesture if a floater with web content has focus - LLFloater* focused_floater = gFloaterView->getFocusedFloater(); - if (focused_floater && (dynamic_cast(focused_floater) || dynamic_cast(focused_floater))) - { - return true; - } - - LLUICtrl* focus_ctrlp = dynamic_cast(gFocusMgr.getKeyboardFocus()); - if (KEYSTATE_UP == s && - ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) - { - // [FS Communication UI] - //if ((LLFloaterReg::getTypedInstance("nearby_chat"))->getCurrentChat().empty()) - //{ - // // No existing chat in chat editor, insert '/' - // LLFloaterIMNearbyChat::startChat("/"); - //} - //else - //{ - // // Don't overwrite existing text in chat editor - // LLFloaterIMNearbyChat::startChat(NULL); - //} - - FSNearbyChat::instance().showDefaultChatBar(TRUE, "/"); - // [FS Communication UI] - } - return true; -} - -bool run_forward(EKeystate s) -{ - if (KEYSTATE_UP != s) - { - if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD) - { - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_FORWARD; - } - if (!gAgent.getRunning()) - { -// gAgent.setRunning(); -// gAgent.sendWalkRun(true); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.setTempRun(); -// [/RLVa:KB] - } - } - else if(KEYSTATE_UP == s) - { - if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_FORWARD) - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE; -// gAgent.clearRunning(); -// gAgent.sendWalkRun(false); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.clearTempRun(); -// [/RLVa:KB] - } - agent_push_forward(s); - return true; -} - -bool run_backward(EKeystate s) -{ - if (KEYSTATE_UP != s) - { - if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD) - { - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_BACKWARD; - } - if (!gAgent.getRunning()) - { -// gAgent.setRunning(); -// gAgent.sendWalkRun(true); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.setTempRun(); -// [/RLVa:KB] - } - } - else if (KEYSTATE_UP == s) - { - if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_BACKWARD) - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE; -// gAgent.clearRunning(); -// gAgent.sendWalkRun(false); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.clearTempRun(); -// [/RLVa:KB] - } - agent_push_backward(s); - return true; -} - -bool run_left(EKeystate s) -{ - if (KEYSTATE_UP != s) - { - if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT) - { - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDELEFT; - } - if (!gAgent.getRunning()) - { -// gAgent.setRunning(); -// gAgent.sendWalkRun(true); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.setTempRun(); -// [/RLVa:KB] - } - } - else if (KEYSTATE_UP == s) - { - if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDELEFT) - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE; -// gAgent.clearRunning(); -// gAgent.sendWalkRun(false); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.clearTempRun(); -// [/RLVa:KB] - } - agent_slide_left(s); - return true; -} - -bool run_right(EKeystate s) -{ - if (KEYSTATE_UP != s) - { - if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT) - { - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDERIGHT; - } - if (!gAgent.getRunning()) - { -// gAgent.setRunning(); -// gAgent.sendWalkRun(true); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.setTempRun(); -// [/RLVa:KB] - } - } - else if (KEYSTATE_UP == s) - { - if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDERIGHT) - gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE; -// gAgent.clearRunning(); -// gAgent.sendWalkRun(false); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i - gAgent.clearTempRun(); -// [/RLVa:KB] - } - agent_slide_right(s); - return true; -} - -bool toggle_run(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - bool run = gAgent.getAlwaysRun(); - if (run) - { - gAgent.clearAlwaysRun(); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i -// gAgent.clearRunning(); -// [/RLVa:KB] - } - else - { - gAgent.setAlwaysRun(); -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i -// gAgent.setRunning(); -// [/RLVa:KB] - } -// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i -// gAgent.sendWalkRun(!run); -// [/RLVa:KB] - return true; -} - -bool toggle_sit(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - if (gAgent.isSitting()) - { - gAgent.standUp(); - } - else - { - gAgent.sitDown(); - } - return true; -} - -bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar -{ - if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying(); - LLViewerMedia::getInstance()->setAllMediaPaused(pause); - return true; -} - -bool toggle_enable_media(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying() || LLViewerMedia::getInstance()->isAnyMediaShowing(); - LLViewerMedia::getInstance()->setAllMediaEnabled(!pause); - return true; -} - -bool walk_to(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - return LLToolPie::getInstance()->walkToClickedLocation(); -} - -bool teleport_to(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - return LLToolPie::getInstance()->teleportToClickedLocation(); -} - -bool toggle_voice(EKeystate s) -{ - if (KEYSTATE_DOWN != s) return true; - if (!LLAgent::isActionAllowed("speak")) return false; - LLVoiceClient::getInstance()->toggleUserPTTState(); - return true; -} - -bool voice_follow_key(EKeystate s) -{ - if (KEYSTATE_DOWN == s) - { - if (!LLAgent::isActionAllowed("speak")) return false; - LLVoiceClient::getInstance()->setUserPTTState(true); - return true; - } - else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState()) - { - LLVoiceClient::getInstance()->setUserPTTState(false); - return true; - } - return false; -} - -bool agen_control_lbutton_handle(EKeystate s) -{ - switch (s) - { - case KEYSTATE_DOWN: - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); - break; - case KEYSTATE_UP: - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); - break; - default: - break; - } - return true; -} - -#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); -REGISTER_KEYBOARD_ACTION("jump", agent_jump); -REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); -REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward); -REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward); -REGISTER_KEYBOARD_ACTION("look_up", agent_look_up); -REGISTER_KEYBOARD_ACTION("look_down", agent_look_down); -REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly); -REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left); -REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right); -REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left); -REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right); -REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw); -REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw); -REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting); -REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting); -REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over); -REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under); -REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting); -REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting); -REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward); -REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward); -REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting); -REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting); -REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up); -REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down); -REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left); -REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right); -REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in); -REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out); -REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast); -REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over); -REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under); -REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward); -REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward); -REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); -REGISTER_KEYBOARD_ACTION("start_chat", start_chat); -REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); -REGISTER_KEYBOARD_ACTION("run_forward", run_forward); -REGISTER_KEYBOARD_ACTION("run_backward", run_backward); -REGISTER_KEYBOARD_ACTION("run_left", run_left); -REGISTER_KEYBOARD_ACTION("run_right", run_right); -REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run); -REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit); -REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); -REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media); -REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to); -REGISTER_KEYBOARD_ACTION("walk_to", walk_to); -REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice); -REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key); -#undef REGISTER_KEYBOARD_ACTION - -LLViewerInput::LLViewerInput() -{ - resetBindings(); - - for (S32 i = 0; i < KEY_COUNT; i++) - { - mKeyHandledByUI[i] = FALSE; - } - for (S32 i = 0; i < CLICK_COUNT; i++) - { - mMouseLevel[i] = MOUSE_STATE_SILENT; - } - // we want the UI to never see these keys so that they can always control the avatar/camera - for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) - { - mKeysSkippedByUI.insert(k); - } -} - -// static -BOOL LLViewerInput::modeFromString(const std::string& string, S32 *mode) -{ - if (string == "FIRST_PERSON") - { - *mode = MODE_FIRST_PERSON; - return TRUE; - } - else if (string == "THIRD_PERSON") - { - *mode = MODE_THIRD_PERSON; - return TRUE; - } - else if (string == "EDIT_AVATAR") - { - *mode = MODE_EDIT_AVATAR; - return TRUE; - } - else if (string == "SITTING") - { - *mode = MODE_SITTING; - return TRUE; - } - else - { - *mode = MODE_THIRD_PERSON; - return FALSE; - } -} - -// static -BOOL LLViewerInput::mouseFromString(const std::string& string, EMouseClickType *mode) -{ - if (string == "LMB") - { - *mode = CLICK_LEFT; - return TRUE; - } - else if (string == "Double LMB") - { - *mode = CLICK_DOUBLELEFT; - return TRUE; - } - else if (string == "MMB") - { - *mode = CLICK_MIDDLE; - return TRUE; - } - else if (string == "MB4") - { - *mode = CLICK_BUTTON4; - return TRUE; - } - else if (string == "MB5") - { - *mode = CLICK_BUTTON5; - return TRUE; - } - else - { - *mode = CLICK_NONE; - return FALSE; - } -} - -BOOL LLViewerInput::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) -{ - // check for re-map - EKeyboardMode mode = gViewerInput.getMode(); - U32 keyidx = (translated_mask<<16) | translated_key; - key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx); - if (iter != mRemapKeys[mode].end()) - { - translated_key = (iter->second) & 0xff; - translated_mask = (iter->second)>>16; - } - - // No repeats of F-keys - BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12); - if (!repeatable_key && repeated) - { - return FALSE; - } - - LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL; - // skip skipped keys - if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) - { - mKeyHandledByUI[translated_key] = FALSE; - //LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL; - LL_INFOS_ONCE("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL; // Change log message to not print out every time - } - else - { - // it is sufficient to set this value once per call to handlekey - // without clearing it, as it is only used in the subsequent call to scanKey - mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask); - // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress) - // NOT whether some UI shortcut wishes to handle the keypress - - } - return mKeyHandledByUI[translated_key]; -} - -BOOL LLViewerInput::handleKeyUp(KEY translated_key, MASK translated_mask) -{ - return gViewerWindow->handleKeyUp(translated_key, translated_mask); -} - -BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) -{ - S32 index; - typedef boost::function function_t; - function_t function = NULL; - std::string name; - - // Allow remapping of F2-F12 - if (function_name[0] == 'F') - { - int c1 = function_name[1] - '0'; - int c2 = function_name[2] ? function_name[2] - '0' : -1; - if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9) - { - int idx = c1; - if (c2 >= 0) - idx = idx*10 + c2; - if (idx >=2 && idx <= 12) - { - U32 keyidx = ((mask<<16)|key); - (mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1))); - return TRUE; - } - } - } - - // Not remapped, look for a function - - function_t* result = LLKeyboardActionRegistry::getValue(function_name); - if (result) - { - function = *result; - } - - if (!function) - { - LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; - return FALSE; - } - - // check for duplicate first and overwrite - S32 size = mKeyBindings[mode].size(); - for (index = 0; index < size; index++) - { - if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) - break; - } - - if (mode >= MODE_COUNT) - { - LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; - return FALSE; - } - - LLKeyboardBinding bind; - bind.mKey = key; - bind.mMask = mask; - bind.mFunction = function; - - mKeyBindings[mode].push_back(bind); - - return TRUE; -} - -BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name) -{ - S32 index; - typedef boost::function function_t; - function_t function = NULL; - - function_t* result = LLKeyboardActionRegistry::getValue(function_name); - if (result) - { - function = *result; - } - - if (!function) - { - LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; - return FALSE; - } - - // check for duplicate first and overwrite - S32 size = mMouseBindings[mode].size(); - for (index = 0; index < size; index++) - { - if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) - break; - } - - if (mode >= MODE_COUNT) - { - LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; - return FALSE; - } - - LLMouseBinding bind; - bind.mMouse = mouse; - bind.mMask = mask; - bind.mFunction = function; - - mMouseBindings[mode].push_back(bind); - - return TRUE; -} - -LLViewerInput::KeyBinding::KeyBinding() -: key("key"), - mouse("mouse"), - mask("mask"), - command("command") -{} - -LLViewerInput::KeyMode::KeyMode() -: bindings("binding") -{} - -LLViewerInput::Keys::Keys() -: first_person("first_person"), - third_person("third_person"), - sitting("sitting"), - edit_avatar("edit_avatar") -{} - -void LLViewerInput::resetBindings() -{ - for (S32 i = 0; i < MODE_COUNT; i++) - { - mKeyBindings[i].clear(); - mMouseBindings[i].clear(); - } -} - -S32 LLViewerInput::loadBindingsXML(const std::string& filename) -{ - resetBindings(); - - S32 binding_count = 0; - Keys keys; - LLSimpleXUIParser parser; - - if (parser.readXUI(filename, keys) - && keys.validateBlock()) - { - binding_count += loadBindingMode(keys.first_person, MODE_FIRST_PERSON); - binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON); - binding_count += loadBindingMode(keys.sitting, MODE_SITTING); - binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); - } - return binding_count; -} - -S32 count_masks(const MASK &mask) -{ - S32 res = 0; - if (mask & MASK_CONTROL) - { - res++; - } - if (mask & MASK_SHIFT) - { - res++; - } - if (mask & MASK_ALT) - { - res++; - } - return res; -} - -bool compare_key_by_mask(LLKeyboardBinding i1, LLKeyboardBinding i2) -{ - return (count_masks(i1.mMask) > count_masks(i2.mMask)); -} - -bool compare_mouse_by_mask(LLMouseBinding i1, LLMouseBinding i2) -{ - return (count_masks(i1.mMask) > count_masks(i2.mMask)); -} - -S32 LLViewerInput::loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode) -{ - S32 binding_count = 0; - for (LLInitParam::ParamIterator::const_iterator it = keymode.bindings.begin(), - end_it = keymode.bindings.end(); - it != end_it; - ++it) - { - bool processed = false; - std::string key_str = it->key.getValue(); - if (!key_str.empty() && key_str != "NONE") - { - KEY key; - LLKeyboard::keyFromString(key_str, &key); - if (key != KEY_NONE) - { - MASK mask; - LLKeyboard::maskFromString(it->mask, &mask); - bindKey(mode, key, mask, it->command); - processed = true; - } - else - { - LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; - } - } - if (!processed && it->mouse.isProvided() && !it->mouse.getValue().empty()) - { - EMouseClickType mouse; - mouseFromString(it->mouse.getValue(), &mouse); - if (mouse != CLICK_NONE) - { - MASK mask; - LLKeyboard::maskFromString(it->mask, &mask); - bindMouse(mode, mouse, mask, it->command); - processed = true; - } - else - { - LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL; - } - } - if (processed) - { - // total - binding_count++; - } - } - - // sort lists by mask (so that Shift+W is executed before W, if both are assigned, but if Shift+W is not assigned W should be executed) - std::sort(mKeyBindings[mode].begin(), mKeyBindings[mode].end(), compare_key_by_mask); - std::sort(mMouseBindings[mode].begin(), mMouseBindings[mode].end(), compare_mouse_by_mask); - - return binding_count; -} - -EKeyboardMode LLViewerInput::getMode() const -{ - if ( gAgentCamera.cameraMouselook() ) - { - return MODE_FIRST_PERSON; - } - else if ( gMorphView && gMorphView->getVisible()) - { - return MODE_EDIT_AVATAR; - } - else if (isAgentAvatarValid() && gAgentAvatarp->isSitting()) - { - return MODE_SITTING; - } - else - { - return MODE_THIRD_PERSON; - } -} - -bool LLViewerInput::scanKey(const std::vector &binding, - S32 binding_count, - KEY key, - MASK mask, - BOOL key_down, - BOOL key_up, - BOOL key_level, - bool repeat) const -{ - for (S32 i = 0; i < binding_count; i++) - { - if (binding[i].mKey == key) - { - if ((binding[i].mMask & mask) == binding[i].mMask) - { - bool res = false; - if (key_down && !repeat) - { - // ...key went down this frame, call function - res = binding[i].mFunction( KEYSTATE_DOWN ); - return true; - } - else if (key_up) - { - // ...key went down this frame, call function - res = binding[i].mFunction( KEYSTATE_UP ); - } - else if (key_level) - { - // ...key held down from previous frame - // Not windows, just call the function. - res = binding[i].mFunction( KEYSTATE_LEVEL ); - }//if - // Key+Mask combinations are supposed to be unique, so we won't find anything else - return res; - }//if - }//if - }//for - return false; -} - -// Called from scanKeyboard. -bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const -{ - if (LLApp::isExiting()) - { - return false; - } - - S32 mode = getMode(); - // Consider keyboard scanning as NOT mouse event. JC - MASK mask = gKeyboard->currentMask(FALSE); - - if (mKeyHandledByUI[key]) - { - return false; - } - - // don't process key down on repeated keys - BOOL repeat = gKeyboard->getKeyRepeated(key); - - bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat); - - if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) - { - if (key_down && !repeat) - { - res = agen_control_lbutton_handle(KEYSTATE_DOWN); - } - if (key_up) - { - res = agen_control_lbutton_handle(KEYSTATE_UP); - } - } - return res; -} - -BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) -{ - BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down); - - if (clicktype != CLICK_NONE) - { - // Special case - // If UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set - // handle !down as if we are handling doubleclick - - bool double_click_sp = (clicktype == CLICK_LEFT - && (mMouseLevel[CLICK_DOUBLELEFT] != MOUSE_STATE_SILENT) - && mMouseLevel[CLICK_LEFT] == MOUSE_STATE_SILENT); - if (double_click_sp && !down) - { - // Process doubleclick instead - clicktype = CLICK_DOUBLELEFT; - } - - - if (double_click_sp && down) - { - // Consume click. - // Due to handling, double click that is not handled will be immediately followed by LMB click - } - // If UI handled 'down', it should handle 'up' as well - // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI - else if (handled) - { - // UI handled new 'down' so iterupt whatever state we were in. - if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) - { - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - mMouseLevel[clicktype] = MOUSE_STATE_CLICK; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_UP; - } - } - } - else if (down) - { - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - // this is repeated hit (mouse does not repeat event until release) - // for now treat rapid clicking like mouse being held - mMouseLevel[clicktype] = MOUSE_STATE_LEVEL; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_DOWN; - } - } - else if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT) - { - // Released mouse key - if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) - { - mMouseLevel[clicktype] = MOUSE_STATE_CLICK; - } - else - { - mMouseLevel[clicktype] = MOUSE_STATE_UP; - } - } - } - - return handled; -} - -bool LLViewerInput::scanMouse(const std::vector &binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const -{ - for (S32 i = 0; i < binding_count; i++) - { - if (binding[i].mMouse == mouse && (binding[i].mMask & mask) == binding[i].mMask) - { - bool res = false; - switch (state) - { - case MOUSE_STATE_DOWN: - res = binding[i].mFunction(KEYSTATE_DOWN); - break; - case MOUSE_STATE_CLICK: - // Button went down and up in scope of single frame - // might not work best with some functions, - // but some function need specific states specifically - res = binding[i].mFunction(KEYSTATE_DOWN); - res |= binding[i].mFunction(KEYSTATE_UP); - break; - case MOUSE_STATE_LEVEL: - res = binding[i].mFunction(KEYSTATE_LEVEL); - break; - case MOUSE_STATE_UP: - res = binding[i].mFunction(KEYSTATE_UP); - break; - default: - break; - } - // Key+Mask combinations are supposed to be unique, no need to continue - return res; - } - } - return false; -} - -// todo: this recods key, scanMouse() triggers functions with EKeystate -bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const -{ - bool res = false; - S32 mode = getMode(); - MASK mask = gKeyboard->currentMask(TRUE); - res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state); - // no user defined actions found or those actions can't handle the key/button, handle control if nessesary - if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) - { - switch (state) - { - case MOUSE_STATE_DOWN: - agen_control_lbutton_handle(KEYSTATE_DOWN); - res = true; - break; - case MOUSE_STATE_CLICK: - // might not work best with some functions, - // but some function need specific states too specifically - agen_control_lbutton_handle(KEYSTATE_DOWN); - agen_control_lbutton_handle(KEYSTATE_UP); - res = true; - break; - case MOUSE_STATE_UP: - agen_control_lbutton_handle(KEYSTATE_UP); - res = true; - break; - default: - break; - } - } - return res; -} - -void LLViewerInput::scanMouse() -{ - for (S32 i = 0; i < CLICK_COUNT; i++) - { - if (mMouseLevel[i] != MOUSE_STATE_SILENT) - { - scanMouse((EMouseClickType)i, mMouseLevel[i]); - if (mMouseLevel[i] == MOUSE_STATE_DOWN) - { - // mouse doesn't support 'continued' state, so after handling, switch to LEVEL - mMouseLevel[i] = MOUSE_STATE_LEVEL; - } - else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK) - { - mMouseLevel[i] = MOUSE_STATE_SILENT; - } - } - } -} diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h deleted file mode 100644 index a22a632500..0000000000 --- a/indra/newview/llviewerinput.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file llviewerinput.h - * @brief LLViewerInput class header file - * - * $LicenseInfo:firstyear=2005&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_LLVIEWERINPUT_H -#define LL_LLVIEWERINPUT_H - -#include "llkeyboard.h" // For EKeystate -#include "llinitparam.h" - -const S32 MAX_KEY_BINDINGS = 128; // was 60 - -class LLNamedFunction -{ -public: - LLNamedFunction() : mFunction(NULL) { }; - ~LLNamedFunction() { }; - - std::string mName; - LLKeyFunc mFunction; -}; - -class LLKeyboardBinding -{ -public: - KEY mKey; - MASK mMask; - - LLKeyFunc mFunction; -}; - -class LLMouseBinding -{ -public: - EMouseClickType mMouse; - MASK mMask; - - LLKeyFunc mFunction; -}; - - -typedef enum e_keyboard_mode -{ - MODE_FIRST_PERSON, - MODE_THIRD_PERSON, - MODE_EDIT_AVATAR, - MODE_SITTING, - MODE_COUNT -} EKeyboardMode; - -class LLWindow; - -void bind_keyboard_functions(); - -class LLViewerInput -{ -public: - struct KeyBinding : public LLInitParam::Block - { - Mandatory key, - mask, - command; - Optional mouse; // Note, not mandatory for the sake of backward campatibility with keys.xml - - KeyBinding(); - }; - - struct KeyMode : public LLInitParam::Block - { - Multiple bindings; - - KeyMode(); - }; - - struct Keys : public LLInitParam::Block - { - Optional first_person, - third_person, - sitting, - edit_avatar; - - Keys(); - }; - - LLViewerInput(); - - BOOL handleKey(KEY key, MASK mask, BOOL repeated); - BOOL handleKeyUp(KEY key, MASK mask); - - S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error - EKeyboardMode getMode() const; - - static BOOL modeFromString(const std::string& string, S32 *mode); // False on failure - static BOOL mouseFromString(const std::string& string, EMouseClickType *mode);// False on failure - - bool scanKey(KEY key, - BOOL key_down, - BOOL key_up, - BOOL key_level) const; - - // handleMouse() records state, scanMouse() goes through states, scanMouse(click) processes individual saved states after UI is done with them - BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); - void scanMouse(); - -private: - bool scanKey(const std::vector &binding, - S32 binding_count, - KEY key, - MASK mask, - BOOL key_down, - BOOL key_up, - BOOL key_level, - bool repeat) const; - - enum EMouseState - { - MOUSE_STATE_DOWN, // key down this frame - MOUSE_STATE_CLICK, // key went up and down in scope of same frame - MOUSE_STATE_LEVEL, // clicked again fast, or never released - MOUSE_STATE_UP, // went up this frame - MOUSE_STATE_SILENT // notified about 'up', do not notify again - }; - bool scanMouse(EMouseClickType click, EMouseState state) const; - bool scanMouse(const std::vector &binding, - S32 binding_count, - EMouseClickType mouse, - MASK mask, - EMouseState state) const; - - S32 loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode); - BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name); - BOOL bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name); - void resetBindings(); - - // Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here - - // TODO: at some point it is better to remake this, especially keyaboard part - // would be much better to send to functions actual state of the button than - // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown) - std::vector mKeyBindings[MODE_COUNT]; - std::vector mMouseBindings[MODE_COUNT]; - - typedef std::map key_remap_t; - key_remap_t mRemapKeys[MODE_COUNT]; - std::set mKeysSkippedByUI; - BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI - - // This is indentical to what llkeyboard does (mKeyRepeated, mKeyLevel, mKeyDown e t c), - // just instead of remembering individually as bools, we record state as enum - EMouseState mMouseLevel[CLICK_COUNT]; // records of key state -}; - -extern LLViewerInput gViewerInput; -bool agent_push_forward(EKeystate s);// Mouse movement by Singularity -#endif // LL_LLVIEWERINPUT_H diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 1a12236d8a..6183eba22d 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -253,7 +253,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //---------------------------------------------------------------- llassert( !(mTexture.notNull() && mLayerSet) ); // mutually exclusive - LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; + // LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; // Rye Mutt's broken local texture rendering fix LLViewerTexLayerSet *layerset = dynamic_cast(mLayerSet); if (mTestImageName) { @@ -283,12 +283,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else if ( !is_dummy && mTexture.notNull() ) { - if(mTexture->hasGLTexture()) - { - old_mode = mTexture->getAddressMode(); - } + // Rye Mutt's broken local texture rendering fix + //if(mTexture->hasGLTexture()) + //{ + // old_mode = mTexture->getAddressMode(); + //} + // gGL.getTexUnit(diffuse_channel)->bind(mTexture); - gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + //gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); // Rye Mutt's broken local texture rendering fix } else { @@ -341,11 +343,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT); } - if (mTexture.notNull() && !is_dummy) - { - gGL.getTexUnit(diffuse_channel)->bind(mTexture); - gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode); - } + // Rye Mutt's broken local texture rendering fix + //if (mTexture.notNull() && !is_dummy) + //{ + // gGL.getTexUnit(diffuse_channel)->bind(mTexture); + // gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode); + //} + // return triangle_count; } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp new file mode 100644 index 0000000000..f1f9f9e34e --- /dev/null +++ b/indra/newview/llviewerkeyboard.cpp @@ -0,0 +1,1111 @@ +/** + * @file llviewerkeyboard.cpp + * @brief LLViewerKeyboard class implementation + * + * $LicenseInfo:firstyear=2005&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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappviewer.h" +#include "llfloaterreg.h" +#include "llviewerkeyboard.h" +#include "llmath.h" +#include "llagent.h" +#include "llagentcamera.h" +// [FS Communication UI] +// #include "llfloaterimnearbychat.h" +#include "fsnearbychathub.h" +#include "lllineeditor.h" +// [FS Communication UI] +#include "llviewercontrol.h" +#include "llfocusmgr.h" +#include "llmorphview.h" +#include "llmoveview.h" +#include "lltoolfocus.h" +#include "llviewerwindow.h" +#include "llvoavatarself.h" +#include "llfloatercamera.h" +#include "llinitparam.h" +#include "llfloaterwebcontent.h" +#include "fsfloatersearch.h" + +// +// Constants +// + +const F32 FLY_TIME = 0.5f; +const F32 FLY_FRAMES = 4; + +const F32 NUDGE_TIME = 0.25f; // in seconds +const S32 NUDGE_FRAMES = 2; +const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed + +struct LLKeyboardActionRegistry +: public LLRegistrySingleton, LLKeyboardActionRegistry> +{ + LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); +}; + +LLViewerKeyboard gViewerKeyboard; + +void agent_jump( EKeystate s ) +{ + static BOOL first_fly_attempt(TRUE); + if (KEYSTATE_UP == s) + { + first_fly_attempt = TRUE; + return; + } + F32 time = gKeyboard->getCurKeyElapsedTime(); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); + + // Chalice Yao's crouch toggle + if (gSavedPerAccountSettings.getBOOL("FSCrouchToggleStatus")) + { + gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", FALSE); + } + // + + if( time < FLY_TIME + || frame_count <= FLY_FRAMES + || gAgent.upGrabbed() + || !gSavedSettings.getBOOL("AutomaticFly")) + { + gAgent.moveUp(1); + } + else + { + gAgent.setFlying(TRUE, first_fly_attempt); + first_fly_attempt = FALSE; + gAgent.moveUp(1); + } +} + +void agent_push_down( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + // Chalice Yao's crouch toggle + //gAgent.moveUp(-1); + else if (KEYSTATE_DOWN == s && !gAgent.getFlying() && !gAgentAvatarp->isSitting() && gSavedPerAccountSettings.getBOOL("FSCrouchToggle")) + { + if (gSavedPerAccountSettings.getBOOL("FSCrouchToggleStatus")) + { + gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", FALSE); + } + else + { + gSavedPerAccountSettings.setBOOL("FSCrouchToggleStatus", TRUE); + gAgent.moveUp(-1); + } + } + else + { + gAgent.moveUp(-1); + } + // +} + +static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode) +{ +// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i + if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) ) + gAgent.clearTempRun(); +// [/RLVa:KB] +// if (gAgent.mDoubleTapRunMode == mode && +// gAgent.getRunning() && +// !gAgent.getAlwaysRun()) +// { +// // Turn off temporary running. +// gAgent.clearRunning(); +// gAgent.sendWalkRun(gAgent.getRunning()); +// } +} + +static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode) +{ + if (KEYSTATE_UP == s) + { + // Note: in case shift is already released, slide left/right run + // will be released in agent_turn_left()/agent_turn_right() + agent_check_temporary_run(mode); + } + else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") && + KEYSTATE_DOWN == s && + !gAgent.getRunning()) + { + if (gAgent.mDoubleTapRunMode == mode && + gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME) + { + // Same walk-key was pushed again quickly; this is a + // double-tap so engage temporary running. +// gAgent.setRunning(); +// gAgent.sendWalkRun(gAgent.getRunning()); +// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i + gAgent.setTempRun(); +// [/RLVa:KB] + } + + // Pressing any walk-key resets the double-tap timer + gAgent.mDoubleTapRunTimer.reset(); + gAgent.mDoubleTapRunMode = mode; + } +} + +static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) +{ + agent_handle_doubletap_run(s, mode); + if (KEYSTATE_UP == s) return; + + F32 time = gKeyboard->getCurKeyElapsedTime(); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); + + if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) + { + gAgent.moveAtNudge(direction); + } + else + { + gAgent.moveAt(direction); + } +} + +void camera_move_forward( EKeystate s ); + +void agent_push_forward( EKeystate s ) +{ + if(gAgent.isMovementLocked()) return; + + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_forward(s); + } + else + { + agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); + } +} + +void camera_move_backward( EKeystate s ); + +void agent_push_backward( EKeystate s ) +{ + if(gAgent.isMovementLocked()) return; + + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_move_backward(s); + } + else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook")) + { + gAgentCamera.changeCameraToThirdPerson(); + } + else + { + agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); + } +} + +static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) +{ + agent_handle_doubletap_run(s, mode); + if( KEYSTATE_UP == s ) return; + F32 time = gKeyboard->getCurKeyElapsedTime(); + S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); + + if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES) + { + gAgent.moveLeftNudge(direction); + } + else + { + gAgent.moveLeft(direction); + } +} + + +void agent_slide_left( EKeystate s ) +{ + if(gAgent.isMovementLocked()) return; + agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); +} + + +void agent_slide_right( EKeystate s ) +{ + if(gAgent.isMovementLocked()) return; + agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); +} + +void camera_spin_around_cw( EKeystate s ); + +void agent_turn_left( EKeystate s ) +{ + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_cw(s); + return; + } + + if(gAgent.isMovementLocked()) return; + + if (LLToolCamera::getInstance()->mouseSteerMode()) + { + agent_slide_left(s); + } + else + { + if (KEYSTATE_UP == s) + { + // Check temporary running. In case user released 'left' key with shift already released. + agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT); + return; + } + F32 time = gKeyboard->getCurKeyElapsedTime(); + gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); + } +} + +void camera_spin_around_ccw( EKeystate s ); + +void agent_turn_right( EKeystate s ) +{ + //in free camera control mode we need to intercept keyboard events for avatar movements + if (LLFloaterCamera::inFreeCameraMode()) + { + camera_spin_around_ccw(s); + return; + } + + if(gAgent.isMovementLocked()) return; + + if (LLToolCamera::getInstance()->mouseSteerMode()) + { + agent_slide_right(s); + } + else + { + if (KEYSTATE_UP == s) + { + // Check temporary running. In case user released 'right' key with shift already released. + agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT); + return; + } + F32 time = gKeyboard->getCurKeyElapsedTime(); + gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); + } +} + +void agent_look_up( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgent.movePitch(-1); + //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); +} + + +void agent_look_down( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgent.movePitch(1); + //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); +} + +void agent_toggle_fly( EKeystate s ) +{ + // Only catch the edge + if (KEYSTATE_DOWN == s ) + { + LLAgent::toggleFlying(); + } +} + +F32 get_orbit_rate() +{ + F32 time = gKeyboard->getCurKeyElapsedTime(); + if( time < NUDGE_TIME ) + { + F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; + //LL_INFOS() << rate << LL_ENDL; + return rate; + } + else + { + return 1; + } +} + +void camera_spin_around_ccw( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); +} + + +void camera_spin_around_cw( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); +} + +void camera_spin_around_ccw_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return; + if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) + { + //send keystrokes, but do not change camera + agent_turn_right(s); + } + else + { + //change camera but do not send keystrokes + gAgentCamera.unlockView(); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); + } +} + + +void camera_spin_around_cw_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return; + if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) + { + //send keystrokes, but do not change camera + agent_turn_left(s); + } + else + { + //change camera but do not send keystrokes + gAgentCamera.unlockView(); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); + } +} + + +void camera_spin_over( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); +} + + +void camera_spin_under( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); +} + +void camera_spin_over_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) + { + //send keystrokes, but do not change camera + agent_jump(s); + } + else + { + //change camera but do not send keystrokes + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); + } +} + + +void camera_spin_under_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) + { + //send keystrokes, but do not change camera + agent_push_down(s); + } + else + { + //change camera but do not send keystrokes + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); + } +} + +void camera_move_forward( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); +} + + +void camera_move_backward( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); +} + +void camera_move_forward_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return; + if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) + { + agent_push_forward(s); + } + else + { + gAgentCamera.setOrbitInKey( get_orbit_rate() ); + } +} + + +void camera_move_backward_sitting( EKeystate s ) +{ + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return; + + if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) + { + agent_push_backward(s); + } + else + { + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); + } +} + +void camera_pan_up( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanUpKey( get_orbit_rate() ); +} + +void camera_pan_down( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanDownKey( get_orbit_rate() ); +} + +void camera_pan_left( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanLeftKey( get_orbit_rate() ); +} + +void camera_pan_right( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanRightKey( get_orbit_rate() ); +} + +void camera_pan_in( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanInKey( get_orbit_rate() ); +} + +void camera_pan_out( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setPanOutKey( get_orbit_rate() ); +} + +void camera_move_forward_fast( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey(2.5f); +} + +void camera_move_backward_fast( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey(2.5f); +} + + +void edit_avatar_spin_ccw( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); + //gMorphView->orbitLeft( get_orbit_rate() ); +} + + +void edit_avatar_spin_cw( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); + //gMorphView->orbitRight( get_orbit_rate() ); +} + +void edit_avatar_spin_over( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); + //gMorphView->orbitUp( get_orbit_rate() ); +} + + +void edit_avatar_spin_under( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); + //gMorphView->orbitDown( get_orbit_rate() ); +} + +void edit_avatar_move_forward( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); + //gMorphView->orbitIn(); +} + + +void edit_avatar_move_backward( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + gMorphView->setCameraDrivenByKeys( TRUE ); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); + //gMorphView->orbitOut(); +} + +void stop_moving( EKeystate s ) +{ + if( KEYSTATE_UP == s ) return; + // stop agent + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + // cancel autopilot + gAgent.stopAutoPilot(); +} + +void start_chat( EKeystate s ) +{ + if (LLAppViewer::instance()->quitRequested()) + { + return; // can't talk, gotta go, kthxbye! + } + + // start chat + // [FS Communication UI] + //LLFloaterIMNearbyChat::startChat(NULL); + FSNearbyChat::instance().showDefaultChatBar(TRUE); + // [FS Communication UI] +} + +void start_gesture( EKeystate s ) +{ + // If avatar is pointing at something, don't start gesture. + // This works around the bug with Shared Media prims. + if (gAgentCamera.mPointAtObject) + { + return; + } + + // FIRE-4167: Don't start gesture if a floater with web content has focus + LLFloater* focused_floater = gFloaterView->getFocusedFloater(); + if (focused_floater && (dynamic_cast(focused_floater) || dynamic_cast(focused_floater))) + { + return; + } + + LLUICtrl* focus_ctrlp = dynamic_cast(gFocusMgr.getKeyboardFocus()); + if (KEYSTATE_UP == s && + ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) + { + // [FS Communication UI] + //if ((LLFloaterReg::getTypedInstance("nearby_chat"))->getCurrentChat().empty()) + //{ + // // No existing chat in chat editor, insert '/' + // LLFloaterIMNearbyChat::startChat("/"); + //} + //else + //{ + // // Don't overwrite existing text in chat editor + // LLFloaterIMNearbyChat::startChat(NULL); + //} + + FSNearbyChat::instance().showDefaultChatBar(TRUE, "/"); + // [FS Communication UI] + } +} + +#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); +REGISTER_KEYBOARD_ACTION("jump", agent_jump); +REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); +REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward); +REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward); +REGISTER_KEYBOARD_ACTION("look_up", agent_look_up); +REGISTER_KEYBOARD_ACTION("look_down", agent_look_down); +REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly); +REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left); +REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right); +REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left); +REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right); +REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw); +REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw); +REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting); +REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting); +REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over); +REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under); +REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting); +REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting); +REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward); +REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward); +REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting); +REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting); +REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up); +REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down); +REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left); +REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right); +REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in); +REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out); +REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast); +REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast); +REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw); +REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw); +REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over); +REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under); +REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward); +REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward); +REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); +REGISTER_KEYBOARD_ACTION("start_chat", start_chat); +REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); +#undef REGISTER_KEYBOARD_ACTION + +LLViewerKeyboard::LLViewerKeyboard() +{ + for (S32 i = 0; i < MODE_COUNT; i++) + { + mBindingCount[i] = 0; + } + + for (S32 i = 0; i < KEY_COUNT; i++) + { + mKeyHandledByUI[i] = FALSE; + } + // we want the UI to never see these keys so that they can always control the avatar/camera + for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) + { + mKeysSkippedByUI.insert(k); + } +} + +BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) +{ + if (string == "FIRST_PERSON") + { + *mode = MODE_FIRST_PERSON; + return TRUE; + } + else if (string == "THIRD_PERSON") + { + *mode = MODE_THIRD_PERSON; + return TRUE; + } + else if (string == "EDIT") + { + *mode = MODE_EDIT; + return TRUE; + } + else if (string == "EDIT_AVATAR") + { + *mode = MODE_EDIT_AVATAR; + return TRUE; + } + else if (string == "SITTING") + { + *mode = MODE_SITTING; + return TRUE; + } + else + { + *mode = MODE_THIRD_PERSON; + return FALSE; + } +} + +BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) +{ + // check for re-map + EKeyboardMode mode = gViewerKeyboard.getMode(); + U32 keyidx = (translated_mask<<16) | translated_key; + key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx); + if (iter != mRemapKeys[mode].end()) + { + translated_key = (iter->second) & 0xff; + translated_mask = (iter->second)>>16; + } + + // No repeats of F-keys + BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12); + if (!repeatable_key && repeated) + { + return FALSE; + } + + LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL; + // skip skipped keys + if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) + { + mKeyHandledByUI[translated_key] = FALSE; + //LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL; + LL_INFOS_ONCE("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL; // Change log message to not print out every time + } + else + { + // it is sufficient to set this value once per call to handlekey + // without clearing it, as it is only used in the subsequent call to scanKey + mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask); + // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress) + // NOT whether some UI shortcut wishes to handle the keypress + + } + return mKeyHandledByUI[translated_key]; +} + +BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) +{ + return gViewerWindow->handleKeyUp(translated_key, translated_mask); +} + +BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) +{ + S32 index; + typedef boost::function function_t; + function_t function = NULL; + std::string name; + + // Allow remapping of F2-F12 + if (function_name[0] == 'F') + { + int c1 = function_name[1] - '0'; + int c2 = function_name[2] ? function_name[2] - '0' : -1; + if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9) + { + int idx = c1; + if (c2 >= 0) + idx = idx*10 + c2; + if (idx >=2 && idx <= 12) + { + U32 keyidx = ((mask<<16)|key); + (mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1))); + return TRUE; + } + } + } + + // Not remapped, look for a function + + function_t* result = LLKeyboardActionRegistry::getValue(function_name); + if (result) + { + function = *result; + } + + if (!function) + { + LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; + return FALSE; + } + + // check for duplicate first and overwrite + for (index = 0; index < mBindingCount[mode]; index++) + { + if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask) + break; + } + + if (index >= MAX_KEY_BINDINGS) + { + LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; + return FALSE; + } + + if (mode >= MODE_COUNT) + { + LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; + return FALSE; + } + + mBindings[mode][index].mKey = key; + mBindings[mode][index].mMask = mask; + mBindings[mode][index].mFunction = function; + + if (index == mBindingCount[mode]) + mBindingCount[mode]++; + + return TRUE; +} + +LLViewerKeyboard::KeyBinding::KeyBinding() +: key("key"), + mask("mask"), + command("command") +{} + +LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode) +: bindings("binding"), + mode(_mode) +{} + +LLViewerKeyboard::Keys::Keys() +: first_person("first_person", KeyMode(MODE_FIRST_PERSON)), + third_person("third_person", KeyMode(MODE_THIRD_PERSON)), + edit("edit", KeyMode(MODE_EDIT)), + sitting("sitting", KeyMode(MODE_SITTING)), + edit_avatar("edit_avatar", KeyMode(MODE_EDIT_AVATAR)) +{} + +S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) +{ + // Allow instant change of keyboard layout + for (S32 i = 0; i < MODE_COUNT; i++) + { + mBindingCount[i] = 0; + + for (S32 j = 0; j < MAX_KEY_BINDINGS; j++) + { + mBindings[i][j] = LLKeyBinding(); + } + } + // + + S32 binding_count = 0; + Keys keys; + LLSimpleXUIParser parser; + + if (parser.readXUI(filename, keys) + && keys.validateBlock()) + { + binding_count += loadBindingMode(keys.first_person); + binding_count += loadBindingMode(keys.third_person); + binding_count += loadBindingMode(keys.edit); + binding_count += loadBindingMode(keys.sitting); + binding_count += loadBindingMode(keys.edit_avatar); + } + return binding_count; +} + +S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode) +{ + S32 binding_count = 0; + for (LLInitParam::ParamIterator::const_iterator it = keymode.bindings.begin(), + end_it = keymode.bindings.end(); + it != end_it; + ++it) + { + KEY key; + MASK mask; + LLKeyboard::keyFromString(it->key, &key); + LLKeyboard::maskFromString(it->mask, &mask); + bindKey(keymode.mode, key, mask, it->command); + binding_count++; + } + + return binding_count; +} + +S32 LLViewerKeyboard::loadBindings(const std::string& filename) +{ + LLFILE *fp; + const S32 BUFFER_SIZE = 2048; + char buffer[BUFFER_SIZE]; /* Flawfinder: ignore */ + // *NOTE: This buffer size is hard coded into scanf() below. + char mode_string[MAX_STRING] = ""; /* Flawfinder: ignore */ + char key_string[MAX_STRING] = ""; /* Flawfinder: ignore */ + char mask_string[MAX_STRING] = ""; /* Flawfinder: ignore */ + char function_string[MAX_STRING] = ""; /* Flawfinder: ignore */ + S32 mode = MODE_THIRD_PERSON; + KEY key = 0; + MASK mask = 0; + S32 tokens_read; + S32 binding_count = 0; + S32 line_count = 0; + + if(filename.empty()) + { + LL_ERRS() << " No filename specified" << LL_ENDL; + return 0; + } + + fp = LLFile::fopen(filename, "r"); + + if (!fp) + { + return 0; + } + + + while (!feof(fp)) + { + line_count++; + if (!fgets(buffer, BUFFER_SIZE, fp)) + break; + + // skip over comments, blank lines + if (buffer[0] == '#' || buffer[0] == '\n') continue; + + // grab the binding strings + tokens_read = sscanf( /* Flawfinder: ignore */ + buffer, + "%254s %254s %254s %254s", + mode_string, + key_string, + mask_string, + function_string); + + if (tokens_read == EOF) + { + LL_INFOS() << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << LL_ENDL; + fclose(fp); + return 0; + } + else if (tokens_read < 4) + { + LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL; + continue; + } + + // convert mode + if (!modeFromString(mode_string, &mode)) + { + LL_INFOS() << "Unknown mode on line " << line_count << " of key binding file " << filename << LL_ENDL; + LL_INFOS() << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << LL_ENDL; + continue; + } + + // convert key + if (!LLKeyboard::keyFromString(key_string, &key)) + { + LL_INFOS() << "Can't interpret key on line " << line_count << " of key binding file " << filename << LL_ENDL; + continue; + } + + // convert mask + if (!LLKeyboard::maskFromString(mask_string, &mask)) + { + LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL; + continue; + } + + // bind key + if (bindKey(mode, key, mask, function_string)) + { + binding_count++; + } + } + + fclose(fp); + + return binding_count; +} + + +EKeyboardMode LLViewerKeyboard::getMode() +{ + if ( gAgentCamera.cameraMouselook() ) + { + return MODE_FIRST_PERSON; + } + else if ( gMorphView && gMorphView->getVisible()) + { + return MODE_EDIT_AVATAR; + } + else if (isAgentAvatarValid() && gAgentAvatarp->isSitting()) + { + return MODE_SITTING; + } + else + { + return MODE_THIRD_PERSON; + } +} + + +// Called from scanKeyboard. +void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) +{ + if (LLApp::isExiting()) + { + return; + } + + S32 mode = getMode(); + // Consider keyboard scanning as NOT mouse event. JC + MASK mask = gKeyboard->currentMask(FALSE); + + LLKeyBinding* binding = mBindings[mode]; + S32 binding_count = mBindingCount[mode]; + + + if (mKeyHandledByUI[key]) + { + return; + } + + // don't process key down on repeated keys + BOOL repeat = gKeyboard->getKeyRepeated(key); + + for (S32 i = 0; i < binding_count; i++) + { + //for (S32 key = 0; key < KEY_COUNT; key++) + if (binding[i].mKey == key) + { + //if (binding[i].mKey == key && binding[i].mMask == mask) + if (binding[i].mMask == mask) + { + if (key_down && !repeat) + { + // ...key went down this frame, call function + binding[i].mFunction( KEYSTATE_DOWN ); + } + else if (key_up) + { + // ...key went down this frame, call function + binding[i].mFunction( KEYSTATE_UP ); + } + else if (key_level) + { + // ...key held down from previous frame + // Not windows, just call the function. + binding[i].mFunction( KEYSTATE_LEVEL ); + }//if + }//if + }//for + }//for +} diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h new file mode 100644 index 0000000000..80f326175f --- /dev/null +++ b/indra/newview/llviewerkeyboard.h @@ -0,0 +1,118 @@ +/** + * @file llviewerkeyboard.h + * @brief LLViewerKeyboard class header file + * + * $LicenseInfo:firstyear=2005&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_LLVIEWERKEYBOARD_H +#define LL_LLVIEWERKEYBOARD_H + +#include "llkeyboard.h" // For EKeystate +#include "llinitparam.h" + +const S32 MAX_NAMED_FUNCTIONS = 100; +const S32 MAX_KEY_BINDINGS = 128; // was 60 + +class LLNamedFunction +{ +public: + LLNamedFunction() : mFunction(NULL) { }; + ~LLNamedFunction() { }; + + std::string mName; + LLKeyFunc mFunction; +}; + +typedef enum e_keyboard_mode +{ + MODE_FIRST_PERSON, + MODE_THIRD_PERSON, + MODE_EDIT, + MODE_EDIT_AVATAR, + MODE_SITTING, + MODE_COUNT +} EKeyboardMode; + + +void bind_keyboard_functions(); + +class LLViewerKeyboard +{ +public: + struct KeyBinding : public LLInitParam::Block + { + Mandatory key, + mask, + command; + + KeyBinding(); + }; + + struct KeyMode : public LLInitParam::Block + { + Multiple bindings; + EKeyboardMode mode; + KeyMode(EKeyboardMode mode); + }; + + struct Keys : public LLInitParam::Block + { + Optional first_person, + third_person, + edit, + sitting, + edit_avatar; + + Keys(); + }; + + LLViewerKeyboard(); + + BOOL handleKey(KEY key, MASK mask, BOOL repeated); + BOOL handleKeyUp(KEY key, MASK mask); + + S32 loadBindings(const std::string& filename); // returns number bound, 0 on error + S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error + EKeyboardMode getMode(); + + BOOL modeFromString(const std::string& string, S32 *mode); // False on failure + + void scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); + +private: + S32 loadBindingMode(const LLViewerKeyboard::KeyMode& keymode); + BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name); + + // Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here + S32 mBindingCount[MODE_COUNT]; + LLKeyBinding mBindings[MODE_COUNT][MAX_KEY_BINDINGS]; + + typedef std::map key_remap_t; + key_remap_t mRemapKeys[MODE_COUNT]; + std::set mKeysSkippedByUI; + BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI +}; + +extern LLViewerKeyboard gViewerKeyboard; +void agent_push_forward(EKeystate s);// Mouse movement by Singularity +#endif // LL_LLVIEWERKEYBOARD_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 19ae07a672..d10a4e966f 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -2349,6 +2349,18 @@ void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button) } } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::scrollWheel(const LLVector2& texture_coords, S32 scroll_x, S32 scroll_y, MASK mask) +{ + if (mMediaSource) + { + S32 x, y; + scaleTextureCoords(texture_coords, &x, &y); + + scrollWheel(x, y, scroll_x, scroll_y, mask); + } +} + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask) { diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index a5cde35c88..8bf1ad2441 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -235,6 +235,7 @@ public: void mouseMove(const LLVector2& texture_coords, MASK mask); void mouseDoubleClick(const LLVector2& texture_coords, MASK mask); void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0); + void scrollWheel(const LLVector2& texture_coords, S32 scroll_x, S32 scroll_y, MASK mask); void scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask); void mouseCapture(); diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index f207a6edc3..1c5eac6f98 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -373,13 +373,26 @@ BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa media_impl->handleUnicodeCharHere(uni_char); return true; } -BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks) + +BOOL LLViewerMediaFocus::handleScrollWheel(const LLVector2& texture_coords, S32 clicks_x, S32 clicks_y) +{ + BOOL retval = FALSE; + LLViewerMediaImpl* media_impl = getFocusedMediaImpl(); + if (media_impl && media_impl->hasMedia()) + { + media_impl->scrollWheel(texture_coords, clicks_x, clicks_y, gKeyboard->currentMask(TRUE)); + retval = TRUE; + } + return retval; +} + +BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks_x, S32 clicks_y) { BOOL retval = FALSE; LLViewerMediaImpl* media_impl = getFocusedMediaImpl(); if(media_impl && media_impl->hasMedia()) { - media_impl->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE)); + media_impl->scrollWheel(x, y, clicks_x, clicks_y, gKeyboard->currentMask(TRUE)); retval = TRUE; } return retval; diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index d26b35378b..effd08a559 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -58,7 +58,8 @@ public: /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); /*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent); /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + BOOL handleScrollWheel(const LLVector2& texture_coords, S32 clicks_x, S32 clicks_y); + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks_x, S32 clicks_y); void update(); @@ -67,7 +68,8 @@ public: bool isFocusedOnFace(LLPointer objectp, S32 face); bool isHoveringOverFace(LLPointer objectp, S32 face); - + bool isHoveringOverFocused() { return mFocusedObjectID == mHoverObjectID && mFocusedObjectFace == mHoverObjectFace; }; + // These look up (by uuid) and return the values that were set with setFocusFace. They will return null if the objects have been destroyed. LLViewerMediaImpl* getFocusedMediaImpl(); LLViewerObject* getFocusedObject(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2e8be566ff..d45d1e3f84 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8788,15 +8788,16 @@ BOOL object_selected_and_point_valid(const LLSD& sdParam) } -// [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a -/* BOOL object_is_wearable() { if (!isAgentAvatarValid()) { return FALSE; } - if (!object_selected_and_point_valid()) +// if (!object_selected_and_point_valid()) +// [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a + if (!object_selected_and_point_valid(LLSD(0))) +// [/RLVa:KB] { return FALSE; } @@ -8806,8 +8807,6 @@ BOOL object_is_wearable() } return gAgentAvatarp->canAttachMoreObjects(); } -*/ -// [/RLVa:KB] class LLAttachmentPointFilled : public view_listener_t { @@ -10174,6 +10173,7 @@ BOOL LLViewerMenuHolderGL::hideMenus() if (LLMenuHolderGL::hideMenus()) { + LLToolPie::instance().blockClickToWalk(); handled = TRUE; } @@ -10781,8 +10781,8 @@ class LLWorldEnvSettings : public view_listener_t bool handleEvent(const LLSD& userdata) { -// [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-1.0.0g - if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) +// [RLVa:KB] - @setenv + if (!RlvActions::canChangeEnvironment()) return true; // [/RLVa:KB] @@ -11781,10 +11781,7 @@ void initialize_menus() enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1)); enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); -// enable.add("Object.EnableWear", boost::bind(&object_is_wearable)); -// [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a - enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid, _2)); -// [/RLVa:KB] + enable.add("Object.EnableWear", boost::bind(&object_is_wearable)); enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); @@ -11868,11 +11865,8 @@ void initialize_menus() // [RLVa:KB] - Checked: RLVa-2.0.0 enable.add("RLV.MainToggleVisible", boost::bind(&rlvMenuMainToggleVisible, _1)); - //if (RlvActions::isRlvEnabled()) // FIRE-20539: Toolbar buttons don't show disabled state anymore - { - enable.add("RLV.CanShowName", boost::bind(&rlvMenuCanShowName)); - enable.add("RLV.EnableIfNot", boost::bind(&rlvMenuEnableIfNot, _2)); - } + enable.add("RLV.CanShowName", boost::bind(&rlvMenuCanShowName)); + enable.add("RLV.EnableIfNot", boost::bind(&rlvMenuEnableIfNot, _2)); // [/RLVa:KB] // Toggle internal web browser diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3c7e49e104..a08157c9e4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2325,15 +2325,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const LLUUID destination; bool accept = true; -// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1) - bool fRlvNotifyAccepted = false; -// [/RLVa:KB] // If user accepted, accept to proper folder, if user discarded, accept to trash. switch(button) { case IOR_ACCEPT: - destination = mFolderID; - // [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1) // Only treat the offer as 'Give to #RLV' if: // - the user has enabled the feature @@ -2341,28 +2336,28 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const // - the name starts with the prefix - mDesc format: '[OBJECTNAME]' ( http://slurl.com/... ) if ( (rlv_handler_t::isEnabled()) && (IM_TASK_INVENTORY_OFFERED == mIM) && (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 1) ) { - fRlvNotifyAccepted = true; if (!RlvSettings::getForbidGiveToRLV()) { const LLUUID& idRlvRoot = RlvInventory::instance().getSharedRootID(); if (idRlvRoot.notNull()) mFolderID = idRlvRoot; - fRlvNotifyAccepted = false; // "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder - + // "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID); gInventory.addObserver(pOfferObserver); } - } - - if (fRlvNotifyAccepted) - { - std::string::size_type idxToken = mDesc.find("' ( http://"); - if (std::string::npos != idxToken) - RlvBehaviourNotifyHandler::sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1)); + else + { + std::string::size_type idxToken = mDesc.find("' ( http://"); + if (std::string::npos != idxToken) + { + RlvBehaviourNotifyHandler::sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1)); + } + } } // [/RLVa:KB] + destination = mFolderID; //don't spam user if flooded if (check_offer_throttle(mFromName, true)) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 320090b0d8..e08fdb7a6c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -397,10 +397,10 @@ public: void sendShapeUpdate(); -// U8 getAttachmentState() { return mAttachmentState; } // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0a) | Added: RLVa-1.2.0a - U8 getAttachmentState() const { return mAttachmentState; } + U8 getAttachmentState() const { return mAttachmentState; } // [/RLVa:KB] +// U8 getAttachmentState() { return mAttachmentState; } F32 getAppAngle() const { return mAppAngle; } F32 getPixelArea() const { return mPixelArea; } diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 4c43d416f9..78d2710a89 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -142,6 +142,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel) if(mMediaImpl.isNull()) { + play(parcel); return; } @@ -206,6 +207,12 @@ void LLViewerParcelMedia::play(LLParcel* parcel) if (!gSavedSettings.getBOOL("AudioStreamingMedia")) return; + // This test appears all over the code and really should be facotred out into a single + // call that returns true/false (with option ask dialog) but that is outside of scope + // for this work so we'll just directly. + if (gSavedSettings.getS32("ParcelMediaAutoPlayEnable") == 0 ) + return; + std::string media_url = parcel->getMediaURL(); std::string media_current_url = parcel->getMediaCurrentURL(); std::string mime_type = parcel->getMediaType(); diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 405103843d..3277acd3ec 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -60,7 +60,10 @@ LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height) : // ORDER_LAST => must render these after the hints are created. LLTexLayerSetBuffer(owner), - LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), + // Rye Mutt's broken local texture rendering fix + //LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), + LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, FALSE ), + // // [Legacy Bake] mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates mNeedsUpload(FALSE), diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4b566532ed..95c19f4f68 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -45,8 +45,7 @@ #include "llmeshrepository.h" #include "llnotificationhandler.h" #include "llpanellogin.h" -#include "llsetkeybinddialog.h" -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "llviewermenu.h" // physics display changes #include "llspatialpartition.h" @@ -181,7 +180,7 @@ #include "llviewergesture.h" #include "llviewertexturelist.h" #include "llviewerinventory.h" -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "llviewermedia.h" #include "llviewermediafocus.h" #include "llviewermenu.h" @@ -990,18 +989,7 @@ LLViewerWindow::Params::Params() {} -void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask) -{ - if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) - { - // If the current tool didn't process the click, we should show - // the pie menu. This can be done by passing the event to the pie - // menu tool. - LLToolPie::getInstance()->handleRightMouseDown(x, y, mask); - } -} - -BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) +BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) { const char* buttonname = ""; const char* buttonstatestr = ""; @@ -1025,30 +1013,28 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m switch (clicktype) { - case CLICK_LEFT: + case LLMouseHandler::CLICK_LEFT: mLeftMouseDown = down; buttonname = "Left"; break; - case CLICK_RIGHT: + case LLMouseHandler::CLICK_RIGHT: mRightMouseDown = down; buttonname = "Right"; break; - case CLICK_MIDDLE: + case LLMouseHandler::CLICK_MIDDLE: mMiddleMouseDown = down; buttonname = "Middle"; break; - case CLICK_DOUBLELEFT: + case LLMouseHandler::CLICK_DOUBLELEFT: mLeftMouseDown = down; buttonname = "Left Double Click"; break; - case CLICK_BUTTON4: + case LLMouseHandler::CLICK_BUTTON4: buttonname = "Button 4"; break; - case CLICK_BUTTON5: + case LLMouseHandler::CLICK_BUTTON5: buttonname = "Button 5"; break; - default: - break; // COUNT and NONE } LLView::sMouseHandlerMessage.clear(); @@ -1099,11 +1085,6 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname)); } - else if (down && clicktype == CLICK_RIGHT) - { - handlePieMenu(x, y, mask); - r = TRUE; - } return r; } @@ -1150,12 +1131,7 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m return TRUE; } - if (down && clicktype == CLICK_RIGHT) - { - handlePieMenu(x, y, mask); - return TRUE; - } - + // If we got this far on a down-click, it wasn't handled. // Up-clicks, though, are always handled as far as the OS is concerned. BOOL default_rtn = !down; @@ -1174,8 +1150,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask mMouseDownTimer.reset(); } BOOL down = TRUE; - //handleMouse() loops back to LLViewerWindow::handleAnyMouseClick - return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down); + return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); } BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1183,7 +1158,8 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma // try handling as a double-click first, then a single-click if that // wasn't handled. BOOL down = TRUE; - if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down)) + if (handleAnyMouseClick(window, pos, mask, + LLMouseHandler::CLICK_DOUBLELEFT, down)) { return TRUE; } @@ -1197,24 +1173,47 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) mMouseDownTimer.stop(); } BOOL down = FALSE; - return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down); + return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); } + + BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { + S32 x = pos.mX; + S32 y = pos.mY; + x = ll_round((F32)x / mDisplayScale.mV[VX]); + y = ll_round((F32)y / mDisplayScale.mV[VY]); + BOOL down = TRUE; - return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); + BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); + if (handle) + return handle; + + // *HACK: this should be rolled into the composite tool logic, not + // hardcoded at the top level. + if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) + { + // If the current tool didn't process the click, we should show + // the pie menu. This can be done by passing the event to the pie + // menu tool. + LLToolPie::getInstance()->handleRightMouseDown(x, y, mask); + // show_context_menu( x, y, mask ); + } + + return TRUE; } BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down); + return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); } BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = TRUE; - gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true); + handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); // Always handled as far as the OS is concerned. return TRUE; @@ -1369,7 +1368,8 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false); + handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); // Always handled as far as the OS is concerned. return TRUE; @@ -1380,10 +1380,12 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask switch (button) { case 4: - gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON4, down); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down); + handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down); break; case 5: - gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON5, down); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down); + handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down); break; default: break; @@ -1530,6 +1532,9 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) { + // Let the voice chat code check for its PTT key. Note that this never affects event processing. + LLVoiceClient::getInstance()->keyDown(key, mask); + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) { gAgent.clearAFK(); @@ -1548,12 +1553,14 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) return FALSE; } - // remaps, handles ignored cases and returns back to viewer window. - return gViewerInput.handleKey(key, mask, repeated); + return gViewerKeyboard.handleKey(key, mask, repeated); } BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) { + // Let the voice chat code check for its PTT key. Note that this never affects event processing. + LLVoiceClient::getInstance()->keyUp(key, mask); + // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) @@ -1561,13 +1568,13 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) tool_inspectp->keyUp(key, mask); } - return gViewerInput.handleKeyUp(key, mask); + return gViewerKeyboard.handleKeyUp(key, mask); } void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) { LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); - gViewerInput.scanKey(key, key_down, key_up, key_level); + gViewerKeyboard.scanKey(key, key_down, key_up, key_level); return; // Be clear this function returns nothing } @@ -3113,14 +3120,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // hide tooltips on keypress LLToolTipMgr::instance().blockToolTips(); - // let menus handle navigation keys for navigation - if (LLSetKeyBindDialog::recordKey(key, mask)) - { - LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL; - LLViewerEventRecorder::instance().logKeyEvent(key,mask); - return TRUE; - } - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if (keyboard_focus @@ -3393,8 +3392,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) { if (mask != MASK_ALT) { - // remaps, handles ignored cases and returns back to viewer window. - return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); + return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); } } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b3e22d83cb..307e3f474f 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -176,9 +176,8 @@ public: void initWorldUI(); void setUIVisibility(bool); bool getUIVisibility(); - void handlePieMenu(S32 x, S32 y, MASK mask); - BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); // // LLWindowCallback interface implementation diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index d868719e6f..fa8f89dfd0 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -217,6 +217,8 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion() void LLVoiceClient::updateSettings() { setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled")); + std::string keyString = gSavedSettings.getString("PushToTalkButton"); + setPTTKey(keyString); setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle")); mDisableMic = gSavedSettings.getBOOL("VoiceDisableMic"); @@ -658,6 +660,32 @@ bool LLVoiceClient::getPTTIsToggle() return mPTTIsToggle; } +void LLVoiceClient::setPTTKey(std::string &key) +{ + // Value is stored as text for readability + if(key == "MiddleMouse") + { + mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE; + } + else if(key == "MouseButton4") + { + mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4; + } + else if (key == "MouseButton5") + { + mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5; + } + else + { + mPTTMouseButton = 0; + if(!LLKeyboard::keyFromString(key, &mPTTKey)) + { + // If the call failed, don't match any key. + key = KEY_NONE; + } + } +} + void LLVoiceClient::inputUserControlState(bool down) { if(mPTTIsToggle) @@ -678,6 +706,43 @@ void LLVoiceClient::toggleUserPTTState(void) setUserPTTState(!getUserPTTState()); } +void LLVoiceClient::keyDown(KEY key, MASK mask) +{ + if (gKeyboard->getKeyRepeated(key)) + { + // ignore auto-repeat keys + return; + } + + if (mPTTMouseButton == 0 && LLAgent::isActionAllowed("speak") && (key == mPTTKey)) + { + bool down = gKeyboard->getKeyDown(mPTTKey); + if (down) + { + inputUserControlState(down); + } + } + +} +void LLVoiceClient::keyUp(KEY key, MASK mask) +{ + if (mPTTMouseButton == 0 && (key == mPTTKey)) + { + bool down = gKeyboard->getKeyDown(mPTTKey); + if (!down) + { + inputUserControlState(down); + } + } +} +void LLVoiceClient::updateMouseState(S32 click, bool down) +{ + if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak")) + { + inputUserControlState(down); + } +} + //------------------------------------------- // nearby speaker accessors diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index ee67682d68..1bded82dd4 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -437,10 +437,16 @@ public: void setUsePTT(bool usePTT); void setPTTIsToggle(bool PTTIsToggle); bool getPTTIsToggle(); - + void setPTTKey(std::string &key); + void updateMicMuteLogic(); - + BOOL lipSyncEnabled(); + + // PTT key triggering + void keyDown(KEY key, MASK mask); + void keyUp(KEY key, MASK mask); + void updateMouseState(S32 click, bool down); boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 36657dab43..9f9ee03f63 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5283,11 +5283,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; } - bool selected = facep->getViewerObject()->isSelected(); - +// bool selected = facep->getViewerObject()->isSelected(); +// // if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects) // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c const LLViewerObject* pObj = facep->getViewerObject(); + bool selected = pObj->isSelected(); if ( (pObj->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) && ( (!RlvActions::isRlvEnabled()) || ( ((!pObj->isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(pObj->getRootEdit()))) && diff --git a/indra/newview/llwindowlistener.cpp b/indra/newview/llwindowlistener.cpp index aa8c79b0d2..9e4297baaf 100644 --- a/indra/newview/llwindowlistener.cpp +++ b/indra/newview/llwindowlistener.cpp @@ -37,7 +37,7 @@ #include "llview.h" #include "llviewinject.h" #include "llviewerwindow.h" -#include "llviewerinput.h" +#include "llviewerkeyboard.h" #include "llrootview.h" #include "llsdutil.h" #include "stringize.h" @@ -279,7 +279,7 @@ void LLWindowListener::keyDown(LLSD const & evt) response.setResponse(target_view->getInfo()); gFocusMgr.setKeyboardFocus(target_view); - gViewerInput.handleKey(key, mask, false); + gViewerKeyboard.handleKey(key, mask, false); if(key < 0x80) mWindow->handleUnicodeChar(key, mask); } else @@ -291,7 +291,7 @@ void LLWindowListener::keyDown(LLSD const & evt) } else { - gViewerInput.handleKey(key, mask, false); + gViewerKeyboard.handleKey(key, mask, false); if(key < 0x80) mWindow->handleUnicodeChar(key, mask); } } diff --git a/indra/newview/quickprefs.cpp b/indra/newview/quickprefs.cpp index 0b9a7c091b..d787bef23a 100644 --- a/indra/newview/quickprefs.cpp +++ b/indra/newview/quickprefs.cpp @@ -52,12 +52,12 @@ #include "llspinctrl.h" #include "lltoolbarview.h" #include "llviewercontrol.h" +#include "llviewernetwork.h" // for LLGridManager #include "llviewerregion.h" #include "llvoavatar.h" #include "llvoavatarself.h" #include "rlvhandler.h" -std::string unescape_name(const std::string& name); class FSSettingsCollector : public LLInventoryCollectFunctor { public: @@ -288,6 +288,27 @@ void FloaterQuickPrefs::loadDayCyclePresets(const std::multimapadd(preset_name, LLSD(asset_id)); } } +// Opensim legacy windlight support +// Opensim may support both environment and extenvironment caps on the same region +// we also need these disabled in SL on the OpenSim build. +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + LL_DEBUGS("WindlightCaps") << "Adding legacy day cycle presets to QP" << LL_ENDL; + // WL still supported + if (!daycycle_map.empty() && !LLEnvironment::getInstance()->mLegacyDayCycles.empty()) + { + mDayCyclePresetsCombo->addSeparator(); + } + for(const auto& preset_name : LLEnvironment::getInstance()->mLegacyDayCycles) + { + // we add by name and only build the envp on demand + LL_DEBUGS("WindlightCaps") << "Adding legacy day cycle " << preset_name << LL_ENDL; + mDayCyclePresetsCombo->add(preset_name, LLSD(preset_name)); + } + LL_DEBUGS("WindlightCaps") << "Done: Adding legacy day cycle presets to QP" << LL_ENDL; + } +#endif } void FloaterQuickPrefs::loadSkyPresets(const std::multimap& sky_map) @@ -308,6 +329,27 @@ void FloaterQuickPrefs::loadSkyPresets(const std::multimap& mWLPresetsCombo->add(preset_name, LLSD(asset_id)); } } +// Opensim legacy windlight support +// Opensim may support both environment and extenvironment caps on the same region +// we also need these disabled in SL on the OpenSim build. +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + LL_DEBUGS("WindlightCaps") << "Adding legacy sky presets to QP" << LL_ENDL; + // WL still supported + if (!sky_map.empty() && !LLEnvironment::getInstance()->mLegacySkies.empty()) + { + mWLPresetsCombo->addSeparator(); + } + for(const auto& preset_name : LLEnvironment::getInstance()->mLegacySkies) + { + // we add by name and only build the envp on demand + LL_DEBUGS("WindlightCaps") << "Adding legacy sky " << preset_name << LL_ENDL; + mWLPresetsCombo->add(preset_name, LLSD(preset_name)); + } + LL_DEBUGS("WindlightCaps") << "Done: Adding legacy sky presets to QP" << LL_ENDL; + } +#endif } void FloaterQuickPrefs::loadWaterPresets(const std::multimap& water_map) @@ -328,6 +370,27 @@ void FloaterQuickPrefs::loadWaterPresets(const std::multimapadd(preset_name, LLSD(asset_id)); } } +// Opensim legacy windlight support +// Opensim may support both environment and extenvironment caps on the same region +// we also need these disabled in SL on the OpenSim build. +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + LL_DEBUGS("WindlightCaps") << "Adding legacy presets to QP" << LL_ENDL; + // WL still supported + if (!water_map.empty() && !LLEnvironment::getInstance()->mLegacyWater.empty()) + { + mWaterPresetsCombo->addSeparator(); + } + for(const auto& preset_name : LLEnvironment::getInstance()->mLegacyWater) + { + // we add by name and only build the envp on demand + LL_DEBUGS("WindlightCaps") << "Adding legacy water " << preset_name << LL_ENDL; + mWaterPresetsCombo->add(preset_name, LLSD(preset_name)); + } + LL_DEBUGS("WindlightCaps") << "Done: Adding legacy water presets to QP" << LL_ENDL; + } +#endif } void FloaterQuickPrefs::loadPresets() @@ -388,33 +451,109 @@ void FloaterQuickPrefs::setSelectedEnvironment() // day cycle. If no fixed sky or fixed water is set, they are either // defined in the day cycle or inherited from a higher environment level. LLSettingsDay::ptr_t day = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_LOCAL); - if (day && day->getAssetId().notNull()) + if (day) { //LL_INFOS() << "EEP: day name = " << day->getName() << " - asset id = " << day->getAssetId() << LL_ENDL; - - mDayCyclePresetsCombo->selectByValue(LLSD(day->getAssetId())); - - // Water is part of a day cycle - mWLPresetsCombo->selectByValue(LLSD(PRESET_NAME_DAY_CYCLE)); - mWaterPresetsCombo->selectByValue(LLSD(PRESET_NAME_DAY_CYCLE)); + if( day->getAssetId().notNull()) + { // EEP processing + mDayCyclePresetsCombo->selectByValue(LLSD(day->getAssetId())); + // Sky and Water are part of a day cycle in EEP + mWLPresetsCombo->selectByValue(LLSD(PRESET_NAME_DAY_CYCLE)); + mWaterPresetsCombo->selectByValue(LLSD(PRESET_NAME_DAY_CYCLE)); + } +#ifdef OPENSIM + else if (LLGridManager::getInstance()->isInOpenSim()) + { + auto preset_name = day->getName(); + LL_DEBUGS("WindlightCaps") << "Current Day cycle is " << preset_name << LL_ENDL; + if (preset_name == "_default_") + { + preset_name = "Default"; + } + mDayCyclePresetsCombo->selectByValue(preset_name); + // Sky is part of day so treat that as day cycle + mWLPresetsCombo->selectByValue(LLSD(PRESET_NAME_DAY_CYCLE)); + // Water is not part of legacy day so we need to hunt around + LLSettingsWater::ptr_t water = LLEnvironment::instance().getEnvironmentFixedWater(LLEnvironment::ENV_LOCAL); + if (water) + { + // This is going to be possible. OS will support both Legacy and EEP + // so having a water EEP asset with a Legacy day cycle could happen. + LLUUID asset_id = water->getAssetId(); + if (asset_id.notNull()) + { + mWaterPresetsCombo->selectByValue(LLSD(asset_id)); + } + else + { + //mWaterPresetsCombo->selectByValue(LLSD(water->getName())); + std::string preset_name = water->getName(); + if (preset_name == "_default_") + { + preset_name = "Default"; + } + mWaterPresetsCombo->selectByValue(preset_name); + } + } + } +#endif //OPENSIM + } + else + { + mDayCyclePresetsCombo->selectByValue(LLSD(PRESET_NAME_NONE)); } LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL); - if (sky && sky->getAssetId().notNull()) + if (sky) { //LL_INFOS() << "EEP: sky name = " << sky->getName() << " - asset id = " << sky->getAssetId() << LL_ENDL; - - mWLPresetsCombo->selectByValue(LLSD(sky->getAssetId())); + if(sky->getAssetId().notNull()) + { + mWLPresetsCombo->selectByValue(LLSD(sky->getAssetId())); + } +#ifdef OPENSIM + else if (LLGridManager::getInstance()->isInOpenSim()) + { + auto preset_name = sky->getName(); + LL_DEBUGS("WindlightCaps") << "Current Sky is " << preset_name << LL_ENDL; + if (preset_name == "_default_") + { + preset_name = "Default"; + } + mWLPresetsCombo->selectByValue(preset_name); + } +#endif } - + // Water is not part of legacy day so we need to hunt around LLSettingsWater::ptr_t water = LLEnvironment::instance().getEnvironmentFixedWater(LLEnvironment::ENV_LOCAL); - if (water && water->getAssetId().notNull()) + if (water) { - //LL_INFOS() << "EEP: water name = " << water->getName() << " - asset id = " << water->getAssetId() << LL_ENDL; - - mWaterPresetsCombo->selectByValue(LLSD(water->getAssetId())); + LLUUID asset_id = water->getAssetId(); + if (asset_id.notNull()) + { + mWaterPresetsCombo->selectByValue(LLSD(asset_id)); + } +#ifdef OPENSIM + else if (LLGridManager::getInstance()->isInOpenSim()) + { + auto preset_name = water->getName(); + if (preset_name == "_default_") + { + preset_name = "Default"; + } + mWaterPresetsCombo->selectByValue(preset_name); + } +#endif //OPENSIM } } + else + { + // LLEnvironment::ENV_REGION: + // LLEnvironment::ENV_PARCEL: + mWLPresetsCombo->selectByValue(LLSD(PRESET_NAME_REGION_DEFAULT)); + mWaterPresetsCombo->selectByValue(LLSD(PRESET_NAME_REGION_DEFAULT)); + mDayCyclePresetsCombo->selectByValue(LLSD(PRESET_NAME_REGION_DEFAULT)); + } } BOOL FloaterQuickPrefs::postBuild() @@ -631,11 +770,21 @@ void FloaterQuickPrefs::loadSavedSettingsFromFile(const std::string& settings_pa bool FloaterQuickPrefs::isValidPreset(const LLSD& preset) { - return (!preset.asString().empty() && - !preset.asUUID().isNull() && - preset.asString() != PRESET_NAME_REGION_DEFAULT && - preset.asString() != PRESET_NAME_DAY_CYCLE && - preset.asString() != PRESET_NAME_NONE); + if (preset.isUUID()) + { + if(!preset.asUUID().isNull()){ return true;} + } + else if (preset.isString()) + { + if(!preset.asString().empty() && + preset.asString() != PRESET_NAME_REGION_DEFAULT && + preset.asString() != PRESET_NAME_DAY_CYCLE && + preset.asString() != PRESET_NAME_NONE) + { + return true; + } + } + return false; } void FloaterQuickPrefs::stepComboBox(LLComboBox* ctrl, bool forward) @@ -663,21 +812,88 @@ void FloaterQuickPrefs::stepComboBox(LLComboBox* ctrl, bool forward) void FloaterQuickPrefs::selectSkyPreset(const LLSD& preset) { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); +// Opensim continued W/L support +#ifdef OPENSIM + if(!preset.isUUID() && LLGridManager::getInstance()->isInOpenSim()) + { + LLSettingsSky::ptr_t legacy_sky = nullptr; + LLSD messages; + + legacy_sky = LLEnvironment::createSkyFromLegacyPreset(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "skies", preset.asString() + ".xml"), messages); + + if (legacy_sky) + { + // Need to preserve current sky manually in this case in contrast to asset-based settings + LLSettingsWater::ptr_t current_water = LLEnvironment::instance().getCurrentWater(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, legacy_sky, current_water); + } + else + { + LL_WARNS() << "Legacy windlight conversion failed for " << preset << " existing env unchanged." << LL_ENDL; + return; + } + } + else // note the else here bridges the endif +#endif + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); + } LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); } void FloaterQuickPrefs::selectWaterPreset(const LLSD& preset) { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); +#ifdef OPENSIM + if(!preset.isUUID() && LLGridManager::getInstance()->isInOpenSim()) + { + LLSettingsWater::ptr_t legacy_water = nullptr; + LLSD messages; + legacy_water = LLEnvironment::createWaterFromLegacyPreset(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "water", preset.asString() + ".xml"), messages); + if (legacy_water) + { + // Need to preserve current sky manually in this case in contrast to asset-based settings + LLSettingsSky::ptr_t current_sky = LLEnvironment::instance().getCurrentSky(); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, current_sky, legacy_water); + } + else + { + LL_WARNS() << "Legacy windlight conversion failed for " << preset << " existing env unchanged." << LL_ENDL; + return; + } + } + else // beware the trailing else here. +#endif + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); + } LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); } void FloaterQuickPrefs::selectDayCyclePreset(const LLSD& preset) { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); +#ifdef OPENSIM + if(!preset.isUUID() && LLGridManager::getInstance()->isInOpenSim()) + { + LLSettingsDay::ptr_t legacyday = nullptr; + LLSD messages; + legacyday = LLEnvironment::createDayCycleFromLegacyPreset(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "days", preset.asString() + ".xml"), messages); + if (legacyday) + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, legacyday); + } + else + { + LL_WARNS() << "Legacy windlight conversion failed for " << preset << " existing env unchanged." << LL_ENDL; + return; + } + } + else // beware trailing else that bridges the endif +#endif + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, preset.asUUID()); + } LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); } @@ -943,18 +1159,11 @@ void FloaterQuickPrefs::updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamT { if (behavior == RLV_BHVR_SETENV) { - if (type == RLV_TYPE_ADD) - { - enableWindlightButtons(FALSE); - } - else - { - enableWindlightButtons(TRUE); - } + enableWindlightButtons(type != RLV_TYPE_ADD); } } -void FloaterQuickPrefs::enableWindlightButtons(BOOL enable) +void FloaterQuickPrefs::enableWindlightButtons(bool enable) { childSetEnabled("WLPresetsCombo", enable); childSetEnabled("WLPrevPreset", enable); diff --git a/indra/newview/quickprefs.h b/indra/newview/quickprefs.h index 187ce3e10d..ce8f286b9d 100644 --- a/indra/newview/quickprefs.h +++ b/indra/newview/quickprefs.h @@ -91,7 +91,7 @@ private: boost::signals2::connection mRlvBehaviorCallbackConnection; void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type); - void enableWindlightButtons(BOOL enable); + void enableWindlightButtons(bool enable); public: /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 9314c3479a..956a6c90c2 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -42,7 +42,7 @@ bool RlvActions::canChangeCameraPreset(const LLUUID& idRlvObject) // NOTE: if an object has exclusive camera control then all other objects are locked out return ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || (gRlvHandler.hasBehaviour(idRlvObject, RLV_BHVR_SETCAM)) ) && - (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); + (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSETSCALE)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); } bool RlvActions::canChangeToMouselook() @@ -70,7 +70,9 @@ bool RlvActions::isCameraFOVClamped() bool RlvActions::isCameraPresetLocked() { - return (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); + return + (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || + (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSETSCALE)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); } bool RlvActions::getCameraAvatarDistanceLimits(float& nDistMin, float& nDistMax) @@ -353,6 +355,15 @@ bool RlvActions::isLocalTp(const LLVector3d& posGlobal) return nDistSq < RLV_MODIFIER_TPLOCAL_DEFAULT * RLV_MODIFIER_TPLOCAL_DEFAULT; } +// ============================================================================ +// WindLight +// + +bool RlvActions::canChangeEnvironment() +{ + return !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV); +} + // ============================================================================ // World interaction // diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 90b1069f6b..be22f4ce6a 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -26,6 +26,7 @@ class LLInventoryCategory; class LLInventoryItem; +class LLViewerObject; // ============================================================================ // RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible @@ -207,6 +208,16 @@ public: */ static bool isLocalTp(const LLVector3d& posGlobal); + // ========= + // WindLight + // ========= +public: + /* + * Returns true if the user can make changes to their WindLight environment + */ + static bool canChangeEnvironment(); + + // ================= // World interaction // ================= diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 9eaea8d394..fa52c0ed99 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -346,8 +346,11 @@ void RlvStrings::saveToFile(const std::string& strFilePath) // Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a std::string RlvStrings::getAnonym(const std::string& strName) { - if (!rlv_handler_t::isEnabled()) - return strName; + static const std::string strUnknown = LLTrans::getString("Unknown"); + if ( (!RlvActions::isRlvEnabled()) || (m_Anonyms.empty()) ) + { + return strUnknown; + } const char* pszName = strName.c_str(); U32 nHash = 0; @@ -438,6 +441,11 @@ std::string RlvStrings::getVersionNum(const LLUUID& idRlvObject) (!fCompatMode) ? RLV_VERSION_PATCH : RLV_VERSION_PATCH_COMPAT, (!fCompatMode) ? RLV_VERSION_BUILD : RLV_VERSION_BUILD_COMPAT); } +std::string RlvStrings::getVersionImplNum() +{ + return llformat("%d%02d%02d%02d", RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH, RLVa_IMPL_ID); +} + // Checked: 2011-11-08 (RLVa-1.5.0) bool RlvStrings::hasString(const std::string& strStringName, bool fCheckCustom) { @@ -733,8 +741,13 @@ void rlvMenuToggleVisible() bool rlvMenuCanShowName() { - const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); - return (pAvatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, pAvatar->getID())); + bool fEnable = true; + if (rlv_handler_t::isEnabled()) + { + const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + fEnable = (pAvatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, pAvatar->getID())); + } + return fEnable; } // Checked: 2010-04-23 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 50dc08283f..62b7c0ab6d 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -57,7 +57,7 @@ class RlvObject; struct RlvException; typedef boost::variant RlvExceptionOption; -typedef boost::variant RlvBehaviourModifierValue; +typedef boost::variant RlvBehaviourModifierValue; class RlvGCTimer; @@ -152,6 +152,7 @@ public: static const std::string& getStringMapPath() { return m_StringMapPath; } static std::string getVersion(const LLUUID& idRlvObject, bool fLegacy = false); static std::string getVersionAbout(); + static std::string getVersionImplNum(); static std::string getVersionNum(const LLUUID& idRlvObject); static bool hasString(const std::string& strStringName, bool fCheckCustom = false); static void setCustomString(const std::string& strStringName, const std::string& strStringValue); diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 322218f1c7..9ce476ee5c 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -23,8 +23,8 @@ // Version of the specifcation we report const S32 RLV_VERSION_MAJOR = 3; -const S32 RLV_VERSION_MINOR = 2; -const S32 RLV_VERSION_PATCH = 1; +const S32 RLV_VERSION_MINOR = 3; +const S32 RLV_VERSION_PATCH = 3; const S32 RLV_VERSION_BUILD = 0; // Version of the specifcation we report (in compatibility mode) @@ -35,8 +35,9 @@ const S32 RLV_VERSION_BUILD_COMPAT = 0; // Implementation version const S32 RLVa_VERSION_MAJOR = 2; -const S32 RLVa_VERSION_MINOR = 2; +const S32 RLVa_VERSION_MINOR = 3; const S32 RLVa_VERSION_PATCH = 0; +const S32 RLVa_IMPL_ID = 13; // Uncomment before a final release #define RLV_RELEASE @@ -180,6 +181,7 @@ enum ERlvBehaviour { RLV_BHVR_DETACHTHIS, // "detachthis" RLV_BHVR_DETACHTHISEXCEPT, // "detachthis_except" RLV_BHVR_ADJUSTHEIGHT, // "adjustheight" + RLV_BHVR_GETHEIGHTOFFSET, // "getheightoffset" RLV_BHVR_TPTO, // "tpto" RLV_BHVR_VERSION, // "version" RLV_BHVR_VERSIONNEW, // "versionnew" @@ -213,6 +215,7 @@ enum ERlvBehaviour { RLV_BHVR_SETCAM_ORIGINDISTMIN, // Enforces a minimum distance from the camera origin (in m) RLV_BHVR_SETCAM_ORIGINDISTMAX, // Enforces a maximum distance from the camera origin (in m) RLV_BHVR_SETCAM_EYEOFFSET, // Changes the default camera offset + RLV_BHVR_SETCAM_EYEOFFSETSCALE, // Changes the default camera offset scale RLV_BHVR_SETCAM_FOCUSOFFSET, // Changes the default camera focus offset RLV_BHVR_SETCAM_FOCUS, // Forces the camera focus and/or position to a specific object, avatar or position RLV_BHVR_SETCAM_FOV, // Changes the current - vertical - field of view @@ -266,6 +269,7 @@ enum ERlvBehaviourModifier RLV_MODIFIER_SETCAM_ORIGINDISTMIN, // Minimum distance between the camera position and the origin point (normal value) RLV_MODIFIER_SETCAM_ORIGINDISTMAX, // Maximum distance between the camera position and the origin point (normal value) RLV_MODIFIER_SETCAM_EYEOFFSET, // Specifies the default camera's offset from the camera (vector) + RLV_MODIFIER_SETCAM_EYEOFFSETSCALE, // Specifies the default camera's offset scale (multiplier) RLV_MODIFIER_SETCAM_FOCUSOFFSET, // Specifies the default camera's focus (vector) RLV_MODIFIER_SETCAM_FOVMIN, // Minimum value for the camera's field of view (angle in radians) RLV_MODIFIER_SETCAM_FOVMAX, // Maximum value for the camera's field of view (angle in radians) diff --git a/indra/newview/rlvenvironment.cpp b/indra/newview/rlvenvironment.cpp new file mode 100644 index 0000000000..d723630fdb --- /dev/null +++ b/indra/newview/rlvenvironment.cpp @@ -0,0 +1,698 @@ +/** + * + * Copyright (c) 2009-2020, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#include "llviewerprecompiledheaders.h" + +#include "llinventoryfunctions.h" +#include "llsettingsvo.h" +#include + +#include "rlvactions.h" +#include "rlvenvironment.h" +#include "rlvhelper.h" + +// ================================================================================================ +// Constants and helper functions +// + +namespace +{ + const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f); + const F32 SLIDER_SCALE_DENSITY_MULTIPLIER(0.001f); + const F32 SLIDER_SCALE_GLOW_R(20.0f); + const F32 SLIDER_SCALE_GLOW_B(-5.0f); + const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f); + + const std::string RLV_GETENV_PREFIX = "getenv_"; + const std::string RLV_SETENV_PREFIX = "setenv_"; + + U32 rlvGetColorComponentFromCharacter(char ch) + { + if ( ('r' == ch) || ('x' == ch) ) return VRED; + else if ( ('g' == ch) || ('y' == ch )) return VGREEN; + else if ( ('b' == ch) || ('d' == ch) ) return VBLUE; + else if ('i' == ch) return VALPHA; + return U32_MAX; + } + + const LLUUID& rlvGetLibraryEnvironmentsFolder() + { + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLNameCategoryCollector f("Environments"); + gInventory.collectDescendentsIf(gInventory.getLibraryRootFolderID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, f); + return (!cats.empty()) ? cats.front()->getUUID() : LLUUID::null; + } + + // Legacy WindLight values we need tend to be expressed as a fraction of the [0, 2PI[ domain + F32 normalize_angle_domain(F32 angle) + { + while (angle < 0) + angle += F_TWO_PI; + while (angle > F_TWO_PI) + angle -= F_TWO_PI; + return angle; + } +} + +/* + * Reasoning (Reference - https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Azimuth-Altitude_schematic.svg/1024px-Azimuth-Altitude_schematic.svg.png) + * + * Given a(zimuth angle) and e(levation angle) - in the SL axis - we know that it calculates the quaternion as follows: + * + * | cos a sin a 0 | | cos e | | cos a x cos e | = | x | + * | sin a cos a 0 | x | 0 | = | sin a x cos e | = | y | (normalized direction vector identifying the sun position on a unit sphere) + * | 0 0 1 | | sin e | | sin e | = | z | + * + * As a result we can reverse the above by: quaternion -> rotate it around X-axis + * x = cos a x cos e <=> cos a = x / cos e \ + * | (if we divide them we can get rid of cos e) + * | <=> sin a / cos a = y / x <=> tan a = y / x <=> a = atan2(y, x) + * y = sin a x cos e <=> sin a = y / cos e / + * z = sin e <=> e = asin z + * + * If we look at the resulting domain azimuth lies in ]-PI, PI] and elevation lies in [-PI/2, PI/2] which I actually prefer most. Going forward people should get the sun in a wind + * direction by manipulating the azimuth and then deal with the elevation (which ends up mimicking how a camera or an observer behave in real life). + * + * Special cases: + * x = 0 => (1) cos e = 0 -> sin e = 1 so y = 0 and z = 1 => in (0, 0, 1) we loose all information about the azimuth since cos e = 0 + * OR (2) cos a = 0 -> sin a = 1 so y = cos e and z = sin e => tan e = z/y (with y != 0) => in (0, Y, Z) azimuth is PI/2 (or 3PI/2) and elevation can have an extended domain of ]-PI, PI] + * => When x = 0 (and y != 0) return PI/2 for azimuth and atan2(z, y) for elevation + * y = 0 => (1) sin a = 0 -> cos a = 1 so x = cos e and z = sin e => tan e = z/x (with x != 0) => in (X, 0, Z) azimuth is 0 (or PI) and elevation can have an extended domain of ]-PI, PI] + * OR (2) cos e = 0 -> see above + => When y = 0 (and x != 0) return 0 for azimuth and atan2(z, x) for elevation + * z = 0 => sin e = 0 -> cos e = 1 so x = cos a and y = sin a => tan a = y / x => in (X, Y, 0) elevation is 0 (or PI) and azimuth has its normal domain of ]-PI, PI] + * => When z = 0 return 0 for elevation and a = atan2(y, x) for azimuth + * + * We still need to convert all that back/forth between legacy WindLight's odd choices: + * east angle = SL's azimuth rotates from E (1, 0, 0) to N (0, 1, 0) to W (-1, 0, 0) to S (0, -1, O) but the legacy east angle rotates the opposite way from E to S to W to N so invert the angle + * (the resulting number then needs to be positive and reported as a fraction of 2PI) + * sunposition = sun elevation reported as a fraction of 2PI + * moonposition = the moon always has sun's azimuth but its negative elevation + * + * Pre-EEP both azimuth and elevation have a 2PI range which means that two different a and e value combinations could yield the same sun direction which causes us problems now since we + * can't differentiate between the two. Pre-EEP likely favoured elevation over azimuth since people might naturally get the time of day they're thinking of and then try to adjust the + * azimuth to get the sun in the correct wind direction; however I've already decided that we'll favour azimuth going forward (see above). + * + * Comparison of pre-EEP and post-EEP legacy values: + * east angle = 0 (aka azimuth = 0) -> y = 0 so e = atan2(z, x) -> elevation has a range of 2PI so we correctly report pre-EEP values + * sunmoonpos = 0 (aka elevation = 0) -> z = 0 so a = atan2(y, x) -> azimuth has a range of 2PI so we correctly report pre-EEP values + * -PI/2 < sunmoonpos < PI/2 -> general case -> post-EEP ranges match pre-EEP ranges so we correctly report pre-EEP values + * sunmoonpos > PI/2 -> elevation went beyond our new maxium so the post-EEP sunmoonpos will actually be off by PI/2 (or 0.25) + * (and the resulting east angle is off by PI or 0.5 - for example smp 0.375 and ea 0.875 are equivalent with smp 0.125 and ea 0.375) + * + * In reverse this means that when setting values through RLVa: + * sunmoonpos without eastangle (=0) => always correct + * eastangle without sunmoonpos (=0) => always correct + * eastangle before sunmoonpos => always correct + * sunmoonpos before eastangle => correct for -0.25 <= sunmoonpos <= 0.25 + * incorrect for 0.75 > sunmoonpos > 0.25 + */ +F32 rlvGetAzimuthFromDirectionVector(const LLVector3& vecDir) +{ + if (is_zero(vecDir.mV[VY])) + return 0.f; + else if (is_zero(vecDir.mV[VX])) + return F_PI_BY_TWO; + + F32 radAzimuth = atan2f(vecDir.mV[VY], vecDir.mV[VX]); + return (radAzimuth >= 0.f) ? radAzimuth : radAzimuth + F_TWO_PI; +} + +F32 rlvGetElevationFromDirectionVector(const LLVector3& vecDir) +{ + if (is_zero(vecDir.mV[VZ])) + return 0.f; + + F32 radElevation; + if ( (is_zero(vecDir.mV[VX])) && (!is_zero(vecDir.mV[VY])) ) + radElevation = atan2f(vecDir.mV[VZ], vecDir.mV[VY]); + else if ( (!is_zero(vecDir.mV[VX])) && (is_zero(vecDir.mV[VY])) ) + radElevation = atan2f(vecDir.mV[VZ], vecDir.mV[VX]); + else + radElevation = asinf(vecDir.mV[VZ]); + return (radElevation >= 0.f) ? radElevation : radElevation + F_TWO_PI; +} + +// Defined in llsettingssky.cpp +LLQuaternion convert_azimuth_and_altitude_to_quat(F32 azimuth, F32 altitude); + +// ================================================================================================ +// RlvIsOfSettingsType - Inventory collector for settings of a specific subtype +// + +class RlvIsOfSettingsType : public LLInventoryCollectFunctor +{ +public: + RlvIsOfSettingsType(LLSettingsType::type_e eSettingsType, const std::string& strNameMatch = LLStringUtil::null) + : m_eSettingsType(eSettingsType) + , m_strNameMatch(strNameMatch) + { + } + + ~RlvIsOfSettingsType() override + { + } + + bool operator()(LLInventoryCategory*, LLInventoryItem* pItem) override + { + if ( (pItem) && (LLAssetType::AT_SETTINGS == pItem->getActualType()) ) + { + return + (m_eSettingsType == LLSettingsType::fromInventoryFlags(pItem->getFlags())) && + ( (m_strNameMatch.empty()) || (boost::iequals(pItem->getName(), m_strNameMatch)) ); + } + return false; + } + +protected: + LLSettingsType::type_e m_eSettingsType; + std::string m_strNameMatch; +}; + +// ================================================================================================ +// RlvEnvironment +// + +RlvEnvironment::RlvEnvironment() +{ + // + // Presets + // + registerSetEnvFn("asset", [](LLEnvironment::EnvSelection_t env, const LLUUID& idAsset) + { + if (idAsset.isNull()) + return RLV_RET_FAILED_OPTION; + + LLEnvironment::instance().setEnvironment(env, idAsset); + return RLV_RET_SUCCESS; + }); + // Deprecated + auto fnApplyLibraryPreset = [](LLEnvironment::EnvSelection_t env, const std::string& strPreset, LLSettingsType::type_e eSettingsType) + { + LLUUID idAsset(strPreset); + if (idAsset.isNull()) + { + const LLUUID& idLibraryEnv = rlvGetLibraryEnvironmentsFolder(); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + RlvIsOfSettingsType f(eSettingsType, strPreset); + gInventory.collectDescendentsIf(idLibraryEnv, cats, items, LLInventoryModel::EXCLUDE_TRASH, f); + if (!items.empty()) + idAsset = items.front()->getAssetUUID(); + } + + if (idAsset.isNull()) + return RLV_RET_FAILED_OPTION; + + LLEnvironment::instance().setEnvironment(env, idAsset); + return RLV_RET_SUCCESS; + }; + registerSetEnvFn("preset", [&fnApplyLibraryPreset](LLEnvironment::EnvSelection_t env, const std::string& strPreset) { return fnApplyLibraryPreset(env, strPreset, LLSettingsType::ST_SKY); }); + registerSetEnvFn("daycycle", [&fnApplyLibraryPreset](LLEnvironment::EnvSelection_t env, const std::string& strPreset) { return fnApplyLibraryPreset(env, strPreset, LLSettingsType::ST_DAYCYCLE); }); + + // + // Atmosphere & Lighting tab + // + + // SETTING_AMBIENT + registerSkyFn("ambient", [](LLSettingsSky::ptr_t pSky) { return pSky->getAmbientColor() * (1.f / SLIDER_SCALE_SUN_AMBIENT); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setAmbientColor(clrValue * SLIDER_SCALE_SUN_AMBIENT); }); + registerLegacySkyFn("ambient",[](LLSettingsSky::ptr_t pSky) { return pSky->getAmbientColor() * (1.f / SLIDER_SCALE_SUN_AMBIENT); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setAmbientColor(clrValue * SLIDER_SCALE_SUN_AMBIENT); }); + + // SETTING_BLUE_DENSITY + registerSkyFn("bluedensity", [](LLSettingsSky::ptr_t pSky) { return pSky->getBlueDensity() * (1.f / SLIDER_SCALE_BLUE_HORIZON_DENSITY); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setBlueDensity(clrValue * SLIDER_SCALE_BLUE_HORIZON_DENSITY); }); + registerLegacySkyFn("bluedensity",[](LLSettingsSky::ptr_t pSky) { return pSky->getBlueDensity() * (1.f / SLIDER_SCALE_BLUE_HORIZON_DENSITY); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setBlueDensity(clrValue * SLIDER_SCALE_BLUE_HORIZON_DENSITY); }); + + // SETTING_BLUE_HORIZON + registerSkyFn("bluehorizon", [](LLSettingsSky::ptr_t pSky) { return pSky->getBlueHorizon() * (1.f / SLIDER_SCALE_BLUE_HORIZON_DENSITY); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setBlueHorizon(clrValue * SLIDER_SCALE_BLUE_HORIZON_DENSITY); }); + registerLegacySkyFn("bluehorizon",[](LLSettingsSky::ptr_t pSky) { return pSky->getBlueHorizon() * (1.f / SLIDER_SCALE_BLUE_HORIZON_DENSITY); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setBlueHorizon(clrValue * SLIDER_SCALE_BLUE_HORIZON_DENSITY); }); + + // SETTING_DENSITY_MULTIPLIER + registerSkyFn("densitymultiplier", [](LLSettingsSky::ptr_t pSky) { return pSky->getDensityMultiplier() / SLIDER_SCALE_DENSITY_MULTIPLIER; }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setDensityMultiplier(nValue * SLIDER_SCALE_DENSITY_MULTIPLIER); }); + + // SETTING_DISTANCE_MULTIPLIER + registerSkyFn("distancemultiplier",[](LLSettingsSky::ptr_t pSky) { return pSky->getDistanceMultiplier(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setDistanceMultiplier(nValue); }); + + + // SETTING_SKY_DROPLET_RADIUS + registerSkyFn("dropletradius", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyDropletRadius(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyDropletRadius(nValue); }); + + // SETTING_HAZE_DENSITY + registerSkyFn("hazedensity", [](LLSettingsSky::ptr_t pSky) { return pSky->getHazeDensity(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setHazeDensity(nValue); }); + + // SETTING_HAZE_HORIZON + registerSkyFn("hazehorizon", [](LLSettingsSky::ptr_t pSky) { return pSky->getHazeHorizon(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setHazeHorizon(nValue); }); + + // SETTING_SKY_ICE_LEVEL + registerSkyFn("icelevel", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyIceLevel(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyIceLevel(nValue); }); + + // SETTING_MAX_Y + registerSkyFn("maxaltitude", [](LLSettingsSky::ptr_t pSky) { return pSky->getMaxY(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMaxY(nValue); }); + + // SETTING_SKY_MOISTURE_LEVEL + registerSkyFn("moisturelevel", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyMoistureLevel(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyMoistureLevel(nValue); }); + + // SETTING_GAMMA + registerSkyFn("scenegamma", [](LLSettingsSky::ptr_t pSky) { return pSky->getGamma(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setGamma(nValue); }); + + // + // Clouds tab + // + + // SETTING_CLOUD_COLOR + registerSkyFn("cloudcolor", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudColor(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudColor(clrValue); }); + registerLegacySkyFn("cloudcolor", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudColor(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudColor(clrValue); }); + + // SETTING_CLOUD_SHADOW + registerSkyFn("cloudcoverage", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudShadow(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudShadow(nValue); }); + + // SETTING_CLOUD_POS_DENSITY1 + registerSkyFn("clouddensity", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity1(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity1(clrValue); }); + registerLegacySkyFn("cloud", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity1(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity1(clrValue); }); + + // SETTING_CLOUD_POS_DENSITY2 + registerSkyFn("clouddetail", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity2(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity2(clrValue); }); + registerLegacySkyFn("clouddetail",[](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity2(); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity2(clrValue); }); + + // SETTING_CLOUD_SCALE + registerSkyFn("cloudscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScale(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudScale(nValue); }); + + // SETTING_CLOUD_SCROLL_RATE + registerSkyFn("cloudscroll", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScrollRate(); }, + [](LLSettingsSky::ptr_t pSky, const LLVector2& vecValue) { pSky->setCloudScrollRate(vecValue); }); + registerLegacySkyFn("cloudscroll", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScrollRate(); }, + [](LLSettingsSky::ptr_t pSky, const LLVector2& vecValue) { pSky->setCloudScrollRate(vecValue); }); + + // SETTING_CLOUD_TEXTUREID + registerSkyFn("cloudtexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudNoiseTextureId(); }, + [](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setCloudNoiseTextureId(idTexture); }); + + // SETTING_CLOUD_VARIANCE + registerSkyFn("cloudvariance", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudVariance(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudVariance(nValue); }); + + // + // Sun & Moon + // + + // SETTING_MOON_BRIGHTNESS + registerSkyFn("moonbrightness", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonBrightness(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMoonBrightness(nValue); }); + + // SETTING_MOON_SCALE + registerSkyFn("moonscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonScale(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMoonScale(nValue); }); + + // SETTING_MOON_TEXTUREID + registerSkyFn("moontexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonTextureId(); }, + [](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setMoonTextureId(idTexture); }); + + // SETTING_GLOW + registerSkyFn("sunglowsize", [](LLSettingsSky::ptr_t pSky) { return 2.0 - (pSky->getGlow().mV[VRED] / SLIDER_SCALE_GLOW_R); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setGlow(LLColor3((2.0f - nValue) * SLIDER_SCALE_GLOW_R, .0f, pSky->getGlow().mV[VBLUE])); }); + registerSkyFn("sunglowfocus", [](LLSettingsSky::ptr_t pSky) { return pSky->getGlow().mV[VBLUE] / SLIDER_SCALE_GLOW_B; }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setGlow(LLColor3(pSky->getGlow().mV[VRED], .0f, nValue * SLIDER_SCALE_GLOW_B)); }); + + // SETTING_SUNLIGHT_COLOR + registerSkyFn("sunlightcolor",[](LLSettingsSky::ptr_t pSky) { return pSky->getSunlightColor() * (1.f / SLIDER_SCALE_SUN_AMBIENT); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setSunlightColor(clrValue * SLIDER_SCALE_SUN_AMBIENT); }); + registerLegacySkyFn("sunmooncolor", [](LLSettingsSky::ptr_t pSky) { return pSky->getSunlightColor() * (1.f / SLIDER_SCALE_SUN_AMBIENT); }, + [](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setSunlightColor(clrValue * SLIDER_SCALE_SUN_AMBIENT); }); + + // SETTING_SUN_SCALE + registerSkyFn("sunscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getSunScale(); }, + [](LLSettingsSky::ptr_t pSky, F32 nValue) { pSky->setSunScale(nValue); }); + + // SETTING_SUN_TEXTUREID + registerSkyFn("suntexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getSunTextureId(); }, + [](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setSunTextureId(idTexture); }); + + // SETTING_STAR_BRIGHTNESS + registerSkyFn("starbrightness", [](LLSettingsSky::ptr_t pSky) { return pSky->getStarBrightness(); }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setStarBrightness(nValue); }); + + // SETTING_SUN_ROTATION + registerSkyFn("sunazimuth", [](LLSettingsSky::ptr_t pSky) { return rlvGetAzimuthFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation()); }, + [](LLSettingsSky::ptr_t pSky, const F32& radAzimuth) { + pSky->setSunRotation(convert_azimuth_and_altitude_to_quat(radAzimuth, rlvGetElevationFromDirectionVector(LLVector3::x_axis* pSky->getSunRotation()))); + }); + registerSkyFn("sunelevation", [](LLSettingsSky::ptr_t pSky) { return rlvGetElevationFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation()); }, + [](LLSettingsSky::ptr_t pSky, F32 radElevation) { + radElevation = llclamp(radElevation, -F_PI_BY_TWO, F_PI_BY_TWO); + pSky->setSunRotation(convert_azimuth_and_altitude_to_quat(rlvGetAzimuthFromDirectionVector(LLVector3::x_axis* pSky->getSunRotation()), radElevation)); + }); + + // SETTING_MOON_ROTATION + registerSkyFn("moonazimuth", [](LLSettingsSky::ptr_t pSky) { return rlvGetAzimuthFromDirectionVector(LLVector3::x_axis * pSky->getMoonRotation()); }, + [](LLSettingsSky::ptr_t pSky, const F32& radAzimuth) { + pSky->setMoonRotation(convert_azimuth_and_altitude_to_quat(radAzimuth, rlvGetElevationFromDirectionVector(LLVector3::x_axis* pSky->getMoonRotation()))); + }); + registerSkyFn("moonelevation", [](LLSettingsSky::ptr_t pSky) { return rlvGetElevationFromDirectionVector(LLVector3::x_axis * pSky->getMoonRotation()); }, + [](LLSettingsSky::ptr_t pSky, F32 radElevation) { + radElevation = llclamp(radElevation, -F_PI_BY_TWO, F_PI_BY_TWO); + pSky->setMoonRotation(convert_azimuth_and_altitude_to_quat(rlvGetAzimuthFromDirectionVector(LLVector3::x_axis* pSky->getMoonRotation()), radElevation)); + }); + + // Legacy WindLight support (see remarks at the top of this file) + registerSkyFn("eastangle", [](LLSettingsSky::ptr_t pSky) { return normalize_angle_domain(-rlvGetAzimuthFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation())) / F_TWO_PI; }, + [](LLSettingsSky::ptr_t pSky, const F32& radEastAngle) + { + const F32 radAzimuth = -radEastAngle * F_TWO_PI; + const F32 radElevation = rlvGetElevationFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation()); + pSky->setSunRotation(convert_azimuth_and_altitude_to_quat(radAzimuth, radElevation)); + pSky->setMoonRotation(convert_azimuth_and_altitude_to_quat(radAzimuth + F_PI, -radElevation)); + }); + + registerSkyFn("sunmoonposition", [](LLSettingsSky::ptr_t pSky) { return rlvGetElevationFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation()) / F_TWO_PI; }, + [](LLSettingsSky::ptr_t pSky, const F32& nValue) + { + const F32 radAzimuth = rlvGetAzimuthFromDirectionVector(LLVector3::x_axis * pSky->getSunRotation()); + const F32 radElevation = nValue * F_TWO_PI; + pSky->setSunRotation(convert_azimuth_and_altitude_to_quat(radAzimuth, radElevation)); + pSky->setMoonRotation(convert_azimuth_and_altitude_to_quat(radAzimuth + F_PI, -radElevation)); + }); + + // Create a fixed sky from the nearest daycycle (local > experience > parcel > region) + registerSetEnvFn("daytime", [](LLEnvironment::EnvSelection_t env, const F32& nValue) + { + if ((nValue >= 0.f) && (nValue <= 1.0f)) + { + LLSettingsDay::ptr_t pDay; + if (LLEnvironment::ENV_EDIT != env) + { + LLEnvironment::EnvSelection_t envs[] = { LLEnvironment::ENV_LOCAL, LLEnvironment::ENV_PUSH, LLEnvironment::ENV_PARCEL, LLEnvironment::ENV_REGION }; + for (size_t idxEnv = 0, cntEnv = sizeof(envs) / sizeof(LLEnvironment::EnvSelection_t); idxEnv < cntEnv && !pDay; idxEnv++) + pDay = LLEnvironment::instance().getEnvironmentDay(envs[idxEnv]); + } + else + { + pDay = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_EDIT); + } + + if (pDay) + { + auto pNewSky = LLSettingsVOSky::buildDefaultSky(); + auto pSkyBlender = std::make_shared(pNewSky, pDay, 1); + pSkyBlender->setPosition(nValue); + + LLEnvironment::instance().setEnvironment(env, pNewSky); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } + } + else if (nValue == -1) + { + LLEnvironment::instance().clearEnvironment(env); + LLEnvironment::instance().setSelectedEnvironment(env); + LLEnvironment::instance().updateEnvironment(); +// defocusEnvFloaters(); + } + else + { + return RLV_RET_FAILED_OPTION; + } + + return RLV_RET_SUCCESS; + }); + registerGetEnvFn("daytime", [](LLEnvironment::EnvSelection_t env) + { + // I forgot how much I hate this command... it literally makes no sense since time of day only has any meaning in an + // actively animating day cycle (but in that case we have to return -1). + if (!LLEnvironment::instance().getEnvironmentFixedSky(env)) { + return std::to_string(-1.f); + } + + // It's invalid input for @setenv_daytime (see above) so it can be fed in without changing the current environment + return std::to_string(2.f); + }); +} + +RlvEnvironment::~RlvEnvironment() +{ +} + +// static +LLEnvironment::EnvSelection_t RlvEnvironment::getTargetEnvironment() +{ + return RlvActions::canChangeEnvironment() ? LLEnvironment::ENV_LOCAL : LLEnvironment::ENV_EDIT; +} + +// static +bool RlvEnvironment::onHandleCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet, const std::string& strCmdPrefix, const handler_map_t& fnLookup, const legacy_handler_map_t& legacyFnLookup) +{ + if ( (rlvCmd.getBehaviour().length() > strCmdPrefix.length() + 2) && (boost::starts_with(rlvCmd.getBehaviour(), strCmdPrefix)) ) + { + std::string strEnvCommand = rlvCmd.getBehaviour().substr(strCmdPrefix.length()); + + handler_map_t::const_iterator itFnEntry = fnLookup.find(strEnvCommand); + if (fnLookup.end() != itFnEntry) + { + cmdRet = itFnEntry->second((RLV_TYPE_FORCE == rlvCmd.getParamType()) ? rlvCmd.getOption() : rlvCmd.getParam()); + return true; + } + + // Legacy handling (blargh) + U32 idxComponent = rlvGetColorComponentFromCharacter(strEnvCommand.back()); + if (idxComponent <= VALPHA) + { + strEnvCommand.pop_back(); + + legacy_handler_map_t::const_iterator itLegacyFnEntry = legacyFnLookup.find(strEnvCommand); + if (legacyFnLookup.end() != itLegacyFnEntry) + { + cmdRet = itLegacyFnEntry->second((RLV_TYPE_FORCE == rlvCmd.getParamType()) ? rlvCmd.getOption() : rlvCmd.getParam(), idxComponent); + return true; + } + } + } + + return false; +} + +bool RlvEnvironment::onReplyCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) +{ + return onHandleCommand(rlvCmd, cmdRet, RLV_GETENV_PREFIX, m_GetFnLookup, m_LegacyGetFnLookup); +} + +bool RlvEnvironment::onForceCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) +{ + return onHandleCommand(rlvCmd, cmdRet, RLV_SETENV_PREFIX, m_SetFnLookup, m_LegacySetFnLookup); +} + +template<> +std::string RlvEnvironment::handleGetFn(const std::function& fn) +{ + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + return std::to_string(fn(pSky)); +} + +template<> +std::string RlvEnvironment::handleGetFn(const std::function& fn) +{ + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + return fn(pSky).asString(); +} + +template<> +std::string RlvEnvironment::handleGetFn(const std::function& fn) +{ + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + LLVector2 replyVec = fn(pSky); + return llformat("%f/%f", replyVec.mV[VX], replyVec.mV[VY]); +} + +template<> +std::string RlvEnvironment::handleGetFn(const std::function& fn) +{ + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + LLColor3 replyColor = fn(pSky); + return llformat("%f/%f/%f", replyColor.mV[VX], replyColor.mV[VY], replyColor.mV[VZ]); +} + +template +ERlvCmdRet RlvEnvironment::handleSetFn(const std::string& strRlvOption, const std::function& fn) +{ + T optionValue; + if (!RlvCommandOptionHelper::parseOption(strRlvOption, optionValue)) + return RLV_RET_FAILED_PARAM; + + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + fn(pSky, optionValue); + pSky->update(); + return RLV_RET_SUCCESS; +} + +template<> +std::string RlvEnvironment::handleLegacyGetFn(const std::function& getFn, U32 idxComponent) +{ + if (idxComponent > 2) + return LLStringUtil::null; + return std::to_string(getFn(LLEnvironment::instance().getCurrentSky()).mV[idxComponent]); +} + +template<> +std::string RlvEnvironment::handleLegacyGetFn(const std::function& getFn, U32 idxComponent) +{ + if ( (idxComponent >= VRED) && (idxComponent <= VBLUE) ) + { + return std::to_string(getFn(LLEnvironment::instance().getCurrentSky()).mV[idxComponent]); + } + else if (idxComponent == VALPHA) + { + const LLColor3& clr = getFn(LLEnvironment::instance().getCurrentSky()); + return std::to_string(llmax(clr.mV[VRED], clr.mV[VGREEN], clr.mV[VBLUE])); + } + return LLStringUtil::null; +} + +template<> +ERlvCmdRet RlvEnvironment::handleLegacySetFn(float optionValue, LLVector2 curValue, const std::function& setFn, U32 idxComponent) +{ + if (idxComponent > 2) + return RLV_RET_FAILED_UNKNOWN; + + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + curValue.mV[idxComponent] = optionValue; + setFn(pSky, curValue); + pSky->update(); + + return RLV_RET_SUCCESS; +} + +template<> +ERlvCmdRet RlvEnvironment::handleLegacySetFn(float optionValue, LLColor3 curValue, const std::function& setFn, U32 idxComponent) +{ + LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky(); + if ( (idxComponent >= VRED) && (idxComponent <= VBLUE) ) + { + curValue.mV[idxComponent] = optionValue; + } + else if (idxComponent == VALPHA) + { + const F32 curMax = llmax(curValue.mV[VRED], curValue.mV[VGREEN], curValue.mV[VBLUE]); + if ( (0.0f == optionValue) || (0.0f == curMax) ) + { + curValue.mV[VRED] = curValue.mV[VGREEN] = curValue.mV[VBLUE] = optionValue; + } + else + { + const F32 nDelta = (optionValue - curMax) / curMax; + curValue.mV[VRED] *= (1.0f + nDelta); + curValue.mV[VGREEN] *= (1.0f + nDelta); + curValue.mV[VBLUE] *= (1.0f + nDelta); + } + } + else + { + return RLV_RET_FAILED_UNKNOWN; + } + + setFn(pSky, curValue); + pSky->update(); + + return RLV_RET_SUCCESS; +} + + +template +void RlvEnvironment::registerSkyFn(const std::string& strFnName, const std::function& getFn, const std::function& setFn) +{ + RLV_ASSERT(m_GetFnLookup.end() == m_GetFnLookup.find(strFnName)); + m_GetFnLookup.insert(std::make_pair(strFnName, [this, getFn](const std::string& strRlvParam) + { + if (RlvUtil::sendChatReply(strRlvParam, handleGetFn(getFn))) + return RLV_RET_SUCCESS; + return RLV_RET_FAILED_PARAM; + })); + + RLV_ASSERT(m_SetFnLookup.end() == m_SetFnLookup.find(strFnName)); + m_SetFnLookup.insert(std::make_pair(strFnName, [this, setFn](const std::string& strRlvOption) + { + return handleSetFn(strRlvOption, setFn); + })); +} + +void RlvEnvironment::registerGetEnvFn(const std::string& strFnName, const std::function& getFn) +{ + RLV_ASSERT(m_GetFnLookup.end() == m_GetFnLookup.find(strFnName)); + m_GetFnLookup.insert(std::make_pair(strFnName, [getFn](const std::string& strRlvParam) + { + if (RlvUtil::sendChatReply(strRlvParam, getFn(getTargetEnvironment()))) + return RLV_RET_SUCCESS; + return RLV_RET_FAILED_PARAM; + })); +} + +template +void RlvEnvironment::registerSetEnvFn(const std::string& strFnName, const std::function& setFn) +{ + RLV_ASSERT(m_SetFnLookup.end() == m_SetFnLookup.find(strFnName)); + m_SetFnLookup.insert(std::make_pair(strFnName, [setFn](const std::string& strRlvOption) + { + T optionValue; + if (!RlvCommandOptionHelper::parseOption(strRlvOption, optionValue)) + return RLV_RET_FAILED_PARAM; + return setFn(getTargetEnvironment(), optionValue); + })); +} + +template +void RlvEnvironment::registerLegacySkyFn(const std::string& strFnName, const std::function& getFn, const std::function& setFn) +{ + RLV_ASSERT(m_LegacyGetFnLookup.end() == m_LegacyGetFnLookup.find(strFnName)); + m_LegacyGetFnLookup.insert(std::make_pair(strFnName, [this, getFn](const std::string& strRlvParam, U32 idxComponent) + { + const std::string strReply = handleLegacyGetFn(getFn, idxComponent); + if (strReply.empty()) + return RLV_RET_FAILED_UNKNOWN; + else if (RlvUtil::sendChatReply(strRlvParam, strReply)) + return RLV_RET_SUCCESS; + return RLV_RET_FAILED_PARAM; + })); + + RLV_ASSERT(m_LegacySetFnLookup.end() == m_LegacySetFnLookup.find(strFnName)); + m_LegacySetFnLookup.insert(std::make_pair(strFnName, [this, getFn, setFn](const std::string& strRlvOption, U32 idxComponent) + { + float optionValue; + if (!RlvCommandOptionHelper::parseOption(strRlvOption, optionValue)) + return RLV_RET_FAILED_PARAM; + return handleLegacySetFn(optionValue, getFn(LLEnvironment::instance().getCurrentSky()), setFn, idxComponent);; + })); +} + +// ================================================================================================ diff --git a/indra/newview/rlvenvironment.h b/indra/newview/rlvenvironment.h new file mode 100644 index 0000000000..0f70e24cae --- /dev/null +++ b/indra/newview/rlvenvironment.h @@ -0,0 +1,66 @@ +/** + * + * Copyright (c) 2009-2020, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#pragma once + +#include "llenvironment.h" + +#include "rlvcommon.h" + +// ============================================================================ +// RlvEnvironment - viewer-side scripted environment changes +// + +class RlvEnvironment : public RlvExtCommandHandler +{ +public: + RlvEnvironment(); + ~RlvEnvironment() override; + + bool onReplyCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) override; + bool onForceCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) override; +protected: + static LLEnvironment::EnvSelection_t getTargetEnvironment(); + typedef std::map> handler_map_t; + typedef std::map> legacy_handler_map_t; + static bool onHandleCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet, const std::string& strCmdPrefix, const handler_map_t& fnLookup, const legacy_handler_map_t& legacyFnLookup); + + /* + * Command registration + */ +protected: + void registerGetEnvFn(const std::string& strFnName, const std::function& getFn); + template void registerSetEnvFn(const std::string& strFnName, const std::function& setFn); + template void registerSkyFn(const std::string& strFnName, const std::function& getFn, const std::function& setFn); + template void registerLegacySkyFn(const std::string& strFnName, const std::function& getFn, const std::function& setFn); + + // Command handling helpers + template std::string handleGetFn(const std::function& fn); + template ERlvCmdRet handleSetFn(const std::string& strRlvOption, const std::function& fn); + template std::string handleLegacyGetFn(const std::function& getFn, U32 idxComponent); + template ERlvCmdRet handleLegacySetFn(float optionValue, T value, const std::function& setFn, U32 idxComponent); + + /* + * Member variables + */ +protected: + handler_map_t m_GetFnLookup; + handler_map_t m_SetFnLookup; + legacy_handler_map_t m_LegacyGetFnLookup; + legacy_handler_map_t m_LegacySetFnLookup; +}; + +// ============================================================================ diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp index 6e8924f90b..4612331c96 100644 --- a/indra/newview/rlvextensions.cpp +++ b/indra/newview/rlvextensions.cpp @@ -1,25 +1,23 @@ -/** +/** * * Copyright (c) 2009-2011, Kitty Barnett - * - * The source code in this file is provided to you under the terms of the + * + * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt - * + * * By copying, modifying or distributing this software, you acknowledge that - * you have read and understood your obligations described above, and agree to + * you have read and understood your obligations described above, and agree to * abide by those obligations. - * + * */ #include "llviewerprecompiledheaders.h" #include "llagent.h" #include "llagentcamera.h" -// #include "lldaycyclemanager.h" // [EEPMERGE] #include "llvoavatarself.h" -//#include "llwlparammanager.h" // [EEPMERGE] #include "rlvextensions.h" #include "rlvhandler.h" @@ -27,354 +25,6 @@ // ============================================================================ -#if 0// [EEPMERGE] -class RlvWindLightControl -{ -public: - enum EType { TYPE_COLOR, TYPE_COLOR_R, TYPE_FLOAT, TYPE_UNKNOWN }; - enum EColorComponent { COMPONENT_R, COMPONENT_G, COMPONENT_B, COMPONENT_I, COMPONENT_NONE }; -public: - RlvWindLightControl(WLColorControl* pCtrl, bool fColorR) : m_eType((!fColorR) ? TYPE_COLOR: TYPE_COLOR_R), m_pColourCtrl(pCtrl), m_pFloatCtrl(NULL) {} - RlvWindLightControl(WLFloatControl* pCtrl) : m_eType(TYPE_FLOAT), m_pColourCtrl(NULL), m_pFloatCtrl(pCtrl) {} - - EType getControlType() const { return m_eType; } - bool isColorType() const { return (TYPE_COLOR == m_eType) || (TYPE_COLOR_R == m_eType); } - bool isFloatType() const { return (TYPE_FLOAT == m_eType); } - // TYPE_COLOR and TYPE_COLOR_R - F32 getColorComponent(EColorComponent eComponent, bool& fError) const; - LLVector4 getColorVector(bool& fError) const; - bool setColorComponent(EColorComponent eComponent, F32 nValue); - // TYPE_FLOAT - F32 getFloat(bool& fError) const; - bool setFloat(F32 nValue); - - static EColorComponent getComponentFromCharacter(char ch); -protected: - EType m_eType; // Type of the WindLight control - WLColorControl* m_pColourCtrl; - WLFloatControl* m_pFloatCtrl; -}; - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -static F32 get_intensity_from_color(const LLVector4& v) -{ - return llmax(v.mV[0], v.mV[1], v.mV[2]); -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -F32 RlvWindLightControl::getColorComponent(EColorComponent eComponent, bool& fError) const -{ - switch (eComponent) - { - case COMPONENT_R: return getColorVector(fError).mV[0]; - case COMPONENT_G: return getColorVector(fError).mV[1]; - case COMPONENT_B: return getColorVector(fError).mV[2]; - case COMPONENT_I: return get_intensity_from_color(getColorVector(fError)); // SL-2.8: Always seems to be 1.0 so get it manually - default : RLV_ASSERT(false); fError = true; return 0.0; - } -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -RlvWindLightControl::EColorComponent RlvWindLightControl::getComponentFromCharacter(char ch) -{ - if (('r' == ch) || ('x' == ch)) - return COMPONENT_R; - else if (('g' == ch) || ('y' == ch)) - return COMPONENT_G; - else if (('b' == ch) || ('d' == ch)) - return COMPONENT_B; - else if ('i' == ch) - return COMPONENT_I; - return COMPONENT_NONE; -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -LLVector4 RlvWindLightControl::getColorVector(bool& fError) const -{ - if ((fError = !isColorType())) - return LLVector4(0, 0, 0, 0); - F32 nMult = (m_pColourCtrl->isSunOrAmbientColor) ? 3.0f : ((m_pColourCtrl->isBlueHorizonOrDensity) ? 2.0f : 1.0f); - return LLWLParamManager::getInstance()->mCurParams.getVector(m_pColourCtrl->mName, fError) / nMult; -} - -// Checked: 2011-08-28 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -bool RlvWindLightControl::setColorComponent(EColorComponent eComponent, F32 nValue) -{ - if (isColorType()) - { - nValue *= (m_pColourCtrl->isSunOrAmbientColor) ? 3.0f : ((m_pColourCtrl->isBlueHorizonOrDensity) ? 2.0f : 1.0f); - if (COMPONENT_I == eComponent) // (See: LLFloaterWindLight::onColorControlIMoved) - { - if (m_pColourCtrl->hasSliderName) - { - F32 curMax = llmax(m_pColourCtrl->r, m_pColourCtrl->g, m_pColourCtrl->b); - if ( (0.0f == nValue) || (0.0f == curMax) ) - { - m_pColourCtrl->r = m_pColourCtrl->g = m_pColourCtrl->b = m_pColourCtrl->i = nValue; - } - else - { - F32 nDelta = (nValue - curMax) / curMax; - m_pColourCtrl->r *= (1.0f + nDelta); - m_pColourCtrl->g *= (1.0f + nDelta); - m_pColourCtrl->b *= (1.0f + nDelta); - m_pColourCtrl->i = nValue; - } - } - } - else // (See: LLFloaterWindLight::onColorControlRMoved) - { - F32* pnValue = (COMPONENT_R == eComponent) ? &m_pColourCtrl->r : (COMPONENT_G == eComponent) ? &m_pColourCtrl->g : (COMPONENT_B == eComponent) ? &m_pColourCtrl->b : NULL; - if (pnValue) - *pnValue = nValue; - if (m_pColourCtrl->hasSliderName) - m_pColourCtrl->i = llmax(m_pColourCtrl->r, m_pColourCtrl->g, m_pColourCtrl->b); - } - m_pColourCtrl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); - } - return isColorType(); -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -F32 RlvWindLightControl::getFloat(bool& fError) const -{ - return (!(fError = (TYPE_FLOAT != m_eType))) ? LLWLParamManager::getInstance()->mCurParams.getVector(m_pFloatCtrl->mName, fError).mV[0] * m_pFloatCtrl->mult : 0.0; -} - -// Checked: 2011-08-28 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -bool RlvWindLightControl::setFloat(F32 nValue) -{ - if (TYPE_FLOAT == m_eType) - { - m_pFloatCtrl->x = nValue / m_pFloatCtrl->mult; - m_pFloatCtrl->update(LLWLParamManager::getInstance()->mCurParams); - LLWLParamManager::getInstance()->propagateParameters(); - } - return (TYPE_FLOAT == m_eType); -} - -// ============================================================================ - -class RlvWindLight : public LLSingleton -{ - LLSINGLETON(RlvWindLight); -public: - std::string getValue(const std::string& strSetting, bool& fError); - bool setValue(const std::string& strRlvName, const std::string& strValue); - -protected: - std::map m_ControlLookupMap; -}; - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -RlvWindLight::RlvWindLight() -{ - LLWLParamManager* pWLParamMgr = LLWLParamManager::getInstance(); - - // TYPE_FLOAT - m_ControlLookupMap.insert(std::pair("cloudcoverage", RlvWindLightControl(&pWLParamMgr->mCloudCoverage))); - m_ControlLookupMap.insert(std::pair("cloudscale", RlvWindLightControl(&pWLParamMgr->mCloudScale))); - m_ControlLookupMap.insert(std::pair("densitymultiplier", RlvWindLightControl(&pWLParamMgr->mDensityMult))); - m_ControlLookupMap.insert(std::pair("distancemultiplier", RlvWindLightControl(&pWLParamMgr->mDistanceMult))); - m_ControlLookupMap.insert(std::pair("maxaltitude", RlvWindLightControl(&pWLParamMgr->mMaxAlt))); - m_ControlLookupMap.insert(std::pair("scenegamma", RlvWindLightControl(&pWLParamMgr->mWLGamma))); - m_ControlLookupMap.insert(std::pair("hazedensity", RlvWindLightControl(&pWLParamMgr->mHazeDensity))); - m_ControlLookupMap.insert(std::pair("hazehorizon", RlvWindLightControl(&pWLParamMgr->mHazeHorizon))); - // TYPE_COLOR - m_ControlLookupMap.insert(std::pair("ambient", RlvWindLightControl(&pWLParamMgr->mAmbient, false))); - m_ControlLookupMap.insert(std::pair("bluedensity", RlvWindLightControl(&pWLParamMgr->mBlueDensity, false))); - m_ControlLookupMap.insert(std::pair("bluehorizon", RlvWindLightControl(&pWLParamMgr->mBlueHorizon, false))); - m_ControlLookupMap.insert(std::pair("cloud", RlvWindLightControl(&pWLParamMgr->mCloudMain, false))); - m_ControlLookupMap.insert(std::pair("cloudcolor", RlvWindLightControl(&pWLParamMgr->mCloudColor, false))); - m_ControlLookupMap.insert(std::pair("clouddetail", RlvWindLightControl(&pWLParamMgr->mCloudDetail, false))); - m_ControlLookupMap.insert(std::pair("sunmooncolor", RlvWindLightControl(&pWLParamMgr->mSunlight, false))); -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -std::string RlvWindLight::getValue(const std::string& strSetting, bool& fError) -{ - LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); - LLEnvManagerNew* pEnvMgr = LLEnvManagerNew::getInstance(); - - fError = false; // Assume we won't fail - if ("preset" == strSetting) - return (pEnvMgr->getUseFixedSky()) ? pEnvMgr->getSkyPresetName() : std::string(); - else if ("daycycle" == strSetting) - return (pEnvMgr->getUseDayCycle()) ? pEnvMgr->getDayCycleName() : std::string(); - - F32 nValue = 0.0f; - if ("daytime" == strSetting) - { - nValue = (pEnvMgr->getUseFixedSky()) ? pWLParams->mCurParams.getFloat("sun_angle", fError) / F_TWO_PI : -1.0f; - } - else if (("sunglowfocus" == strSetting) || ("sunglowsize" == strSetting)) - { - pWLParams->mGlow = pWLParams->mCurParams.getVector(pWLParams->mGlow.mName, fError); - RLV_ASSERT_DBG(!fError); - - if ("sunglowfocus" == strSetting) - nValue = -pWLParams->mGlow.b / 5.0f; - else - nValue = 2 - pWLParams->mGlow.r / 20.0f; - } - else if ("starbrightness" == strSetting) nValue = pWLParams->mCurParams.getStarBrightness(); - else if ("eastangle" == strSetting) nValue = pWLParams->mCurParams.getEastAngle() / F_TWO_PI; - else if ("sunmoonposition" == strSetting) nValue = pWLParams->mCurParams.getSunAngle() / F_TWO_PI; - else if ("cloudscrollx" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollX() - 10.0f; - else if ("cloudscrolly" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollY() - 10.0f; - else - { - std::map::const_iterator itControl = m_ControlLookupMap.find(strSetting); - if (m_ControlLookupMap.end() != itControl) - { - switch (itControl->second.getControlType()) - { - case RlvWindLightControl::TYPE_FLOAT: - nValue = itControl->second.getFloat(fError); - break; - case RlvWindLightControl::TYPE_COLOR_R: - nValue = itControl->second.getColorComponent(RlvWindLightControl::COMPONENT_R, fError); - break; - default: - fError = true; - break; - } - } - else - { - // Couldn't find the exact name, check for a color control name - RlvWindLightControl::EColorComponent eComponent = RlvWindLightControl::getComponentFromCharacter(strSetting[strSetting.length() - 1]); - if (RlvWindLightControl::COMPONENT_NONE != eComponent) - itControl = m_ControlLookupMap.find(strSetting.substr(0, strSetting.length() - 1)); - if ( (m_ControlLookupMap.end() != itControl) && (itControl->second.isColorType()) ) - nValue = itControl->second.getColorComponent(eComponent, fError); - else - fError = true; - } - } - return llformat("%f", nValue); -} - -// Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a -bool RlvWindLight::setValue(const std::string& strRlvName, const std::string& strValue) -{ - F32 nValue = 0.0f; - // Sanity check - make sure strValue specifies a number for all settings except "preset" and "daycycle" - if ( (RlvSettings::getNoSetEnv()) || - ( (!LLStringUtil::convertToF32(strValue, nValue)) && (("preset" != strRlvName) && ("daycycle" != strRlvName)) ) ) - { - return false; - } - - LLWLParamManager* pWLParams = LLWLParamManager::getInstance(); - LLEnvManagerNew* pEnvMgr = LLEnvManagerNew::getInstance(); - - if ("daytime" == strRlvName) - { - if (0.0f <= nValue) - { - pWLParams->mAnimator.deactivate(); - pWLParams->mAnimator.setDayTime(nValue); - pWLParams->mAnimator.update(pWLParams->mCurParams); - } - else - { - pEnvMgr->setUserPrefs(pEnvMgr->getWaterPresetName(), pEnvMgr->getSkyPresetName(), pEnvMgr->getDayCycleName(), false, true); - } - return true; - } - else if ("preset" == strRlvName) - { - std::string strPresetName = pWLParams->findPreset(strValue, LLEnvKey::SCOPE_LOCAL); - if (!strPresetName.empty()) - pEnvMgr->useSkyPreset(strPresetName); - return !strPresetName.empty(); - } - else if ("daycycle" == strRlvName) - { - std::string strPresetName = LLDayCycleManager::instance().findPreset(strValue); - if (!strPresetName.empty()) - pEnvMgr->useDayCycle(strValue, LLEnvKey::SCOPE_LOCAL); - return !strPresetName.empty(); - } - - bool fError = false; - pWLParams->mAnimator.deactivate(); - if (("sunglowfocus" == strRlvName) || ("sunglowsize" == strRlvName)) - { - pWLParams->mGlow = pWLParams->mCurParams.getVector(pWLParams->mGlow.mName, fError); - RLV_ASSERT_DBG(!fError); - - if ("sunglowfocus" == strRlvName) - pWLParams->mGlow.b = -nValue * 5; - else - pWLParams->mGlow.r = (2 - nValue) * 20; - - pWLParams->mGlow.update(pWLParams->mCurParams); - pWLParams->propagateParameters(); - return true; - } - else if ("starbrightness" == strRlvName) - { - pWLParams->mCurParams.setStarBrightness(nValue); - return true; - } - else if (("eastangle" == strRlvName) || ("sunmoonposition" == strRlvName)) - { - if ("eastangle" == strRlvName) - pWLParams->mCurParams.setEastAngle(F_TWO_PI * nValue); - else - pWLParams->mCurParams.setSunAngle(F_TWO_PI * nValue); - - // Set the sun vector - pWLParams->mLightnorm.r = -sin(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); - pWLParams->mLightnorm.g = sin(pWLParams->mCurParams.getSunAngle()); - pWLParams->mLightnorm.b = cos(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); - pWLParams->mLightnorm.i = 1.f; - - pWLParams->propagateParameters(); - return true; - } - else if ("cloudscrollx" == strRlvName) - { - pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f); - return true; - } - else if ("cloudscrolly" == strRlvName) - { - pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f); - return true; - } - - std::map::iterator itControl = m_ControlLookupMap.find(strRlvName); - if (m_ControlLookupMap.end() != itControl) - { - switch (itControl->second.getControlType()) - { - case RlvWindLightControl::TYPE_FLOAT: - return itControl->second.setFloat(nValue); - case RlvWindLightControl::TYPE_COLOR_R: - return itControl->second.setColorComponent(RlvWindLightControl::COMPONENT_R, nValue); - default: - RLV_ASSERT(false); - } - } - else - { - // Couldn't find the exact name, check for a color control name - RlvWindLightControl::EColorComponent eComponent = RlvWindLightControl::getComponentFromCharacter(strRlvName[strRlvName.length() - 1]); - if (RlvWindLightControl::COMPONENT_NONE != eComponent) - itControl = m_ControlLookupMap.find(strRlvName.substr(0, strRlvName.length() - 1)); - if ( (m_ControlLookupMap.end() != itControl) && (itControl->second.isColorType()) ) - return itControl->second.setColorComponent(eComponent, nValue); - } - return false; -} -#endif // [EEPMERGE] - -// ============================================================================ - std::map RlvExtGetSet::m_DbgAllowed; std::map RlvExtGetSet::m_PseudoDebug; @@ -441,27 +91,6 @@ bool RlvExtGetSet::processCommand(const RlvCommand& rlvCmd, ERlvCmdRet& eRet) return true; } } - else if ("env" == strBehaviour) - { - bool fError = false; - if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) - { - // [EEPMERGE] - //RlvUtil::sendChatReply(rlvCmd.getParam(), RlvWindLight::instance().getValue(strSetting, fError)); - eRet = (!fError) ? RLV_RET_SUCCESS : RLV_RET_FAILED_UNKNOWN; - return true; - } - else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) - { - // [EEPMERGE] - //if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, rlvCmd.getObjectID())) - // eRet = (RlvWindLight::instance().setValue(strSetting, rlvCmd.getOption())) ? RLV_RET_SUCCESS : RLV_RET_FAILED_UNKNOWN; - //else - // eRet = RLV_RET_FAILED_LOCK; - // [/EEPMERGE] - return true; - } - } } else if ("setrot" == rlvCmd.getBehaviour()) { diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 9184abd6cd..df2a7d3b68 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -37,8 +37,7 @@ #include "llavataractions.h" // @stopim IM query #include "llavatarnamecache.h" // @shownames #include "llavatarlist.h" // @shownames -// [EEPMERGE] -//#include "llenvmanager.h" // @setenv +#include "llfloatercamera.h" // @setcam family #include "llfloatersidepanelcontainer.h"// @shownames #include "llnotifications.h" // @list IM query #include "llnotificationsutil.h" @@ -57,6 +56,7 @@ // RLVa includes #include "rlvactions.h" +#include "rlvenvironment.h" #include "rlvfloaters.h" #include "rlvactions.h" #include "rlvhandler.h" @@ -152,14 +152,58 @@ RlvHandler::RlvHandler() : m_fCanCancelTp(true), m_posSitSource(), m_pGCTimer(NU RlvHandler::~RlvHandler() { + cleanup(); +} + +void RlvHandler::cleanup() +{ + // Nothing to clean if we're not enabled (or already cleaned up) + if (!m_fEnabled) + return; + + // + // Clean up any restrictions that are still active + // + RLV_ASSERT(LLApp::isQuitting()); // Several commands toggle debug settings but won't if they know the viewer is quitting + + // Assume we have no way to predict how m_Objects will change so make a copy ahead of time + uuid_vec_t idRlvObjects; + idRlvObjects.reserve(m_Objects.size()); + std::transform(m_Objects.begin(), m_Objects.end(), std::back_inserter(idRlvObjects), [](const rlv_object_map_t::value_type& kvPair) {return kvPair.first; }); + for (const LLUUID & idRlvObj : idRlvObjects) + { + processCommand(idRlvObj, "clear", true); + } + + // Sanity check + RLV_ASSERT(m_Objects.empty()); + RLV_ASSERT(m_Exceptions.empty()); + RLV_ASSERT(std::all_of(m_Behaviours, m_Behaviours + RLV_BHVR_COUNT, [](S16 cnt) { return !cnt; })); + RLV_ASSERT(m_CurCommandStack.empty()); + RLV_ASSERT(m_CurObjectStack.empty()); + RLV_ASSERT(m_pOverlayImage.isNull()); + + // + // Clean up what's left + // gAgent.removeListener(this); + m_Retained.clear(); + //delete m_pGCTimer; // <- deletes itself + if (m_PendingGroupChange.first.notNull()) { - LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + if (LLGroupMgr::instanceExists()) + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); } - //delete m_pGCTimer; // <- deletes itself + for (RlvExtCommandHandler* pCmdHandler : m_CommandHandlers) + { + delete pCmdHandler; + } + m_CommandHandlers.clear(); + + m_fEnabled = false; } // ============================================================================ @@ -401,42 +445,46 @@ bool RlvHandler::notifyCommandHandlers(rlvExtCommandHandler f, const RlvCommand& } // Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f -ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) +ERlvCmdRet RlvHandler::processCommand(std::reference_wrapper rlvCmd, bool fFromObj) { - RLV_DEBUGS << "[" << rlvCmd.getObjectID() << "]: " << rlvCmd.asString() << RLV_ENDL; + { + const RlvCommand& rlvCmdTmp = rlvCmd; // Reference to the temporary with limited variable scope since we don't want it to leak below - if ( (isBlockedObject(rlvCmd.getObjectID())) && (RLV_TYPE_REMOVE != rlvCmd.getParamType()) && (RLV_TYPE_CLEAR != rlvCmd.getParamType()) ) - { - RLV_DEBUGS << "\t-> blocked object" << RLV_ENDL; - return RLV_RET_FAILED_BLOCKED; - } - if (!rlvCmd.isValid()) - { - RLV_DEBUGS << "\t-> invalid syntax" << RLV_ENDL; - return RLV_RET_FAILED_SYNTAX; - } - if (rlvCmd.isBlocked()) - { - RLV_DEBUGS << "\t-> blocked command" << RLV_ENDL; - return RLV_RET_FAILED_DISABLED; + RLV_DEBUGS << "[" << rlvCmdTmp.getObjectID() << "]: " << rlvCmdTmp.asString() << RLV_ENDL; + + if ( (isBlockedObject(rlvCmdTmp.getObjectID())) && (RLV_TYPE_REMOVE != rlvCmdTmp.getParamType()) && (RLV_TYPE_CLEAR != rlvCmdTmp.getParamType()) ) + { + RLV_DEBUGS << "\t-> blocked object" << RLV_ENDL; + return RLV_RET_FAILED_BLOCKED; + } + if (!rlvCmdTmp.isValid()) + { + RLV_DEBUGS << "\t-> invalid syntax" << RLV_ENDL; + return RLV_RET_FAILED_SYNTAX; + } + if (rlvCmdTmp.isBlocked()) + { + RLV_DEBUGS << "\t-> blocked command" << RLV_ENDL; + return RLV_RET_FAILED_DISABLED; + } } // Using a stack for executing commands solves a few problems: // - if we passed RlvObject::m_idObj for idObj somewhere and process a @clear then idObj points to invalid/cleared memory at the end // - if command X triggers command Y along the way then getCurrentCommand()/getCurrentObject() still return Y even when finished - m_CurCommandStack.push(&rlvCmd); m_CurObjectStack.push(rlvCmd.getObjectID()); + m_CurCommandStack.push(rlvCmd); m_CurObjectStack.push(rlvCmd.get().getObjectID()); const LLUUID& idCurObj = m_CurObjectStack.top(); ERlvCmdRet eRet = RLV_RET_UNKNOWN; - switch (rlvCmd.getParamType()) + switch (rlvCmd.get().getParamType()) { case RLV_TYPE_ADD: // Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f { - if ( (m_Behaviours[rlvCmd.getBehaviourType()]) && - ( (RLV_BHVR_SETCAM == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) ) + ERlvBehaviour eBhvr = rlvCmd.get().getBehaviourType(); + if ( (m_Behaviours[eBhvr]) && ( (RLV_BHVR_SETCAM == eBhvr) || (RLV_BHVR_SETDEBUG == eBhvr) || (RLV_BHVR_SETENV == eBhvr) ) ) { // Some restrictions can only be held by one single object to avoid deadlocks - RLV_DEBUGS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << RLV_ENDL; + RLV_DEBUGS << "\t- " << rlvCmd.get().getBehaviour() << " is already set by another object => discarding" << RLV_ENDL; eRet = RLV_RET_FAILED_LOCK; break; } @@ -444,14 +492,14 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) rlv_object_map_t::iterator itObj = m_Objects.find(idCurObj); bool fAdded = false; if (itObj != m_Objects.end()) { - RlvObject& rlvObj = itObj->second; - fAdded = rlvObj.addCommand(rlvCmd); + // Add the command to an existing object + rlvCmd = itObj->second.addCommand(rlvCmd, fAdded); } else { - RlvObject rlvObj(idCurObj); - fAdded = rlvObj.addCommand(rlvCmd); - itObj = m_Objects.insert(std::pair(idCurObj, rlvObj)).first; + // Create a new RLV object and then add the command to it (and grab its reference) + itObj = m_Objects.insert(std::pair(idCurObj, RlvObject(idCurObj))).first; + rlvCmd = itObj->second.addCommand(rlvCmd, fAdded); } RLV_DEBUGS << "\t- " << ( (fAdded) ? "adding behaviour" : "skipping duplicate" ) << RLV_ENDL; @@ -526,12 +574,13 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) // Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj) { + const RlvCommand rlvCmd(idObj, strCommand); if (STATE_STARTED != LLStartUp::getStartupState()) { - m_Retained.push_back(RlvCommand(idObj, strCommand)); + m_Retained.push_back(rlvCmd); return RLV_RET_RETAINED; } - return processCommand(RlvCommand(idObj, strCommand), fFromObj); + return processCommand(std::ref(rlvCmd), fFromObj); } // Checked: 2010-02-27 (RLVa-1.2.0a) | Modified: RLVa-1.1.0f @@ -546,7 +595,7 @@ void RlvHandler::processRetainedCommands(ERlvBehaviour eBhvrFilter /*=RLV_BHVR_U if ( ((RLV_BHVR_UNKNOWN == eBhvrFilter) || (rlvCmd.getBehaviourType() == eBhvrFilter)) && ((RLV_TYPE_UNKNOWN == eTypeFilter) || (rlvCmd.getParamType() == eTypeFilter)) ) { - processCommand(rlvCmd, true); + processCommand(std::ref(rlvCmd), true); m_Retained.erase(itCurCmd); } } @@ -823,6 +872,23 @@ void RlvHandler::setActiveGroupRole(const LLUUID& idGroup, const std::string& st m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); } +// @setcam family +void RlvHandler::setCameraOverride(bool fOverride) +{ + if ( (fOverride) && (CAMERA_RLV_SETCAM_VIEW != gAgentCamera.getCameraPreset()) ) + { + m_strCameraPresetRestore = gSavedSettings.getString("PresetCameraActive"); + gAgentCamera.switchCameraPreset(CAMERA_RLV_SETCAM_VIEW); + } + else if ( (!fOverride) && (CAMERA_RLV_SETCAM_VIEW == gAgentCamera.getCameraPreset() && (!RlvActions::isCameraPresetLocked())) ) + { + // We need to clear it or it won't reset properly + gSavedSettings.setString("PresetCameraActive", LLStringUtil::null); + LLFloaterCamera::switchToPreset(m_strCameraPresetRestore); + m_strCameraPresetRestore.clear(); + } +} + // ============================================================================ // Externally invoked event handlers // @@ -1047,6 +1113,12 @@ bool RlvHandler::onGC() return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do } +// static +void RlvHandler::cleanupClass() +{ + gRlvHandler.cleanup(); +} + // Checked: 2009-11-26 (RLVa-1.1.0f) | Added: RLVa-1.1.0f void RlvHandler::onIdleStartup(void* pParam) { @@ -1448,6 +1520,7 @@ bool RlvHandler::setEnabled(bool fEnable) RlvSettings::initClass(); RlvStrings::initClass(); + RlvHandler::instance().addCommandHandler(new RlvEnvironment()); RlvHandler::instance().addCommandHandler(new RlvExtGetSet()); // Make sure we get notified when login is successful @@ -2071,20 +2144,23 @@ void RlvBehaviourModifierHandler::onValueChange() gAgentCamera.changeCameraToThirdPerson(); } -// Handles: @setcam_eyeoffset:=n|y and @setcam_focusoffset:=n|y toggles +// Handles: @setcam_eyeoffset:=n|y, @setcam_eyeoffsetscale:=n|y and @setcam_focusoffset:=n|y toggles template<> template<> void RlvBehaviourCamEyeFocusOffsetHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { if (fHasBhvr) { - gAgentCamera.switchCameraPreset(CAMERA_RLV_SETCAM_VIEW); + gRlvHandler.setCameraOverride(true); } else { - const RlvBehaviourModifier* pBhvrEyeModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET); - const RlvBehaviourModifier* pBhvrOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET); - if ( (!pBhvrEyeModifier->hasValue()) && (!pBhvrOffsetModifier->hasValue()) ) - gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); + const RlvBehaviourModifier* pBhvrEyeOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET); + const RlvBehaviourModifier* pBhvrEyeOffsetScaleModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE); + const RlvBehaviourModifier* pBhvrFocusOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET); + if ( (!pBhvrEyeOffsetModifier->hasValue()) && (!pBhvrEyeOffsetScaleModifier->hasValue()) && (!pBhvrFocusOffsetModifier->hasValue()) ) + { + gRlvHandler.setCameraOverride(false); + } } } @@ -2102,7 +2178,21 @@ void RlvBehaviourModifierHandler::onValueChange() } } -// Handles: @setcam_focusoffset:=n|y changes +// Handles: @setcam_eyeoffsetscale:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)) + { + LLControlVariable* pControl = gSavedSettings.getControl("CameraOffsetScaleRLVa"); + if (pBhvrModifier->hasValue()) + pControl->setValue(pBhvrModifier->getValue()); + else + pControl->resetToDefault(); + } +} + +// Handles: @setcam_focusoffset:=n|y changes template<> void RlvBehaviourModifierHandler::onValueChange() const { @@ -2110,7 +2200,7 @@ void RlvBehaviourModifierHandler::onValueChange { LLControlVariable* pControl = gSavedSettings.getControl("FocusOffsetRLVaView"); if (pBhvrModifier->hasValue()) - pControl->setValue(pBhvrModifier->getValue().getValue()); + pControl->setValue(pBhvrModifier->getValue().getValue()); else pControl->resetToDefault(); } @@ -2229,12 +2319,13 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour e if (fHasCamUnlock != gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_UNLOCK)) RlvBehaviourToggleHandler::onCommandToggle(RLV_BHVR_SETCAM_UNLOCK, !fHasCamUnlock); - gAgentCamera.switchCameraPreset( (fHasBhvr) ? CAMERA_RLV_SETCAM_VIEW : CAMERA_PRESET_REAR_VIEW ); + gRlvHandler.setCameraOverride(fHasBhvr); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMAX)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMIN)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMAX)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMIN)->setPrimaryObject(idRlvObject); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMAX)->setPrimaryObject(idRlvObject); @@ -2256,7 +2347,7 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { - const std::string strEnvFloaters[] = { "env_post_process", "env_settings", "env_delete_preset", "env_edit_sky", "env_edit_water", "env_edit_day_cycle" }; + const std::string strEnvFloaters[] = { "env_adjust_snapshot", "env_edit_extdaycycle", "env_fixed_environmentent_sky", "env_fixed_environmentent_water", "my_environments" }; for (int idxFloater = 0, cntFloater = sizeof(strEnvFloaters) / sizeof(std::string); idxFloater < cntFloater; idxFloater++) { if (fHasBhvr) @@ -2273,13 +2364,26 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour e } } - // Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n + // Don't allow toggling "Atmopsheric Shaders" through the debug settings under @setenv=n gSavedSettings.getControl("WindLightUseAtmosShaders")->setHiddenFromSettingsEditor(fHasBhvr); - // Restore the user's WindLight preferences when releasing - // [EEPMERGE] Use LLEnvironment::loadPreferences()??? - //if (!fHasBhvr) - // LLEnvManagerNew::instance().usePrefs(); + if (fHasBhvr) + { + // Usurp the 'edit' environment for RLVa locking so TPV tools like quick prefs and phototools are automatically locked out as well + // (these needed per-feature awareness of RLV in the previous implementation which often wasn't implemented) + LLEnvironment* pEnv = LLEnvironment::getInstance(); + LLSettingsSky::ptr_t pRlvSky = pEnv->getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL, true)->buildClone(); + pEnv->setEnvironment(LLEnvironment::ENV_EDIT, pRlvSky); + pEnv->setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); + pEnv->updateEnvironment(LLEnvironment::TRANSITION_INSTANT); + } + else + { + // Restore the user's WindLight preferences when releasing + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().updateEnvironment(); + } } // Handles: @showhovertext:=n|y @@ -2403,13 +2507,12 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviou // Force the use of the "display name" cache so we can filter both display and legacy names (or return back to the user's preference) if (fHasBhvr) { - LLAvatarNameCache::getInstance()->setForceDisplayNames(true); + LLAvatarNameCache::instance().setForceDisplayNames(true); } else { - LLAvatarNameCache* inst = LLAvatarNameCache::getInstance(); - inst->setForceDisplayNames(false); - inst->setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); + LLAvatarNameCache::instance().setForceDisplayNames(false); + LLAvatarNameCache::instance().setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); } // Refresh all name tags and HUD text @@ -2726,7 +2829,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvC return RLV_RET_SUCCESS; } -// Handles: @setcam_eyeoffset[:]=force and @setcam_focusoffset[:]=force +// Handles: @setcam_eyeoffset[:]=force, @setcam_eyeoffsetscale[:]=force and @setcam_focusoffset[:]=force template<> template<> ERlvCmdRet RlvForceCamEyeFocusOffsetHandler::onCommand(const RlvCommand& rlvCmd) { @@ -2734,22 +2837,54 @@ ERlvCmdRet RlvForceCamEyeFocusOffsetHandler::onCommand(const RlvCommand& rlvCmd) if (!RlvActions::canChangeCameraPreset(rlvCmd.getObjectID())) return RLV_RET_FAILED_LOCK; - LLControlVariable* pOffsetControl = gSavedSettings.getControl("CameraOffsetRLVaView"); - LLControlVariable* pFocusControl = gSavedSettings.getControl("FocusOffsetRLVaView"); - LLControlVariable* pControl = (rlvCmd.getBehaviourType() == RLV_BHVR_SETCAM_EYEOFFSET) ? pOffsetControl : pFocusControl; - if (rlvCmd.hasOption()) + LLControlVariable* pEyeOffsetControl = gSavedSettings.getControl("CameraOffsetRLVaView"); + LLControlVariable* pEyeOffsetScaleControl = gSavedSettings.getControl("CameraOffsetScaleRLVa"); + LLControlVariable* pFocusOffsetControl = gSavedSettings.getControl("FocusOffsetRLVaView"); + + LLControlVariable* pControl; LLSD sdControlValue; + switch (rlvCmd.getBehaviourType()) { - LLVector3 vecOffset; - if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), vecOffset)) - return RLV_RET_FAILED_OPTION; - pControl->setValue(vecOffset.getValue()); - } - else - { - pControl->resetToDefault(); + case RLV_BHVR_SETCAM_EYEOFFSET: + if (rlvCmd.hasOption()) + { + LLVector3 vecOffset; + if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), vecOffset)) + return RLV_RET_FAILED_OPTION; + sdControlValue = vecOffset.getValue(); + } + pControl = pEyeOffsetControl; + break; + case RLV_BHVR_SETCAM_EYEOFFSETSCALE: + if (rlvCmd.hasOption()) + { + float nScale; + if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), nScale)) + return RLV_RET_FAILED_OPTION; + sdControlValue = nScale; + } + pControl = pEyeOffsetScaleControl; + break; + case RLV_BHVR_SETCAM_FOCUSOFFSET: + if (rlvCmd.hasOption()) + { + LLVector3d vecOffset; + if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), vecOffset)) + return RLV_RET_FAILED_OPTION; + sdControlValue = vecOffset.getValue(); + } + pControl = pFocusOffsetControl; + break; + default: + return RLV_RET_FAILED; } - gAgentCamera.switchCameraPreset( ((pOffsetControl->isDefault()) && (pFocusControl->isDefault())) ? CAMERA_PRESET_REAR_VIEW : CAMERA_RLV_SETCAM_VIEW); + if (!sdControlValue.isUndefined()) + pControl->setValue(sdControlValue); + else + pControl->resetToDefault(); + + // NOTE: this doesn't necessarily release the camera preset even if all 3 are at their default now (e.g. @setcam is currently set) + gRlvHandler.setCameraOverride( (!pEyeOffsetControl->isDefault()) || (!pEyeOffsetScaleControl->isDefault()) || (!pFocusOffsetControl->isDefault()) ); return RLV_RET_SUCCESS; } @@ -3122,7 +3257,10 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const break; case RLV_BHVR_VERSIONNUM: // @versionnum= - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.4b // NOTE: RLV will respond even if there's an option - strReply = RlvStrings::getVersionNum(rlvCmd.getObjectID()); + if (!rlvCmd.hasOption()) + strReply = RlvStrings::getVersionNum(rlvCmd.getObjectID()); + else if ("impl" == rlvCmd.getOption()) + strReply = RlvStrings::getVersionImplNum(); break; case RLV_BHVR_GETATTACH: // @getattach[:]= eRet = onGetAttach(rlvCmd, strReply); @@ -3440,6 +3578,19 @@ ERlvCmdRet RlvReplyHandler::onCommand(const RlvCommand& rlv return RLV_RET_SUCCESS; } +// Handles: @getheightoffset= +template<> template<> +ERlvCmdRet RlvReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) +{ + if (!rlvCmd.getOption().empty()) + return RLV_RET_FAILED_OPTION; + else if (!isAgentAvatarValid()) + return RLV_RET_FAILED_UNKNOWN; + + strReply = llformat("%.2f", gAgentAvatarp->getHoverOffset()[VZ] * 100); + return RLV_RET_SUCCESS; +} + // Checked: 2010-03-09 (RLVa-1.2.0a) | Modified: RLVa-1.1.0f ERlvCmdRet RlvHandler::onGetInv(const RlvCommand& rlvCmd, std::string& strReply) const { @@ -3568,7 +3719,8 @@ ERlvCmdRet RlvHandler::onGetOutfit(const RlvCommand& rlvCmd, std::string& strRep LLWearableType::WT_GLOVES, LLWearableType::WT_JACKET, LLWearableType::WT_PANTS, LLWearableType::WT_SHIRT, LLWearableType::WT_SHOES, LLWearableType::WT_SKIRT, LLWearableType::WT_SOCKS, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_SKIN, LLWearableType::WT_EYES, LLWearableType::WT_HAIR, - LLWearableType::WT_SHAPE, LLWearableType::WT_ALPHA, LLWearableType::WT_TATTOO, LLWearableType::WT_PHYSICS + LLWearableType::WT_SHAPE, LLWearableType::WT_ALPHA, LLWearableType::WT_TATTOO, LLWearableType::WT_PHYSICS, + LLWearableType::WT_UNIVERSAL, }; for (int idxType = 0, cntType = sizeof(wtRlvTypes) / sizeof(LLWearableType::EType); idxType < cntType; idxType++) diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 85acec1bce..32eda85137 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -133,7 +133,7 @@ public: bool processIMQuery(const LLUUID& idSender, const std::string& strCommand); // Returns a pointer to the currently executing command (do *not* save this pointer) - const RlvCommand* getCurrentCommand() const { return (!m_CurCommandStack.empty()) ? m_CurCommandStack.top() : NULL; } + const RlvCommand* getCurrentCommand() const { return (!m_CurCommandStack.empty()) ? &m_CurCommandStack.top().get() : nullptr; } // Returns the UUID of the object we're currently executing a command for const LLUUID& getCurrentObject() const { return (!m_CurObjectStack.empty()) ? m_CurObjectStack.top() : LLUUID::null; } @@ -147,6 +147,7 @@ protected: void clearOverlayImage(); // @setoverlay=n void setActiveGroup(const LLUUID& idGroup); // @setgroup=force void setActiveGroupRole(const LLUUID& idGroup, const std::string& strRole); // @setgroup=force + void setCameraOverride(bool fOverride); // @setcam family void setOverlayImage(const LLUUID& idTexture); // @setoverlay=n void onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse); @@ -173,6 +174,7 @@ protected: // Externally invoked event handlers public: + void cleanup(); void onActiveGroupChanged(); void onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); void onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); @@ -183,6 +185,7 @@ public: void onSitOrStand(bool fSitting); void onTeleportFailed(); void onTeleportFinished(const LLVector3d& posArrival); + static void cleanupClass(); static void onIdleStartup(void* pParam); protected: void getAttachmentResourcesCoro(const std::string& strUrl); @@ -201,7 +204,7 @@ public: * Command processing */ protected: - ERlvCmdRet processCommand(const RlvCommand& rlvCmd, bool fFromObj); + ERlvCmdRet processCommand(std::reference_wrapper rlvCmdRef, bool fFromObj); ERlvCmdRet processClearCommand(const RlvCommand& rlvCmd); // Command handlers (RLV_TYPE_ADD and RLV_TYPE_CLEAR) @@ -242,7 +245,7 @@ protected: rlv_command_list_t m_Retained; RlvGCTimer* m_pGCTimer; - std::stack m_CurCommandStack;// Convenience (see @tpto) + std::stack> m_CurCommandStack; // Convenience (see @tpto) std::stack m_CurObjectStack; // Convenience (see @tpto) rlv_behaviour_signal_t m_OnBehaviour; @@ -263,6 +266,8 @@ protected: LLPointer m_pOverlayImage = nullptr; // @setoverlay=n int m_nOverlayOrigBoost = 0; // @setoverlay=n + std::string m_strCameraPresetRestore; // @setcam_eyeoffset, @setcam_eyeoffsetscale and @setcam_focusoffset + friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete friend class RlvGCTimer; // Timer clear its own point at destruction template friend struct RlvBehaviourGenericHandler; diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index b988fbc9e7..71c4bd3720 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -193,10 +193,12 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addModifier(RLV_BHVR_SETCAM_ORIGINDISTMIN, RLV_MODIFIER_SETCAM_ORIGINDISTMIN, new RlvBehaviourModifier("Camera - Focus Distance (Min)", 0.0f, true, new RlvBehaviourModifierCompMax)); addEntry(new RlvBehaviourGenericProcessor("setcam_origindistmax", RLV_BHVR_SETCAM_ORIGINDISTMAX, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(RLV_BHVR_SETCAM_ORIGINDISTMAX, RLV_MODIFIER_SETCAM_ORIGINDISTMAX, new RlvBehaviourModifier("Camera - Focus Distance (Max)", F32_MAX, true, new RlvBehaviourModifierCompMin)); - addEntry(new RlvBehaviourGenericToggleProcessor("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvBehaviourGenericToggleProcessor("setcam_eyeoffset")); addModifier(RLV_BHVR_SETCAM_EYEOFFSET, RLV_MODIFIER_SETCAM_EYEOFFSET, new RlvBehaviourModifierHandler("Camera - Eye Offset", LLVector3::zero, true, nullptr)); - addEntry(new RlvBehaviourGenericToggleProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_SETCAM_FOCUSOFFSET, RLV_MODIFIER_SETCAM_FOCUSOFFSET, new RlvBehaviourModifierHandler("Camera - Focus Offset", LLVector3::zero, true, nullptr)); + addEntry(new RlvBehaviourGenericToggleProcessor("setcam_eyeoffsetscale")); + addModifier(RLV_BHVR_SETCAM_EYEOFFSETSCALE, RLV_MODIFIER_SETCAM_EYEOFFSETSCALE, new RlvBehaviourModifierHandler("Camera - Eye Offset Scale", 0, true, nullptr)); + addEntry(new RlvBehaviourGenericToggleProcessor("setcam_focusoffset")); + addModifier(RLV_BHVR_SETCAM_FOCUSOFFSET, RLV_MODIFIER_SETCAM_FOCUSOFFSET, new RlvBehaviourModifierHandler("Camera - Focus Offset", LLVector3d::zero, true, nullptr)); addEntry(new RlvBehaviourProcessor("setcam_fovmin")); addModifier(RLV_BHVR_SETCAM_FOVMIN, RLV_MODIFIER_SETCAM_FOVMIN, new RlvBehaviourModifierHandler("Camera - FOV (Min)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifierCompMax)); addEntry(new RlvBehaviourProcessor("setcam_fovmax")); @@ -265,8 +267,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvForceProcessor("detachme")); addEntry(new RlvForceProcessor("fly")); addEntry(new RlvForceProcessor("setcam_focus", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addEntry(new RlvForceProcessor("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addEntry(new RlvForceProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvForceProcessor("setcam_eyeoffset")); + addEntry(new RlvForceProcessor("setcam_eyeoffsetscale")); + addEntry(new RlvForceProcessor("setcam_focusoffset")); addEntry(new RlvForceProcessor("setcam_fov", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("setcam_mode", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("setgroup")); @@ -292,6 +295,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvReplyProcessor("getcam_textures", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvReplyProcessor("getcommand", RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("getgroup", RLV_BHVR_GETGROUP, RLV_TYPE_REPLY)); + addEntry(new RlvReplyProcessor("getheightoffset", RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("getinv", RLV_BHVR_GETINV, RLV_TYPE_REPLY)); addEntry(new RlvBehaviourInfo("getinvworn", RLV_BHVR_GETINVWORN, RLV_TYPE_REPLY)); addEntry(new RlvBehaviourInfo("getoutfit", RLV_BHVR_GETOUTFIT, RLV_TYPE_REPLY)); @@ -645,8 +649,9 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand) } RlvCommand::RlvCommand(const RlvCommand& rlvCmd, ERlvParamType eParamType) - : m_fValid(rlvCmd.m_fValid), m_idObj(rlvCmd.m_idObj), m_strBehaviour(rlvCmd.m_strBehaviour), m_pBhvrInfo(rlvCmd.m_pBhvrInfo), - m_eParamType( (RLV_TYPE_UNKNOWN == eParamType) ? rlvCmd.m_eParamType : eParamType),m_fStrict(rlvCmd.m_fStrict), m_strOption(rlvCmd.m_strOption), m_strParam(rlvCmd.m_strParam), m_fRefCounted(false) + : m_fValid(rlvCmd.m_fValid), m_idObj(rlvCmd.m_idObj), m_strBehaviour(rlvCmd.m_strBehaviour), m_pBhvrInfo(rlvCmd.m_pBhvrInfo) + , m_eParamType( (RLV_TYPE_UNKNOWN == eParamType) ? rlvCmd.m_eParamType : eParamType),m_fStrict(rlvCmd.m_fStrict), m_strOption(rlvCmd.m_strOption) + , m_strParam(rlvCmd.m_strParam), m_fRefCounted(rlvCmd.m_fRefCounted) { } @@ -688,6 +693,13 @@ bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBeh // Command option parsing utility classes // +template<> +bool RlvCommandOptionHelper::parseOption(const std::string& strOption, std::string& valueOption) +{ + valueOption = strOption; + return true; +} + template<> bool RlvCommandOptionHelper::parseOption(const std::string& strOption, LLUUID& idOption) { @@ -769,6 +781,17 @@ bool RlvCommandOptionHelper::parseOption(const std:: return pFolder != NULL; } +template<> +bool RlvCommandOptionHelper::parseOption(const std::string& strOption, LLVector2& vecOption) +{ + if (!strOption.empty()) + { + S32 cntToken = sscanf(strOption.c_str(), "%f/%f", vecOption.mV + 0, vecOption.mV + 1); + return (2 == cntToken); + } + return false; +} + template<> bool RlvCommandOptionHelper::parseOption(const std::string& strOption, LLVector3& vecOption) { @@ -791,6 +814,17 @@ bool RlvCommandOptionHelper::parseOption(const std::string& strOptio return false; } +template<> +bool RlvCommandOptionHelper::parseOption(const std::string& strOption, LLColor3& clrOption) +{ + if (!strOption.empty()) + { + S32 cntToken = sscanf(strOption.c_str(), "%f/%f/%f", clrOption.mV + 0, clrOption.mV + 1, clrOption.mV + 2); + return (3 == cntToken); + } + return false; +} + template<> bool RlvCommandOptionHelper::parseOption(const std::string& strOption, RlvCommandOptionGeneric& genericOption) { @@ -992,7 +1026,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_idObj(idObj), m_nLookupMisses(0) m_idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null; } -bool RlvObject::addCommand(const RlvCommand& rlvCmd) +const RlvCommand& RlvObject::addCommand(const RlvCommand& rlvCmd, bool& fAdded) { RLV_ASSERT(RLV_TYPE_ADD == rlvCmd.getParamType()); @@ -1002,14 +1036,15 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd) if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) && (itCmd->isStrict() == rlvCmd.isStrict() ) ) { - return false; + fAdded = false; + return *itCmd; } } // Now that we know it's not a duplicate, add it to the end of the list m_Commands.push_back(rlvCmd); - - return true; + fAdded = true; + return m_Commands.back(); } bool RlvObject::removeCommand(const RlvCommand& rlvCmd) diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 31ac0e4bc3..9c8d015f76 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -172,7 +172,7 @@ template using RlvForceHandler = RlvCommandHandler using RlvReplyHandler = RlvCommandHandler; // List of shared handlers -typedef RlvBehaviourToggleHandler RlvBehaviourCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset and @setcam_focusoffset +typedef RlvBehaviourToggleHandler RlvBehaviourCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset, @setcam_eyeoffsetscale and @setcam_focusoffset typedef RlvBehaviourHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach typedef RlvBehaviourHandler RlvBehaviourSendChannelHandler; // Shared between @sendchannel and @sendchannel_except typedef RlvBehaviourHandler RlvBehaviourRecvSendStartIMHandler; // Shared between @recvim, @sendim and @startim @@ -181,7 +181,7 @@ typedef RlvBehaviourToggleHandler RlvBehaviourShowSelfToggleH typedef RlvBehaviourHandler RlvBehaviourCamZoomMinMaxHandler; // Shared between @camzoommin and @camzoommax (deprecated) typedef RlvReplyHandler RlvReplyCamMinMaxModifierHandler; // Shared between @getcam_avdistmin and @getcam_avdistmax typedef RlvForceHandler RlvForceRemAttachHandler; // Shared between @remattach and @detach -typedef RlvForceHandler RlvForceCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset and @setcam_focusoffset +typedef RlvForceHandler RlvForceCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset, @setcam_eyeoffsetscale and @setcam_focusoffset // // RlvCommandProcessor - Templated glue class that brings RlvBehaviourInfo, RlvCommandHandlerBaseImpl and RlvCommandHandler together @@ -434,8 +434,8 @@ public: * Member functions */ public: - bool addCommand(const RlvCommand& rlvCmd); - bool removeCommand(const RlvCommand& rlvCmd); + const RlvCommand& addCommand(const RlvCommand& rlvCmd, bool& fAdded); + bool removeCommand(const RlvCommand& rlvCmd); std::string getStatusString(const std::string& strFilter, const std::string& strSeparator) const; bool hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const; diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index b8cfb82991..0f6c108f79 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -578,36 +578,56 @@ void RlvGiveToRLVOffer::onCategoryCreateCallback(LLUUID idFolder, RlvGiveToRLVOf pInstance->onDestinationCreated(idFolder, pInstance->m_DestPath.front()); } -// Checked: 2014-01-07 (RLVa-1.4.10) -void RlvGiveToRLVOffer::moveAndRename(const LLUUID& idFolder, const LLUUID& idDestination, const std::string& strName) +// static +void RlvGiveToRLVOffer::moveAndRename(const LLUUID& idFolder, const LLUUID& idDestination, const std::string& strName, const LLPointer cbFinal) { - const LLViewerInventoryCategory* pDest = gInventory.getCategory(idDestination); const LLViewerInventoryCategory* pFolder = gInventory.getCategory(idFolder); - if ( (pDest) && (pFolder) ) + if ( (idDestination.notNull()) && (pFolder) ) { - LLPointer pNewFolder = new LLViewerInventoryCategory(pFolder); - if (pDest->getUUID() != pFolder->getParentUUID()) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate updOldParent(pFolder->getParentUUID(), -1); - update.push_back(updOldParent); - LLInventoryModel::LLCategoryUpdate updNewParent(pDest->getUUID(), 1); - update.push_back(updNewParent); - gInventory.accountForUpdate(update); + bool needsRename = (pFolder->getName() != strName); - pNewFolder->setParent(pDest->getUUID()); - pNewFolder->updateParentOnServer(FALSE); + LLPointer cbMove; + if (idDestination != pFolder->getParentUUID()) + { + // We have to move *after* the rename operation completes or AIS will drop it + if (!needsRename) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate updOldParent(pFolder->getParentUUID(), -1); + update.push_back(updOldParent); + LLInventoryModel::LLCategoryUpdate updNewParent(idDestination, 1); + update.push_back(updNewParent); + gInventory.accountForUpdate(update); + + LLPointer pNewFolder = new LLViewerInventoryCategory(pFolder); + pNewFolder->setParent(idDestination); + pNewFolder->updateParentOnServer(FALSE); + + gInventory.updateCategory(pNewFolder); + gInventory.notifyObservers(); + + if (cbFinal) + { + cbFinal.get()->fire(idFolder); + } + } + else + { + cbMove = new LLBoostFuncInventoryCallback(boost::bind(RlvGiveToRLVOffer::moveAndRename, _1, idDestination, strName, cbFinal)); + } } - pNewFolder->rename(strName); - pNewFolder->updateServer(FALSE); - gInventory.updateCategory(pNewFolder); - - gInventory.notifyObservers(); + if (needsRename) + { + rename_category(&gInventory, idFolder, strName, (cbMove) ? cbMove : cbFinal); + } + } + else if (cbFinal) + { + cbFinal.get()->fire(LLUUID::null); } } -// Checked: 2010-04-18 (RLVa-1.2.0) void RlvGiveToRLVTaskOffer::changed(U32 mask) { if (mask & LLInventoryObserver::ADD) @@ -633,7 +653,6 @@ void RlvGiveToRLVTaskOffer::changed(U32 mask) } } -// Checked: 2010-04-18 (RLVa-1.2.0) void RlvGiveToRLVTaskOffer::done() { gInventory.removeObserver(this); @@ -642,22 +661,29 @@ void RlvGiveToRLVTaskOffer::done() doOnIdleOneTime(boost::bind(&RlvGiveToRLVTaskOffer::doneIdle, this)); } -// Checked: 2014-01-07 (RLVa-1.4.10) void RlvGiveToRLVTaskOffer::doneIdle() { - const LLViewerInventoryCategory* pFolder = (m_Folders.size()) ? gInventory.getCategory(m_Folders.front()) : NULL; + const LLViewerInventoryCategory* pFolder = (m_Folders.size()) ? gInventory.getCategory(m_Folders.front()) : nullptr; if ( (!pFolder) || (!createDestinationFolder(pFolder->getName())) ) delete this; } -// Checked: 2010-04-18 (RLVa-1.2.0) -void RlvGiveToRLVTaskOffer::onDestinationCreated(const LLUUID& idFolder, const std::string& strName) +void RlvGiveToRLVTaskOffer::onDestinationCreated(const LLUUID& idDestFolder, const std::string& strName) { - const LLViewerInventoryCategory* pTarget = (idFolder.notNull()) ? gInventory.getCategory(idFolder) : NULL; - if (pTarget) + if (const LLViewerInventoryCategory* pTarget = (idDestFolder.notNull()) ? gInventory.getCategory(idDestFolder) : nullptr) + { + moveAndRename(m_Folders.front(), idDestFolder, strName, new LLBoostFuncInventoryCallback(boost::bind(&RlvGiveToRLVTaskOffer::onOfferCompleted, this, _1))); + } + else + { + onOfferCompleted(LLUUID::null); + } +} + +void RlvGiveToRLVTaskOffer::onOfferCompleted(const LLUUID& idOfferedFolder) +{ + if (idOfferedFolder.notNull()) { - const LLUUID& idOfferedFolder = m_Folders.front(); - moveAndRename(idOfferedFolder, idFolder, strName); RlvBehaviourNotifyHandler::sendNotification("accepted_in_rlv inv_offer " + RlvInventory::instance().getSharedPath(idOfferedFolder)); } delete this; @@ -684,7 +710,7 @@ void RlvGiveToRLVAgentOffer::doneIdle() void RlvGiveToRLVAgentOffer::onDestinationCreated(const LLUUID& idFolder, const std::string& strName) { if ( (idFolder.notNull()) && (mComplete.size()) ) - moveAndRename(mComplete[0], idFolder, strName); + moveAndRename(mComplete[0], idFolder, strName, nullptr); delete this; } diff --git a/indra/newview/rlvinventory.h b/indra/newview/rlvinventory.h index 2eb73380bf..570cafc1a3 100644 --- a/indra/newview/rlvinventory.h +++ b/indra/newview/rlvinventory.h @@ -130,8 +130,8 @@ protected: virtual ~RlvGiveToRLVOffer() {} protected: bool createDestinationFolder(const std::string& strPath); - virtual void onDestinationCreated(const LLUUID& idFolder, const std::string& strName) = 0; - void moveAndRename(const LLUUID& idFolder, const LLUUID& idDestination, const std::string& strName); + virtual void onDestinationCreated(const LLUUID& idDestFolder, const std::string& strName) = 0; + static void moveAndRename(const LLUUID& idFolder, const LLUUID& idDestination, const std::string& strName, LLPointer cb); private: static void onCategoryCreateCallback(LLUUID idFolder, RlvGiveToRLVOffer* pInstance); @@ -146,11 +146,12 @@ class RlvGiveToRLVTaskOffer : public LLInventoryObserver, RlvGiveToRLVOffer { public: RlvGiveToRLVTaskOffer(const LLUUID& idTransaction) : RlvGiveToRLVOffer(), m_idTransaction(idTransaction) {} - /*virtual*/ void changed(U32 mask); + void changed(U32 mask) override; protected: - /*virtual*/ void done(); - void doneIdle(); - /*virtual*/ void onDestinationCreated(const LLUUID& idFolder, const std::string& strName); + void done(); + void doneIdle(); + void onDestinationCreated(const LLUUID& idDestFolder, const std::string& strName) override; + void onOfferCompleted(const LLUUID& idOfferedFolder); protected: typedef std::vector folder_ref_t; diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index a81071e1ff..575a32677e 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -136,7 +136,6 @@ void RlvUIEnabler::onToggleShowLoc() // If the last entry in the persistent teleport history matches the current teleport history entry then we should remove it LLTeleportHistory* pTpHistory = LLTeleportHistory::getInstance(); LLTeleportHistoryStorage* pTpHistoryStg = LLTeleportHistoryStorage::getInstance(); - RLV_ASSERT( (pTpHistory) && (pTpHistoryStg) && (pTpHistory->getItems().size() > 0) && (pTpHistory->getCurrentItemIndex() >= 0) ); if ( (pTpHistory) && (pTpHistory->getItems().size() > 0) && (pTpHistory->getCurrentItemIndex() >= 0) && (pTpHistoryStg) && (pTpHistoryStg->getItems().size() > 0) ) { diff --git a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml index 56b358453e..a68437d9c1 100644 --- a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml +++ b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml @@ -42,6 +42,7 @@ + diff --git a/indra/newview/skins/ansastorm/xui/ru/panel_edit_eyes.xml b/indra/newview/skins/ansastorm/xui/ru/panel_edit_eyes.xml index 74ab2d5ba7..81370196be 100644 --- a/indra/newview/skins/ansastorm/xui/ru/panel_edit_eyes.xml +++ b/indra/newview/skins/ansastorm/xui/ru/panel_edit_eyes.xml @@ -1,7 +1,7 @@ - + diff --git a/indra/newview/skins/ansastorm/xui/ru/panel_edit_jacket.xml b/indra/newview/skins/ansastorm/xui/ru/panel_edit_jacket.xml index 1df6317ba8..f21e9fc934 100644 --- a/indra/newview/skins/ansastorm/xui/ru/panel_edit_jacket.xml +++ b/indra/newview/skins/ansastorm/xui/ru/panel_edit_jacket.xml @@ -1,8 +1,8 @@ - - + + diff --git a/indra/newview/skins/ansastorm/xui/ru/panel_edit_shape.xml b/indra/newview/skins/ansastorm/xui/ru/panel_edit_shape.xml index df88c137ff..7fc65d406d 100644 --- a/indra/newview/skins/ansastorm/xui/ru/panel_edit_shape.xml +++ b/indra/newview/skins/ansastorm/xui/ru/panel_edit_shape.xml @@ -4,7 +4,7 @@ Метры - Ноги + Футы Высота: diff --git a/indra/newview/skins/ansastorm/xui/ru/panel_group_notify.xml b/indra/newview/skins/ansastorm/xui/ru/panel_group_notify.xml index fa6d488271..e634c5a88c 100644 --- a/indra/newview/skins/ansastorm/xui/ru/panel_group_notify.xml +++ b/indra/newview/skins/ansastorm/xui/ru/panel_group_notify.xml @@ -3,5 +3,5 @@ - + +