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
00098
00099
00100
00102
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
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
00125 virtual void onClose(bool app_quitting);
00126 virtual BOOL postBuild();
00127
00128
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
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;
00166
00167 LLUUID mWhiteImageAssetID;
00168 LLUUID mSpecialCurrentImageAssetID;
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
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
00251 mInventoryPanel->getRootFolder()->getFilter()->markDefault();
00252
00253
00254
00255
00256
00257
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
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
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
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
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
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
00431 root_folder->setFocus(TRUE);
00432
00433
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
00449 void LLFloaterTexturePicker::onClose(bool app_quitting)
00450 {
00451 if (mOwner)
00452 {
00453 mOwner->onFloaterClose();
00454 }
00455 stopUsingPipette();
00456 destroy();
00457 }
00458
00459
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
00475 void LLFloaterTexturePicker::draw()
00476 {
00477 if (mOwner)
00478 {
00479
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
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
00540 mSearchEdit->setText(mInventoryPanel->getFilterSubString());
00541
00542
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
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
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
00590 mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
00591
00592
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
00604 gl_draw_x(interior, LLColor4::black );
00605 }
00606 }
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
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
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
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
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
00685 void LLFloaterTexturePicker::onBtnWhite(void* userdata)
00686 {
00687 LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00688 self->setImageID( self->mWhiteImageAssetID );
00689 self->commitIfImmediateSet();
00690 }
00691
00692
00693
00694 void LLFloaterTexturePicker::onBtnNone(void* userdata)
00695 {
00696 LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00697 self->setImageID( LLUUID::null );
00698 self->commitIfImmediateSet();
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
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
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
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
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
00779 self->commitIfImmediateSet();
00780 }
00781 }
00782 }
00783 }
00784
00785
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
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
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
00830 return;
00831 }
00832
00833 picker->mSavedFolderState.setApply(TRUE);
00834 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
00835
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
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
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
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
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);
00942 }
00943
00944
00945 LLTextureCtrl::~LLTextureCtrl()
00946 {
00947 closeFloater();
00948 }
00949
00950
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
01049
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
01077 BOOL LLTextureCtrl::isDirty() const
01078 {
01079 return mDirty;
01080 }
01081
01082
01083 void LLTextureCtrl::resetDirty()
01084 {
01085 mDirty = FALSE;
01086 }
01087
01088
01089
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
01106 if( floaterp )
01107 {
01108 floaterp->open( );
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();
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
01150 class LLTextureFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
01151 {
01152 public:
01153 virtual void done()
01154 {
01155
01156
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
01178 gInventory.startBackgroundFetch(gInventory.findCategoryUUIDForType(LLAssetType::AT_TEXTURE));
01179
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
01251
01252
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
01261
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
01295 LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
01296 gl_rect_2d( border, mBorderColor, FALSE );
01297
01298
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
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
01338
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
01360 if(mDropCallback)
01361 {
01362
01363
01364 return mDropCallback(this, item, mCallbackUserData);
01365 }
01366
01367
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
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);
01450 return TRUE;
01451 }
01452
01453
01454