lltexturectrl.cpp

Go to the documentation of this file.
00001 
00033 #include "llviewerprecompiledheaders.h"
00034 
00035 #include "lltexturectrl.h"
00036 
00037 #include "llglimmediate.h"
00038 #include "llagent.h"
00039 #include "llviewerimagelist.h"
00040 #include "llcheckboxctrl.h"
00041 #include "llcombobox.h"
00042 #include "llbutton.h"
00043 #include "lldraghandle.h"
00044 #include "llfocusmgr.h"
00045 #include "llviewerimage.h"
00046 #include "llfolderview.h"
00047 #include "llinventory.h"
00048 #include "llinventorymodel.h"
00049 #include "llinventoryview.h"
00050 #include "lllineeditor.h"
00051 #include "llui.h"
00052 #include "llviewerinventory.h"
00053 #include "llpermissions.h"
00054 #include "llsaleinfo.h"
00055 #include "llassetstorage.h"
00056 #include "lltextbox.h"
00057 #include "llresizehandle.h"
00058 #include "llscrollcontainer.h"
00059 #include "lltoolmgr.h"
00060 #include "lltoolpipette.h"
00061 
00062 #include "lltool.h"
00063 #include "llviewerwindow.h"
00064 #include "llviewerobject.h"
00065 #include "llviewercontrol.h"
00066 #include "llglheaders.h"
00067 #include "lluictrlfactory.h"
00068 
00069 
00070 static const S32 CLOSE_BTN_WIDTH = 100;
00071 const S32 PIPETTE_BTN_WIDTH = 32;
00072 static const S32 HPAD = 4;
00073 static const S32 VPAD = 4;
00074 static const S32 LINE = 16;
00075 static const S32 SMALL_BTN_WIDTH = 64;
00076 static const S32 TEX_PICKER_MIN_WIDTH = 
00077         (HPAD +
00078         CLOSE_BTN_WIDTH +
00079         HPAD +
00080         CLOSE_BTN_WIDTH +
00081         HPAD + 
00082         SMALL_BTN_WIDTH +
00083         HPAD +
00084         SMALL_BTN_WIDTH +
00085         HPAD + 
00086         30 +
00087         RESIZE_HANDLE_WIDTH * 2);
00088 static const S32 CLEAR_BTN_WIDTH = 50;
00089 static const S32 TEX_PICKER_MIN_HEIGHT = 290;
00090 static const S32 FOOTER_HEIGHT = 100;
00091 static const S32 BORDER_PAD = HPAD;
00092 static const S32 TEXTURE_INVENTORY_PADDING = 30;
00093 static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
00094 static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
00095 static const F32 CONTEXT_FADE_TIME = 0.08f;
00096 
00097 //static const char CURRENT_IMAGE_NAME[] = "Current Texture";
00098 //static const char WHITE_IMAGE_NAME[] = "Blank Texture";
00099 //static const char NO_IMAGE_NAME[] = "None";
00100 
00102 // LLFloaterTexturePicker
00103 
00104 class LLFloaterTexturePicker : public LLFloater
00105 {
00106 public:
00107         LLFloaterTexturePicker(
00108                 LLTextureCtrl* owner,
00109                 const LLRect& rect,
00110                 const std::string& label,
00111                 PermissionMask immediate_filter_perm_mask,
00112                 PermissionMask non_immediate_filter_perm_mask,
00113                 BOOL can_apply_immediately);
00114         virtual ~LLFloaterTexturePicker();
00115 
00116         // LLView overrides
00117         virtual BOOL    handleDragAndDrop(S32 x, S32 y, MASK mask,
00118                                                 BOOL drop, EDragAndDropType cargo_type, void *cargo_data, 
00119                                                 EAcceptance *accept,
00120                                                 LLString& tooltip_msg);
00121         virtual void    draw();
00122         virtual BOOL    handleKeyHere(KEY key, MASK mask);
00123 
00124         // LLFloater overrides
00125         virtual void    onClose(bool app_quitting);
00126         virtual BOOL    postBuild();
00127         
00128         // New functions
00129         void setImageID( const LLUUID& image_asset_id);
00130         void updateImageStats();
00131         const LLUUID& getAssetID() { return mImageAssetID; }
00132         const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
00133         void                    setCanApplyImmediately(BOOL b);
00134 
00135         void                    setDirty( BOOL b ) { mIsDirty = b; }
00136         BOOL                    isDirty() const { return mIsDirty; }
00137         void                    setActive( BOOL active );
00138 
00139         LLTextureCtrl*  getOwner() const { return mOwner; }
00140         void                    setOwner(LLTextureCtrl* owner) { mOwner = owner; }
00141         
00142         void                    stopUsingPipette();
00143         PermissionMask  getFilterPermMask();
00144         void updateFilterPermMask();
00145         void commitIfImmediateSet();
00146 
00147         static void             onBtnSetToDefault( void* userdata );
00148         static void             onBtnSelect( void* userdata );
00149         static void             onBtnCancel( void* userdata );
00150         static void             onBtnPipette( void* userdata );
00151         //static void           onBtnRevert( void* userdata );
00152         static void             onBtnWhite( void* userdata );
00153         static void             onBtnNone( void* userdata );
00154         static void             onBtnClear( void* userdata );
00155         static void             onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
00156         static void             onShowFolders(LLUICtrl* ctrl, void* userdata);
00157         static void             onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
00158         static void             onSearchEdit(const LLString& search_string, void* user_data );
00159         static void             onTextureSelect( const LLTextureEntry& te, void *data );
00160 
00161 protected:
00162         LLPointer<LLViewerImage> mTexturep;
00163         LLTextureCtrl*          mOwner;
00164 
00165         LLUUID                          mImageAssetID; // Currently selected texture
00166 
00167         LLUUID                          mWhiteImageAssetID;
00168         LLUUID                          mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.
00169         LLUUID                          mOriginalImageAssetID;
00170 
00171         std::string         mLabel;
00172 
00173         LLTextBox*                      mTentativeLabel;
00174         LLTextBox*                      mResolutionLabel;
00175 
00176         LLString                        mPendingName;
00177         BOOL                            mIsDirty;
00178         BOOL                            mActive;
00179 
00180         LLSearchEditor*         mSearchEdit;
00181         LLInventoryPanel*       mInventoryPanel;
00182         PermissionMask          mImmediateFilterPermMask;
00183         PermissionMask          mNonImmediateFilterPermMask;
00184         BOOL                            mCanApplyImmediately;
00185         BOOL                            mNoCopyTextureSelected;
00186         F32                                     mContextConeOpacity;
00187         LLSaveFolderState       mSavedFolderState;
00188 };
00189 
00190 LLFloaterTexturePicker::LLFloaterTexturePicker( 
00191         LLTextureCtrl* owner,
00192         const LLRect& rect,
00193         const std::string& label,
00194         PermissionMask immediate_filter_perm_mask,
00195         PermissionMask non_immediate_filter_perm_mask,
00196         BOOL can_apply_immediately)
00197         :
00198         LLFloater( "texture picker",
00199                 rect,
00200                 LLString( "Pick: " ) + label,
00201                 TRUE,
00202                 TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT ),
00203         mOwner( owner ),
00204         mImageAssetID( owner->getImageAssetID() ),
00205         mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),
00206         mOriginalImageAssetID(owner->getImageAssetID()),
00207         mLabel(label),
00208         mTentativeLabel(NULL),
00209         mResolutionLabel(NULL),
00210         mIsDirty( FALSE ),
00211         mActive( TRUE ),
00212         mSearchEdit(NULL),
00213         mImmediateFilterPermMask(immediate_filter_perm_mask),
00214         mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
00215         mContextConeOpacity(0.f)
00216 {
00217         LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml");
00218 
00219         mTentativeLabel = getChild<LLTextBox>("Multiple");
00220 
00221         mResolutionLabel = getChild<LLTextBox>("unknown");
00222 
00223 
00224         childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
00225         childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
00226         childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
00227 
00228                 
00229         childSetCommitCallback("show_folders_check", onShowFolders, this);
00230         childSetVisible("show_folders_check", FALSE);
00231         
00232         mSearchEdit = getChild<LLSearchEditor>("inventory search editor");
00233         mSearchEdit->setSearchCallback(onSearchEdit, this);
00234                 
00235         mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
00236 
00237         if(mInventoryPanel)
00238         {
00239                 U32 filter_types = 0x0;
00240                 filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
00241                 filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
00242 
00243                 mInventoryPanel->setFilterTypes(filter_types);
00244                 //mInventoryPanel->setFilterPermMask(getFilterPermMask());  //Commented out due to no-copy texture loss.
00245                 mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask);
00246                 mInventoryPanel->setSelectCallback(onSelectionChange, this);
00247                 mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00248                 mInventoryPanel->setAllowMultiSelect(FALSE);
00249 
00250                 // store this filter as the default one
00251                 mInventoryPanel->getRootFolder()->getFilter()->markDefault();
00252 
00253                 // Commented out to stop opening all folders with textures
00254                 // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE);
00255                 
00256                 // don't put keyboard focus on selected item, because the selection callback
00257                 // will assume that this was user input
00258                 mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
00259         }
00260 
00261         mCanApplyImmediately = can_apply_immediately;
00262         mNoCopyTextureSelected = FALSE;
00263                 
00264         childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately"));
00265         childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
00266         
00267         if (!can_apply_immediately)
00268         {
00269                 childSetEnabled("show_folders_check", FALSE);
00270         }
00271 
00272         childSetAction("Pipette", LLFloaterTexturePicker::onBtnPipette,this);
00273         childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
00274         childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
00275 
00276         // update permission filter once UI is fully initialized
00277         updateFilterPermMask();
00278 
00279         setCanMinimize(FALSE);
00280 
00281         mSavedFolderState.setApply(FALSE);
00282 }
00283 
00284 LLFloaterTexturePicker::~LLFloaterTexturePicker()
00285 {
00286 }
00287 
00288 void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
00289 {
00290         if( mImageAssetID != image_id && mActive)
00291         {
00292                 mNoCopyTextureSelected = FALSE;
00293                 mIsDirty = TRUE;
00294                 mImageAssetID = image_id; 
00295                 LLUUID item_id = findItemID(mImageAssetID, FALSE);
00296                 if (item_id.isNull())
00297                 {
00298                         mInventoryPanel->clearSelection();
00299                 }
00300                 else
00301                 {
00302                         LLInventoryItem* itemp = gInventory.getItem(image_id);
00303                         if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
00304                         {
00305                                 // no copy texture
00306                                 childSetValue("apply_immediate_check", FALSE);
00307                                 mNoCopyTextureSelected = TRUE;
00308                         }
00309                         mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
00310                 }
00311         }
00312 }
00313 
00314 void LLFloaterTexturePicker::setActive( BOOL active )                                   
00315 {
00316         if (!active && childGetValue("Pipette").asBoolean())
00317         {
00318                 stopUsingPipette();
00319         }
00320         mActive = active; 
00321 }
00322 
00323 void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
00324 {
00325         mCanApplyImmediately = b;
00326         if (!mCanApplyImmediately)
00327         {
00328                 childSetValue("apply_immediate_check", FALSE);
00329         }
00330         updateFilterPermMask();
00331 }
00332 
00333 void LLFloaterTexturePicker::stopUsingPipette()
00334 {
00335         if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance())
00336         {
00337                 LLToolMgr::getInstance()->clearTransientTool();
00338         }
00339 }
00340 
00341 void LLFloaterTexturePicker::updateImageStats()
00342 {
00343         if (mTexturep.notNull())
00344         {
00345                 //RN: have we received header data for this image?
00346                 if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0)
00347                 {
00348                         LLString formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0));
00349                         mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
00350                 }
00351                 else
00352                 {
00353                         mResolutionLabel->setTextArg("[DIMENSIONS]", LLString("[? x ?]"));
00354                 }
00355         }
00356 }
00357 
00358 // virtual
00359 BOOL LLFloaterTexturePicker::handleDragAndDrop( 
00360                 S32 x, S32 y, MASK mask,
00361                 BOOL drop,
00362                 EDragAndDropType cargo_type, void *cargo_data, 
00363                 EAcceptance *accept,
00364                 LLString& tooltip_msg)
00365 {
00366         BOOL handled = FALSE;
00367 
00368         if (cargo_type == DAD_TEXTURE)
00369         {
00370                 LLInventoryItem *item = (LLInventoryItem *)cargo_data;
00371 
00372                 BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
00373                 BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
00374                 BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
00375                                                                                                                         gAgent.getID());
00376 
00377                 PermissionMask item_perm_mask = 0;
00378                 if (copy) item_perm_mask |= PERM_COPY;
00379                 if (mod)  item_perm_mask |= PERM_MODIFY;
00380                 if (xfer) item_perm_mask |= PERM_TRANSFER;
00381                 
00382                 //PermissionMask filter_perm_mask = getFilterPermMask();  Commented out due to no-copy texture loss.
00383                 PermissionMask filter_perm_mask = mImmediateFilterPermMask;
00384                 if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
00385                 {
00386                         if (drop)
00387                         {
00388                                 setImageID( item->getAssetUUID() );
00389                                 commitIfImmediateSet();
00390                         }
00391 
00392                         *accept = ACCEPT_YES_SINGLE;
00393                 }
00394                 else
00395                 {
00396                         *accept = ACCEPT_NO;
00397                 }
00398         }
00399         else
00400         {
00401                 *accept = ACCEPT_NO;
00402         }
00403 
00404         handled = TRUE;
00405         lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFloaterTexturePicker " << getName() << llendl;
00406 
00407         return handled;
00408 }
00409 
00410 BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
00411 {
00412         LLFolderView* root_folder = mInventoryPanel->getRootFolder();
00413 
00414         if (root_folder && mSearchEdit)
00415         {
00416                 if (mSearchEdit->hasFocus() 
00417                         && (key == KEY_RETURN || key == KEY_DOWN) 
00418                         && mask == MASK_NONE)
00419                 {
00420                         if (!root_folder->getCurSelectedItem())
00421                         {
00422                                 LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
00423                                 if (itemp)
00424                                 {
00425                                         root_folder->setSelection(itemp, FALSE, FALSE);
00426                                 }
00427                         }
00428                         root_folder->scrollToShowSelection();
00429                         
00430                         // move focus to inventory proper
00431                         root_folder->setFocus(TRUE);
00432                         
00433                         // treat this as a user selection of the first filtered result
00434                         commitIfImmediateSet();
00435                         
00436                         return TRUE;
00437                 }
00438                 
00439                 if (root_folder->hasFocus() && key == KEY_UP)
00440                 {
00441                         mSearchEdit->focusFirstItem(TRUE);
00442                 }
00443         }
00444 
00445         return LLFloater::handleKeyHere(key, mask);
00446 }
00447 
00448 // virtual
00449 void LLFloaterTexturePicker::onClose(bool app_quitting)
00450 {
00451         if (mOwner)
00452         {
00453                 mOwner->onFloaterClose();
00454         }
00455         stopUsingPipette();
00456         destroy();
00457 }
00458 
00459 // virtual
00460 BOOL LLFloaterTexturePicker::postBuild()
00461 {
00462         LLFloater::postBuild();
00463 
00464         if (!mLabel.empty())
00465         {
00466                 std::string pick = getString("pick title");
00467         
00468                 setTitle(pick + mLabel);
00469         }
00470 
00471         return TRUE;
00472 }
00473 
00474 // virtual
00475 void LLFloaterTexturePicker::draw()
00476 {
00477         if (mOwner)
00478         {
00479                 // draw cone of context pointing back to texture swatch 
00480                 LLRect owner_rect;
00481                 mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect, this);
00482                 LLRect local_rect = getLocalRect();
00483                 if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
00484                 {
00485                         LLGLSNoTexture no_texture;
00486                         LLGLEnable(GL_CULL_FACE);
00487                         gGL.begin(LLVertexBuffer::QUADS);
00488                         {
00489                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00490                                 gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
00491                                 gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
00492                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00493                                 gGL.vertex2i(local_rect.mRight, local_rect.mTop);
00494                                 gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
00495 
00496                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00497                                 gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
00498                                 gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
00499                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00500                                 gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
00501                                 gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
00502 
00503                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00504                                 gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
00505                                 gGL.vertex2i(local_rect.mRight, local_rect.mTop);
00506                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00507                                 gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
00508                                 gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
00509 
00510 
00511                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
00512                                 gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
00513                                 gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
00514                                 gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
00515                                 gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
00516                                 gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
00517                         }
00518                         gGL.end();
00519                 }
00520         }
00521 
00522         if (gFocusMgr.childHasMouseCapture(getDragHandle()))
00523         {
00524                 mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
00525         }
00526         else
00527         {
00528                 mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
00529         }
00530 
00531         updateImageStats();
00532 
00533         // if we're inactive, gray out "apply immediate" checkbox
00534         childSetEnabled("show_folders_check", mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
00535         childSetEnabled("Select", mActive);
00536         childSetEnabled("Pipette", mActive);
00537         childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
00538 
00539         //RN: reset search bar to reflect actual search query (all caps, for example)
00540         mSearchEdit->setText(mInventoryPanel->getFilterSubString());
00541 
00542         //BOOL allow_copy = FALSE;
00543         if( mOwner ) 
00544         {
00545                 mTexturep = NULL;
00546                 if(mImageAssetID.notNull())
00547                 {
00548                         mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
00549                         mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
00550                 }
00551 
00552                 if (mTentativeLabel)
00553                 {
00554                         mTentativeLabel->setVisible( FALSE  );
00555                 }
00556 
00557                 childSetEnabled("Default",  mImageAssetID != mOwner->getDefaultImageAssetID());
00558                 childSetEnabled("Blank",   mImageAssetID != mWhiteImageAssetID );
00559                 childSetEnabled("None", mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );
00560 
00561                 LLFloater::draw();
00562 
00563                 if( isMinimized() )
00564                 {
00565                         return;
00566                 }
00567 
00568                 // Border
00569                 LLRect border( BORDER_PAD, 
00570                                 getRect().getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD, 
00571                                 ((TEX_PICKER_MIN_WIDTH / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD,
00572                                 BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - TEX_PICKER_MIN_HEIGHT));
00573                 gl_rect_2d( border, LLColor4::black, FALSE );
00574 
00575 
00576                 // Interior
00577                 LLRect interior = border;
00578                 interior.stretch( -1 ); 
00579 
00580                 if( mTexturep )
00581                 {
00582                         if( mTexturep->getComponents() == 4 )
00583                         {
00584                                 gl_rect_2d_checkerboard( interior );
00585                         }
00586 
00587                         gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep );
00588 
00589                         // Pump the priority
00590                         mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
00591 
00592                         // Draw Tentative Label over the image
00593                         if( mOwner->getTentative() && !mIsDirty )
00594                         {
00595                                 mTentativeLabel->setVisible( TRUE );
00596                                 drawChild(mTentativeLabel);
00597                         }
00598                 }
00599                 else
00600                 {
00601                         gl_rect_2d( interior, LLColor4::grey, TRUE );
00602 
00603                         // Draw X
00604                         gl_draw_x(interior, LLColor4::black );
00605                 }
00606         }
00607 }
00608 
00609 // static
00610 /*
00611 void LLFloaterTexturePicker::onSaveAnotherCopyDialog( S32 option, void* userdata )
00612 {
00613         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00614         if( 0 == option )
00615         {
00616                 self->copyToInventoryFinal();
00617         }
00618 }
00619 */
00620 
00621 const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only)
00622 {
00623         LLViewerInventoryCategory::cat_array_t cats;
00624         LLViewerInventoryItem::item_array_t items;
00625         LLAssetIDMatches asset_id_matches(asset_id);
00626         gInventory.collectDescendentsIf(LLUUID::null,
00627                                                         cats,
00628                                                         items,
00629                                                         LLInventoryModel::INCLUDE_TRASH,
00630                                                         asset_id_matches);
00631 
00632         if (items.count())
00633         {
00634                 // search for copyable version first
00635                 for (S32 i = 0; i < items.count(); i++)
00636                 {
00637                         LLInventoryItem* itemp = items[i];
00638                         LLPermissions item_permissions = itemp->getPermissions();
00639                         if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
00640                         {
00641                                 return itemp->getUUID();
00642                         }
00643                 }
00644                 // otherwise just return first instance, unless copyable requested
00645                 if (copyable_only)
00646                 {
00647                         return LLUUID::null;
00648                 }
00649                 else
00650                 {
00651                         return items[0]->getUUID();
00652                 }
00653         }
00654 
00655         return LLUUID::null;
00656 }
00657 
00658 PermissionMask LLFloaterTexturePicker::getFilterPermMask()
00659 {
00660         bool apply_immediate = childGetValue("apply_immediate_check").asBoolean();
00661         return apply_immediate ? mImmediateFilterPermMask : mNonImmediateFilterPermMask;
00662 }
00663 
00664 void LLFloaterTexturePicker::commitIfImmediateSet()
00665 {
00666         bool apply_immediate = childGetValue("apply_immediate_check").asBoolean();
00667         if (!mNoCopyTextureSelected && apply_immediate && mOwner)
00668         {
00669                 mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
00670         }
00671 }
00672 
00673 // static
00674 void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
00675 {
00676         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00677         if (self->mOwner)
00678         {
00679                 self->setImageID( self->mOwner->getDefaultImageAssetID() );
00680         }
00681         self->commitIfImmediateSet();
00682 }
00683 
00684 // static
00685 void LLFloaterTexturePicker::onBtnWhite(void* userdata)
00686 {
00687         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00688         self->setImageID( self->mWhiteImageAssetID );
00689         self->commitIfImmediateSet();
00690 }
00691 
00692 
00693 // static
00694 void LLFloaterTexturePicker::onBtnNone(void* userdata)
00695 {
00696         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00697         self->setImageID( LLUUID::null );
00698         self->commitIfImmediateSet();
00699 }
00700 
00701 /*
00702 // static
00703 void LLFloaterTexturePicker::onBtnRevert(void* userdata)
00704 {
00705         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00706         self->setImageID( self->mOriginalImageAssetID );
00707         // TODO: Change this to tell the owner to cancel.  It needs to be
00708         // smart enough to restore multi-texture selections.
00709         self->mOwner->onFloaterCommit();
00710         self->mIsDirty = FALSE;
00711 }*/
00712 
00713 // static
00714 void LLFloaterTexturePicker::onBtnCancel(void* userdata)
00715 {
00716         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00717         self->setImageID( self->mOriginalImageAssetID );
00718         if (self->mOwner)
00719         {
00720                 self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
00721         }
00722         self->mIsDirty = FALSE;
00723         self->close();
00724 }
00725 
00726 // static
00727 void LLFloaterTexturePicker::onBtnSelect(void* userdata)
00728 {
00729         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00730         if (self->mOwner)
00731         {
00732                 self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT);
00733         }
00734         self->close();
00735 }
00736 
00737 // static
00738 void LLFloaterTexturePicker::onBtnPipette( void* userdata )
00739 {
00740         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00741 
00742         if ( self)
00743         {
00744                 BOOL pipette_active = self->childGetValue("Pipette").asBoolean();
00745                 pipette_active = !pipette_active;
00746                 if (pipette_active)
00747                 {
00748                         LLToolPipette::getInstance()->setSelectCallback(onTextureSelect, self);
00749                         LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
00750                 }
00751                 else
00752                 {
00753                         LLToolMgr::getInstance()->clearTransientTool();
00754                 }
00755         }
00756 
00757 }
00758 
00759 // static 
00760 void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
00761 {
00762         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
00763         if (items.size())
00764         {
00765                 LLFolderViewItem* first_item = items.front();
00766                 LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
00767                 self->mNoCopyTextureSelected = FALSE;
00768                 if (itemp)
00769                 {
00770                         if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
00771                         {
00772                                 self->mNoCopyTextureSelected = TRUE;
00773                         }
00774                         self->mImageAssetID = itemp->getAssetUUID();
00775                         self->mIsDirty = TRUE;
00776                         if (user_action)
00777                         {
00778                                 // only commit intentional selections, not implicit ones
00779                                 self->commitIfImmediateSet();
00780                         }
00781                 }
00782         }
00783 }
00784 
00785 // static
00786 void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)
00787 {
00788         LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
00789         LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
00790 
00791         if (check_box->get())
00792         {
00793                 picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00794         }
00795         else
00796         {
00797                 picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
00798         }
00799 }
00800 
00801 // static
00802 void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
00803 {
00804         LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
00805 
00806         LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
00807         gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get());
00808 
00809         picker->updateFilterPermMask();
00810         picker->commitIfImmediateSet();
00811 }
00812 
00813 void LLFloaterTexturePicker::updateFilterPermMask()
00814 {
00815         //mInventoryPanel->setFilterPermMask( getFilterPermMask() );  Commented out due to no-copy texture loss.
00816 }
00817 
00818 void LLFloaterTexturePicker::onSearchEdit(const LLString& search_string, void* user_data )
00819 {
00820         LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
00821 
00822         std::string upper_case_search_string = search_string;
00823         LLString::toUpper(upper_case_search_string);
00824 
00825         if (upper_case_search_string.empty())
00826         {
00827                 if (picker->mInventoryPanel->getFilterSubString().empty())
00828                 {
00829                         // current filter and new filter empty, do nothing
00830                         return;
00831                 }
00832 
00833                 picker->mSavedFolderState.setApply(TRUE);
00834                 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
00835                 // add folder with current item to list of previously opened folders
00836                 LLOpenFoldersWithSelection opener;
00837                 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
00838                 picker->mInventoryPanel->getRootFolder()->scrollToShowSelection();
00839 
00840         }
00841         else if (picker->mInventoryPanel->getFilterSubString().empty())
00842         {
00843                 // first letter in search term, save existing folder open state
00844                 if (!picker->mInventoryPanel->getRootFolder()->isFilterModified())
00845                 {
00846                         picker->mSavedFolderState.setApply(FALSE);
00847                         picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
00848                 }
00849         }
00850 
00851         picker->mInventoryPanel->setFilterSubString(upper_case_search_string);
00852 }
00853 
00854 //static 
00855 void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te, void *data )
00856 {
00857         LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
00858 
00859         LLUUID inventory_item_id = self->findItemID(te.getID(), TRUE);
00860         if (self && inventory_item_id.notNull())
00861         {
00862                 LLToolPipette::getInstance()->setResult(TRUE, "");
00863                 self->setImageID(te.getID());
00864 
00865                 self->mNoCopyTextureSelected = FALSE;
00866                 LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
00867 
00868                 if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
00869                 {
00870                         // no copy texture
00871                         self->mNoCopyTextureSelected = TRUE;
00872                 }
00873                 
00874                 self->commitIfImmediateSet();
00875         }
00876         else
00877         {
00878                 LLToolPipette::getInstance()->setResult(FALSE, "You do not have a copy this \nof texture in your inventory");
00879         }
00880 }
00881 
00883 // LLTextureCtrl
00884 
00885 static LLRegisterWidget<LLTextureCtrl> r("texture_picker");
00886 
00887 LLTextureCtrl::LLTextureCtrl(
00888         const std::string& name, 
00889         const LLRect &rect, 
00890         const std::string& label,
00891         const LLUUID &image_id, 
00892         const LLUUID &default_image_id, 
00893         const std::string& default_image_name )
00894         :       
00895         LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
00896         mDragCallback(NULL),
00897         mDropCallback(NULL),
00898         mOnCancelCallback(NULL),
00899         mOnSelectCallback(NULL),
00900         mBorderColor( gColors.getColor("DefaultHighlightLight") ),
00901         mImageAssetID( image_id ),
00902         mDefaultImageAssetID( default_image_id ),
00903         mDefaultImageName( default_image_name ),
00904         mLabel( label ),
00905         mAllowNoTexture( FALSE ),
00906         mImmediateFilterPermMask( PERM_NONE ),
00907         mNonImmediateFilterPermMask( PERM_NONE ),
00908         mCanApplyImmediately( FALSE ),
00909         mNeedsRawImageData( FALSE ),
00910         mValid( TRUE ),
00911         mDirty( FALSE )
00912 {
00913         mCaption = new LLTextBox( label, 
00914                 LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
00915                 label,
00916                 LLFontGL::sSansSerifSmall );
00917         mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
00918         addChild( mCaption );
00919 
00920         S32 image_top = getRect().getHeight();
00921         S32 image_bottom = BTN_HEIGHT_SMALL;
00922         S32 image_middle = (image_top + image_bottom) / 2;
00923         S32 line_height = llround(LLFontGL::sSansSerifSmall->getLineHeight());
00924 
00925         mTentativeLabel = new LLTextBox( "Multiple", 
00926                 LLRect( 
00927                         0, image_middle + line_height / 2,
00928                         getRect().getWidth(), image_middle - line_height / 2 ),
00929                 "Multiple",
00930                 LLFontGL::sSansSerifSmall );
00931         mTentativeLabel->setHAlign( LLFontGL::HCENTER );
00932         mTentativeLabel->setFollowsAll();
00933         addChild( mTentativeLabel );
00934 
00935         LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
00936         border_rect.mBottom += BTN_HEIGHT_SMALL;
00937         mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN);
00938         mBorder->setFollowsAll();
00939         addChild(mBorder);
00940 
00941         setEnabled(TRUE); // for the tooltip
00942 }
00943 
00944 
00945 LLTextureCtrl::~LLTextureCtrl()
00946 {
00947         closeFloater();
00948 }
00949 
00950 // virtual
00951 LLXMLNodePtr LLTextureCtrl::getXML(bool save_children) const
00952 {
00953         LLXMLNodePtr node = LLUICtrl::getXML();
00954 
00955         node->createChild("label", TRUE)->setStringValue(getLabel());
00956 
00957         node->createChild("default_image_name", TRUE)->setStringValue(getDefaultImageName());
00958 
00959         node->createChild("allow_no_texture", TRUE)->setBoolValue(mAllowNoTexture);
00960 
00961         node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately );
00962 
00963         return node;
00964 }
00965 
00966 LLView* LLTextureCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
00967 {
00968         LLString name("texture_picker");
00969         node->getAttributeString("name", name);
00970 
00971         LLRect rect;
00972         createRect(node, rect, parent);
00973 
00974         LLString label;
00975         node->getAttributeString("label", label);
00976 
00977         LLString image_id("");
00978         node->getAttributeString("image", image_id);
00979 
00980         LLString default_image_id("");
00981         node->getAttributeString("default_image", default_image_id);
00982 
00983         LLString default_image_name("Default");
00984         node->getAttributeString("default_image_name", default_image_name);
00985 
00986         BOOL allow_no_texture = FALSE;
00987         node->getAttributeBOOL("allow_no_texture", allow_no_texture);
00988 
00989         BOOL can_apply_immediately = FALSE;
00990         node->getAttributeBOOL("can_apply_immediately", can_apply_immediately);
00991 
00992         if (label.empty())
00993         {
00994                 label.assign(node->getValue());
00995         }
00996 
00997         LLTextureCtrl* texture_picker = new LLTextureCtrl(
00998                                                                         name, 
00999                                                                         rect,
01000                                                                         label,
01001                                                                         LLUUID(image_id),
01002                                                                         LLUUID(default_image_id), 
01003                                                                         default_image_name );
01004         texture_picker->setAllowNoTexture(allow_no_texture);
01005         texture_picker->setCanApplyImmediately(can_apply_immediately);
01006 
01007         texture_picker->initFromXML(node, parent);
01008 
01009         return texture_picker;
01010 }
01011 
01012 void LLTextureCtrl::setCaption(const LLString& caption)
01013 {
01014         mCaption->setText( caption );
01015 }
01016 
01017 void LLTextureCtrl::setCanApplyImmediately(BOOL b)
01018 {
01019         mCanApplyImmediately = b; 
01020         LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01021         if( floaterp )
01022         {
01023                 floaterp->setCanApplyImmediately(b);
01024         }
01025 }
01026 
01027 void LLTextureCtrl::setVisible( BOOL visible ) 
01028 {
01029         if( !visible )
01030         {
01031                 closeFloater();
01032         }
01033         LLUICtrl::setVisible( visible );
01034 }
01035 
01036 void LLTextureCtrl::setEnabled( BOOL enabled )
01037 {
01038         LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01039         if( enabled )
01040         {
01041                 LLString tooltip;
01042                 if (floaterp) tooltip = floaterp->getUIString("choose_picture");
01043                 setToolTip( tooltip );
01044         }
01045         else
01046         {
01047                 setToolTip( LLString() );
01048                 // *TODO: would be better to keep floater open and show
01049                 // disabled state.
01050                 closeFloater();
01051         }
01052 
01053         if( floaterp )
01054         {
01055                 floaterp->setActive(enabled);
01056         }
01057 
01058         mCaption->setEnabled( enabled );
01059 
01060         LLView::setEnabled( enabled );
01061 }
01062 
01063 void LLTextureCtrl::setValid(BOOL valid )
01064 {
01065         mValid = valid;
01066         if (!valid)
01067         {
01068                 LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01069                 if (pickerp)
01070                 {
01071                         pickerp->setActive(FALSE);
01072                 }
01073         }
01074 }
01075 
01076 // virtual 
01077 BOOL    LLTextureCtrl::isDirty() const          
01078 { 
01079         return mDirty;  
01080 }
01081 
01082 // virtual 
01083 void    LLTextureCtrl::resetDirty()
01084 { 
01085         mDirty = FALSE; 
01086 }
01087 
01088 
01089 // virtual
01090 void LLTextureCtrl::clear()
01091 {
01092         setImageAssetID(LLUUID::null);
01093 }
01094 
01095 void LLTextureCtrl::setLabel(const LLString& label)
01096 {
01097         mLabel = label;
01098         mCaption->setText(label);
01099 }
01100 
01101 void LLTextureCtrl::showPicker(BOOL take_focus)
01102 {
01103         LLFloater* floaterp = mFloaterHandle.get();
01104 
01105         // Show the dialog
01106         if( floaterp )
01107         {
01108                 floaterp->open( );              /* Flawfinder: ignore */
01109         }
01110         else
01111         {
01112                 if( !mLastFloaterLeftTop.mX && !mLastFloaterLeftTop.mY )
01113                 {
01114                         gFloaterView->getNewFloaterPosition(&mLastFloaterLeftTop.mX, &mLastFloaterLeftTop.mY);
01115                 }
01116                 LLRect rect = gSavedSettings.getRect("TexturePickerRect");
01117                 rect.translate( mLastFloaterLeftTop.mX - rect.mLeft, mLastFloaterLeftTop.mY - rect.mTop );
01118 
01119                 floaterp = new LLFloaterTexturePicker(
01120                         this,
01121                         rect,
01122                         mLabel,
01123                         mImmediateFilterPermMask,
01124                         mNonImmediateFilterPermMask,
01125                         mCanApplyImmediately);
01126                 mFloaterHandle = floaterp->getHandle();
01127 
01128                 gFloaterView->getParentFloater(this)->addDependentFloater(floaterp);
01129                 floaterp->open();               /* Flawfinder: ignore */
01130         }
01131 
01132         if (take_focus)
01133         {
01134                 floaterp->setFocus(TRUE);
01135         }
01136 }
01137 
01138 
01139 void LLTextureCtrl::closeFloater()
01140 {
01141         LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01142         if( floaterp )
01143         {
01144                 floaterp->setOwner(NULL);
01145                 floaterp->close();
01146         }
01147 }
01148 
01149 // Allow us to download textures quickly when floater is shown
01150 class LLTextureFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
01151 {
01152 public:
01153         virtual void done()
01154         {
01155                 // We need to find textures in all folders, so get the main
01156                 // background download going.
01157                 gInventory.startBackgroundFetch();
01158                 gInventory.removeObserver(this);
01159                 delete this;
01160         }
01161 };
01162 
01163 BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask)
01164 {
01165         getWindow()->setCursor(UI_CURSOR_HAND);
01166         return TRUE;
01167 }
01168 
01169 
01170 BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
01171 {
01172         BOOL handled = LLUICtrl::handleMouseDown( x, y , mask );
01173         if( handled )
01174         {
01175                 showPicker(FALSE);
01176 
01177                 //grab textures first...
01178                 gInventory.startBackgroundFetch(gInventory.findCategoryUUIDForType(LLAssetType::AT_TEXTURE));
01179                 //...then start full inventory fetch.
01180                 gInventory.startBackgroundFetch();
01181         }
01182         return handled;
01183 }
01184 
01185 void LLTextureCtrl::onFloaterClose()
01186 {
01187         LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01188 
01189         if (floaterp)
01190         {
01191                 floaterp->setOwner(NULL);
01192                 mLastFloaterLeftTop.set( floaterp->getRect().mLeft, floaterp->getRect().mTop );
01193         }
01194 
01195         mFloaterHandle.markDead();
01196 }
01197 
01198 void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
01199 {
01200         LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01201 
01202         if( floaterp && getEnabled())
01203         {
01204                 mDirty = (op != TEXTURE_CANCEL);
01205                 if( floaterp->isDirty() )
01206                 {
01207                         setTentative( FALSE );
01208                         mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
01209                         lldebugs << "mImageItemID: " << mImageItemID << llendl;
01210                         mImageAssetID = floaterp->getAssetID();
01211                         lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
01212                         if (op == TEXTURE_SELECT && mOnSelectCallback)
01213                         {
01214                                 mOnSelectCallback(this, mCallbackUserData);
01215                         }
01216                         else if (op == TEXTURE_CANCEL && mOnCancelCallback)
01217                         {
01218                                 mOnCancelCallback(this, mCallbackUserData);
01219                         }
01220                         else
01221                         {
01222                                 onCommit();
01223                         }
01224                 }
01225         }
01226 }
01227 
01228 void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
01229 {
01230         if( mImageAssetID != asset_id )
01231         {
01232                 mImageItemID.setNull();
01233                 mImageAssetID = asset_id;
01234                 LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
01235                 if( floaterp && getEnabled() )
01236                 {
01237                         floaterp->setImageID( asset_id );
01238                         floaterp->setDirty( FALSE );
01239                 }
01240         }
01241 }
01242 
01243 BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
01244                                           BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
01245                                           EAcceptance *accept,
01246                                           LLString& tooltip_msg)
01247 {
01248         BOOL handled = FALSE;
01249 
01250         // this downcast may be invalid - but if the second test below
01251         // returns true, then the cast was valid, and we can perform
01252         // the third test without problems.
01253         LLInventoryItem* item = (LLInventoryItem*)cargo_data; 
01254         if (getEnabled() && (cargo_type == DAD_TEXTURE) && allowDrop(item))
01255         {
01256                 if (drop)
01257                 {
01258                         if(doDrop(item))
01259                         {
01260                                 // This removes the 'Multiple' overlay, since
01261                                 // there is now only one texture selected.
01262                                 setTentative( FALSE ); 
01263                                 onCommit();
01264                         }
01265                 }
01266 
01267                 *accept = ACCEPT_YES_SINGLE;
01268         }
01269         else
01270         {
01271                 *accept = ACCEPT_NO;
01272         }
01273 
01274         handled = TRUE;
01275         lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLTextureCtrl " << getName() << llendl;
01276 
01277         return handled;
01278 }
01279 
01280 void LLTextureCtrl::draw()
01281 {
01282         mBorder->setKeyboardFocusHighlight(hasFocus());
01283 
01284         if (mImageAssetID.isNull() || !mValid)
01285         {
01286                 mTexturep = NULL;
01287         }
01288         else
01289         {
01290                 mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
01291                 mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
01292         }
01293         
01294         // Border
01295         LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
01296         gl_rect_2d( border, mBorderColor, FALSE );
01297 
01298         // Interior
01299         LLRect interior = border;
01300         interior.stretch( -1 ); 
01301 
01302         if( mTexturep )
01303         {
01304                 if( mTexturep->getComponents() == 4 )
01305                 {
01306                         gl_rect_2d_checkerboard( interior );
01307                 }
01308                 
01309                 gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep);
01310                 mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
01311         }
01312         else
01313         {
01314                 gl_rect_2d( interior, LLColor4::grey, TRUE );
01315 
01316                 // Draw X
01317                 gl_draw_x( interior, LLColor4::black );
01318         }
01319 
01320         mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() );
01321 
01322         LLUICtrl::draw();
01323 }
01324 
01325 BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
01326 {
01327         BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
01328         BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
01329         BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
01330                                                                                                                 gAgent.getID());
01331 
01332         PermissionMask item_perm_mask = 0;
01333         if (copy) item_perm_mask |= PERM_COPY;
01334         if (mod)  item_perm_mask |= PERM_MODIFY;
01335         if (xfer) item_perm_mask |= PERM_TRANSFER;
01336         
01337 //      PermissionMask filter_perm_mask = mCanApplyImmediately ?                        commented out due to no-copy texture loss.
01338 //                      mImmediateFilterPermMask : mNonImmediateFilterPermMask;
01339         PermissionMask filter_perm_mask = mImmediateFilterPermMask;
01340         if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
01341         {
01342                 if(mDragCallback)
01343                 {
01344                         return mDragCallback(this, item, mCallbackUserData);
01345                 }
01346                 else
01347                 {
01348                         return TRUE;
01349                 }
01350         }
01351         else
01352         {
01353                 return FALSE;
01354         }
01355 }
01356 
01357 BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
01358 {
01359         // call the callback if it exists.
01360         if(mDropCallback)
01361         {
01362                 // if it returns TRUE, we return TRUE, and therefore the
01363                 // commit is called above.
01364                 return mDropCallback(this, item, mCallbackUserData);
01365         }
01366 
01367         // no callback installed, so just set the image ids and carry on.
01368         setImageAssetID( item->getAssetUUID() );
01369         mImageItemID = item->getUUID();
01370         return TRUE;
01371 }
01372 
01373 BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
01374 {
01375         if( ' ' == uni_char )
01376         {
01377                 showPicker(TRUE);
01378                 return TRUE;
01379         }
01380         return LLUICtrl::handleUnicodeCharHere(uni_char);
01381 }
01382 
01383 void LLTextureCtrl::setValue( const LLSD& value )
01384 {
01385         setImageAssetID(value.asUUID());
01386 }
01387 
01388 LLSD LLTextureCtrl::getValue() const
01389 {
01390         return LLSD(getImageAssetID());
01391 }
01392 
01393 
01395 // LLToolTexEyedropper
01396 
01397 class LLToolTexEyedropper : public LLTool 
01398 {
01399 public:
01400         LLToolTexEyedropper( void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ), void* userdata );
01401         virtual ~LLToolTexEyedropper();
01402         virtual BOOL            handleMouseDown(S32 x, S32 y, MASK mask);
01403         virtual BOOL            handleHover(S32 x, S32 y, MASK mask);
01404 
01405 protected:
01406         void                            (*mCallback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata );
01407         void*                           mCallbackUserData;
01408 };
01409 
01410 
01411 LLToolTexEyedropper::LLToolTexEyedropper( 
01412         void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ),
01413         void* userdata )
01414         : LLTool("texeyedropper"),
01415           mCallback( callback ),
01416           mCallbackUserData( userdata )
01417 {
01418 }
01419 
01420 LLToolTexEyedropper::~LLToolTexEyedropper()
01421 {
01422 }
01423 
01424 
01425 BOOL LLToolTexEyedropper::handleMouseDown(S32 x, S32 y, MASK mask)
01426 {
01427         LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
01428         if (hit_obj && 
01429                 !hit_obj->isAvatar())
01430         {
01431                 if( (0 <= gLastHitObjectFace) && (gLastHitObjectFace < hit_obj->getNumTEs()) )
01432                 {
01433                         LLViewerImage* image = hit_obj->getTEImage( gLastHitObjectFace );
01434                         if( image )
01435                         {
01436                                 if( mCallback )
01437                                 {
01438                                         mCallback( hit_obj->getID(), image->getID(), mCallbackUserData );
01439                                 }
01440                         }
01441                 }
01442         }
01443         return TRUE;
01444 }
01445 
01446 BOOL LLToolTexEyedropper::handleHover(S32 x, S32 y, MASK mask)
01447 {
01448         lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolTexEyedropper" << llendl;
01449         gViewerWindow->getWindow()->setCursor(UI_CURSOR_CROSS);  // TODO: better cursor
01450         return TRUE;
01451 }
01452 
01453 
01454 

Generated on Fri May 16 08:34:04 2008 for SecondLife by  doxygen 1.5.5