lltexturectrl.cpp

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

Generated on Thu Jul 1 06:09:18 2010 for Second Life Viewer by  doxygen 1.4.7