Ansariel 2020-06-24 12:12:46 +02:00
commit a72e1418ad
317 changed files with 6927 additions and 8986 deletions

1
.gitignore vendored
View File

@ -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.*

View File

@ -826,9 +826,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>23aeaf23e7db2484a1850017141860dd</string>
<string>350866eec6be17ffc265904b91dcfe6b</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/34069/283470/dullahan-1.1.1320_3.3626.1895.g7001d56-darwin64-525361.tar.bz2</string>
<string>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</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -850,9 +850,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>43c03679c3847754b407532efe5d4392</string>
<string>aa4faf9ef9057362d63f8d57092506b3</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/dullahan-1.7.0.202005292352_81.3.10_gb223419_chromium-81.0.4044.138-windows-201512310.tar.bz2</string>
<string>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</string>
</map>
<key>name</key>
<string>windows</string>
@ -862,16 +862,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>13574736220c05de847980f851f42827</string>
<string>6e29ea2ccdad80dcf1b5dc974932c1f6</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/dullahan-1.7.0.202005292352_81.3.10_gb223419_chromium-81.0.4044.138-windows64-201512301.tar.bz2</string>
<string>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</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.1.1320_3.3626.1895.g7001d56</string>
<string>1.7.0.202005311828_81.3.10_gb223419_chromium-81.0.4044.138</string>
</map>
<key>elfio</key>
<map>

View File

@ -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}")

View File

@ -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

View File

@ -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;

View File

@ -36,6 +36,12 @@
#include "llpreprocessor.h"
#include <boost/static_assert.hpp>
// <FS:ND> 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
// </FS:ND>
const int LL_ERR_NOERR = 0;
// Define one of these for different error levels in release...

View File

@ -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();
}

View File

@ -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<LLKeyData> data_vector_t;
data_vector_t mData;
};
#endif // LL_KEYBIND_H

View File

@ -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");

View File

@ -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];

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -266,9 +266,10 @@ void LLModel::normalizeVolumeFaces()
scale.splat(1.f);
scale.div(size);
LLVector4a inv_scale(1.f);
inv_scale.div(scale);
// <FS:Beq> BUG-228952 - bad vertex normal scaling on mesh asset import
// LLVector4a inv_scale(1.f);
// inv_scale.div(scale);
// </FS:Beq>
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);
// <FS:Beq> BUG-228952 - bad vertex normal scaling on mesh asset import
// norm[j].mul(inv_scale);
norm[j].mul(scale);
// </FS:Beq>
norm[j].normalize3();
}
}

View File

@ -698,6 +698,14 @@ void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVect
// </FS:Ansariel>
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
// <FS:Beq> 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;
}
// </FS:Beq>
// <FS:Ansariel> Crash fix due to invalid calls to drawElements by Drake Arconis
if (num_vertices <= 0)

View File

@ -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 <LLMenuKeyboardBinding*> *listp)
BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
{
LLMenuKeyboardBinding *accelerator = NULL;
LLKeyBinding *accelerator = NULL;
if (mAcceleratorKey != KEY_NONE)
{
std::list<LLMenuKeyboardBinding*>::iterator list_it;
std::list<LLKeyBinding*>::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 <LLMenuKeyboardBinding*> *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<LLMenuKeyboardBinding*> *listp)
BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *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

View File

@ -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<LLMenuKeyboardBinding*> *listp);
virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *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 <LLMenuKeyboardBinding*> *listp);
virtual BOOL addToAcceleratorList(std::list <LLKeyBinding*> *listp);
// called to rebuild the draw label
virtual void buildDrawLabel( void );
@ -816,7 +806,7 @@ private:
void checkMenuTrigger();
std::list <LLMenuKeyboardBinding*> mAccelerators;
std::list <LLKeyBinding*> mAccelerators;
BOOL mAltKeyTrigger;
};

View File

@ -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);
}
}

View File

@ -59,8 +59,7 @@ public:
visible;
Optional<void*> userdata;
Optional<LLSD> value; // state of checkbox, icon id/name, date
Optional<std::string> label; // description or text
Optional<LLSD> value;
Optional<std::string> tool_tip;
Optional<const LLFontGL*> 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<LLUIImage> mIcon;
S32 mPad;
};
#endif

View File

@ -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), // <FS:Ansariel> Persists sort order of scroll lists
primary_sort_only("primary_sort_only", false), // <FS:Ansariel> 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<F32> 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)
// </FS:Ansariel> 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;
}
}

View File

@ -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<LLScrollListCtrl::ESelectionType, SelectionTypeNames>
{
static void declareValues();
};
struct Contents : public LLInitParam::Block<Contents>
{
Multiple<LLScrollListColumn::Params> columns;
@ -111,8 +99,6 @@ public:
commit_on_keyboard_movement,
mouse_wheel_opaque;
Optional<ESelectionType, SelectionTypeNames> selection_type;
// display flags
Optional<bool> has_border,
draw_heading,
@ -129,8 +115,7 @@ public:
// sort and search behavior
Optional<S32> search_column,
sort_column;
Optional<bool> sort_ascending,
can_sort; // whether user is allowed to sort
Optional<bool> sort_ascending;
Optional<bool> persist_sort_order; // <FS:Ansariel> Persists sort order of scroll lists
Optional<bool> primary_sort_only; // <FS:Ansariel> 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;

View File

@ -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();

View File

@ -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;

View File

@ -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] == '+'))

View File

@ -38,10 +38,10 @@ enum EKeystate
{
KEYSTATE_DOWN,
KEYSTATE_LEVEL,
KEYSTATE_UP
KEYSTATE_UP
};
typedef boost::function<bool(EKeystate keystate)> LLKeyFunc;
typedef boost::function<void(EKeystate keystate)> 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; }

View File

@ -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)

View File

@ -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;

View File

@ -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,

View File

@ -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<std::string> 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<std::string> 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<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialo
return std::vector<std::string>();
}
////////////////////////////////////////////////////////////////////////////////
//
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")
{

View File

@ -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

View File

@ -1 +1 @@
6.4.4
6.4.5

View File

@ -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());

View File

@ -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"
/>

File diff suppressed because it is too large Load Diff

View File

@ -28,12 +28,34 @@
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="A" mask="SHIFT" command="slide_left"/>
<binding key="D" mask="SHIFT" command="slide_right"/>
<binding key="W" mask="SHIFT" command="push_forward"/>
<binding key="S" mask="SHIFT" command="push_backward"/>
<binding key="E" mask="SHIFT" command="jump"/>
<binding key="C" mask="SHIFT" command="push_down"/>
<binding key="F" mask="SHIFT" command="toggle_fly"/>
<binding key="SPACE" mask="NONE" command="stop_moving"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="LEFT" mask="SHIFT" command="slide_left"/>
<binding key="RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="UP" mask="SHIFT" command="push_forward"/>
<binding key="DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PGUP" mask="SHIFT" command="jump"/>
<binding key="PGDN" mask="SHIFT" command="push_down"/>
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
<binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
<binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
<binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
<binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
</first_person>
<third_person>
<binding key="A" mask="NONE" command="turn_left"/>
@ -42,10 +64,15 @@
<binding key="D" mask="SHIFT" command="slide_right"/>
<binding key="W" mask="NONE" command="push_forward"/>
<binding key="S" mask="NONE" command="push_backward"/>
<binding key="W" mask="SHIFT" command="push_forward"/>
<binding key="S" mask="SHIFT" command="push_backward"/>
<binding key="E" mask="NONE" command="jump"/>
<binding key="C" mask="NONE" command="push_down"/>
<binding key="E" mask="SHIFT" command="jump"/>
<binding key="C" mask="SHIFT" command="push_down"/>
<binding key="F" mask="NONE" command="toggle_fly"/>
<binding key="F" mask="SHIFT" command="toggle_fly"/>
<binding key="SPACE" mask="NONE" command="stop_moving"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
@ -57,8 +84,13 @@
<binding key="RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="UP" mask="NONE" command="push_forward"/>
<binding key="DOWN" mask="NONE" command="push_backward"/>
<binding key="UP" mask="SHIFT" command="push_forward"/>
<binding key="DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PGUP" mask="NONE" command="jump"/>
<binding key="PGDN" mask="NONE" command="push_down"/>
<binding key="PGUP" mask="SHIFT" command="jump"/>
<binding key="PGDN" mask="SHIFT" command="push_down"/>
<binding key="HOME" mask="SHIFT" command="toggle_fly"/>
<binding key="HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
@ -67,12 +99,20 @@
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="NONE" command="push_forward"/>
<binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
<binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
<binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PAD_PGUP" mask="NONE" command="jump"/>
<binding key="PAD_PGDN" mask="NONE" command="push_down"/>
<binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
<binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
<binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
<binding key="PAD_CENTER" mask="SHIFT" command="stop_moving"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
<!--Camera controls in third person on Alt-->
<binding key="LEFT" mask="ALT" command="spin_around_cw"/>
@ -99,14 +139,28 @@
<binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
<!--mimic alt zoom behavior with keyboard only-->
<binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
<binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="W" mask="CTL_ALT" command="spin_over"/>
<binding key="S" mask="CTL_ALT" command="spin_under"/>
<binding key="E" mask="CTL_ALT" command="spin_over"/>
<binding key="C" mask="CTL_ALT" command="spin_under"/>
<binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
<binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="UP" mask="CTL_ALT" command="spin_over"/>
<binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
<binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
<binding key="PGDN" mask="CTL_ALT" command="spin_under"/>
<binding key="PAD_LEFT" mask="CTL_ALT" command="spin_around_cw"/>
<binding key="PAD_RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
<binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
<binding key="PAD_PGUP" mask="CTL_ALT" command="spin_over"/>
<binding key="PAD_PGDN" mask="CTL_ALT" command="spin_under"/>
<binding key="PAD_ENTER" mask="CTL_ALT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="CTL_ALT" command="start_gesture"/>
<!--Therefore pan on Alt-Shift-->
<binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
@ -125,10 +179,63 @@
<binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
</third_person>
<!-- Basic editing camera control -->
<edit>
<binding key="A" mask="NONE" command="spin_around_cw"/>
<binding key="D" mask="NONE" command="spin_around_ccw"/>
<binding key="W" mask="NONE" command="move_forward"/>
<binding key="S" mask="NONE" command="move_backward"/>
<binding key="E" mask="NONE" command="spin_over"/>
<binding key="C" mask="NONE" command="spin_under"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="LEFT" mask="NONE" command="spin_around_cw"/>
<binding key="RIGHT" mask="NONE" command="spin_around_ccw"/>
<binding key="UP" mask="NONE" command="move_forward"/>
<binding key="DOWN" mask="NONE" command="move_backward"/>
<binding key="PGUP" mask="NONE" command="spin_over"/>
<binding key="PGDN" mask="NONE" command="spin_under"/>
<binding key="A" mask="SHIFT" command="pan_left"/>
<binding key="D" mask="SHIFT" command="pan_right"/>
<binding key="W" mask="SHIFT" command="pan_up"/>
<binding key="S" mask="SHIFT" command="pan_down"/>
<binding key="LEFT" mask="SHIFT" command="pan_left"/>
<binding key="RIGHT" mask="SHIFT" command="pan_right"/>
<binding key="UP" mask="SHIFT" command="pan_up"/>
<binding key="DOWN" mask="SHIFT" command="pan_down"/>
<!--Walking works with ALT held down.-->
<binding key="A" mask="ALT" command="slide_left"/>
<binding key="D" mask="ALT" command="slide_right"/>
<binding key="W" mask="ALT" command="push_forward"/>
<binding key="S" mask="ALT" command="push_backward"/>
<binding key="E" mask="ALT" command="jump"/>
<binding key="C" mask="ALT" command="push_down"/>
<binding key="LEFT" mask="ALT" command="slide_left"/>
<binding key="RIGHT" mask="ALT" command="slide_right"/>
<binding key="UP" mask="ALT" command="push_forward"/>
<binding key="DOWN" mask="ALT" command="push_backward"/>
<binding key="PGUP" mask="ALT" command="jump"/>
<binding key="PGDN" mask="ALT" command="push_down"/>
<binding key="HOME" mask="ALT" command="toggle_fly"/>
<binding key="PAD_LEFT" mask="ALT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="ALT" command="slide_right"/>
<binding key="PAD_UP" mask="ALT" command="push_forward"/>
<binding key="PAD_DOWN" mask="ALT" command="push_backward"/>
<binding key="PAD_PGUP" mask="ALT" command="jump"/>
<binding key="PAD_PGDN" mask="ALT" command="push_down"/>
<binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
</edit>
<sitting>
<binding key="A" mask="ALT" command="spin_around_cw"/>
<binding key="D" mask="ALT" command="spin_around_ccw"/>
@ -144,11 +251,15 @@
<binding key="PGUP" mask="ALT" command="spin_over"/>
<binding key="PGDN" mask="ALT" command="spin_under"/>
<binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
<binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="W" mask="CTL_ALT" command="spin_over"/>
<binding key="S" mask="CTL_ALT" command="spin_under"/>
<binding key="E" mask="CTL_ALT" command="spin_over"/>
<binding key="C" mask="CTL_ALT" command="spin_under"/>
<binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
<binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="UP" mask="CTL_ALT" command="spin_over"/>
<binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
<binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
@ -183,23 +294,23 @@
<binding key="A" mask="SHIFT" command="slide_left"/>
<binding key="D" mask="SHIFT" command="slide_right"/>
<binding key="W" mask="SHIFT" command="move_forward_sitting"/>
<binding key="S" mask="SHIFT" command="move_backward_sitting"/>
<binding key="E" mask="SHIFT" command="spin_over_sitting"/>
<binding key="C" mask="SHIFT" command="spin_under_sitting"/>
<binding key="S" mask="SHIFT" command="move_backward_sitting"/>
<binding key="E" mask="SHIFT" command="spin_over_sitting"/>
<binding key="C" mask="SHIFT" command="spin_under_sitting"/>
<binding key="LEFT" mask="SHIFT" command="slide_left"/>
<binding key="RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="UP" mask="SHIFT" command="move_forward_sitting"/>
<binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
<binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
<binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/>
<binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
<binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
<binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
@ -223,9 +334,6 @@
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
</sitting>
<edit_avatar>
<!--Avatar editing camera controls-->
@ -251,7 +359,5 @@
<binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
</edit_avatar>
</keys>
</keys>

View File

@ -5557,7 +5557,7 @@
<key>DoubleClickAutoPilot</key>
<map>
<key>Comment</key>
<string>(Obsolete)Enable double-click auto pilot</string>
<string>Enable double-click auto pilot</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -5568,13 +5568,13 @@
<key>DoubleClickTeleport</key>
<map>
<key>Comment</key>
<string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
<string>Enable double-click to teleport where allowed</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>DoubleClickShowWorldMap</key>
<map>
@ -10979,7 +10979,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>PushToTalkButton</key>
<map>
<key>Comment</key>
<string>(Obsolete)Which button or keyboard key is used for push-to-talk</string>
<string>Which button or keyboard key is used for push-to-talk</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -11159,7 +11159,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.125</real>
<real>0.02</real>
</map>
<key>MediaRollOffMin</key>
<map>
@ -11170,7 +11170,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>10.0</real>
<real>40.0</real>
</map>
<key>MediaRollOffMax</key>
<map>
@ -11181,7 +11181,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>30.0</real>
<real>80.0</real>
</map>
<key>RecentItemsSortOrder</key>
<map>
@ -19805,7 +19805,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>ClickToWalk</key>
<map>
<key>Comment</key>
<string>(obsolete)Click in world to walk to location</string>
<string>Click in world to walk to location</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -21041,6 +21041,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>FSUseAzertyKeyboardLayout</key>
<map>
<key>Comment</key>
<string>Uses a keyboard layout suitable for keyboards with AZERTY layout.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSNameTagZOffsetCorrection</key>
<map>
<key>Comment</key>

View File

@ -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"))

View File

@ -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
{

View File

@ -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();

View File

@ -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"

View File

@ -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)
}
}
}

View File

@ -18,9 +18,6 @@
#include "llviewerprecompiledheaders.h"
#include "lggbeamscolors.h"
#include "llfile.h"
#include "llsdserialize.h"
lggBeamsColors lggBeamsColors::fromLLSD(const LLSD& inputData)
{
lggBeamsColors toReturn;

View File

@ -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<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
// focus_offset = convert_from_llsd<LLVector3d>(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<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, "");
// [RLVa:KB] - @setcam_eyeoffset
return convert_from_llsd<LLVector3>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mCameraOffsetInitialControl->get() : mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, "");
// [/RLVa:KB]
// return convert_from_llsd<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, "");
}
LLVector3d LLAgentCamera::getFocusOffsetInitial()
{
return convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
// [RLVa:KB] - @setcam_focusoffset
return convert_from_llsd<LLVector3d>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mFocusOffsetInitialControl->get() : mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, "");
// [/RLVa:KB]
// return convert_from_llsd<LLVector3d>(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]
// <FS:Ansariel> 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]

View File

@ -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<LLControlVariable> mCameraOffsetInitial;
// LLPointer<LLControlVariable> mCameraOffsetInitial;
// [RLVa:KB] - @setcam_eyeoffset
// Renamed to catch their uses
LLPointer<LLControlVariable> mCameraOffsetInitialControl;
LLPointer<LLControlVariable> mRlvCameraOffsetInitialControl;
// [/RLVa:KB]
// [RLVa:KB] - @setcam_eyeoffsetscale
LLPointer<LLControlVariable> mRlvCameraOffsetScaleControl;
// [/RLVa:KB]
/** Initial focus offset */
LLPointer<LLControlVariable> mFocusOffsetInitial;
// LLPointer<LLControlVariable> mFocusOffsetInitial;
// [RLVa:KB] - @setcam_focusoffset
// Renamed to catch their uses
LLPointer<LLControlVariable> mFocusOffsetInitialControl;
LLPointer<LLControlVariable> mRlvFocusOffsetInitialControl;
// [/RLVa:KB]
LLQuaternion mInitSitRot;

View File

@ -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;
}

View File

@ -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 <boost/lexical_cast.hpp>
#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
// <FS:Ansariel> 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,
// </FS:Ansariel>
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();
// <FS:Ansariel> Chalice Yao's crouch toggle
static LLCachedControl<bool> fsCrouchToggle(gSavedPerAccountSettings, "FSCrouchToggle");
static LLCachedControl<bool> 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

View File

@ -33,6 +33,7 @@
#include "llagent.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewerregion.h"
#include "llviewernetwork.h" // <FS:Beq/> 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)
{
}
// <FS:Beq> OpenSim legacy Windlight setting support
#ifdef OPENSIM
void LLEnvironment::loadLegacyPresets()
{
std::string path_name;
std::vector<decltype(LL_PATH_APP_SETTINGS)> 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
//</FS:Beq>
void LLEnvironment::initSingleton()
{
@ -833,6 +904,16 @@ void LLEnvironment::initSingleton()
mEnvironments[ENV_DEFAULT] = mCurrentEnvironment;
// <FS:Beq> OpenSim legacy Windlight setting support
#ifdef OPENSIM
if (LLGridManager::instance().isInOpenSim())
{
loadLegacyPresets();
loadUserPrefs();
}
#endif
// </FS:Beq>
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();// <FS:Beq/> 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<DayTransition>(
mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
trans->animate();
mCurrentEnvironment = trans;
DayInstance::ptr_t trans = std::make_shared<DayTransition>(
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();
// <FS:Beq> 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();
}
// </FS:Beq>
}
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;
// <FS:Beq> 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;
// </FS:Beq>
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();// <FS:Beq/> fix the args to match the template.
LLNotificationsUtil::add("FailedToFindSettings", args);
return;
}

View File

@ -374,6 +374,20 @@ private:
experience_overrides_t mExperienceOverrides;
DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false);
// <FS:Beq> opensim windlight setting
#ifdef OPENSIM
public:
std::vector<std::string> mLegacySkies;
std::vector<std::string> mLegacyWater;
std::vector<std::string> mLegacyDayCycles;
std::string mWaterPresetName;
std::string mSkyPresetName;
std::string mDayCycleName;
private:
void loadLegacyPresets();
void loadUserPrefs();
#endif
// </FS:Beq>
void updateCloudScroll();

View File

@ -45,6 +45,9 @@
#include "llhints.h"
#include "lltabcontainer.h"
#include "llvoavatarself.h"
// [RLVa:KB] - @setcam
#include "rlvactions.h"
// [/RLVa:KB]
static LLDefaultChildRegistry::Register<LLPanelCameraItem> 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)

View File

@ -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<LabelTable>
{}
};
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<LLUICtrl>("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)
}
// </FS:AW opensim search support>
/*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<LLSetKeyBindDialog>);
LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
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)); // <FS:Ansariel> FIRE-3803: Clear voice toggle button
mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
//<FS:KC> 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;
}
// <FS:Ansariel> 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<LLFloaterPreferenceProxy>("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();
// <FS:PP> Load UI Sounds tabs settings.
updateUISoundsControls();
@ -2067,7 +2198,7 @@ void LLFloaterPreference::refreshEnabledState()
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
// [RLVa:KB] - Checked: 2013-05-11 (RLVa-1.4.9)
if (rlv_handler_t::isEnabled())
if (RlvActions::isRlvEnabled())
{
getChild<LLUICtrl>("do_not_disturb_response")->setEnabled(!RlvActions::hasBehaviour(RLV_BHVR_SENDIM));
}
@ -2121,11 +2252,11 @@ void LLFloaterPreference::refreshEnabledState()
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLSliderCtrl* sky = getChild<LLSliderCtrl>("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<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
LLTextBox* sky_text = getChild<LLTextBox>("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<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE);
if (dialog)
{
dialog->setParent(this);
}
}
// <FS:Ansariel> FIRE-3803: Clear voice toggle button
void LLFloaterPreference::onClickClearKey()
{
gSavedSettings.setString("PushToTalkButton", "");
}
// </FS:Ansariel>
void LLFloaterPreference::setKey(KEY key)
{
getChild<LLUICtrl>("modifier_combo")->setValue(LLKeyboard::stringFromKey(key));
// update the control right away since we no longer wait for apply
getChild<LLUICtrl>("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<LLUICtrl>("modifier_combo");
// We are using text control names for readability and compatibility with voice
p2t_line_editor->setControlValue(ctrl_value);
// <FS:Ansariel> Fix crash "Failed to find string middle_mouse in panel Media Voice tab loaded from file"
//LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent()->getParent()->getParent());
// </FS:Ansariel>
if (advanced_preferences)
{
p2t_line_editor->setValue(advanced_preferences->getString(bt_name));
}
}
}
void LLFloaterPreference::onClickSetMiddleMouse()
{
LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("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<LLPanel>("audio");
p2t_line_editor->setValue(audioPanel->getString("middle_mouse"));
}
//<FS:KC> Handled centrally now
/*
void LLFloaterPreference::onClickSetSounds()
@ -2656,6 +2860,18 @@ void LLFloaterPreference::onClickPreviewUISound(const LLSD& ui_sound_id)
}
// </FS:PP> 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<LLScrollListCtrl>("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<LLComboBox>("single_click_action_combo")->getValue().asInteger();
const int double_clk_action = getChild<LLComboBox>("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<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
}
// <FS:PP> Load UI Sounds tabs settings
void LLFloaterPreference::updateUISoundsControls()
{
@ -3604,6 +3845,24 @@ BOOL LLPanelPreference::postBuild()
getChild<LLTextBox>("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<LLUICtrl>("modifier_combo")->getValue().asString();
if (MIDDLE_MOUSE_CV == modifier_value)
{
getChild<LLUICtrl>("modifier_combo")->setValue(getString("middle_mouse"));
}
else if (MOUSE_BUTTON_4_CV == modifier_value)
{
getChild<LLUICtrl>("modifier_combo")->setValue(getString("button4_mouse"));
}
else if (MOUSE_BUTTON_5_CV == modifier_value)
{
getChild<LLUICtrl>("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<LLPanelPreferenceControls> 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<LLScrollListCtrl>("controls_list");
pKeyModeBox = getChild<LLComboBox>("key_mode");
pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this));
pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this));
getChild<LLButton>("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<LLScrollListColumn::Params>::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<LLScrollListItem::Params>::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<LLScrollListItem*> 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<LLSetKeyBindDialog>("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)
{

View File

@ -37,8 +37,6 @@
#include "llavatarpropertiesprocessor.h"
#include "llconversationlog.h"
#include "llsearcheditor.h"
#include "llsetkeybinddialog.h"
#include "llkeyconflict.h"
#include "llaudioengine.h" // <FS:Ansariel> 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:
// <FS:AO> 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();
// <FS:PP> updates UI Sounds controls depending on values from settings.xml
void updateUISoundsControls();
@ -164,6 +166,7 @@ protected:
// <FS:Zi> 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(); // <FS:Ansariel> FIRE-3803: Clear voice toggle button
void setKey(KEY key);
void setMouse(LLMouseHandler::EClickType click);
void onClickSetMiddleMouse();
// void onClickSetSounds(); //<FS:KC> Handled centrally now
void onClickPreviewUISound(const LLSD& ui_sound_id); // <FS:PP> 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:

View File

@ -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);
}

View File

@ -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<LLInventoryCallback> 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,

View File

@ -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<LLInventoryCallback> 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);

View File

@ -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<LLViewerInput::KeyBinding>::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<decltype(saved_settings_key_controls)>::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<std::string, S32> 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<std::string, S32>::iterator cnflct_iter = conflict_list.begin();
std::map<std::string, S32>::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;
}

View File

@ -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<std::string, LLKeyConflict> 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

View File

@ -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)
// <FS:CR> 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());
// </FS:CR> Aurora Sim
//height will get properly clammed by sendPosition
}

View File

@ -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)

View File

@ -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);

View File

@ -340,12 +340,12 @@ void LLPreviewNotecard::loadAsset()
{
editor->setEnabled(FALSE);
getChildView("lock")->setVisible( TRUE);
getChildView("Edit")->setEnabled(FALSE); // <FS:LO> 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); // <FS:LO> Don't enable external editor button on no mod notecards.
}
}
else

View File

@ -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<LLTextBox>("logos_lbl");

View File

@ -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<void(MASK)> 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<LLUICtrl>("Cancel")->setFocus(TRUE);
pCheckBox = getChild<LLCheckBoxCtrl>("apply_all");
pDesription = getChild<LLTextBase>("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<F32> 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<LLSetKeyBindDialog>("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;
}
}

View File

@ -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 <LLView> mFrustumOrigin;
F32 mContextConeOpacity;
F32 mContextConeInAlpha;
F32 mContextConeOutAlpha;
F32 mContextConeFadeTime;
};
#endif // LL_LLSETKEYBINDDIALOG_H

View File

@ -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))
{

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -39,7 +39,7 @@
#include "llagentcamera.h"
#include "llbutton.h"
#include "llviewercontrol.h"
#include "llviewerinput.h"//<FS:JL> Mouse movement by Singularity
#include "llviewerkeyboard.h"//<FS:JL> Mouse movement by Singularity
#include "lldrawable.h"
#include "lltooltip.h"
#include "llhudmanager.h"

View File

@ -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();
}
// <FS:Ansariel> FIRE-15189: Fix ClickToWalk not allowing mouse-walk (behavior change)
//if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk"))
if (object && object == gAgentAvatarp)
// </FS:Ansariel>
{
// 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())
{

View File

@ -42,13 +42,14 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
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<LLHUDEffectBlob> mAutoPilotDestination;
LLPointer<LLHUDEffectBlob> mMouseSteerGrabPoint;
bool mClockwise;
bool mBlockClickToWalk;
LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;

View File

@ -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)
// </FS:Ansariel>
{
// [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)
}
// </FS:CR>
// <FS:Ansariel> 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);
}
// </FS:Ansariel>
// <FS:Ansariel> 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:Ansariel> [FS communication UI]
gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2));
gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2));

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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<KeyBinding>
{
Mandatory<std::string> key,
mask,
command;
Optional<std::string> mouse; // Note, not mandatory for the sake of backward campatibility with keys.xml
KeyBinding();
};
struct KeyMode : public LLInitParam::Block<KeyMode>
{
Multiple<KeyBinding> bindings;
KeyMode();
};
struct Keys : public LLInitParam::Block<Keys>
{
Optional<KeyMode> 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<LLKeyboardBinding> &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<LLMouseBinding> &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<LLKeyboardBinding> mKeyBindings[MODE_COUNT];
std::vector<LLMouseBinding> mMouseBindings[MODE_COUNT];
typedef std::map<U32, U32> key_remap_t;
key_remap_t mRemapKeys[MODE_COUNT];
std::set<KEY> 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);//<FS:JL> Mouse movement by Singularity
#endif // LL_LLVIEWERINPUT_H

View File

@ -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; // <FS> Rye Mutt's broken local texture rendering fix
LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(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();
}
// <FS> Rye Mutt's broken local texture rendering fix
//if(mTexture->hasGLTexture())
//{
// old_mode = mTexture->getAddressMode();
//}
// </FS>
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
//gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); // <FS> 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);
}
// <FS> 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);
//}
// </FS>
return triangle_count;
}

File diff suppressed because it is too large Load Diff

View File

@ -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<KeyBinding>
{
Mandatory<std::string> key,
mask,
command;
KeyBinding();
};
struct KeyMode : public LLInitParam::Block<KeyMode>
{
Multiple<KeyBinding> bindings;
EKeyboardMode mode;
KeyMode(EKeyboardMode mode);
};
struct Keys : public LLInitParam::Block<Keys>
{
Optional<KeyMode> 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<U32, U32> key_remap_t;
key_remap_t mRemapKeys[MODE_COUNT];
std::set<KEY> mKeysSkippedByUI;
BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI
};
extern LLViewerKeyboard gViewerKeyboard;
void agent_push_forward(EKeystate s);//<FS:JL> Mouse movement by Singularity
#endif // LL_LLVIEWERKEYBOARD_H

View File

@ -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)
{

View File

@ -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();

View File

@ -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;

View File

@ -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<LLViewerObject> objectp, S32 face);
bool isHoveringOverFace(LLPointer<LLViewerObject> 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();

View File

@ -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()) // <FS:Ansariel> 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]
// <FS:Ansariel> Toggle internal web browser

View File

@ -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))
{

View File

@ -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; }

View File

@ -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();

View File

@ -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 ),
// <FS> Rye Mutt's broken local texture rendering fix
//LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, FALSE ),
// </FS>
// <FS:Ansariel> [Legacy Bake]
mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
mNeedsUpload(FALSE),

View File

@ -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"
//<FS:Beq> 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));
}
}

View File

@ -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

View File

@ -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

View File

@ -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); }

View File

@ -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()))) &&

View File

@ -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);
}
}

View File

@ -52,12 +52,12 @@
#include "llspinctrl.h"
#include "lltoolbarview.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h" // <FS:Beq/> 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::multimap<std::string, LLU
mDayCyclePresetsCombo->add(preset_name, LLSD(asset_id));
}
}
// <FS:Beq> 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<std::string, LLUUID>& sky_map)
@ -308,6 +329,27 @@ void FloaterQuickPrefs::loadSkyPresets(const std::multimap<std::string, LLUUID>&
mWLPresetsCombo->add(preset_name, LLSD(asset_id));
}
}
// <FS:Beq> 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<std::string, LLUUID>& water_map)
@ -328,6 +370,27 @@ void FloaterQuickPrefs::loadWaterPresets(const std::multimap<std::string, LLUUID
mWaterPresetsCombo->add(preset_name, LLSD(asset_id));
}
}
// <FS:Beq> 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);

View File

@ -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();

View File

@ -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
//

View File

@ -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
// =================

View File

@ -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

View File

@ -57,7 +57,7 @@ class RlvObject;
struct RlvException;
typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
typedef boost::variant<int, float, bool, LLVector3, LLUUID> RlvBehaviourModifierValue;
typedef boost::variant<int, float, bool, LLVector3, LLVector3d, LLUUID> 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);

View File

@ -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)

View File

@ -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 <boost/algorithm/string.hpp>
#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<LLUUID>("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<std::string>("preset", [&fnApplyLibraryPreset](LLEnvironment::EnvSelection_t env, const std::string& strPreset) { return fnApplyLibraryPreset(env, strPreset, LLSettingsType::ST_SKY); });
registerSetEnvFn<std::string>("daycycle", [&fnApplyLibraryPreset](LLEnvironment::EnvSelection_t env, const std::string& strPreset) { return fnApplyLibraryPreset(env, strPreset, LLSettingsType::ST_DAYCYCLE); });
//
// Atmosphere & Lighting tab
//
// SETTING_AMBIENT
registerSkyFn<LLColor3>("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<LLColor3>("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<LLColor3>("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<LLColor3>("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<LLColor3>("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<LLColor3>("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<F32>("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<F32>("distancemultiplier",[](LLSettingsSky::ptr_t pSky) { return pSky->getDistanceMultiplier(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setDistanceMultiplier(nValue); });
// SETTING_SKY_DROPLET_RADIUS
registerSkyFn<F32>("dropletradius", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyDropletRadius(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyDropletRadius(nValue); });
// SETTING_HAZE_DENSITY
registerSkyFn<F32>("hazedensity", [](LLSettingsSky::ptr_t pSky) { return pSky->getHazeDensity(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setHazeDensity(nValue); });
// SETTING_HAZE_HORIZON
registerSkyFn<F32>("hazehorizon", [](LLSettingsSky::ptr_t pSky) { return pSky->getHazeHorizon(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setHazeHorizon(nValue); });
// SETTING_SKY_ICE_LEVEL
registerSkyFn<F32>("icelevel", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyIceLevel(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyIceLevel(nValue); });
// SETTING_MAX_Y
registerSkyFn<F32>("maxaltitude", [](LLSettingsSky::ptr_t pSky) { return pSky->getMaxY(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMaxY(nValue); });
// SETTING_SKY_MOISTURE_LEVEL
registerSkyFn<F32>("moisturelevel", [](LLSettingsSky::ptr_t pSky) { return pSky->getSkyMoistureLevel(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setSkyMoistureLevel(nValue); });
// SETTING_GAMMA
registerSkyFn<F32>("scenegamma", [](LLSettingsSky::ptr_t pSky) { return pSky->getGamma(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setGamma(nValue); });
//
// Clouds tab
//
// SETTING_CLOUD_COLOR
registerSkyFn<LLColor3>("cloudcolor", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudColor(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudColor(clrValue); });
registerLegacySkyFn<LLColor3>("cloudcolor", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudColor(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudColor(clrValue); });
// SETTING_CLOUD_SHADOW
registerSkyFn<F32>("cloudcoverage", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudShadow(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudShadow(nValue); });
// SETTING_CLOUD_POS_DENSITY1
registerSkyFn<LLColor3>("clouddensity", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity1(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity1(clrValue); });
registerLegacySkyFn<LLColor3>("cloud", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity1(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity1(clrValue); });
// SETTING_CLOUD_POS_DENSITY2
registerSkyFn<LLColor3>("clouddetail", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity2(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity2(clrValue); });
registerLegacySkyFn<LLColor3>("clouddetail",[](LLSettingsSky::ptr_t pSky) { return pSky->getCloudPosDensity2(); },
[](LLSettingsSky::ptr_t pSky, const LLColor3& clrValue) { pSky->setCloudPosDensity2(clrValue); });
// SETTING_CLOUD_SCALE
registerSkyFn<F32>("cloudscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScale(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudScale(nValue); });
// SETTING_CLOUD_SCROLL_RATE
registerSkyFn<LLVector2>("cloudscroll", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScrollRate(); },
[](LLSettingsSky::ptr_t pSky, const LLVector2& vecValue) { pSky->setCloudScrollRate(vecValue); });
registerLegacySkyFn<LLVector2>("cloudscroll", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudScrollRate(); },
[](LLSettingsSky::ptr_t pSky, const LLVector2& vecValue) { pSky->setCloudScrollRate(vecValue); });
// SETTING_CLOUD_TEXTUREID
registerSkyFn<LLUUID>("cloudtexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudNoiseTextureId(); },
[](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setCloudNoiseTextureId(idTexture); });
// SETTING_CLOUD_VARIANCE
registerSkyFn<F32>("cloudvariance", [](LLSettingsSky::ptr_t pSky) { return pSky->getCloudVariance(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setCloudVariance(nValue); });
//
// Sun & Moon
//
// SETTING_MOON_BRIGHTNESS
registerSkyFn<F32>("moonbrightness", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonBrightness(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMoonBrightness(nValue); });
// SETTING_MOON_SCALE
registerSkyFn<F32>("moonscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonScale(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setMoonScale(nValue); });
// SETTING_MOON_TEXTUREID
registerSkyFn<LLUUID>("moontexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getMoonTextureId(); },
[](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setMoonTextureId(idTexture); });
// SETTING_GLOW
registerSkyFn<float>("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<float>("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<LLColor3>("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<LLColor3>("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<float>("sunscale", [](LLSettingsSky::ptr_t pSky) { return pSky->getSunScale(); },
[](LLSettingsSky::ptr_t pSky, F32 nValue) { pSky->setSunScale(nValue); });
// SETTING_SUN_TEXTUREID
registerSkyFn<LLUUID>("suntexture", [](LLSettingsSky::ptr_t pSky) { return pSky->getSunTextureId(); },
[](LLSettingsSky::ptr_t pSky, const LLUUID& idTexture) { pSky->setSunTextureId(idTexture); });
// SETTING_STAR_BRIGHTNESS
registerSkyFn<F32>("starbrightness", [](LLSettingsSky::ptr_t pSky) { return pSky->getStarBrightness(); },
[](LLSettingsSky::ptr_t pSky, const F32& nValue) { pSky->setStarBrightness(nValue); });
// SETTING_SUN_ROTATION
registerSkyFn<F32>("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<F32>("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<F32>("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<F32>("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<F32>("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<F32>("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<F32>("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<LLTrackBlenderLoopingManual>(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<float>(const std::function<float(LLSettingsSky::ptr_t)>& fn)
{
LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky();
return std::to_string(fn(pSky));
}
template<>
std::string RlvEnvironment::handleGetFn<LLUUID>(const std::function<LLUUID(LLSettingsSky::ptr_t)>& fn)
{
LLSettingsSky::ptr_t pSky = LLEnvironment::instance().getCurrentSky();
return fn(pSky).asString();
}
template<>
std::string RlvEnvironment::handleGetFn<LLVector2>(const std::function<LLVector2(LLSettingsSky::ptr_t)>& 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<LLColor3>(const std::function<LLColor3(LLSettingsSky::ptr_t)>& 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<typename T>
ERlvCmdRet RlvEnvironment::handleSetFn(const std::string& strRlvOption, const std::function<void(LLSettingsSky::ptr_t, const T&)>& fn)
{
T optionValue;
if (!RlvCommandOptionHelper::parseOption<T>(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<LLVector2>(const std::function<const LLVector2& (LLSettingsSkyPtr_t)>& getFn, U32 idxComponent)
{
if (idxComponent > 2)
return LLStringUtil::null;
return std::to_string(getFn(LLEnvironment::instance().getCurrentSky()).mV[idxComponent]);
}
template<>
std::string RlvEnvironment::handleLegacyGetFn<LLColor3>(const std::function<const LLColor3& (LLSettingsSkyPtr_t)>& 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<LLVector2>(float optionValue, LLVector2 curValue, const std::function<void(LLSettingsSkyPtr_t, const LLVector2&)>& 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<LLColor3>(float optionValue, LLColor3 curValue, const std::function<void(LLSettingsSkyPtr_t, const LLColor3&)>& 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<typename T>
void RlvEnvironment::registerSkyFn(const std::string& strFnName, const std::function<T(LLSettingsSkyPtr_t)>& getFn, const std::function<void(LLSettingsSkyPtr_t, const T&)>& 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<T>(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<T>(strRlvOption, setFn);
}));
}
void RlvEnvironment::registerGetEnvFn(const std::string& strFnName, const std::function<std::string(LLEnvironment::EnvSelection_t env)>& 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<typename T>
void RlvEnvironment::registerSetEnvFn(const std::string& strFnName, const std::function<ERlvCmdRet(LLEnvironment::EnvSelection_t env, const T& strRlvOption)>& 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<T>(strRlvOption, optionValue))
return RLV_RET_FAILED_PARAM;
return setFn(getTargetEnvironment(), optionValue);
}));
}
template<typename T>
void RlvEnvironment::registerLegacySkyFn(const std::string& strFnName, const std::function<const T& (LLSettingsSkyPtr_t)>& getFn, const std::function<void(LLSettingsSkyPtr_t, const T&)>& 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<T>(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<T>(optionValue, getFn(LLEnvironment::instance().getCurrentSky()), setFn, idxComponent);;
}));
}
// ================================================================================================

Some files were not shown because too many files have changed in this diff Show More