summaryrefslogtreecommitdiff
path: root/indra/newview/lltexturectrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltexturectrl.cpp')
-rw-r--r--indra/newview/lltexturectrl.cpp910
1 files changed, 434 insertions, 476 deletions
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4f8e562baf..328298bda4 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -3,30 +3,25 @@
* @author Richard Nelson, James Cook
* @brief LLTextureCtrl class implementation including related functions
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * 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
+ * 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.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * 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.
*
- * 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.
+ * 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
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,19 +29,23 @@
#include "lltexturectrl.h"
-#include "llglimmediate.h"
+#include "llrender.h"
#include "llagent.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llbutton.h"
#include "lldraghandle.h"
#include "llfocusmgr.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llfolderview.h"
+#include "llfoldervieweventlistener.h"
#include "llinventory.h"
-#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+#include "llfloaterinventory.h"
#include "lllineeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
@@ -58,35 +57,20 @@
#include "llscrollcontainer.h"
#include "lltoolmgr.h"
#include "lltoolpipette.h"
+#include "llfiltereditor.h"
#include "lltool.h"
#include "llviewerwindow.h"
#include "llviewerobject.h"
#include "llviewercontrol.h"
#include "llglheaders.h"
-#include "llvieweruictrlfactory.h"
+#include "lluictrlfactory.h"
+#include "lltrans.h"
-static const S32 CLOSE_BTN_WIDTH = 100;
-const S32 PIPETTE_BTN_WIDTH = 32;
static const S32 HPAD = 4;
static const S32 VPAD = 4;
static const S32 LINE = 16;
-static const S32 SMALL_BTN_WIDTH = 64;
-static const S32 TEX_PICKER_MIN_WIDTH =
- (HPAD +
- CLOSE_BTN_WIDTH +
- HPAD +
- CLOSE_BTN_WIDTH +
- HPAD +
- SMALL_BTN_WIDTH +
- HPAD +
- SMALL_BTN_WIDTH +
- HPAD +
- 30 +
- RESIZE_HANDLE_WIDTH * 2);
-static const S32 CLEAR_BTN_WIDTH = 50;
-static const S32 TEX_PICKER_MIN_HEIGHT = 290;
static const S32 FOOTER_HEIGHT = 100;
static const S32 BORDER_PAD = HPAD;
static const S32 TEXTURE_INVENTORY_PADDING = 30;
@@ -106,24 +90,25 @@ class LLFloaterTexturePicker : public LLFloater
public:
LLFloaterTexturePicker(
LLTextureCtrl* owner,
- const LLRect& rect,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
- BOOL can_apply_immediately);
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image_name);
+
virtual ~LLFloaterTexturePicker();
// LLView overrides
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
- LLString& tooltip_msg);
- virtual void draw();
- virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
+ std::string& tooltip_msg);
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
// LLFloater overrides
- virtual void onClose(bool app_quitting);
- virtual BOOL postBuild();
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_settings);
// New functions
void setImageID( const LLUUID& image_asset_id);
@@ -132,8 +117,6 @@ public:
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
void setCanApplyImmediately(BOOL b);
- void setDirty( BOOL b ) { mIsDirty = b; }
- BOOL isDirty() const { return mIsDirty; }
void setActive( BOOL active );
LLTextureCtrl* getOwner() const { return mOwner; }
@@ -143,41 +126,42 @@ public:
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
-
+
+ void onFilterEdit(const std::string& search_string );
+
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
static void onBtnCancel( void* userdata );
- static void onBtnPipette( void* userdata );
+ void onBtnPipette( );
//static void onBtnRevert( void* userdata );
static void onBtnWhite( void* userdata );
static void onBtnNone( void* userdata );
static void onBtnClear( void* userdata );
- static void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
- static void onSearchEdit(const LLString& search_string, void* user_data );
- static void onTextureSelect( const LLTextureEntry& te, void *data );
+ void onTextureSelect( const LLTextureEntry& te );
protected:
- LLPointer<LLViewerImage> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
LLTextureCtrl* mOwner;
LLUUID mImageAssetID; // Currently selected texture
+ LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
LLUUID mWhiteImageAssetID;
LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
LLUUID mOriginalImageAssetID;
- std::string mLabel;
+ std::string mLabel;
LLTextBox* mTentativeLabel;
LLTextBox* mResolutionLabel;
- LLString mPendingName;
- BOOL mIsDirty;
+ std::string mPendingName;
BOOL mActive;
- LLSearchEditor* mSearchEdit;
+ LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
@@ -185,100 +169,36 @@ protected:
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
+
+ BOOL mSelectedItemPinned;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLTextureCtrl* owner,
- const LLRect& rect,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
- BOOL can_apply_immediately)
- :
- LLFloater( "texture picker",
- rect,
- LLString( "Pick: " ) + label,
- TRUE,
- TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT ),
+ BOOL can_apply_immediately,
+ LLUIImagePtr fallback_image)
+: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
+ mFallbackImage( fallback_image ),
mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),
mOriginalImageAssetID(owner->getImageAssetID()),
mLabel(label),
mTentativeLabel(NULL),
mResolutionLabel(NULL),
- mIsDirty( FALSE ),
mActive( TRUE ),
- mSearchEdit(NULL),
+ mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
- mContextConeOpacity(0.f)
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE )
{
- gUICtrlFactory->buildFloater(this,"floater_texture_ctrl.xml");
-
- mTentativeLabel = LLUICtrlFactory::getTextBoxByName(this,"Multiple");
-
- mResolutionLabel = LLUICtrlFactory::getTextBoxByName(this,"unknown");
-
-
- childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
- childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
- childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
-
-
- childSetCommitCallback("show_folders_check", onShowFolders, this);
- childSetVisible("show_folders_check", FALSE);
-
- mSearchEdit = (LLSearchEditor*)getCtrlByNameAndType("inventory search editor", WIDGET_TYPE_SEARCH_EDITOR);
- mSearchEdit->setSearchCallback(onSearchEdit, this);
-
- mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("inventory panel", WIDGET_TYPE_INVENTORY_PANEL);
-
- if(mInventoryPanel)
- {
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
- filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
-
- mInventoryPanel->setFilterTypes(filter_types);
- //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
- mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask);
- mInventoryPanel->setSelectCallback(onSelectionChange, this);
- mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mInventoryPanel->setAllowMultiSelect(FALSE);
-
- // store this filter as the default one
- mInventoryPanel->getRootFolder()->getFilter()->markDefault();
-
- // Commented out to stop opening all folders with textures
- // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE);
-
- // don't put keyboard focus on selected item, because the selection callback
- // will assume that this was user input
- mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
- }
-
+ buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
- mNoCopyTextureSelected = FALSE;
-
- childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately"));
- childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
-
- if (!can_apply_immediately)
- {
- childSetEnabled("show_folders_check", FALSE);
- }
-
- childSetAction("Pipette", LLFloaterTexturePicker::onBtnPipette,this);
- childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
- childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
-
- // update permission filter once UI is fully initialized
- updateFilterPermMask();
-
setCanMinimize(FALSE);
-
- mSavedFolderState.setApply(FALSE);
}
LLFloaterTexturePicker::~LLFloaterTexturePicker()
@@ -290,7 +210,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
if( mImageAssetID != image_id && mActive)
{
mNoCopyTextureSelected = FALSE;
- mIsDirty = TRUE;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
mImageAssetID = image_id;
LLUUID item_id = findItemID(mImageAssetID, FALSE);
if (item_id.isNull())
@@ -303,7 +223,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
// no copy texture
- childSetValue("apply_immediate_check", FALSE);
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
mNoCopyTextureSelected = TRUE;
}
mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
@@ -313,7 +233,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
void LLFloaterTexturePicker::setActive( BOOL active )
{
- if (!active && childGetValue("Pipette").asBoolean())
+ if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
{
stopUsingPipette();
}
@@ -325,16 +245,16 @@ void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
mCanApplyImmediately = b;
if (!mCanApplyImmediately)
{
- childSetValue("apply_immediate_check", FALSE);
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
}
updateFilterPermMask();
}
void LLFloaterTexturePicker::stopUsingPipette()
{
- if (gToolMgr && gToolMgr->getCurrentTool() == gToolPipette)
+ if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance())
{
- gToolMgr->clearTransientTool();
+ LLToolMgr::getInstance()->clearTransientTool();
}
}
@@ -343,16 +263,20 @@ void LLFloaterTexturePicker::updateImageStats()
if (mTexturep.notNull())
{
//RN: have we received header data for this image?
- if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0)
+ if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0)
{
- LLString formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0));
+ std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight());
mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
}
else
{
- mResolutionLabel->setTextArg("[DIMENSIONS]", LLString("[? x ?]"));
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
}
}
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
+ }
}
// virtual
@@ -361,7 +285,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
BOOL drop,
EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
- LLString& tooltip_msg)
+ std::string& tooltip_msg)
{
BOOL handled = FALSE;
@@ -407,19 +331,19 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
return handled;
}
-BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
+BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
{
LLFolderView* root_folder = mInventoryPanel->getRootFolder();
- if (root_folder && mSearchEdit)
+ if (root_folder && mFilterEdit)
{
- if (!called_from_parent && mSearchEdit->hasFocus() &&
- (key == KEY_RETURN || key == KEY_DOWN) &&
- mask == MASK_NONE)
+ if (mFilterEdit->hasFocus()
+ && (key == KEY_RETURN || key == KEY_DOWN)
+ && mask == MASK_NONE)
{
if (!root_folder->getCurSelectedItem())
{
- LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
+ LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
if (itemp)
{
root_folder->setSelection(itemp, FALSE, FALSE);
@@ -428,7 +352,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_
root_folder->scrollToShowSelection();
// move focus to inventory proper
- root_folder->setFocus(TRUE);
+ mInventoryPanel->setFocus(TRUE);
// treat this as a user selection of the first filtered result
commitIfImmediateSet();
@@ -436,16 +360,15 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_
return TRUE;
}
- if (root_folder->hasFocus() && key == KEY_UP)
+ if (mInventoryPanel->hasFocus() && key == KEY_UP)
{
- mSearchEdit->focusFirstItem(TRUE);
+ mFilterEdit->focusFirstItem(TRUE);
}
}
- return LLFloater::handleKeyHere(key, mask, called_from_parent);
+ return LLFloater::handleKeyHere(key, mask);
}
-// virtual
void LLFloaterTexturePicker::onClose(bool app_quitting)
{
if (mOwner)
@@ -453,7 +376,6 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
mOwner->onFloaterClose();
}
stopUsingPipette();
- destroy();
}
// virtual
@@ -467,13 +389,81 @@ BOOL LLFloaterTexturePicker::postBuild()
setTitle(pick + mLabel);
}
+ mTentativeLabel = getChild<LLTextBox>("Multiple");
+
+ mResolutionLabel = getChild<LLTextBox>("unknown");
+
+
+ childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
+ childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
+ childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
+
+
+ childSetCommitCallback("show_folders_check", onShowFolders, this);
+ getChildView("show_folders_check")->setVisible( FALSE);
+
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+
+ mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
+
+ if(mInventoryPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+
+ mInventoryPanel->setFilterTypes(filter_types);
+ //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->setAllowMultiSelect(FALSE);
+
+ // Disable auto selecting first filtered item because it takes away
+ // selection from the item set by LLTextureCtrl owning this floater.
+ mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE);
+
+ // Commented out to scroll to currently selected texture. See EXT-5403.
+ // // store this filter as the default one
+ // mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+
+ // Commented out to stop opening all folders with textures
+ // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
+
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
+ mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ }
+
+
+ mNoCopyTextureSelected = FALSE;
+
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately"));
+ childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
+
+ if (!mCanApplyImmediately)
+ {
+ getChildView("show_folders_check")->setEnabled(FALSE);
+ }
+ getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
+ childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
+ childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
+
+ // update permission filter once UI is fully initialized
+ updateFilterPermMask();
+ mSavedFolderState.setApply(FALSE);
+
+ LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
+
return TRUE;
}
// virtual
void LLFloaterTexturePicker::draw()
{
+ S32 floater_header_size = getHeaderHeight();
if (mOwner)
{
// draw cone of context pointing back to texture swatch
@@ -482,9 +472,9 @@ void LLFloaterTexturePicker::draw()
LLRect local_rect = getLocalRect();
if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
{
- LLGLSNoTexture no_texture;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLEnable(GL_CULL_FACE);
- gGL.begin(GL_QUADS);
+ gGL.begin(LLRender::QUADS);
{
gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
@@ -531,22 +521,19 @@ void LLFloaterTexturePicker::draw()
updateImageStats();
// if we're inactive, gray out "apply immediate" checkbox
- childSetEnabled("show_folders_check", mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
- childSetEnabled("Select", mActive);
- childSetEnabled("Pipette", gToolMgr != NULL && mActive);
- childSetValue("Pipette", gToolMgr && gToolMgr->getCurrentTool() == gToolPipette);
-
- //RN: reset search bar to reflect actual search query (all caps, for example)
- mSearchEdit->setText(mInventoryPanel->getFilterSubString());
+ getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
+ getChildView("Select")->setEnabled(mActive);
+ getChildView("Pipette")->setEnabled(mActive);
+ getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
//BOOL allow_copy = FALSE;
- if( getVisible() && mOwner)
+ if( mOwner )
{
mTexturep = NULL;
if(mImageAssetID.notNull())
{
- mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
}
if (mTentativeLabel)
@@ -554,9 +541,9 @@ void LLFloaterTexturePicker::draw()
mTentativeLabel->setVisible( FALSE );
}
- childSetEnabled("Default", mImageAssetID != mOwner->getDefaultImageAssetID());
- childSetEnabled("Blank", mImageAssetID != mWhiteImageAssetID );
- childSetEnabled("None", mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );
+ getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID());
+ getChildView("Blank")->setEnabled(mImageAssetID != mWhiteImageAssetID );
+ getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );
LLFloater::draw();
@@ -567,9 +554,9 @@ void LLFloaterTexturePicker::draw()
// Border
LLRect border( BORDER_PAD,
- getRect().getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD,
- ((TEX_PICKER_MIN_WIDTH / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD,
- BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - TEX_PICKER_MIN_HEIGHT));
+ getRect().getHeight() - floater_header_size - BORDER_PAD,
+ ((getMinWidth() / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD,
+ BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - getMinHeight()));
gl_rect_2d( border, LLColor4::black, FALSE );
@@ -588,13 +575,10 @@ void LLFloaterTexturePicker::draw()
// Pump the priority
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
-
- // Draw Tentative Label over the image
- if( mOwner->getTentative() && !mIsDirty )
- {
- mTentativeLabel->setVisible( TRUE );
- drawChild(mTentativeLabel);
- }
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior);
}
else
{
@@ -603,6 +587,38 @@ void LLFloaterTexturePicker::draw()
// Draw X
gl_draw_x(interior, LLColor4::black );
}
+
+ // Draw Tentative Label over the image
+ if( mOwner->getTentative() && !mViewModel->isDirty() )
+ {
+ mTentativeLabel->setVisible( TRUE );
+ drawChild(mTentativeLabel);
+ }
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLInventoryFilter* filter = folder_view->getFilter();
+ if (!filter) return;
+
+ bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+ filter->isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->dirtyFilter();
+ folder_view->arrangeFromRoot();
+
+ mSelectedItemPinned = TRUE;
+ }
}
}
@@ -657,13 +673,13 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co
PermissionMask LLFloaterTexturePicker::getFilterPermMask()
{
- bool apply_immediate = childGetValue("apply_immediate_check").asBoolean();
+ bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
return apply_immediate ? mImmediateFilterPermMask : mNonImmediateFilterPermMask;
}
void LLFloaterTexturePicker::commitIfImmediateSet()
{
- bool apply_immediate = childGetValue("apply_immediate_check").asBoolean();
+ bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
if (!mNoCopyTextureSelected && apply_immediate && mOwner)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
@@ -707,7 +723,7 @@ void LLFloaterTexturePicker::onBtnRevert(void* userdata)
// TODO: Change this to tell the owner to cancel. It needs to be
// smart enough to restore multi-texture selections.
self->mOwner->onFloaterCommit();
- self->mIsDirty = FALSE;
+ self->mViewModel->resetDirty();
}*/
// static
@@ -719,8 +735,8 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
}
- self->mIsDirty = FALSE;
- self->close();
+ self->mViewModel->resetDirty();
+ self->closeFloater();
}
// static
@@ -731,52 +747,42 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT);
}
- self->close();
+ self->closeFloater();
}
-// static
-void LLFloaterTexturePicker::onBtnPipette( void* userdata )
+void LLFloaterTexturePicker::onBtnPipette()
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
-
- if ( self && gToolMgr)
+ BOOL pipette_active = getChild<LLUICtrl>("Pipette")->getValue().asBoolean();
+ pipette_active = !pipette_active;
+ if (pipette_active)
{
- BOOL pipette_active = self->childGetValue("Pipette").asBoolean();
- pipette_active = !pipette_active;
- if (pipette_active)
- {
- gToolPipette->setSelectCallback(onTextureSelect, self);
- gToolMgr->setTransientTool(gToolPipette);
- }
- else
- {
- gToolMgr->clearTransientTool();
- }
+ LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
+ }
+ else
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
}
-
}
-// static
-void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
+void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
if (items.size())
{
LLFolderViewItem* first_item = items.front();
LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
- self->mNoCopyTextureSelected = FALSE;
+ mNoCopyTextureSelected = FALSE;
if (itemp)
{
if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
- self->mNoCopyTextureSelected = TRUE;
+ mNoCopyTextureSelected = TRUE;
}
- self->mImageAssetID = itemp->getAssetUUID();
- self->mIsDirty = TRUE;
+ mImageAssetID = itemp->getAssetUUID();
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if (user_action)
{
// only commit intentional selections, not implicit ones
- self->commitIfImmediateSet();
+ commitIfImmediateSet();
}
}
}
@@ -815,198 +821,135 @@ void LLFloaterTexturePicker::updateFilterPermMask()
//mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
}
-void LLFloaterTexturePicker::onSearchEdit(const LLString& search_string, void* user_data )
+void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
{
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
-
std::string upper_case_search_string = search_string;
- LLString::toUpper(upper_case_search_string);
+ LLStringUtil::toUpper(upper_case_search_string);
if (upper_case_search_string.empty())
{
- if (picker->mInventoryPanel->getFilterSubString().empty())
+ if (mInventoryPanel->getFilterSubString().empty())
{
// current filter and new filter empty, do nothing
return;
}
- picker->mSavedFolderState.setApply(TRUE);
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
+ mSavedFolderState.setApply(TRUE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
// add folder with current item to list of previously opened folders
LLOpenFoldersWithSelection opener;
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
- picker->mInventoryPanel->getRootFolder()->scrollToShowSelection();
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryPanel->getRootFolder()->scrollToShowSelection();
}
- else if (picker->mInventoryPanel->getFilterSubString().empty())
+ else if (mInventoryPanel->getFilterSubString().empty())
{
// first letter in search term, save existing folder open state
- if (!picker->mInventoryPanel->getRootFolder()->isFilterModified())
+ if (!mInventoryPanel->getRootFolder()->isFilterModified())
{
- picker->mSavedFolderState.setApply(FALSE);
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
+ mSavedFolderState.setApply(FALSE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
}
}
- picker->mInventoryPanel->setFilterSubString(upper_case_search_string);
+ mInventoryPanel->setFilterSubString(search_string);
}
-//static
-void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te, void *data )
+void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
-
- LLUUID inventory_item_id = self->findItemID(te.getID(), TRUE);
- if (self && inventory_item_id.notNull())
+ LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
+ if (inventory_item_id.notNull())
{
- gToolPipette->setResult(TRUE, "");
- self->setImageID(te.getID());
+ LLToolPipette::getInstance()->setResult(TRUE, "");
+ setImageID(te.getID());
- self->mNoCopyTextureSelected = FALSE;
+ mNoCopyTextureSelected = FALSE;
LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
// no copy texture
- self->mNoCopyTextureSelected = TRUE;
+ mNoCopyTextureSelected = TRUE;
}
- self->commitIfImmediateSet();
+ commitIfImmediateSet();
}
else
{
- gToolPipette->setResult(FALSE, "You do not have a copy this \nof texture in your inventory");
+ LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture"));
}
}
///////////////////////////////////////////////////////////////////////
// LLTextureCtrl
-LLTextureCtrl::LLTextureCtrl(
- const std::string& name,
- const LLRect &rect,
- const std::string& label,
- const LLUUID &image_id,
- const LLUUID &default_image_id,
- const std::string& default_image_name )
- :
- LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
+static LLDefaultChildRegistry::Register<LLTextureCtrl> r("texture_picker");
+
+LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
+: LLUICtrl(p),
mDragCallback(NULL),
mDropCallback(NULL),
mOnCancelCallback(NULL),
mOnSelectCallback(NULL),
- mBorderColor( gColors.getColor("DefaultHighlightLight") ),
- mImageAssetID( image_id ),
- mDefaultImageAssetID( default_image_id ),
- mDefaultImageName( default_image_name ),
- mLabel( label ),
+ mBorderColor( p.border_color() ),
mAllowNoTexture( FALSE ),
mImmediateFilterPermMask( PERM_NONE ),
mNonImmediateFilterPermMask( PERM_NONE ),
mCanApplyImmediately( FALSE ),
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
- mDirty( FALSE )
+ mShowLoadingPlaceholder( TRUE ),
+ mImageAssetID(p.image_id),
+ mDefaultImageAssetID(p.default_image_id),
+ mDefaultImageName(p.default_image_name),
+ mFallbackImage(p.fallback_image)
{
- mCaption = new LLTextBox( label,
- LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
- label,
- LLFontGL::sSansSerifSmall );
- mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
+ setAllowNoTexture(p.allow_no_texture);
+ setCanApplyImmediately(p.can_apply_immediately);
+ mCommitOnSelection = !p.no_commit_on_selection;
+
+ LLTextBox::Params params(p.caption_text);
+ params.name(p.label);
+ params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ params.initial_value(p.label());
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ mCaption = LLUICtrlFactory::create<LLTextBox> (params);
addChild( mCaption );
S32 image_top = getRect().getHeight();
S32 image_bottom = BTN_HEIGHT_SMALL;
S32 image_middle = (image_top + image_bottom) / 2;
- S32 line_height = llround(LLFontGL::sSansSerifSmall->getLineHeight());
-
- mTentativeLabel = new LLTextBox( "Multiple",
- LLRect(
- 0, image_middle + line_height / 2,
- getRect().getWidth(), image_middle - line_height / 2 ),
- "Multiple",
- LLFontGL::sSansSerifSmall );
- mTentativeLabel->setHAlign( LLFontGL::HCENTER );
- mTentativeLabel->setFollowsAll();
+ S32 line_height = llround(LLFontGL::getFontSansSerifSmall()->getLineHeight());
+
+ LLTextBox::Params tentative_label_p(p.multiselect_text);
+ tentative_label_p.name("Multiple");
+ tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 ));
+ tentative_label_p.follows.flags(FOLLOWS_ALL);
+ mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p);
addChild( mTentativeLabel );
- LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ LLRect border_rect = getLocalRect();
border_rect.mBottom += BTN_HEIGHT_SMALL;
- mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN);
+ LLViewBorder::Params vbparams(p.border);
+ vbparams.name("border");
+ vbparams.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams);
addChild(mBorder);
- setEnabled(TRUE); // for the tooltip
+ mLoadingPlaceholderString = LLTrans::getString("texture_loading");
}
-
LLTextureCtrl::~LLTextureCtrl()
{
- closeFloater();
+ closeDependentFloater();
}
-// virtual
-LLXMLNodePtr LLTextureCtrl::getXML(bool save_children) const
+void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder)
{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("label", TRUE)->setStringValue(getLabel());
-
- node->createChild("default_image_name", TRUE)->setStringValue(getDefaultImageName());
-
- node->createChild("allow_no_texture", TRUE)->setBoolValue(mAllowNoTexture);
-
- node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately );
-
- return node;
-}
-
-LLView* LLTextureCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- LLString name("texture_picker");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent);
-
- LLString label;
- node->getAttributeString("label", label);
-
- LLString image_id("");
- node->getAttributeString("image", image_id);
-
- LLString default_image_id("");
- node->getAttributeString("default_image", default_image_id);
-
- LLString default_image_name("Default");
- node->getAttributeString("default_image_name", default_image_name);
-
- BOOL allow_no_texture = FALSE;
- node->getAttributeBOOL("allow_no_texture", allow_no_texture);
-
- BOOL can_apply_immediately = FALSE;
- node->getAttributeBOOL("can_apply_immediately", can_apply_immediately);
-
- if (label.empty())
- {
- label.assign(node->getValue());
- }
-
- LLTextureCtrl* texture_picker = new LLTextureCtrl(
- name,
- rect,
- label,
- LLUUID(image_id),
- LLUUID(default_image_id),
- default_image_name );
- texture_picker->setAllowNoTexture(allow_no_texture);
- texture_picker->setCanApplyImmediately(can_apply_immediately);
-
- texture_picker->initFromXML(node, parent);
-
- return texture_picker;
+ mShowLoadingPlaceholder = showLoadingPlaceholder;
}
-void LLTextureCtrl::setCaption(const LLString& caption)
+void LLTextureCtrl::setCaption(const std::string& caption)
{
mCaption->setText( caption );
}
@@ -1025,7 +968,7 @@ void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
{
- closeFloater();
+ closeDependentFloater();
}
LLUICtrl::setVisible( visible );
}
@@ -1035,16 +978,16 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( enabled )
{
- LLString tooltip;
- if (floaterp) tooltip = floaterp->getUIString("choose_picture");
+ std::string tooltip;
+ if (floaterp) tooltip = floaterp->getString("choose_picture");
setToolTip( tooltip );
}
else
{
- setToolTip( LLString() );
+ setToolTip( std::string() );
// *TODO: would be better to keep floater open and show
// disabled state.
- closeFloater();
+ closeDependentFloater();
}
if( floaterp )
@@ -1070,18 +1013,6 @@ void LLTextureCtrl::setValid(BOOL valid )
}
}
-// virtual
-BOOL LLTextureCtrl::isDirty() const
-{
- return mDirty;
-}
-
-// virtual
-void LLTextureCtrl::resetDirty()
-{
- mDirty = FALSE;
-}
-
// virtual
void LLTextureCtrl::clear()
@@ -1089,7 +1020,7 @@ void LLTextureCtrl::clear()
setImageAssetID(LLUUID::null);
}
-void LLTextureCtrl::setLabel(const LLString& label)
+void LLTextureCtrl::setLabel(const std::string& label)
{
mLabel = label;
mCaption->setText(label);
@@ -1097,33 +1028,32 @@ void LLTextureCtrl::setLabel(const LLString& label)
void LLTextureCtrl::showPicker(BOOL take_focus)
{
+ // show hourglass cursor when loading inventory window
+ // because inventory construction is slooow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
LLFloater* floaterp = mFloaterHandle.get();
// Show the dialog
if( floaterp )
{
- floaterp->open( ); /* Flawfinder: ignore */
+ floaterp->openFloater();
}
else
{
- if( !mLastFloaterLeftTop.mX && !mLastFloaterLeftTop.mY )
- {
- gFloaterView->getNewFloaterPosition(&mLastFloaterLeftTop.mX, &mLastFloaterLeftTop.mY);
- }
- LLRect rect = gSavedSettings.getRect("TexturePickerRect");
- rect.translate( mLastFloaterLeftTop.mX - rect.mLeft, mLastFloaterLeftTop.mY - rect.mTop );
-
floaterp = new LLFloaterTexturePicker(
this,
- rect,
mLabel,
mImmediateFilterPermMask,
mNonImmediateFilterPermMask,
- mCanApplyImmediately);
+ mCanApplyImmediately,
+ mFallbackImage);
+
mFloaterHandle = floaterp->getHandle();
- gFloaterView->getParentFloater(this)->addDependentFloater(floaterp);
- floaterp->open(); /* Flawfinder: ignore */
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(floaterp);
+ floaterp->openFloater();
}
if (take_focus)
@@ -1133,13 +1063,13 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
}
-void LLTextureCtrl::closeFloater()
+void LLTextureCtrl::closeDependentFloater()
{
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( floaterp )
{
floaterp->setOwner(NULL);
- floaterp->close();
+ floaterp->closeFloater();
}
}
@@ -1151,7 +1081,7 @@ public:
{
// We need to find textures in all folders, so get the main
// background download going.
- gInventory.startBackgroundFetch();
+ LLInventoryModelBackgroundFetch::instance().start();
gInventory.removeObserver(this);
delete this;
}
@@ -1167,15 +1097,17 @@ BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask)
BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleMouseDown( x, y , mask );
- if( handled )
+
+ if( !handled )
{
showPicker(FALSE);
-
//grab textures first...
- gInventory.startBackgroundFetch(gInventory.findCategoryUUIDForType(LLAssetType::AT_TEXTURE));
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
//...then start full inventory fetch.
- gInventory.startBackgroundFetch();
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
}
+
return handled;
}
@@ -1186,7 +1118,6 @@ void LLTextureCtrl::onFloaterClose()
if (floaterp)
{
floaterp->setOwner(NULL);
- mLastFloaterLeftTop.set( floaterp->getRect().mLeft, floaterp->getRect().mTop );
}
mFloaterHandle.markDead();
@@ -1198,7 +1129,14 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
if( floaterp && getEnabled())
{
- mDirty = (op != TEXTURE_CANCEL);
+ if (op == TEXTURE_CANCEL)
+ mViewModel->resetDirty();
+ // If the "no_commit_on_selection" parameter is set
+ // we get dirty only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ else if (mCommitOnSelection || op == TEXTURE_SELECT)
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
if( floaterp->isDirty() )
{
setTentative( FALSE );
@@ -1208,20 +1146,38 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
if (op == TEXTURE_SELECT && mOnSelectCallback)
{
- mOnSelectCallback(this, mCallbackUserData);
+ mOnSelectCallback( this, LLSD() );
}
else if (op == TEXTURE_CANCEL && mOnCancelCallback)
{
- mOnCancelCallback(this, mCallbackUserData);
+ mOnCancelCallback( this, LLSD() );
}
else
{
- onCommit();
+ // If the "no_commit_on_selection" parameter is set
+ // we commit only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ if (mCommitOnSelection || op == TEXTURE_SELECT)
+ onCommit();
}
}
}
}
+void LLTextureCtrl::setImageAssetName(const std::string& name)
+{
+ LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
+ if(imagep)
+ {
+ LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
+ if(pTexture)
+ {
+ LLUUID id = pTexture->getID();
+ setImageAssetID(id);
+ }
+ }
+}
+
void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
{
if( mImageAssetID != asset_id )
@@ -1232,7 +1188,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
if( floaterp && getEnabled() )
{
floaterp->setImageID( asset_id );
- floaterp->setDirty( FALSE );
+ floaterp->resetDirty();
}
}
}
@@ -1240,7 +1196,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
- LLString& tooltip_msg)
+ std::string& tooltip_msg)
{
BOOL handled = FALSE;
@@ -1254,6 +1210,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
{
if(doDrop(item))
{
+ if (!mCommitOnSelection)
+ mViewModel->setDirty();
+
// This removes the 'Multiple' overlay, since
// there is now only one texture selected.
setTentative( FALSE );
@@ -1276,50 +1235,107 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
void LLTextureCtrl::draw()
{
- if( getVisible() )
+ mBorder->setKeyboardFocusHighlight(hasFocus());
+
+ if (!mValid)
+ {
+ mTexturep = NULL;
+ }
+ else if (!mImageAssetID.isNull())
{
- mBorder->setKeyboardFocusHighlight(hasFocus());
+ LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ texture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+ texture->forceToSaveRawImage(0) ;
- if (mImageAssetID.isNull() || !mValid)
- {
- mTexturep = NULL;
- }
- else
+ mTexturep = texture;
+ }
+ else//mImageAssetID == LLUUID::null
+ {
+ mTexturep = NULL;
+ }
+
+ // Border
+ LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
+ gl_rect_2d( border, mBorderColor.get(), FALSE );
+
+ // Interior
+ LLRect interior = border;
+ interior.stretch( -1 );
+
+ if( mTexturep )
+ {
+ if( mTexturep->getComponents() == 4 )
{
- mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ gl_rect_2d_checkerboard( interior );
}
- // Border
- LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
- gl_rect_2d( border, mBorderColor, FALSE );
+ gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep);
+ mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ }
+ else if (!mFallbackImage.isNull())
+ {
+ mFallbackImage->draw(interior);
+ }
+ else
+ {
+ gl_rect_2d( interior, LLColor4::grey, TRUE );
- // Interior
- LLRect interior = border;
- interior.stretch( -1 );
+ // Draw X
+ gl_draw_x( interior, LLColor4::black );
+ }
- if( mTexturep )
+ mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() );
+
+ // Show "Loading..." string on the top left corner while this texture is loading.
+ // Using the discard level, do not show the string if the texture is almost but not
+ // fully loaded.
+ if (mTexturep.notNull() &&
+ (!mTexturep->isFullyLoaded()) &&
+ (mShowLoadingPlaceholder == TRUE))
+ {
+ U32 v_offset = 25;
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+
+ // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god
+ if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike())
{
- if( mTexturep->getComponents() == 4 )
- {
- gl_rect_2d_checkerboard( interior );
- }
-
- gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep);
- mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+ font->renderUTF8(
+ mLoadingPlaceholderString,
+ 0,
+ llfloor(interior.mLeft+3),
+ llfloor(interior.mTop-v_offset),
+ LLColor4::white,
+ LLFontGL::LEFT,
+ LLFontGL::BASELINE,
+ LLFontGL::DROP_SHADOW);
}
- else
- {
- gl_rect_2d( interior, LLColor4::grey, TRUE );
- // Draw X
- gl_draw_x( interior, LLColor4::black );
+ // Optionally show more detailed information.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+ std::string tdesc;
+ // Show what % the texture has loaded (0 to 100%, 100 is highest), and what level of detail (5 to 0, 0 is best).
+
+ v_offset += 12;
+ tdesc = llformat(" PK : %d%%", U32(mTexturep->getDownloadProgress()*100.0));
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" LVL: %d", mTexturep->getDiscardLevel());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+
+ v_offset += 12;
+ tdesc = llformat(" ID : %s...", (mImageAssetID.asString().substr(0,7)).c_str());
+ font->renderUTF8(tdesc, 0, llfloor(interior.mLeft+3), llfloor(interior.mTop-v_offset),
+ LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
}
-
- mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() );
-
- LLUICtrl::draw();
}
+
+ LLUICtrl::draw();
}
BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
@@ -1341,7 +1357,7 @@ BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
{
if(mDragCallback)
{
- return mDragCallback(this, item, mCallbackUserData);
+ return mDragCallback(this, item);
}
else
{
@@ -1361,7 +1377,7 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
{
// if it returns TRUE, we return TRUE, and therefore the
// commit is called above.
- return mDropCallback(this, item, mCallbackUserData);
+ return mDropCallback(this, item);
}
// no callback installed, so just set the image ids and carry on.
@@ -1370,17 +1386,17 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
return TRUE;
}
-BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent)
+BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
{
- if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char )
+ if( ' ' == uni_char )
{
showPicker(TRUE);
return TRUE;
}
- return LLUICtrl::handleUnicodeCharHere(uni_char, called_from_parent);
+ return LLUICtrl::handleUnicodeCharHere(uni_char);
}
-void LLTextureCtrl::setValue( LLSD value )
+void LLTextureCtrl::setValue( const LLSD& value )
{
setImageAssetID(value.asUUID());
}
@@ -1391,64 +1407,6 @@ LLSD LLTextureCtrl::getValue() const
}
-/////////////////////////////////////////////////////////////////////////////////
-// LLToolTexEyedropper
-
-class LLToolTexEyedropper : public LLTool
-{
-public:
- LLToolTexEyedropper( void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ), void* userdata );
- virtual ~LLToolTexEyedropper();
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
-
-protected:
- void (*mCallback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata );
- void* mCallbackUserData;
-};
-
-
-LLToolTexEyedropper::LLToolTexEyedropper(
- void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ),
- void* userdata )
- : LLTool("texeyedropper"),
- mCallback( callback ),
- mCallbackUserData( userdata )
-{
-}
-
-LLToolTexEyedropper::~LLToolTexEyedropper()
-{
-}
-
-
-BOOL LLToolTexEyedropper::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
- if (hit_obj &&
- !hit_obj->isAvatar())
- {
- if( (0 <= gLastHitObjectFace) && (gLastHitObjectFace < hit_obj->getNumTEs()) )
- {
- LLViewerImage* image = hit_obj->getTEImage( gLastHitObjectFace );
- if( image )
- {
- if( mCallback )
- {
- mCallback( hit_obj->getID(), image->getID(), mCallbackUserData );
- }
- }
- }
- }
- return TRUE;
-}
-
-BOOL LLToolTexEyedropper::handleHover(S32 x, S32 y, MASK mask)
-{
- lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolTexEyedropper" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_CROSS); // TODO: better cursor
- return TRUE;
-}