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
00097
00098
00099
00101
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
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
00124 virtual void onClose(bool app_quitting);
00125 virtual BOOL postBuild();
00126
00127
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
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;
00165
00166 LLUUID mWhiteImageAssetID;
00167 LLUUID mSpecialCurrentImageAssetID;
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
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
00250 mInventoryPanel->getRootFolder()->getFilter()->markDefault();
00251
00252
00253
00254
00255
00256
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
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
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
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
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
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
00436 root_folder->setFocus(TRUE);
00437
00438
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
00454 void LLFloaterTexturePicker::onClose(bool app_quitting)
00455 {
00456 if (mOwner)
00457 {
00458 mOwner->onFloaterClose();
00459 }
00460 stopUsingPipette();
00461 destroy();
00462 }
00463
00464
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
00480 void LLFloaterTexturePicker::draw()
00481 {
00482 if (mOwner)
00483 {
00484
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
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
00545 mSearchEdit->setText(mInventoryPanel->getFilterSubString());
00546
00547
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
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
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
00595 mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
00596
00597
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
00609 gl_draw_x(interior, LLColor4::black );
00610 }
00611 }
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
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
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
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
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
00690 void LLFloaterTexturePicker::onBtnWhite(void* userdata)
00691 {
00692 LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00693 self->setImageID( self->mWhiteImageAssetID );
00694 self->commitIfImmediateSet();
00695 }
00696
00697
00698
00699 void LLFloaterTexturePicker::onBtnNone(void* userdata)
00700 {
00701 LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
00702 self->setImageID( LLUUID::null );
00703 self->commitIfImmediateSet();
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
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
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
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
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
00784 self->commitIfImmediateSet();
00785 }
00786 }
00787 }
00788 }
00789
00790
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
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
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
00835 return;
00836 }
00837
00838 picker->mSavedFolderState.setApply(TRUE);
00839 picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
00840
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
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
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
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
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);
00944 }
00945
00946
00947 LLTextureCtrl::~LLTextureCtrl()
00948 {
00949 closeFloater();
00950 }
00951
00952
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
01048
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
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 = LLFloater::getFloaterByHandle(mFloaterHandle);
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*)LLFloater::getFloaterByHandle(mFloaterHandle);
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*)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
01251
01252
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
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 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
01297 LLRect border( 0, mRect.getHeight(), mRect.getWidth(), BTN_HEIGHT_SMALL );
01298 gl_rect_2d( border, mBorderColor, FALSE );
01299
01300
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
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
01341
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
01363 if(mDropCallback)
01364 {
01365
01366
01367 return mDropCallback(this, item, mCallbackUserData);
01368 }
01369
01370
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
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);
01453 return TRUE;
01454 }
01455
01456