Merge branch 'V2MultiWear' of git://github.com/Shyotl/SingularityViewer into V2MultiWear

Conflicts:
	indra/newview/llfloateravatarlist.cpp
	indra/newview/llfloatermessagelog.cpp
	indra/newview/llstartup.cpp
	indra/newview/llviewermenu.cpp
	indra/newview/llviewermessage.cpp
	indra/newview/skins/default/xui/fr/menu_inventory.xml
This commit is contained in:
Siana Gearz
2012-03-28 22:27:45 +02:00
264 changed files with 27606 additions and 15368 deletions

View File

@@ -77,6 +77,7 @@ if (VIEWER)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui) add_subdirectory(${LIBS_OPEN_PREFIX}llui)
add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
# viewer plugins directory # viewer plugins directory
add_subdirectory(${LIBS_OPEN_PREFIX}plugins) add_subdirectory(${LIBS_OPEN_PREFIX}plugins)

View File

@@ -0,0 +1,7 @@
# -*- cmake -*-
set(LLXUIXML_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llxuixml
)
set(LLXUIXML_LIBRARIES llxuixml)

View File

@@ -1,31 +1,25 @@
/** /**
* @file llgesture.cpp * @file llgesture.cpp
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -3,31 +3,25 @@
* @brief A gesture is a combination of a triggering chat phrase or * @brief A gesture is a combination of a triggering chat phrase or
* key, a sound, an animation, and a chat string. * key, a sound, an animation, and a chat string.
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file llmultigesture.cpp * @file llmultigesture.cpp
* @brief Gestures that are asset-based and can have multiple steps. * @brief Gestures that are asset-based and can have multiple steps.
* *
* $LicenseInfo:firstyear=2004&license=viewergpl$ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
*
* Copyright (c) 2004-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -70,6 +70,10 @@ public:
KEY mKey; KEY mKey;
MASK mMask; MASK mMask;
// This name can be empty if the inventory item is not around and
// the gesture manager has not yet set the name
std::string mName;
// String, like "/foo" or "hello" that makes it play // String, like "/foo" or "hello" that makes it play
std::string mTrigger; std::string mTrigger;

View File

@@ -2,31 +2,25 @@
* @file llvisualparam.cpp * @file llvisualparam.cpp
* @brief Implementation of LLPolyMesh class. * @brief Implementation of LLPolyMesh class.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -2,31 +2,25 @@
* @file llvisualparam.h * @file llvisualparam.h
* @brief Implementation of LLPolyMesh class. * @brief Implementation of LLPolyMesh class.
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -223,7 +223,7 @@ void LLPrimitive::setPCode(const U8 p_code)
} }
//=============================================================== //===============================================================
const LLTextureEntry* LLPrimitive::getTE(const U8 index) const LLTextureEntry* LLPrimitive::getTE(const U8 index) const
{ {
return mTextureList.getTexture(index); return mTextureList.getTexture(index);
} }

View File

@@ -334,7 +334,7 @@ public:
// Modify texture entry properties // Modify texture entry properties
inline BOOL validTE(const U8 te_num) const; inline BOOL validTE(const U8 te_num) const;
const LLTextureEntry *getTE(const U8 te_num) const; LLTextureEntry *getTE(const U8 te_num) const;
virtual void setNumTEs(const U8 num_tes); virtual void setNumTEs(const U8 num_tes);
virtual void setAllTETextures(const LLUUID &tex_id); virtual void setAllTETextures(const LLUUID &tex_id);

View File

@@ -5,22 +5,26 @@ project(llui)
include(00-Common) include(00-Common)
include(LLCommon) include(LLCommon)
include(LLImage) include(LLImage)
include(LLInventory)
include(LLMath) include(LLMath)
include(LLMessage) include(LLMessage)
include(LLRender) include(LLRender)
include(LLWindow) include(LLWindow)
include(LLVFS) include(LLVFS)
include(LLXML) include(LLXML)
include(LLXUIXML)
include_directories( include_directories(
${LLCOMMON_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS} ${LLIMAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS}
${LLXUIXML_INCLUDE_DIRS}
) )
set(llui_SOURCE_FILES set(llui_SOURCE_FILES
@@ -75,6 +79,7 @@ set(llui_SOURCE_FILES
lluistring.cpp lluistring.cpp
llundo.cpp llundo.cpp
llviewborder.cpp llviewborder.cpp
llviewmodel.cpp
llview.cpp llview.cpp
llviewquery.cpp llviewquery.cpp
) )
@@ -142,6 +147,7 @@ set(llui_HEADER_FILES
lluixmltags.h lluixmltags.h
llundo.h llundo.h
llviewborder.h llviewborder.h
llviewmodel.h
llview.h llview.h
llviewquery.h llviewquery.h
) )
@@ -159,6 +165,7 @@ target_link_libraries(llui
llwindow llwindow
llimage llimage
llvfs # ugh, just for LLDir llvfs # ugh, just for LLDir
llxuixml
llxml llxml
llcommon # must be after llimage, llwindow, llrender llcommon # must be after llimage, llwindow, llrender
llmath llmath

File diff suppressed because it is too large Load Diff

View File

@@ -41,6 +41,8 @@
#include "llfontgl.h" #include "llfontgl.h"
#include "lluiimage.h" #include "lluiimage.h"
#include "lluistring.h" #include "lluistring.h"
#include "llinitparam.h"
#include "lluicolor.h"
// //
// Constants // Constants
@@ -85,21 +87,26 @@ public:
const LLFontGL* mGLFont = NULL, const LLFontGL* mGLFont = NULL,
const std::string& unselected_label = LLStringUtil::null, const std::string& unselected_label = LLStringUtil::null,
const std::string& selected_label = LLStringUtil::null ); const std::string& selected_label = LLStringUtil::null );
public:
virtual ~LLButton(); ~LLButton();
void init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const std::string& control_name); // For backward compatability only
typedef boost::function<void(void*)> button_callback_t;
void addImageAttributeToXML(LLXMLNodePtr node, const LLPointer<LLUIImage>, const std::string& xmlTagName) const;
void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName, void init(void (*click_callback)(void*), void *callback_data, const std::string& control_name);
const LLUUID& imageID,const std::string& xmlTagName) const;
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
virtual void setAlpha( F32 alpha ) { mAlpha = alpha; }
virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual void draw(); virtual void draw();
virtual void onMouseCaptureLost(); virtual void onMouseCaptureLost();
@@ -109,29 +116,48 @@ public:
void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; } void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; } void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
void setClickedCallback( void (*cb)(void *data), void* data = NULL ); // mouse down and up within button
void setMouseDownCallback( void (*cb)(void *data) ) { mMouseDownCallback = cb; } // mouse down within button /*boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb);
void setMouseUpCallback( void (*cb)(void *data) ) { mMouseUpCallback = cb; } // mouse up, EVEN IF NOT IN BUTTON boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb);
void setHeldDownCallback( void (*cb)(void *data) ) { mHeldDownCallback = cb; } // Mouse button held down and in button boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb);
boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb);*/
boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON
// Passes a 'count' parameter in the commit param payload, i.e. param["count"])
boost::signals2::connection setHeldDownCallback( const commit_signal_t::slot_type& cb ); // Mouse button held down and in button
// *TODO: Deprecate (for backwards compatability only)
boost::signals2::connection setClickedCallback( button_callback_t cb, void* data );
boost::signals2::connection setMouseDownCallback( button_callback_t cb, void* data );
boost::signals2::connection setMouseUpCallback( button_callback_t cb, void* data );
boost::signals2::connection setHeldDownCallback( button_callback_t cb, void* data );
void setHeldDownDelay( F32 seconds, S32 frames = 0) { mHeldDownDelay = seconds; mHeldDownFrameDelay = frames; } void setHeldDownDelay( F32 seconds, S32 frames = 0) { mHeldDownDelay = seconds; mHeldDownFrameDelay = frames; }
F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); } F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); }
BOOL getIsToggle() const { return mIsToggle; }
void setIsToggle(BOOL is_toggle) { mIsToggle = is_toggle; }
BOOL toggleState(); BOOL toggleState();
BOOL getToggleState() const { return mToggleState; } BOOL getToggleState() const;
void setToggleState(BOOL b); void setToggleState(BOOL b);
void setHighlight(bool b);
void setFlashing( BOOL b ); void setFlashing( BOOL b );
BOOL getFlashing() const { return mFlashing; } BOOL getFlashing() const { return mFlashing; }
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
LLFontGL::HAlign getHAlign() const { return mHAlign; } LLFontGL::HAlign getHAlign() const { return mHAlign; }
void setLeftHPad( S32 pad ) { mLeftHPad = pad; } void setLeftHPad( S32 pad ) { mLeftHPad = pad; }
S32 getLeftHPad() const { return mLeftHPad; } S32 getLeftHPad() const { return mLeftHPad; }
void setRightHPad( S32 pad ) { mRightHPad = pad; } void setRightHPad( S32 pad ) { mRightHPad = pad; }
S32 getRightHPad() const { return mRightHPad; } S32 getRightHPad() const { return mRightHPad; }
void setImageOverlayTopPad( S32 pad ) { mImageOverlayTopPad = pad; }
S32 getImageOverlayTopPad() const { return mImageOverlayTopPad; }
void setImageOverlayBottomPad( S32 pad ) { mImageOverlayBottomPad = pad; }
S32 getImageOverlayBottomPad() const { return mImageOverlayBottomPad; }
const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); }
const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); }
@@ -139,35 +165,31 @@ public:
void setImageColor(const std::string& color_control); void setImageColor(const std::string& color_control);
void setImageColor(const LLColor4& c); void setImageColor(const LLColor4& c);
/*virtual*/ void setColor(const LLColor4& c); /*virtual*/ void setColor(const LLColor4& c);
/*virtual*/ void setAlpha(F32 alpha);
void setImages(const std::string &image_name, const std::string &selected_name); void setImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImages(const std::string &image_name, const std::string &selected_name, const LLColor4& c);
void setHoverImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImageColor(const LLColor4& c) { mDisabledImageColor = c; } void setDisabledImageColor(const LLColor4& c) { mDisabledImageColor = c; }
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; } LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
LLFontGL::HAlign getImageOverlayHAlign() const { return mImageOverlayAlignment; }
void autoResize(); // resize with label of current btn state
virtual void setValue(const LLSD& value ); void resize(LLUIString label); // resize with label input
virtual LLSD getValue() const;
void setLabel( const LLStringExplicit& label); void setLabel( const LLStringExplicit& label);
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
void setLabelUnselected(const LLStringExplicit& label); void setLabelUnselected(const LLStringExplicit& label);
void setLabelSelected(const LLStringExplicit& label); void setLabelSelected(const LLStringExplicit& label);
void setDisabledLabel(const LLStringExplicit& disabled_label);
void setDisabledSelectedLabel(const LLStringExplicit& disabled_label);
void setDisabledLabelColor( const LLColor4& c ) { mDisabledLabelColor = c; } void setDisabledLabelColor( const LLColor4& c ) { mDisabledLabelColor = c; }
void setFont(const LLFontGL *font) void setFont(const LLFontGL *font)
{ mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); } { mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); }
const LLFontGL* getFont() const { return mGLFont; }
const LLUIString& getCurrentLabel() const;
void setScaleImage(BOOL scale) { mScaleImage = scale; } void setScaleImage(BOOL scale) { mScaleImage = scale; }
BOOL getScaleImage() const { return mScaleImage; } BOOL getScaleImage() const { return mScaleImage; }
@@ -175,132 +197,130 @@ public:
void setBorderEnabled(BOOL b) { mBorderEnabled = b; } void setBorderEnabled(BOOL b) { mBorderEnabled = b; }
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; }
void setImageUnselected(const std::string &image_name);
const std::string& getImageUnselectedName() const { return mImageUnselectedName; }
void setImageSelected(const std::string &image_name);
const std::string& getImageSelectedName() const { return mImageSelectedName; }
void setImageHoverSelected(const std::string &image_name);
void setImageHoverUnselected(const std::string &image_name);
void setImageDisabled(const std::string &image_name);
void setImageDisabledSelected(const std::string &image_name);
void setImageUnselected(LLPointer<LLUIImage> image); void setImageUnselected(LLPointer<LLUIImage> image);
void setImageSelected(LLPointer<LLUIImage> image); void setImageSelected(LLPointer<LLUIImage> image);
void setImageHoverSelected(LLPointer<LLUIImage> image); void setImageHoverSelected(LLPointer<LLUIImage> image);
void setImageHoverUnselected(LLPointer<LLUIImage> image); void setImageHoverUnselected(LLPointer<LLUIImage> image);
void setImageDisabled(LLPointer<LLUIImage> image); void setImageDisabled(LLPointer<LLUIImage> image);
void setImageDisabledSelected(LLPointer<LLUIImage> image); void setImageDisabledSelected(LLPointer<LLUIImage> image);
void setImageFlash(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; } BOOL getCommitOnReturn() const { return mCommitOnReturn; }
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
void setHelpURLCallback(const std::string &help_url); void setHelpURLCallback(const std::string &help_url);
const std::string& getHelpURL() const { return mHelpURL; } const std::string& getHelpURL() const { return mHelpURL; }
void setForcePressedState(bool b) { mForcePressedState = b; }
void setAutoResize(bool auto_resize) { mAutoResize = auto_resize; }
bool getIsToggle() const { return mIsToggle; }
bool setIsToggle(bool toggle) { return mIsToggle = toggle; }
protected: protected:
virtual void drawBorder(const LLColor4& color, S32 size);
void setImageUnselectedID(const LLUUID &image_id);
const LLUUID& getImageUnselectedID() const { return mImageUnselectedID; }
void setImageSelectedID(const LLUUID &image_id);
const LLUUID& getImageSelectedID() const { return mImageSelectedID; }
void setImageHoverSelectedID(const LLUUID &image_id);
void setImageHoverUnselectedID(const LLUUID &image_id);
void setImageDisabledID(const LLUUID &image_id);
void setImageDisabledSelectedID(const LLUUID &image_id);
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; } const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
const LLPointer<LLUIImage>& getImageSelected() const { return mImageSelected; } const LLPointer<LLUIImage>& getImageSelected() const { return mImageSelected; }
void getOverlayImageSize(S32& overlay_width, S32& overlay_height);
LLFrameTimer mMouseDownTimer; LLFrameTimer mMouseDownTimer;
bool mNeedsHighlight;
S32 mButtonFlashCount;
F32 mButtonFlashRate;
private: void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
void resetMouseDownTimer();
void (*mClickedCallback)(void* data );
void (*mMouseDownCallback)(void *data);
void (*mMouseUpCallback)(void *data);
void (*mHeldDownCallback)(void *data);
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
commit_signal_t* mHeldDownSignal;
const LLFontGL *mGLFont; const LLFontGL *mGLFont;
S32 mMouseDownFrame; S32 mMouseDownFrame;
F32 mHeldDownDelay; // seconds, after which held-down callbacks get called S32 mMouseHeldDownCount; // Counter for parameter passed to held-down callback
S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called F32 mHeldDownDelay; // seconds, after which held-down callbacks get called
S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
LLPointer<LLUIImage> mImageOverlay; LLPointer<LLUIImage> mImageOverlay;
LLFontGL::HAlign mImageOverlayAlignment; LLFontGL::HAlign mImageOverlayAlignment;
LLColor4 mImageOverlayColor; LLUIColor mImageOverlayColor;
LLUIColor mImageOverlaySelectedColor;
LLUIColor mImageOverlayDisabledColor;
LLPointer<LLUIImage> mImageUnselected; LLPointer<LLUIImage> mImageUnselected;
LLUIString mUnselectedLabel; LLUIString mUnselectedLabel;
LLColor4 mUnselectedLabelColor; LLUIColor mUnselectedLabelColor;
LLPointer<LLUIImage> mImageSelected; LLPointer<LLUIImage> mImageSelected;
LLUIString mSelectedLabel; LLUIString mSelectedLabel;
LLColor4 mSelectedLabelColor; LLUIColor mSelectedLabelColor;
LLPointer<LLUIImage> mImageHoverSelected; LLPointer<LLUIImage> mImageHoverSelected;
LLPointer<LLUIImage> mImageHoverUnselected; LLPointer<LLUIImage> mImageHoverUnselected;
LLPointer<LLUIImage> mImageDisabled; LLPointer<LLUIImage> mImageDisabled;
LLUIString mDisabledLabel; LLUIColor mDisabledLabelColor;
LLColor4 mDisabledLabelColor;
LLPointer<LLUIImage> mImageDisabledSelected; LLPointer<LLUIImage> mImageDisabledSelected;
LLUIString mDisabledSelectedLabel; LLUIString mDisabledSelectedLabel;
LLColor4 mDisabledSelectedLabelColor; LLUIColor mDisabledSelectedLabelColor;
LLUUID mImageUnselectedID; LLPointer<LLUIImage> mImagePressed;
LLUUID mImageSelectedID; LLPointer<LLUIImage> mImagePressedSelected;
LLUUID mImageHoverSelectedID;
LLUUID mImageHoverUnselectedID;
LLUUID mImageDisabledID;
LLUUID mImageDisabledSelectedID;
std::string mImageUnselectedName;
std::string mImageSelectedName;
std::string mImageHoverSelectedName;
std::string mImageHoverUnselectedName;
std::string mImageDisabledName;
std::string mImageDisabledSelectedName;
LLColor4 mHighlightColor; /* There are two ways an image can flash- by making changes in color according to flash_color attribute
LLColor4 mUnselectedBgColor; or by changing icon from current to the one specified in image_flash. Second way is used only if
LLColor4 mSelectedBgColor; flash icon name is set in attributes(by default it isn't). First way is used otherwise. */
LLColor4 mFlashBgColor; LLPointer<LLUIImage> mImageFlash;
LLColor4 mImageColor; LLUIColor mFlashBgColor;
LLColor4 mDisabledImageColor;
BOOL mIsToggle; LLUIColor mImageColor;
BOOL mToggleState; LLUIColor mDisabledImageColor;
BOOL mScaleImage;
BOOL mDropShadowedText; bool mIsToggle;
bool mScaleImage;
BOOL mBorderEnabled; bool mDropShadowedText;
bool mAutoResize;
bool mBorderEnabled;
bool mFlashing;
BOOL mFlashing; LLFontGL::HAlign mHAlign;
S32 mLeftHPad;
S32 mRightHPad;
S32 mBottomVPad; // under text label
LLFontGL::HAlign mHAlign; S32 mImageOverlayTopPad;
S32 mLeftHPad; S32 mImageOverlayBottomPad;
S32 mRightHPad;
F32 mHoverGlowStrength; /*
F32 mCurGlowStrength; * Space between image_overlay and label
*/
S32 mImgOverlayLabelSpace;
BOOL mNeedsHighlight; F32 mHoverGlowStrength;
BOOL mCommitOnReturn; F32 mCurGlowStrength;
std::string mHelpURL; bool mCommitOnReturn;
bool mFadeWhenDisabled;
LLPointer<LLUIImage> mImagep; bool mForcePressedState;
bool mDisplayPressedState;
LLFrameTimer mFlashingTimer; std::string mHelpURL;
LLFrameTimer mFlashingTimer;
bool mHandleRightMouse;
F32 mAlpha;
}; };
#endif // LL_LLBUTTON_H #endif // LL_LLBUTTON_H

View File

@@ -113,37 +113,27 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect,
LLCHECKBOXCTRL_VPAD, LLCHECKBOXCTRL_VPAD,
LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING + text_width + LLCHECKBOXCTRL_HPAD, LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING + text_width + LLCHECKBOXCTRL_HPAD,
llmax( text_height, LLCHECKBOXCTRL_BTN_SIZE ) + LLCHECKBOXCTRL_VPAD); llmax( text_height, LLCHECKBOXCTRL_BTN_SIZE ) + LLCHECKBOXCTRL_VPAD);
std::string active_true_id, active_false_id;
std::string inactive_true_id, inactive_false_id; std::string active_true_id = mRadioStyle ? "UIImgRadioActiveSelectedUUID" : "UIImgCheckboxActiveSelectedUUID";
if (mRadioStyle) std::string active_false_id = mRadioStyle ? "UIImgRadioActiveUUID" : "UIImgCheckboxActiveUUID";
{ std::string inactive_true_id = mRadioStyle ? "UIImgRadioInactiveSelectedUUID" : "UIImgCheckboxInactiveSelectedUUID";
active_true_id = "UIImgRadioActiveSelectedUUID"; std::string inactive_false_id = mRadioStyle ? "UIImgRadioInactiveUUID" : "UIImgCheckboxInactiveUUID";
active_false_id = "UIImgRadioActiveUUID"; std::string button_name = mRadioStyle ? "Radio control button" : "Checkbox control button";
inactive_true_id = "UIImgRadioInactiveSelectedUUID";
inactive_false_id = "UIImgRadioInactiveUUID"; mButton = new LLButton( button_name, btn_rect,
mButton = new LLButton(std::string("Radio control button"), btn_rect, active_false_id, active_true_id, control_which,
active_false_id, active_true_id, control_which, &LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
mButton->setDisabledImages( inactive_false_id, inactive_true_id ); mButton->setImageDisabledSelected(LLUI::getUIImage(inactive_true_id));
mButton->setHoverGlowStrength(0.35f); mButton->setImageDisabled(LLUI::getUIImage(inactive_false_id));
} mButton->setHoverGlowStrength(0.35f);
else
{
active_false_id = "UIImgCheckboxActiveUUID";
active_true_id = "UIImgCheckboxActiveSelectedUUID";
inactive_true_id = "UIImgCheckboxInactiveSelectedUUID";
inactive_false_id = "UIImgCheckboxInactiveUUID";
mButton = new LLButton(std::string("Checkbox control button"), btn_rect,
active_false_id, active_true_id, control_which,
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
mButton->setDisabledImages( inactive_false_id, inactive_true_id );
mButton->setHoverGlowStrength(0.35f);
}
mButton->setIsToggle(TRUE); mButton->setIsToggle(TRUE);
mButton->setToggleState( initial_value ); mButton->setToggleState( initial_value );
mButton->setFollowsLeft(); mButton->setFollowsLeft();
mButton->setFollowsBottom(); mButton->setFollowsBottom();
mButton->setCommitOnReturn(FALSE); mButton->setCommitOnReturn(FALSE);
mButton->setScaleImage(FALSE);
addChild(mButton); addChild(mButton);
} }
@@ -156,22 +146,8 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
// static // static
void LLCheckBoxCtrl::onButtonPress( void *userdata ) void LLCheckBoxCtrl::onButtonPress( void *userdata )
{ {
LLCheckBoxCtrl* self = (LLCheckBoxCtrl*) userdata; LLCheckBoxCtrl* self = (LLCheckBoxCtrl*)userdata;
if (self->mRadioStyle)
{
self->setValue(TRUE);
}
self->setControlValue(self->getValue());
// HACK: because buttons don't normally commit
self->onCommit(); self->onCommit();
if (self->mKeyboardFocusOnClick)
{
self->setFocus( TRUE );
self->onFocusReceived();
}
} }
void LLCheckBoxCtrl::onCommit() void LLCheckBoxCtrl::onCommit()
@@ -179,6 +155,7 @@ void LLCheckBoxCtrl::onCommit()
if( getEnabled() ) if( getEnabled() )
{ {
setTentative(FALSE); setTentative(FALSE);
setControlValue(getValue());
LLUICtrl::onCommit(); LLUICtrl::onCommit();
} }
} }
@@ -186,7 +163,15 @@ void LLCheckBoxCtrl::onCommit()
void LLCheckBoxCtrl::setEnabled(BOOL b) void LLCheckBoxCtrl::setEnabled(BOOL b)
{ {
LLView::setEnabled(b); LLView::setEnabled(b);
mButton->setEnabled(b);
if (b)
{
mLabel->setColor( mTextEnabledColor.get() );
}
else
{
mLabel->setColor( mTextDisabledColor.get() );
}
} }
void LLCheckBoxCtrl::clear() void LLCheckBoxCtrl::clear()
@@ -219,21 +204,6 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
LLUICtrl::reshape(width, height, called_from_parent); LLUICtrl::reshape(width, height, called_from_parent);
} }
void LLCheckBoxCtrl::draw()
{
if (getEnabled())
{
mLabel->setColor( mTextEnabledColor );
}
else
{
mLabel->setColor( mTextDisabledColor );
}
// Draw children
LLUICtrl::draw();
}
//virtual //virtual
void LLCheckBoxCtrl::setValue(const LLSD& value ) void LLCheckBoxCtrl::setValue(const LLSD& value )
{ {
@@ -246,6 +216,18 @@ LLSD LLCheckBoxCtrl::getValue() const
return mButton->getValue(); return mButton->getValue();
} }
//virtual
void LLCheckBoxCtrl::setTentative(BOOL b)
{
mButton->setTentative(b);
}
//virtual
BOOL LLCheckBoxCtrl::getTentative() const
{
return mButton->getTentative();
}
void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label ) void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label )
{ {
mLabel->setText( label ); mLabel->setText( label );
@@ -282,7 +264,7 @@ BOOL LLCheckBoxCtrl::isDirty() const
{ {
if ( mButton ) if ( mButton )
{ {
return (mSetValue != mButton->getToggleState()); return mButton->isDirty();
} }
return FALSE; // Shouldn't get here return FALSE; // Shouldn't get here
} }
@@ -293,11 +275,12 @@ void LLCheckBoxCtrl::resetDirty()
{ {
if ( mButton ) if ( mButton )
{ {
mSetValue = mButton->getToggleState(); mButton->resetDirty();
} }
} }
// virtual // virtual
LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const
{ {

View File

@@ -82,7 +82,6 @@ public:
virtual void setEnabled( BOOL b ); virtual void setEnabled( BOOL b );
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
// LLUICtrl interface // LLUICtrl interface
@@ -91,8 +90,8 @@ public:
BOOL get() { return (BOOL)getValue().asBoolean(); } BOOL get() { return (BOOL)getValue().asBoolean(); }
void set(BOOL value) { setValue(value); } void set(BOOL value) { setValue(value); }
virtual void setTentative(BOOL b) { mButton->setTentative(b); } virtual void setTentative(BOOL b);
virtual BOOL getTentative() const { return mButton->getTentative(); } virtual BOOL getTentative() const;
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
@@ -108,6 +107,9 @@ public:
void setLabel( const LLStringExplicit& label ); void setLabel( const LLStringExplicit& label );
std::string getLabel() const; std::string getLabel() const;
void setFont( const LLFontGL* font ) { mFont = font; }
const LLFontGL* getFont() { return mFont; }
virtual void setControlName(const std::string& control_name, LLView* context); virtual void setControlName(const std::string& control_name, LLView* context);
virtual std::string getControlName() const; virtual std::string getControlName() const;
@@ -121,8 +123,9 @@ protected:
LLButton* mButton; LLButton* mButton;
LLTextBox* mLabel; LLTextBox* mLabel;
const LLFontGL* mFont; const LLFontGL* mFont;
LLColor4 mTextEnabledColor;
LLColor4 mTextDisabledColor; LLUIColor mTextEnabledColor;
LLUIColor mTextDisabledColor;
BOOL mRadioStyle; BOOL mRadioStyle;
BOOL mInitialValue; // Value set in constructor BOOL mInitialValue; // Value set in constructor
BOOL mSetValue; // Value set programmatically BOOL mSetValue; // Value set programmatically

View File

@@ -85,13 +85,13 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
LLRect(), LLRect(),
LLStringUtil::null, LLStringUtil::null,
NULL, this); NULL, this);
mButton->setImageUnselected(std::string("square_btn_32x128.tga")); mButton->setImageUnselected(LLUI::getUIImage("square_btn_32x128.tga"));
mButton->setImageSelected(std::string("square_btn_selected_32x128.tga")); mButton->setImageSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
mButton->setImageDisabled(std::string("square_btn_32x128.tga")); mButton->setImageDisabled(LLUI::getUIImage("square_btn_32x128.tga"));
mButton->setImageDisabledSelected(std::string("square_btn_selected_32x128.tga")); mButton->setImageDisabledSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
mButton->setScaleImage(TRUE); mButton->setScaleImage(TRUE);
mButton->setMouseDownCallback(onButtonDown); mButton->setMouseDownCallback(boost::bind(&LLComboBox::onButtonDown,this));
mButton->setFont(LLFontGL::getFontSansSerifSmall()); mButton->setFont(LLFontGL::getFontSansSerifSmall());
mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
mButton->setHAlign( LLFontGL::LEFT ); mButton->setHAlign( LLFontGL::LEFT );
@@ -110,13 +110,11 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT); mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT);
updateLayout(); updateLayout();
mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
} }
LLComboBox::~LLComboBox()
{
// children automatically deleted, including mMenu, mButton
}
// virtual // virtual
LLXMLNodePtr LLComboBox::getXML(bool save_children) const LLXMLNodePtr LLComboBox::getXML(bool save_children) const
@@ -228,6 +226,16 @@ void LLComboBox::setEnabled(BOOL enabled)
mButton->setEnabled(enabled); mButton->setEnabled(enabled);
} }
LLComboBox::~LLComboBox()
{
// children automatically deleted, including mMenu, mButton
// explicitly disconect this signal, since base class destructor might fire top lost
mTopLostSignalConnection.disconnect();
}
void LLComboBox::clear() void LLComboBox::clear()
{ {
if (mTextEntry) if (mTextEntry)
@@ -236,8 +244,6 @@ void LLComboBox::clear()
} }
mButton->setLabelSelected(LLStringUtil::null); mButton->setLabelSelected(LLStringUtil::null);
mButton->setLabelUnselected(LLStringUtil::null); mButton->setLabelUnselected(LLStringUtil::null);
mButton->setDisabledLabel(LLStringUtil::null);
mButton->setDisabledSelectedLabel(LLStringUtil::null);
mList->deselectAllItems(); mList->deselectAllItems();
} }
@@ -437,8 +443,6 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
{ {
mButton->setLabelUnselected(name); mButton->setLabelUnselected(name);
mButton->setLabelSelected(name); mButton->setLabelSelected(name);
mButton->setDisabledLabel(name);
mButton->setDisabledSelectedLabel(name);
} }
} }
@@ -481,12 +485,6 @@ void LLComboBox::onFocusLost()
LLUICtrl::onFocusLost(); LLUICtrl::onFocusLost();
} }
void LLComboBox::onLostTop()
{
hideList();
}
void LLComboBox::setButtonVisible(BOOL visible) void LLComboBox::setButtonVisible(BOOL visible)
{ {
mButton->setVisible(visible); mButton->setVisible(visible);
@@ -749,10 +747,10 @@ void LLComboBox::onButtonDown(void *userdata)
self->setFocus( TRUE ); self->setFocus( TRUE );
// pass mouse capture on to list if button is depressed // pass mouse capture on to list if button is depressed
if (self->mButton->hasMouseCapture()) /*if (self->mButton->hasMouseCapture())
{ {
gFocusMgr.setMouseCapture(self->mList); gFocusMgr.setMouseCapture(self->mList);
} }*/
} }
else else
{ {
@@ -1216,7 +1214,7 @@ LLFlyoutButton::LLFlyoutButton(
LLRect(), LLStringUtil::null, NULL, this); LLRect(), LLStringUtil::null, NULL, this);
mActionButton->setScaleImage(TRUE); mActionButton->setScaleImage(TRUE);
mActionButton->setClickedCallback(onActionButtonClick); mActionButton->setClickedCallback(boost::bind(&LLFlyoutButton::onActionButtonClick, this));
mActionButton->setFollowsAll(); mActionButton->setFollowsAll();
mActionButton->setHAlign( LLFontGL::HCENTER ); mActionButton->setHAlign( LLFontGL::HCENTER );
mActionButton->setLabel(label); mActionButton->setLabel(label);

View File

@@ -80,7 +80,6 @@ public:
virtual void draw(); virtual void draw();
virtual void onFocusLost(); virtual void onFocusLost();
virtual void onLostTop();
virtual void setEnabled(BOOL enabled); virtual void setEnabled(BOOL enabled);
@@ -212,6 +211,7 @@ private:
bool mSuppressTentative; bool mSuppressTentative;
void (*mPrearrangeCallback)(LLUICtrl*,void*); void (*mPrearrangeCallback)(LLUICtrl*,void*);
void (*mTextEntryCallback)(LLLineEditor*, void*); void (*mTextEntryCallback)(LLLineEditor*, void*);
boost::signals2::connection mTopLostSignalConnection;
}; };
class LLFlyoutButton : public LLComboBox class LLFlyoutButton : public LLComboBox

View File

@@ -430,6 +430,27 @@ void LLFloater::initFloater(const std::string& title,
} }
} }
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
{
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::TOP]->setVisible(enable && height);
mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height);
mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width);
mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height);
mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height);
for (S32 i = 0; i < 4; ++i)
{
mResizeHandle[i]->setVisible(enable && width && height);
mResizeHandle[i]->setEnabled(enable && width && height);
}
}
// virtual // virtual
LLFloater::~LLFloater() LLFloater::~LLFloater()
{ {
@@ -707,6 +728,8 @@ const std::string& LLFloater::getCurrentTitle() const
void LLFloater::setTitle( const std::string& title ) void LLFloater::setTitle( const std::string& title )
{ {
if(mTitle == title)
return;
mTitle = title; mTitle = title;
applyTitle(); applyTitle();
} }
@@ -1542,10 +1565,12 @@ void LLFloater::setCanResize(BOOL can_resize)
{ {
for (S32 i = 0; i < 4; i++) for (S32 i = 0; i < 4; i++)
{ {
removeChild(mResizeBar[i], TRUE); removeChild(mResizeBar[i]);
delete mResizeBar[i];
mResizeBar[i] = NULL; mResizeBar[i] = NULL;
removeChild(mResizeHandle[i], TRUE); removeChild(mResizeHandle[i]);
delete mResizeHandle[i];
mResizeHandle[i] = NULL; mResizeHandle[i] = NULL;
} }
} }
@@ -1611,6 +1636,7 @@ void LLFloater::setCanResize(BOOL can_resize)
mMinHeight, mMinHeight,
LLResizeHandle::LEFT_TOP ); LLResizeHandle::LEFT_TOP );
addChild(mResizeHandle[3]); addChild(mResizeHandle[3]);
enableResizeCtrls(can_resize);
} }
mResizable = can_resize; mResizable = can_resize;
} }
@@ -1714,8 +1740,8 @@ void LLFloater::buildButtons()
buttonp->setFollowsRight(); buttonp->setFollowsRight();
buttonp->setToolTip( sButtonToolTips[i] ); buttonp->setToolTip( sButtonToolTips[i] );
buttonp->setImageColor(LLUI::sColorsGroup->getColor("FloaterButtonImageColor")); buttonp->setImageColor(LLUI::sColorsGroup->getColor("FloaterButtonImageColor"));
buttonp->setHoverImages(sButtonPressedImageNames[i], buttonp->setImageHoverSelected(LLUI::getUIImage(sButtonPressedImageNames[i]));
sButtonPressedImageNames[i]); buttonp->setImageHoverUnselected(LLUI::getUIImage(sButtonPressedImageNames[i]));
buttonp->setScaleImage(TRUE); buttonp->setScaleImage(TRUE);
buttonp->setSaveToXML(false); buttonp->setSaveToXML(false);
addChild(buttonp); addChild(buttonp);
@@ -2459,8 +2485,12 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)
void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
{ {
for (child_list_const_iter_t child_iter = getChildList()->begin(); // make a copy of the list since some floaters change their
child_iter != getChildList()->end(); ++child_iter) // order in the childList when changing visibility.
child_list_t child_list_copy = *getChildList();
for (child_list_const_iter_t child_iter = child_list_copy.begin();
child_iter != child_list_copy.end(); ++child_iter)
{ {
LLView *view = *child_iter; LLView *view = *child_iter;
if (skip_list.find(view) == skip_list.end()) if (skip_list.find(view) == skip_list.end())

View File

@@ -250,6 +250,7 @@ public:
static BOOL getEditModeEnabled() { return sEditModeEnabled; } static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; } static LLMultiFloater* getFloaterHost() {return sHostp; }
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
protected: protected:
virtual void bringToFront(S32 x, S32 y); virtual void bringToFront(S32 x, S32 y);

View File

@@ -2,31 +2,25 @@
* @file llfocusmgr.cpp * @file llfocusmgr.cpp
* @brief LLFocusMgr base class * @brief LLFocusMgr base class
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -38,13 +32,11 @@
const F32 FOCUS_FADE_TIME = 0.3f; const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement() LLFocusableElement::LLFocusableElement()
: mFocusLostCallback(NULL), : mFocusLostCallback(NULL),
mFocusReceivedCallback(NULL), mFocusReceivedCallback(NULL),
mFocusChangedCallback(NULL), mFocusChangedCallback(NULL),
mFocusCallbackUserData(NULL) mTopLostCallback(NULL)
{ {
} }
@@ -63,31 +55,27 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
// virtual // virtual
LLFocusableElement::~LLFocusableElement() LLFocusableElement::~LLFocusableElement()
{ {
delete mFocusLostCallback;
delete mFocusReceivedCallback;
delete mFocusChangedCallback;
delete mTopLostCallback;
} }
void LLFocusableElement::onFocusReceived() void LLFocusableElement::onFocusReceived()
{ {
if( mFocusReceivedCallback ) if (mFocusReceivedCallback) (*mFocusReceivedCallback)(this);
{ if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
mFocusReceivedCallback( this, mFocusCallbackUserData );
}
if( mFocusChangedCallback )
{
mFocusChangedCallback( this, mFocusCallbackUserData );
}
} }
void LLFocusableElement::onFocusLost() void LLFocusableElement::onFocusLost()
{ {
if( mFocusLostCallback ) if (mFocusLostCallback) (*mFocusLostCallback)(this);
{ if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
mFocusLostCallback( this, mFocusCallbackUserData ); }
}
if( mFocusChangedCallback ) void LLFocusableElement::onTopLost()
{ {
mFocusChangedCallback( this, mFocusCallbackUserData ); if (mTopLostCallback) (*mTopLostCallback)(this);
}
} }
BOOL LLFocusableElement::hasFocus() const BOOL LLFocusableElement::hasFocus() const
@@ -99,28 +87,63 @@ void LLFocusableElement::setFocus(BOOL b)
{ {
} }
boost::signals2::connection LLFocusableElement::setFocusLostCallback( const focus_signal_t::slot_type& cb)
{
if (!mFocusLostCallback) mFocusLostCallback = new focus_signal_t();
return mFocusLostCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusReceivedCallback) mFocusReceivedCallback = new focus_signal_t();
return mFocusReceivedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusChangedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusChangedCallback) mFocusChangedCallback = new focus_signal_t();
return mFocusChangedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setTopLostCallback(const focus_signal_t::slot_type& cb)
{
if (!mTopLostCallback) mTopLostCallback = new focus_signal_t();
return mTopLostCallback->connect(cb);
}
typedef std::list<LLHandle<LLView> > view_handle_list_t;
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
struct LLFocusMgr::Impl
{
// caching list of keyboard focus ancestors for calling onFocusReceived and onFocusLost
view_handle_list_t mCachedKeyboardFocusList;
focus_history_map_t mFocusHistory;
};
LLFocusMgr gFocusMgr; LLFocusMgr gFocusMgr;
LLFocusMgr::LLFocusMgr() LLFocusMgr::LLFocusMgr()
: : mLockedView( NULL ),
mLockedView( NULL ),
mMouseCaptor( NULL ), mMouseCaptor( NULL ),
mKeyboardFocus( NULL ), mKeyboardFocus( NULL ),
mLastKeyboardFocus( NULL ), mLastKeyboardFocus( NULL ),
mDefaultKeyboardFocus( NULL ), mDefaultKeyboardFocus( NULL ),
mKeystrokesOnly(FALSE), mKeystrokesOnly(FALSE),
mTopCtrl( NULL ), mTopCtrl( NULL ),
mFocusWeight(0.f), mAppHasFocus(TRUE), // Macs don't seem to notify us that we've gotten focus, so default to true
mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true mImpl(new LLFocusMgr::Impl)
#ifdef _DEBUG
, mMouseCaptorName("none")
, mKeyboardFocusName("none")
, mTopCtrlName("none")
#endif
{ {
} }
LLFocusMgr::~LLFocusMgr()
{
mImpl->mFocusHistory.clear();
delete mImpl;
mImpl = NULL;
}
void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
{ {
@@ -151,6 +174,12 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
{ {
// notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)
// making the rest of our processing unnecessary since it will already be
// handled by the recursive call
static bool focus_dirty;
focus_dirty = false;
if (mLockedView && if (mLockedView &&
(new_focus == NULL || (new_focus == NULL ||
(new_focus != mLockedView (new_focus != mLockedView
@@ -162,8 +191,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
return; return;
} }
//llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
mKeystrokesOnly = keystrokes_only; mKeystrokesOnly = keystrokes_only;
if( new_focus != mKeyboardFocus ) if( new_focus != mKeyboardFocus )
@@ -171,23 +198,58 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
mLastKeyboardFocus = mKeyboardFocus; mLastKeyboardFocus = mKeyboardFocus;
mKeyboardFocus = new_focus; mKeyboardFocus = new_focus;
if( mLastKeyboardFocus ) // list of the focus and it's ancestors
view_handle_list_t old_focus_list = mImpl->mCachedKeyboardFocusList;
view_handle_list_t new_focus_list;
// walk up the tree to root and add all views to the new_focus_list
for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
{ {
mLastKeyboardFocus->onFocusLost(); new_focus_list.push_back(ctrl->getHandle());
} }
// clear out any existing flash // remove all common ancestors since their focus is unchanged
if (new_focus) while (!new_focus_list.empty() &&
!old_focus_list.empty() &&
new_focus_list.back() == old_focus_list.back())
{ {
mFocusWeight = 0.f; new_focus_list.pop_back();
new_focus->onFocusReceived(); old_focus_list.pop_back();
} }
mFocusTimer.reset();
#ifdef _DEBUG // walk up the old focus branch calling onFocusLost
LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus); // we bubble up the tree to release focus, and back down to add
mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none"); for (view_handle_list_t::iterator old_focus_iter = old_focus_list.begin();
#endif old_focus_iter != old_focus_list.end() && !focus_dirty;
old_focus_iter++)
{
LLView* old_focus_view = old_focus_iter->get();
if (old_focus_view)
{
mImpl->mCachedKeyboardFocusList.pop_front();
old_focus_view->onFocusLost();
}
}
// walk down the new focus branch calling onFocusReceived
for (view_handle_list_t::reverse_iterator new_focus_riter = new_focus_list.rbegin();
new_focus_riter != new_focus_list.rend() && !focus_dirty;
new_focus_riter++)
{
LLView* new_focus_view = new_focus_riter->get();
if (new_focus_view)
{
mImpl->mCachedKeyboardFocusList.push_front(new_focus_view->getHandle());
new_focus_view->onFocusReceived();
}
}
// if focus was changed as part of an onFocusLost or onFocusReceived call
// stop iterating on current list since it is now invalid
if (focus_dirty)
{
return;
}
// If we've got a default keyboard focus, and the caller is // If we've got a default keyboard focus, and the caller is
// releasing keyboard focus, move to the default. // releasing keyboard focus, move to the default.
@@ -212,7 +274,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
if (focus_subtree) if (focus_subtree)
{ {
LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus); LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus);
mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>(); mImpl->mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();
} }
} }
@@ -220,6 +282,8 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
{ {
lockFocus(); lockFocus();
} }
focus_dirty = true;
} }
@@ -241,7 +305,7 @@ BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
// Returns TRUE is parent or any descedent of parent is the mouse captor. // Returns TRUE is parent or any descedent of parent is the mouse captor.
BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const
{ {
if( mMouseCaptor && mMouseCaptor->isView() ) if( mMouseCaptor && dynamic_cast<LLView*>(mMouseCaptor) != NULL )
{ {
LLView* captor_view = (LLView*)mMouseCaptor; LLView* captor_view = (LLView*)mMouseCaptor;
while( captor_view ) while( captor_view )
@@ -268,65 +332,42 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
if( mKeyboardFocus == focus ) if( mKeyboardFocus == focus )
{ {
mKeyboardFocus = NULL; mKeyboardFocus = NULL;
#ifdef _DEBUG
mKeyboardFocusName = std::string("none");
#endif
} }
} }
void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
{ {
//if (mFocusLocked)
//{
// return;
//}
if( new_captor != mMouseCaptor ) if( new_captor != mMouseCaptor )
{ {
LLMouseHandler* old_captor = mMouseCaptor; LLMouseHandler* old_captor = mMouseCaptor;
mMouseCaptor = new_captor; mMouseCaptor = new_captor;
/*
if (new_captor) if (LLView::sDebugMouseHandling)
{ {
if ( new_captor->getName() == "Stickto") if (new_captor)
{ {
llinfos << "New mouse captor: " << new_captor->getName() << llendl; llinfos << "New mouse captor: " << new_captor->getName() << llendl;
} }
else else
{ {
llinfos << "New mouse captor: " << new_captor->getName() << llendl; llinfos << "New mouse captor: NULL" << llendl;
} }
} }
else
{
llinfos << "New mouse captor: NULL" << llendl;
}
*/
if( old_captor ) if( old_captor )
{ {
old_captor->onMouseCaptureLost(); old_captor->onMouseCaptureLost();
} }
#ifdef _DEBUG
mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none");
#endif
} }
} }
void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ) void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor )
{ {
//if (mFocusLocked)
//{
// return;
//}
if( mMouseCaptor == captor ) if( mMouseCaptor == captor )
{ {
mMouseCaptor = NULL; mMouseCaptor = NULL;
#ifdef _DEBUG
mMouseCaptorName = std::string("none");
#endif
} }
} }
@@ -355,13 +396,9 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top )
{ {
mTopCtrl = new_top; mTopCtrl = new_top;
#ifdef _DEBUG
mTopCtrlName = new_top ? new_top->getName() : std::string("none");
#endif
if (old_top) if (old_top)
{ {
old_top->onLostTop(); old_top->onTopLost();
} }
} }
} }
@@ -371,9 +408,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
if( mTopCtrl == top_view ) if( mTopCtrl == top_view )
{ {
mTopCtrl = NULL; mTopCtrl = NULL;
#ifdef _DEBUG
mTopCtrlName = std::string("none");
#endif
} }
} }
@@ -389,12 +423,13 @@ void LLFocusMgr::unlockFocus()
F32 LLFocusMgr::getFocusFlashAmt() const F32 LLFocusMgr::getFocusFlashAmt() const
{ {
return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f); return clamp_rescale(mFocusFlashTimer.getElapsedTimeF32(), 0.f, FOCUS_FADE_TIME, 1.f, 0.f);
} }
LLColor4 LLFocusMgr::getFocusColor() const LLColor4 LLFocusMgr::getFocusColor() const
{ {
LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt()); static LLCachedControl<LLColor4> focus_color_cached(*LLUI::sColorsGroup,"FocusColor", LLColor4::white);
LLColor4 focus_color = lerp(focus_color_cached, LLColor4::white, getFocusFlashAmt());
// de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem) // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem)
if (!mAppHasFocus) if (!mAppHasFocus)
{ {
@@ -405,8 +440,7 @@ LLColor4 LLFocusMgr::getFocusColor() const
void LLFocusMgr::triggerFocusFlash() void LLFocusMgr::triggerFocusFlash()
{ {
mFocusTimer.reset(); mFocusFlashTimer.reset();
mFocusWeight = 1.f;
} }
void LLFocusMgr::setAppHasFocus(BOOL focus) void LLFocusMgr::setAppHasFocus(BOOL focus)
@@ -428,8 +462,8 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
{ {
if (subtree_root) if (subtree_root)
{ {
focus_history_map_t::const_iterator found_it = mFocusHistory.find(subtree_root->getHandle()); focus_history_map_t::const_iterator found_it = mImpl->mFocusHistory.find(subtree_root->getHandle());
if (found_it != mFocusHistory.end()) if (found_it != mImpl->mFocusHistory.end())
{ {
// found last focus for this subtree // found last focus for this subtree
return static_cast<LLUICtrl*>(found_it->second.get()); return static_cast<LLUICtrl*>(found_it->second.get());
@@ -442,6 +476,6 @@ void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)
{ {
if (subtree_root) if (subtree_root)
{ {
mFocusHistory.erase(subtree_root->getHandle()); mImpl->mFocusHistory.erase(subtree_root->getHandle());
} }
} }

View File

@@ -2,31 +2,25 @@
* @file llfocusmgr.h * @file llfocusmgr.h
* @brief LLFocusMgr base class * @brief LLFocusMgr base class
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -38,12 +32,12 @@
#include "llstring.h" #include "llstring.h"
#include "llframetimer.h" #include "llframetimer.h"
#include "llui.h" #include "llui.h"
#include "llhandle.h"
class LLUICtrl; class LLUICtrl;
class LLMouseHandler; class LLMouseHandler;
class LLView; class LLView;
// NOTE: the LLFocusableElement class declaration has been moved here from lluictrl.h.
class LLFocusableElement class LLFocusableElement
{ {
friend class LLFocusMgr; // allow access to focus change handlers friend class LLFocusMgr; // allow access to focus change handlers
@@ -54,21 +48,25 @@ public:
virtual void setFocus( BOOL b ); virtual void setFocus( BOOL b );
virtual BOOL hasFocus() const; virtual BOOL hasFocus() const;
void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setTopLostCallback(const focus_signal_t::slot_type& cb);
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus. // These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
protected: protected:
virtual void onFocusReceived(); virtual void onFocusReceived();
virtual void onFocusLost(); virtual void onFocusLost();
void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); focus_signal_t* mFocusLostCallback;
void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); focus_signal_t* mFocusReceivedCallback;
void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); focus_signal_t* mFocusChangedCallback;
void* mFocusCallbackUserData; focus_signal_t* mTopLostCallback;
}; };
@@ -76,7 +74,7 @@ class LLFocusMgr
{ {
public: public:
LLFocusMgr(); LLFocusMgr();
~LLFocusMgr() { mFocusHistory.clear(); } ~LLFocusMgr();
// Mouse Captor // Mouse Captor
void setMouseCapture(LLMouseHandler* new_captor); // new_captor = NULL to release the mouse. void setMouseCapture(LLMouseHandler* new_captor); // new_captor = NULL to release the mouse.
@@ -93,7 +91,7 @@ public:
BOOL getKeystrokesOnly() { return mKeystrokesOnly; } BOOL getKeystrokesOnly() { return mKeystrokesOnly; }
void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; } void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; }
F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } F32 getFocusTime() const { return mFocusFlashTimer.getElapsedTimeF32(); }
F32 getFocusFlashAmt() const; F32 getFocusFlashAmt() const;
S32 getFocusFlashWidth() const { return llround(lerp(1.f, 3.f, getFocusFlashAmt())); } S32 getFocusFlashWidth() const { return llround(lerp(1.f, 3.f, getFocusFlashAmt())); }
LLColor4 getFocusColor() const; LLColor4 getFocusColor() const;
@@ -121,6 +119,9 @@ public:
void unlockFocus(); void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; } BOOL focusLocked() const { return mLockedView != NULL; }
struct Impl;
private: private:
LLUICtrl* mLockedView; LLUICtrl* mLockedView;
@@ -132,23 +133,15 @@ private:
LLFocusableElement* mLastKeyboardFocus; // who last had focus LLFocusableElement* mLastKeyboardFocus; // who last had focus
LLFocusableElement* mDefaultKeyboardFocus; LLFocusableElement* mDefaultKeyboardFocus;
BOOL mKeystrokesOnly; BOOL mKeystrokesOnly;
// Top View // Top View
LLUICtrl* mTopCtrl; LLUICtrl* mTopCtrl;
LLFrameTimer mFocusTimer; LLFrameTimer mFocusFlashTimer;
F32 mFocusWeight;
BOOL mAppHasFocus; BOOL mAppHasFocus;
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t; Impl * mImpl;
focus_history_map_t mFocusHistory;
#ifdef _DEBUG
std::string mMouseCaptorName;
std::string mKeyboardFocusName;
std::string mTopCtrlName;
#endif
}; };
extern LLFocusMgr gFocusMgr; extern LLFocusMgr gFocusMgr;

View File

@@ -104,7 +104,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
: :
LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
mMaxLengthBytes(max_length_bytes), mMaxLengthBytes(max_length_bytes),
mPopupMenuHandle(),
mCursorPos( 0 ), mCursorPos( 0 ),
mScrollHPos( 0 ), mScrollHPos( 0 ),
mTextPadLeft(0), mTextPadLeft(0),
@@ -140,7 +139,8 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
mHaveHistory(FALSE), mHaveHistory(FALSE),
mImage( sImage ), mImage( sImage ),
mReplaceNewlinesWithSpaces( TRUE ), mReplaceNewlinesWithSpaces( TRUE ),
mSpellCheckable( FALSE ) mSpellCheckable( FALSE ),
mContextMenuHandle()
{ {
llassert( max_length_bytes > 0 ); llassert( max_length_bytes > 0 );
@@ -156,7 +156,8 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
mGLFont = LLFontGL::getFontSansSerifSmall(); mGLFont = LLFontGL::getFontSansSerifSmall();
} }
setFocusLostCallback(focus_lost_callback); if(focus_lost_callback)
setFocusLostCallback(boost::bind(focus_lost_callback,_1,(void*)NULL));
setTextPadding(0, 0); setTextPadding(0, 0);
@@ -185,35 +186,30 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
{ {
menu = new LLMenuGL(LLStringUtil::null); menu = new LLMenuGL(LLStringUtil::null);
}*/ }*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->appendSeparator("Spelsep"); menu->addSeparator();
//menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
menu->setCanTearOff(FALSE); menu->setCanTearOff(FALSE);
menu->setVisible(FALSE); menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle(); setContextMenu(menu);
} }
LLLineEditor::~LLLineEditor() LLLineEditor::~LLLineEditor()
{ {
mCommitOnFocusLost = FALSE; mCommitOnFocusLost = FALSE;
// calls onCommit() while LLLineEditor still valid
gFocusMgr.releaseFocusIfNeeded( this ); gFocusMgr.releaseFocusIfNeeded( this );
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
LLView::deleteViewByHandle(mPopupMenuHandle);
} }
void LLLineEditor::onFocusReceived() void LLLineEditor::onFocusReceived()
{ {
gEditMenuHandler = this;
LLUICtrl::onFocusReceived(); LLUICtrl::onFocusReceived();
updateAllowingLanguageInput(); updateAllowingLanguageInput();
} }
@@ -645,105 +641,6 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE; return TRUE;
} }
BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
setFocus(TRUE);
//setCursorAtLocalPos( x);
S32 wordStart = 0;
S32 wordLen = 0;
S32 pos = calculateCursorFromMouse(x);
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu)
{
if(menu->isOpen())
{
menu->setVisible(FALSE);
}
for (int i = 0;i<(int)suggestionMenuItems.size();i++)
{
SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind)
{
menu->remove((LLMenuItemCallGL *)tempBind->menuItem);
((LLMenuItemCallGL *)tempBind->menuItem)->die();
//delete tempBind->menuItem;
//tempBind->menuItem = NULL;
delete tempBind;
}
}
suggestionMenuItems.clear();
// spell_check="true" in xui
menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
if (!mReadOnly && mSpellCheckable)
{
// search for word matches
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
if (is_word_part)
{
const LLWString& text = mText.getWString();
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
if (!glggHunSpell->isSpelledRight(selectedWord))
{
//misspelled word here, and you have just right clicked on it!
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
for (int i = 0; i<(int)suggs.size() ;i++)
{
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = suggs[i];
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_correct, NULL, tempStruct);
//new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = selectedWord;
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
if (glggHunSpell->getSpellCheckHighlight())
{
tempStruct->word = "Hide Misspellings";
}
else
{
tempStruct->word = "Show Misspellings";
}
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
mLastContextMenuX = x;
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
}
BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{ {
// Check first whether the "clear search" button wants to deal with this. // Check first whether the "clear search" button wants to deal with this.
@@ -835,6 +732,16 @@ BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
return TRUE; return TRUE;
} }
BOOL LLLineEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
if (!LLUICtrl::handleRightMouseDown(x, y, mask))
{
showContextMenu(x, y);
}
return TRUE;
}
BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
{ {
BOOL handled = FALSE; BOOL handled = FALSE;
@@ -1615,7 +1522,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
// SL-51858: Key presses are not being passed to the Popup menu. // SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu. // A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu && menu->isOpen()) if (menu && menu->isOpen())
{ {
LLMenuGL::sMenuContainer->hideMenus(); LLMenuGL::sMenuContainer->hideMenus();
@@ -1697,7 +1604,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
{ {
// SL-51858: Key presses are not being passed to the Popup menu. // SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu. // A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu && menu->isOpen()) if (menu && menu->isOpen())
{ {
LLMenuGL::sMenuContainer->hideMenus(); LLMenuGL::sMenuContainer->hideMenus();
@@ -2060,7 +1967,7 @@ void LLLineEditor::draw()
// Make sure the IME is in the right place // Make sure the IME is in the right place
S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position
LLRect screen_pos = getScreenRect(); LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD ); LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
@@ -3069,6 +2976,121 @@ LLWString LLLineEditor::getConvertedText() const
return text; return text;
} }
void LLLineEditor::showContextMenu(S32 x, S32 y)
{
LLMenuGL* menu = static_cast<LLMenuGL*>(mContextMenuHandle.get());
if (menu)
{
gEditMenuHandler = this;
/*S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
menu->show(screen_x, screen_y);*/
//setCursorAtLocalPos( x);
S32 wordStart = 0;
S32 wordLen = 0;
S32 pos = calculateCursorFromMouse(x);
LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu)
{
if(menu->isOpen())
{
menu->setVisible(FALSE);
}
for (int i = 0;i<(int)suggestionMenuItems.size();i++)
{
SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind)
{
menu->removeChild((LLMenuItemCallGL *)tempBind->menuItem);
((LLMenuItemCallGL *)tempBind->menuItem)->die();
//delete tempBind->menuItem;
//tempBind->menuItem = NULL;
delete tempBind;
}
}
suggestionMenuItems.clear();
// spell_check="true" in xui
menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
if (!mReadOnly && mSpellCheckable)
{
// search for word matches
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
if (is_word_part)
{
const LLWString& text = mText.getWString();
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
if (!glggHunSpell->isSpelledRight(selectedWord))
{
//misspelled word here, and you have just right clicked on it!
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
for (int i = 0; i<(int)suggs.size() ;i++)
{
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = suggs[i];
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_correct, NULL, tempStruct);
//new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = selectedWord;
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
if (glggHunSpell->getSpellCheckHighlight())
{
tempStruct->word = "Hide Misspellings";
}
else
{
tempStruct->word = "Show Misspellings";
}
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
mLastContextMenuX = x;
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
}
}
void LLLineEditor::setContextMenu(LLMenuGL* new_context_menu)
{
if (new_context_menu)
mContextMenuHandle = new_context_menu->getHandle();
else
mContextMenuHandle.markDead();
}
static LLRegisterWidget<LLSearchEditor> r2("search_editor"); static LLRegisterWidget<LLSearchEditor> r2("search_editor");

View File

@@ -56,6 +56,7 @@
class LLFontGL; class LLFontGL;
class LLLineEditorRollback; class LLLineEditorRollback;
class LLButton; class LLButton;
class LLMenuGL;
typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr);
@@ -79,6 +80,9 @@ public:
LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
S32 border_thickness = 1); S32 border_thickness = 1);
protected:
void showContextMenu(S32 x, S32 y);
public:
virtual ~LLLineEditor(); virtual ~LLLineEditor();
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
@@ -252,7 +256,9 @@ public:
void updateHistory(); // stores current line in history void updateHistory(); // stores current line in history
void setReplaceNewlinesWithSpaces(BOOL replace); void setReplaceNewlinesWithSpaces(BOOL replace);
void setContextMenu(LLMenuGL* new_context_menu);
private: private:
// private helper methods // private helper methods
@@ -285,7 +291,6 @@ private:
virtual S32 getPreeditFontSize() const; virtual S32 getPreeditFontSize() const;
protected: protected:
LLHandle<LLView> mPopupMenuHandle;
LLUIString mText; // The string being edited. LLUIString mText; // The string being edited.
std::string mPrevText; // Saved string for 'ESC' revert std::string mPrevText; // Saved string for 'ESC' revert
LLUIString mLabel; // text label that is visible when no user text provided LLUIString mLabel; // text label that is visible when no user text provided
@@ -359,6 +364,8 @@ protected:
std::vector<S32> mPreeditPositions; std::vector<S32> mPreeditPositions;
LLPreeditor::standouts_t mPreeditStandouts; LLPreeditor::standouts_t mPreeditStandouts;
LLHandle<LLView> mContextMenuHandle;
private: private:
// Utility on top of LLUI::getUIImage, looks up a named image in a given XML node and returns it if possible // Utility on top of LLUI::getUIImage, looks up a named image in a given XML node and returns it if possible
// or returns a given default image if anything in the process fails. // or returns a given default image if anything in the process fails.

File diff suppressed because it is too large Load Diff

View File

@@ -76,32 +76,40 @@ typedef void (*label_callback)(std::string&,void*);
// The LLMenuItemGL represents a single menu item in a menu. // The LLMenuItemGL represents a single menu item in a menu.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemGL : public LLView class LLMenuItemGL : public LLUICtrl
{ {
public: public:
// static functions to control the global color scheme. // static functions to control the global color scheme.
static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } /*static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; }
static const LLColor4& getEnabledColor() { return sEnabledColor; } static const LLColor4& getEnabledColor() { return sEnabledColor; }
static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; } static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; }
static const LLColor4& getDisabledColor() { return sDisabledColor; } static const LLColor4& getDisabledColor() { return sDisabledColor; }
static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; } static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; }
static const LLColor4& getHighlightBGColor() { return sHighlightBackground; } static const LLColor4& getHighlightBGColor() { return sHighlightBackground; }
static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; } static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; }
static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }*/
LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE ); LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE );
virtual ~LLMenuItemGL() {}; virtual ~LLMenuItemGL();
virtual void setValue(const LLSD& value) { setLabel(value.asString()); }
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "item"; } virtual std::string getType() const { return "item"; }
virtual BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
// LLUICtrl overrides
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ LLSD getValue() const;
virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
LLColor4 getHighlightBgColor() { return mHighlightBackground; }
void setJumpKey(KEY key); void setJumpKey(KEY key);
KEY getJumpKey() const { return mJumpKey; } KEY getJumpKey() const { return mJumpKey; }
@@ -115,8 +123,8 @@ public:
virtual U32 getNominalHeight( void ) const; virtual U32 getNominalHeight( void ) const;
// Marks item as not needing space for check marks or accelerator keys // Marks item as not needing space for check marks or accelerator keys
virtual void setBriefItem(BOOL brief) { mBriefItem = brief; } virtual void setBriefItem(BOOL brief);
virtual BOOL isBriefItem() const { return mBriefItem; } virtual BOOL isBriefItem() const;
virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp); virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
@@ -128,7 +136,7 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
// Get the parent menu for this item // Get the parent menu for this item
virtual class LLMenuGL* getMenu(); virtual class LLMenuGL* getMenu() const;
// returns the normal width of this control in pixels - this is // returns the normal width of this control in pixels - this is
// used for calculating the widest item, as well as for horizontal // used for calculating the widest item, as well as for horizontal
@@ -167,6 +175,7 @@ public:
virtual BOOL handleKeyHere( KEY key, MASK mask ); virtual BOOL handleKeyHere( KEY key, MASK mask );
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual void draw( void ); virtual void draw( void );
BOOL getHover() const { return mGotHover; } BOOL getHover() const { return mGotHover; }
@@ -193,13 +202,19 @@ protected:
LLUIString mDrawAccelLabel; LLUIString mDrawAccelLabel;
LLUIString mDrawBranchLabel; LLUIString mDrawBranchLabel;
LLColor4 mEnabledColor;
LLColor4 mDisabledColor;
LLColor4 mHighlightBackground;
LLColor4 mHighlightForeground;
BOOL mHighlight; BOOL mHighlight;
private: public:
static LLColor4 sEnabledColor; static LLColor4 sEnabledColor;
static LLColor4 sDisabledColor; static LLColor4 sDisabledColor;
static LLColor4 sHighlightBackground; static LLColor4 sHighlightBackground;
static LLColor4 sHighlightForeground; static LLColor4 sHighlightForeground;
private:
// Keyboard and mouse variables // Keyboard and mouse variables
BOOL mAllowKeyRepeat; BOOL mAllowKeyRepeat;
BOOL mGotHover; BOOL mGotHover;
@@ -216,6 +231,30 @@ private:
KEY mJumpKey; KEY mJumpKey;
}; };
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemSeparatorGL
//
// This class represents a separator.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemSeparatorGL : public LLMenuItemGL
{
public:
LLMenuItemSeparatorGL( const std::string &name = std::string() );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "separator"; }
// doIt() - do the primary funcationality of the menu item.
virtual void doIt( void ) {}
virtual void draw( void );
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual U32 getNominalHeight( void ) const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemCallGL // Class LLMenuItemCallGL
@@ -278,6 +317,9 @@ public:
void setUserData(void *userdata) { mUserData = userdata; } void setUserData(void *userdata) { mUserData = userdata; }
void* getUserData() const { return mUserData; } void* getUserData() const { return mUserData; }
protected:
void updateEnabled( void );
public:
// called to rebuild the draw label // called to rebuild the draw label
virtual void buildDrawLabel( void ); virtual void buildDrawLabel( void );
@@ -285,7 +327,8 @@ public:
virtual void doIt( void ); virtual void doIt( void );
virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask);
//virtual void draw(); //virtual void draw();
@@ -403,24 +446,35 @@ class LLMenuGL
// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united. // TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united.
// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG // I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG
{ {
public:
// textual artwork which menugl-imitators may want to match
static const std::string BOOLEAN_TRUE_PREFIX;
static const std::string BRANCH_SUFFIX;
static const std::string ARROW_UP;
static const std::string ARROW_DOWN;
protected:
// let branching menu items use my protected traversal methods // let branching menu items use my protected traversal methods
friend class LLMenuItemBranchGL; friend class LLMenuItemBranchGL;
public: public:
LLMenuGL( const std::string& name, const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>()); LLMenuGL( const std::string& name, const std::string& label);
LLMenuGL( const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() ); LLMenuGL( const std::string& label);
virtual ~LLMenuGL( void ); virtual ~LLMenuGL( void );
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory); void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory);
// LLView Functionality // LLView Functionality
virtual BOOL handleUnicodeCharHere( llwchar uni_char ); /*virtual*/ BOOL handleUnicodeCharHere( llwchar uni_char );
virtual BOOL handleHover( S32 x, S32 y, MASK mask ); /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
virtual void draw( void ); /*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
/*virtual*/ void draw( void );
virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color); virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
virtual void setVisible(BOOL visible); /*virtual*/ void setVisible(BOOL visible);
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
/*virtual*/ void removeChild( LLView* ctrl);
/*virtual*/ BOOL postBuild();
virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
@@ -437,23 +491,10 @@ public:
void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; } void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; }
const LLColor4& getBackgroundColor() const { return mBackgroundColor; } const LLColor4& getBackgroundColor() const { return mBackgroundColor; }
void setBackgroundVisible( BOOL b ) { mBgVisible = b; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; }
void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); void setCanTearOff(BOOL tear_off);
// Add the menu item to this menu.
virtual BOOL append( LLMenuItemGL* item );
// Remove a menu item from this menu.
virtual BOOL remove( LLMenuItemGL* item );
// *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0
// Its added as a fix to a viewer 1.23 bug that has already been address by skinning work.
virtual BOOL appendNoArrange( LLMenuItemGL* item );
// add a separator to this menu // add a separator to this menu
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null ); virtual BOOL addSeparator();
// add a menu - this will create a cascading menu
virtual BOOL appendMenu( LLMenuGL* menu );
// for branching menu items, bring sub menus up to root level of menu hierarchy // for branching menu items, bring sub menus up to root level of menu hierarchy
virtual void updateParent( LLView* parentp ); virtual void updateParent( LLView* parentp );
@@ -477,19 +518,17 @@ public:
virtual BOOL isOpen(); virtual BOOL isOpen();
void needsArrange() { mNeedsArrange = TRUE; }
// Shape this menu to fit the current state of the children, and // Shape this menu to fit the current state of the children, and
// adjust the child rects to fit. This is called automatically // adjust the child rects to fit. This is called automatically
// when you add items. *FIX: We may need to deal with visibility // when you add items. *FIX: We may need to deal with visibility
// arrangement. // arrangement.
virtual void arrange( void ); virtual void arrange( void );
void arrangeAndClear( void );
// remove all items on the menu // remove all items on the menu
void empty( void ); void empty( void );
// Rearrange the components, and do the right thing if the menu doesn't
// fit in the bounds.
// virtual void arrangeWithBounds(LLRect bounds);
void setItemLastSelected(LLMenuItemGL* item); // must be in menu void setItemLastSelected(LLMenuItemGL* item); // must be in menu
U32 getItemCount(); // number of menu items U32 getItemCount(); // number of menu items
LLMenuItemGL* getItem(S32 number); // 0 = first item LLMenuItemGL* getItem(S32 number); // 0 = first item
@@ -510,8 +549,8 @@ public:
// Whether to drop shadow menu bar // Whether to drop shadow menu bar
void setDropShadowed( const BOOL shadowed ); void setDropShadowed( const BOOL shadowed );
void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item; } void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item->getHandle(); }
LLMenuItemGL* getParentMenuItem() const { return mParentMenuItem; } LLMenuItemGL* getParentMenuItem() const { return dynamic_cast<LLMenuItemGL*>(mParentMenuItem.get()); }
void setTornOff(BOOL torn_off); void setTornOff(BOOL torn_off);
BOOL getTornOff() { return mTornOff; } BOOL getTornOff() { return mTornOff; }
@@ -524,15 +563,26 @@ public:
static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; } static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; }
static BOOL getKeyboardMode() { return sKeyboardMode; } static BOOL getKeyboardMode() { return sKeyboardMode; }
S32 getShortcutPad() { return mShortcutPad; }
BOOL isScrollable() const { return FALSE; }
static class LLMenuHolderGL* sMenuContainer; static class LLMenuHolderGL* sMenuContainer;
bool isScrollPositionOnShowReset() { return false; }
protected: protected:
void createSpilloverBranch(); void createSpilloverBranch();
void cleanupSpilloverBranch(); void cleanupSpilloverBranch();
// Add the menu item to this menu.
virtual BOOL append( LLMenuItemGL* item );
// add a menu - this will create a cascading menu
virtual BOOL appendMenu( LLMenuGL* menu );
// TODO: create accessor methods for these? // TODO: create accessor methods for these?
typedef std::list< LLMenuItemGL* > item_list_t; typedef std::list< LLMenuItemGL* > item_list_t;
item_list_t mItems; item_list_t mItems;
LLMenuItemGL*mFirstVisibleItem;
typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t; typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t;
navigation_key_map_t mJumpKeys; navigation_key_map_t mJumpKeys;
S32 mLastMouseX; S32 mLastMouseX;
@@ -541,6 +591,7 @@ protected:
S32 mMouseVelY; S32 mMouseVelY;
BOOL mHorizontalLayout; BOOL mHorizontalLayout;
BOOL mKeepFixedSize; BOOL mKeepFixedSize;
BOOL mNeedsArrange;
private: private:
static LLColor4 sDefaultBackgroundColor; static LLColor4 sDefaultBackgroundColor;
@@ -548,17 +599,17 @@ private:
LLColor4 mBackgroundColor; LLColor4 mBackgroundColor;
BOOL mBgVisible; BOOL mBgVisible;
LLMenuItemGL* mParentMenuItem; LLHandle<LLView> mParentMenuItem;
LLUIString mLabel; LLUIString mLabel;
BOOL mDropShadowed; // Whether to drop shadow BOOL mDropShadowed; // Whether to drop shadow
BOOL mHasSelection; bool mHasSelection;
LLFrameTimer mFadeTimer; LLFrameTimer mFadeTimer;
BOOL mTornOff; BOOL mTornOff;
class LLMenuItemTearOffGL* mTearOffItem; class LLMenuItemTearOffGL* mTearOffItem;
class LLMenuItemBranchGL* mSpilloverBranch; class LLMenuItemBranchGL* mSpilloverBranch;
LLMenuGL* mSpilloverMenu; LLMenuGL* mSpilloverMenu;
LLHandle<LLFloater> mParentFloaterHandle;
KEY mJumpKey; KEY mJumpKey;
S32 mShortcutPad;
}; // end class LLMenuGL }; // end class LLMenuGL
@@ -604,11 +655,11 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL isActive() const { return isOpen() && getBranch()->getHighlightedItem(); } virtual BOOL isActive() const;
virtual BOOL isOpen() const { return getBranch() && getBranch()->isOpen(); } virtual BOOL isOpen() const;
LLMenuGL *getBranch() const { return (LLMenuGL*)(mBranch.get()); } LLMenuGL* getBranch() const { return (LLMenuGL*)mBranchHandle.get(); }
virtual void updateBranchParent( LLView* parentp ); virtual void updateBranchParent( LLView* parentp );
@@ -624,7 +675,7 @@ public:
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
private: private:
LLHandle<LLView> mBranch; LLHandle<LLView> mBranchHandle;
}; // end class LLMenuItemBranchGL }; // end class LLMenuItemBranchGL
@@ -646,6 +697,9 @@ public:
void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory);
// LLView Functionality // LLView Functionality
// hide separators. they are added to 'pad' in empty cells.
virtual bool addChild(LLView* view, S32 tab_group = 0);
// can't set visibility directly, must call show or hide // can't set visibility directly, must call show or hide
virtual void setVisible(BOOL visible); virtual void setVisible(BOOL visible);
@@ -657,8 +711,10 @@ public:
virtual void draw(); virtual void draw();
virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color); virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
private:
virtual BOOL append(LLMenuItemGL* item); virtual BOOL append(LLMenuItemGL* item);
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null ); public:
virtual BOOL addSeparator();
BOOL appendPieMenu(LLPieMenu *menu); BOOL appendPieMenu(LLPieMenu *menu);
@@ -703,23 +759,17 @@ public:
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask); void setVisible(BOOL visible);
virtual BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ BOOL handleAcceleratorKey(KEY key, MASK mask);
virtual BOOL handleJumpKey(KEY key); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleJumpKey(KEY key);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
// rearrange the child rects so they fit the shape of the menu /*virtual*/ void draw();
// bar. /*virtual*/ BOOL jumpKeysActive();
virtual void arrange( void );
virtual void draw();
virtual BOOL jumpKeysActive();
// add a vertical separator to this menu // add a vertical separator to this menu
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null ); virtual BOOL addSeparator();
// add a menu - this will create a drop down menu.
virtual BOOL appendMenu( LLMenuGL* menu );
// LLView Functionality // LLView Functionality
virtual BOOL handleHover( S32 x, S32 y, MASK mask ); virtual BOOL handleHover( S32 x, S32 y, MASK mask );
@@ -730,6 +780,12 @@ public:
void resetMenuTrigger() { mAltKeyTrigger = FALSE; } void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
private: private:
// add a menu - this will create a drop down menu.
virtual BOOL appendMenu( LLMenuGL* menu );
// rearrange the child rects so they fit the shape of the menu
// bar.
virtual void arrange( void );
void checkMenuTrigger(); void checkMenuTrigger();
std::list <LLKeyBinding*> mAccelerators; std::list <LLKeyBinding*> mAccelerators;
@@ -757,11 +813,20 @@ public:
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
// Close context menus on right mouse up not handled by menus.
/*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask );
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual const LLRect getMenuRect() const { return getLocalRect(); } virtual const LLRect getMenuRect() const { return getLocalRect(); }
virtual BOOL hasVisibleMenu() const; LLView*const getVisibleMenu() const;
virtual BOOL hasVisibleMenu() const {return getVisibleMenu() != NULL;}
static void setActivatedItem(LLMenuItemGL* item); static void setActivatedItem(LLMenuItemGL* item);
// Need to detect if mouse-up after context menu spawn has moved.
// If not, need to keep the menu up.
static LLCoordGL sContextMenuSpawnPos;
private: private:
static LLHandle<LLView> sItemLastSelectedHandle; static LLHandle<LLView> sItemLastSelectedHandle;
static LLFrameTimer sItemActivationTimer; static LLFrameTimer sItemActivationTimer;
@@ -805,7 +870,7 @@ private:
class LLMenuItemTearOffGL : public LLMenuItemGL class LLMenuItemTearOffGL : public LLMenuItemGL
{ {
public: public:
LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); LLMenuItemTearOffGL();
virtual LLXMLNodePtr getXML(bool save_children = true) const; virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "tearoff_menu"; } virtual std::string getType() const { return "tearoff_menu"; }
@@ -814,8 +879,7 @@ public:
virtual void draw(void); virtual void draw(void);
virtual U32 getNominalHeight() const; virtual U32 getNominalHeight() const;
private: LLFloater* getParentFloater();
LLHandle<LLFloater> mParentHandle;
}; };

View File

@@ -127,7 +127,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
&LLLineEditor::prevalidateFloat ); &LLLineEditor::prevalidateFloat );
mEditor->setFollowsLeft(); mEditor->setFollowsLeft();
mEditor->setFollowsBottom(); mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus, this ); mEditor->setFocusReceivedCallback( boost::bind(&LLMultiSliderCtrl::onFocusReceived, this) );
mEditor->setIgnoreTab(TRUE); mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases // don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others // and double clicking in others
@@ -151,16 +151,6 @@ LLMultiSliderCtrl::~LLMultiSliderCtrl()
// Children all cleaned up by default view destructor. // Children all cleaned up by default view destructor.
} }
// static
void LLMultiSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLMultiSliderCtrl::setValue(const LLSD& value) void LLMultiSliderCtrl::setValue(const LLSD& value)
{ {
mMultiSlider->setValue(value); mMultiSlider->setValue(value);

View File

@@ -126,7 +126,6 @@ public:
static void onSliderCommit(LLUICtrl* caller, void* userdata); static void onSliderCommit(LLUICtrl* caller, void* userdata);
static void onEditorCommit(LLUICtrl* ctrl, void* userdata); static void onEditorCommit(LLUICtrl* ctrl, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
private: private:

View File

@@ -79,7 +79,6 @@ void LLPanel::init()
mBorder = NULL; mBorder = NULL;
mDefaultBtn = NULL; mDefaultBtn = NULL;
setIsChrome(FALSE); //is this a decorator to a live window or a form? setIsChrome(FALSE); //is this a decorator to a live window or a form?
mLastTabGroup = 0;
mPanelHandle.bind(this); mPanelHandle.bind(this);
setTabStop(FALSE); setTabStop(FALSE);
@@ -269,20 +268,6 @@ void LLPanel::setDefaultBtn(const std::string& id)
} }
} }
void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
{
mLastTabGroup = tab_group;
LLView::addCtrl(ctrl, tab_group);
}
void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
{
mLastTabGroup = tab_group;
LLView::addCtrlAtEnd(ctrl, tab_group);
}
BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
{ {
BOOL handled = FALSE; BOOL handled = FALSE;
@@ -760,16 +745,6 @@ BOOL LLPanel::childHasFocus(const std::string& id)
} }
} }
void LLPanel::childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data)
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
if (child)
{
child->setFocusChangedCallback(cb, user_data);
}
}
void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void *userdata ) void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void *userdata )
{ {
LLUICtrl* child = getChild<LLUICtrl>(id, true); LLUICtrl* child = getChild<LLUICtrl>(id, true);
@@ -1199,9 +1174,13 @@ void LLLayoutStack::draw()
} }
} }
void LLLayoutStack::removeCtrl(LLUICtrl* ctrl) void LLLayoutStack::removeChild(LLView* ctrl)
{ {
LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl); LLView::removeChild(ctrl);
LLPanel* panel = dynamic_cast<LLPanel*>(ctrl);
if(!panel)
return;
LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel(panel);
if (embedded_panelp) if (embedded_panelp)
{ {
@@ -1210,10 +1189,8 @@ void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
} }
// need to update resizebars // need to update resizebars
calcMinExtents(); calcMinExtents();
LLView::removeCtrl(ctrl);
} }
LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const

View File

@@ -138,8 +138,6 @@ public:
LLHandle<LLPanel> getHandle() const { return mPanelHandle; } LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
S32 getLastTabGroup() const { return mLastTabGroup; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
@@ -170,7 +168,6 @@ public:
// LLUICtrl // LLUICtrl
void childSetFocus(const std::string& id, BOOL focus = TRUE); void childSetFocus(const std::string& id, BOOL focus = TRUE);
BOOL childHasFocus(const std::string& id); BOOL childHasFocus(const std::string& id);
void childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data = NULL);
void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL ); void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL );
void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL ); void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL );
@@ -236,10 +233,6 @@ private:
// common construction logic // common construction logic
void init(); void init();
// From LLView
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group );
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
// Unified error reporting for the child* functions // Unified error reporting for the child* functions
typedef std::set<std::string> expected_members_list_t; typedef std::set<std::string> expected_members_list_t;
mutable expected_members_list_t mExpectedMembers; mutable expected_members_list_t mExpectedMembers;
@@ -254,7 +247,6 @@ private:
LLViewBorder* mBorder; LLViewBorder* mBorder;
LLButton* mDefaultBtn; LLButton* mDefaultBtn;
std::string mLabel; std::string mLabel;
S32 mLastTabGroup;
LLRootHandle<LLPanel> mPanelHandle; LLRootHandle<LLPanel> mPanelHandle;
typedef std::map<std::string, std::string> ui_string_map_t; typedef std::map<std::string, std::string> ui_string_map_t;
@@ -279,7 +271,7 @@ public:
/*virtual*/ void draw(); /*virtual*/ void draw();
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void removeCtrl(LLUICtrl* ctrl); /*virtual*/ void removeChild(LLView* ctrl);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);

View File

@@ -185,7 +185,8 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if (mSnappingEnabled) if (mSnappingEnabled)
{ {
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0); //static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
switch( mSide ) switch( mSide )
{ {
case LEFT: case LEFT:

View File

@@ -46,7 +46,7 @@ const S32 RESIZE_BORDER_WIDTH = 3;
LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner ) LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
: :
LLView( name, rect, TRUE ), LLView( name, rect, FALSE ),
mDragLastScreenX( 0 ), mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ), mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ), mLastMouseScreenX( 0 ),
@@ -205,7 +205,8 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = NULL; LLView* snap_view = NULL;
LLView* test_view = NULL; LLView* test_view = NULL;
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0); //static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
// now do snapping // now do snapping
switch(mCorner) switch(mCorner)
{ {

View File

@@ -73,7 +73,8 @@ LLScrollbar::LLScrollbar(
mHighlightColor ( LLUI::sColorsGroup->getColor("DefaultHighlightLight") ), mHighlightColor ( LLUI::sColorsGroup->getColor("DefaultHighlightLight") ),
mShadowColor ( LLUI::sColorsGroup->getColor("DefaultShadowLight") ), mShadowColor ( LLUI::sColorsGroup->getColor("DefaultShadowLight") ),
mOnScrollEndCallback( NULL ), mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL ) mOnScrollEndData( NULL ),
mThickness( SCROLLBAR_SIZE )
{ {
//llassert( 0 <= mDocSize ); //llassert( 0 <= mDocSize );
//llassert( 0 <= mDocPos && mDocPos <= mDocSize ); //llassert( 0 <= mDocPos && mDocPos <= mDocSize );
@@ -92,22 +93,22 @@ LLScrollbar::LLScrollbar(
if( LLScrollbar::VERTICAL == mOrientation ) if( LLScrollbar::VERTICAL == mOrientation )
{ {
line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), mThickness, mThickness );
line_up_img="UIImgBtnScrollUpOutUUID"; line_up_img="UIImgBtnScrollUpOutUUID";
line_up_selected_img="UIImgBtnScrollUpInUUID"; line_up_selected_img="UIImgBtnScrollUpInUUID";
line_down_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_down_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollDownOutUUID"; line_down_img="UIImgBtnScrollDownOutUUID";
line_down_selected_img="UIImgBtnScrollDownInUUID"; line_down_selected_img="UIImgBtnScrollDownInUUID";
} }
else else
{ {
// Horizontal // Horizontal
line_up_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_up_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_up_img="UIImgBtnScrollLeftOutUUID"; line_up_img="UIImgBtnScrollLeftOutUUID";
line_up_selected_img="UIImgBtnScrollLeftInUUID"; line_up_selected_img="UIImgBtnScrollLeftInUUID";
line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_down_rect.setOriginAndSize( getRect().getWidth() - mThickness, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollRightOutUUID"; line_down_img="UIImgBtnScrollRightOutUUID";
line_down_selected_img="UIImgBtnScrollRightInUUID"; line_down_selected_img="UIImgBtnScrollRightInUUID";
} }
@@ -126,7 +127,7 @@ LLScrollbar::LLScrollbar(
line_up_btn->setFollowsLeft(); line_up_btn->setFollowsLeft();
line_up_btn->setFollowsBottom(); line_up_btn->setFollowsBottom();
} }
line_up_btn->setHeldDownCallback( &LLScrollbar::onLineUpBtnPressed ); line_up_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineUpBtnPressed, (void*)this) );
line_up_btn->setTabStop(FALSE); line_up_btn->setTabStop(FALSE);
line_up_btn->setScaleImage(TRUE); line_up_btn->setScaleImage(TRUE);
@@ -137,7 +138,7 @@ LLScrollbar::LLScrollbar(
&LLScrollbar::onLineDownBtnPressed, this, LLFontGL::getFontSansSerif() ); &LLScrollbar::onLineDownBtnPressed, this, LLFontGL::getFontSansSerif() );
line_down_btn->setFollowsRight(); line_down_btn->setFollowsRight();
line_down_btn->setFollowsBottom(); line_down_btn->setFollowsBottom();
line_down_btn->setHeldDownCallback( &LLScrollbar::onLineDownBtnPressed ); line_down_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineDownBtnPressed, this) );
line_down_btn->setTabStop(FALSE); line_down_btn->setTabStop(FALSE);
line_down_btn->setScaleImage(TRUE); line_down_btn->setScaleImage(TRUE);
addChild(line_down_btn); addChild(line_down_btn);
@@ -158,7 +159,8 @@ void LLScrollbar::setDocParams( S32 size, S32 pos )
updateThumbRect(); updateThumbRect();
} }
void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb) // returns true if document position really changed
bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{ {
pos = llclamp(pos, 0, getDocPosMax()); pos = llclamp(pos, 0, getDocPosMax());
if (pos != mDocPos) if (pos != mDocPos)
@@ -175,7 +177,9 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{ {
updateThumbRect(); updateThumbRect();
} }
return true;
} }
return false;
} }
void LLScrollbar::setDocSize(S32 size) void LLScrollbar::setDocSize(S32 size)
@@ -221,7 +225,7 @@ void LLScrollbar::updateThumbRect()
const S32 THUMB_MIN_LENGTH = 16; const S32 THUMB_MIN_LENGTH = 16;
S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight(); S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE); S32 thumb_bg_length = llmax(0, window_length - 2 * mThickness);
S32 visible_lines = llmin( mDocSize, mPageSize ); S32 visible_lines = llmin( mDocSize, mPageSize );
S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length; S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
@@ -229,24 +233,24 @@ void LLScrollbar::updateThumbRect()
if( mOrientation == LLScrollbar::VERTICAL ) if( mOrientation == LLScrollbar::VERTICAL )
{ {
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE; S32 thumb_start_max = thumb_bg_length + mThickness;
S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH; S32 thumb_start_min = mThickness + THUMB_MIN_LENGTH;
S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max; S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
mThumbRect.mLeft = 0; mThumbRect.mLeft = 0;
mThumbRect.mTop = thumb_start; mThumbRect.mTop = thumb_start;
mThumbRect.mRight = SCROLLBAR_SIZE; mThumbRect.mRight = mThickness;
mThumbRect.mBottom = thumb_start - thumb_length; mThumbRect.mBottom = thumb_start - thumb_length;
} }
else else
{ {
// Horizontal // Horizontal
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length; S32 thumb_start_max = thumb_bg_length + mThickness - thumb_length;
S32 thumb_start_min = SCROLLBAR_SIZE; S32 thumb_start_min = mThickness;
S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min; S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
mThumbRect.mLeft = thumb_start; mThumbRect.mLeft = thumb_start;
mThumbRect.mTop = SCROLLBAR_SIZE; mThumbRect.mTop = mThickness;
mThumbRect.mRight = thumb_start + thumb_length; mThumbRect.mRight = thumb_start + thumb_length;
mThumbRect.mBottom = 0; mThumbRect.mBottom = 0;
} }
@@ -318,21 +322,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
// S32 old_pos = mThumbRect.mTop; // S32 old_pos = mThumbRect.mTop;
S32 delta_pixels = y - mDragStartY; S32 delta_pixels = y - mDragStartY;
if( mOrigRect.mBottom + delta_pixels < SCROLLBAR_SIZE ) if( mOrigRect.mBottom + delta_pixels < mThickness )
{ {
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mBottom - 1; delta_pixels = mThickness - mOrigRect.mBottom - 1;
} }
else else
if( mOrigRect.mTop + delta_pixels > height - SCROLLBAR_SIZE ) if( mOrigRect.mTop + delta_pixels > height - mThickness )
{ {
delta_pixels = height - SCROLLBAR_SIZE - mOrigRect.mTop + 1; delta_pixels = height - mThickness - mOrigRect.mTop + 1;
} }
mThumbRect.mTop = mOrigRect.mTop + delta_pixels; mThumbRect.mTop = mOrigRect.mTop + delta_pixels;
mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels; mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels;
S32 thumb_length = mThumbRect.getHeight(); S32 thumb_length = mThumbRect.getHeight();
S32 thumb_track_length = height - 2 * SCROLLBAR_SIZE; S32 thumb_track_length = height - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged) if( delta_pixels != mLastDelta || mDocChanged)
@@ -343,7 +347,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{ {
S32 variable_lines = getDocPosMax(); S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mTop; S32 pos = mThumbRect.mTop;
F32 ratio = F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length; F32 ratio = F32(pos - mThickness - thumb_length) / usable_track_length;
S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines ); S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines );
// Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly // Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
@@ -362,21 +366,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
S32 delta_pixels = x - mDragStartX; S32 delta_pixels = x - mDragStartX;
if( mOrigRect.mLeft + delta_pixels < SCROLLBAR_SIZE ) if( mOrigRect.mLeft + delta_pixels < mThickness )
{ {
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mLeft - 1; delta_pixels = mThickness - mOrigRect.mLeft - 1;
} }
else else
if( mOrigRect.mRight + delta_pixels > width - SCROLLBAR_SIZE ) if( mOrigRect.mRight + delta_pixels > width - mThickness )
{ {
delta_pixels = width - SCROLLBAR_SIZE - mOrigRect.mRight + 1; delta_pixels = width - mThickness - mOrigRect.mRight + 1;
} }
mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels; mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels;
mThumbRect.mRight = mOrigRect.mRight + delta_pixels; mThumbRect.mRight = mOrigRect.mRight + delta_pixels;
S32 thumb_length = mThumbRect.getWidth(); S32 thumb_length = mThumbRect.getWidth();
S32 thumb_track_length = width - 2 * SCROLLBAR_SIZE; S32 thumb_track_length = width - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged) if( delta_pixels != mLastDelta || mDocChanged)
{ {
@@ -386,7 +390,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{ {
S32 variable_lines = getDocPosMax(); S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mLeft; S32 pos = mThumbRect.mLeft;
F32 ratio = F32(pos - SCROLLBAR_SIZE) / usable_track_length; F32 ratio = F32(pos - mThickness) / usable_track_length;
S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines); S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines);
@@ -405,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
} }
else else
{ {
handled = childrenHandleMouseUp( x, y, mask ) != NULL; handled = childrenHandleHover( x, y, mask ) != NULL;
} }
// Opaque // Opaque
@@ -423,8 +427,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
{ {
changeLine( clicks * mStepSize, TRUE ); BOOL handled = changeLine( clicks * mStepSize, TRUE );
return TRUE; return handled;
} }
BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -475,14 +479,14 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
if (mOrientation == VERTICAL) if (mOrientation == VERTICAL)
{ {
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE)); up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE)); down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight()); up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
} }
else else
{ {
up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight()); up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight()); down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom); down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
} }
updateThumbRect(); updateThumbRect();
@@ -513,10 +517,10 @@ void LLScrollbar::draw()
if (!rounded_rect_imagep) if (!rounded_rect_imagep)
{ {
gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(),
mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE); mOrientation == VERTICAL ? mThickness : 0, mTrackColor, TRUE);
gl_rect_2d(mThumbRect, mThumbColor, TRUE); gl_rect_2d(mThumbRect, mThumbColor, TRUE);
@@ -560,9 +564,9 @@ void LLScrollbar::draw()
} // end draw } // end draw
void LLScrollbar::changeLine( S32 delta, BOOL update_thumb ) bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
{ {
setDocPos(mDocPos + delta, update_thumb); return setDocPos(mDocPos + delta, update_thumb);
} }
void LLScrollbar::setValue(const LLSD& value) void LLScrollbar::setValue(const LLSD& value)

View File

@@ -82,7 +82,7 @@ public:
// How many "lines" the "document" has scrolled. // How many "lines" the "document" has scrolled.
// 0 <= DocPos <= DocSize - DocVisibile // 0 <= DocPos <= DocSize - DocVisibile
void setDocPos( S32 pos, BOOL update_thumb = TRUE ); bool setDocPos( S32 pos, BOOL update_thumb = TRUE );
S32 getDocPos() const { return mDocPos; } S32 getDocPos() const { return mDocPos; }
BOOL isAtBeginning(); BOOL isAtBeginning();
@@ -113,7 +113,7 @@ public:
private: private:
void updateThumbRect(); void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb ); bool changeLine(S32 delta, BOOL update_thumb );
void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata ); void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata );
void* mCallbackUserData; void* mCallbackUserData;
@@ -142,6 +142,7 @@ private:
void (*mOnScrollEndCallback)(void*); void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData; void *mOnScrollEndData;
S32 mThickness;
}; };

View File

@@ -69,52 +69,31 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
BOOL is_opaque, BOOL is_opaque,
const LLColor4& bg_color ) : const LLColor4& bg_color ) :
LLUICtrl( name, rect, FALSE, NULL, NULL ), LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_view ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ), mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f ) mAutoScrollRate( 0.f ),
mBackgroundColor( bg_color ),
mIsOpaque( is_opaque ),
mHideScrollbar( FALSE ),
mReserveScrollCorner( FALSE ),
mMinAutoScrollRate( MIN_AUTO_SCROLL_RATE ),
mMaxAutoScrollRate( MAX_AUTO_SCROLL_RATE ),
mScrolledView( scrolled_view )
{ {
if( mScrolledView ) if( mScrolledView )
{ {
addChild( mScrolledView ); LLView::addChild( mScrolledView );
} }
init(); S32 scrollbar_size = SCROLLBAR_SIZE;
}
// LLUICtrl constructor
LLScrollableContainerView::LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque,
const LLColor4& bg_color) :
LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_ctrl ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f )
{
if( scrolled_ctrl )
{
addChild( scrolled_ctrl );
}
init();
}
void LLScrollableContainerView::init()
{
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN ); mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN );
addChild( mBorder ); LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() ); mInnerRect.stretch( -getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect; LLRect vertical_scroll_rect = mInnerRect;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE; vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"), mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"),
vertical_scroll_rect, vertical_scroll_rect,
LLScrollbar::VERTICAL, LLScrollbar::VERTICAL,
@@ -123,14 +102,14 @@ void LLScrollableContainerView::init()
mInnerRect.getHeight(), mInnerRect.getHeight(),
NULL, this, NULL, this,
VERTICAL_MULTIPLE); VERTICAL_MULTIPLE);
addChild( mScrollbar[VERTICAL] ); LLView::addChild( mScrollbar[VERTICAL] );
mScrollbar[VERTICAL]->setVisible( FALSE ); mScrollbar[VERTICAL]->setVisible( FALSE );
mScrollbar[VERTICAL]->setFollowsRight(); mScrollbar[VERTICAL]->setFollowsRight();
mScrollbar[VERTICAL]->setFollowsTop(); mScrollbar[VERTICAL]->setFollowsTop();
mScrollbar[VERTICAL]->setFollowsBottom(); mScrollbar[VERTICAL]->setFollowsBottom();
LLRect horizontal_scroll_rect = mInnerRect; LLRect horizontal_scroll_rect = mInnerRect;
horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE; horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size;
mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"), mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"),
horizontal_scroll_rect, horizontal_scroll_rect,
LLScrollbar::HORIZONTAL, LLScrollbar::HORIZONTAL,
@@ -139,7 +118,7 @@ void LLScrollableContainerView::init()
mInnerRect.getWidth(), mInnerRect.getWidth(),
NULL, this, NULL, this,
HORIZONTAL_MULTIPLE); HORIZONTAL_MULTIPLE);
addChild( mScrollbar[HORIZONTAL] ); LLView::addChild( mScrollbar[HORIZONTAL] );
mScrollbar[HORIZONTAL]->setVisible( FALSE ); mScrollbar[HORIZONTAL]->setVisible( FALSE );
mScrollbar[HORIZONTAL]->setFollowsLeft(); mScrollbar[HORIZONTAL]->setFollowsLeft();
mScrollbar[HORIZONTAL]->setFollowsRight(); mScrollbar[HORIZONTAL]->setFollowsRight();
@@ -190,8 +169,8 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
{ {
LLUICtrl::reshape( width, height, called_from_parent ); LLUICtrl::reshape( width, height, called_from_parent );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect = getLocalRect();
mInnerRect.stretch( -mBorder->getBorderWidth() ); mInnerRect.stretch( -getBorderWidth() );
if (mScrolledView) if (mScrolledView)
{ {
@@ -201,22 +180,33 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
S32 visible_height = 0; S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE; BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE;
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height ); mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width ); mScrollbar[HORIZONTAL]->setPageSize( visible_width );
updateScroll();
} }
} }
BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask) BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
{ {
// allow scrolled view to handle keystrokes in case it delegated keyboard focus
// to the scroll container.
// NOTE: this should not recurse indefinitely as handleKeyHere
// should not propagate to parent controls, so mScrolledView should *not*
// call LLScrollContainer::handleKeyHere in turn
if (mScrolledView && mScrolledView->handleKeyHere(key, mask))
{
return TRUE;
}
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{ {
if( mScrollbar[i]->handleKeyHere(key, mask) ) if( mScrollbar[i]->handleKeyHere(key, mask) )
{ {
updateScroll();
return TRUE; return TRUE;
} }
} }
@@ -226,38 +216,37 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
{ {
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) // Give event to my child views - they may have scroll bars
{ // (Bad UI design, but technically possible.)
// Note: tries vertical and then horizontal if (LLUICtrl::handleScrollWheel(x,y,clicks))
return TRUE;
// When the vertical scrollbar is visible, scroll wheel
// only affects vertical scrolling. It's confusing to have
// scroll wheel perform both vertical and horizontal in a
// single container.
LLScrollbar* vertical = mScrollbar[VERTICAL];
if (vertical->getVisible()
&& vertical->getEnabled())
{
// Pretend the mouse is over the scrollbar // Pretend the mouse is over the scrollbar
if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) if (vertical->handleScrollWheel( 0, 0, clicks ) )
{ {
return TRUE; updateScroll();
} }
// Always eat the event
return TRUE;
} }
// Eat scroll wheel event (to avoid scrolling nested containers?) LLScrollbar* horizontal = mScrollbar[HORIZONTAL];
return TRUE; // Test enablement and visibility for consistency with
} // LLView::childrenHandleScrollWheel().
if (horizontal->getVisible()
BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const && horizontal->getEnabled()
{ && horizontal->handleScrollWheel( 0, 0, clicks ) )
if(mScrollbar[axis]->getVisible())
{ {
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); updateScroll();
const S32 AUTOSCROLL_SIZE = 10; return TRUE;
if(mScrollbar[axis]->getVisible())
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
inner_rect_local.mTop += AUTOSCROLL_SIZE;
inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
}
if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
{
return TRUE;
}
} }
return FALSE; return FALSE;
} }
@@ -269,65 +258,10 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept, EAcceptance* accept,
std::string& tooltip_msg) std::string& tooltip_msg)
{ {
//S32 scrollbar_size = SCROLLBAR_SIZE;
// Scroll folder view if needed. Never accepts a drag or drop. // Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO; *accept = ACCEPT_NO;
BOOL handled = FALSE; BOOL handled = autoScroll(x, y);
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
const S32 AUTOSCROLL_SIZE = 10;
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += SCROLLBAR_SIZE;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
}
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = inner_rect_local;
left_scroll_rect.mRight = AUTOSCROLL_SIZE;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect right_scroll_rect = inner_rect_local;
right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = inner_rect_local;
bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect top_scroll_rect = inner_rect_local;
top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
}
if( !handled ) if( !handled )
{ {
@@ -338,6 +272,78 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
return TRUE; return TRUE;
} }
bool LLScrollableContainerView::autoScroll(S32 x, S32 y)
{
S32 scrollbar_size = SCROLLBAR_SIZE;
bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
LLRect screen_local_extents;
screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += scrollbar_size;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= scrollbar_size;
}
// clip rect against root view
inner_rect_local.intersectWith(screen_local_extents);
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
// autoscroll region should take up no more than one third of visible scroller area
S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10);
S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10);
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = screen_local_extents;
left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect right_scroll_rect = screen_local_extents;
right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = screen_local_extents;
bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect top_scroll_rect = screen_local_extents;
top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
}
return scrolling;
}
BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
{ {
@@ -368,42 +374,44 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LL
void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{ {
const LLRect& rect = mScrolledView->getRect(); const LLRect& doc_rect = getScrolledViewRect();
calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); S32 scrollbar_size = SCROLLBAR_SIZE;
}
void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
S32 doc_width = doc_rect.getWidth(); S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight(); S32 doc_height = doc_rect.getHeight();
*visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth(); S32 border_width = getBorderWidth();
*visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth(); *visible_width = getRect().getWidth() - 2 * border_width;
*visible_height = getRect().getHeight() - 2 * border_width;
*show_v_scrollbar = FALSE; *show_v_scrollbar = FALSE;
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
*visible_width -= SCROLLBAR_SIZE;
}
*show_h_scrollbar = FALSE; *show_h_scrollbar = FALSE;
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= SCROLLBAR_SIZE;
// Must retest now that visible_height has changed if (!mHideScrollbar)
if( !*show_v_scrollbar && (*visible_height < doc_height) ) {
if( *visible_height < doc_height )
{ {
*show_v_scrollbar = TRUE; *show_v_scrollbar = TRUE;
*visible_width -= SCROLLBAR_SIZE; *visible_width -= scrollbar_size;
}
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
} }
} }
} }
void LLScrollableContainerView::draw() void LLScrollableContainerView::draw()
{ {
S32 scrollbar_size = SCROLLBAR_SIZE;
if (mAutoScrolling) if (mAutoScrolling)
{ {
// add acceleration to autoscroll // add acceleration to autoscroll
@@ -411,76 +419,79 @@ void LLScrollableContainerView::draw()
} }
else else
{ {
// reset to minimum // reset to minimum for next time
mAutoScrollRate = MIN_AUTO_SCROLL_RATE; mAutoScrollRate = mMinAutoScrollRate;
} }
// clear this flag to be set on next call to handleDragAndDrop // clear this flag to be set on next call to autoScroll
mAutoScrolling = FALSE; mAutoScrolling = FALSE;
// auto-focus when scrollbar active // auto-focus when scrollbar active
// this allows us to capture user intent (i.e. stop automatically scrolling the view/etc) // this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
if (!gFocusMgr.childHasKeyboardFocus(this) && if (!hasFocus()
(mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture())) && (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
{ {
focusFirstItem(); focusFirstItem();
} }
// Draw background if (getRect().isValid())
if( mIsOpaque )
{ {
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Draw background
gGL.color4fv( mBackgroundColor.mV ); if( mIsOpaque )
gl_rect_2d( mInnerRect ); {
} gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
// Draw mScrolledViews and update scroll bars. // Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The // get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds // scissor region ensures that we don't draw outside of the bounds
// of the rectangle. // of the rectangle.
if( mScrolledView ) if( mScrolledView )
{
updateScroll();
// Draw the scrolled area.
{ {
S32 visible_width = 0; updateScroll();
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft, // Draw the scrolled area.
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height, {
visible_width, S32 visible_width = 0;
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) S32 visible_height = 0;
)); BOOL show_v_scrollbar = FALSE;
drawChild(mScrolledView); BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
}
} }
}
// Highlight border if a child of this container has keyboard focus // Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() ) if( mBorder->getVisible() )
{ {
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
} }
// Draw all children except mScrolledView // Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code // Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin(); for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter) child_iter != getChildList()->rend(); ++child_iter)
{
LLView *viewp = *child_iter;
if( sDebugRects )
{ {
sDepth++; LLView *viewp = *child_iter;
} if( sDebugRects )
if( (viewp != mScrolledView) && viewp->getVisible() ) {
{ sDepth++;
drawChild(viewp); }
} if( (viewp != mScrolledView) && viewp->getVisible() )
if( sDebugRects ) {
{ drawChild(viewp);
sDepth--; }
if( sDebugRects )
{
sDepth--;
}
} }
} }
@@ -491,8 +502,30 @@ void LLScrollableContainerView::draw()
} // end draw } // end draw
bool LLScrollableContainerView::addChild(LLView* view, S32 tab_group)
{
if (!mScrolledView)
{
// Use the first panel or container as the scrollable view (bit of a hack)
mScrolledView = view;
}
bool ret_val = LLView::addChild(view, tab_group);
//bring the scrollbars to the front
sendChildToFront( mScrollbar[HORIZONTAL] );
sendChildToFront( mScrollbar[VERTICAL] );
return ret_val;
}
void LLScrollableContainerView::updateScroll() void LLScrollableContainerView::updateScroll()
{ {
if (!mScrolledView)
{
return;
}
S32 scrollbar_size = SCROLLBAR_SIZE;
LLRect doc_rect = mScrolledView->getRect(); LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth(); S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight(); S32 doc_height = doc_rect.getHeight();
@@ -500,9 +533,9 @@ void LLScrollableContainerView::updateScroll()
S32 visible_height = 0; S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE; BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE;
calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth(); S32 border_width = getBorderWidth();
if( show_v_scrollbar ) if( show_v_scrollbar )
{ {
if( doc_rect.mTop < getRect().getHeight() - border_width ) if( doc_rect.mTop < getRect().getHeight() - border_width )
@@ -516,15 +549,15 @@ void LLScrollableContainerView::updateScroll()
S32 v_scrollbar_height = visible_height; S32 v_scrollbar_height = visible_height;
if( !show_h_scrollbar && mReserveScrollCorner ) if( !show_h_scrollbar && mReserveScrollCorner )
{ {
v_scrollbar_height -= SCROLLBAR_SIZE; v_scrollbar_height -= scrollbar_size;
} }
mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE ); mScrollbar[VERTICAL]->reshape( scrollbar_size, v_scrollbar_height, TRUE );
// Make room for the horizontal scrollbar (or not) // Make room for the horizontal scrollbar (or not)
S32 v_scrollbar_offset = 0; S32 v_scrollbar_offset = 0;
if( show_h_scrollbar || mReserveScrollCorner ) if( show_h_scrollbar || mReserveScrollCorner )
{ {
v_scrollbar_offset = SCROLLBAR_SIZE; v_scrollbar_offset = scrollbar_size;
} }
LLRect r = mScrollbar[VERTICAL]->getRect(); LLRect r = mScrollbar[VERTICAL]->getRect();
r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset ); r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset );
@@ -554,9 +587,9 @@ void LLScrollableContainerView::updateScroll()
S32 h_scrollbar_width = visible_width; S32 h_scrollbar_width = visible_width;
if( !show_v_scrollbar && mReserveScrollCorner ) if( !show_v_scrollbar && mReserveScrollCorner )
{ {
h_scrollbar_width -= SCROLLBAR_SIZE; h_scrollbar_width -= scrollbar_size;
} }
mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE ); mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, scrollbar_size, TRUE );
} }
else else
{ {
@@ -576,101 +609,115 @@ void LLScrollableContainerView::updateScroll()
void LLScrollableContainerView::setBorderVisible(BOOL b) void LLScrollableContainerView::setBorderVisible(BOOL b)
{ {
mBorder->setVisible( b ); mBorder->setVisible( b );
// Recompute inner rect, as border visibility changes it
mInnerRect = getLocalRect();
mInnerRect.stretch( -getBorderWidth() );
} }
// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled) LLRect LLScrollableContainerView::getVisibleContentRect()
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset) {
updateScroll();
LLRect visible_rect = getContentWindowRect();
LLRect contents_rect = mScrolledView->getRect();
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
return visible_rect;
}
LLRect LLScrollableContainerView::getContentWindowRect()
{
updateScroll();
LLRect scroller_view_rect;
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_h_scrollbar = FALSE;
BOOL show_v_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = getBorderWidth();
scroller_view_rect.setOriginAndSize(border_width,
show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
visible_width,
visible_height);
return scroller_view_rect;
}
// rect is in document coordinates, constraint is in display coordinates relative to content window rect
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
{ {
if (!mScrolledView) if (!mScrolledView)
{ {
llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl; llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl;
return; return;
} }
S32 visible_width = 0; LLRect content_window_rect = getContentWindowRect();
S32 visible_height = 0; // get document rect
BOOL show_v_scrollbar = FALSE; LLRect scrolled_rect = mScrolledView->getRect();
BOOL show_h_scrollbar = FALSE;
const LLRect& scrolled_rect = mScrolledView->getRect();
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
// can't be so far left that right side of rect goes off screen, or so far right that left side does // shrink target rect to fit within constraint region, biasing towards top left
S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0); LLRect rect_to_constrain = rect;
// can't be so high that bottom of rect goes off screen, or so low that top does rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight());
S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight())); rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth());
// Vertical // calculate allowable positions for scroller window in document coordinates
// 1. First make sure the top is visible LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight,
// 2. Then, if possible without hiding the top, make the bottom visible. rect_to_constrain.mBottom - constraint.mBottom,
S32 vert_pos = mScrollbar[VERTICAL]->getDocPos(); rect_to_constrain.mLeft - constraint.mLeft,
rect_to_constrain.mTop - constraint.mTop);
// find scrollbar position to get top of rect on screen (scrolling up) // translate from allowable region for lower left corner to upper left corner
S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset; allowable_scroll_rect.translate(0, content_window_rect.getHeight());
// find scrollbar position to get bottom of rect on screen (scrolling down)
S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset; S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(),
// scroll up far enough to see top or scroll down just enough if item is bigger than visual area mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll
if( vert_pos >= top_offset || visible_height < rect.getHeight()) mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll
{
vert_pos = top_offset;
}
// else scroll down far enough to see bottom
else
if( vert_pos <= bottom_offset )
{
vert_pos = bottom_offset;
}
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height ); mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() );
mScrollbar[VERTICAL]->setDocPos( vert_pos ); mScrollbar[VERTICAL]->setDocPos( vert_pos );
// Horizontal S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(),
// 1. First make sure left side is visible allowable_scroll_rect.mLeft,
// 2. Then, if possible without hiding the left side, make the right side visible. allowable_scroll_rect.mRight);
S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos();
S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset;
S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset;
if( horiz_pos >= left_offset || visible_width < rect.getWidth() )
{
horiz_pos = left_offset;
}
else if( horiz_pos <= right_offset )
{
horiz_pos = right_offset;
}
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width ); mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() );
mScrollbar[HORIZONTAL]->setDocPos( horiz_pos ); mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos );
// propagate scroll to document // propagate scroll to document
updateScroll(); updateScroll();
// In case we are in accordion tab notify parent to show selected rectangle
LLRect screen_rc;
localRectToScreen(rect_to_constrain, &screen_rc);
notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
} }
void LLScrollableContainerView::pageUp(S32 overlap) void LLScrollableContainerView::pageUp(S32 overlap)
{ {
mScrollbar[VERTICAL]->pageUp(overlap); mScrollbar[VERTICAL]->pageUp(overlap);
updateScroll();
} }
void LLScrollableContainerView::pageDown(S32 overlap) void LLScrollableContainerView::pageDown(S32 overlap)
{ {
mScrollbar[VERTICAL]->pageDown(overlap); mScrollbar[VERTICAL]->pageDown(overlap);
updateScroll();
} }
void LLScrollableContainerView::goToTop() void LLScrollableContainerView::goToTop()
{ {
mScrollbar[VERTICAL]->setDocPos(0); mScrollbar[VERTICAL]->setDocPos(0);
updateScroll();
} }
void LLScrollableContainerView::goToBottom() void LLScrollableContainerView::goToBottom()
{ {
mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
updateScroll();
} }
S32 LLScrollableContainerView::getBorderWidth() const S32 LLScrollableContainerView::getBorderWidth() const
{ {
if (mBorder) if (mBorder && mBorder->getVisible())
{ {
return mBorder->getBorderWidth(); return mBorder->getBorderWidth();
} }

View File

@@ -63,30 +63,29 @@ public:
LLScrollableContainerView( const std::string& name, const LLRect& rect, LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLView* scrolled_view, BOOL is_opaque = FALSE, LLView* scrolled_view, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) ); const LLColor4& bg_color = LLColor4(0,0,0,0) );
LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) );
virtual ~LLScrollableContainerView( void ); virtual ~LLScrollableContainerView( void );
void setScrolledView(LLView* view) { mScrolledView = view; } void setScrolledView(LLView* view) { mScrolledView = view; }
virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); } virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void setBorderVisible( BOOL b ); void setBorderVisible( BOOL b );
void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset ); void scrollToShowRect( const LLRect& rect, const LLRect& constraint);
void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); }
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; } void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
const LLRect& getScrolledViewRect() const { return mScrolledView->getRect(); } LLRect getVisibleContentRect();
LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0); void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0); void pageDown(S32 overlap = 0);
void goToTop(); void goToTop();
void goToBottom(); void goToBottom();
bool isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); }
bool isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); }
S32 getBorderWidth() const; S32 getBorderWidth() const;
BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const;
// LLView functionality // LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -99,8 +98,10 @@ public:
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual void draw(); virtual void draw();
virtual bool addChild(LLView* view, S32 tab_group = 0);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
bool autoScroll(S32 x, S32 y);
virtual LLXMLNodePtr getXML(bool save_children) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
private: private:
@@ -110,6 +111,9 @@ private:
virtual void scrollHorizontal( S32 new_pos ); virtual void scrollHorizontal( S32 new_pos );
virtual void scrollVertical( S32 new_pos ); virtual void scrollVertical( S32 new_pos );
void updateScroll(); void updateScroll();
public:
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
private:
LLScrollbar* mScrollbar[SCROLLBAR_COUNT]; LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView; LLView* mScrolledView;
@@ -121,6 +125,9 @@ private:
BOOL mReserveScrollCorner; BOOL mReserveScrollCorner;
BOOL mAutoScrolling; BOOL mAutoScrolling;
F32 mAutoScrollRate; F32 mAutoScrollRate;
F32 mMinAutoScrollRate;
F32 mMaxAutoScrollRate;
bool mHideScrollbar;
}; };

View File

@@ -52,7 +52,7 @@ void LLScrollingPanelList::clearPanels()
void LLScrollingPanelList::addPanel( LLScrollingPanel* panel ) void LLScrollingPanelList::addPanel( LLScrollingPanel* panel )
{ {
addChildAtEnd( panel ); addChildInBack( panel );
mPanelList.push_front( panel ); mPanelList.push_front( panel );
const S32 GAP_BETWEEN_PANELS = 6; const S32 GAP_BETWEEN_PANELS = 6;

View File

@@ -117,7 +117,11 @@ LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width)
LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width) LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width)
: LLScrollListCell(width), : LLScrollListCell(width),
mColor(LLColor4::white) // <edit>
mCallback(NULL),
mUserData(NULL),
// </edit>
mColor(LLColor4::white)
{ {
setValue(value); setValue(value);
} }
@@ -637,6 +641,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data), : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data),
mLineHeight(0), mLineHeight(0),
mScrollLines(0), mScrollLines(0),
mMouseWheelOpaque(true),
mPageLines(0), mPageLines(0),
mHeadingHeight(20), mHeadingHeight(20),
mMaxSelectable(0), mMaxSelectable(0),
@@ -745,11 +750,6 @@ S32 LLScrollListCtrl::getSearchColumn()
LLScrollListCtrl::~LLScrollListCtrl() LLScrollListCtrl::~LLScrollListCtrl()
{ {
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
} }
@@ -1951,6 +1951,12 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
BOOL handled = FALSE; BOOL handled = FALSE;
// Pretend the mouse is over the scrollbar // Pretend the mouse is over the scrollbar
handled = mScrollbar->handleScrollWheel( 0, 0, clicks ); handled = mScrollbar->handleScrollWheel( 0, 0, clicks );
if (mMouseWheelOpaque)
{
return TRUE;
}
return handled; return handled;
} }
@@ -2129,6 +2135,8 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
mSelectionChanged = FALSE; mSelectionChanged = FALSE;
handleClick(x, y, mask); handleClick(x, y, mask);
setFocus(TRUE);
} }
return TRUE; return TRUE;
@@ -2843,6 +2851,8 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
node->createChild("draw_stripes", TRUE)->setBoolValue(mDrawStripes); node->createChild("draw_stripes", TRUE)->setBoolValue(mDrawStripes);
node->createChild("column_padding", TRUE)->setIntValue(mColumnPadding); node->createChild("column_padding", TRUE)->setIntValue(mColumnPadding);
node->createChild("mouse_wheel_opaque", TRUE)->setBoolValue(mMouseWheelOpaque);
addColorXML(node, mBgWriteableColor, "bg_writeable_color", "ScrollBgWriteableColor"); addColorXML(node, mBgWriteableColor, "bg_writeable_color", "ScrollBgWriteableColor");
addColorXML(node, mBgReadOnlyColor, "bg_read_only_color", "ScrollBgReadOnlyColor"); addColorXML(node, mBgReadOnlyColor, "bg_read_only_color", "ScrollBgReadOnlyColor");
@@ -2970,6 +2980,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
BOOL sort_ascending = TRUE; BOOL sort_ascending = TRUE;
node->getAttributeBOOL("sort_ascending", sort_ascending); node->getAttributeBOOL("sort_ascending", sort_ascending);
BOOL mouse_wheel_opaque = TRUE;
node->getAttributeBOOL("mouse_wheel_opaque", mouse_wheel_opaque);
LLUICtrlCallback callback = NULL; LLUICtrlCallback callback = NULL;
@@ -2994,6 +3007,8 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
scroll_list->initFromXML(node, parent); scroll_list->initFromXML(node, parent);
scroll_list->setSearchColumn(search_column); scroll_list->setSearchColumn(search_column);
scroll_list->mMouseWheelOpaque = mouse_wheel_opaque;
LLSD columns; LLSD columns;
S32 index = 0; S32 index = 0;
@@ -3684,9 +3699,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS
mButton->setTabStop(FALSE); mButton->setTabStop(FALSE);
// require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate // require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate
mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2); mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2);
mButton->setHeldDownCallback(onHeldDown); mButton->setHeldDownCallback(boost::bind(&LLColumnHeader::onHeldDown, this));
mButton->setClickedCallback(onClick); mButton->setClickedCallback(boost::bind(&LLColumnHeader::onClick, this));
mButton->setMouseDownCallback(onMouseDown); mButton->setMouseDownCallback(boost::bind(&LLColumnHeader::onMouseDown, this));
mButton->setCallbackUserData(this); mButton->setCallbackUserData(this);
mButton->setToolTip(label); mButton->setToolTip(label);
@@ -3848,8 +3863,8 @@ void LLColumnHeader::setImage(const std::string &image_name)
{ {
if (mButton) if (mButton)
{ {
mButton->setImageSelected(image_name); mButton->setImageSelected(LLUI::getUIImage(image_name));
mButton->setImageUnselected(image_name); mButton->setImageUnselected(LLUI::getUIImage(image_name));
} }
} }
@@ -3885,6 +3900,8 @@ void LLColumnHeader::onClick(void* user_data)
// propagate new sort order to sort order list // propagate new sort order to sort order list
headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1); headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
headerp->mList->setFocus(TRUE);
} }
//static //static

View File

@@ -671,6 +671,7 @@ private:
BOOL mCommitOnSelectionChange; BOOL mCommitOnSelectionChange;
BOOL mSelectionChanged; BOOL mSelectionChanged;
BOOL mNeedsScroll; BOOL mNeedsScroll;
BOOL mMouseWheelOpaque;
BOOL mCanSelect; BOOL mCanSelect;
BOOL mDisplayColumnHeaders; BOOL mDisplayColumnHeaders;
BOOL mColumnsDirty; BOOL mColumnsDirty;

View File

@@ -121,7 +121,7 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
&LLLineEditor::prevalidateFloat ); &LLLineEditor::prevalidateFloat );
mEditor->setFollowsLeft(); mEditor->setFollowsLeft();
mEditor->setFollowsBottom(); mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this ); mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onFocusReceived, this) );
mEditor->setIgnoreTab(TRUE); mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases // don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others // and double clicking in others
@@ -140,17 +140,6 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
updateText(); updateText();
} }
// static
void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLSliderCtrl* self = (LLSliderCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLSliderCtrl::setValue(F32 v, BOOL from_event) void LLSliderCtrl::setValue(F32 v, BOOL from_event)
{ {
mSlider->setValue( v, from_event ); mSlider->setValue( v, from_event );

View File

@@ -117,7 +117,6 @@ public:
static void onSliderCommit(LLUICtrl* caller, void* userdata); static void onSliderCommit(LLUICtrl* caller, void* userdata);
static void onEditorCommit(LLUICtrl* caller, void* userdata); static void onEditorCommit(LLUICtrl* caller, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
private: private:

View File

@@ -101,7 +101,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLSpinCtrl::onUpBtn, this, LLFontGL::getFontSansSerif() ); &LLSpinCtrl::onUpBtn, this, LLFontGL::getFontSansSerif() );
mUpBtn->setFollowsLeft(); mUpBtn->setFollowsLeft();
mUpBtn->setFollowsBottom(); mUpBtn->setFollowsBottom();
mUpBtn->setHeldDownCallback( &LLSpinCtrl::onUpBtn ); mUpBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onUpBtn,this));
mUpBtn->setTabStop(FALSE); mUpBtn->setTabStop(FALSE);
addChild(mUpBtn); addChild(mUpBtn);
@@ -115,7 +115,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLSpinCtrl::onDownBtn, this, LLFontGL::getFontSansSerif() ); &LLSpinCtrl::onDownBtn, this, LLFontGL::getFontSansSerif() );
mDownBtn->setFollowsLeft(); mDownBtn->setFollowsLeft();
mDownBtn->setFollowsBottom(); mDownBtn->setFollowsBottom();
mDownBtn->setHeldDownCallback( &LLSpinCtrl::onDownBtn ); mDownBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onDownBtn,this));
mDownBtn->setTabStop(FALSE); mDownBtn->setTabStop(FALSE);
addChild(mDownBtn); addChild(mDownBtn);
@@ -126,7 +126,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLLineEditor::prevalidateASCII ); &LLLineEditor::prevalidateASCII );
mEditor->setFollowsLeft(); mEditor->setFollowsLeft();
mEditor->setFollowsBottom(); mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this ); mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onFocusReceived, this) );
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus //RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text, // than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand // it's easier to understand
@@ -243,15 +243,6 @@ void LLSpinCtrl::onDownBtn( void *userdata )
} }
} }
// static
void LLSpinCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLSpinCtrl* self = (LLSpinCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLSpinCtrl::setValue(const LLSD& value ) void LLSpinCtrl::setValue(const LLSD& value )
{ {
F32 v = (F32)value.asReal(); F32 v = (F32)value.asReal();

View File

@@ -110,7 +110,6 @@ public:
virtual void draw(); virtual void draw();
static void onEditorCommit(LLUICtrl* caller, void* userdata); static void onEditorCommit(LLUICtrl* caller, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
static void onUpBtn(void *userdata); static void onUpBtn(void *userdata);

View File

@@ -803,7 +803,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
LLStringUtil::null, LLStringUtil::null,
LLStringUtil::null, LLStringUtil::null,
LLStringUtil::null, LLStringUtil::null,
&LLTabContainer::onTabBtn, NULL, NULL, NULL,
font, font,
trimmed_label, trimmed_label); trimmed_label, trimmed_label);
btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga")); btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga"));
@@ -825,7 +825,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
btn = new LLButton(std::string(child->getName()) + " tab", btn = new LLButton(std::string(child->getName()) + " tab",
btn_rect, btn_rect,
LLStringUtil::null, LLStringUtil::null, LLStringUtil::null, LLStringUtil::null, LLStringUtil::null, LLStringUtil::null,
&LLTabContainer::onTabBtn, NULL, // set userdata below NULL, NULL, // set userdata below
font, font,
trimmed_label, trimmed_label ); trimmed_label, trimmed_label );
btn->setVisible( FALSE ); btn->setVisible( FALSE );
@@ -865,7 +865,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
if (btn) if (btn)
{ {
btn->setSaveToXML(false); btn->setSaveToXML(false);
btn->setCallbackUserData( tuple ); btn->setClickedCallback(&LLTabContainer::onTabBtn, tuple);
addChild( btn, 0 ); addChild( btn, 0 );
} }
if (child) if (child)
@@ -1682,7 +1682,7 @@ void LLTabContainer::initButtons()
mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect, mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect,
out_id, in_id, LLStringUtil::null, out_id, in_id, LLStringUtil::null,
&LLTabContainer::onPrevBtn, this, LLFontGL::getFontSansSerif() ); &LLTabContainer::onPrevBtn, this, LLFontGL::getFontSansSerif() );
mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); mPrevArrowBtn->setHeldDownCallback(boost::bind(LLTabContainer::onPrevBtnHeld, this));
mPrevArrowBtn->setFollowsLeft(); mPrevArrowBtn->setFollowsLeft();
out_id = "UIImgBtnJumpRightOutUUID"; out_id = "UIImgBtnJumpRightOutUUID";
@@ -1717,12 +1717,12 @@ void LLTabContainer::initButtons()
} }
} }
mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); mPrevArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onPrevBtnHeld, this));
mPrevArrowBtn->setSaveToXML(false); mPrevArrowBtn->setSaveToXML(false);
mPrevArrowBtn->setTabStop(FALSE); mPrevArrowBtn->setTabStop(FALSE);
addChild(mPrevArrowBtn); addChild(mPrevArrowBtn);
mNextArrowBtn->setHeldDownCallback(onNextBtnHeld); mNextArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onNextBtnHeld, this));
mNextArrowBtn->setSaveToXML(false); mNextArrowBtn->setSaveToXML(false);
mNextArrowBtn->setTabStop(FALSE); mNextArrowBtn->setTabStop(FALSE);
addChild(mNextArrowBtn); addChild(mNextArrowBtn);

View File

@@ -356,12 +356,12 @@ LLTextEditor::LLTextEditor(
{ {
menu = new LLMenuGL(LLStringUtil::null); menu = new LLMenuGL(LLStringUtil::null);
}*/ }*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this)); menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this)); menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this)); menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this)); menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->appendSeparator("Spelsep"); menu->addSeparator();
menu->setCanTearOff(FALSE); menu->setCanTearOff(FALSE);
menu->setVisible(FALSE); menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle(); mPopupMenuHandle = menu->getHandle();
@@ -372,18 +372,12 @@ LLTextEditor::~LLTextEditor()
{ {
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
// Route menu back to the default
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
// Scrollbar is deleted by LLView // Scrollbar is deleted by LLView
mHoverSegment = NULL; mHoverSegment = NULL;
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
LLView::deleteViewByHandle(mPopupMenuHandle); //LLView::deleteViewByHandle(mPopupMenuHandle);
} }
void LLTextEditor::context_cut(void* data) void LLTextEditor::context_cut(void* data)
{ {
@@ -1283,7 +1277,8 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_
BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
{ {
// Pretend the mouse is over the scrollbar // Pretend the mouse is over the scrollbar
return mScrollbar->handleScrollWheel( 0, 0, clicks ); mScrollbar->handleScrollWheel( 0, 0, clicks );
return TRUE;
} }
BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1389,7 +1384,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
SpellMenuBind * tempBind = suggestionMenuItems[i]; SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind) if(tempBind)
{ {
menu->remove(tempBind->menuItem); menu->removeChild(tempBind->menuItem);
tempBind->menuItem->die(); tempBind->menuItem->die();
//delete tempBind->menuItem; //delete tempBind->menuItem;
//tempBind->menuItem = NULL; //tempBind->menuItem = NULL;
@@ -1425,7 +1420,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
tempStruct->word, spell_correct, NULL, tempStruct); tempStruct->word, spell_correct, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem; tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct); suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem); menu->addChild(suggMenuItem);
} }
SpellMenuBind * tempStruct = new SpellMenuBind; SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this; tempStruct->origin = this;
@@ -1437,7 +1432,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
"Add Word", spell_add, NULL, tempStruct); "Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem; tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct); suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem); menu->addChild(suggMenuItem);
} }
} }
@@ -1456,7 +1451,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
tempStruct->word, spell_show, NULL, tempStruct); tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem; tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct); suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem); menu->addChild(suggMenuItem);
} }
mLastContextMenuX = x; mLastContextMenuX = x;
mLastContextMenuY = y; mLastContextMenuY = y;
@@ -3246,7 +3241,7 @@ void LLTextEditor::drawCursor()
} }
// Make sure the IME is in the right place // Make sure the IME is in the right place
LLRect screen_pos = getScreenRect(); LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) ); LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);

View File

@@ -72,7 +72,11 @@ bool LLTrans::parseStrings(const std::string& xml_filename, const std::set<std::
continue; continue;
} }
LLTransTemplate xml_template(string_name, string->getTextContents()); std::string contents;
//value is used for strings with preceeding spaces. If not present, fall back to getTextContents()
if(!string->getAttributeString("value",contents))
contents=string->getTextContents();
LLTransTemplate xml_template(string_name, contents);
sStringTemplates[xml_template.mName] = xml_template; sStringTemplates[xml_template.mName] = xml_template;
std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName); std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName);

View File

@@ -42,10 +42,10 @@ static LLRegisterWidget<LLUICtrl> r("ui_ctrl");
// NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined. // NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined.
LLUICtrl::LLUICtrl() : LLUICtrl::LLUICtrl() :
mViewModel(LLViewModelPtr(new LLViewModel)),
mCommitSignal(NULL), mCommitSignal(NULL),
mValidateSignal(NULL), mValidateSignal(NULL),
mCommitCallback(NULL), mCommitCallback(NULL),
mLostTopCallback(NULL),
mValidateCallback(NULL), mValidateCallback(NULL),
mCallbackUserData(NULL), mCallbackUserData(NULL),
mTentative(FALSE), mTentative(FALSE),
@@ -63,8 +63,8 @@ LLUICtrl::LLUICtrl(const std::string& name, const LLRect& rect, BOOL mouse_opaqu
LLView( name, rect, mouse_opaque, reshape ), LLView( name, rect, mouse_opaque, reshape ),
mCommitSignal(NULL), mCommitSignal(NULL),
mValidateSignal(NULL), mValidateSignal(NULL),
mViewModel(LLViewModelPtr(new LLViewModel)),
mCommitCallback( on_commit_callback), mCommitCallback( on_commit_callback),
mLostTopCallback( NULL ),
mValidateCallback( NULL ), mValidateCallback( NULL ),
mCallbackUserData( callback_userdata ), mCallbackUserData( callback_userdata ),
mTentative( FALSE ), mTentative( FALSE ),
@@ -103,12 +103,33 @@ BOOL LLUICtrl::isCtrl() const
return TRUE; return TRUE;
} }
//virtual
void LLUICtrl::setValue(const LLSD& value)
{
mViewModel->setValue(value);
}
//virtual //virtual
LLSD LLUICtrl::getValue() const LLSD LLUICtrl::getValue() const
{ {
return LLSD(); return mViewModel->getValue();
} }
/// When two widgets are displaying the same data (e.g. during a skin
/// change), share their ViewModel.
void LLUICtrl::shareViewModelFrom(const LLUICtrl& other)
{
// Because mViewModel is an LLViewModelPtr, this assignment will quietly
// dispose of the previous LLViewModel -- unless it's already shared by
// somebody else.
mViewModel = other.mViewModel;
}
//virtual
LLViewModel* LLUICtrl::getViewModel() const
{
return mViewModel;
}
// virtual // virtual
BOOL LLUICtrl::setTextArg( const std::string& key, const LLStringExplicit& text ) BOOL LLUICtrl::setTextArg( const std::string& key, const LLStringExplicit& text )
{ {
@@ -167,58 +188,6 @@ void LLUICtrl::setFocus(BOOL b)
} }
} }
void LLUICtrl::onFocusReceived()
{
// trigger callbacks
LLFocusableElement::onFocusReceived();
// find first view in hierarchy above new focus that is a LLUICtrl
LLView* viewp = getParent();
LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus());
while (viewp && !viewp->isCtrl())
{
viewp = viewp->getParent();
}
// and if it has newly gained focus, call onFocusReceived()
LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp)))
{
ctrlp->onFocusReceived();
}
}
void LLUICtrl::onFocusLost()
{
// trigger callbacks
LLFocusableElement::onFocusLost();
// find first view in hierarchy above old focus that is a LLUICtrl
LLView* viewp = getParent();
while (viewp && !viewp->isCtrl())
{
viewp = viewp->getParent();
}
// and if it has just lost focus, call onFocusReceived()
LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
// hasFocus() includes any descendants
if (ctrlp && !ctrlp->hasFocus())
{
ctrlp->onFocusLost();
}
}
void LLUICtrl::onLostTop()
{
if (mLostTopCallback)
{
mLostTopCallback(this, mCallbackUserData);
}
}
// virtual // virtual
void LLUICtrl::setTabStop( BOOL b ) void LLUICtrl::setTabStop( BOOL b )
{ {
@@ -240,12 +209,13 @@ BOOL LLUICtrl::acceptsTextInput() const
//virtual //virtual
BOOL LLUICtrl::isDirty() const BOOL LLUICtrl::isDirty() const
{ {
return FALSE; return mViewModel->isDirty();
}; };
//virtual //virtual
void LLUICtrl::resetDirty() void LLUICtrl::resetDirty()
{ {
mViewModel->resetDirty();
} }
// virtual // virtual

View File

@@ -38,11 +38,13 @@
#include "llrect.h" #include "llrect.h"
#include "llsd.h" #include "llsd.h"
#include "llviewmodel.h" // *TODO move dependency to .cpp file
class LLUICtrl class LLUICtrl
: public LLView : public LLView
{ {
public: public:
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t; typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t; typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
@@ -56,15 +58,15 @@ public:
U32 reshape=FOLLOWS_NONE); U32 reshape=FOLLOWS_NONE);
/*virtual*/ ~LLUICtrl(); /*virtual*/ ~LLUICtrl();
// We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const;
// We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&);
// LLView interface // LLView interface
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent); /*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
/*virtual*/ BOOL isCtrl() const; /*virtual*/ BOOL isCtrl() const;
/*virtual*/ void setTentative(BOOL b);
/*virtual*/ BOOL getTentative() const;
// From LLFocusableElement // From LLFocusableElement
/*virtual*/ void setFocus( BOOL b ); /*virtual*/ void setFocus( BOOL b );
@@ -77,7 +79,14 @@ public:
virtual class LLCtrlListInterface* getListInterface(); virtual class LLCtrlListInterface* getListInterface();
virtual class LLCtrlScrollInterface* getScrollInterface(); virtual class LLCtrlScrollInterface* getScrollInterface();
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const; virtual LLSD getValue() const;
/// When two widgets are displaying the same data (e.g. during a skin
/// change), share their ViewModel.
virtual void shareViewModelFrom(const LLUICtrl& other);
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual void setIsChrome(BOOL is_chrome); virtual void setIsChrome(BOOL is_chrome);
@@ -89,7 +98,6 @@ public:
virtual void resetDirty(); //Defaults to no-op virtual void resetDirty(); //Defaults to no-op
// Call appropriate callbacks // Call appropriate callbacks
virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere
virtual void onCommit(); virtual void onCommit();
// Default to no-op: // Default to no-op:
@@ -125,7 +133,6 @@ public:
void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; } void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; }
void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; }
void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; }
static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory); static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
@@ -143,8 +150,9 @@ protected:
commit_signal_t* mCommitSignal; commit_signal_t* mCommitSignal;
enable_signal_t* mValidateSignal; enable_signal_t* mValidateSignal;
LLViewModelPtr mViewModel;
void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata ); void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata );
void (*mLostTopCallback)( LLUICtrl* ctrl, void* userdata );
BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata ); BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata );
void* mCallbackUserData; void* mCallbackUserData;

View File

@@ -38,6 +38,7 @@
#include "llcallbackmap.h" #include "llcallbackmap.h"
#include "llfloater.h" #include "llfloater.h"
#include "llinitparam.h"
class LLView; class LLView;
class LLPanel; class LLPanel;

File diff suppressed because it is too large Load Diff

View File

@@ -54,6 +54,7 @@
#include "stdenums.h" #include "stdenums.h"
#include "lluistring.h" #include "lluistring.h"
#include "llcursortypes.h" #include "llcursortypes.h"
#include "llinitparam.h"
#include "llfocusmgr.h" #include "llfocusmgr.h"
const U32 FOLLOWS_NONE = 0x00; const U32 FOLLOWS_NONE = 0x00;
@@ -68,88 +69,6 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE;
const U32 GL_NAME_UI_RESERVED = 2; const U32 GL_NAME_UI_RESERVED = 2;
/*
// virtual functions defined in LLView:
virtual BOOL isCtrl() const;
LLUICtrl
virtual BOOL isPanel();
LLPanel
virtual void setRect(const LLRect &rect);
LLLineEditor
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
virtual void removeCtrl( LLUICtrl* ctrl);
LLPanel
virtual BOOL canFocusChildren() const { return TRUE; }
LLFolderView
virtual void deleteAllChildren();
LLFolderView, LLPanelInventory
virtual void setTentative(BOOL b) {}
LLUICtrl, LLSliderCtrl, LLSpinCtrl
virtual BOOL getTentative() const { return FALSE; }
LLUICtrl, LLCheckBoxCtrl
virtual void setVisible(BOOL visible);
LLFloater, LLAlertDialog, LLMenuItemGL, LLModalDialog
virtual void setEnabled(BOOL enabled) { mEnabled = enabled; }
LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; }
LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl
virtual void handleVisibilityChange ( BOOL curVisibilityIn );
LLMenuGL
virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual
LLFloater
virtual LLRect getRequiredRect() { return mRect; }
LLScrolllistCtrl
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
LLUICtrl, et. al.
virtual void translate( S32 x, S32 y );
LLMenuGL
virtual void handleReshape(const LLRect& new_rect, bool by_user = false);
LLFloater, LLScrollLIstVtrl
virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
LLScrollListCtrl
virtual BOOL canSnapTo(const LLView* other_view) { return other_view != this && other_view->getVisible(); }
LLFloater
virtual void setSnappedTo(const LLView* snap_view) {}
LLFloater
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
*
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
*
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropType cargo_type,void* cargo_data,EAcceptance* accept,std::string& tooltip_msg);
*
virtual void draw();
*
*
virtual LLXMLNodePtr getXML(bool save_children = true) const;
*
virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
*
virtual void onFocusLost() {}
LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox
virtual void onFocusReceived() {}
LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
LLTabContainer, LLPanel, LLMenuGL
virtual void setControlName(const std::string& control, LLView *context);
LLSliderCtrl, LLCheckBoxCtrl
virtual std::string getControlName() const { return mControlName; }
LLSliderCtrl, LLCheckBoxCtrl
virtual bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
LLMenuItem
virtual void setValue(const LLSD& value);
*
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask);
*
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
*
*/
class LLUICtrlFactory; class LLUICtrlFactory;
// maps xml strings to widget classes // maps xml strings to widget classes
@@ -209,9 +128,73 @@ public:
} }
}; };
class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement class LLView
: public LLMouseHandler, // handles mouse events
public LLFocusableElement, // handles keyboard events
public LLMortician // lazy deletion
//public LLHandleProvider<LLView> // passes out weak references to self
{ {
public:
struct Follows : public LLInitParam::ChoiceBlock<Follows>
{
Alternative<std::string> string;
Alternative<U32> flags;
Follows();
};
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
Optional<bool> enabled,
visible,
mouse_opaque,
use_bounding_rect,
from_xui,
focus_root;
Optional<S32> tab_group,
default_tab_group;
Optional<std::string> tool_tip;
Optional<S32> sound_flags;
Optional<Follows> follows;
Optional<std::string> hover_cursor;
Optional<std::string> layout;
Optional<LLRect> rect;
// Historical bottom-left layout used bottom_delta and left_delta
// for relative positioning. New layout "topleft" prefers specifying
// based on top edge.
Optional<S32> bottom_delta, // from last bottom to my bottom
top_pad, // from last bottom to my top
top_delta, // from last top to my top
left_pad, // from last right to my left
left_delta; // from last left to my left
//FIXME: get parent context involved in parsing traversal
Ignored needs_translate, // cue for translation tools
xmlns, // xml namespace
xmlns_xsi, // xml namespace
xsi_schemaLocation, // xml schema
xsi_type; // xml schema type
Params();
};
void initFromParams(const LLView::Params&);
protected:
LLView(const LLView::Params&);
//friend class LLUICtrlFactory;
private:
void init(const LLView::Params&);
private:
// widgets in general are not copyable
LLView(const LLView& other) {};
public: public:
#if LL_DEBUG #if LL_DEBUG
static BOOL sIsDrawing; static BOOL sIsDrawing;
@@ -294,7 +277,9 @@ public:
void setSoundFlags(U8 flags) { mSoundFlags = flags; } void setSoundFlags(U8 flags) { mSoundFlags = flags; }
void setName(std::string name) { mName = name; } void setName(std::string name) { mName = name; }
void setUseBoundingRect( BOOL use_bounding_rect ); void setUseBoundingRect( BOOL use_bounding_rect );
BOOL getUseBoundingRect(); BOOL getUseBoundingRect() const;
ECursorType getHoverCursor() { return mHoverCursor; }
const std::string& getToolTip() const { return mToolTipMsg.getString(); } const std::string& getToolTip() const { return mToolTipMsg.getString(); }
@@ -302,15 +287,14 @@ public:
void sendChildToBack(LLView* child); void sendChildToBack(LLView* child);
void moveChildToFrontOfTabGroup(LLUICtrl* child); void moveChildToFrontOfTabGroup(LLUICtrl* child);
void moveChildToBackOfTabGroup(LLUICtrl* child); void moveChildToBackOfTabGroup(LLUICtrl* child);
virtual bool addChild(LLView* view, S32 tab_group = 0);
// implemented in terms of addChild()
bool addChildInBack(LLView* view, S32 tab_group = 0);
void addChild(LLView* view, S32 tab_group = 0);
void addChildAtEnd(LLView* view, S32 tab_group = 0);
// remove the specified child from the view, and set it's parent to NULL. // remove the specified child from the view, and set it's parent to NULL.
void removeChild(LLView* view, BOOL deleteIt = FALSE); virtual void removeChild(LLView* view);
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
virtual void removeCtrl( LLUICtrl* ctrl);
child_tab_order_t getCtrlOrder() const { return mCtrlOrder; } child_tab_order_t getCtrlOrder() const { return mCtrlOrder; }
ctrl_list_t getCtrlList() const; ctrl_list_t getCtrlList() const;
@@ -318,6 +302,7 @@ public:
void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; }
S32 getDefaultTabGroup() const { return mDefaultTabGroup; } S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
S32 getLastTabGroup() { return mLastTabGroup; }
BOOL isInVisibleChain() const; BOOL isInVisibleChain() const;
BOOL isInEnabledChain() const; BOOL isInEnabledChain() const;
@@ -336,18 +321,19 @@ public:
void setAllChildrenEnabled(BOOL b); void setAllChildrenEnabled(BOOL b);
virtual void setVisible(BOOL visible); virtual void setVisible(BOOL visible);
BOOL getVisible() const { return mVisible; } const BOOL& getVisible() const { return mVisible; }
virtual void setEnabled(BOOL enabled); virtual void setEnabled(BOOL enabled);
BOOL getEnabled() const { return mEnabled; } BOOL getEnabled() const { return mEnabled; }
U8 getSoundFlags() const { return mSoundFlags; } U8 getSoundFlags() const { return mSoundFlags; }
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
virtual void handleVisibilityChange ( BOOL curVisibilityIn ); virtual void handleVisibilityChange ( BOOL new_visibility );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; } void popVisible() { setVisible(mLastVisible); }
BOOL getLastVisible() const { return mLastVisible; }
LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }
U32 getFollows() const { return mReshapeFlags; } U32 getFollows() const { return mReshapeFlags; }
@@ -360,18 +346,22 @@ public:
const LLRect& getRect() const { return mRect; } const LLRect& getRect() const { return mRect; }
const LLRect& getBoundingRect() const { return mBoundingRect; } const LLRect& getBoundingRect() const { return mBoundingRect; }
LLRect getLocalBoundingRect() const; LLRect getLocalBoundingRect() const;
LLRect getScreenRect() const; LLRect calcScreenRect() const;
LLRect calcScreenBoundingRect() const;
LLRect getLocalRect() const; LLRect getLocalRect() const;
virtual LLRect getSnapRect() const; virtual LLRect getSnapRect() const;
LLRect getLocalSnapRect() const; LLRect getLocalSnapRect() const;
// Override and return required size for this object. 0 for width/height means don't care. // Override and return required size for this object. 0 for width/height means don't care.
virtual LLRect getRequiredRect(); virtual LLRect getRequiredRect();
LLRect calcBoundingRect();
void updateBoundingRect(); void updateBoundingRect();
LLView* getRootView(); LLView* getRootView();
LLView* getParent() const { return mParentView; } LLView* getParent() const { return mParentView; }
LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
LLView* findPrevSibling(LLView* child);
LLView* findNextSibling(LLView* child);
S32 getChildCount() const { return (S32)mChildList.size(); } S32 getChildCount() const { return (S32)mChildList.size(); }
template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
BOOL hasAncestor(const LLView* parentp) const; BOOL hasAncestor(const LLView* parentp) const;
@@ -388,6 +378,7 @@ public:
virtual void translate( S32 x, S32 y ); virtual void translate( S32 x, S32 y );
void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside ); BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
BOOL translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
void centerWithin(const LLRect& bounds); void centerWithin(const LLRect& bounds);
void setShape(const LLRect& new_rect, bool by_user = false); void setShape(const LLRect& new_rect, bool by_user = false);
@@ -422,10 +413,6 @@ public:
BOOL getSaveToXML() const { return mSaveToXML; } BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; } void setSaveToXML(BOOL b) { mSaveToXML = b; }
// inherited from LLFocusableElement
/* virtual */ void onFocusLost();
/* virtual */ void onFocusReceived();
typedef enum e_hit_test_type typedef enum e_hit_test_type
{ {
HIT_TEST_USE_BOUNDING_RECT, HIT_TEST_USE_BOUNDING_RECT,
@@ -465,6 +452,8 @@ public:
virtual LLSD getValue() const; virtual LLSD getValue() const;
const child_list_t* getChildList() const { return &mChildList; } const child_list_t* getChildList() const { return &mChildList; }
child_list_const_iter_t beginChild() const { return mChildList.begin(); }
child_list_const_iter_t endChild() const { return mChildList.end(); }
// LLMouseHandler functions // LLMouseHandler functions
// Default behavior is to pass events to children // Default behavior is to pass events to children
@@ -592,12 +581,20 @@ public:
static LLWindow* getWindow(void) { return LLUI::sWindow; } static LLWindow* getWindow(void) { return LLUI::sWindow; }
virtual void handleReshape(const LLRect& rect, bool by_user); virtual void handleReshape(const LLRect& rect, bool by_user);
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleUnicodeCharHere(llwchar uni_char);
//send custom notification to LLView parent
virtual S32 notifyParent(const LLSD& info);
protected:
void drawDebugRect(); void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
void drawChildren();
bool visibleAndContains(S32 local_x, S32 local_Y);
bool visibleEnabledAndContains(S32 local_x, S32 local_y);
void logMouseEvent();
LLView* childrenHandleKey(KEY key, MASK mask); LLView* childrenHandleKey(KEY key, MASK mask);
LLView* childrenHandleUnicodeChar(llwchar uni_char); LLView* childrenHandleUnicodeChar(llwchar uni_char);
@@ -624,18 +621,36 @@ protected:
control_map_t mFloaterControls; control_map_t mFloaterControls;
private: private:
template <typename METHOD, typename XDATA>
LLView* childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block = true);
template <typename METHOD, typename CHARTYPE>
LLView* childrenHandleCharEvent(const std::string& desc, const METHOD& method,
CHARTYPE c, MASK mask);
// adapter to blur distinction between handleKey() and handleUnicodeChar()
// for childrenHandleCharEvent()
BOOL handleUnicodeCharWithDummyMask(llwchar uni_char, MASK /* dummy */, BOOL from_parent)
{
return handleUnicodeChar(uni_char, from_parent);
}
LLView* mParentView; LLView* mParentView;
child_list_t mChildList; child_list_t mChildList;
std::string mName;
// location in pixels, relative to surrounding structure, bottom,left=0,0 // location in pixels, relative to surrounding structure, bottom,left=0,0
BOOL mVisible;
LLRect mRect; LLRect mRect;
LLRect mBoundingRect; LLRect mBoundingRect;
std::string mName;
U32 mReshapeFlags; U32 mReshapeFlags;
child_tab_order_t mCtrlOrder; child_tab_order_t mCtrlOrder;
S32 mDefaultTabGroup; S32 mDefaultTabGroup;
S32 mLastTabGroup;
BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application." BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application."
// A disabled view, for example, may still have a scrollbar that responds to mouse events. // A disabled view, for example, may still have a scrollbar that responds to mouse events.
@@ -651,14 +666,9 @@ private:
LLRootHandle<LLView> mHandle; LLRootHandle<LLView> mHandle;
BOOL mLastVisible; BOOL mLastVisible;
BOOL mVisible;
S32 mNextInsertionOrdinal; S32 mNextInsertionOrdinal;
// <edit> bool mInDraw;
public:
BOOL mDelayedDelete;
// </edit>
private: private:
static LLWindow* sWindow; // All root views must know about their window. static LLWindow* sWindow; // All root views must know about their window.
@@ -674,6 +684,34 @@ private:
boost::signals2::connection mControlConnection; boost::signals2::connection mControlConnection;
ECursorType mHoverCursor; ECursorType mHoverCursor;
// This allows special mouse-event targeting logic for testing.
typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
static DrilldownFunc sDrilldown;
public:
// This is the only public accessor to alter sDrilldown. This is not
// an accident. The intended usage pattern is like:
// {
// LLView::TemporaryDrilldownFunc scoped_func(myfunctor);
// // ... test with myfunctor ...
// } // exiting block restores original LLView::sDrilldown
class TemporaryDrilldownFunc: public boost::noncopyable
{
public:
TemporaryDrilldownFunc(const DrilldownFunc& func):
mOldDrilldown(sDrilldown)
{
sDrilldown = func;
}
~TemporaryDrilldownFunc()
{
sDrilldown = mOldDrilldown;
}
private:
DrilldownFunc mOldDrilldown;
};
public: public:
static BOOL sDebugRects; // Draw debug rects behind everything. static BOOL sDebugRects; // Draw debug rects behind everything.

157
indra/llui/llviewmodel.cpp Normal file
View File

@@ -0,0 +1,157 @@
/**
* @file llviewmodel.cpp
* @author Nat Goodspeed
* @date 2008-08-08
* @brief Implementation for llviewmodel.
*
* $LicenseInfo:firstyear=2008&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$
*/
// Precompiled header
#include "linden_common.h"
// associated header
#include "llviewmodel.h"
// STL headers
// std headers
// external library headers
// other Linden headers
///
LLViewModel::LLViewModel()
: mDirty(false)
{
}
/// Instantiate an LLViewModel with an existing data value
LLViewModel::LLViewModel(const LLSD& value)
: mDirty(false)
{
setValue(value);
}
/// Update the stored value
void LLViewModel::setValue(const LLSD& value)
{
mValue = value;
mDirty = true;
}
LLSD LLViewModel::getValue() const
{
return mValue;
}
////////////////////////////////////////////////////////////////////////////
///
LLTextViewModel::LLTextViewModel()
: LLViewModel(false),
mUpdateFromDisplay(false)
{
}
/// Instantiate an LLViewModel with an existing data value
LLTextViewModel::LLTextViewModel(const LLSD& value)
: LLViewModel(value),
mUpdateFromDisplay(false)
{
}
/// Update the stored value
void LLTextViewModel::setValue(const LLSD& value)
{
LLViewModel::setValue(value);
mDisplay = utf8str_to_wstring(value.asString());
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
void LLTextViewModel::setDisplay(const LLWString& value)
{
// This is the strange way to alter the value. Normally we'd setValue()
// and do the utf8str_to_wstring() to get the corresponding mDisplay
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
mDisplay = value;
mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
// doing.
mUpdateFromDisplay = true;
}
LLSD LLTextViewModel::getValue() const
{
// Has anyone called setDisplay() since the last setValue()? If so, have
// to convert mDisplay back to UTF8.
if (mUpdateFromDisplay)
{
// The fact that we're lazily updating fields in this object should be
// transparent to clients, which is why this method is left
// conventionally const. Nor do we particularly want to make these
// members mutable. Just cast away constness in this one place.
LLTextViewModel* nthis = const_cast<LLTextViewModel*>(this);
nthis->mUpdateFromDisplay = false;
nthis->mValue = wstring_to_utf8str(mDisplay);
}
return LLViewModel::getValue();
}
////////////////////////////////////////////////////////////////////////////
LLListViewModel::LLListViewModel(const LLSD& values)
: LLViewModel()
{
}
void LLListViewModel::addColumn(const LLSD& column, EAddPosition pos)
{
}
void LLListViewModel::clearColumns()
{
}
void LLListViewModel::setColumnLabel(const std::string& column, const std::string& label)
{
}
LLScrollListItem* LLListViewModel::addElement(const LLSD& value, EAddPosition pos,
void* userdata)
{
return NULL;
}
LLScrollListItem* LLListViewModel::addSimpleElement(const std::string& value, EAddPosition pos,
const LLSD& id)
{
return NULL;
}
void LLListViewModel::clearRows()
{
}
void LLListViewModel::sortByColumn(const std::string& name, bool ascending)
{
}

214
indra/llui/llviewmodel.h Normal file
View File

@@ -0,0 +1,214 @@
/**
* @file llviewmodel.h
* @author Nat Goodspeed
* @date 2008-08-08
* @brief Define "View Model" classes intended to store data values for use
* by LLUICtrl subclasses. The phrase is borrowed from Microsoft
* terminology, in which "View Model" means the storage object
* underlying a specific widget object -- as in our case -- rather
* than the business "model" object underlying the overall "view"
* presented by the collection of widgets.
*
* $LicenseInfo:firstyear=2008&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$
*/
#if ! defined(LL_LLVIEWMODEL_H)
#define LL_LLVIEWMODEL_H
#include "llpointer.h"
#include "llsd.h"
#include "llrefcount.h"
#include "stdenums.h"
#include "llstring.h"
#include <string>
class LLScrollListItem;
class LLViewModel;
class LLTextViewModel;
class LLListViewModel;
// Because LLViewModel is derived from LLRefCount, always pass, store
// and return LLViewModelPtr rather than plain LLViewModel*.
typedef LLPointer<LLViewModel> LLViewModelPtr;
typedef LLPointer<LLTextViewModel> LLTextViewModelPtr;
typedef LLPointer<LLListViewModel> LLListViewModelPtr;
/**
* LLViewModel stores a scalar LLSD data item, the current display value of a
* scalar LLUICtrl widget. LLViewModel subclasses are used to store data
* collections used for aggregate widgets. LLViewModel is ref-counted because
* -- for multiple skins -- we may have distinct widgets sharing the same
* LLViewModel data. This way, the LLViewModel is quietly deleted when the
* last referencing widget is destroyed.
*/
class LLViewModel: public LLRefCount
{
public:
LLViewModel();
/// Instantiate an LLViewModel with an existing data value
LLViewModel(const LLSD& value);
/// Update the stored value
virtual void setValue(const LLSD& value);
/// Get the stored value, in appropriate type.
virtual LLSD getValue() const;
/// Has the value been changed since last time we checked?
bool isDirty() const { return mDirty; }
/// Once the value has been saved to a file, or otherwise consumed by the
/// app, we no longer need to enable the Save button
void resetDirty() { mDirty = false; }
//
void setDirty() { mDirty = true; }
protected:
LLSD mValue;
bool mDirty;
};
/**
* LLTextViewModel stores a value displayed as text.
*/
class LLTextViewModel: public LLViewModel
{
public:
LLTextViewModel();
/// Instantiate an LLViewModel with an existing data value
LLTextViewModel(const LLSD& value);
// LLViewModel functions
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
/**
* Set the display string directly (see LLTextEditor). What the user is
* editing is actually the LLWString value rather than the underlying
* UTF-8 value.
*/
void setDisplay(const LLWString& value);
private:
/// To avoid converting every widget's stored value from LLSD to LLWString
/// every frame, cache the converted value
LLWString mDisplay;
/// As the user edits individual characters (setDisplay()), defer
/// LLWString-to-UTF8 conversions until s/he's done.
bool mUpdateFromDisplay;
};
/**
* LLListViewModel stores a list of data items. The semantics are borrowed
* from LLScrollListCtrl.
*/
class LLListViewModel: public LLViewModel
{
public:
LLListViewModel() {}
LLListViewModel(const LLSD& values);
virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
virtual void clearColumns();
virtual void setColumnLabel(const std::string& column, const std::string& label);
virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM,
void* userdata = NULL);
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos,
const LLSD& id);
virtual void clearRows();
virtual void sortByColumn(const std::string& name, bool ascending);
};
//namespace LLViewModel
//{
// class Value
// {
// public:
// Value(const LLSD& value = LLSD());
//
// LLSD getValue() const { return mValue; }
// void setValue(const LLSD& value) { mValue = value; }
//
// bool isAvailable() const { return false; }
// bool isReadOnly() const { return false; }
//
// bool undo() { return false; }
// bool redo() { return false; }
//
// /// Has the value been changed since last time we checked?
// bool isDirty() const { return mDirty; }
// /// Once the value has been saved to a file, or otherwise consumed by the
// /// app, we no longer need to enable the Save button
// void resetDirty() { mDirty = false; }
// //
// void setDirty() { mDirty = true; }
//
// protected:
// LLSD mValue;
// bool mDirty;
// };
//
// class Numeric : public Value
// {
// public:
// Numeric(S32 value = 0);
// Numeric(F32 value);
//
// F32 getPrecision();
// F32 getMin();
// F32 getMax();
//
// void increment();
// void decrement();
// };
//
// class MultipleValues : public Value
// {
// class Selector
// {};
//
// MultipleValues();
// virtual S32 numElements();
// };
//
// class Tuple : public MultipleValues
// {
// Tuple(S32 size);
// LLSD getValue(S32 which) const;
// void setValue(S32 which, const LLSD& value);
// };
//
// class List : public MultipleValues
// {
// List();
//
// void add(const ValueModel& value);
// bool remove(const Selector& item);
//
// void setSortElement(const Selector& element);
// void sort();
// };
//
//};
#endif /* ! defined(LL_LLVIEWMODEL_H) */

View File

@@ -174,6 +174,8 @@ public:
// Provide native key event data // Provide native key event data
virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }
virtual void setTitle(const std::string &title){};
protected: protected:
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
virtual ~LLWindow(); virtual ~LLWindow();

View File

@@ -3269,6 +3269,15 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
} }
} }
void LLWindowMacOSX::setTitle(const std::string &title)
{
/*strncpy((char*)mWindowTitle + 1, title.c_str(), 253);
mWindowTitle[0] = title.length();*/
CFStringRef title_str = CFStringCreateWithCString(NULL, title.c_str(), kCFStringEncodingUTF8);
SetWindowTitleWithCFString(mWindow, title_str);
}
LLSD LLWindowMacOSX::getNativeKeyData() LLSD LLWindowMacOSX::getNativeKeyData()
{ {
LLSD result = LLSD::emptyMap(); LLSD result = LLSD::emptyMap();

View File

@@ -118,6 +118,8 @@ public:
/*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void interruptLanguageTextInput();
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void setTitle(const std::string &title);
static std::vector<std::string> getDynamicFallbackFontList(); static std::vector<std::string> getDynamicFallbackFontList();
// Provide native key event data // Provide native key event data

View File

@@ -2512,6 +2512,11 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
llinfos << "spawn_web_browser returning." << llendl; llinfos << "spawn_web_browser returning." << llendl;
} }
void LLWindowSDL::setTitle(const std::string &title)
{
mWindowTitle = title;
SDL_WM_SetCaption(mWindowTitle.c_str(),mWindowTitle.c_str());
}
void *LLWindowSDL::getPlatformWindow() void *LLWindowSDL::getPlatformWindow()
{ {

View File

@@ -127,6 +127,8 @@ public:
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void setTitle(const std::string &title);
static std::vector<std::string> getDynamicFallbackFontList(); static std::vector<std::string> getDynamicFallbackFontList();
// Not great that these are public, but they have to be accessible // Not great that these are public, but they have to be accessible

View File

@@ -3140,6 +3140,14 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async)
ShellExecuteEx( &sei ); ShellExecuteEx( &sei );
} }
void LLWindowWin32::setTitle(const std::string &title)
{
mbstowcs(mWindowTitle, title.c_str(), 255);
mWindowTitle[255] = 0;
SetWindowText(mWindowHandle, mWindowTitle);
}
/* /*
Make the raw keyboard data available - used to poke through to LLQtWebKit so Make the raw keyboard data available - used to poke through to LLQtWebKit so
that Qt/Webkit has access to the virtual keycodes etc. that it needs that Qt/Webkit has access to the virtual keycodes etc. that it needs

View File

@@ -117,6 +117,8 @@ public:
void ShellEx(const std::string& command); void ShellEx(const std::string& command);
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ void setTitle(const std::string &title);
LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
static std::vector<std::string> getDynamicFallbackFontList(); static std::vector<std::string> getDynamicFallbackFontList();

View File

@@ -0,0 +1,40 @@
# -*- cmake -*-
project(llxuixml)
include(00-Common)
include(LLCommon)
include(LLMath)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(llxuixml_SOURCE_FILES
llinitparam.cpp
lluicolor.cpp
)
set(llxuixml_HEADER_FILES
CMakeLists.txt
llinitparam.h
lluicolor.h
)
set_source_files_properties(${llxuixml_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND llxuixml_SOURCE_FILES ${llxuixml_HEADER_FILES})
add_library (llxuixml ${llxuixml_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
target_link_libraries(llxuixml
llxml
llcommon
llmath
)

View File

@@ -0,0 +1,469 @@
/**
* @file llinitparam.cpp
* @brief parameter block abstraction for creating complex objects and
* parsing construction parameters from xml and LLSD
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llinitparam.h"
namespace LLInitParam
{
//
// Param
//
Param::Param(BaseBlock* enclosing_block)
: mIsProvided(false)
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
}
//
// ParamDescriptor
//
ParamDescriptor::ParamDescriptor(param_handle_t p,
merge_func_t merge_func,
deserialize_func_t deserialize_func,
serialize_func_t serialize_func,
validation_func_t validation_func,
inspect_func_t inspect_func,
S32 min_count,
S32 max_count)
: mParamHandle(p),
mMergeFunc(merge_func),
mDeserializeFunc(deserialize_func),
mSerializeFunc(serialize_func),
mValidationFunc(validation_func),
mInspectFunc(inspect_func),
mMinCount(min_count),
mMaxCount(max_count),
mUserData(NULL)
{}
ParamDescriptor::ParamDescriptor()
: mParamHandle(0),
mMergeFunc(NULL),
mDeserializeFunc(NULL),
mSerializeFunc(NULL),
mValidationFunc(NULL),
mInspectFunc(NULL),
mMinCount(0),
mMaxCount(0),
mUserData(NULL)
{}
ParamDescriptor::~ParamDescriptor()
{
delete mUserData;
}
//
// Parser
//
Parser::~Parser()
{}
void Parser::parserWarning(const std::string& message)
{
if (mParseSilently) return;
llwarns << message << llendl;
}
void Parser::parserError(const std::string& message)
{
if (mParseSilently) return;
llerrs << message << llendl;
}
//
// BlockDescriptor
//
void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
{
mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
}
BlockDescriptor::BlockDescriptor()
: mMaxParamOffset(0),
mInitializationState(UNINITIALIZED),
mCurrentBlockPtr(NULL)
{}
// called by each derived class in least to most derived order
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
descriptor.mCurrentBlockPtr = this;
descriptor.mMaxParamOffset = block_size;
switch(descriptor.mInitializationState)
{
case BlockDescriptor::UNINITIALIZED:
// copy params from base class here
descriptor.aggregateBlockData(base_descriptor);
descriptor.mInitializationState = BlockDescriptor::INITIALIZING;
break;
case BlockDescriptor::INITIALIZING:
descriptor.mInitializationState = BlockDescriptor::INITIALIZED;
break;
case BlockDescriptor::INITIALIZED:
// nothing to do
break;
}
}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const
{
const U8* param_address = reinterpret_cast<const U8*>(param);
const U8* baseblock_address = reinterpret_cast<const U8*>(this);
return (param_address - baseblock_address);
}
bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
{
if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
{
if (!silent)
{
p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str()));
}
return false;
}
return true;
}
bool BaseBlock::validateBlock(bool emit_errors) const
{
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
{
const Param* param = getParamFromHandle(it->first);
if (!it->second(param))
{
if (emit_errors)
{
llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
}
return false;
}
}
return true;
}
void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
++it)
{
param_handle_t param_handle = (*it)->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
if (serialize_func)
{
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
// each param descriptor remembers its serial number
// so we can inspect the same param under different names
// and see that it has the same number
name_stack.push_back(std::make_pair("", true));
serialize_func(*param, parser, name_stack, diff_param);
name_stack.pop_back();
}
}
for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
it != block_data.mNamedParams.end();
++it)
{
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
if (serialize_func && param->anyProvided())
{
// Ensure this param has not already been serialized
// Prevents <rect> from being serialized as its own tag.
bool duplicate = false;
for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
it2 != block_data.mUnnamedParams.end();
++it2)
{
if (param_handle == (*it2)->mParamHandle)
{
duplicate = true;
break;
}
}
//FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
// don't know how to detect them
if (duplicate)
{
continue;
}
name_stack.push_back(std::make_pair(it->first, !duplicate));
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
serialize_func(*param, parser, name_stack, diff_param);
name_stack.pop_back();
}
}
}
bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
++it)
{
param_handle_t param_handle = (*it)->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
if (inspect_func)
{
name_stack.push_back(std::make_pair("", true));
inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
name_stack.pop_back();
}
}
for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
it != block_data.mNamedParams.end();
++it)
{
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
if (inspect_func)
{
// Ensure this param has not already been inspected
bool duplicate = false;
for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
it2 != block_data.mUnnamedParams.end();
++it2)
{
if (param_handle == (*it2)->mParamHandle)
{
duplicate = true;
break;
}
}
name_stack.push_back(std::make_pair(it->first, !duplicate));
inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
name_stack.pop_back();
}
}
return true;
}
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
bool names_left = name_stack_range.first != name_stack_range.second;
bool new_name = names_left
? name_stack_range.first->second
: true;
if (names_left)
{
const std::string& top_name = name_stack_range.first->first;
ParamDescriptor::deserialize_func_t deserialize_func = NULL;
Param* paramp = NULL;
BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
if (found_it != block_data.mNamedParams.end())
{
// find pointer to member parameter from offset table
paramp = getParamFromHandle(found_it->second->mParamHandle);
deserialize_func = found_it->second->mDeserializeFunc;
Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
++new_name_stack.first;
if (deserialize_func(*paramp, p, new_name_stack, new_name))
{
// value is no longer new, we know about it now
name_stack_range.first->second = false;
return true;
}
else
{
return false;
}
}
}
// try to parse unnamed parameters, in declaration order
for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
++it)
{
Param* paramp = getParamFromHandle((*it)->mParamHandle);
ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
if (deserialize_func && deserialize_func(*paramp, p, name_stack_range, new_name))
{
return true;
}
}
// if no match, and no names left on stack, this is just an existence assertion of this block
// verify by calling readValue with NoParamValue type, an inherently unparseable type
if (!names_left)
{
Flag no_value;
return p.readValue(no_value);
}
return false;
}
//static
void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
{
// create a copy of the param descriptor in mAllParams
// so other data structures can store a pointer to it
block_data.mAllParams.push_back(in_param);
ParamDescriptorPtr param(block_data.mAllParams.back());
std::string name(char_name);
if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
{
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
if (name.empty())
{
block_data.mUnnamedParams.push_back(param);
}
else
{
// don't use insert, since we want to overwrite existing entries
block_data.mNamedParams[name] = param;
}
if (param->mValidationFunc)
{
block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
}
}
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
{
param_handle_t handle = getHandleFromParam(&param);
// check for invalid derivation from a paramblock (i.e. without using
// Block<T, Base_Class>
if ((size_t)handle > block_data.mMaxParamOffset)
{
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
if (param_descriptor)
{
if (synonym.empty())
{
block_data.mUnnamedParams.push_back(param_descriptor);
}
else
{
block_data.mNamedParams[synonym] = param_descriptor;
}
}
}
}
const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
{
param_handle_t handle = getHandleFromParam(paramp);
for (BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin(); it != block_data.mNamedParams.end(); ++it)
{
if (it->second->mParamHandle == handle)
{
return it->first;
}
}
return LLStringUtil::null;
}
ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
{
param_handle_t handle = getHandleFromParam(&param);
BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
it != end_it;
++it)
{
if ((*it)->mParamHandle == handle) return *it;
}
return ParamDescriptorPtr();
}
// take all provided params from other and apply to self
// NOTE: this requires that "other" is of the same derived type as this
bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
{
bool some_param_changed = false;
BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
it != end_it;
++it)
{
const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
if (merge_func)
{
Param* paramp = getParamFromHandle((*it)->mParamHandle);
llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
return some_param_changed;
}
}

2294
indra/llxuixml/llinitparam.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
/**
* @file lluicolor.cpp
* @brief brief LLUIColor class implementation file
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lluicolor.h"
LLUIColor::LLUIColor()
:mColorPtr(NULL)
{
}
LLUIColor::LLUIColor(const LLColor4& color)
: mColor(color),
mColorPtr(NULL)
{
}
LLUIColor::LLUIColor(const LLUIColor* color)
: mColorPtr(color)
{
}
void LLUIColor::set(const LLColor4& color)
{
mColor = color;
mColorPtr = NULL;
}
void LLUIColor::set(const LLUIColor* color)
{
mColorPtr = color;
}
const LLColor4& LLUIColor::get() const
{
return (mColorPtr == NULL ? mColor : mColorPtr->get());
}
LLUIColor::operator const LLColor4& () const
{
return get();
}
const LLColor4& LLUIColor::operator()() const
{
return get();
}
bool LLUIColor::isReference() const
{
return mColorPtr != NULL;
}
namespace LLInitParam
{
// used to detect equivalence with default values on export
bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b)
{
// do not detect value equivalence, treat pointers to colors as distinct from color values
return (a.mColorPtr == NULL && b.mColorPtr == NULL ? a.mColor == b.mColor : a.mColorPtr == b.mColorPtr);
}
}

View File

@@ -0,0 +1,71 @@
/**
* @file lluicolor.h
* @brief brief LLUIColor class header file
*
* $LicenseInfo:firstyear=2009&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_LLUICOLOR_H_
#define LL_LLUICOLOR_H_
#include "v4color.h"
namespace LLInitParam
{
template<typename T, bool>
struct ParamCompare;
}
class LLUIColor
{
public:
LLUIColor();
LLUIColor(const LLColor4& color);
LLUIColor(const LLUIColor* color);
void set(const LLColor4& color);
void set(const LLUIColor* color);
const LLColor4& get() const;
operator const LLColor4& () const;
const LLColor4& operator()() const;
bool isReference() const;
private:
friend struct LLInitParam::ParamCompare<LLUIColor, false>;
const LLUIColor* mColorPtr;
LLColor4 mColor;
};
namespace LLInitParam
{
template<>
struct ParamCompare<LLUIColor, false>
{
static bool equals(const LLUIColor& a, const LLUIColor& b);
};
}
#endif

View File

@@ -37,6 +37,7 @@ include(LLUI)
include(LLVFS) include(LLVFS)
include(LLWindow) include(LLWindow)
include(LLXML) include(LLXML)
include(LLXUIXML)
include(LScript) include(LScript)
include(Linking) include(Linking)
include(NDOF) include(NDOF)
@@ -71,6 +72,7 @@ include_directories(
${LLVFS_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS}
${LLXUIXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
) )
@@ -86,7 +88,6 @@ set(viewer_SOURCE_FILES
lggdicdownload.cpp lggdicdownload.cpp
floaterao.cpp floaterao.cpp
floatervoicelicense.cpp floatervoicelicense.cpp
cofmgr.cpp
lldaycyclemanager.cpp lldaycyclemanager.cpp
llenvmanager.cpp llenvmanager.cpp
llwlhandlers.cpp llwlhandlers.cpp
@@ -122,7 +123,9 @@ set(viewer_SOURCE_FILES
llagentpilot.cpp llagentpilot.cpp
llagentui.cpp llagentui.cpp
llagentwearables.cpp llagentwearables.cpp
llagentwearablesfetch.cpp
llanimstatelabels.cpp llanimstatelabels.cpp
llappearancemgr.cpp
llappviewer.cpp llappviewer.cpp
llassetconverter.cpp llassetconverter.cpp
llassetuploadresponders.cpp llassetuploadresponders.cpp
@@ -308,6 +311,7 @@ set(viewer_SOURCE_FILES
llinventorypanel.cpp llinventorypanel.cpp
lljoystickbutton.cpp lljoystickbutton.cpp
lllandmarklist.cpp lllandmarklist.cpp
lllocaltextureobject.cpp
lllocalinventory.cpp lllocalinventory.cpp
lllogchat.cpp lllogchat.cpp
llloginhandler.cpp llloginhandler.cpp
@@ -329,6 +333,7 @@ set(viewer_SOURCE_FILES
llnamelistctrl.cpp llnamelistctrl.cpp
llnetmap.cpp llnetmap.cpp
llnotify.cpp llnotify.cpp
lloutfitobserver.cpp
lloverlaybar.cpp lloverlaybar.cpp
llpanelaudioprefs.cpp llpanelaudioprefs.cpp
llpanelaudiovolume.cpp llpanelaudiovolume.cpp
@@ -357,7 +362,7 @@ set(viewer_SOURCE_FILES
llpanelgrouproles.cpp llpanelgrouproles.cpp
llpanelgroupvoting.cpp llpanelgroupvoting.cpp
llpanelinput.cpp llpanelinput.cpp
llpanelinventory.cpp llpanelobjectinventory.cpp
llpanelland.cpp llpanelland.cpp
llpanellandaudio.cpp llpanellandaudio.cpp
llpanellandmedia.cpp llpanellandmedia.cpp
@@ -411,7 +416,9 @@ set(viewer_SOURCE_FILES
llstylemap.cpp llstylemap.cpp
llsurface.cpp llsurface.cpp
llsurfacepatch.cpp llsurfacepatch.cpp
lltexglobalcolor.cpp
lltexlayer.cpp lltexlayer.cpp
lltexlayerparams.cpp
lltexturecache.cpp lltexturecache.cpp
lltexturectrl.cpp lltexturectrl.cpp
lltexturefetch.cpp lltexturefetch.cpp
@@ -571,7 +578,6 @@ set(viewer_HEADER_FILES
aoremotectrl.h aoremotectrl.h
floaterao.h floaterao.h
floatervoicelicense.h floatervoicelicense.h
cofmgr.h
lldaycyclemanager.h lldaycyclemanager.h
llenvmanager.h llenvmanager.h
llwlhandlers.h llwlhandlers.h
@@ -607,8 +613,10 @@ set(viewer_HEADER_FILES
llagentpilot.h llagentpilot.h
llagentui.h llagentui.h
llagentwearables.h llagentwearables.h
llagentwearablesfetch.h
llanimstatelabels.h llanimstatelabels.h
llappearance.h llappearance.h
llappearancemgr.h
llappviewer.h llappviewer.h
llassetconverter.h llassetconverter.h
llassetuploadresponders.h llassetuploadresponders.h
@@ -794,6 +802,7 @@ set(viewer_HEADER_FILES
lljoystickbutton.h lljoystickbutton.h
lllandmarklist.h lllandmarklist.h
lllightconstants.h lllightconstants.h
lllocaltextureobject.h
lllocalinventory.h lllocalinventory.h
lllogchat.h lllogchat.h
llloginhandler.h llloginhandler.h
@@ -815,6 +824,7 @@ set(viewer_HEADER_FILES
llnamelistctrl.h llnamelistctrl.h
llnetmap.h llnetmap.h
llnotify.h llnotify.h
lloutfitobserver.h
lloverlaybar.h lloverlaybar.h
llpanelaudioprefs.h llpanelaudioprefs.h
llpanelaudiovolume.h llpanelaudiovolume.h
@@ -843,7 +853,7 @@ set(viewer_HEADER_FILES
llpanelgrouproles.h llpanelgrouproles.h
llpanelgroupvoting.h llpanelgroupvoting.h
llpanelinput.h llpanelinput.h
llpanelinventory.h llpanelobjectinventory.h
llpanelland.h llpanelland.h
llpanellandaudio.h llpanellandaudio.h
llpanellandmedia.h llpanellandmedia.h
@@ -900,7 +910,9 @@ set(viewer_HEADER_FILES
llsurface.h llsurface.h
llsurfacepatch.h llsurfacepatch.h
lltable.h lltable.h
lltexglobalcolor.h
lltexlayer.h lltexlayer.h
lltexlayerparams.h
lltexturecache.h lltexturecache.h
lltexturectrl.h lltexturectrl.h
lltexturefetch.h lltexturefetch.h
@@ -1522,6 +1534,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLVFS_LIBRARIES} ${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES} ${LLWINDOW_LIBRARIES}
${LLXML_LIBRARIES} ${LLXML_LIBRARIES}
${LLXUIXML_LIBRARIES}
${LSCRIPT_LIBRARIES} ${LSCRIPT_LIBRARIES}
${LLMATH_LIBRARIES} ${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES} ${LLCOMMON_LIBRARIES}

View File

@@ -2076,6 +2076,28 @@
<key>Value</key> <key>Value</key>
<integer>2</integer> <integer>2</integer>
</map> </map>
<key>AvatarBakedTextureUploadTimeout</key>
<map>
<key>Comment</key>
<string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>60</integer>
</map>
<key>AvatarBakedLocalTextureUpdateTimeout</key>
<map>
<key>Comment</key>
<string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>10</integer>
</map>
<key>AvatarPhysics</key> <key>AvatarPhysics</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -3994,8 +4016,30 @@
<key>Type</key> <key>Type</key>
<string>String</string> <string>String</string>
<key>Value</key> <key>Value</key>
<string/> <string />
</map> </map>
<key>DebugAvatarRezTime</key>
<map>
<key>Comment</key>
<string>Display times for avatars to resolve.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugAvatarLocalTexLoadedTime</key>
<map>
<key>Comment</key>
<string>Display time for loading avatar local textures.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugBeaconLineWidth</key> <key>DebugBeaconLineWidth</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -6709,6 +6753,17 @@
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>ForceAssetFail</key>
<map>
<key>Comment</key>
<string>Force wearable fetches to fail for this asset type.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>255</integer>
</map>
<key>ForceShowGrid</key> <key>ForceShowGrid</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -7949,6 +8004,17 @@
<key>Value</key> <key>Value</key>
<real>128.0</real> <real>128.0</real>
</map> </map>
<key>MaxWearableWaitTime</key>
<map>
<key>Comment</key>
<string>Max seconds to wait for wearable assets to fetch.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>60.0</real>
</map>
<key>MeanCollisionBump</key> <key>MeanCollisionBump</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -8409,8 +8475,19 @@
<key>Type</key> <key>Type</key>
<string>Boolean</string> <string>Boolean</string>
<key>Value</key> <key>Value</key>
<integer>1</integer> <integer>0</integer>
</map> </map>
<key>MyOutfitsAutofill</key>
<map>
<key>Comment</key>
<string>Always autofill My Outfits from library when empty (else happens just once).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>NearMeRange</key> <key>NearMeRange</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -14694,6 +14771,17 @@
<key>Value</key> <key>Value</key>
<integer>1</integer> <integer>1</integer>
</map> </map>
<key>OutfitOperationsTimeout</key>
<map>
<key>Comment</key>
<string>Timeout for outfit related operations.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>180</integer>
</map>
<key>UseHTTPInventory</key> <key>UseHTTPInventory</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@@ -98,13 +98,11 @@ void LLPrefsAscentVan::onCommitClientTag(LLUICtrl* ctrl, void* userdata)
gSavedSettings.setString("AscentReportClientUUID", client_uuid); gSavedSettings.setString("AscentReportClientUUID", client_uuid);
gSavedSettings.setU32("AscentReportClientIndex", client_index); gSavedSettings.setU32("AscentReportClientIndex", client_index);
LLVOAvatar* avatar = gAgentAvatarp; if (gAgentAvatarp)
if (avatar)
{ {
// Slam pending upload count to "unstick" things // Slam pending upload count to "unstick" things
bool slam_for_debug = true; bool slam_for_debug = true;
avatar->forceBakeAllTextures(slam_for_debug); gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
} }
} }
} }

View File

@@ -6387,8 +6387,6 @@
<layer <layer
name="facialhair" name="facialhair"
global_color="hair_color"> global_color="hair_color">
<morph_mask
morph_name="Displace_Hair_Facial" />
<texture <texture
tga_file="head_hair.tga" tga_file="head_hair.tga"
@@ -7294,12 +7292,6 @@
<texture <texture
local_texture="upper_shirt" /> local_texture="upper_shirt" />
<morph_mask
morph_name="Displace_Loose_Upperbody" />
<morph_mask
morph_name="Shirtsleeve_flair" />
<param <param
id="803" id="803"
group="0" group="0"
@@ -8360,18 +8352,6 @@
<texture <texture
local_texture="lower_pants" /> local_texture="lower_pants" />
<morph_mask
morph_name="Displace_Loose_Lowerbody" />
<morph_mask
morph_name="Leg_Pantflair" />
<morph_mask
morph_name="Low_Crotch" />
<morph_mask
morph_name="Leg_Longcuffs" />
<param <param
id="806" id="806"
group="0" group="0"
@@ -11863,6 +11843,37 @@
value_max="1"> value_max="1">
<param_driver /> <param_driver />
</param> </param>
</driver_parameters> </driver_parameters>
<morph_masks>
<mask
morph_name="Displace_Hair_Facial"
body_region="head"
layer="facialhair" />
<mask
morph_name="Displace_Loose_Upperbody"
body_region="upper_body"
layer="upper_clothes" />
<mask
morph_name="Shirtsleeve_flair"
body_region="upper_body"
layer="upper_clothes" />
<mask
morph_name="Displace_Loose_Lowerbody"
body_region="lower_body"
layer="lower_pants" />
<mask
morph_name="Leg_Pantflair"
body_region="lower_body"
layer="lower_pants" />
<mask
morph_name="Low_Crotch"
body_region="lower_body"
layer="lower_pants" />
<mask
morph_name="Leg_Longcuffs"
body_region="lower_body"
layer="lower_pants" />
</morph_masks>
</linden_avatar> </linden_avatar>

View File

@@ -1,536 +0,0 @@
/**
*
* Copyright (c) 2010, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llviewerprecompiledheaders.h"
#include "cofmgr.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "llcommonutils.h"
#include "llerror.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llvoavatarself.h"
#include "rlvviewer2.h"
// ============================================================================
// Inventory helper classes
//
class LLCOFLinkTargetFetcher : public LLInventoryFetchItemsObserver
{
public:
LLCOFLinkTargetFetcher(const uuid_vec_t& idItems) : LLInventoryFetchItemsObserver(idItems) {}
/*virtual*/ ~LLCOFLinkTargetFetcher() {}
/*virtual*/ void done()
{
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
doOnIdleOneTime(boost::bind(&LLCOFLinkTargetFetcher::doneIdle, this));
gInventory.removeObserver(this);
}
void doneIdle()
{
LLCOFMgr::instance().checkCOF();
LLCOFMgr::instance().setLinkAttachments(true);
LLCOFMgr::instance().updateAttachments();
LLCOFMgr::instance().synchWearables();
delete this;
}
};
class LLCOFFetcher : public LLInventoryFetchDescendentsObserver
{
public:
LLCOFFetcher(const LLUUID& cat_id) : LLInventoryFetchDescendentsObserver(cat_id) {}
/*virtual*/ ~LLCOFFetcher() {}
/*virtual*/ void done()
{
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
doOnIdleOneTime(boost::bind(&LLCOFFetcher::doneIdle, this));
gInventory.removeObserver(this);
}
void doneIdle()
{
uuid_vec_t idItems;
// Add the link targets for COF
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
gInventory.collectDescendents(LLCOFMgr::getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
{
const LLViewerInventoryItem* pItem = items.get(idxItem);
if (!pItem)
continue;
idItems.push_back(pItem->getLinkedUUID());
}
// Add all currently worn wearables
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
{
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType,0); // TODO: MULTI-WEARABLE
if (idItem.isNull())
continue;
idItems.push_back(idItem);
}
// Add all currently worn attachments
const LLVOAvatar* pAvatar = gAgentAvatarp;
if (pAvatar)
{
for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = pAvatar->mAttachmentPoints.begin();
itAttachPt != pAvatar->mAttachmentPoints.end(); ++itAttachPt)
{
const LLViewerJointAttachment* pAttachPt = itAttachPt->second;
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachment = pAttachPt->mAttachedObjects.begin();
itAttachment != pAttachPt->mAttachedObjects.end(); ++itAttachment)
{
const LLUUID& idItem = (*itAttachment)->getAttachmentItemID();
if (idItem.isNull())
continue;
idItems.push_back(idItem);
}
}
}
// Fetch it all
LLCOFLinkTargetFetcher* pFetcher = new LLCOFLinkTargetFetcher(idItems);
pFetcher->startFetch();
if (pFetcher->isFinished())
{
pFetcher->done();
}
else
{
gInventory.addObserver(pFetcher);
// It doesn't look like we *really* need the link targets so we can do a preliminary initialization now already
LLCOFMgr::instance().setLinkAttachments(true);
LLCOFMgr::instance().updateAttachments();
}
delete this;
}
};
class LLDeferredAddLinkTargetFetcher : public LLInventoryFetchItemsObserver
{
public:
LLDeferredAddLinkTargetFetcher(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
: LLInventoryFetchItemsObserver(idItem), m_Callback(cb)
{}
LLDeferredAddLinkTargetFetcher(const uuid_vec_t& idItems, LLPointer<LLInventoryCallback> cb)
: LLInventoryFetchItemsObserver(idItems), m_Callback(cb)
{}
/*virtual*/ ~LLDeferredAddLinkTargetFetcher() {}
/*virtual*/ void done()
{
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
doOnIdleOneTime(boost::bind(&LLDeferredAddLinkTargetFetcher::doneIdle, this));
gInventory.removeObserver(this);
}
void doneIdle()
{
for (uuid_vec_t::const_iterator itItemId = mComplete.begin(); itItemId != mComplete.end(); ++itItemId)
{
const LLViewerInventoryItem* pItem = gInventory.getItem(*itItemId);
if (!pItem)
continue;
LLCOFMgr::instance().addCOFItemLink(pItem, m_Callback);
}
delete this;
}
protected:
LLPointer<LLInventoryCallback> m_Callback;
};
class LLLinkAttachmentCallback : public LLInventoryCallback
{
public:
LLLinkAttachmentCallback() {}
/*virtual*/ ~LLLinkAttachmentCallback() {}
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkAttachmentComplete(idItem); }
};
class LLLinkWearableCallback : public LLInventoryCallback
{
public:
LLLinkWearableCallback() {}
/*virtual*/ ~LLLinkWearableCallback() {}
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkWearableComplete(idItem); }
};
// ============================================================================
// Helper functions
//
void LLCOFMgr::checkCOF()
{
const LLUUID idCOF = getCOF();
const LLUUID idLAF = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
// Check COF for non-links and move them to Lost&Found
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
gInventory.getDirectDescendentsOf(idCOF, pFolders, pItems);
for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
{
LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder).get();
if ( (pFolder) && (idLAF.notNull()) )
change_category_parent(&gInventory, pFolder, idLAF, false);
}
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
{
LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
if ( (pItem) && (!pItem->getIsLinkType()) && (idLAF.notNull()) )
change_item_parent(&gInventory, pItem, idLAF, false);
}
}
void LLCOFMgr::fetchCOF()
{
static bool sFetched = false;
if (!sFetched)
{
const LLUUID idCOF = getCOF();
if (idCOF.isNull())
{
LL_ERRS("COFMgr") << "Unable to find (or create) COF" << LL_ENDL;
return;
}
LLCOFFetcher* pFetcher = new LLCOFFetcher(idCOF);
pFetcher->startFetch();
if (pFetcher->isFinished())
pFetcher->done();
else
gInventory.addObserver(pFetcher);
sFetched = true;
}
}
void LLCOFMgr::getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
LLAssetType::EType typeAsset, bool fFollowFolderLinks)
{
LLInventoryModel::cat_array_t folders;
LLIsType f(typeAsset);
gInventory.collectDescendentsIf(idCat, folders, items, LLInventoryModel::EXCLUDE_TRASH, f, fFollowFolderLinks);
}
void LLCOFMgr::addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
{
const LLViewerInventoryItem *pItem = gInventory.getItem(idItem);
if (!pItem)
{
LLDeferredAddLinkTargetFetcher* pFetcher = new LLDeferredAddLinkTargetFetcher(idItem, cb);
pFetcher->startFetch();
gInventory.addObserver(pFetcher);
return;
}
addCOFItemLink(pItem, cb);
}
void LLCOFMgr::addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb)
{
if ( (!pItem) || (isLinkInCOF(pItem->getLinkedUUID())) )
{
return;
}
gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getLinkedUUID());
const std::string strDescr = (pItem->getIsLinkType()) ? pItem->getDescription() : "";
link_inventory_item(gAgent.getID(), pItem->getLinkedUUID(), getCOF(), pItem->getName(), strDescr, LLAssetType::AT_LINK, cb);
}
bool LLCOFMgr::isLinkInCOF(const LLUUID& idItem) const
{
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
LLLinkedItemIDMatches f(gInventory.getLinkedItemID(idItem));
gInventory.collectDescendentsIf(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f);
return (!items.empty());
}
void LLCOFMgr::removeCOFItemLinks(const LLUUID& idItem)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
gInventory.collectDescendents(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
{
const LLInventoryItem* pItem = items.get(idxItem).get();
if ( (pItem->getIsLinkType()) && (idItem == pItem->getLinkedUUID()) )
gInventory.purgeObject(pItem->getUUID());
}
}
BOOL LLCOFMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
if (!isLinkInCOF(obj_id)) return FALSE;
// If a non-link somehow ended up in COF, allow deletion.
const LLInventoryObject *obj = gInventory.getObject(obj_id);
if (obj && !obj->getIsLinkType())
{
return FALSE;
}
// For now, don't allow direct deletion from the COF. Instead, force users
// to choose "Detach" or "Take Off".
return TRUE;
/*
const LLInventoryObject *obj = gInventory.getObject(obj_id);
if (!obj) return FALSE;
// Can't delete bodyparts, since this would be equivalent to removing the item.
if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
// Can't delete the folder link, since this is saved for bookkeeping.
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
return FALSE;
*/
}
// ============================================================================
// Attachment functions
//
void LLCOFMgr::addAttachment(const LLUUID& idItem)
{
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem) != m_PendingAttachLinks.end()) )
{
return;
}
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
m_PendingAttachLinks.push_back(idItem);
if (m_fLinkAttachments)
{
LLPointer<LLInventoryCallback> cb = new LLLinkAttachmentCallback();
addCOFItemLink(idItem, cb);
}
}
void LLCOFMgr::removeAttachment(const LLUUID& idItem)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
// Remove the attachment from the pending list
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem);
if (itPending != m_PendingAttachLinks.end())
m_PendingAttachLinks.erase(itPending);
if (m_fLinkAttachments)
{
removeCOFItemLinks(idItem);
}
}
void LLCOFMgr::setLinkAttachments(bool fEnable)
{
m_fLinkAttachments = fEnable;
if (m_fLinkAttachments)
linkPendingAttachments();
}
void LLCOFMgr::linkPendingAttachments()
{
LLPointer<LLInventoryCallback> cb = NULL;
for (uuid_vec_t::const_iterator itPending = m_PendingAttachLinks.begin(); itPending != m_PendingAttachLinks.end(); ++itPending)
{
const LLUUID& idAttachItem = *itPending;
if ( (gAgentAvatarp->isWearingAttachment(idAttachItem)) && (!isLinkInCOF(idAttachItem)) )
{
if (!cb)
cb = new LLLinkAttachmentCallback();
addCOFItemLink(idAttachItem, cb);
}
}
}
void LLCOFMgr::onLinkAttachmentComplete(const LLUUID& idItem)
{
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
// Remove the attachment from the pending list
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItemBase);
if (itPending != m_PendingAttachLinks.end())
m_PendingAttachLinks.erase(itPending);
// It may have been detached already in which case we should remove the COF link
if ( (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) )
removeCOFItemLinks(idItemBase);
}
void LLCOFMgr::updateAttachments()
{
/*const*/ LLVOAvatar* pAvatar = gAgentAvatarp;
if (!pAvatar)
return;
const LLUUID idCOF = getCOF();
// Grab all attachment links currently in COF
LLInventoryModel::item_array_t items;
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_OBJECT, true);
// Include attachments which should be in COF but don't have their link created yet
uuid_vec_t::iterator itPendingAttachLink = m_PendingAttachLinks.begin();
while (itPendingAttachLink != m_PendingAttachLinks.end())
{
const LLUUID& idItem = *itPendingAttachLink;
if ( (!pAvatar->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) )
{
itPendingAttachLink = m_PendingAttachLinks.erase(itPendingAttachLink);
continue;
}
LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
if (pItem)
items.push_back(pItem);
++itPendingAttachLink;
}
// Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on)
LLAgentWearables::userUpdateAttachments(items, !pAvatar->isFullyLoaded());
}
// ============================================================================
// Wearable functions
//
void LLCOFMgr::addWearable(const LLUUID& idItem)
{
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem) != m_PendingWearableLinks.end()) )
{
return;
}
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
m_PendingWearableLinks.push_back(idItem);
LLPointer<LLInventoryCallback> cb = new LLLinkWearableCallback();
addCOFItemLink(idItem, cb);
}
void LLCOFMgr::removeWearable(const LLUUID& idItem)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
// Remove the attachment from the pending list
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem);
if (itPending != m_PendingWearableLinks.end())
m_PendingWearableLinks.erase(itPending);
removeCOFItemLinks(idItem);
}
void LLCOFMgr::onLinkWearableComplete(const LLUUID& idItem)
{
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
// Remove the attachment from the pending list
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItemBase);
if (itPending != m_PendingWearableLinks.end())
m_PendingWearableLinks.erase(itPending);
// It may have been removed already in which case we should remove the COF link
if (!gAgentWearables.isWearingItem(idItemBase))
removeCOFItemLinks(idItemBase);
}
void LLCOFMgr::synchWearables()
{
const LLUUID idCOF = getCOF();
// Grab all wearable links currently in COF
LLInventoryModel::item_array_t items;
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_BODYPART, true);
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_CLOTHING, true);
// Transform collection of link LLViewerInventory pointers into collection of target LLUUIDs
uuid_vec_t curItems;
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
{
const LLViewerInventoryItem* pItem = items.get(idxItem);
if (!pItem)
continue;
curItems.push_back(pItem->getLinkedUUID());
}
// Grab the item UUIDs of all currently worn wearables
uuid_vec_t newItems;
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
{
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType, 0); // TODO: MULTI-WEARABLE
if (idItem.isNull())
continue;
newItems.push_back(idItem);
}
uuid_vec_t addItems, remItems;
LLCommonUtils::computeDifference(newItems, curItems, addItems, remItems);
// Add links for worn wearables that aren't linked yet
for (uuid_vec_t::const_iterator itItem = addItems.begin(); itItem != addItems.end(); ++itItem)
addWearable(*itItem);
// Remove links of wearables that aren't worn anymore
for (uuid_vec_t::const_iterator itItem = remItems.begin(); itItem != remItems.end(); ++itItem)
removeWearable(*itItem);
}
// ============================================================================
// Base outfit folder functions
//
void LLCOFMgr::addBOFLink(const LLUUID &idFolder, LLPointer<LLInventoryCallback> cb)
{
purgeBOFLink();
const LLViewerInventoryCategory* pFolder = gInventory.getCategory(idFolder);
if ( (pFolder) && (LLFolderType::FT_OUTFIT == pFolder->getPreferredType()) )
link_inventory_item(gAgent.getID(), idFolder, getCOF(), pFolder->getName(), "", LLAssetType::AT_LINK_FOLDER, cb);
}
void LLCOFMgr::purgeBOFLink()
{
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
gInventory.getDirectDescendentsOf(getCOF(), pFolders, pItems);
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
{
const LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
if ( (!pItem) || (LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) )
continue;
const LLViewerInventoryCategory* pLinkFolder = pItem->getLinkedCategory();
if ( (pLinkFolder) && (LLFolderType::FT_OUTFIT == pLinkFolder->getPreferredType()) )
gInventory.purgeObject(pItem->getUUID());
}
}
// ============================================================================

View File

@@ -1,90 +0,0 @@
/**
*
* Copyright (c) 2010, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llinventorymodel.h"
#include "llmemory.h"
#include "llviewerinventory.h"
// ============================================================================
class LLCOFMgr : public LLSingleton<LLCOFMgr>
{
/*
* Helper functions
*/
public:
void checkCOF();
void fetchCOF();
static const LLUUID getCOF() { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); }
static void getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
LLAssetType::EType typeAsset, bool fFollowFolderLinks);
bool isLinkInCOF(const LLUUID& idItem) const;
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
protected:
void addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb = NULL);
void addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb = NULL);
void removeCOFItemLinks(const LLUUID& idItem);
/*
* Attachment functions
*/
public:
void addAttachment(const LLUUID& idItem);
void removeAttachment(const LLUUID& idItem);
void synchAttachments();
protected:
void onLinkAttachmentComplete(const LLUUID& idItem);
void linkPendingAttachments();
void setLinkAttachments(bool fEnable);
void updateAttachments();
/*
* Wearable functions
*/
public:
void addWearable(const LLUUID& idItem);
void removeWearable(const LLUUID& idItem);
void synchWearables();
protected:
void onLinkWearableComplete(const LLUUID& idItem);
/*
* Base outfit folder functions
*/
public:
void addBOFLink(const LLUUID& idFolder, LLPointer<LLInventoryCallback> cb = NULL);
void purgeBOFLink();
/*
* Member variables
*/
protected:
bool m_fLinkAttachments;
uuid_vec_t m_PendingAttachLinks;
uuid_vec_t m_PendingWearableLinks;
protected:
LLCOFMgr() : m_fLinkAttachments(false) {}
private:
friend class LLCOFFetcher;
friend class LLCOFLinkTargetFetcher;
friend class LLDeferredAddLinkTargetFetcher;
friend class LLLinkAttachmentCallback;
friend class LLLinkWearableCallback;
friend class LLSingleton<LLCOFMgr>;
};
// ============================================================================

View File

@@ -81,10 +81,6 @@ DOHexEditor::DOHexEditor(const std::string& name, const LLRect& rect)
DOHexEditor::~DOHexEditor() DOHexEditor::~DOHexEditor()
{ {
gFocusMgr.releaseFocusIfNeeded(this); gFocusMgr.releaseFocusIfNeeded(this);
if(gEditMenuHandler == this)
{
gEditMenuHandler = NULL;
}
} }
LLView* DOHexEditor::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory) LLView* DOHexEditor::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory)
@@ -273,7 +269,8 @@ U32 DOHexEditor::getProperSelectionEnd()
BOOL DOHexEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL DOHexEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
{ {
return mScrollbar->handleScrollWheel( 0, 0, clicks ); mScrollbar->handleScrollWheel( 0, 0, clicks );
return TRUE;
} }
BOOL DOHexEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL DOHexEditor::handleMouseDown(S32 x, S32 y, MASK mask)

View File

@@ -30,7 +30,7 @@
#include "roles_constants.h" #include "roles_constants.h"
#include "llviewerregion.h" #include "llviewerregion.h"
#include "llpanelinventory.h" #include "llpanelobjectinventory.h"
#include "llinventorybridge.h" #include "llinventorybridge.h"
#include "llboost.h" #include "llboost.h"

View File

@@ -670,8 +670,10 @@ void LocalAssetBrowser::PerformTimedActions(void)
// one of the layer bitmaps has been updated, we need to rebake. // one of the layer bitmaps has been updated, we need to rebake.
if ( mLayerUpdated ) if ( mLayerUpdated )
{ {
LLVOAvatar* avatar = gAgentAvatarp; if (isAgentAvatarValid())
if (avatar) { avatar->forceBakeAllTextures(SLAM_FOR_DEBUG); } {
gAgentAvatarp->forceBakeAllTextures(SLAM_FOR_DEBUG);
}
mLayerUpdated = false; mLayerUpdated = false;
} }

View File

@@ -259,7 +259,7 @@ void LLFloaterSculptPreview::draw()
if (selected <= 0) if (selected <= 0)
{ {
gl_rect_2d_checkerboard(getScreenRect(),mPreviewRect); gl_rect_2d_checkerboard(calcScreenRect(),mPreviewRect);
LLGLDisable gls_alpha(GL_ALPHA_TEST); LLGLDisable gls_alpha(GL_ALPHA_TEST);
if(mImagep.notNull()) if(mImagep.notNull())

View File

@@ -65,6 +65,11 @@ class HippoFloaterXmlImpl : public LLFloater
private: private:
std::string mName; std::string mName;
bool mIsNotifyOnClose; bool mIsNotifyOnClose;
//Must retain handles to unregister notices.
typedef boost::signals2::scoped_connection notice_connection_t;
typedef boost::shared_ptr<notice_connection_t> notice_ptr_t;
std::map<LLUICtrl*, notice_ptr_t > mNotices;
}; };
@@ -260,7 +265,7 @@ void HippoFloaterXml::execute(const std::string &cmds)
// ******************************************************************** // ********************************************************************
// generic notification callbacks // generic notification callbacks
static void notify(LLUICtrl *ctrl, void *data) static void notifyCallback(LLUICtrl *ctrl)
{ {
std::string msg = "NOTIFY:"; std::string msg = "NOTIFY:";
msg += ctrl->getName(); msg += ctrl->getName();
@@ -269,11 +274,6 @@ static void notify(LLUICtrl *ctrl, void *data)
send_chat_from_viewer(msg, CHAT_TYPE_WHISPER, CHANNEL); send_chat_from_viewer(msg, CHAT_TYPE_WHISPER, CHANNEL);
} }
static void notify(void *data)
{
notify(static_cast<LLUICtrl*>(data), 0);
}
void HippoFloaterXmlImpl::onClose(bool quitting) void HippoFloaterXmlImpl::onClose(bool quitting)
{ {
if (mIsNotifyOnClose) if (mIsNotifyOnClose)
@@ -324,16 +324,19 @@ bool HippoFloaterXmlImpl::execute(LLUICtrl *ctrl,
bool set = (value != "0"); bool set = (value != "0");
if (HippoFloaterXmlImpl *floater = dynamic_cast<HippoFloaterXmlImpl*>(ctrl)) { if (HippoFloaterXmlImpl *floater = dynamic_cast<HippoFloaterXmlImpl*>(ctrl)) {
floater->mIsNotifyOnClose = set; floater->mIsNotifyOnClose = set;
} else if (LLButton *button = dynamic_cast<LLButton*>(ctrl)) { } else if (LLButton *button = dynamic_cast<LLButton*>(ctrl))
{
if (set) if (set)
button->setClickedCallback(notify, ctrl); floater->mNotices[button] = notice_ptr_t(new notice_connection_t(button->setClickedCallback(boost::bind(&notifyCallback, ctrl))));
else else
button->setClickedCallback(0, 0); floater->mNotices.erase(button);
} else { }
else
{
if (set) if (set)
ctrl->setCommitCallback(notify); floater->mNotices[ctrl] = notice_ptr_t(new notice_connection_t(ctrl->setCommitCallback(boost::bind(&notifyCallback, ctrl))));
else else
ctrl->setCommitCallback(0); floater->mNotices.erase(ctrl);
} }
} }
} }

View File

@@ -3698,12 +3698,6 @@ void LLAgent::setTeleportState(ETeleportState state)
default: default:
break; break;
} }
// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Version: 1.23.4 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b
if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) )
{
gRlvHandler.setCanCancelTp(true);
}
// [/RLVa:KB]
} }
void LLAgent::stopCurrentAnimations() void LLAgent::stopCurrentAnimations()
@@ -3840,12 +3834,11 @@ void LLAgent::sendAgentSetAppearance()
{ {
if (!isAgentAvatarValid()) return; if (!isAgentAvatarValid()) return;
if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && !gAgentCamera.cameraCustomizeAvatar())) if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
{ {
return; return;
} }
llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl; llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
//dumpAvatarTEs( "sendAgentSetAppearance()" ); //dumpAvatarTEs( "sendAgentSetAppearance()" );
@@ -3875,7 +3868,7 @@ void LLAgent::sendAgentSetAppearance()
// is texture data current relative to wearables? // is texture data current relative to wearables?
// KLW - TAT this will probably need to check the local queue. // KLW - TAT this will probably need to check the local queue.
BOOL textures_current = !gAgentAvatarp->hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded(); BOOL textures_current = gAgentAvatarp->areTexturesCurrent();
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
{ {
@@ -3887,8 +3880,8 @@ void LLAgent::sendAgentSetAppearance()
continue; continue;
} }
// IMG_DEFAULT_AVATAR means not baked // IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
if (!gAgentAvatarp->isTextureDefined(texture_index)) if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
{ {
textures_current = FALSE; textures_current = FALSE;
break; break;
@@ -3901,12 +3894,17 @@ void LLAgent::sendAgentSetAppearance()
llinfos << "TAT: Sending cached texture data" << llendl; llinfos << "TAT: Sending cached texture data" << llendl;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{ {
BOOL generate_valid_hash = TRUE;
if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
{
generate_valid_hash = FALSE;
llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;
}
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, true); const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
if (hash.notNull()) if (hash.notNull())
{ {
const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
msg->nextBlockFast(_PREHASH_WearableData); msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash); msg->addUUIDFast(_PREHASH_CacheID, hash);
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index); msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);

View File

@@ -2392,7 +2392,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
gFocusMgr.setKeyboardFocus( NULL ); gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL ); gFocusMgr.setMouseCapture( NULL );
LLVOAvatar::onCustomizeStart(); LLVOAvatarSelf::onCustomizeStart();
if (isAgentAvatarValid()) if (isAgentAvatarValid())
{ {
@@ -2418,10 +2418,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
{ {
setAnimationDuration(gSavedSettings.getF32("ZoomTime")); setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
} }
//gAgentAvatarp->invalidateAll();
//gAgentAvatarp->updateMeshTextures();
} }
gAgentAvatarp->invalidateAll();
gAgentAvatarp->updateMeshTextures();
gAgentCamera.setFocusGlobal(LLVector3d::zero); gAgentCamera.setFocusGlobal(LLVector3d::zero);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,33 +2,26 @@
* @file llagentwearables.h * @file llagentwearables.h
* @brief LLAgentWearables class header file * @brief LLAgentWearables class header file
* *
* $LicenseInfo:firstyear=2000&license=viewergpl$ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
*
* Copyright (c) 2000-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlife.com/developers/opensource/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*
*/ */
#ifndef LL_LLAGENTWEARABLES_H #ifndef LL_LLAGENTWEARABLES_H
@@ -63,16 +56,16 @@ public:
LLAgentWearables(); LLAgentWearables();
virtual ~LLAgentWearables(); virtual ~LLAgentWearables();
void setAvatarObject(LLVOAvatarSelf *avatar); void setAvatarObject(LLVOAvatarSelf *avatar);
void createStandardWearables(BOOL female); void createStandardWearables();
void cleanup(); void cleanup();
//void dump(); void dump();
// LLInitClass interface // LLInitClass interface
static void initClass(); static void initClass();
protected: protected:
void createStandardWearablesDone(S32 type, U32 index/* = 0*/); void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
void createStandardWearablesAllDone(); void createStandardWearablesAllDone();
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Queries // Queries
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@@ -83,18 +76,16 @@ public:
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const; BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
BOOL areWearablesLoaded() const; BOOL areWearablesLoaded() const;
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
void updateWearablesLoaded(); void updateWearablesLoaded();
//void checkWearablesLoaded() const; void checkWearablesLoaded() const;
//bool canMoveWearable(const LLUUID& item_id, bool closer_to_body); bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1. // Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
//bool canWearableBeRemoved(const LLWearable* wearable) const; bool canWearableBeRemoved(const LLWearable* wearable) const;
//void animateAllWearableParams(F32 delta, BOOL upload_bake); void animateAllWearableParams(F32 delta, BOOL upload_bake);
BOOL needsReplacement(LLWearableType::EType wearableType, S32 remove);
//U32 getWearablePermMask(LLWearableType::EType type) const;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Accessors // Accessors
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@@ -109,11 +100,11 @@ public:
LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/); LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
LLWearable* getTopWearable(const LLWearableType::EType type); LLWearable* getTopWearable(const LLWearableType::EType type);
LLWearable* getBottomWearable(const LLWearableType::EType type); LLWearable* getBottomWearable(const LLWearableType::EType type);
U32 getWearableCount(const LLWearableType::EType type) const; U32 getWearableCount(const LLWearableType::EType type) const;
U32 getWearableCount(const U32 tex_index) const; U32 getWearableCount(const U32 tex_index) const;
static const U32 MAX_CLOTHING_PER_TYPE = 1; static const U32 MAX_CLOTHING_PER_TYPE = 5;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@@ -129,31 +120,20 @@ private:
void popWearable(const LLWearableType::EType type, U32 index); void popWearable(const LLWearableType::EType type, U32 index);
public: public:
void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable); void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove); void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
void setWearableName(const LLUUID& item_id, const std::string& new_name); void setWearableName(const LLUUID& item_id, const std::string& new_name);
//void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index); void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
U32 getWearableIndex(const LLWearable *wearable) const; U32 getWearableIndex(const LLWearable *wearable) const;
protected: protected:
void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ); void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb, void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
LLWearable* wearable, LLWearable* wearable,
const LLUUID& category_id = LLUUID::null, const LLUUID& category_id = LLUUID::null,
BOOL notify = TRUE); BOOL notify = TRUE);
/**
* @brief Only public because of addWearableToAgentInventoryCallback.
*
* NOTE: Do not call this method unless you are the inventory callback.
* NOTE: This can suffer from race conditions when working on the
* same values for index.
* @param index The index in mWearableEntry.
* @param item_id The inventory item id of the new wearable to wear.
* @param wearable The actual wearable data.
*/
void addWearabletoAgentInventoryDone(const LLWearableType::EType type, void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index, const U32 index,
const LLUUID& item_id, const LLUUID& item_id,
@@ -166,15 +146,15 @@ protected:
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public: public:
//static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null); static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
//static void editWearable(const LLUUID& item_id); static void editWearable(const LLUUID& item_id);
//bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
//void requestEditingWearable(const LLUUID& item_id); void requestEditingWearable(const LLUUID& item_id);
//void editWearableIfRequested(const LLUUID& item_id); void editWearableIfRequested(const LLUUID& item_id);
private: private:
//LLUUID mItemToEdit; LLUUID mItemToEdit;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Removing wearables // Removing wearables
@@ -185,7 +165,6 @@ private:
void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/); void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
protected: protected:
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response); static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
static void userRemoveAllClothesStep2(BOOL proceed, void* userdata ); // userdata is NULL
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Server Communication // Server Communication
@@ -201,7 +180,7 @@ protected:
void sendAgentWearablesRequest(); void sendAgentWearablesRequest();
void queryWearableCache(); void queryWearableCache();
void updateServer(); void updateServer();
static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata ); static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Outfits // Outfits
@@ -210,27 +189,20 @@ public:
// Should only be called if we *know* we've never done so before, since users may // Should only be called if we *know* we've never done so before, since users may
// not want the Library outfits to stay in their quick outfit selector and can delete them. // not want the Library outfits to stay in their quick outfit selector and can delete them.
//void populateMyOutfitsFolder(); void populateMyOutfitsFolder();
void makeNewOutfit(
const std::string& new_folder_name,
const LLDynamicArray<S32>& wearables_to_include,
const LLDynamicArray<S32>& attachments_to_include,
BOOL rename_clothing);
private:
private:
void makeNewOutfitDone(S32 type, U32 index); void makeNewOutfitDone(S32 type, U32 index);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Save Wearables // Save Wearables
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public: public:
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found ); void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE, void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
const std::string new_name = ""); const std::string new_name = "");
void saveAllWearables(); void saveAllWearables();
void revertWearable( LLWearableType::EType type, const U32 index); void revertWearable(const LLWearableType::EType type, const U32 index, bool set_by_user=false);
void revertAllWearables();
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Static UI hooks // Static UI hooks
@@ -238,15 +210,10 @@ public:
public: public:
static void userRemoveWearable(const LLWearableType::EType &type, const U32 &index); static void userRemoveWearable(const LLWearableType::EType &type, const U32 &index);
static void userRemoveWearablesOfType(const LLWearableType::EType &type); static void userRemoveWearablesOfType(const LLWearableType::EType &type);
static void userRemoveAllClothes();
typedef std::vector<LLViewerObject*> llvo_vec_t;
// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array); typedef std::vector<LLViewerObject*> llvo_vec_t;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a
// Not the best way to go about this but other attempts changed far too much LL code to be a viable solution static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
// [/SL:KB]
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array); static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userRemoveAllAttachments(); static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
@@ -258,7 +225,7 @@ public:
// Signals // Signals
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public: public:
/*typedef boost::function<void()> loading_started_callback_t; typedef boost::function<void()> loading_started_callback_t;
typedef boost::signals2::signal<void()> loading_started_signal_t; typedef boost::signals2::signal<void()> loading_started_signal_t;
boost::signals2::connection addLoadingStartedCallback(loading_started_callback_t cb); boost::signals2::connection addLoadingStartedCallback(loading_started_callback_t cb);
@@ -267,9 +234,11 @@ public:
boost::signals2::connection addLoadedCallback(loaded_callback_t cb); boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
void notifyLoadingStarted(); void notifyLoadingStarted();
void notifyLoadingFinished();*/ void notifyLoadingFinished();
private: private:
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Member variables // Member variables
@@ -281,6 +250,12 @@ private:
static BOOL mInitialWearablesUpdateReceived; static BOOL mInitialWearablesUpdateReceived;
BOOL mWearablesLoaded; BOOL mWearablesLoaded;
std::set<LLUUID> mItemsAwaitingWearableUpdate;
/**
* True if agent's outfit is being changed now.
*/
BOOL mCOFChangeInProgress;
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Support classes // Support classes
@@ -300,31 +275,22 @@ private:
class addWearableToAgentInventoryCallback : public LLInventoryCallback class addWearableToAgentInventoryCallback : public LLInventoryCallback
{ {
public: public:
enum { enum ETodo
{
CALL_NONE = 0, CALL_NONE = 0,
CALL_UPDATE = 1, CALL_UPDATE = 1,
CALL_RECOVERDONE = 2, CALL_RECOVERDONE = 2,
CALL_CREATESTANDARDDONE = 4, CALL_CREATESTANDARDDONE = 4,
CALL_MAKENEWOUTFITDONE = 8 CALL_MAKENEWOUTFITDONE = 8,
} EType; CALL_WEARITEM = 16
};
/**
* @brief Construct a callback for dealing with the wearables.
*
* Would like to pass the agent in here, but we can't safely
* count on it being around later. Just use gAgent directly.
* @param cb callback to execute on completion (??? unused ???)
* @param index Index for the wearable in the agent
* @param wearable The wearable data.
* @param todo Bitmask of actions to take on completion.
*/
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb, addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
LLWearableType::EType type, LLWearableType::EType type,
U32 index, U32 index,
LLWearable* wearable, LLWearable* wearable,
U32 todo = CALL_NONE); U32 todo = CALL_NONE);
virtual void fire(const LLUUID& inv_item); virtual void fire(const LLUUID& inv_item);
private: private:
LLWearableType::EType mType; LLWearableType::EType mType;
U32 mIndex; U32 mIndex;

View File

@@ -0,0 +1,607 @@
/**
* @file llagentwearablesfetch.cpp
* @brief LLAgentWearblesFetch class implementation
*
* $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$
*/
#include "llviewerprecompiledheaders.h"
#include "llagentwearablesfetch.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
#include "llstartup.h"
#include "llvoavatarself.h"
class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
{
public:
LLOrderMyOutfitsOnDestroy() {};
virtual ~LLOrderMyOutfitsOnDestroy()
{
if (!LLApp::isRunning())
{
llwarns << "called during shutdown, skipping" << llendl;
return;
}
const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if (my_outfits_id.isNull()) return;
LLInventoryModel::cat_array_t* cats;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
if (!cats) return;
//My Outfits should at least contain saved initial outfit and one another outfit
if (cats->size() < 2)
{
llwarning("My Outfits category was not populated properly", 0);
return;
}
llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
outfit_iter != cats->end(); ++outfit_iter)
{
const LLUUID& cat_id = (*outfit_iter)->getUUID();
if (cat_id.isNull()) continue;
// saved initial outfit already contains wearables ordering information
if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
}
llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
}
/* virtual */ void fire(const LLUUID& inv_item) {};
};
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
LLInventoryFetchDescendentsObserver(cof_id)
{
if (isAgentAvatarValid())
{
gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
}
}
LLInitialWearablesFetch::~LLInitialWearablesFetch()
{
}
// virtual
void LLInitialWearablesFetch::done()
{
// Delay processing the actual results of this so it's not handled within
// gInventory.notifyObservers. The results will be handled in the next
// idle tick instead.
gInventory.removeObserver(this);
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
if (isAgentAvatarValid())
{
gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
}
}
void LLInitialWearablesFetch::add(InitialWearableData &data)
{
mAgentInitialWearables.push_back(data);
}
void LLInitialWearablesFetch::processContents()
{
if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
{
delete this;
return ;
}
// Fetch the wearable items from the Current Outfit Folder
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
LLFindWearables is_wearable;
llassert_always(mComplete.size() != 0);
gInventory.collectDescendentsIf(mComplete.front(), cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH, is_wearable);
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
if (wearable_array.count() > 0)
{
gAgentWearables.notifyLoadingStarted();
LLAppearanceMgr::instance().updateAppearanceFromCOF();
}
else
{
// if we're constructing the COF from the wearables message, we don't have a proper outfit link
LLAppearanceMgr::instance().setOutfitDirty(true);
processWearablesMessage();
}
delete this;
}
class LLFetchAndLinkObserver: public LLInventoryFetchItemsObserver
{
public:
LLFetchAndLinkObserver(uuid_vec_t& ids):
LLInventoryFetchItemsObserver(ids)
{
}
~LLFetchAndLinkObserver()
{
}
virtual void done()
{
gInventory.removeObserver(this);
// Link to all fetched items in COF.
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
for (uuid_vec_t::iterator it = mIDs.begin();
it != mIDs.end();
++it)
{
LLUUID id = *it;
LLViewerInventoryItem *item = gInventory.getItem(*it);
if (!item)
{
llwarns << "fetch failed!" << llendl;
continue;
}
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
LLAppearanceMgr::instance().getCOF(),
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
link_waiter);
}
}
};
void LLInitialWearablesFetch::processWearablesMessage()
{
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
{
const LLUUID current_outfit_id = LLAppearanceMgr::instance().getCOF();
uuid_vec_t ids;
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
{
// Populate the current outfit folder with links to the wearables passed in the message
InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
if (wearable_data->mAssetID.notNull())
{
ids.push_back(wearable_data->mItemID);
}
else
{
llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
delete wearable_data;
}
}
// Add all current attachments to the requested items as well.
if (isAgentAvatarValid())
{
for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
{
LLViewerJointAttachment* attachment = iter->second;
if (!attachment) continue;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject* attached_object = (*attachment_iter);
if (!attached_object) continue;
const LLUUID& item_id = attached_object->getAttachmentItemID();
if (item_id.isNull()) continue;
ids.push_back(item_id);
}
}
}
// Need to fetch the inventory items for ids, then create links to them after they arrive.
LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
fetcher->startFetch();
// If no items to be fetched, done will never be triggered.
// TODO: Change LLInventoryFetchItemsObserver::fetchItems to trigger done() on this condition.
if (fetcher->isFinished())
{
fetcher->done();
}
else
{
gInventory.addObserver(fetcher);
}
}
else
{
LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL;
}
}
LLLibraryOutfitsFetch::LLLibraryOutfitsFetch(const LLUUID& my_outfits_id) :
LLInventoryFetchDescendentsObserver(my_outfits_id),
mCurrFetchStep(LOFS_FOLDER),
mOutfitsPopulated(false)
{
llinfos << "created" << llendl;
mMyOutfitsID = LLUUID::null;
mClothingID = LLUUID::null;
mLibraryClothingID = LLUUID::null;
mImportedClothingID = LLUUID::null;
mImportedClothingName = "Imported Library Clothing";
}
LLLibraryOutfitsFetch::~LLLibraryOutfitsFetch()
{
llinfos << "destroyed" << llendl;
}
void LLLibraryOutfitsFetch::done()
{
llinfos << "start" << llendl;
// Delay this until idle() routine, since it's a heavy operation and
// we also can't have it run within notifyObservers.
doOnIdleOneTime(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this));
gInventory.removeObserver(this); // Prevent doOnIdleOneTime from being added twice.
}
void LLLibraryOutfitsFetch::doneIdle()
{
llinfos << "start" << llendl;
gInventory.addObserver(this); // Add this back in since it was taken out during ::done()
switch (mCurrFetchStep)
{
case LOFS_FOLDER:
folderDone();
mCurrFetchStep = LOFS_OUTFITS;
break;
case LOFS_OUTFITS:
outfitsDone();
mCurrFetchStep = LOFS_LIBRARY;
break;
case LOFS_LIBRARY:
libraryDone();
mCurrFetchStep = LOFS_IMPORTED;
break;
case LOFS_IMPORTED:
importedFolderDone();
mCurrFetchStep = LOFS_CONTENTS;
break;
case LOFS_CONTENTS:
contentsDone();
break;
default:
llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl;
mOutfitsPopulated = TRUE;
break;
}
// We're completely done. Cleanup.
if (mOutfitsPopulated)
{
gInventory.removeObserver(this);
delete this;
return;
}
}
void LLLibraryOutfitsFetch::folderDone()
{
llinfos << "start" << llendl;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH);
// Early out if we already have items in My Outfits
// except the case when My Outfits contains just initial outfit
if (cat_array.count() > 1)
{
mOutfitsPopulated = true;
return;
}
mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
// If Library->Clothing->Initial Outfits exists, use that.
LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
cat_array.clear();
gInventory.collectDescendentsIf(mLibraryClothingID,
cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH,
matchFolderFunctor);
if (cat_array.count() > 0)
{
const LLViewerInventoryCategory *cat = cat_array.get(0);
mLibraryClothingID = cat->getUUID();
}
mComplete.clear();
// Get the complete information on the items in the inventory.
uuid_vec_t folders;
folders.push_back(mClothingID);
folders.push_back(mLibraryClothingID);
setFetchIDs(folders);
startFetch();
if (isFinished())
{
done();
}
}
void LLLibraryOutfitsFetch::outfitsDone()
{
llinfos << "start" << llendl;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
uuid_vec_t folders;
// Collect the contents of the Library's Clothing folder
gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH);
llassert(cat_array.count() > 0);
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
iter != cat_array.end();
++iter)
{
const LLViewerInventoryCategory *cat = iter->get();
// Get the names and id's of every outfit in the library, skip "Ruth"
// because it's a low quality legacy outfit
if (cat->getName() != "Ruth")
{
// Get the name of every outfit in the library
folders.push_back(cat->getUUID());
mLibraryClothingFolders.push_back(cat->getUUID());
}
}
cat_array.clear();
wearable_array.clear();
// Check if you already have an "Imported Library Clothing" folder
LLNameCategoryCollector matchFolderFunctor(mImportedClothingName);
gInventory.collectDescendentsIf(mClothingID,
cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH,
matchFolderFunctor);
if (cat_array.size() > 0)
{
const LLViewerInventoryCategory *cat = cat_array.get(0);
mImportedClothingID = cat->getUUID();
}
mComplete.clear();
setFetchIDs(folders);
startFetch();
if (isFinished())
{
done();
}
}
class LLLibraryOutfitsCopyDone: public LLInventoryCallback
{
public:
LLLibraryOutfitsCopyDone(LLLibraryOutfitsFetch * fetcher):
mFireCount(0), mLibraryOutfitsFetcher(fetcher)
{
}
virtual ~LLLibraryOutfitsCopyDone()
{
if (!LLApp::isExiting() && mLibraryOutfitsFetcher)
{
gInventory.addObserver(mLibraryOutfitsFetcher);
mLibraryOutfitsFetcher->done();
}
}
/* virtual */ void fire(const LLUUID& inv_item)
{
mFireCount++;
}
private:
U32 mFireCount;
LLLibraryOutfitsFetch * mLibraryOutfitsFetcher;
};
// Copy the clothing folders from the library into the imported clothing folder
void LLLibraryOutfitsFetch::libraryDone()
{
llinfos << "start" << llendl;
if (mImportedClothingID != LLUUID::null)
{
// Skip straight to fetching the contents of the imported folder
importedFolderFetch();
return;
}
// Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone.
gInventory.removeObserver(this);
LLPointer<LLInventoryCallback> copy_waiter = new LLLibraryOutfitsCopyDone(this);
mImportedClothingID = gInventory.createNewCategory(mClothingID,
LLFolderType::FT_NONE,
mImportedClothingName);
// Copy each folder from library into clothing unless it already exists.
for (uuid_vec_t::const_iterator iter = mLibraryClothingFolders.begin();
iter != mLibraryClothingFolders.end();
++iter)
{
const LLUUID& src_folder_id = (*iter); // Library clothing folder ID
const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id);
if (!cat)
{
llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl;
continue;
}
if (!LLAppearanceMgr::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id))
{
llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl;
continue;
}
// Don't copy the category if it already exists.
LLNameCategoryCollector matchFolderFunctor(cat->getName());
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
gInventory.collectDescendentsIf(mImportedClothingID,
cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH,
matchFolderFunctor);
if (cat_array.size() > 0)
{
continue;
}
LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID,
LLFolderType::FT_NONE,
cat->getName());
LLAppearanceMgr::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter);
}
}
void LLLibraryOutfitsFetch::importedFolderFetch()
{
llinfos << "start" << llendl;
// Fetch the contents of the Imported Clothing Folder
uuid_vec_t folders;
folders.push_back(mImportedClothingID);
mComplete.clear();
setFetchIDs(folders);
startFetch();
if (isFinished())
{
done();
}
}
void LLLibraryOutfitsFetch::importedFolderDone()
{
llinfos << "start" << llendl;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
uuid_vec_t folders;
// Collect the contents of the Imported Clothing folder
gInventory.collectDescendents(mImportedClothingID, cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH);
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
iter != cat_array.end();
++iter)
{
const LLViewerInventoryCategory *cat = iter->get();
// Get the name of every imported outfit
folders.push_back(cat->getUUID());
mImportedClothingFolders.push_back(cat->getUUID());
}
mComplete.clear();
setFetchIDs(folders);
startFetch();
if (isFinished())
{
done();
}
}
void LLLibraryOutfitsFetch::contentsDone()
{
llinfos << "start" << llendl;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
folder_iter != mImportedClothingFolders.end();
++folder_iter)
{
const LLUUID &folder_id = (*folder_iter);
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
if (!cat)
{
llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl;
continue;
}
//initial outfit should be already in My Outfits
if (cat->getName() == LLStartUp::getInitialOutfitName()) continue;
// First, make a folder in the My Outfits directory.
LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName());
cat_array.clear();
wearable_array.clear();
// Collect the contents of each imported clothing folder, so we can create new outfit links for it
gInventory.collectDescendents(folder_id, cat_array, wearable_array,
LLInventoryModel::EXCLUDE_TRASH);
for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin();
wearable_iter != wearable_array.end();
++wearable_iter)
{
const LLViewerInventoryItem *item = wearable_iter->get();
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
new_outfit_folder_id,
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
order_myoutfits_on_destroy);
}
}
mOutfitsPopulated = true;
}

View File

@@ -0,0 +1,114 @@
/**
* @file llagentwearablesinitialfetch.h
* @brief LLAgentWearablesInitialFetch class header file
*
* $LicenseInfo:firstyear=2000&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_LLAGENTWEARABLESINITIALFETCH_H
#define LL_LLAGENTWEARABLESINITIALFETCH_H
#include "llinventoryobserver.h"
#include "llwearabletype.h"
#include "lluuid.h"
//--------------------------------------------------------------------
// InitialWearablesFetch
//
// This grabs contents from the COF and processes them.
// The processing is handled in idle(), i.e. outside of done(),
// to avoid gInventory.notifyObservers recursion.
//--------------------------------------------------------------------
class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
{
LOG_CLASS(LLInitialWearablesFetch);
public:
LLInitialWearablesFetch(const LLUUID& cof_id);
~LLInitialWearablesFetch();
virtual void done();
struct InitialWearableData
{
LLWearableType::EType mType;
LLUUID mItemID;
LLUUID mAssetID;
InitialWearableData(LLWearableType::EType type, LLUUID& itemID, LLUUID& assetID) :
mType(type),
mItemID(itemID),
mAssetID(assetID)
{}
};
void add(InitialWearableData &data);
protected:
void processWearablesMessage();
void processContents();
private:
typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg
};
//--------------------------------------------------------------------
// InitialWearablesFetch
//
// This grabs outfits from the Library and copies those over to the user's
// outfits folder, typically during first-ever login.
//--------------------------------------------------------------------
class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
{
public:
enum ELibraryOutfitFetchStep
{
LOFS_FOLDER = 0,
LOFS_OUTFITS,
LOFS_LIBRARY,
LOFS_IMPORTED,
LOFS_CONTENTS
};
LLLibraryOutfitsFetch(const LLUUID& my_outfits_id);
~LLLibraryOutfitsFetch();
virtual void done();
void doneIdle();
LLUUID mMyOutfitsID;
void importedFolderFetch();
protected:
void folderDone();
void outfitsDone();
void libraryDone();
void importedFolderDone();
void contentsDone();
enum ELibraryOutfitFetchStep mCurrFetchStep;
uuid_vec_t mLibraryClothingFolders;
uuid_vec_t mImportedClothingFolders;
bool mOutfitsPopulated;
LLUUID mClothingID;
LLUUID mLibraryClothingID;
LLUUID mImportedClothingID;
std::string mImportedClothingName;
};
#endif // LL_AGENTWEARABLESINITIALFETCH_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
/**
* @file llappearancemgr.h
* @brief Manager for initiating appearance changes on the viewer
*
* $LicenseInfo:firstyear=2004&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_LLAPPEARANCEMGR_H
#define LL_LLAPPEARANCEMGR_H
#include "llsingleton.h"
#include "llagentwearables.h"
#include "llcallbacklist.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llviewerinventory.h"
class LLWearable;
class LLWearableHoldingPattern;
class LLInventoryCallback;
class LLOutfitUnLockTimer;
class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
{
LOG_CLASS(LLAppearanceMgr);
friend class LLSingleton<LLAppearanceMgr>;
friend class LLOutfitUnLockTimer;
public:
typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
void updateAppearanceFromCOF(bool update_base_outfit_ordering = false);
bool needToSaveCOF();
void updateCOF(const LLUUID& category, bool append = false);
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new,
LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new,
bool append = false, const LLUUID& idOutfit = LLUUID::null);
// [/RLVa:KB]
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append);
void wearOutfitByName(const std::string& name);
void changeOutfit(bool proceed, const LLUUID& category, bool append);
void replaceCurrentOutfit(const LLUUID& new_outfit);
void renameOutfit(const LLUUID& outfit_id);
void takeOffOutfit(const LLUUID& cat_id);
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
LLAssetType::EType type,
S32 max_items,
LLInventoryModel::item_array_t& items_to_kill);
void enforceItemRestrictions();
// Copy all items and the src category itself.
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb);
// Return whether this folder contains minimal contents suitable for making a full outfit.
BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id);
// Determine whether a given outfit can be removed.
bool getCanRemoveOutfit(const LLUUID& outfit_cat_id);
// Determine whether we're wearing any of the outfit contents (excluding body parts).
static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id);
// Determine whether we can add anything (but body parts) from the outfit contents to COF.
static bool getCanAddToCOF(const LLUUID& outfit_cat_id);
// Determine whether we can replace current outfit with the given one.
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
// Copy all items in a category.
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb);
// Find the Current Outfit folder.
const LLUUID getCOF() const;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
bool getBaseOutfitName(std::string &name);
// find the UUID of the currently worn outfit (Base Outfit)
const LLUUID getBaseOutfitUUID();
// Wear/attach an item (from a user's inventory) on the agent
bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true, bool replace = false, LLPointer<LLInventoryCallback> cb = NULL);
// Update the displayed outfit name in UI.
void updatePanelOutfitName(const std::string& name);
void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
// For debugging - could be moved elsewhere.
void dumpCat(const LLUUID& cat_id, const std::string& msg);
void dumpItemArray(const LLInventoryModel::item_array_t& items, const std::string& msg);
// Attachment link management
void unregisterAttachment(const LLUUID& item_id);
void registerAttachment(const LLUUID& item_id);
void setAttachmentInvLinkEnable(bool val);
// utility function for bulk linking.
void linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb);
// Add COF link to individual item.
void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
// Remove COF entries
void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
// Add COF link to ensemble folder.
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
//has the current outfit changed since it was loaded?
bool isOutfitDirty() { return mOutfitIsDirty; }
// set false if you just loaded the outfit, true otherwise
void setOutfitDirty(bool isDirty) { mOutfitIsDirty = isDirty; }
// manually compare ouftit folder link to COF to see if outfit has changed.
// should only be necessary to do on initial login.
void updateIsDirty();
// Called when self avatar is first fully visible.
void onFirstFullyVisible();
// Create initial outfits from library.
void autopopulateOutfits();
// Copy initial gestures from library.
void copyLibraryGestures();
void wearBaseOutfit();
// Overrides the base outfit with the content from COF
// @return false if there is no base outfit
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
void removeItemFromAvatar(const LLUUID& item_id);
LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items);
//Divvy items into arrays by wearable type
static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
//Check ordering information on wearables stored in links' descriptions and update if it is invalid
// COF is processed if cat_id is not specified
void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null, bool update_base_outfit_ordering = false);
bool isOutfitLocked() { return mOutfitLocked; }
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
private:
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
void getDescendentsOfAssetType(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLAssetType::EType type,
bool follow_folder_links);
void getUserDescendents(const LLUUID& category,
LLInventoryModel::item_array_t& wear_items,
LLInventoryModel::item_array_t& obj_items,
LLInventoryModel::item_array_t& gest_items,
bool follow_folder_links);
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
void purgeBaseOutfitLink(const LLUUID& category);
static void onOutfitRename(const LLSD& notification, const LLSD& response);
void setOutfitLocked(bool locked);
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
/**
* Lock for blocking operations on outfit until server reply or timeout exceed
* to avoid unsynchronized outfit state or performing duplicate operations.
*/
bool mOutfitLocked;
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
//////////////////////////////////////////////////////////////////////////////////
// Item-specific convenience functions
public:
// Is this in the COF?
BOOL getIsInCOF(const LLUUID& obj_id) const;
// Is this in the COF and can the user delete it from the COF?
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
/**
* Checks if COF contains link to specified object.
*/
static bool isLinkInCOF(const LLUUID& obj_id);
};
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
{
public:
LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering = false);
virtual ~LLUpdateAppearanceOnDestroy();
/* virtual */ void fire(const LLUUID& inv_item);
private:
U32 mFireCount;
bool mUpdateBaseOrder;
};
#define SUPPORT_ENSEMBLES 0
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
// Invoke a given callable after category contents are fully fetched.
void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
// Wear all items in a uuid vector.
void wear_multiple(const uuid_vec_t& ids, bool replace);
#endif

View File

@@ -3583,7 +3583,7 @@ void LLAppViewer::badNetworkHandler()
std::string grid_support_msg = ""; std::string grid_support_msg = "";
if (!gHippoGridManager->getCurrentGrid()->getSupportUrl().empty()) if (!gHippoGridManager->getCurrentGrid()->getSupportUrl().empty())
{ {
grid_support_msg = "\n\nOr visit the gird support page at: \n " grid_support_msg = "\n\nOr visit the grid support page at: \n "
+ gHippoGridManager->getCurrentGrid()->getSupportUrl(); + gHippoGridManager->getCurrentGrid()->getSupportUrl();
} }
std::ostringstream message; std::ostringstream message;
@@ -3915,7 +3915,7 @@ void LLAppViewer::idle()
return; return;
} }
gViewerWindow->handlePerFrameHover(); gViewerWindow->updateUI();
/////////////////////////////////////// ///////////////////////////////////////
// Agent and camera movement // Agent and camera movement
@@ -4642,13 +4642,9 @@ void LLAppViewer::handleLoginComplete()
{ {
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
} }
writeDebugInfo();
// [RLVa:KB] - Checked: 2010-09-27 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b mOnLoginCompleted();
if (rlv_handler_t::isEnabled())
{ writeDebugInfo();
gRlvHandler.onLoginComplete();
}
// [/RLVa:KB]
} }

View File

@@ -160,6 +160,11 @@ public:
void handleLoginComplete(); void handleLoginComplete();
LLAllocator & getAllocator() { return mAlloc; } LLAllocator & getAllocator() { return mAlloc; }
// On LoginCompleted callback
typedef boost::signals2::signal<void (void)> login_completed_signal_t;
login_completed_signal_t mOnLoginCompleted;
boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
void purgeCache(); // Clear the local cache. void purgeCache(); // Clear the local cache.

View File

@@ -34,19 +34,12 @@
#include "llassetuploadresponders.h" #include "llassetuploadresponders.h"
// library includes
#include "lleconomy.h"
#include "llfocusmgr.h"
#include "llnotifications.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
// viewer includes // viewer includes
#include "llagent.h" #include "llagent.h"
#include "llcompilequeue.h" #include "llcompilequeue.h"
#include "llfloaterbuycurrency.h" #include "llfloaterbuycurrency.h"
#include "llnotify.h" #include "llinventorydefines.h"
#include "llinventorymodel.h" #include "llinventoryobserver.h"
#include "llinventorypanel.h" #include "llinventorypanel.h"
#include "llpanelmaininventory.h" #include "llpanelmaininventory.h"
#include "llpermissionsflags.h" #include "llpermissionsflags.h"
@@ -63,6 +56,18 @@
#include "llviewermenufile.h" #include "llviewermenufile.h"
#include "llviewerwindow.h" #include "llviewerwindow.h"
#include "lltexlayer.h" #include "lltexlayer.h"
#include "lltrans.h"
// library includes
#include "lldir.h"
#include "lleconomy.h"
#include "llfocusmgr.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include "llvfs.h"
#include "statemachine/aifilepicker.h" #include "statemachine/aifilepicker.h"
// When uploading multiple files, don't display any of them when uploading more than this number. // When uploading multiple files, don't display any of them when uploading more than this number.
@@ -70,14 +75,15 @@ static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5;
void dialog_refresh_all(); void dialog_refresh_all();
void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type, void on_new_single_inventory_upload_complete(
LLInventoryType::EType inventory_type, LLAssetType::EType asset_type,
const std::string inventory_type_string, LLInventoryType::EType inventory_type,
const LLUUID& item_folder_id, const std::string inventory_type_string,
const std::string& item_name, const LLUUID& item_folder_id,
const std::string& item_description, const std::string& item_name,
const LLSD& server_response, const std::string& item_description,
S32 upload_price) const LLSD& server_response,
S32 upload_price)
{ {
if (upload_price > 0) if (upload_price > 0)
{ {
@@ -87,7 +93,7 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
LLSD args; LLSD args;
args["AMOUNT"] = llformat("%d", upload_price); args["AMOUNT"] = llformat("%d", upload_price);
LLNotifications::instance().add("UploadPayment", args); LLNotificationsUtil::add("UploadPayment", args);
} }
if (item_folder_id.notNull()) if (item_folder_id.notNull())
@@ -115,9 +121,18 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
} }
LLPermissions new_perms; LLPermissions new_perms;
new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); new_perms.init(
new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, gAgent.getID(),
next_owner_perms); gAgent.getID(),
LLUUID::null,
LLUUID::null);
new_perms.initMasks(
PERM_ALL,
PERM_ALL,
everyone_perms,
group_perms,
next_owner_perms);
U32 inventory_item_flags = 0; U32 inventory_item_flags = 0;
if (server_response.has("inventory_flags")) if (server_response.has("inventory_flags"))
@@ -147,17 +162,18 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
// Show the preview panel for textures and sounds to let // Show the preview panel for textures and sounds to let
// user know that the image (or snapshot) arrived intact. // user know that the image (or snapshot) arrived intact.
LLInventoryView* view = LLInventoryView::getActiveInventory(); LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
if (view) if ( panel )
{ {
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
view->getPanel()->setSelection(server_response["new_inventory_item"].asUUID(), panel->setSelection(
TAKE_FOCUS_NO); server_response["new_inventory_item"].asUUID(),
TAKE_FOCUS_NO);
if ((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) if ((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type)
/* FIXME: && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD */) /* FIXME: && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD */)
{ {
view->getPanel()->openSelected(); panel->openSelected();
} }
// restore keyboard focus // restore keyboard focus
@@ -190,7 +206,8 @@ LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
} }
} }
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, LLAssetUploadResponder::LLAssetUploadResponder(
const LLSD &post_data,
const std::string& file_name, const std::string& file_name,
LLAssetType::EType asset_type) LLAssetType::EType asset_type)
: LLHTTPClient::Responder(), : LLHTTPClient::Responder(),
@@ -221,14 +238,14 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName); args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
args["REASON"] = "Error in upload request. Please visit " args["REASON"] = "Error in upload request. Please visit "
"http://secondlife.com/support for help fixing this problem."; "http://secondlife.com/support for help fixing this problem.";
LLNotifications::instance().add("CannotUploadReason", args); LLNotificationsUtil::add("CannotUploadReason", args);
break; break;
case 500: case 500:
default: default:
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName); args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
args["REASON"] = "The server is experiencing unexpected " args["REASON"] = "The server is experiencing unexpected "
"difficulties."; "difficulties.";
LLNotifications::instance().add("CannotUploadReason", args); LLNotificationsUtil::add("CannotUploadReason", args);
break; break;
} }
LLUploadDialog::modalUploadFinished(); LLUploadDialog::modalUploadFinished();
@@ -291,7 +308,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
LLSD args; LLSD args;
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName); args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
args["REASON"] = content["message"].asString(); args["REASON"] = content["message"].asString();
LLNotifications::instance().add("CannotUploadReason", args); LLNotificationsUtil::add("CannotUploadReason", args);
} }
} }
@@ -299,17 +316,19 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content)
{ {
} }
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
const LLUUID& vfile_id, const LLSD& post_data,
LLAssetType::EType asset_type) const LLUUID& vfile_id,
: LLAssetUploadResponder(post_data, vfile_id, asset_type) LLAssetType::EType asset_type)
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
{ {
} }
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
const std::string& file_name, const LLSD& post_data,
LLAssetType::EType asset_type) const std::string& file_name,
: LLAssetUploadResponder(post_data, file_name, asset_type) LLAssetType::EType asset_type)
: LLAssetUploadResponder(post_data, file_name, asset_type)
{ {
} }
@@ -347,17 +366,21 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
asset_type == LLAssetType::AT_ANIMATION || asset_type == LLAssetType::AT_ANIMATION ||
asset_type == LLAssetType::AT_MESH) asset_type == LLAssetType::AT_MESH)
{ {
expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); expected_upload_cost =
LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
} }
llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
<< content["new_asset"].asUUID() << " to inventory." << llendl; << content["new_asset"].asUUID() << " to inventory." << llendl;
on_new_single_inventory_upload_complete(asset_type, inventory_type, on_new_single_inventory_upload_complete(
mPostData["asset_type"].asString(), asset_type,
mPostData["folder_id"].asUUID(), inventory_type,
mPostData["name"], mPostData["asset_type"].asString(),
mPostData["description"], mPostData["folder_id"].asUUID(),
content, expected_upload_cost); mPostData["name"],
mPostData["description"],
content,
expected_upload_cost);
// continue uploading for bulk uploads // continue uploading for bulk uploads
@@ -378,42 +401,54 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
// and use them for each next file to be uploaded. Note the requested // and use them for each next file to be uploaded. Note the requested
// perms are not the same as the granted ones found in the given // perms are not the same as the granted ones found in the given
// "content" structure but can still be found in mPostData. -MG // "content" structure but can still be found in mPostData. -MG
U32 everyone_perms = mPostData.has("everyone_mask") ? U32 everyone_perms =
mPostData.get("everyone_mask").asInteger() : mPostData.has("everyone_mask") ?
PERM_NONE; mPostData.get("everyone_mask").asInteger() :
PERM_NONE;
U32 group_perms = mPostData.has("group_mask") ? U32 group_perms =
mPostData.get("group_mask").asInteger() : mPostData.has("group_mask") ?
PERM_NONE; mPostData.get("group_mask").asInteger() :
PERM_NONE;
U32 next_owner_perms = mPostData.has("next_owner_mask") ? U32 next_owner_perms =
mPostData.get("next_owner_mask").asInteger() : mPostData.has("next_owner_mask") ?
PERM_NONE; mPostData.get("next_owner_mask").asInteger() :
PERM_NONE;
std::string display_name = LLStringUtil::null; std::string display_name = LLStringUtil::null;
LLAssetStorage::LLStoreAssetCallback callback = NULL; LLAssetStorage::LLStoreAssetCallback callback = NULL;
void *userdata = NULL; void *userdata = NULL;
upload_new_resource(next_file, asset_name, asset_name, 0,
LLFolderType::FT_NONE, LLInventoryType::IT_NONE, upload_new_resource(
next_owner_perms, group_perms, everyone_perms, next_file,
display_name, callback, expected_upload_cost, asset_name,
userdata); asset_name,
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_NONE,
next_owner_perms,
group_perms,
everyone_perms,
display_name,
callback,
expected_upload_cost,
userdata);
} }
} }
LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
const LLUUID& vfile_id, const LLUUID& vfile_id,
LLAssetType::EType asset_type, LLAssetType::EType asset_type,
LLBakedUploadData * baked_upload_data) LLBakedUploadData * baked_upload_data) :
: LLAssetUploadResponder(post_data, vfile_id, asset_type), LLAssetUploadResponder(post_data, vfile_id, asset_type),
mBakedUploadData(baked_upload_data) mBakedUploadData(baked_upload_data)
{ {
} }
LLSendTexLayerResponder::~LLSendTexLayerResponder() LLSendTexLayerResponder::~LLSendTexLayerResponder()
{ {
// mBakedUploadData is normally deleted by calls to // mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
// LLTexLayerSetBuffer::onTextureUploadComplete() below
if (mBakedUploadData) if (mBakedUploadData)
{ // ...but delete it in the case where uploadComplete() is never called { // ...but delete it in the case where uploadComplete() is never called
delete mBakedUploadData; delete mBakedUploadData;
@@ -430,19 +465,16 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
std::string result = content["state"]; std::string result = content["state"];
LLUUID new_id = content["new_asset"]; LLUUID new_id = content["new_asset"];
llinfos << "LLSendTexLayerResponder::result from capabilities: " << result << llendl; llinfos << "result: " << result << " new_id: " << new_id << llendl;
if (result == "complete" && mBakedUploadData != NULL) if (result == "complete"
&& mBakedUploadData != NULL)
{ // Invoke { // Invoke
LLTexLayerSetBuffer::onTextureUploadComplete(new_id, LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
(void*)mBakedUploadData,
0, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete() mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
} }
else else
{ // Invoke the original callback with an error result { // Invoke the original callback with an error result
LLTexLayerSetBuffer::onTextureUploadComplete(new_id, LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
(void*)mBakedUploadData,
-1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete() mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
} }
} }
@@ -452,23 +484,23 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
llinfos << "status: " << statusNum << " reason: " << reason << llendl; llinfos << "status: " << statusNum << " reason: " << reason << llendl;
// Invoke the original callback with an error result // Invoke the original callback with an error result
LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
(void*)mBakedUploadData,
-1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete() mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
} }
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
const LLUUID& vfile_id, const LLSD& post_data,
LLAssetType::EType asset_type) const LLUUID& vfile_id,
: LLAssetUploadResponder(post_data, vfile_id, asset_type) LLAssetType::EType asset_type)
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
{ {
} }
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
const std::string& file_name, const LLSD& post_data,
LLAssetType::EType asset_type) const std::string& file_name,
: LLAssetUploadResponder(post_data, file_name, asset_type) LLAssetType::EType asset_type)
: LLAssetUploadResponder(post_data, file_name, asset_type)
{ {
} }
@@ -501,8 +533,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
case LLInventoryType::IT_NOTECARD: case LLInventoryType::IT_NOTECARD:
{ {
// Update the UI with the new asset. // Update the UI with the new asset.
LLPreviewNotecard* nc; LLPreviewNotecard* nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
if (nc) if (nc)
{ {
// *HACK: we have to delete the asset in the VFS so // *HACK: we have to delete the asset in the VFS so
@@ -511,10 +542,9 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
// the uploader, so this can be optimized away in some // the uploader, so this can be optimized away in some
// cases. A better design is to have a new uuid if the // cases. A better design is to have a new uuid if the
// script actually changed the asset. // script actually changed the asset.
if (nc->hasEmbeddedInventory()) if(nc->hasEmbeddedInventory())
{ {
gVFS->removeFile(content["new_asset"].asUUID(), gVFS->removeFile(content["new_asset"].asUUID(), LLAssetType::AT_NOTECARD);
LLAssetType::AT_NOTECARD);
} }
nc->refreshFromInventory(); nc->refreshFromInventory();
} }
@@ -538,15 +568,16 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
} }
break; break;
} }
case LLInventoryType::IT_GESTURE: case LLInventoryType::IT_GESTURE:
{ {
// If this gesture is active, then we need to update the in-memory // If this gesture is active, then we need to update the in-memory
// active map with the new pointer. // active map with the new pointer.
if (LLGestureMgr::getInstance()->isGestureActive(item_id)) if (LLGestureMgr::instance().isGestureActive(item_id))
{ {
LLUUID asset_id = new_item->getAssetUUID(); LLUUID asset_id = new_item->getAssetUUID();
LLGestureMgr::getInstance()->replaceGesture(item_id, asset_id); LLGestureMgr::instance().replaceGesture(item_id, asset_id);
gInventory.notifyObservers(); gInventory.notifyObservers();
} }
//gesture will have a new asset_id //gesture will have a new asset_id
@@ -639,9 +670,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
// Bytecode save completed // Bytecode save completed
if (content["compiled"]) if (content["compiled"])
{ {
preview->callbackLSLCompileSucceeded(task_id, preview->callbackLSLCompileSucceeded(task_id, item_id, mPostData["is_script_running"]);
item_id,
mPostData["is_script_running"]);
} }
else else
{ {
@@ -662,27 +691,30 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
class LLNewAgentInventoryVariablePriceResponder::Impl class LLNewAgentInventoryVariablePriceResponder::Impl
{ {
public: public:
Impl(const LLUUID& vfile_id, Impl(
LLAssetType::EType asset_type, const LLUUID& vfile_id,
const LLSD& inventory_data) LLAssetType::EType asset_type,
: mVFileID(vfile_id), const LLSD& inventory_data) :
mVFileID(vfile_id),
mAssetType(asset_type), mAssetType(asset_type),
mInventoryData(inventory_data), mInventoryData(inventory_data),
mFileName("") mFileName("")
{ {
if (!gVFS->getExists(vfile_id, asset_type)) if (!gVFS->getExists(vfile_id, asset_type))
{ {
llwarns << "LLAssetUploadResponder called with nonexistant " llwarns
<< "vfile_id " << vfile_id << llendl; << "LLAssetUploadResponder called with nonexistant "
<< "vfile_id " << vfile_id << llendl;
mVFileID.setNull(); mVFileID.setNull();
mAssetType = LLAssetType::AT_NONE; mAssetType = LLAssetType::AT_NONE;
} }
} }
Impl(const std::string& file_name, Impl(
LLAssetType::EType asset_type, const std::string& file_name,
const LLSD& inventory_data) LLAssetType::EType asset_type,
: mFileName(file_name), const LLSD& inventory_data) :
mFileName(file_name),
mAssetType(asset_type), mAssetType(asset_type),
mInventoryData(inventory_data) mInventoryData(inventory_data)
{ {
@@ -741,7 +773,8 @@ public:
args["FILE"] = getFilenameOrIDString(); args["FILE"] = getFilenameOrIDString();
args["REASON"] = reason; args["REASON"] = reason;
LLNotifications::instance().add("CannotUploadReason", args);
LLNotificationsUtil::add("CannotUploadReason", args);
LLUploadDialog::modalUploadFinished(); LLUploadDialog::modalUploadFinished();
} }
@@ -776,45 +809,55 @@ public:
else if (_MISSING_REQUIRED_PARAMETER == error_identifier) else if (_MISSING_REQUIRED_PARAMETER == error_identifier)
{ {
// Missing parameters // Missing parameters
if (error.has(_MISSING_PARAMETER)) if (error.has(_MISSING_PARAMETER) )
{ {
std::string message = "Upload request was missing required parameter '[P]'"; std::string message =
LLStringUtil::replaceString(message, "[P]", "Upload request was missing required parameter '[P]'";
error[_MISSING_PARAMETER].asString()); LLStringUtil::replaceString(
message,
"[P]",
error[_MISSING_PARAMETER].asString());
displayCannotUploadReason(message); displayCannotUploadReason(message);
} }
else else
{ {
std::string message = "Upload request was missing a required parameter"; std::string message =
"Upload request was missing a required parameter";
displayCannotUploadReason(message); displayCannotUploadReason(message);
} }
} }
else if (_INVALID_REQUEST_BODY == error_identifier) else if ( _INVALID_REQUEST_BODY == error_identifier )
{ {
// Invalid request body, check to see if // Invalid request body, check to see if
// a particular parameter was invalid // a particular parameter was invalid
if (error.has(_INVALID_PARAMETER)) if ( error.has(_INVALID_PARAMETER) )
{ {
std::string message = "Upload parameter '[P]' is invalid."; std::string message = "Upload parameter '[P]' is invalid.";
LLStringUtil::replaceString(message, "[P]", LLStringUtil::replaceString(
error[_INVALID_PARAMETER].asString()); message,
"[P]",
error[_INVALID_PARAMETER].asString());
// See if the server also responds with what resource // See if the server also responds with what resource
// is missing. // is missing.
if (error.has(_MISSING_RESOURCE)) if ( error.has(_MISSING_RESOURCE) )
{ {
message += "\nMissing resource '[R]'."; message += "\nMissing resource '[R]'.";
LLStringUtil::replaceString(message, "[R]", LLStringUtil::replaceString(
error[_MISSING_RESOURCE].asString()); message,
"[R]",
error[_MISSING_RESOURCE].asString());
} }
else if (error.has(_INVALID_RESOURCE)) else if ( error.has(_INVALID_RESOURCE) )
{ {
message += "\nInvalid resource '[R]'."; message += "\nInvalid resource '[R]'.";
LLStringUtil::replaceString(message, "[R]", LLStringUtil::replaceString(
error[_INVALID_RESOURCE].asString()); message,
"[R]",
error[_INVALID_RESOURCE].asString());
} }
displayCannotUploadReason(message); displayCannotUploadReason(message);
@@ -837,7 +880,8 @@ public:
void onTransportError() void onTransportError()
{ {
displayCannotUploadReason("The server is experiencing unexpected difficulties."); displayCannotUploadReason(
"The server is experiencing unexpected difficulties.");
} }
void onTransportError(const LLSD& error) void onTransportError(const LLSD& error)
@@ -852,47 +896,72 @@ public:
// TODO*: Pull the user visible strings from an xml file // TODO*: Pull the user visible strings from an xml file
// to be localized // to be localized
if (_SERVER_ERROR_AFTER_CHARGE == error_identifier) if ( _SERVER_ERROR_AFTER_CHARGE == error_identifier )
{ {
displayCannotUploadReason("The server is experiencing unexpected difficulties. You may have been charged for the upload."); displayCannotUploadReason(
"The server is experiencing unexpected difficulties. You may have been charged for the upload.");
} }
else else
{ {
displayCannotUploadReason("The server is experiencing unexpected difficulties."); displayCannotUploadReason(
"The server is experiencing unexpected difficulties.");
} }
} }
bool uploadConfirmationCallback(const LLSD& notification, bool uploadConfirmationCallback(
const LLSD& response, const LLSD& notification,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) const LLSD& response,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
{ {
S32 option = LLNotification::getSelectedOption(notification, response); S32 option;
std::string confirmation_url = notification["payload"]["confirmation_url"].asString(); std::string confirmation_url;
option = LLNotificationsUtil::getSelectedOption(
notification,
response);
confirmation_url =
notification["payload"]["confirmation_url"].asString();
// Yay! We are confirming or cancelling our upload // Yay! We are confirming or cancelling our upload
if (option == 0) switch(option)
{ {
confirmUpload(confirmation_url, responder); case 0:
{
confirmUpload(confirmation_url, responder);
}
break;
case 1:
default:
break;
} }
return false; return false;
} }
void confirmUpload(const std::string& confirmation_url, void confirmUpload(
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) const std::string& confirmation_url,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
{ {
if (getFilename().empty()) if ( getFilename().empty() )
{ {
// we have no filename, use virtual file ID instead // we have no filename, use virtual file ID instead
LLHTTPClient::postFile(confirmation_url, getVFileID(), LLHTTPClient::postFile(
getAssetType(), responder); confirmation_url,
getVFileID(),
getAssetType(),
responder);
} }
else else
{ {
LLHTTPClient::postFile(confirmation_url, getFilename(), responder); LLHTTPClient::postFile(
confirmation_url,
getFilename(),
responder);
} }
} }
private: private:
std::string mFileName; std::string mFileName;
@@ -904,18 +973,26 @@ private:
/////////////////////////////////////////////// ///////////////////////////////////////////////
// LLNewAgentInventoryVariablePriceResponder // // LLNewAgentInventoryVariablePriceResponder //
/////////////////////////////////////////////// ///////////////////////////////////////////////
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(const LLUUID& vfile_id, LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
LLAssetType::EType asset_type, const LLUUID& vfile_id,
const LLSD& inventory_info) LLAssetType::EType asset_type,
const LLSD& inventory_info)
{ {
mImpl = new Impl(vfile_id, asset_type, inventory_info); mImpl = new Impl(
vfile_id,
asset_type,
inventory_info);
} }
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(const std::string& file_name, LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
LLAssetType::EType asset_type, const std::string& file_name,
const LLSD& inventory_info) LLAssetType::EType asset_type,
const LLSD& inventory_info)
{ {
mImpl = new Impl(file_name, asset_type, inventory_info); mImpl = new Impl(
file_name,
asset_type,
inventory_info);
} }
LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResponder() LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResponder()
@@ -923,16 +1000,19 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp
delete mImpl; delete mImpl;
} }
void LLNewAgentInventoryVariablePriceResponder::errorWithContent(U32 statusNum, void LLNewAgentInventoryVariablePriceResponder::errorWithContent(
const std::string& reason, U32 statusNum,
const LLSD& content) const std::string& reason,
const LLSD& content)
{ {
LL_DEBUGS("Upload") << "LLNewAgentInventoryVariablePrice::error " lldebugs
<< statusNum << " reason: " << reason << LL_ENDL; << "LLNewAgentInventoryVariablePrice::error " << statusNum
<< " reason: " << reason << llendl;
if (content.has("error")) if ( content.has("error") )
{ {
static const std::string _ERROR = "error"; static const std::string _ERROR = "error";
mImpl->onTransportError(content[_ERROR]); mImpl->onTransportError(content[_ERROR]);
} }
else else
@@ -972,27 +1052,32 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
{ {
// rename the file in the VFS to the actual asset id // rename the file in the VFS to the actual asset id
// llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl; // llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl;
gVFS->renameFile(mImpl->getVFileID(), asset_type, gVFS->renameFile(
content["new_asset"].asUUID(), asset_type); mImpl->getVFileID(),
asset_type,
content["new_asset"].asUUID(),
asset_type);
} }
on_new_single_inventory_upload_complete(asset_type, on_new_single_inventory_upload_complete(
mImpl->getInventoryType(), asset_type,
mImpl->getInventoryTypeString(), mImpl->getInventoryType(),
mImpl->getFolderID(), mImpl->getInventoryTypeString(),
mImpl->getItemName(), mImpl->getFolderID(),
mImpl->getItemDescription(), mImpl->getItemName(),
content, mImpl->getItemDescription(),
content[_UPLOAD_PRICE].asInteger()); content,
content[_UPLOAD_PRICE].asInteger());
// TODO* Add bulk (serial) uploading or add // TODO* Add bulk (serial) uploading or add
// a super class of this that does so // a super class of this that does so
} }
else if (_CONFIRM_UPLOAD == state) else if ( _CONFIRM_UPLOAD == state )
{ {
showConfirmationDialog(content[_UPLOAD_PRICE].asInteger(), showConfirmationDialog(
content[_RESOURCE_COST].asInteger(), content[_UPLOAD_PRICE].asInteger(),
content[_RSVP].asString()); content[_RESOURCE_COST].asInteger(),
content[_RSVP].asString());
} }
else else
{ {
@@ -1000,14 +1085,16 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
} }
} }
void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError(const LLSD& error) void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError(
const LLSD& error)
{ {
mImpl->onApplicationLevelError(error); mImpl->onApplicationLevelError(error);
} }
void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 upload_price, void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
S32 resource_cost, S32 upload_price,
const std::string& confirmation_url) S32 resource_cost,
const std::string& confirmation_url)
{ {
if (0 == upload_price) if (0 == upload_price)
{ {
@@ -1027,8 +1114,9 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 uploa
// when using plain ol' 'this', that this object // when using plain ol' 'this', that this object
// would be deleted before the callback is triggered // would be deleted before the callback is triggered
// and cause sadness. // and cause sadness.
mImpl->confirmUpload(confirmation_url, mImpl->confirmUpload(
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)); confirmation_url,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
} }
else else
{ {
@@ -1052,10 +1140,15 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 uploa
// when using plain ol' 'this', that this object // when using plain ol' 'this', that this object
// would be deleted before the callback is triggered // would be deleted before the callback is triggered
// and cause sadness. // and cause sadness.
LLNotifications::instance().add("UploadCostConfirmation", LLNotificationsUtil::add(
substitutions, payload, "UploadCostConfirmation",
boost::bind(&LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback, substitutions,
mImpl, _1, _2, payload,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this))); boost::bind(
&LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback,
mImpl,
_1,
_2,
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
} }
} }

View File

@@ -73,12 +73,14 @@ protected:
class LLNewAgentInventoryResponder : public LLAssetUploadResponder class LLNewAgentInventoryResponder : public LLAssetUploadResponder
{ {
public: public:
LLNewAgentInventoryResponder(const LLSD& post_data, LLNewAgentInventoryResponder(
const LLUUID& vfile_id, const LLSD& post_data,
LLAssetType::EType asset_type); const LLUUID& vfile_id,
LLNewAgentInventoryResponder(const LLSD& post_data, LLAssetType::EType asset_type);
const std::string& file_name, LLNewAgentInventoryResponder(
LLAssetType::EType asset_type); const LLSD& post_data,
const std::string& file_name,
LLAssetType::EType asset_type);
virtual void error(U32 statusNum, const std::string& reason); virtual void error(U32 statusNum, const std::string& reason);
virtual void uploadComplete(const LLSD& content); virtual void uploadComplete(const LLSD& content);
virtual void uploadFailure(const LLSD& content); virtual void uploadFailure(const LLSD& content);
@@ -92,23 +94,28 @@ class LLNewAgentInventoryVariablePriceResponder :
public LLHTTPClient::Responder public LLHTTPClient::Responder
{ {
public: public:
LLNewAgentInventoryVariablePriceResponder(const LLUUID& vfile_id, LLNewAgentInventoryVariablePriceResponder(
LLAssetType::EType asset_type, const LLUUID& vfile_id,
const LLSD& inventory_info); LLAssetType::EType asset_type,
const LLSD& inventory_info);
LLNewAgentInventoryVariablePriceResponder(const std::string& file_name, LLNewAgentInventoryVariablePriceResponder(
LLAssetType::EType asset_type, const std::string& file_name,
const LLSD& inventory_info); LLAssetType::EType asset_type,
const LLSD& inventory_info);
virtual ~LLNewAgentInventoryVariablePriceResponder(); virtual ~LLNewAgentInventoryVariablePriceResponder();
void errorWithContent(U32 statusNum, void errorWithContent(
const std::string& reason, U32 statusNum,
const LLSD& content); const std::string& reason,
const LLSD& content);
void result(const LLSD& content); void result(const LLSD& content);
virtual void onApplicationLevelError(const LLSD& error); virtual void onApplicationLevelError(
virtual void showConfirmationDialog(S32 upload_price, const LLSD& error);
S32 resource_cost, virtual void showConfirmationDialog(
S32 upload_price,
S32 resource_cost,
const std::string& confirmation_url); const std::string& confirmation_url);
private: private:
@@ -116,7 +123,7 @@ private:
Impl* mImpl; Impl* mImpl;
}; };
class LLBakedUploadData; struct LLBakedUploadData;
class LLSendTexLayerResponder : public LLAssetUploadResponder class LLSendTexLayerResponder : public LLAssetUploadResponder
{ {
LOG_CLASS(LLSendTexLayerResponder); LOG_CLASS(LLSendTexLayerResponder);

View File

@@ -28,7 +28,7 @@
#ifndef LL_LLATTACHMENTSMGR_H #ifndef LL_LLATTACHMENTSMGR_H
#define LL_LLATTACHMENTSMGR_H #define LL_LLATTACHMENTSMGR_H
#include "llmemory.h" #include "llsingleton.h"
class LLViewerInventoryItem; class LLViewerInventoryItem;

View File

@@ -131,9 +131,6 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avat
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{ {
std::string name;
gCacheName->getFullName(avatar_id, name);
llinfos << "Sending avatarpicksrequest for " << avatar_id << " ("<<name<<")" << llendl;
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest"); sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
} }
@@ -398,10 +395,6 @@ void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg,
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id); msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id); msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
std::string name;
gCacheName->getFullName(avatar_picks.target_id, name);
llinfos << "Got reply for " << avatar_picks.target_id << ": (" << name << ")" << llendl;
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data); S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
for (int block = 0; block < block_count; ++block) for (int block = 0; block < block_count; ++block)
{ {
@@ -411,14 +404,12 @@ void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg,
msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block); msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block); msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
llinfos << "\t" << pick_id << ": " << pick_name << llendl;
avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name)); avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
} }
LLAvatarPropertiesProcessor* self = getInstance(); LLAvatarPropertiesProcessor* self = getInstance();
// Request processed, no longer pending // Request processed, no longer pending
self->removePendingRequest(avatar_picks.target_id, APT_PICKS); self->removePendingRequest(avatar_picks.target_id, APT_PICKS);
self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS); self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
//LLPanelAvatar
} }
void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**) void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)

View File

@@ -65,12 +65,15 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
objectp->getType(), objectp->getType(),
LLInventoryType::IT_CATEGORY, LLInventoryType::IT_CATEGORY,
panelp, panelp,
panelp->getRootFolder(),
objectp->getUUID()); objectp->getUUID());
if (new_listener) if (new_listener)
{ {
LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(), LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
new_listener->getIcon(), new_listener->getIcon(),
new_listener->getIcon(),
NULL,
panelp->getRootFolder(), panelp->getRootFolder(),
new_listener); new_listener);
@@ -86,12 +89,15 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
item->getActualType(), item->getActualType(),
item->getInventoryType(), item->getInventoryType(),
panelp, panelp,
panelp->getRootFolder(),
item->getUUID(), item->getUUID(),
item->getFlags()); item->getFlags());
if (new_listener) if (new_listener)
{ {
itemp = new LLFolderViewItem(new_listener->getDisplayName(), itemp = new LLFolderViewItem(new_listener->getDisplayName(),
new_listener->getIcon(), new_listener->getIcon(),
NULL,
NULL,
new_listener->getCreationDate(), new_listener->getCreationDate(),
panelp->getRootFolder(), panelp->getRootFolder(),
new_listener); new_listener);
@@ -102,7 +108,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
if (itemp) if (itemp)
{ {
itemp->mDelayedDelete = TRUE; //itemp->mDelayedDelete = TRUE;
if (parent_folder) if (parent_folder)
{ {
itemp->addToFolder(parent_folder, panelp->getRootFolder()); itemp->addToFolder(parent_folder, panelp->getRootFolder());

View File

@@ -180,6 +180,12 @@ private:
bool_func_t mCallable; bool_func_t mCallable;
}; };
void doOnIdleRepeating(bool_func_t callable)
{
OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
}
#ifdef _DEBUG #ifdef _DEBUG
void test1(void *data) void test1(void *data)

View File

@@ -153,8 +153,8 @@ BOOL LLChatBar::postBuild()
{ {
mInputEditor->setCallbackUserData(this); mInputEditor->setCallbackUserData(this);
mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke); mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this); mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost));
mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this ); mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus));
mInputEditor->setCommitOnFocusLost( FALSE ); mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setRevertOnEsc( FALSE ); mInputEditor->setRevertOnEsc( FALSE );
mInputEditor->setIgnoreTab(TRUE); mInputEditor->setIgnoreTab(TRUE);
@@ -623,14 +623,14 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
} }
// static // static
void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata) void LLChatBar::onInputEditorFocusLost()
{ {
// stop typing animation // stop typing animation
gAgent.stopTyping(); gAgent.stopTyping();
} }
// static // static
void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata ) void LLChatBar::onInputEditorGainFocus()
{ {
LLFloaterChat::setHistoryCursorAndScrollToEnd(); LLFloaterChat::setHistoryCursorAndScrollToEnd();
} }

View File

@@ -86,8 +86,8 @@ public:
static void onTabClick( void* userdata ); static void onTabClick( void* userdata );
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata); static void onInputEditorFocusLost();
static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata); static void onInputEditorGainFocus();
static void onCommitGesture(LLUICtrl* ctrl, void* data); static void onCommitGesture(LLUICtrl* ctrl, void* data);

View File

@@ -218,7 +218,7 @@ void LLColorSwatchCtrl::draw()
if ( mValid ) if ( mValid )
{ {
// Draw the color swatch // Draw the color swatch
gl_rect_2d_checkerboard( getScreenRect(), interior ); gl_rect_2d_checkerboard( calcScreenRect(), interior );
gl_rect_2d(interior, mColor, TRUE); gl_rect_2d(interior, mColor, TRUE);
LLColor4 opaque_color = mColor; LLColor4 opaque_color = mColor;
opaque_color.mV[VALPHA] = 1.f; opaque_color.mV[VALPHA] = 1.f;
@@ -239,7 +239,7 @@ void LLColorSwatchCtrl::draw()
LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName); LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName);
if( fallback_image->getComponents() == 4 ) if( fallback_image->getComponents() == 4 )
{ {
gl_rect_2d_checkerboard( getScreenRect(), interior ); gl_rect_2d_checkerboard( calcScreenRect(), interior );
} }
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image); gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image);
fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );

View File

@@ -2,31 +2,25 @@
* @file lldriverparam.cpp * @file lldriverparam.cpp
* @brief A visual parameter that drives (controls) other visual parameters. * @brief A visual parameter that drives (controls) other visual parameters.
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -36,6 +30,10 @@
#include "llfasttimer.h" #include "llfasttimer.h"
#include "llvoavatar.h" #include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llagent.h"
#include "llwearable.h"
#include "llagentwearables.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LLDriverParamInfo // LLDriverParamInfo
@@ -100,12 +98,69 @@ BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
return TRUE; return TRUE;
} }
//virtual
void LLDriverParamInfo::toStream(std::ostream &out)
{
LLViewerVisualParamInfo::toStream(out);
out << "driver" << "\t";
out << mDrivenInfoList.size() << "\t";
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
{
LLDrivenEntryInfo driven = *iter;
out << driven.mDrivenID << "\t";
}
out << std::endl;
if(isAgentAvatarValid())
{
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
{
LLDrivenEntryInfo driven = *iter;
LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
if (param)
{
param->getInfo()->toStream(out);
if (param->getWearableType() != mWearableType)
{
if(param->getCrossWearable())
{
out << "cross-wearable" << "\t";
}
else
{
out << "ERROR!" << "\t";
}
}
else
{
out << "valid" << "\t";
}
}
else
{
llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp << " for driver parameter " << getID() << llendl;
}
out << std::endl;
}
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LLDriverParam // LLDriverParam
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
: mCurrentDistortionParam( NULL ), mAvatarp(avatarp) mCurrentDistortionParam( NULL ),
mAvatarp(avatarp),
mWearablep(NULL)
{
}
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
mCurrentDistortionParam( NULL ),
mAvatarp(NULL),
mWearablep(wearablep)
{ {
} }
@@ -122,27 +177,48 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
mID = info->mID; mID = info->mID;
setWeight(getDefaultWeight(), FALSE ); setWeight(getDefaultWeight(), FALSE );
LLDriverParamInfo::entry_info_list_t::iterator iter; return TRUE;
mDriven.reserve(getInfo()->mDrivenInfoList.size()); }
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); iter++)
void LLDriverParam::setWearable(LLWearable *wearablep)
{
if (wearablep)
{ {
LLDrivenEntryInfo *driven_info = &(*iter); mWearablep = wearablep;
S32 driven_id = driven_info->mDrivenID; mAvatarp = NULL;
LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarp->getVisualParam( driven_id ); }
if (param) }
void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
{
if (avatarp)
{
mWearablep = NULL;
mAvatarp = avatarp;
}
}
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
{
LLDriverParam *new_param;
if (wearable)
{
new_param = new LLDriverParam(wearable);
}
else
{
if (mWearablep)
{ {
mDriven.push_back(LLDrivenEntry( param, driven_info )); new_param = new LLDriverParam(mWearablep);
} }
else else
{ {
llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl; new_param = new LLDriverParam(mAvatarp);
mInfo = NULL;
return FALSE;
} }
} }
*new_param = *this;
return TRUE; return new_param;
} }
#if 0 // obsolete #if 0 // obsolete
@@ -408,6 +484,82 @@ void LLDriverParam::stopAnimating(BOOL upload_bake)
} }
} }
/*virtual*/
BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
{
BOOL success = TRUE;
LLDriverParamInfo::entry_info_list_t::iterator iter;
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
{
LLDrivenEntryInfo *driven_info = &(*iter);
S32 driven_id = driven_info->mDrivenID;
// check for already existing links. Do not overwrite.
BOOL found = FALSE;
for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
{
if (driven_iter->mInfo->mDrivenID == driven_id)
{
found = TRUE;
}
}
if (!found)
{
LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
bool push = param && (!only_cross_params || param->getCrossWearable());
if (push)
{
mDriven.push_back(LLDrivenEntry( param, driven_info ));
}
else
{
success = FALSE;
}
}
}
return success;
}
void LLDriverParam::resetDrivenParams()
{
mDriven.clear();
mDriven.reserve(getInfo()->mDrivenInfoList.size());
}
void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
{
bool needs_update = (getWearableType()==driven_type);
// if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
{
needs_update = true;
}
}
if (needs_update)
{
LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
// If we've gotten here, we've added a new wearable of type "type"
// Thus this wearable needs to get updates from the driver wearable.
// The call to setVisualParamWeight seems redundant, but is necessary
// as the number of driven wearables has changed since the last update. -Nyx
LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
if (wearable)
{
wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
}
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// getDrivenWeight() // getDrivenWeight()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -467,7 +619,7 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake) void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
{ {
/*if(isAgentAvatarValid() && if(isAgentAvatarValid() &&
mWearablep && mWearablep &&
driven->mParam->getCrossWearable() && driven->mParam->getCrossWearable() &&
mWearablep->isOnTop()) mWearablep->isOnTop())
@@ -475,7 +627,7 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bo
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake ); gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
} }
else*/ else
{ {
driven->mParam->setWeight( driven_weight, upload_bake ); driven->mParam->setWeight( driven_weight, upload_bake );
} }

View File

@@ -2,31 +2,25 @@
* @file lldriverparam.h * @file lldriverparam.h
* @brief A visual parameter that drives (controls) other visual parameters. * @brief A visual parameter that drives (controls) other visual parameters.
* *
* $LicenseInfo:firstyear=2002&license=viewergpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -34,9 +28,11 @@
#define LL_LLDRIVERPARAM_H #define LL_LLDRIVERPARAM_H
#include "llviewervisualparam.h" #include "llviewervisualparam.h"
#include "llwearabletype.h"
class LLPhysicsMotion; class LLPhysicsMotion;
class LLVOAvatar; class LLVOAvatar;
class LLWearable;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -70,6 +66,8 @@ public:
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
/*virtual*/ void toStream(std::ostream &out);
protected: protected:
typedef std::deque<LLDrivenEntryInfo> entry_info_list_t; typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
entry_info_list_t mDrivenInfoList; entry_info_list_t mDrivenInfoList;
@@ -82,6 +80,7 @@ class LLDriverParam : public LLViewerVisualParam
friend class LLPhysicsMotion; // physics motion needs to access driven params directly. friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
public: public:
LLDriverParam(LLVOAvatar *avatarp); LLDriverParam(LLVOAvatar *avatarp);
LLDriverParam(LLWearable *wearablep);
~LLDriverParam(); ~LLDriverParam();
// Special: These functions are overridden by child classes // Special: These functions are overridden by child classes
@@ -89,12 +88,20 @@ public:
// This sets mInfo and calls initialization functions // This sets mInfo and calls initialization functions
BOOL setInfo(LLDriverParamInfo *info); BOOL setInfo(LLDriverParamInfo *info);
void setWearable(LLWearable *wearablep);
void setAvatar(LLVOAvatar *avatarp);
void updateCrossDrivenParams(LLWearableType::EType driven_type);
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
// LLVisualParam Virtual functions // LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node); ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param. /*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
/*virtual*/ void setWeight(F32 weight, BOOL upload_bake); /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
/*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake ); /*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
/*virtual*/ void stopAnimating(BOOL upload_bake); /*virtual*/ void stopAnimating(BOOL upload_bake);
/*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
/*virtual*/ void resetDrivenParams();
// LLViewerVisualParam Virtual functions // LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion(); /*virtual*/ F32 getTotalDistortion();
@@ -115,6 +122,7 @@ protected:
LLViewerVisualParam* mCurrentDistortionParam; LLViewerVisualParam* mCurrentDistortionParam;
// Backlink only; don't make this an LLPointer. // Backlink only; don't make this an LLPointer.
LLVOAvatar* mAvatarp; LLVOAvatar* mAvatarp;
LLWearable* mWearablep;
}; };
#endif // LL_LLDRIVERPARAM_H #endif // LL_LLDRIVERPARAM_H

View File

@@ -2,31 +2,25 @@
* @file llflexibleobject.cpp * @file llflexibleobject.cpp
* @brief Flexible object implementation * @brief Flexible object implementation
* *
* $LicenseInfo:firstyear=2006&license=viewergpl$ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */

View File

@@ -267,12 +267,13 @@ BOOL LLFloaterAnimPreview::postBuild()
{ {
mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0)); mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0));
} }
mPlayButton->setClickedCallback(onBtnPlay); mPlayButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnPlay,this));
mPlayButton->setCallbackUserData(this);
mPlayButton->setImages(std::string("button_anim_play.tga"), mPlayButton->setImages(std::string("button_anim_play.tga"),
std::string("button_anim_play_selected.tga")); std::string("button_anim_play_selected.tga"));
mPlayButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
mPlayButton->setImageDisabled(NULL);
mPlayButton->setImageDisabledSelected(NULL);
mPlayButton->setScaleImage(TRUE); mPlayButton->setScaleImage(TRUE);
@@ -281,12 +282,13 @@ BOOL LLFloaterAnimPreview::postBuild()
{ {
mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0)); mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0));
} }
mStopButton->setClickedCallback(onBtnStop); mStopButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnStop, this));
mStopButton->setCallbackUserData(this);
mStopButton->setImages(std::string("button_anim_stop.tga"), mStopButton->setImages(std::string("button_anim_stop.tga"),
std::string("button_anim_stop_selected.tga")); std::string("button_anim_stop_selected.tga"));
mStopButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
mStopButton->setImageDisabled(NULL);
mStopButton->setImageDisabledSelected(NULL);
mStopButton->setScaleImage(TRUE); mStopButton->setScaleImage(TRUE);

View File

@@ -236,63 +236,35 @@ LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity()
return mActivityType; return mActivityType;
} }
LLFloaterAvatarList* LLFloaterAvatarList::sInstance = NULL;
LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")) LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar"))
{ {
llassert_always(sInstance == NULL); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml");
sInstance = this;
mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3; mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3;
} }
LLFloaterAvatarList::~LLFloaterAvatarList() LLFloaterAvatarList::~LLFloaterAvatarList()
{ {
gIdleCallbacks.deleteFunction(LLFloaterAvatarList::callbackIdle); gIdleCallbacks.deleteFunction(LLFloaterAvatarList::callbackIdle);
sInstance = NULL;
}
//static
void LLFloaterAvatarList::createInstance(bool visible)
{
sInstance = new LLFloaterAvatarList();
LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_radar.xml");
if(!visible)
{
sInstance->setVisible(FALSE);
gSavedSettings.setBOOL("ShowRadar", FALSE);
}
if(gHippoGridManager->getConnectedGrid()->isSecondLife()){
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("avatar_list");
list->getColumn(1)->setWidth(0);
list->getColumn(6)->setWidth(0);
list->getColumn(6)->mDynamicWidth = FALSE;
list->getColumn(6)->mRelWidth = 0;
list->getColumn(1)->mDynamicWidth = TRUE;
list->getColumn(1)->mRelWidth = -1;
list->updateLayout();
}
} }
//static //static
void LLFloaterAvatarList::toggle(void*) void LLFloaterAvatarList::toggle(void*)
{ {
if (sInstance)
{
if (sInstance->getVisible()
// [RLVa:KB] // [RLVa:KB]
|| gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
if(instanceExists())
getInstance()->close();
}
else
// [/RLVa:KB] // [/RLVa:KB]
) if(!instanceExists() || !getInstance()->getVisible())
{
{ showInstance();
sInstance->close(false);
}
else
{
sInstance->open();
}
} }
else else
{ {
showInstance(); getInstance()->close();
} }
} }
@@ -303,17 +275,7 @@ void LLFloaterAvatarList::showInstance()
if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
return; return;
// [/RLVa:KB] // [/RLVa:KB]
if (sInstance) getInstance()->open();
{
if (!sInstance->getVisible())
{
sInstance->open();
}
}
else
{
createInstance(true);
}
} }
void LLFloaterAvatarList::draw() void LLFloaterAvatarList::draw()
@@ -324,12 +286,11 @@ void LLFloaterAvatarList::draw()
void LLFloaterAvatarList::onOpen() void LLFloaterAvatarList::onOpen()
{ {
gSavedSettings.setBOOL("ShowRadar", TRUE); gSavedSettings.setBOOL("ShowRadar", TRUE);
sInstance->setVisible(TRUE);
} }
void LLFloaterAvatarList::onClose(bool app_quitting) void LLFloaterAvatarList::onClose(bool app_quitting)
{ {
sInstance->setVisible(FALSE); setVisible(FALSE);
if (!app_quitting) if (!app_quitting)
{ {
gSavedSettings.setBOOL("ShowRadar", FALSE); gSavedSettings.setBOOL("ShowRadar", FALSE);
@@ -387,12 +348,23 @@ BOOL LLFloaterAvatarList::postBuild()
gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle);
if(gHippoGridManager->getConnectedGrid()->isSecondLife()){
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("avatar_list");
list->getColumn(1)->setWidth(0);
list->getColumn(6)->setWidth(0);
list->getColumn(6)->mDynamicWidth = FALSE;
list->getColumn(6)->mRelWidth = 0;
list->getColumn(1)->mDynamicWidth = TRUE;
list->getColumn(1)->mRelWidth = -1;
list->updateLayout();
}
return TRUE; return TRUE;
} }
void updateParticleActivity(LLDrawable *drawablep) void updateParticleActivity(LLDrawable *drawablep)
{ {
if (LLFloaterAvatarList::getInstance()) if (LLFloaterAvatarList::instanceExists())
{ {
LLViewerObject *vobj = drawablep->getVObj(); LLViewerObject *vobj = drawablep->getVObj();
if (vobj && vobj->isParticleSource()) if (vobj && vobj->isParticleSource())
@@ -409,10 +381,6 @@ void updateParticleActivity(LLDrawable *drawablep)
void LLFloaterAvatarList::updateAvatarList() void LLFloaterAvatarList::updateAvatarList()
{ {
if (sInstance != this) return;
//if(LLStartUp::getStartupState() < STATE_STARTED)return;
//llinfos << "radar refresh: updating map" << llendl; //llinfos << "radar refresh: updating map" << llendl;
// Check whether updates are enabled // Check whether updates are enabled
@@ -672,7 +640,7 @@ void LLFloaterAvatarList::expireAvatarList()
void LLFloaterAvatarList::refreshAvatarList() void LLFloaterAvatarList::refreshAvatarList()
{ {
// Don't update list when interface is hidden // Don't update list when interface is hidden
if (!sInstance->getVisible()) return; if (!getVisible()) return;
// We rebuild the list fully each time it's refreshed // We rebuild the list fully each time it's refreshed
// The assumption is that it's faster to refill it and sort than // The assumption is that it's faster to refill it and sort than
@@ -1545,15 +1513,13 @@ void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& r
{ {
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
if (option == 0) if (option == 0)
{ {
self->doCommand(cmd_freeze); getInstance()->doCommand( cmd_freeze );
} }
else if (option == 1) else if (option == 1)
{ {
self->doCommand(cmd_unfreeze); getInstance()->doCommand( cmd_unfreeze );
} }
} }
@@ -1562,15 +1528,13 @@ void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& re
{ {
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
if (option == 0) if (option == 0)
{ {
self->doCommand(cmd_eject); getInstance()->doCommand( cmd_eject );
} }
else if (option == 1) else if (option == 1)
{ {
self->doCommand(cmd_ban); getInstance()->doCommand( cmd_ban );
} }
} }
@@ -1579,22 +1543,21 @@ void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, cons
{ {
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
if (option == 0) if (option == 0)
{ {
self->doCommand(cmd_estate_eject); getInstance()->doCommand( cmd_estate_eject );
} }
} }
//static //static
void LLFloaterAvatarList::callbackIdle(void *userdata) { void LLFloaterAvatarList::callbackIdle(void *userdata)
if (LLFloaterAvatarList::sInstance != NULL) {
if (instanceExists())
{ {
// Do not update at every frame: this would be insane ! // Do not update at every frame: this would be insane !
if (gFrameCount % LLFloaterAvatarList::sInstance->mUpdateRate == 0) if (gFrameCount % getInstance()->mUpdateRate == 0)
{ {
LLFloaterAvatarList::sInstance->updateAvatarList(); getInstance()->updateAvatarList();
} }
} }
} }

View File

@@ -159,12 +159,13 @@ private:
* Since I'm very new to C++ any suggestions on coding, style, etc are very * Since I'm very new to C++ any suggestions on coding, style, etc are very
* welcome. * welcome.
*/ */
class LLFloaterAvatarList : public LLFloater class LLFloaterAvatarList : public LLFloater, public LLSingleton<LLFloaterAvatarList>
{ {
/** /**
* @brief Creates and initializes the LLFloaterAvatarList * @brief Creates and initializes the LLFloaterAvatarList
* Here the interface is created, and callbacks are initialized. * Here the interface is created, and callbacks are initialized.
*/ */
friend class LLSingleton<LLFloaterAvatarList>;
private: private:
LLFloaterAvatarList(); LLFloaterAvatarList();
public: public:
@@ -211,11 +212,6 @@ public:
static void sound_trigger_hook(LLMessageSystem* msg,void **); static void sound_trigger_hook(LLMessageSystem* msg,void **);
static void sendKeys(); static void sendKeys();
private:
static LLFloaterAvatarList* sInstance;
public:
static LLFloaterAvatarList* getInstance() { return sInstance; }
private: private:
// when a line editor loses keyboard focus, it is committed. // when a line editor loses keyboard focus, it is committed.
// commit callbacks are named onCommitWidgetName by convention. // commit callbacks are named onCommitWidgetName by convention.

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