Merge viewer-neko
commit
0b6531f60f
|
|
@ -73,6 +73,7 @@ set(llcommon_SOURCE_FILES
|
|||
llinitparam.cpp
|
||||
llinitdestroyclass.cpp
|
||||
llinstancetracker.cpp
|
||||
llkeybind.cpp
|
||||
llleap.cpp
|
||||
llleaplistener.cpp
|
||||
llliveappconfig.cpp
|
||||
|
|
@ -183,6 +184,7 @@ set(llcommon_HEADER_FILES
|
|||
llinitdestroyclass.h
|
||||
llinitparam.h
|
||||
llinstancetracker.h
|
||||
llkeybind.h
|
||||
llkeythrottle.h
|
||||
llleap.h
|
||||
llleaplistener.h
|
||||
|
|
|
|||
|
|
@ -57,6 +57,17 @@ 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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,414 @@
|
|||
/**
|
||||
* @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) == data.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) == mask) || 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)
|
||||
{
|
||||
if (mouse != CLICK_NONE || key != KEY_NONE )
|
||||
{
|
||||
// if both click and key are none, we are inserting a placeholder, we don't want to reset anything
|
||||
// otherwise reset identical key
|
||||
for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++)
|
||||
{
|
||||
if (iter->mKey == key
|
||||
&& iter->mMouse == mouse
|
||||
&& iter->mIgnoreMasks == ignore
|
||||
&& (iter->mIgnoreMasks || iter->mMask == mask))
|
||||
{
|
||||
iter->reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mData.size() > index)
|
||||
{
|
||||
mData[index] = LLKeyData(mouse, key, mask, ignore);
|
||||
}
|
||||
else
|
||||
{
|
||||
mData.push_back(LLKeyData(mouse, key, mask, ignore));
|
||||
}
|
||||
}
|
||||
|
||||
void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index)
|
||||
{
|
||||
if (!data.isEmpty())
|
||||
{
|
||||
for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++)
|
||||
{
|
||||
if (iter->mKey == data.mKey
|
||||
&& iter->mMouse == data.mMouse
|
||||
&& iter->mIgnoreMasks == data.mIgnoreMasks
|
||||
&& (iter->mIgnoreMasks || iter->mMask == data.mMask))
|
||||
{
|
||||
iter->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();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* @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 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
|
||||
|
|
@ -223,6 +223,12 @@ 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)
|
||||
{
|
||||
|
|
@ -284,13 +290,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 <LLKeyBinding*> *listp)
|
||||
BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp)
|
||||
{
|
||||
LLKeyBinding *accelerator = NULL;
|
||||
LLMenuKeyboardBinding *accelerator = NULL;
|
||||
|
||||
if (mAcceleratorKey != KEY_NONE)
|
||||
{
|
||||
std::list<LLKeyBinding*>::iterator list_it;
|
||||
std::list<LLMenuKeyboardBinding*>::iterator list_it;
|
||||
for (list_it = listp->begin(); list_it != listp->end(); ++list_it)
|
||||
{
|
||||
accelerator = *list_it;
|
||||
|
|
@ -314,7 +320,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
|
|||
}
|
||||
if (!accelerator)
|
||||
{
|
||||
accelerator = new LLKeyBinding;
|
||||
accelerator = new LLMenuKeyboardBinding;
|
||||
if (accelerator)
|
||||
{
|
||||
accelerator->mKey = mAcceleratorKey;
|
||||
|
|
@ -1038,6 +1044,11 @@ 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);
|
||||
|
|
@ -1045,7 +1056,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<LLKeyBinding*> *listp)
|
||||
BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp)
|
||||
{
|
||||
LLMenuGL* branch = getBranch();
|
||||
if (!branch)
|
||||
|
|
@ -3028,6 +3039,27 @@ 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
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@
|
|||
extern S32 MENU_BAR_HEIGHT;
|
||||
extern S32 MENU_BAR_WIDTH;
|
||||
|
||||
class LLMenuKeyboardBinding
|
||||
{
|
||||
public:
|
||||
KEY mKey;
|
||||
MASK mMask;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLMenuItemGL
|
||||
//
|
||||
|
|
@ -92,6 +99,7 @@ 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(); }
|
||||
|
|
@ -110,7 +118,7 @@ public:
|
|||
virtual void setBriefItem(BOOL brief);
|
||||
virtual BOOL isBriefItem() const;
|
||||
|
||||
virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
|
||||
virtual BOOL addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp);
|
||||
void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
|
||||
BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; }
|
||||
|
||||
|
|
@ -437,7 +445,8 @@ 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;
|
||||
|
|
@ -630,10 +639,11 @@ 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 <LLKeyBinding*> *listp);
|
||||
virtual BOOL addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp);
|
||||
|
||||
// called to rebuild the draw label
|
||||
virtual void buildDrawLabel( void );
|
||||
|
|
@ -803,7 +813,7 @@ private:
|
|||
|
||||
void checkMenuTrigger();
|
||||
|
||||
std::list <LLKeyBinding*> mAccelerators;
|
||||
std::list <LLMenuKeyboardBinding*> mAccelerators;
|
||||
BOOL mAltKeyTrigger;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ 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);
|
||||
|
|
@ -168,7 +172,7 @@ U32 LLScrollListText::sCount = 0;
|
|||
|
||||
LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
|
||||
: LLScrollListCell(p),
|
||||
mText(p.value().asString()),
|
||||
mText(p.label.isProvided() ? p.label() : p.value().asString()),
|
||||
mFont(p.font),
|
||||
mColor(p.color),
|
||||
mUseColor(p.color.isProvided()),
|
||||
|
|
@ -192,7 +196,7 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
|
|||
void LLScrollListText::highlightText(S32 offset, S32 num_chars)
|
||||
{
|
||||
mHighlightOffset = offset;
|
||||
mHighlightCount = num_chars;
|
||||
mHighlightCount = llmax(0, num_chars);
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -292,11 +296,12 @@ 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(), 0, mHighlightOffset);
|
||||
left = mFont->getWidth(mText.getString(), 1, mHighlightOffset);
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX);
|
||||
|
|
@ -319,7 +324,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
|
|||
switch(mFontAlignment)
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
start_x = 0.f;
|
||||
start_x = 1.f;
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
start_x = (F32)getWidth();
|
||||
|
|
@ -435,3 +440,139 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ public:
|
|||
visible;
|
||||
|
||||
Optional<void*> userdata;
|
||||
Optional<LLSD> value;
|
||||
Optional<LLSD> value; // state of checkbox, icon id/name, date
|
||||
Optional<std::string> label; // description or text
|
||||
Optional<std::string> tool_tip;
|
||||
|
||||
Optional<const LLFontGL*> font;
|
||||
|
|
@ -75,6 +76,7 @@ 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),
|
||||
|
|
@ -152,11 +154,12 @@ public:
|
|||
void setText(const LLStringExplicit& text);
|
||||
void setFontStyle(const U8 font_style);
|
||||
|
||||
private:
|
||||
protected:
|
||||
LLUIString mText;
|
||||
S32 mTextWidth;
|
||||
const LLFontGL* mFont;
|
||||
LLColor4 mColor;
|
||||
LLColor4 mHighlightColor;
|
||||
U8 mUseColor;
|
||||
LLFontGL::HAlign mFontAlignment;
|
||||
BOOL mVisible;
|
||||
|
|
@ -169,7 +172,7 @@ private:
|
|||
};
|
||||
|
||||
/*
|
||||
* Cell displaying an image.
|
||||
* Cell displaying an image. AT the moment, this is specifically UI image
|
||||
*/
|
||||
class LLScrollListIcon : public LLScrollListCell
|
||||
{
|
||||
|
|
@ -223,4 +226,26 @@ 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
|
||||
|
|
|
|||
|
|
@ -117,6 +117,13 @@ 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")
|
||||
|
|
@ -130,8 +137,10 @@ 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),
|
||||
|
|
@ -167,8 +176,10 @@ 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 ),
|
||||
|
|
@ -909,7 +920,15 @@ BOOL LLScrollListCtrl::selectFirstItem()
|
|||
{
|
||||
if (!itemp->getSelected())
|
||||
{
|
||||
selectItem(itemp);
|
||||
switch (mSelectionType)
|
||||
{
|
||||
case CELL:
|
||||
selectItem(itemp, 0);
|
||||
break;
|
||||
case HEADER:
|
||||
case ROW:
|
||||
selectItem(itemp, -1);
|
||||
}
|
||||
}
|
||||
success = TRUE;
|
||||
mOriginalSelection = 0;
|
||||
|
|
@ -976,7 +995,8 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index )
|
|||
{
|
||||
if( itemp->getEnabled() )
|
||||
{
|
||||
selectItem(itemp, FALSE);
|
||||
// TODO: support range selection for cells
|
||||
selectItem(itemp, -1, FALSE);
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1102,10 +1122,14 @@ void LLScrollListCtrl::clearHighlightedItems()
|
|||
|
||||
void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index)
|
||||
{
|
||||
if (mHighlightedItem != target_index)
|
||||
{
|
||||
mHighlightedItem = target_index;
|
||||
}
|
||||
if (mHighlightedItem != target_index)
|
||||
{
|
||||
if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size())
|
||||
{
|
||||
mItemList[mHighlightedItem]->setHoverCell(-1);
|
||||
}
|
||||
mHighlightedItem = target_index;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
|
||||
|
|
@ -1120,7 +1144,8 @@ S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
|
|||
{
|
||||
if (item->getEnabled() && (item->getUUID() == (*iditr)))
|
||||
{
|
||||
selectItem(item,FALSE);
|
||||
// TODO: support multiple selection for cells
|
||||
selectItem(item, -1, FALSE);
|
||||
++count;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1199,7 +1224,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection)
|
|||
{
|
||||
if (prev_item)
|
||||
{
|
||||
selectItem(prev_item, !extend_selection);
|
||||
selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1243,7 +1268,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
|
|||
{
|
||||
if (next_item)
|
||||
{
|
||||
selectItem(next_item, !extend_selection);
|
||||
selectItem(next_item, cur_item->getSelectedCell(), !extend_selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1322,7 +1347,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
|
|||
bool found = NULL != item;
|
||||
if(found)
|
||||
{
|
||||
selectItem(item);
|
||||
selectItem(item, -1);
|
||||
}
|
||||
|
||||
if (mCommitOnSelectionChange)
|
||||
|
|
@ -1397,7 +1422,7 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre
|
|||
BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
|
||||
if (select)
|
||||
{
|
||||
selectItem(item);
|
||||
selectItem(item, -1);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1448,7 +1473,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);
|
||||
selectItem(item, -1);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1527,7 +1552,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
|
|||
{
|
||||
if (selected)
|
||||
{
|
||||
selectItem(item);
|
||||
selectItem(item, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1609,7 +1634,7 @@ void LLScrollListCtrl::drawItems()
|
|||
|
||||
S32 max_columns = 0;
|
||||
|
||||
LLColor4 highlight_color = LLColor4::white;
|
||||
LLColor4 highlight_color = LLColor4::white; // ex: text inside cells
|
||||
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);
|
||||
|
||||
|
|
@ -1661,7 +1686,8 @@ void LLScrollListCtrl::drawItems()
|
|||
max_columns = llmax(max_columns, item->getNumColumns());
|
||||
|
||||
LLColor4 fg_color;
|
||||
LLColor4 bg_color(LLColor4::transparent);
|
||||
LLColor4 hover_color(LLColor4::transparent);
|
||||
LLColor4 select_color(LLColor4::transparent);
|
||||
|
||||
if( mScrollLines <= line && line < mScrollLines + num_page_lines )
|
||||
{
|
||||
|
|
@ -1670,45 +1696,45 @@ void LLScrollListCtrl::drawItems()
|
|||
{
|
||||
if(item->getHighlighted()) // if it's highlighted, average the colors
|
||||
{
|
||||
bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
|
||||
select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
|
||||
}
|
||||
else // otherwise just select-highlight it
|
||||
{
|
||||
bg_color = mBgSelectedColor.get();
|
||||
select_color = mBgSelectedColor.get();
|
||||
}
|
||||
|
||||
fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get());
|
||||
}
|
||||
else if (mHighlightedItem == line && mCanSelect)
|
||||
if (mHighlightedItem == line && mCanSelect)
|
||||
{
|
||||
if(item->getHighlighted()) // if it's highlighted, average the colors
|
||||
{
|
||||
bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
|
||||
hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
|
||||
}
|
||||
else // otherwise just hover-highlight it
|
||||
{
|
||||
bg_color = mHoveredColor.get();
|
||||
hover_color = mHoveredColor.get();
|
||||
}
|
||||
}
|
||||
else if (item->getHighlighted())
|
||||
{
|
||||
bg_color = mHighlightedColor.get();
|
||||
hover_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))
|
||||
{
|
||||
bg_color = mBgStripeColor.get();
|
||||
hover_color = mBgStripeColor.get();
|
||||
}
|
||||
}
|
||||
|
||||
if (!item->getEnabled())
|
||||
{
|
||||
bg_color = mBgReadOnlyColor.get();
|
||||
hover_color = mBgReadOnlyColor.get();
|
||||
}
|
||||
|
||||
item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
|
||||
item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding);
|
||||
|
||||
cur_y -= mLineHeight;
|
||||
}
|
||||
|
|
@ -1884,7 +1910,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (mLastSelected == NULL)
|
||||
{
|
||||
selectItem(hit_item);
|
||||
selectItem(hit_item, getColumnIndexFromOffset(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1914,7 +1940,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, FALSE);
|
||||
selectItem(item, getColumnIndexFromOffset(x), FALSE);
|
||||
selecting = !selecting;
|
||||
if (hit_item == lastSelected)
|
||||
{
|
||||
|
|
@ -1924,7 +1950,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
if (selecting)
|
||||
{
|
||||
selectItem(item, FALSE);
|
||||
selectItem(item, getColumnIndexFromOffset(x), FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1939,7 +1965,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable))
|
||||
{
|
||||
selectItem(hit_item, FALSE);
|
||||
selectItem(hit_item, getColumnIndexFromOffset(x), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1953,12 +1979,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
|
|||
else
|
||||
{
|
||||
deselectAllItems(TRUE);
|
||||
selectItem(hit_item);
|
||||
selectItem(hit_item, getColumnIndexFromOffset(x));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectItem(hit_item);
|
||||
selectItem(hit_item, getColumnIndexFromOffset(x));
|
||||
}
|
||||
|
||||
selection_changed = mSelectionChanged;
|
||||
|
|
@ -2365,8 +2391,29 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
|
|||
{
|
||||
LLScrollListItem* item = hitItem(x, y);
|
||||
if (item)
|
||||
{
|
||||
mouseOverHighlightNthItem(getItemIndex(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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2414,6 +2461,52 @@ 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())
|
||||
{
|
||||
|
|
@ -2593,7 +2686,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);
|
||||
selectItem(item, -1);
|
||||
mNeedsScroll = true;
|
||||
cellp->highlightText(0, 1);
|
||||
mSearchTimer.reset();
|
||||
|
|
@ -2645,7 +2738,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item)
|
||||
void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item)
|
||||
{
|
||||
if (!itemp) return;
|
||||
|
||||
|
|
@ -2664,6 +2757,18 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
|
|||
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;
|
||||
}
|
||||
|
|
@ -2931,7 +3036,7 @@ void LLScrollListCtrl::selectAll()
|
|||
LLScrollListItem *itemp = *iter;
|
||||
if( itemp->getEnabled() )
|
||||
{
|
||||
selectItem(itemp, FALSE);
|
||||
selectItem(itemp, -1, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3108,6 +3213,8 @@ 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];
|
||||
|
|
@ -3472,7 +3579,7 @@ void LLScrollListCtrl::setFilterString(const std::string& str)
|
|||
{
|
||||
if (!isFiltered(*iter))
|
||||
{
|
||||
selectItem(*iter);
|
||||
selectItem(*iter, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,18 @@ 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;
|
||||
|
|
@ -99,6 +111,8 @@ public:
|
|||
commit_on_keyboard_movement,
|
||||
mouse_wheel_opaque;
|
||||
|
||||
Optional<ESelectionType, SelectionTypeNames> selection_type;
|
||||
|
||||
// display flags
|
||||
Optional<bool> has_border,
|
||||
draw_heading,
|
||||
|
|
@ -114,7 +128,8 @@ public:
|
|||
// sort and search behavior
|
||||
Optional<S32> search_column,
|
||||
sort_column;
|
||||
Optional<bool> sort_ascending;
|
||||
Optional<bool> sort_ascending,
|
||||
can_sort; // whether user is allowed to sort
|
||||
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
|
||||
|
||||
|
|
@ -456,7 +471,7 @@ private:
|
|||
void updateLineHeightInsert(LLScrollListItem* item);
|
||||
void reportInvalidInput();
|
||||
BOOL isRepeatedChars(const LLWString& string) const;
|
||||
void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
|
||||
void selectItem(LLScrollListItem* itemp, S32 cell, BOOL single_select = TRUE);
|
||||
void deselectItem(LLScrollListItem* itemp);
|
||||
void commitIfChanged();
|
||||
BOOL setSort(S32 column, BOOL ascending);
|
||||
|
|
@ -484,9 +499,11 @@ 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;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
LLScrollListItem::LLScrollListItem( const Params& p )
|
||||
: mSelected(FALSE),
|
||||
mHighlighted(FALSE),
|
||||
mHoverIndex(-1),
|
||||
mSelectedIndex(-1),
|
||||
mEnabled(p.enabled),
|
||||
mUserdata(p.userdata),
|
||||
mItemValue(p.value)
|
||||
|
|
@ -53,6 +55,28 @@ 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));
|
||||
|
|
@ -120,12 +144,21 @@ std::string LLScrollListItem::getContentsCSV() const
|
|||
}
|
||||
|
||||
|
||||
void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
|
||||
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)
|
||||
{
|
||||
// draw background rect
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLRect bg_rect = rect;
|
||||
gl_rect_2d( bg_rect, bg_color );
|
||||
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);
|
||||
}
|
||||
|
||||
S32 cur_x = rect.mLeft;
|
||||
S32 num_cols = getNumColumns();
|
||||
|
|
@ -141,6 +174,25 @@ 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();
|
||||
|
|
|
|||
|
|
@ -77,15 +77,21 @@ public:
|
|||
|
||||
virtual ~LLScrollListItem();
|
||||
|
||||
void setSelected( BOOL b ) { mSelected = b; }
|
||||
void setSelected( BOOL b );
|
||||
BOOL getSelected() const { return mSelected; }
|
||||
|
||||
void setEnabled( BOOL b ) { mEnabled = b; }
|
||||
BOOL getEnabled() const { return mEnabled; }
|
||||
|
||||
void setHighlighted( BOOL b ) { mHighlighted = b; }
|
||||
void setHighlighted( BOOL 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; }
|
||||
|
||||
|
|
@ -107,14 +113,21 @@ public:
|
|||
|
||||
std::string getContentsCSV() const;
|
||||
|
||||
virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
|
||||
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);
|
||||
|
||||
protected:
|
||||
LLScrollListItem( const Params& );
|
||||
|
||||
private:
|
||||
BOOL mSelected;
|
||||
BOOL mHighlighted;
|
||||
BOOL mHighlighted;
|
||||
S32 mHoverIndex;
|
||||
S32 mSelectedIndex;
|
||||
BOOL mEnabled;
|
||||
void* mUserdata;
|
||||
LLSD mItemValue;
|
||||
|
|
|
|||
|
|
@ -347,7 +347,48 @@ std::string LLKeyboard::stringFromKey(KEY key)
|
|||
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 )
|
||||
{
|
||||
|
|
@ -359,41 +400,7 @@ std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key )
|
|||
return 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
|
||||
res.append(stringFromAccelerator(accel_mask));
|
||||
std::string key_string = LLKeyboard::stringFromKey(key);
|
||||
if ((accel_mask & MASK_NORMALKEYS) &&
|
||||
(key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+'))
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ enum EKeystate
|
|||
{
|
||||
KEYSTATE_DOWN,
|
||||
KEYSTATE_LEVEL,
|
||||
KEYSTATE_UP
|
||||
KEYSTATE_UP
|
||||
};
|
||||
|
||||
typedef boost::function<void(EKeystate keystate)> LLKeyFunc;
|
||||
typedef boost::function<bool(EKeystate keystate)> LLKeyFunc;
|
||||
typedef std::string (LLKeyStringTranslatorFunc)(const char *label);
|
||||
|
||||
enum EKeyboardInsertMode
|
||||
|
|
@ -50,15 +50,6 @@ enum EKeyboardInsertMode
|
|||
LL_KIM_OVERWRITE
|
||||
};
|
||||
|
||||
class LLKeyBinding
|
||||
{
|
||||
public:
|
||||
KEY mKey;
|
||||
MASK mMask;
|
||||
// const char *mName; // unused
|
||||
LLKeyFunc mFunction;
|
||||
};
|
||||
|
||||
class LLWindowCallbacks;
|
||||
|
||||
class LLKeyboard
|
||||
|
|
@ -104,6 +95,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);
|
||||
static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"...
|
||||
static std::string stringFromAccelerator( MASK accel_mask, KEY key );
|
||||
|
||||
void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "llmousehandler.h"
|
||||
|
||||
//virtual
|
||||
BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
|
||||
BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
if (down)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "llrect.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
// Mostly-abstract interface.
|
||||
// Intended for use via multiple inheritance.
|
||||
|
|
@ -46,16 +47,7 @@ public:
|
|||
SHOW_ALWAYS,
|
||||
} EShowToolTip;
|
||||
|
||||
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 handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType 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;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ set(llxml_HEADER_FILES
|
|||
CMakeLists.txt
|
||||
|
||||
llcontrol.h
|
||||
llcontrolgroupreader.h
|
||||
llxmlnode.h
|
||||
llxmlparser.h
|
||||
llxmltree.h
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
#include "llrefcount.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
#include "llcontrolgroupreader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
/**
|
||||
* @file llcontrolgroupreader.h
|
||||
* @brief Interface providing readonly access to LLControlGroup (intended for unit testing)
|
||||
*
|
||||
* $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_LLCONTROLGROUPREADER_H
|
||||
#define LL_LLCONTROLGROUPREADER_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include <string>
|
||||
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
#include "llrect.h"
|
||||
|
||||
class LLControlGroupReader
|
||||
{
|
||||
public:
|
||||
LLControlGroupReader() {}
|
||||
virtual ~LLControlGroupReader() {}
|
||||
|
||||
virtual std::string getString(const std::string& name) { return ""; }
|
||||
virtual LLWString getWString(const std::string& name) { return LLWString(); }
|
||||
virtual std::string getText(const std::string& name) { return ""; }
|
||||
virtual LLVector3 getVector3(const std::string& name) { return LLVector3(); }
|
||||
virtual LLVector3d getVector3d(const std::string& name) { return LLVector3d(); }
|
||||
virtual LLRect getRect(const std::string& name) { return LLRect(); }
|
||||
virtual BOOL getBOOL(const std::string& name) { return FALSE; }
|
||||
virtual S32 getS32(const std::string& name) { return 0; }
|
||||
virtual F32 getF32(const std::string& name) {return 0.0f; }
|
||||
virtual U32 getU32(const std::string& name) {return 0; }
|
||||
virtual LLSD getLLSD(const std::string& name) { return LLSD(); }
|
||||
|
||||
virtual LLColor4 getColor(const std::string& name) { return LLColor4(); }
|
||||
virtual LLColor4 getColor4(const std::string& name) { return LLColor4(); }
|
||||
virtual LLColor3 getColor3(const std::string& name) { return LLColor3(); }
|
||||
|
||||
virtual void setBOOL(const std::string& name, BOOL val) {}
|
||||
virtual void setS32(const std::string& name, S32 val) {}
|
||||
virtual void setF32(const std::string& name, F32 val) {}
|
||||
virtual void setU32(const std::string& name, U32 val) {}
|
||||
virtual void setString(const std::string& name, const std::string& val) {}
|
||||
virtual void setVector3(const std::string& name, const LLVector3 &val) {}
|
||||
virtual void setVector3d(const std::string& name, const LLVector3d &val) {}
|
||||
virtual void setRect(const std::string& name, const LLRect &val) {}
|
||||
virtual void setColor4(const std::string& name, const LLColor4 &val) {}
|
||||
virtual void setLLSD(const std::string& name, const LLSD& val) {}
|
||||
};
|
||||
|
||||
#endif /* LL_LLCONTROLGROUPREADER_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -291,6 +291,7 @@ set(viewer_SOURCE_FILES
|
|||
lldonotdisturbnotificationstorage.cpp
|
||||
lldndbutton.cpp
|
||||
lldrawable.cpp
|
||||
lldrawfrustum.cpp
|
||||
lldrawpool.cpp
|
||||
lldrawpoolalpha.cpp
|
||||
lldrawpoolavatar.cpp
|
||||
|
|
@ -491,6 +492,7 @@ set(viewer_SOURCE_FILES
|
|||
llinventoryobserver.cpp
|
||||
llinventorypanel.cpp
|
||||
lljoystickbutton.cpp
|
||||
llkeyconflict.cpp
|
||||
lllandmarkactions.cpp
|
||||
lllandmarklist.cpp
|
||||
lllistbrowser.cpp
|
||||
|
|
@ -664,6 +666,7 @@ set(viewer_SOURCE_FILES
|
|||
llsecapi.cpp
|
||||
llsechandler_basic.cpp
|
||||
llselectmgr.cpp
|
||||
llsetkeybinddialog.cpp
|
||||
llshareavatarhandler.cpp
|
||||
llsidepanelappearance.cpp
|
||||
llsidepanelinventory.cpp
|
||||
|
|
@ -768,7 +771,7 @@ set(viewer_SOURCE_FILES
|
|||
llviewerjointattachment.cpp
|
||||
llviewerjointmesh.cpp
|
||||
llviewerjoystick.cpp
|
||||
llviewerkeyboard.cpp
|
||||
llviewerinput.cpp
|
||||
llviewerlayer.cpp
|
||||
llviewermedia.cpp
|
||||
llviewermedia_streamingaudio.cpp
|
||||
|
|
@ -1051,6 +1054,7 @@ set(viewer_HEADER_FILES
|
|||
lldonotdisturbnotificationstorage.h
|
||||
lldndbutton.h
|
||||
lldrawable.h
|
||||
lldrawfrustum.h
|
||||
lldrawpool.h
|
||||
lldrawpoolalpha.h
|
||||
lldrawpoolavatar.h
|
||||
|
|
@ -1252,6 +1256,7 @@ set(viewer_HEADER_FILES
|
|||
llinventoryobserver.h
|
||||
llinventorypanel.h
|
||||
lljoystickbutton.h
|
||||
llkeyconflict.h
|
||||
lllandmarkactions.h
|
||||
lllandmarklist.h
|
||||
lllightconstants.h
|
||||
|
|
@ -1416,6 +1421,7 @@ set(viewer_HEADER_FILES
|
|||
llsecapi.h
|
||||
llsechandler_basic.h
|
||||
llselectmgr.h
|
||||
llsetkeybinddialog.h
|
||||
llsidepanelappearance.h
|
||||
llsidepanelinventory.h
|
||||
llsidepanelinventorysubpanel.h
|
||||
|
|
@ -1522,7 +1528,7 @@ set(viewer_HEADER_FILES
|
|||
llviewerjointattachment.h
|
||||
llviewerjointmesh.h
|
||||
llviewerjoystick.h
|
||||
llviewerkeyboard.h
|
||||
llviewerinput.h
|
||||
llviewerlayer.h
|
||||
llviewermedia.h
|
||||
llviewermediafocus.h
|
||||
|
|
@ -2020,7 +2026,7 @@ set(viewer_APPSETTINGS_FILES
|
|||
app_settings/growl_notifications.xml
|
||||
app_settings/high_graphics.xml
|
||||
app_settings/ignorable_dialogs.xml
|
||||
app_settings/keys.xml
|
||||
app_settings/key_bindings.xml
|
||||
app_settings/keys_azerty.xml
|
||||
app_settings/keywords.ini
|
||||
app_settings/keywords_lsl_default.xml
|
||||
|
|
|
|||
|
|
@ -28,34 +28,12 @@
|
|||
<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="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"/>
|
||||
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
|
||||
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
|
||||
</first_person>
|
||||
<third_person>
|
||||
<binding key="A" mask="NONE" command="turn_left"/>
|
||||
|
|
@ -64,15 +42,10 @@
|
|||
<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"/>
|
||||
|
|
@ -84,13 +57,8 @@
|
|||
<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"/>
|
||||
|
|
@ -99,20 +67,12 @@
|
|||
<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"/>
|
||||
|
|
@ -139,28 +99,14 @@
|
|||
<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"/>
|
||||
|
|
@ -179,63 +125,10 @@
|
|||
<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"/>
|
||||
|
|
@ -251,15 +144,11 @@
|
|||
<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"/>
|
||||
|
|
@ -294,23 +183,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"/>
|
||||
|
||||
|
|
@ -334,6 +223,9 @@
|
|||
|
||||
<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-->
|
||||
|
|
@ -359,5 +251,7 @@
|
|||
<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>
|
||||
|
|
@ -1,363 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<keys>
|
||||
<first_person>
|
||||
<binding key="Q" mask="NONE" command="slide_left"/>
|
||||
<binding key="D" mask="NONE" command="slide_right"/>
|
||||
<binding key="Z" mask="NONE" command="push_forward"/>
|
||||
<binding key="S" mask="NONE" command="push_backward"/>
|
||||
<binding key="E" mask="NONE" command="jump"/>
|
||||
<binding key="C" mask="NONE" command="push_down"/>
|
||||
<binding key="F" mask="NONE" command="toggle_fly"/>
|
||||
|
||||
<binding key="LEFT" mask="NONE" command="slide_left"/>
|
||||
<binding key="RIGHT" mask="NONE" command="slide_right"/>
|
||||
<binding key="UP" mask="NONE" command="push_forward"/>
|
||||
<binding key="DOWN" mask="NONE" command="push_backward"/>
|
||||
<binding key="PGUP" mask="NONE" command="jump"/>
|
||||
<binding key="PGDN" mask="NONE" command="push_down"/>
|
||||
<binding key="HOME" mask="NONE" command="toggle_fly"/>
|
||||
|
||||
<binding key="PAD_LEFT" mask="NONE" command="slide_left"/>
|
||||
<binding key="PAD_RIGHT" mask="NONE" command="slide_right"/>
|
||||
<binding key="PAD_UP" mask="NONE" command="push_forward"/>
|
||||
<binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
|
||||
<binding key="PAD_PGUP" mask="NONE" command="jump"/>
|
||||
<binding key="PAD_PGDN" mask="NONE" command="push_down"/>
|
||||
<binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
|
||||
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
|
||||
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
|
||||
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
|
||||
<binding key="Q" mask="NONE" command="slide_left"/>
|
||||
<binding key="D" mask="NONE" command="slide_right"/>
|
||||
<binding key="Z" mask="NONE" command="push_forward"/>
|
||||
<binding key="S" mask="NONE" command="push_backward"/>
|
||||
<binding key="E" mask="NONE" command="jump"/>
|
||||
<binding key="C" mask="NONE" command="push_down"/>
|
||||
<binding key="F" mask="NONE" 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="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="Q" mask="NONE" command="turn_left"/>
|
||||
<binding key="D" mask="NONE" command="turn_right"/>
|
||||
<binding key="Q" mask="SHIFT" command="slide_left"/>
|
||||
<binding key="D" mask="SHIFT" command="slide_right"/>
|
||||
<binding key="Z" mask="NONE" command="push_forward"/>
|
||||
<binding key="S" mask="NONE" command="push_backward"/>
|
||||
<binding key="Z" 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"/>
|
||||
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
|
||||
<binding key="LEFT" mask="NONE" command="turn_left"/>
|
||||
<binding key="LEFT" mask="SHIFT" command="slide_left"/>
|
||||
<binding key="RIGHT" mask="NONE" command="turn_right"/>
|
||||
<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"/>
|
||||
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
|
||||
<binding key="PAD_RIGHT" mask="NONE" command="turn_right"/>
|
||||
<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"/>
|
||||
<binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
|
||||
<binding key="UP" mask="ALT" command="move_forward"/>
|
||||
<binding key="DOWN" mask="ALT" command="move_backward"/>
|
||||
<binding key="PGUP" mask="ALT" command="spin_over"/>
|
||||
<binding key="PGDN" mask="ALT" command="spin_under"/>
|
||||
|
||||
<binding key="Q" mask="ALT" command="spin_around_cw"/>
|
||||
<binding key="D" mask="ALT" command="spin_around_ccw"/>
|
||||
<binding key="Z" mask="ALT" command="move_forward"/>
|
||||
<binding key="S" mask="ALT" command="move_backward"/>
|
||||
<binding key="E" mask="ALT" command="spin_over"/>
|
||||
<binding key="C" mask="ALT" command="spin_under"/>
|
||||
|
||||
<binding key="PAD_LEFT" mask="ALT" command="spin_around_cw"/>
|
||||
<binding key="PAD_RIGHT" mask="ALT" command="spin_around_ccw"/>
|
||||
<binding key="PAD_UP" mask="ALT" command="move_forward"/>
|
||||
<binding key="PAD_DOWN" mask="ALT" command="move_backward"/>
|
||||
<binding key="PAD_PGUP" mask="ALT" command="spin_over"/>
|
||||
<binding key="PAD_PGDN" mask="ALT" command="spin_under"/>
|
||||
<binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
|
||||
<binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
|
||||
|
||||
<!--mimic alt zoom behavior with keyboard only-->
|
||||
<binding key="Q" mask="CTL_ALT" command="spin_around_cw"/>
|
||||
<binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
|
||||
<binding key="Z" 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="Q" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="Z" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<binding key="S" mask="CTL_ALT_SHIFT" command="pan_down"/>
|
||||
|
||||
<binding key="LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
|
||||
|
||||
<binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<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"/>
|
||||
</third_person>
|
||||
|
||||
<!--Basic editing camera control-->
|
||||
<edit>
|
||||
<binding key="Q" mask="NONE" command="spin_around_cw"/>
|
||||
<binding key="D" mask="NONE" command="spin_around_ccw"/>
|
||||
<binding key="Z" 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="Q" mask="SHIFT" command="pan_left"/>
|
||||
<binding key="D" mask="SHIFT" command="pan_right"/>
|
||||
<binding key="Z" 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="Q" mask="ALT" command="slide_left"/>
|
||||
<binding key="D" mask="ALT" command="slide_right"/>
|
||||
<binding key="Z" 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="Q" mask="ALT" command="spin_around_cw"/>
|
||||
<binding key="D" mask="ALT" command="spin_around_ccw"/>
|
||||
<binding key="Z" mask="ALT" command="move_forward"/>
|
||||
<binding key="S" mask="ALT" command="move_backward"/>
|
||||
<binding key="E" mask="ALT" command="spin_over_sitting"/>
|
||||
<binding key="C" mask="ALT" command="spin_under_sitting"/>
|
||||
|
||||
<binding key="LEFT" mask="ALT" command="spin_around_cw"/>
|
||||
<binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
|
||||
<binding key="UP" mask="ALT" command="move_forward"/>
|
||||
<binding key="DOWN" mask="ALT" command="move_backward"/>
|
||||
<binding key="PGUP" mask="ALT" command="spin_over"/>
|
||||
<binding key="PGDN" mask="ALT" command="spin_under"/>
|
||||
|
||||
<binding key="Q" mask="CTL_ALT" command="spin_around_cw"/>
|
||||
<binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
|
||||
<binding key="Z" 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="Q" mask="NONE" command="spin_around_cw_sitting"/>
|
||||
<binding key="D" mask="NONE" command="spin_around_ccw_sitting"/>
|
||||
<binding key="Z" mask="NONE" command="move_forward_sitting"/>
|
||||
<binding key="S" mask="NONE" command="move_backward_sitting"/>
|
||||
<binding key="E" mask="NONE" command="spin_over_sitting"/>
|
||||
<binding key="C" mask="NONE" command="spin_under_sitting"/>
|
||||
|
||||
<binding key="LEFT" mask="NONE" command="spin_around_cw_sitting"/>
|
||||
<binding key="RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
|
||||
<binding key="UP" mask="NONE" command="move_forward_sitting"/>
|
||||
<binding key="DOWN" mask="NONE" command="move_backward_sitting"/>
|
||||
<binding key="PGUP" mask="NONE" command="spin_over_sitting"/>
|
||||
<binding key="PGDN" mask="NONE" command="spin_under_sitting"/>
|
||||
|
||||
<binding key="PAD_LEFT" mask="NONE" command="spin_around_cw_sitting"/>
|
||||
<binding key="PAD_RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
|
||||
<binding key="PAD_UP" mask="NONE" command="move_forward_sitting"/>
|
||||
<binding key="PAD_DOWN" mask="NONE" command="move_backward_sitting"/>
|
||||
<binding key="PAD_PGUP" mask="NONE" command="spin_over_sitting"/>
|
||||
<binding key="PAD_PGDN" mask="NONE" command="spin_under_sitting"/>
|
||||
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
|
||||
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
|
||||
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
|
||||
<!--these are for passing controls when sitting on vehicles-->
|
||||
<binding key="Q" mask="SHIFT" command="slide_left"/>
|
||||
<binding key="D" mask="SHIFT" command="slide_right"/>
|
||||
<binding key="Z" 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="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="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_ENTER" mask="SHIFT" command="start_chat"/>
|
||||
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
|
||||
|
||||
<!--pan on Alt-Shift-->
|
||||
<binding key="Q" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="Z" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<binding key="S" mask="CTL_ALT_SHIFT" command="pan_down"/>
|
||||
|
||||
<binding key="LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
|
||||
|
||||
<binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
|
||||
<binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
|
||||
<binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
|
||||
<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="ENTER" mask="NONE" command="start_chat"/>
|
||||
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
</sitting>
|
||||
<edit_avatar>
|
||||
<!--Avatar editing camera controls-->
|
||||
<binding key="Q" mask="NONE" command="edit_avatar_spin_cw"/>
|
||||
<binding key="D" mask="NONE" command="edit_avatar_spin_ccw"/>
|
||||
<binding key="Z" mask="NONE" command="edit_avatar_move_forward"/>
|
||||
<binding key="S" mask="NONE" command="edit_avatar_move_backward"/>
|
||||
<binding key="E" mask="NONE" command="edit_avatar_spin_over"/>
|
||||
<binding key="C" mask="NONE" command="edit_avatar_spin_under"/>
|
||||
<binding key="LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
|
||||
<binding key="RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
|
||||
<binding key="UP" mask="NONE" command="edit_avatar_move_forward"/>
|
||||
<binding key="DOWN" mask="NONE" command="edit_avatar_move_backward"/>
|
||||
<binding key="PGUP" mask="NONE" command="edit_avatar_spin_over"/>
|
||||
<binding key="PGDN" mask="NONE" command="edit_avatar_spin_under"/>
|
||||
<binding key="ENTER" mask="NONE" command="start_chat"/>
|
||||
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
<binding key="PAD_LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
|
||||
<binding key="PAD_RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
|
||||
<binding key="PAD_UP" mask="NONE" command="edit_avatar_move_forward"/>
|
||||
<binding key="PAD_DOWN" mask="NONE" command="edit_avatar_move_backward"/>
|
||||
<binding key="PAD_PGUP" mask="NONE" command="edit_avatar_spin_over"/>
|
||||
<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"/>
|
||||
</edit_avatar>
|
||||
</keys>
|
||||
|
|
@ -5507,7 +5507,7 @@
|
|||
<key>DoubleClickAutoPilot</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable double-click auto pilot</string>
|
||||
<string>(Obsolete)Enable double-click auto pilot</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -5518,13 +5518,13 @@
|
|||
<key>DoubleClickTeleport</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable double-click to teleport where allowed</string>
|
||||
<string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>DoubleClickShowWorldMap</key>
|
||||
<map>
|
||||
|
|
@ -10887,7 +10887,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>PushToTalkButton</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Which button or keyboard key is used for push-to-talk</string>
|
||||
<string>(Obsolete)Which button or keyboard key is used for push-to-talk</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -19663,7 +19663,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>ClickToWalk</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Click in world to walk to location</string>
|
||||
<string>(obsolete)Click in world to walk to location</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -20921,17 +20921,6 @@ 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>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include "lllineeditor.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llviewerinput.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llworld.h"
|
||||
#include "rlvactions.h"
|
||||
|
|
|
|||
|
|
@ -1121,10 +1121,10 @@ void FSPanelLogin::onSelectServer()
|
|||
{
|
||||
std::string location = location_combo->getValue().asString();
|
||||
LLSLURL slurl(location); // generata a slurl from the location combo contents
|
||||
if (location.empty()
|
||||
|| (slurl.getType() == LLSLURL::LOCATION
|
||||
&& slurl.getGrid() != LLGridManager::getInstance()->getGrid())
|
||||
)
|
||||
if (location.empty()
|
||||
|| (slurl.getType() == LLSLURL::LOCATION
|
||||
&& slurl.getGrid() != LLGridManager::getInstance()->getGrid())
|
||||
)
|
||||
{
|
||||
// the grid specified by the location is not this one, so clear the combo
|
||||
location_combo->setCurrentByIndex(0); // last location on the new grid
|
||||
|
|
|
|||
|
|
@ -974,6 +974,17 @@ bool LLAgent::enableFlying()
|
|||
// </FS:Zi>
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAgent::isSitting()
|
||||
{
|
||||
BOOL sitting = FALSE;
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
sitting = gAgentAvatarp->isSitting();
|
||||
}
|
||||
return sitting;
|
||||
}
|
||||
|
||||
void LLAgent::standUp()
|
||||
{
|
||||
// setControlFlags(AGENT_CONTROL_STAND_UP);
|
||||
|
|
|
|||
|
|
@ -358,6 +358,7 @@ public:
|
|||
static void toggleFlying();
|
||||
static bool enableFlying();
|
||||
BOOL canFly(); // Does this parcel allow you to fly?
|
||||
static bool isSitting();
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Voice
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@
|
|||
#include "llapr.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llviewerinput.h"
|
||||
#include "lllfsthread.h"
|
||||
#include "llworkerthread.h"
|
||||
#include "lltexturecache.h"
|
||||
|
|
@ -1190,28 +1190,15 @@ bool LLAppViewer::init()
|
|||
gGLManager.getGLInfo(gDebugInfo);
|
||||
gGLManager.printGLInfoString();
|
||||
|
||||
// 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"))
|
||||
// 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))
|
||||
{
|
||||
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))
|
||||
// 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))
|
||||
{
|
||||
LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
|
||||
LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1709,6 +1696,7 @@ 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");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* @file lldrawfrustum.cpp
|
||||
* @brief Implementation of lldrawfrustum
|
||||
*
|
||||
* $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 "lldrawfrustum.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLDrawFrustum::LLDrawFrustum()
|
||||
: mContextConeOpacity(0.f)
|
||||
{
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); // 0.0f
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); // 1.f
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); // 0.08f
|
||||
}
|
||||
|
||||
LLDrawFrustum::LLDrawFrustum(LLView *origin)
|
||||
: mContextConeOpacity(0.f)
|
||||
{
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
setFrustumOrigin(origin);
|
||||
}
|
||||
|
||||
void LLDrawFrustum::setFrustumOrigin(LLView *origin)
|
||||
{
|
||||
if (origin)
|
||||
{
|
||||
mFrustumOrigin = origin->getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawFrustum::drawFrustum(const LLRect &derived_local_rect, const LLView *root_view, const LLView *drag_handle, bool has_focus)
|
||||
{
|
||||
if (mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, root_view);
|
||||
// draw context cone connecting derived floater (ex: color picker) with view (ex: color swatch) in parent floater
|
||||
if (has_focus && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//{
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mTop);
|
||||
// gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mTop);
|
||||
// gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mBottom);
|
||||
// gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mBottom);
|
||||
// gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
//}
|
||||
//gGL.end();
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(derived_local_rect.mRight, derived_local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(derived_local_rect.mLeft, derived_local_rect.mTop);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(drag_handle))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file lldrawfrustum.h
|
||||
* @brief Header file for lldrawfrustum
|
||||
*
|
||||
* $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_LLDRAWFRUSTUM_H
|
||||
#define LL_LLDRAWFRUSTUM_H
|
||||
|
||||
#include "llview.h"
|
||||
|
||||
class LLDrawFrustum
|
||||
{
|
||||
public:
|
||||
LLDrawFrustum();
|
||||
LLDrawFrustum(LLView *origin);
|
||||
protected:
|
||||
|
||||
// Draw's a cone from origin to derived view or floater
|
||||
// @derived_local_rect derived flaoter's local rect
|
||||
// @droot_view usually it is a derived floater
|
||||
// @drag_handle floater's drag handle getDragHandle()
|
||||
void drawFrustum(const LLRect &derived_local_rect, const LLView *root_view, const LLView *drag_handle, bool has_focus);
|
||||
|
||||
void setFrustumOrigin(LLView *origin);
|
||||
private:
|
||||
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
};
|
||||
|
||||
#endif // LL_LLDRAWFRUSTUM_H
|
||||
|
||||
|
|
@ -92,6 +92,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
|
|||
floater->mNearMeListComplete = FALSE;
|
||||
floater->mCloseOnSelect = closeOnSelect;
|
||||
floater->mExcludeAgentFromSearchResults = skip_agent;
|
||||
floater->setFrustumOrigin(frustumOrigin);
|
||||
|
||||
if (!closeOnSelect)
|
||||
{
|
||||
|
|
@ -102,10 +103,6 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
|
|||
floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
|
||||
}
|
||||
|
||||
if(frustumOrigin)
|
||||
{
|
||||
floater->mFrustumOrigin = frustumOrigin->getHandle();
|
||||
}
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
|
@ -116,17 +113,9 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
|
|||
mNumResultsReturned(0),
|
||||
mNearMeListComplete(FALSE),
|
||||
mCloseOnSelect(FALSE),
|
||||
mContextConeOpacity (0.f),
|
||||
mContextConeInAlpha(0.f),
|
||||
mContextConeOutAlpha(0.f),
|
||||
mContextConeFadeTime(0.f),
|
||||
mFindUUIDAvatarNameCacheConnection() // <FS:Ansariel> Search by UUID
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
|
||||
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
}
|
||||
|
||||
BOOL LLFloaterAvatarPicker::postBuild()
|
||||
|
|
@ -518,92 +507,10 @@ void LLFloaterAvatarPicker::populateFriend()
|
|||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
void LLFloaterAvatarPicker::drawFrustum()
|
||||
{
|
||||
if(mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//{
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
//}
|
||||
//gGL.end();
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
}
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterAvatarPicker::draw()
|
||||
{
|
||||
drawFrustum();
|
||||
LLRect local_rect = getLocalRect();
|
||||
drawFrustum(local_rect, this, getDragHandle(), hasFocus());
|
||||
|
||||
// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
|
||||
// lets check this via mOkButtonValidateSignal callback periodically.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#define LLFLOATERAVATARPICKER_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lldrawfrustum.h"
|
||||
#include "lleventcoro.h"
|
||||
#include "llcoros.h"
|
||||
|
||||
|
|
@ -36,7 +37,7 @@
|
|||
class LLAvatarName;
|
||||
class LLScrollListCtrl;
|
||||
|
||||
class LLFloaterAvatarPicker :public LLFloater
|
||||
class LLFloaterAvatarPicker :public LLFloater, public LLDrawFrustum
|
||||
{
|
||||
public:
|
||||
typedef boost::signals2::signal<bool(const uuid_vec_t&), boost_boolean_combiner> validate_signal_t;
|
||||
|
|
@ -102,7 +103,6 @@ private:
|
|||
void setAllowMultiple(BOOL allow_multiple);
|
||||
LLScrollListCtrl* getActiveList();
|
||||
|
||||
void drawFrustum();
|
||||
virtual void draw();
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
||||
|
|
@ -111,11 +111,6 @@ private:
|
|||
BOOL mNearMeListComplete;
|
||||
BOOL mCloseOnSelect;
|
||||
BOOL mExcludeAgentFromSearchResults;
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
|
||||
validate_signal_t mOkButtonValidateSignal;
|
||||
select_callback_t mSelectionCallback;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
|
||||
LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
|
||||
: LLFloater(LLSD()),
|
||||
LLDrawFrustum(swatch),
|
||||
mComponents ( 3 ),
|
||||
mMouseDownInLumRegion ( FALSE ),
|
||||
mMouseDownInHueRegion ( FALSE ),
|
||||
|
|
@ -103,11 +104,7 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
|
|||
mPaletteRegionHeight ( 40 ),
|
||||
mSwatch ( swatch ),
|
||||
mActive ( TRUE ),
|
||||
mCanApplyImmediately ( show_apply_immediate ),
|
||||
mContextConeOpacity ( 0.f ),
|
||||
mContextConeInAlpha ( 0.f ),
|
||||
mContextConeOutAlpha ( 0.f ),
|
||||
mContextConeFadeTime ( 0.f )
|
||||
mCanApplyImmediately ( show_apply_immediate )
|
||||
{
|
||||
buildFromFile ( "floater_color_picker.xml");
|
||||
|
||||
|
|
@ -119,10 +116,6 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
|
|||
mApplyImmediateCheck->setEnabled(FALSE);
|
||||
mApplyImmediateCheck->set(FALSE);
|
||||
}
|
||||
|
||||
mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
|
||||
mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
|
||||
mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
|
||||
}
|
||||
|
||||
LLFloaterColorPicker::~LLFloaterColorPicker()
|
||||
|
|
@ -498,82 +491,10 @@ BOOL LLFloaterColorPicker::isColorChanged()
|
|||
//
|
||||
void LLFloaterColorPicker::draw()
|
||||
{
|
||||
LLRect swatch_rect;
|
||||
mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//{
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
|
||||
// gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
drawFrustum(local_rect, this, getDragHandle(), hasFocus());
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
|
||||
// gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
|
||||
// gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
|
||||
// gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
|
||||
//}
|
||||
//gGL.end();
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
}
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),
|
||||
LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
|
||||
mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
|
||||
mApplyImmediateCheck->setEnabled(mActive && mCanApplyImmediately);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lldrawfrustum.h"
|
||||
#include "llpointer.h"
|
||||
#include "llcolorswatch.h"
|
||||
#include "llspinctrl.h"
|
||||
|
|
@ -41,7 +42,7 @@ class LLCheckBoxCtrl;
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// floater class
|
||||
class LLFloaterColorPicker
|
||||
: public LLFloater
|
||||
: public LLFloater, public LLDrawFrustum
|
||||
{
|
||||
public:
|
||||
LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate = FALSE);
|
||||
|
|
@ -63,7 +64,7 @@ class LLFloaterColorPicker
|
|||
void destroyUI ();
|
||||
void cancelSelection ();
|
||||
LLColorSwatchCtrl* getSwatch () { return mSwatch; };
|
||||
void setSwatch( LLColorSwatchCtrl* swatch) { mSwatch = swatch; }
|
||||
void setSwatch(LLColorSwatchCtrl* swatch) { mSwatch = swatch; setFrustumOrigin(mSwatch); }
|
||||
|
||||
// mutator / accessor for original RGB value
|
||||
void setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn );
|
||||
|
|
@ -197,12 +198,6 @@ class LLFloaterColorPicker
|
|||
|
||||
LLButton* mPipetteBtn;
|
||||
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
|
||||
|
||||
// <FS:Zi> Add float LSL color entry widgets
|
||||
protected:
|
||||
static void onClickCopyLSL ( void* data );
|
||||
|
|
|
|||
|
|
@ -64,114 +64,22 @@ LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t ca
|
|||
floater->mSearchPanel->filterContent();
|
||||
}
|
||||
|
||||
if(frustumOrigin)
|
||||
{
|
||||
floater->mFrustumOrigin = frustumOrigin->getHandle();
|
||||
}
|
||||
floater->setFrustumOrigin(frustumOrigin);
|
||||
|
||||
return floater;
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::drawFrustum()
|
||||
{
|
||||
if(mFrustumOrigin.get())
|
||||
{
|
||||
LLView * frustumOrigin = mFrustumOrigin.get();
|
||||
LLRect origin_rect;
|
||||
frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
|
||||
// draw context cone connecting color picker with color swatch in parent floater
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//{
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
// gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
// gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
//}
|
||||
//gGL.end();
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
}
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExperiencePicker::draw()
|
||||
{
|
||||
drawFrustum();
|
||||
LLRect local_rect = getLocalRect();
|
||||
drawFrustum(local_rect, this, getDragHandle(), hasFocus());
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::LLFloaterExperiencePicker( const LLSD& key )
|
||||
:LLFloater(key)
|
||||
,mSearchPanel(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");
|
||||
}
|
||||
|
||||
LLFloaterExperiencePicker::~LLFloaterExperiencePicker()
|
||||
|
|
|
|||
|
|
@ -28,13 +28,14 @@
|
|||
#define LL_LLFLOATEREXPERIENCEPICKER_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lldrawfrustum.h"
|
||||
|
||||
class LLScrollListCtrl;
|
||||
class LLLineEditor;
|
||||
class LLPanelExperiencePicker;
|
||||
|
||||
|
||||
class LLFloaterExperiencePicker : public LLFloater
|
||||
class LLFloaterExperiencePicker : public LLFloater, public LLDrawFrustum
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -54,13 +55,6 @@ public:
|
|||
private:
|
||||
|
||||
LLPanelExperiencePicker* mSearchPanel;
|
||||
|
||||
void drawFrustum();
|
||||
LLHandle <LLView> mFrustumOrigin;
|
||||
F32 mContextConeOpacity;
|
||||
F32 mContextConeInAlpha;
|
||||
F32 mContextConeOutAlpha;
|
||||
F32 mContextConeFadeTime;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATEREXPERIENCEPICKER_H
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@
|
|||
#include "lltrans.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewerthrottle.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
|
@ -210,87 +211,6 @@ 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
|
||||
|
||||
|
|
@ -472,37 +392,6 @@ 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;
|
||||
|
|
@ -527,8 +416,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
mGotPersonalInfo(false),
|
||||
mOriginalIMViaEmail(false),
|
||||
mLanguageChanged(false),
|
||||
mAvatarDataInitialized(false),
|
||||
mClickActionDirty(false)
|
||||
mAvatarDataInitialized(false)
|
||||
{
|
||||
LLConversationLog::instance().addObserver(this);
|
||||
|
||||
|
|
@ -537,7 +425,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
static bool registered_dialog = false;
|
||||
if (!registered_dialog)
|
||||
{
|
||||
LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
|
||||
LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSetKeyBindDialog>);
|
||||
registered_dialog = true;
|
||||
}
|
||||
|
||||
|
|
@ -556,9 +444,7 @@ 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));
|
||||
|
|
@ -591,8 +477,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
|
||||
sSkin = gSavedSettings.getString("SkinCurrent");
|
||||
|
||||
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));
|
||||
|
|
@ -1080,12 +964,6 @@ 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"));
|
||||
}
|
||||
|
|
@ -1120,12 +998,6 @@ 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)
|
||||
{
|
||||
|
|
@ -1233,9 +1105,6 @@ 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();
|
||||
|
|
@ -2852,15 +2721,6 @@ 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()
|
||||
{
|
||||
|
|
@ -2868,60 +2728,6 @@ void LLFloaterPreference::onClickClearKey()
|
|||
}
|
||||
// </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);
|
||||
LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
|
||||
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()
|
||||
|
|
@ -2941,18 +2747,6 @@ 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");
|
||||
|
|
@ -3557,11 +3351,6 @@ void LLFloaterPreference::onClickAdvanced()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onClickActionChange()
|
||||
{
|
||||
mClickActionDirty = true;
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onClickPermsDefault()
|
||||
{
|
||||
LLFloaterReg::showInstance("perms_default");
|
||||
|
|
@ -3599,26 +3388,6 @@ 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()
|
||||
{
|
||||
|
|
@ -3907,24 +3676,6 @@ 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"))
|
||||
{
|
||||
|
|
@ -4444,7 +4195,7 @@ void LLPanelPreferenceGraphics::setPresetText()
|
|||
// </FS:Ansariel>
|
||||
|
||||
// <FS:Ansariel> Graphic preset controls independent from XUI
|
||||
//if (hasDirtyChilds() && !preset_graphic_active.empty())
|
||||
//if (hasDirtyChilds() && !preset_graphic_active.empty())
|
||||
//{
|
||||
// gSavedSettings.setString("PresetGraphicActive", "");
|
||||
// preset_graphic_active.clear();
|
||||
|
|
@ -4570,6 +4321,368 @@ 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;
|
||||
}
|
||||
|
||||
std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename);
|
||||
LLSimpleXUIParser parser;
|
||||
LLScrollListCtrl::Contents contents;
|
||||
if (!parser.readXUI(full_filename, contents)
|
||||
|| !contents.validateBlock())
|
||||
{
|
||||
LL_INFOS() << "Failed to load" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = contents.columns.begin();
|
||||
row_it != contents.columns.end();
|
||||
++row_it)
|
||||
{
|
||||
pControlsTable->addColumn(*row_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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llconversationlog.h"
|
||||
#include "llsearcheditor.h"
|
||||
#include "llsetkeybinddialog.h"
|
||||
#include "llkeyconflict.h"
|
||||
|
||||
#include "llaudioengine.h" // <FS:Ansariel> Output device selection
|
||||
|
||||
|
|
@ -45,7 +47,9 @@ class LLPanelPreference;
|
|||
class LLPanelLCD;
|
||||
class LLPanelDebug;
|
||||
class LLMessageSystem;
|
||||
class LLComboBox;
|
||||
class LLScrollListCtrl;
|
||||
class LLScrollListCell;
|
||||
class LLSliderCtrl;
|
||||
class LLSD;
|
||||
class LLTextBox;
|
||||
|
|
@ -144,12 +148,6 @@ 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();
|
||||
|
||||
|
|
@ -166,7 +164,6 @@ 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.
|
||||
|
|
@ -195,11 +192,7 @@ 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();
|
||||
|
|
@ -286,7 +279,6 @@ 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;
|
||||
|
|
@ -396,6 +388,44 @@ 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:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,868 @@
|
|||
/**
|
||||
* @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 "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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
EMouseClickType mouse_from_string(const std::string& input)
|
||||
{
|
||||
if (input == "LMB")
|
||||
{
|
||||
return CLICK_LEFT;
|
||||
}
|
||||
if (input == "MMB")
|
||||
{
|
||||
return CLICK_MIDDLE;
|
||||
}
|
||||
if (input == "RMB")
|
||||
{
|
||||
return CLICK_RIGHT;
|
||||
}
|
||||
if (input == "MB4")
|
||||
{
|
||||
return CLICK_BUTTON4;
|
||||
}
|
||||
if (input == "MB5")
|
||||
{
|
||||
return CLICK_BUTTON5;
|
||||
}
|
||||
return CLICK_NONE;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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 = it->mouse.isProvided() ? mouse_from_string(it->mouse) : CLICK_NONE;
|
||||
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
|
||||
{
|
||||
// Note: this is UI string, we might want to hardcode our own for 'fixed' use in keys.xml
|
||||
binding.key = LLKeyboard::stringFromKey(data.mKey);
|
||||
}
|
||||
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), 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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* @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);
|
||||
|
||||
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
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
|
||||
#include "llbutton.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,333 @@
|
|||
/**
|
||||
* @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"
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSetKeyBindDialog::draw()
|
||||
{
|
||||
LLRect local_rect;
|
||||
drawFrustum(local_rect, this, (LLView*)getDragHandle(), hasFocus());
|
||||
LLModalDialog::draw();
|
||||
}
|
||||
|
||||
void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask)
|
||||
{
|
||||
pParent = parent;
|
||||
setFrustumOrigin(frustum_origin);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* @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"
|
||||
#include "lldrawfrustum.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 LLDrawFrustum
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_LLSETKEYBINDDIALOG_H
|
||||
|
|
@ -1007,7 +1007,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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@
|
|||
//#include "llfirstuse.h"
|
||||
#include "llfloaterhud.h"
|
||||
#include "llfloaterland.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloatertopobjects.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llgesturemgr.h"
|
||||
|
|
|
|||
|
|
@ -75,10 +75,6 @@
|
|||
|
||||
#include "fscommon.h"
|
||||
|
||||
static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
|
||||
static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
|
||||
static const F32 CONTEXT_FADE_TIME = 0.08f;
|
||||
|
||||
static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
|
||||
|
||||
//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
|
||||
|
|
@ -116,7 +112,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
|
|||
mImmediateFilterPermMask(immediate_filter_perm_mask),
|
||||
mDnDFilterPermMask(dnd_filter_perm_mask),
|
||||
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
|
||||
mContextConeOpacity(0.f),
|
||||
mSelectedItemPinned( FALSE ),
|
||||
mCanApply(true),
|
||||
mCanPreview(true),
|
||||
|
|
@ -131,6 +126,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
|
|||
buildFromFile("floater_texture_ctrl.xml");
|
||||
mCanApplyImmediately = can_apply_immediately;
|
||||
setCanMinimize(FALSE);
|
||||
setFrustumOrigin(mOwner);
|
||||
|
||||
// <FS:Ansariel> Threaded filepickers
|
||||
mLocalBitmapsAddedCallbackConnection = LLLocalBitmapMgr::setBitmapsAddedCallback(boost::bind(&LLFloaterTexturePicker::onLocalBitmapsAddedCallback, this));
|
||||
|
|
@ -498,85 +494,9 @@ BOOL LLFloaterTexturePicker::postBuild()
|
|||
// virtual
|
||||
void LLFloaterTexturePicker::draw()
|
||||
{
|
||||
if (mOwner)
|
||||
{
|
||||
// draw cone of context pointing back to texture swatch
|
||||
LLRect owner_rect;
|
||||
mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect, this);
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLGLEnable(GL_CULL_FACE);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(LLRender::QUADS);
|
||||
//{
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
|
||||
// gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
|
||||
// gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
|
||||
// gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
|
||||
|
||||
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
// gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
// gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
// gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
|
||||
// gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
|
||||
//}
|
||||
//gGL.end();
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
{
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
|
||||
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
|
||||
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
|
||||
}
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
|
||||
}
|
||||
else
|
||||
{
|
||||
mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
|
||||
}
|
||||
// draw cone of context pointing back to texture swatch
|
||||
LLRect local_rect = getLocalRect();
|
||||
drawFrustum(local_rect, this, getDragHandle(), hasFocus());
|
||||
|
||||
updateImageStats();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#define LL_LLTEXTURECTRL_H
|
||||
|
||||
#include "llcoord.h"
|
||||
#include "lldrawfrustum.h"
|
||||
#include "llfiltereditor.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfolderview.h"
|
||||
|
|
@ -258,7 +259,7 @@ typedef boost::function<void()> floater_close_callback;
|
|||
typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
|
||||
typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback;
|
||||
|
||||
class LLFloaterTexturePicker : public LLFloater
|
||||
class LLFloaterTexturePicker : public LLFloater, public LLDrawFrustum
|
||||
{
|
||||
public:
|
||||
LLFloaterTexturePicker(
|
||||
|
|
@ -302,7 +303,7 @@ public:
|
|||
void setActive(BOOL active);
|
||||
|
||||
LLView* getOwner() const { return mOwner; }
|
||||
void setOwner(LLView* owner) { mOwner = owner; }
|
||||
void setOwner(LLView* owner) { mOwner = owner; setFrustumOrigin(owner); }
|
||||
void stopUsingPipette();
|
||||
PermissionMask getFilterPermMask();
|
||||
|
||||
|
|
@ -380,7 +381,6 @@ protected:
|
|||
PermissionMask mNonImmediateFilterPermMask;
|
||||
BOOL mCanApplyImmediately;
|
||||
BOOL mNoCopyTextureSelected;
|
||||
F32 mContextConeOpacity;
|
||||
LLSaveFolderState mSavedFolderState;
|
||||
BOOL mSelectedItemPinned;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ LLTool::~LLTool()
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
|
||||
BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType 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;
|
||||
gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, LLMouseHandler::EClickType clicktype, BOOL down);
|
||||
virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType 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);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "llagentcamera.h"
|
||||
#include "llbutton.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerkeyboard.h"//<FS:JL> Mouse movement by Singularity
|
||||
#include "llviewerinput.h"//<FS:JL> Mouse movement by Singularity
|
||||
#include "lldrawable.h"
|
||||
#include "lltooltip.h"
|
||||
#include "llhudmanager.h"
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ LLToolPie::LLToolPie()
|
|||
mMouseOutsideSlop( false ),
|
||||
mMouseSteerX(-1),
|
||||
mMouseSteerY(-1),
|
||||
mBlockClickToWalk(false),
|
||||
mClickAction(0),
|
||||
mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
|
||||
mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ),
|
||||
|
|
@ -100,7 +99,7 @@ LLToolPie::LLToolPie()
|
|||
{
|
||||
}
|
||||
|
||||
BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
|
||||
BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
|
||||
{
|
||||
BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
|
||||
|
||||
|
|
@ -187,10 +186,8 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
mPick.mKeyMask = mask;
|
||||
|
||||
mMouseButtonDown = true;
|
||||
|
||||
handleLeftClickPick();
|
||||
|
||||
return TRUE;
|
||||
return handleLeftClickPick();
|
||||
}
|
||||
|
||||
// Spawn context menus on right mouse down so you can drag over and select
|
||||
|
|
@ -400,8 +397,6 @@ 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);
|
||||
}
|
||||
|
||||
|
|
@ -457,10 +452,7 @@ 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;
|
||||
|
|
@ -478,7 +470,6 @@ BOOL LLToolPie::handleLeftClickPick()
|
|||
// LLFirstUse::useLeftClickNoHit();
|
||||
/////////
|
||||
|
||||
// Eat the event
|
||||
return LLTool::handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
||||
|
|
@ -590,17 +581,112 @@ void LLToolPie::resetSelection()
|
|||
mClickAction = 0;
|
||||
}
|
||||
|
||||
void LLToolPie::walkToClickedLocation()
|
||||
bool LLToolPie::walkToClickedLocation()
|
||||
{
|
||||
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);
|
||||
if (gAgent.getFlying() // don't auto-navigate while flying until that works
|
||||
|| !gAgentAvatarp
|
||||
|| gAgentAvatarp->isSitting())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
|
||||
gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE);
|
||||
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;
|
||||
}
|
||||
|
||||
gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
|
||||
|
||||
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]
|
||||
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;
|
||||
}
|
||||
|
||||
// When we get object properties after left-clicking on an object
|
||||
|
|
@ -684,8 +770,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
|
|||
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
|
||||
}
|
||||
else if (!mMouseOutsideSlop
|
||||
&& mMouseButtonDown
|
||||
&& gSavedSettings.getBOOL("ClickToWalk"))
|
||||
&& mMouseButtonDown)
|
||||
{
|
||||
S32 delta_x = x - mMouseDownX;
|
||||
S32 delta_y = y - mMouseDownY;
|
||||
|
|
@ -783,84 +868,10 @@ 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())
|
||||
{
|
||||
|
|
@ -870,7 +881,6 @@ 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);
|
||||
}
|
||||
|
||||
|
|
@ -896,78 +906,13 @@ 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;
|
||||
}
|
||||
|
||||
|
|
@ -1725,7 +1670,6 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info)
|
|||
void LLToolPie::handleSelect()
|
||||
{
|
||||
// tool is reselected when app gets focus, etc.
|
||||
mBlockClickToWalk = true;
|
||||
}
|
||||
|
||||
void LLToolPie::handleDeselect()
|
||||
|
|
@ -1790,7 +1734,7 @@ void LLToolPie::stopCameraSteering()
|
|||
|
||||
bool LLToolPie::inCameraSteerMode()
|
||||
{
|
||||
return mMouseButtonDown && mMouseOutsideSlop && gSavedSettings.getBOOL("ClickToWalk");
|
||||
return mMouseButtonDown && mMouseOutsideSlop;
|
||||
}
|
||||
|
||||
// true if x,y outside small box around start_x,start_y
|
||||
|
|
@ -2374,7 +2318,6 @@ void LLToolPie::startCameraSteering()
|
|||
{
|
||||
LLFirstUse::notMoving(false);
|
||||
mMouseOutsideSlop = true;
|
||||
mBlockClickToWalk = true;
|
||||
|
||||
if (gAgentCamera.getFocusOnAvatar())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
|
|||
public:
|
||||
|
||||
// Virtual functions inherited from LLMouseHandler
|
||||
virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
|
||||
virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType 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);
|
||||
|
|
@ -70,8 +70,8 @@ public:
|
|||
LLViewerObject* getClickActionObject() { return mClickActionObject; }
|
||||
LLObjectSelection* getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; }
|
||||
void resetSelection();
|
||||
void walkToClickedLocation();
|
||||
void blockClickToWalk() { mBlockClickToWalk = true; }
|
||||
bool walkToClickedLocation();
|
||||
bool teleportToClickedLocation();
|
||||
void stopClickToWalk();
|
||||
|
||||
static void selectionPropertiesReceived();
|
||||
|
|
@ -120,7 +120,6 @@ private:
|
|||
LLPointer<LLHUDEffectBlob> mAutoPilotDestination;
|
||||
LLPointer<LLHUDEffectBlob> mMouseSteerGrabPoint;
|
||||
bool mClockwise;
|
||||
bool mBlockClickToWalk;
|
||||
LLUUID mMediaMouseCaptureID;
|
||||
LLPickInfo mPick;
|
||||
LLPickInfo mHoverPick;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@
|
|||
#include "llnotificationsutil.h"
|
||||
#include "llpanelplaces.h"
|
||||
#include "llstatusbar.h"
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llviewerinput.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "NACLantispam.h"
|
||||
|
|
@ -813,23 +813,6 @@ 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)
|
||||
{
|
||||
|
|
@ -1174,8 +1157,6 @@ 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));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* @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;
|
||||
|
||||
BOOL modeFromString(const std::string& string, S32 *mode) const; // False on failure
|
||||
BOOL mouseFromString(const std::string& string, EMouseClickType *mode) const;// 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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
* @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
|
||||
|
|
@ -10132,7 +10132,6 @@ BOOL LLViewerMenuHolderGL::hideMenus()
|
|||
|
||||
if (LLMenuHolderGL::hideMenus())
|
||||
{
|
||||
LLToolPie::instance().blockClickToWalk();
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@
|
|||
#include "llmeshrepository.h"
|
||||
#include "llnotificationhandler.h"
|
||||
#include "llpanellogin.h"
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llsetkeybinddialog.h"
|
||||
#include "llviewerinput.h"
|
||||
#include "llviewermenu.h"
|
||||
//<FS:Beq> physics display changes
|
||||
#include "llspatialpartition.h"
|
||||
|
|
@ -180,7 +181,7 @@
|
|||
#include "llviewergesture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llviewerinput.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "llviewermediafocus.h"
|
||||
#include "llviewermenu.h"
|
||||
|
|
@ -971,7 +972,18 @@ LLViewerWindow::Params::Params()
|
|||
{}
|
||||
|
||||
|
||||
BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
|
||||
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)
|
||||
{
|
||||
const char* buttonname = "";
|
||||
const char* buttonstatestr = "";
|
||||
|
|
@ -995,28 +1007,30 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
|
|||
|
||||
switch (clicktype)
|
||||
{
|
||||
case LLMouseHandler::CLICK_LEFT:
|
||||
case CLICK_LEFT:
|
||||
mLeftMouseDown = down;
|
||||
buttonname = "Left";
|
||||
break;
|
||||
case LLMouseHandler::CLICK_RIGHT:
|
||||
case CLICK_RIGHT:
|
||||
mRightMouseDown = down;
|
||||
buttonname = "Right";
|
||||
break;
|
||||
case LLMouseHandler::CLICK_MIDDLE:
|
||||
case CLICK_MIDDLE:
|
||||
mMiddleMouseDown = down;
|
||||
buttonname = "Middle";
|
||||
break;
|
||||
case LLMouseHandler::CLICK_DOUBLELEFT:
|
||||
case CLICK_DOUBLELEFT:
|
||||
mLeftMouseDown = down;
|
||||
buttonname = "Left Double Click";
|
||||
break;
|
||||
case LLMouseHandler::CLICK_BUTTON4:
|
||||
case CLICK_BUTTON4:
|
||||
buttonname = "Button 4";
|
||||
break;
|
||||
case LLMouseHandler::CLICK_BUTTON5:
|
||||
case CLICK_BUTTON5:
|
||||
buttonname = "Button 5";
|
||||
break;
|
||||
default:
|
||||
break; // COUNT and NONE
|
||||
}
|
||||
|
||||
LLView::sMouseHandlerMessage.clear();
|
||||
|
|
@ -1067,6 +1081,11 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
|
|||
LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
|
||||
|
||||
}
|
||||
else if (down && clicktype == CLICK_RIGHT)
|
||||
{
|
||||
handlePieMenu(x, y, mask);
|
||||
r = TRUE;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -1113,7 +1132,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
|
|||
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;
|
||||
|
|
@ -1132,7 +1156,8 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
|
|||
mMouseDownTimer.reset();
|
||||
}
|
||||
BOOL down = TRUE;
|
||||
return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
|
||||
//handleMouse() loops back to LLViewerWindow::handleAnyMouseClick
|
||||
return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
|
||||
}
|
||||
|
||||
BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
|
||||
|
|
@ -1140,8 +1165,7 @@ 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 (handleAnyMouseClick(window, pos, mask,
|
||||
LLMouseHandler::CLICK_DOUBLELEFT, down))
|
||||
if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1155,47 +1179,24 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
|
|||
mMouseDownTimer.stop();
|
||||
}
|
||||
BOOL down = FALSE;
|
||||
return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
|
||||
return gViewerInput.handleMouse(window, pos, mask, 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;
|
||||
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;
|
||||
return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
|
||||
}
|
||||
|
||||
BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
|
||||
{
|
||||
BOOL down = FALSE;
|
||||
return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
|
||||
return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
|
||||
}
|
||||
|
||||
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
|
||||
{
|
||||
BOOL down = TRUE;
|
||||
LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true);
|
||||
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
|
||||
gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
|
||||
|
||||
// Always handled as far as the OS is concerned.
|
||||
return TRUE;
|
||||
|
|
@ -1350,8 +1351,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
|
|||
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
|
||||
{
|
||||
BOOL down = FALSE;
|
||||
LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false);
|
||||
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
|
||||
gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
|
||||
|
||||
// Always handled as far as the OS is concerned.
|
||||
return TRUE;
|
||||
|
|
@ -1362,12 +1362,10 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask
|
|||
switch (button)
|
||||
{
|
||||
case 4:
|
||||
LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down);
|
||||
handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down);
|
||||
gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON4, down);
|
||||
break;
|
||||
case 5:
|
||||
LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down);
|
||||
handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down);
|
||||
gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON5, down);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1513,9 +1511,6 @@ 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();
|
||||
|
|
@ -1534,14 +1529,12 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return gViewerKeyboard.handleKey(key, mask, repeated);
|
||||
// remaps, handles ignored cases and returns back to viewer window.
|
||||
return gViewerInput.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)
|
||||
|
|
@ -1549,13 +1542,13 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
|
|||
tool_inspectp->keyUp(key, mask);
|
||||
}
|
||||
|
||||
return gViewerKeyboard.handleKeyUp(key, mask);
|
||||
return gViewerInput.handleKeyUp(key, mask);
|
||||
}
|
||||
|
||||
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
|
||||
{
|
||||
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
|
||||
gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
|
||||
gViewerInput.scanKey(key, key_down, key_up, key_level);
|
||||
return; // Be clear this function returns nothing
|
||||
}
|
||||
|
||||
|
|
@ -3108,6 +3101,14 @@ 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
|
||||
|
|
@ -3380,7 +3381,8 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
|
|||
{
|
||||
if (mask != MASK_ALT)
|
||||
{
|
||||
return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
|
||||
// remaps, handles ignored cases and returns back to viewer window.
|
||||
return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,8 +176,9 @@ public:
|
|||
void initWorldUI();
|
||||
void setUIVisibility(bool);
|
||||
bool getUIVisibility();
|
||||
void handlePieMenu(S32 x, S32 y, MASK mask);
|
||||
|
||||
BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
|
||||
BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
|
||||
|
||||
//
|
||||
// LLWindowCallback interface implementation
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ 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");
|
||||
|
||||
|
|
@ -659,32 +657,6 @@ 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)
|
||||
|
|
@ -705,43 +677,6 @@ 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
|
||||
|
|
|
|||
|
|
@ -438,16 +438,10 @@ 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); }
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "llview.h"
|
||||
#include "llviewinject.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerkeyboard.h"
|
||||
#include "llviewerinput.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);
|
||||
gViewerKeyboard.handleKey(key, mask, false);
|
||||
gViewerInput.handleKey(key, mask, false);
|
||||
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
|
||||
}
|
||||
else
|
||||
|
|
@ -291,7 +291,7 @@ void LLWindowListener::keyDown(LLSD const & evt)
|
|||
}
|
||||
else
|
||||
{
|
||||
gViewerKeyboard.handleKey(key, mask, false);
|
||||
gViewerInput.handleKey(key, mask, false);
|
||||
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
<panel label="Bewegung" name="tab-movement">
|
||||
<check_box label="Mit Pfeiltasten bewegen" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Buchstabeneingabe beeinflusst Bewegung (z.B. WASD)" name="LetterKeysAffectsMovementNotFocusChatBar"/>
|
||||
<check_box label="AZERTY-Tastaturlayout verwenden" name="FSUseAzertyKeyboardLayout"/>
|
||||
<check_box label="Drücken-drücken-halten, um zu rennen" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Fliegen/Landen beim Drücken von auf (springen) / ab (kriechen)" name="automatic_fly" />
|
||||
<check_box label="Kriech-Umschaltmodus aktivieren" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,569 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<contents>
|
||||
<columns
|
||||
relative_width="0.34"
|
||||
label="Action"
|
||||
name="lst_action" />
|
||||
<columns
|
||||
relative_width="0.22"
|
||||
label="Primary Control"
|
||||
name="lst_ctrl1" />
|
||||
<columns
|
||||
relative_width="0.22"
|
||||
label="Alternate 1"
|
||||
name="lst_ctrl2" />
|
||||
<columns
|
||||
relative_width="0.22"
|
||||
label="Alternate 2"
|
||||
name="lst_ctrl3" />
|
||||
<rows
|
||||
enabled="false"
|
||||
value="">
|
||||
<columns
|
||||
type="icontext"
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
label="Move Actions"
|
||||
name="lst_action"
|
||||
value="Move_Walk_Off" />
|
||||
</rows>
|
||||
<rows
|
||||
value="walk_to">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Walk to location mouse cursor points to"
|
||||
value="Walk to" />
|
||||
</rows>
|
||||
<rows
|
||||
value="teleport_to">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Teleport to location mouse cursor points to, but not all locations allow direct teleportation so you might be teleported closer to destination instead"
|
||||
value="Teleport to" />
|
||||
</rows>
|
||||
<rows
|
||||
value="push_forward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Move Forward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="push_backward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Move Backward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="turn_left">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Left" />
|
||||
</rows>
|
||||
<rows
|
||||
value="turn_right">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Right" />
|
||||
</rows>
|
||||
<rows
|
||||
value="slide_left">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Strafe left" />
|
||||
</rows>
|
||||
<rows
|
||||
value="slide_right">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Strafe right" />
|
||||
</rows>
|
||||
<rows
|
||||
value="jump">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Jump/Up" />
|
||||
</rows>
|
||||
<rows
|
||||
value="push_down">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Down" />
|
||||
</rows>
|
||||
<rows
|
||||
value="run_forward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Run Forward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="run_backward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Run Backward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="run_left">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Run Left" />
|
||||
</rows>
|
||||
<rows
|
||||
value="run_right">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Run Right" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_run">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Toggle Run" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_fly">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Fly/Stop flying" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_sit">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Sit/Stand" />
|
||||
</rows>
|
||||
<rows
|
||||
value="stop_moving">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Stop Moving" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false">
|
||||
<columns
|
||||
type="icon"
|
||||
color="0 0 0 0.7"
|
||||
halign="center"
|
||||
value="menu_separator" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false"
|
||||
value="">
|
||||
<columns
|
||||
type="icontext"
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
label="Camera"
|
||||
name="lst_action"
|
||||
value="Cam_FreeCam_Off" />
|
||||
</rows>
|
||||
<rows
|
||||
value="look_up">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Look Up" />
|
||||
</rows>
|
||||
<rows
|
||||
value="look_down">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Look Down" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_forward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Forward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_backward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Backward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_forward_fast">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Forward Fast" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_backward_fast">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Backward Fast" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_forward_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Forward Sitting" />
|
||||
</rows>
|
||||
<rows
|
||||
value="move_backward_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Backward Sitting" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_over">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Spin Over" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_under">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Spin Under" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_over_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Spin Over" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_under_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Spin Under" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_up">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan Up" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_down">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan Down" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_left">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan Left" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_right">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan Right" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_in">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan In" />
|
||||
</rows>
|
||||
<rows
|
||||
value="pan_out">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Pan Out" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_around_ccw">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around counterclockwise"
|
||||
value="Counterclockwise" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_around_cw">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around clockwise"
|
||||
value="Clockwise" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_around_ccw_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around counterclockwise sitting"
|
||||
value="Counterclockwise Sitting" />
|
||||
</rows>
|
||||
<rows
|
||||
value="spin_around_cw_sitting">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around clockwise sitting"
|
||||
value="Clockwise Sitting" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false">
|
||||
<columns
|
||||
type="icon"
|
||||
color="0 0 0 0.7"
|
||||
halign="center"
|
||||
value="menu_separator" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false"
|
||||
value="">
|
||||
<columns
|
||||
type="icontext"
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
label="Editing"
|
||||
name="lst_action"
|
||||
value="Tool_Dozer" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_spin_ccw">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around avatar counterclockwise"
|
||||
value="Counterclockwise" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_spin_cw">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin around avatar clockwise"
|
||||
value="Clockwise" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_spin_over">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin over avatar"
|
||||
value="Camera Spin Over" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_spin_under">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
tool_tip="Camera spin under avatar"
|
||||
value="Camera Spin Under" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_move_forward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Forward" />
|
||||
</rows>
|
||||
<rows
|
||||
value="edit_avatar_move_backward">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Camera Backward" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false">
|
||||
<columns
|
||||
type="icon"
|
||||
color="0 0 0 0.7"
|
||||
halign="center"
|
||||
value="menu_separator" />
|
||||
</rows>
|
||||
<rows
|
||||
enabled="false"
|
||||
value="">
|
||||
<columns
|
||||
type="icontext"
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
label="Sound and Media"
|
||||
name="lst_action"
|
||||
value="Audio_Press" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_pause_media">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Play/Pause Media" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_enable_media">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Play/Stop All Media" />
|
||||
</rows>
|
||||
<rows
|
||||
value="voice_follow_key">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Voice" />
|
||||
</rows>
|
||||
<rows
|
||||
value="toggle_voice">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Toggle Voice" />
|
||||
</rows>
|
||||
<rows
|
||||
value="start_chat">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Start Chat" />
|
||||
</rows>
|
||||
<rows
|
||||
value="start_gesture">
|
||||
<columns
|
||||
column="lst_action"
|
||||
font="SansSerif"
|
||||
halign="left"
|
||||
name="lst_action"
|
||||
value="Start Gesture" />
|
||||
</rows>
|
||||
</contents>
|
||||
|
|
@ -146,6 +146,13 @@ https://accounts.secondlife.com/change_email/
|
|||
layout="topleft"
|
||||
help_topic="preferences_move_tab"
|
||||
name="move" />
|
||||
<panel
|
||||
class="panel_preference_controls"
|
||||
filename="panel_preferences_controls.xml"
|
||||
label="Controls"
|
||||
layout="topleft"
|
||||
help_topic="preferences_controls_tab"
|
||||
name="controls" />
|
||||
<panel
|
||||
class="panel_preference"
|
||||
filename="panel_preferences_alerts.xml"
|
||||
|
|
|
|||
|
|
@ -6,10 +6,27 @@
|
|||
border="false"
|
||||
can_close="false"
|
||||
can_minimize="false"
|
||||
height="90"
|
||||
height="116"
|
||||
layout="topleft"
|
||||
name="modal container"
|
||||
width="240">
|
||||
width="272">
|
||||
<floater.string
|
||||
name="keyboard">
|
||||
Keyboard
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="mouse">
|
||||
Mouse Buttons
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="basic_description">
|
||||
Press a key to set your trigger.
|
||||
Allowed input: [INPUT].
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="reserved_by_menu">
|
||||
Combination [KEYSTR] is reserved by menu.
|
||||
</floater.string>
|
||||
<text
|
||||
type="string"
|
||||
halign="center"
|
||||
|
|
@ -18,19 +35,47 @@
|
|||
height="30"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Save item as:"
|
||||
name="descritption"
|
||||
top="25"
|
||||
word_wrap="true"
|
||||
width="220">
|
||||
Press a key to set your Speak button trigger.
|
||||
width="212">
|
||||
Press a key to set your trigger.
|
||||
Allowed input: [INPUT].
|
||||
</text>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
height="20"
|
||||
initial_value="false"
|
||||
label="Apply to all"
|
||||
layout="topleft"
|
||||
left="90"
|
||||
name="apply_all"
|
||||
tool_tip="Viewer uses different control combinations depending on what you are doing in world, setting this will apply your change to all combinations"
|
||||
top_pad="8"
|
||||
width="160" />
|
||||
|
||||
<button
|
||||
height="23"
|
||||
label="Set Empty"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
name="SetEmpty"
|
||||
top_pad="6"
|
||||
width="80" />
|
||||
<button
|
||||
height="23"
|
||||
label="Default"
|
||||
layout="topleft"
|
||||
left_pad="8"
|
||||
name="Default"
|
||||
top_delta="0"
|
||||
width="80" />
|
||||
<button
|
||||
height="23"
|
||||
label="Cancel"
|
||||
label_selected="Cancel"
|
||||
layout="topleft"
|
||||
right="-10"
|
||||
left_pad="8"
|
||||
name="Cancel"
|
||||
top_pad="8"
|
||||
width="100" />
|
||||
top_delta="0"
|
||||
width="80" />
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -12513,6 +12513,19 @@ Changes won't take effect until after you restart [APP_NAME].
|
|||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PreferenceControlsDefaults"
|
||||
type="alertmodal">
|
||||
Do you want to restore default values for controls?
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
canceltext="Cancel"
|
||||
name="yesnocancelbuttons"
|
||||
notext="Current mode"
|
||||
yestext="All modes"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<panel
|
||||
border="true"
|
||||
follows="all"
|
||||
height="408"
|
||||
label="Controls"
|
||||
layout="topleft"
|
||||
left="102"
|
||||
name="controls"
|
||||
top="1"
|
||||
width="517">
|
||||
<combo_box
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
top="6"
|
||||
left="10"
|
||||
height="23"
|
||||
width="140"
|
||||
name="key_mode">
|
||||
<combo_box.item
|
||||
label="Third Person "
|
||||
name="third_person"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="First Person (Mouselook)"
|
||||
name="first_person"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Edit Avatar"
|
||||
name="edit_avatar"
|
||||
value="2"/>
|
||||
<combo_box.item
|
||||
label="Sitting"
|
||||
name="sitting"
|
||||
value="3"/>
|
||||
</combo_box>
|
||||
|
||||
<button
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
top="6"
|
||||
right="-10"
|
||||
height="23"
|
||||
width="140"
|
||||
label="Restore Defaults"
|
||||
tooltip="Restores default values for all control modes."
|
||||
name="restore_defaults"/>
|
||||
|
||||
<scroll_list
|
||||
draw_heading="true"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
column_padding="0"
|
||||
selection_type="header"
|
||||
top="31"
|
||||
left="3"
|
||||
bottom="-3"
|
||||
right="-3"
|
||||
can_sort="false"
|
||||
multi_select="false"
|
||||
name="controls_list"
|
||||
fg_disable_color="ScrollUnselectedColor"/>
|
||||
</panel>
|
||||
|
|
@ -499,16 +499,6 @@
|
|||
name="LetterKeysAffectsMovementNotFocusChatBar"
|
||||
width="180"
|
||||
top_pad="0"/>
|
||||
<check_box
|
||||
control_name="FSUseAzertyKeyboardLayout"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Use AZERTY keyboard layout"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="FSUseAzertyKeyboardLayout"
|
||||
width="400"
|
||||
top_pad="0"/>
|
||||
<check_box
|
||||
control_name="AllowTapTapHoldRun"
|
||||
follows="left|top"
|
||||
|
|
@ -640,70 +630,6 @@
|
|||
width="237"
|
||||
top_pad="0"/>
|
||||
|
||||
<text
|
||||
follows="left|top"
|
||||
type="string"
|
||||
length="1"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="single_click_action_lbl"
|
||||
width="150"
|
||||
top_pad="20">
|
||||
Single click on land:
|
||||
</text>
|
||||
<combo_box
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
top_delta="-6"
|
||||
name="single_click_action_combo"
|
||||
width="200">
|
||||
<combo_box.item
|
||||
label="No action"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Move to clicked point"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.commit_callback
|
||||
function="Pref.ClickActionChange"/>
|
||||
</combo_box>
|
||||
<text
|
||||
follows="left|top"
|
||||
type="string"
|
||||
length="1"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="double_click_action_lbl"
|
||||
width="150"
|
||||
top_pad="10">
|
||||
Double click on land:
|
||||
</text>
|
||||
<combo_box
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
top_delta="-6"
|
||||
name="double_click_action_combo"
|
||||
width="200">
|
||||
<combo_box.item
|
||||
label="No action"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Move to clicked point"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="Teleport to clicked point"
|
||||
name="2"
|
||||
value="2"/>
|
||||
<combo_box.commit_callback
|
||||
function="Pref.ClickActionChange"/>
|
||||
</combo_box>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
|
|
|
|||
|
|
@ -1014,67 +1014,13 @@
|
|||
enabled_control="EnableVoiceChat"
|
||||
control_name="PushToTalkToggle"
|
||||
height="15"
|
||||
label="Toggle speak on/off when I press:"
|
||||
label="Toggle speak on/off when I press button in toolbar"
|
||||
layout="topleft"
|
||||
left="25"
|
||||
name="push_to_talk_toggle_check"
|
||||
width="237"
|
||||
tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
|
||||
top_pad="10"/>
|
||||
<line_editor
|
||||
follows="top|left"
|
||||
control_name="PushToTalkButton"
|
||||
enabled="false"
|
||||
enabled_control="EnableVoiceChat"
|
||||
height="23"
|
||||
left="60"
|
||||
max_length_bytes="200"
|
||||
name="modifier_combo"
|
||||
label="Push-to-Speak trigger"
|
||||
top_pad="3"
|
||||
width="200" />
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="top|left"
|
||||
enabled_control="EnableVoiceChat"
|
||||
height="23"
|
||||
label="Set Key"
|
||||
left_pad="5"
|
||||
name="set_voice_hotkey_button"
|
||||
width="100">
|
||||
<button.commit_callback
|
||||
function="Pref.VoiceSetKey" />
|
||||
</button>
|
||||
<button
|
||||
enabled_control="EnableVoiceChat"
|
||||
follows="top|left"
|
||||
halign="center"
|
||||
height="23"
|
||||
image_overlay="StopReload_Off"
|
||||
layout="topleft"
|
||||
tool_tip="Clears the toggle button"
|
||||
mouse_opaque="true"
|
||||
name="clear_voice_hotkey_button"
|
||||
left_pad="5"
|
||||
width="25">
|
||||
<button.commit_callback
|
||||
function="Pref.VoiceSetClearKey" />
|
||||
</button>
|
||||
<button
|
||||
enabled_control="EnableVoiceChat"
|
||||
follows="top|left"
|
||||
halign="center"
|
||||
height="23"
|
||||
image_overlay="Refresh_Off"
|
||||
layout="topleft"
|
||||
tool_tip="Reset to Middle Mouse Button"
|
||||
mouse_opaque="true"
|
||||
name="set_voice_middlemouse_button"
|
||||
left_pad="5"
|
||||
width="25">
|
||||
<button.commit_callback
|
||||
function="Pref.VoiceSetMiddleMouse" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
control_name="ShowDeviceSettings"
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
<panel label="Movimiento" name="tab-movement">
|
||||
<check_box label="Las teclas de cursor siempre me mueven" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Pulsar teclas alfanuméricas afecta al movimiento (p. ej. WASD)" name="LetterKeysAffectsMovementNotFocusChatBar"/>
|
||||
<check_box label="Usar disposición de teclado AZERTY" name="FSUseAzertyKeyboardLayout"/>
|
||||
<check_box label="Pulsar-pulsar-mantener para correr" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Volar/aterrizar al mantener arriba/abajo" name="automatic_fly"/>
|
||||
<check_box label="Activar el modo conmutado para agacharse" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
<panel label="Mouvement" name="tab-movement">
|
||||
<check_box label="Les flèches directionnelles déplacent toujours mon avatar" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Appuyer sur les touches alphabétiques de déplacement (WASD) déplace mon avatar" name="LetterKeysAffectsMovementNotFocusChatBar"/>
|
||||
<check_box label="Utiliser les touches de déplacement pour clavier AZERTY" name="FSUseAzertyKeyboardLayout"/>
|
||||
<check_box label="Double-pression sur une touche directionnelle pour courir" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Décoller / Atterrir en maintenant les touches Saut / Accroupi" name="automatic_fly"/>
|
||||
<check_box label="Rester accroupi jusqu'à ce que je me relève" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
<panel name="tab-movement" label="Movimento">
|
||||
<check_box label="Le frecce di direzione fanno sempre spostare" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Premere i tasti delle lettere permette il movimento (es. WASD)" name="LetterKeysAffectsMovementNotFocusChatBar" />
|
||||
<check_box label="Usare tastiera AZERTY" name="FSUseAzertyKeyboardLayout" />
|
||||
<check_box label="Doppio clic e tenere premuto per correre" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Volare/atterrare tenendo premuto salta (PagSu)/chinati (PagGiù)" name="automatic_fly"/>
|
||||
<check_box label="Blocca azione chinarsi (PagGiù)" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@
|
|||
<panel label="移動" name="tab-movement">
|
||||
<check_box label="常に矢印キー操作で動くようにする" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="WASDなどの文字キーを押すと、ローカルチャットを始めるのではなく、前左後右に移動するようにする" name="LetterKeysAffectsMovementNotFocusChatBar" />
|
||||
<check_box label="AZERTYキーボード配列(フランス式)を使用" name="FSUseAzertyKeyboardLayout" />
|
||||
<check_box label="上矢印キー2度押し+長押しで走る" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="UP/DOWNキーの長押しで飛行/着地する" name="automatic_fly" />
|
||||
<check_box label="身をかがめる動作を有効にする" name="crouch_toggle_mode" />
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
<panel label="Ruch" name="tab-movement">
|
||||
<check_box label="Przyciski ze strzałkami zawsze poruszają awatarem" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Naciskanie klawiszy liter wpływa na ruch (tzn. WASD) zamiast rozpoczynać czat" name="LetterKeysAffectsMovementNotFocusChatBar"/>
|
||||
<check_box label="Użyj układu klawiatury AZERTY" name="FSUseAzertyKeyboardLayout"/>
|
||||
<check_box label="Puk-puk-trzymaj, aby biec" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Przytrzymaj klawisz skoku lub kucania, aby zacząć lub przestać latać" name="automatic_fly"/>
|
||||
<check_box label="Włącz tryb przełączania kucania" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
<panel label="Движение" name="tab-movement">
|
||||
<check_box label="Клавиши со стрелками всегда перемещают меня" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Буквенные клавиши влияют на движение не запуская локальный чат (т.e. WASD)" name="LetterKeysAffectsMovementNotFocusChatBar"/>
|
||||
<check_box label="Использовать раскладку AZERTY" name="FSUseAzertyKeyboardLayout"/>
|
||||
<check_box label="Двойное нажатие для бега" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Летать / Приземлиться (верх (прыжок) / вниз (присесть))" name="automatic_fly"/>
|
||||
<check_box label="Включить режим переключения приседания" name="crouch_toggle_mode"/>
|
||||
|
|
|
|||
|
|
@ -153,6 +153,13 @@ https://accounts.secondlife.com/change_email/
|
|||
layout="topleft"
|
||||
help_topic="preferences_move_tab"
|
||||
name="move" />
|
||||
<panel
|
||||
class="panel_preference_controls"
|
||||
filename="panel_preferences_controls.xml"
|
||||
label="Controls"
|
||||
layout="topleft"
|
||||
help_topic="preferences_controls_tab"
|
||||
name="controls" />
|
||||
<panel
|
||||
class="panel_preference"
|
||||
filename="panel_preferences_alerts.xml"
|
||||
|
|
|
|||
|
|
@ -135,6 +135,13 @@ https://accounts.secondlife.com/change_email/
|
|||
layout="topleft"
|
||||
help_topic="preferences_move_tab"
|
||||
name="move" />
|
||||
<panel
|
||||
class="panel_preference_controls"
|
||||
filename="panel_preferences_controls.xml"
|
||||
label="Controls"
|
||||
layout="topleft"
|
||||
help_topic="preferences_controls_tab"
|
||||
name="controls" />
|
||||
<panel
|
||||
class="panel_preference"
|
||||
filename="panel_preferences_alerts.xml"
|
||||
|
|
|
|||
Loading…
Reference in New Issue