lltexturectrl.cpp 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005
  1. /**
  2. * @file lltexturectrl.cpp
  3. * @author Richard Nelson, James Cook
  4. * @brief LLTextureCtrl class implementation including related functions
  5. *
  6. * $LicenseInfo:firstyear=2002&license=viewergpl$
  7. *
  8. * Copyright (c) 2002-2009, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "lltexturectrl.h"
  35. #include "llassetstorage.h"
  36. #include "llavatarappearancedefines.h"
  37. #include "llbutton.h"
  38. #include "llcheckboxctrl.h"
  39. #include "lldraghandle.h"
  40. #include "llgl.h"
  41. #include "llpermissions.h"
  42. #include "llradiogroup.h"
  43. #include "llrender.h"
  44. #include "llresizehandle.h"
  45. #include "llscrolllistctrl.h"
  46. #include "lltextbox.h"
  47. #include "llsaleinfo.h"
  48. #include "lltrans.h"
  49. #include "lluictrlfactory.h"
  50. #include "llagent.h"
  51. #include "llfloaterimagepreview.h"
  52. #include "llfloaterinventory.h"
  53. #include "llfolderview.h"
  54. #include "llinventorymodel.h"
  55. #include "llinventorymodelfetch.h"
  56. #include "lllocalbitmaps.h"
  57. #include "llpreviewtexture.h"
  58. //MK
  59. #include "mkrlinterface.h"
  60. //mk
  61. #include "llselectmgr.h"
  62. #include "lltool.h"
  63. #include "lltoolmgr.h"
  64. #include "lltoolpipette.h"
  65. #include "llviewercontrol.h"
  66. #include "llviewerinventory.h"
  67. #include "llviewerobject.h"
  68. #include "llviewertexturelist.h"
  69. #include "llviewerwindow.h"
  70. using namespace LLAvatarAppearanceDefines;
  71. constexpr S32 CLOSE_BTN_WIDTH = 100;
  72. constexpr S32 SMALL_BTN_WIDTH = 64;
  73. constexpr S32 TEX_PICKER_MIN_WIDTH = (HPAD + CLOSE_BTN_WIDTH + HPAD +
  74. CLOSE_BTN_WIDTH + HPAD +
  75. SMALL_BTN_WIDTH + HPAD +
  76. SMALL_BTN_WIDTH + HPAD +
  77. 30 + RESIZE_HANDLE_WIDTH * 2);
  78. constexpr S32 TEX_PICKER_MIN_HEIGHT = 290;
  79. constexpr S32 FOOTER_HEIGHT = 100;
  80. constexpr S32 BORDER_PAD = HPAD;
  81. constexpr S32 TEXTURE_INVENTORY_PADDING = 30;
  82. constexpr F32 CONTEXT_CONE_IN_ALPHA = 0.f;
  83. constexpr F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
  84. constexpr F32 CONTEXT_FADE_TIME = 0.08f;
  85. ///////////////////////////////////////////////////////////////////////////////
  86. // LLFloaterTexturePicker class
  87. ///////////////////////////////////////////////////////////////////////////////
  88. class LLFloaterTexturePicker final : public LLFloater
  89. {
  90. protected:
  91. LOG_CLASS(LLFloaterTexturePicker);
  92. public:
  93. LLFloaterTexturePicker(LLTextureCtrl* owner,
  94. const LLRect& rect,
  95. const std::string& label,
  96. PermissionMask immediate_filter_perm_mask,
  97. PermissionMask non_immediate_filter_perm_mask,
  98. bool can_apply_immediately,
  99. bool allow_local_texture,
  100. bool bake_texture_enabled,
  101. LLViewerFetchedTexture* texp);
  102. ~LLFloaterTexturePicker() override {}
  103. // LLView overrides
  104. bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
  105. EDragAndDropType cargo_type, void* cargo_data,
  106. EAcceptance* accept, std::string& tooltip) override;
  107. void draw() override;
  108. bool handleKeyHere(KEY key, MASK mask) override;
  109. // LLFloater overrides
  110. bool postBuild() override;
  111. void onClose(bool app_quitting) override;
  112. void setImageID(const LLUUID& image_asset_id);
  113. void updateImageStats();
  114. LL_INLINE const LLUUID& getAssetID() { return mImageAssetID; }
  115. const LLUUID& findItemID(const LLUUID& asset_id, bool copyable_only);
  116. void setCanApplyImmediately(bool b);
  117. void setLocalTextureEnabled(bool b);
  118. void setBakeTextureEnabled(bool enabled);
  119. LL_INLINE void setDirty(bool b) { mIsDirty = b; }
  120. LL_INLINE bool isDirty() const override { return mIsDirty; }
  121. void setActive(bool active);
  122. LL_INLINE LLTextureCtrl* getOwner() const { return mOwner; }
  123. LL_INLINE void setOwner(LLTextureCtrl* owner) { mOwner = owner; }
  124. void stopUsingPipette();
  125. PermissionMask getFilterPermMask();
  126. void updateFilterPermMask();
  127. void setImmediateFilterPermMask(PermissionMask mask);
  128. void commitIfImmediateSet();
  129. private:
  130. static void onBtnSetToDefault(void* userdata);
  131. static void onBtnSelect(void* userdata);
  132. static void onBtnCancel(void* userdata);
  133. static void onBtnPipette(void* userdata);
  134. static void onBtnBlank(void* userdata);
  135. static void onBtnInvisible(void* userdata);
  136. static void onBtnNone(void* userdata);
  137. static void onBtnClear(void* userdata);
  138. static void onBtnAdd(void* userdata);
  139. static void onBtnRemove(void* userdata);
  140. static void onBtnUpload(void* userdata);
  141. static void onSelectionChange(LLFolderView* folderp, bool user_action,
  142. void* userdata);
  143. static void onApplyImmediateCheck(LLUICtrl* ctrlp, void* userdata);
  144. static void onBakeTextureSelect(LLUICtrl* ctrlp, void* userdata);
  145. static void onSearchEdit(const std::string& search_string, void* userdata);
  146. static void onTextureSelect(const LLTextureEntry& te, void* userdata);
  147. static void onModeSelect(LLUICtrl*, void* userdata);
  148. static void onLocalScrollCommit(LLUICtrl*, void* userdata);
  149. static void onDragHandleClicked(S32 x, S32 y, void* userdata);
  150. protected:
  151. LLPointer<LLViewerFetchedTexture> mTexturep;
  152. // What to show if currently selected texture is null:
  153. LLPointer<LLViewerFetchedTexture> mFallbackImagep;
  154. LLTextureCtrl* mOwner;
  155. LLTextBox* mTentativeLabel;
  156. LLTextBox* mResolutionLabel;
  157. LLButton* mPipetteButton;
  158. LLButton* mSelectButton;
  159. LLButton* mDefaultButton;
  160. LLButton* mNoneButton;
  161. LLButton* mBlankButton;
  162. LLButton* mInvisibleButton;
  163. LLButton* mAddButton;
  164. LLButton* mRemoveButton;
  165. LLButton* mUploadButton;
  166. LLCheckBoxCtrl* mApplyImmediatelyCheck;
  167. LLComboBox* mBakeTextureCombo;
  168. LLSearchEditor* mSearchEdit;
  169. LLInventoryPanel* mInventoryPanel;
  170. LLRadioGroup* mModeSelector;
  171. LLScrollListCtrl* mLocalScrollCtrl;
  172. LLUUID mBlankImageAssetID;
  173. LLUUID mInvisibleImageAssetID;
  174. // Currently selected texture
  175. LLUUID mImageAssetID;
  176. // Used when the asset id has no corresponding texture in the user's
  177. // inventory:
  178. LLUUID mSpecialCurrentImageAssetID;
  179. LLUUID mOriginalImageAssetID;
  180. std::string mLabel;
  181. std::string mPendingName;
  182. S32 mLastBitmapsListVersion;
  183. F32 mContextConeOpacity;
  184. LLSaveFolderState mSavedFolderState;
  185. PermissionMask mImmediateFilterPermMask;
  186. PermissionMask mNonImmediateFilterPermMask;
  187. bool mIsDirty;
  188. bool mActive;
  189. bool mCanApplyImmediately;
  190. bool mNoCopyTextureSelected;
  191. bool mBakeTextureEnabled;
  192. };
  193. LLFloaterTexturePicker::LLFloaterTexturePicker(LLTextureCtrl* owner,
  194. const LLRect& rect,
  195. const std::string& label,
  196. PermissionMask immediate_filter_perm_mask,
  197. PermissionMask non_immediate_filter_perm_mask,
  198. bool can_apply_immediately,
  199. bool allow_local_texture,
  200. bool bake_texture_enabled,
  201. LLViewerFetchedTexture* texp)
  202. : LLFloater("texture picker", rect, "Pick: " + label, true,
  203. TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT),
  204. mOwner(owner),
  205. mImageAssetID(owner->getImageAssetID()),
  206. mBlankImageAssetID(owner->getBlankImageAssetID()),
  207. mInvisibleImageAssetID(gSavedSettings.getString("UIImgInvisibleUUID")),
  208. mOriginalImageAssetID(owner->getImageAssetID()),
  209. mLabel(label),
  210. mIsDirty(false),
  211. mActive(true),
  212. mImmediateFilterPermMask(immediate_filter_perm_mask),
  213. mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
  214. mNoCopyTextureSelected(false),
  215. mCanApplyImmediately(can_apply_immediately),
  216. mBakeTextureEnabled(false),
  217. mFallbackImagep(texp),
  218. mContextConeOpacity(0.f),
  219. mLastBitmapsListVersion(-1)
  220. {
  221. LLUICtrlFactory::getInstance()->buildFloater(this,
  222. "floater_texture_ctrl.xml");
  223. mTentativeLabel = getChild<LLTextBox>("Multiple");
  224. mResolutionLabel = getChild<LLTextBox>("unknown");
  225. mDefaultButton = getChild<LLButton>("Default");
  226. mDefaultButton->setClickedCallback(onBtnSetToDefault, this);
  227. mNoneButton = getChild<LLButton>("None");
  228. mNoneButton->setClickedCallback(onBtnNone, this);
  229. mBlankButton = getChild<LLButton>("Blank");
  230. mBlankButton->setClickedCallback(onBtnBlank, this);
  231. mInvisibleButton = getChild<LLButton>("Invisible");
  232. mInvisibleButton->setClickedCallback(onBtnInvisible, this);
  233. mAddButton = getChild<LLButton>("Add");
  234. mAddButton->setClickedCallback(onBtnAdd, this);
  235. mRemoveButton = getChild<LLButton>("Remove");
  236. mRemoveButton->setClickedCallback(onBtnRemove, this);
  237. mRemoveButton->setEnabled(false);
  238. mUploadButton = getChild<LLButton>("Upload");
  239. mUploadButton->setClickedCallback(onBtnUpload, this);
  240. mUploadButton->setEnabled(false);
  241. mModeSelector = getChild<LLRadioGroup>("mode_selection");
  242. mModeSelector->setCommitCallback(onModeSelect);
  243. mModeSelector->setCallbackUserData(this);
  244. mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
  245. mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit);
  246. mLocalScrollCtrl->setCallbackUserData(this);
  247. mLocalScrollCtrl->setCommitOnSelectionChange(true);
  248. mSearchEdit = getChild<LLSearchEditor>("inventory search editor");
  249. mSearchEdit->setSearchCallback(onSearchEdit, this);
  250. // Initialize before mInventoryPanel, since mApplyImmediatelyCheck is used
  251. // in getFilterPermMask() that we call to set the inventory panel filter
  252. // permission mask. HB
  253. mApplyImmediatelyCheck = getChild<LLCheckBoxCtrl>("apply_immediate_check");
  254. mApplyImmediatelyCheck->set(mCanApplyImmediately &&
  255. gSavedSettings.getBool("ApplyTextureImmediately"));
  256. mApplyImmediatelyCheck->setEnabled(mCanApplyImmediately);
  257. mApplyImmediatelyCheck->setCommitCallback(onApplyImmediateCheck);
  258. mApplyImmediatelyCheck->setCallbackUserData(this);
  259. mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
  260. U32 filter_types = 0x0;
  261. filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
  262. filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
  263. mInventoryPanel->setFilterTypes(filter_types);
  264. mInventoryPanel->setFilterPermMask(getFilterPermMask());
  265. mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
  266. mInventoryPanel->setSelectCallback(onSelectionChange, this);
  267. mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
  268. mInventoryPanel->setAllowMultiSelect(false);
  269. // Store this filter as the default one
  270. mInventoryPanel->getRootFolder()->getFilter()->markDefault();
  271. mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE);
  272. // Do not put keyboard focus on selected item, because the selection
  273. // callback will assume that this was user input:
  274. mInventoryPanel->setSelection(findItemID(mImageAssetID, false),
  275. TAKE_FOCUS_NO);
  276. mBakeTextureCombo = getChild<LLComboBox>("bake_texture_combo");
  277. mBakeTextureCombo->setCommitCallback(onBakeTextureSelect);
  278. mBakeTextureCombo->setCallbackUserData(this);
  279. mPipetteButton = getChild<LLButton>("Pipette");
  280. mPipetteButton->setClickedCallback(onBtnPipette, this);
  281. childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel, this);
  282. mSelectButton = getChild<LLButton>("Select");
  283. mSelectButton->setClickedCallback(onBtnSelect, this);
  284. // Update permission filter once UI is fully initialized
  285. updateFilterPermMask();
  286. setCanMinimize(false);
  287. mSavedFolderState.setApply(false);
  288. LLDragHandle* drag_handle = getDragHandle();
  289. if (drag_handle)
  290. {
  291. drag_handle->setClickedCallback(onDragHandleClicked, this);
  292. }
  293. setLocalTextureEnabled(allow_local_texture);
  294. setBakeTextureEnabled(bake_texture_enabled);
  295. }
  296. //virtual
  297. bool LLFloaterTexturePicker::postBuild()
  298. {
  299. if (!mLabel.empty())
  300. {
  301. std::string pick = getString("pick title");
  302. setTitle(pick + mLabel);
  303. }
  304. return true;
  305. }
  306. //virtual
  307. void LLFloaterTexturePicker::onClose(bool app_quitting)
  308. {
  309. if (mOwner)
  310. {
  311. mOwner->onFloaterClose();
  312. }
  313. stopUsingPipette();
  314. destroy();
  315. }
  316. //virtual
  317. void LLFloaterTexturePicker::draw()
  318. {
  319. if (mOwner)
  320. {
  321. // Draw cone of context pointing back to texture swatch
  322. LLRect owner_rect;
  323. mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect,
  324. this);
  325. LLRect local_rect = getLocalRect();
  326. if (gFocusMgr.childHasKeyboardFocus(this) &&
  327. mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
  328. {
  329. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  330. LLGLEnable(GL_CULL_FACE);
  331. gGL.begin(LLRender::TRIANGLE_STRIP);
  332. {
  333. F32 alpha_in = CONTEXT_CONE_IN_ALPHA * mContextConeOpacity;
  334. F32 alpha_out = CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity;
  335. gGL.color4f(0.f, 0.f, 0.f, alpha_out);
  336. gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
  337. gGL.color4f(0.f, 0.f, 0.f, alpha_in);
  338. gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
  339. gGL.color4f(0.f, 0.f, 0.f, alpha_out);
  340. gGL.vertex2i(local_rect.mRight, local_rect.mTop);
  341. gGL.color4f(0.f, 0.f, 0.f, alpha_in);
  342. gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
  343. gGL.color4f(0.f, 0.f, 0.f, alpha_out);
  344. gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
  345. gGL.color4f(0.f, 0.f, 0.f, alpha_in);
  346. gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
  347. gGL.color4f(0.f, 0.f, 0.f, alpha_out);
  348. gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
  349. gGL.color4f(0.f, 0.f, 0.f, alpha_in);
  350. gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
  351. gGL.color4f(0.f, 0.f, 0.f, alpha_out);
  352. gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
  353. gGL.color4f(0.f, 0.f, 0.f, alpha_in);
  354. gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
  355. }
  356. gGL.end();
  357. }
  358. }
  359. F32 opacity = 0.f;
  360. if (gFocusMgr.childHasMouseCapture(getDragHandle()))
  361. {
  362. static LLCachedControl<F32> picker_opacity(gSavedSettings,
  363. "PickerContextOpacity");
  364. opacity = picker_opacity;
  365. }
  366. mContextConeOpacity =
  367. lerp(mContextConeOpacity, opacity,
  368. LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
  369. updateImageStats();
  370. // If we are inactive, gray out "apply immediate" checkbox
  371. mSelectButton->setEnabled(mActive);
  372. mPipetteButton->setEnabled(mActive);
  373. mPipetteButton->setValue(gToolMgr.isCurrentTool(&gToolPipette));
  374. // RN: reset search bar to reflect actual search query (all caps, for
  375. // example)
  376. mSearchEdit->setText(mInventoryPanel->getFilterSubString());
  377. if (mOwner)
  378. {
  379. mTexturep = NULL;
  380. if (mImageAssetID.notNull())
  381. {
  382. if (LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
  383. {
  384. LLViewerObject* obj =
  385. gSelectMgr.getSelection()->getFirstObject();
  386. if (obj)
  387. {
  388. LLViewerTexture* baked_tex =
  389. obj->getBakedTextureForMagicId(mImageAssetID);
  390. if (baked_tex)
  391. {
  392. mTexturep = baked_tex->asFetched();
  393. }
  394. }
  395. }
  396. if (mTexturep.isNull())
  397. {
  398. mTexturep =
  399. LLViewerTextureManager::getFetchedTexture(mImageAssetID,
  400. FTT_DEFAULT,
  401. true,
  402. LLGLTexture::BOOST_PREVIEW);
  403. }
  404. }
  405. else if (mFallbackImagep.notNull())
  406. {
  407. mTexturep = mFallbackImagep;
  408. }
  409. if (mTentativeLabel)
  410. {
  411. mTentativeLabel->setVisible(false);
  412. }
  413. const LLUUID& default_id = mOwner->getDefaultImageAssetID();
  414. mDefaultButton->setEnabled(default_id.notNull() &&
  415. mImageAssetID != default_id);
  416. mBlankButton->setEnabled(mImageAssetID != mBlankImageAssetID);
  417. mInvisibleButton->setEnabled(mOwner->getAllowInvisibleTexture() &&
  418. mImageAssetID != mInvisibleImageAssetID);
  419. mNoneButton->setEnabled(mOwner->getAllowNoTexture() &&
  420. mImageAssetID.notNull());
  421. // Fill-up the local bitmap list if needed
  422. if (mLastBitmapsListVersion != LLLocalBitmap::getBitmapListVersion())
  423. {
  424. mLastBitmapsListVersion = LLLocalBitmap::getBitmapListVersion();
  425. mLocalScrollCtrl->clearRows();
  426. const LLLocalBitmap::list_t& bitmaps = LLLocalBitmap::getBitmapList();
  427. if (!bitmaps.empty())
  428. {
  429. for (LLLocalBitmap::list_t::const_iterator
  430. iter = bitmaps.begin(), end = bitmaps.end();
  431. iter != end; ++iter)
  432. {
  433. LLLocalBitmap* bitmap = *iter;
  434. if (!bitmap) continue; // Paranoia
  435. LLSD element;
  436. element["id"] = bitmap->getTrackingID();
  437. element["columns"][0]["column"] = "unit_name";
  438. element["columns"][0]["type"] = "text";
  439. element["columns"][0]["value"] = bitmap->getShortName();
  440. mLocalScrollCtrl->addElement(element);
  441. }
  442. }
  443. }
  444. LLFloater::draw();
  445. if (isMinimized())
  446. {
  447. return;
  448. }
  449. // Border
  450. LLRect border(BORDER_PAD,
  451. getRect().getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD,
  452. TEX_PICKER_MIN_WIDTH / 2 - TEXTURE_INVENTORY_PADDING - HPAD - BORDER_PAD,
  453. BORDER_PAD + FOOTER_HEIGHT + getRect().getHeight() - TEX_PICKER_MIN_HEIGHT);
  454. gl_rect_2d(border, LLColor4::black, false);
  455. // Interior
  456. LLRect interior = border;
  457. interior.stretch(-1);
  458. if (mTexturep)
  459. {
  460. if (mTexturep->getComponents() == 4)
  461. {
  462. gl_rect_2d_checkerboard(interior);
  463. }
  464. F32 width = interior.getWidth();
  465. F32 height = interior.getHeight();
  466. gl_draw_scaled_image(interior.mLeft, interior.mBottom,
  467. width, height, mTexturep);
  468. // Pump the priority
  469. mTexturep->addTextureStats(width * height);
  470. // Draw Tentative Label over the image
  471. if (mOwner->getTentative() && !mIsDirty)
  472. {
  473. mTentativeLabel->setVisible(true);
  474. drawChild(mTentativeLabel);
  475. }
  476. }
  477. else
  478. {
  479. gl_rect_2d(interior, LLColor4::grey);
  480. // Draw X
  481. gl_draw_x(interior, LLColor4::black);
  482. }
  483. }
  484. }
  485. //virtual
  486. bool LLFloaterTexturePicker::handleDragAndDrop(S32 x, S32 y, MASK mask,
  487. bool drop,
  488. EDragAndDropType cargo_type,
  489. void* cargo_data,
  490. EAcceptance* accept,
  491. std::string& tooltip_msg)
  492. {
  493. //MK
  494. if (gRLenabled && gRLInterface.mContainsShowinv)
  495. {
  496. *accept = ACCEPT_NO;
  497. return true;
  498. }
  499. //mk
  500. #if LL_MESH_ASSET_SUPPORT
  501. if (cargo_type == DAD_TEXTURE || cargo_type == DAD_MESH)
  502. #else
  503. if (cargo_type == DAD_TEXTURE)
  504. #endif
  505. {
  506. LLInventoryItem* item = (LLInventoryItem*)cargo_data;
  507. const LLPermissions& perms = item->getPermissions();
  508. PermissionMask item_perm_mask = 0;
  509. if (perms.allowCopyBy(gAgentID))
  510. {
  511. item_perm_mask = PERM_COPY;
  512. }
  513. if (perms.allowModifyBy(gAgentID))
  514. {
  515. item_perm_mask |= PERM_MODIFY;
  516. }
  517. if (perms.allowTransferBy(gAgentID))
  518. {
  519. item_perm_mask |= PERM_TRANSFER;
  520. }
  521. PermissionMask filter_perm_mask = getFilterPermMask();
  522. if ((item_perm_mask & filter_perm_mask) == filter_perm_mask)
  523. {
  524. if (drop)
  525. {
  526. setImageID(item->getAssetUUID());
  527. commitIfImmediateSet();
  528. }
  529. *accept = ACCEPT_YES_SINGLE;
  530. }
  531. else
  532. {
  533. *accept = ACCEPT_NO;
  534. }
  535. }
  536. else
  537. {
  538. *accept = ACCEPT_NO;
  539. }
  540. LL_DEBUGS("UserInput") << "dragAndDrop handled by LLFloaterTexturePicker "
  541. << getName() << LL_ENDL;
  542. return true;
  543. }
  544. //virtual
  545. bool LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
  546. {
  547. LLFolderView* root_folder = mInventoryPanel->getRootFolder();
  548. if (root_folder && mSearchEdit)
  549. {
  550. if (mSearchEdit->hasFocus() && mask == MASK_NONE &&
  551. (key == KEY_RETURN || key == KEY_DOWN))
  552. {
  553. if (!root_folder->getCurSelectedItem())
  554. {
  555. LLFolderViewItem* itemp =
  556. root_folder->getItemByID(gInventory.getRootFolderID());
  557. if (itemp)
  558. {
  559. root_folder->setSelection(itemp, false, false);
  560. mSelectButton->setEnabled(true);
  561. }
  562. else
  563. {
  564. mSelectButton->setEnabled(false);
  565. }
  566. }
  567. root_folder->scrollToShowSelection();
  568. // Move focus to inventory proper
  569. root_folder->setFocus(true);
  570. // Treat this as a user selection of the first filtered result
  571. commitIfImmediateSet();
  572. return true;
  573. }
  574. if (root_folder->hasFocus() && key == KEY_UP)
  575. {
  576. mSearchEdit->focusFirstItem(true);
  577. }
  578. }
  579. return LLFloater::handleKeyHere(key, mask);
  580. }
  581. void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
  582. {
  583. if (!mActive || mImageAssetID == image_id)
  584. {
  585. return;
  586. }
  587. mNoCopyTextureSelected = false;
  588. mIsDirty = true;
  589. mImageAssetID = image_id;
  590. S32 mode = mModeSelector->getSelectedIndex();
  591. if (LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
  592. {
  593. if (mBakeTextureEnabled && mode != 2)
  594. {
  595. mModeSelector->setSelectedIndex(2, 0);
  596. onModeSelect((LLUICtrl*)mModeSelector, this);
  597. }
  598. }
  599. else
  600. {
  601. if (mode == 2)
  602. {
  603. mModeSelector->setSelectedIndex(0, 0);
  604. onModeSelect((LLUICtrl*)mModeSelector, this);
  605. }
  606. LLUUID item_id = findItemID(mImageAssetID, false);
  607. if (item_id.isNull())
  608. {
  609. mInventoryPanel->getRootFolder()->clearSelection();
  610. }
  611. else
  612. {
  613. LLInventoryItem* itemp = gInventory.getItem(image_id);
  614. if (itemp && !itemp->getPermissions().allowCopyBy(gAgentID))
  615. {
  616. // No-copy texture
  617. mApplyImmediatelyCheck->set(false);
  618. mNoCopyTextureSelected = true;
  619. }
  620. mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
  621. }
  622. }
  623. }
  624. void LLFloaterTexturePicker::setActive(bool active)
  625. {
  626. if (!active && mPipetteButton->getValue().asBoolean())
  627. {
  628. stopUsingPipette();
  629. }
  630. mActive = active;
  631. }
  632. void LLFloaterTexturePicker::setCanApplyImmediately(bool b)
  633. {
  634. mCanApplyImmediately = b;
  635. if (!mCanApplyImmediately)
  636. {
  637. mApplyImmediatelyCheck->set(false);
  638. }
  639. mApplyImmediatelyCheck->setEnabled(mCanApplyImmediately);
  640. updateFilterPermMask();
  641. }
  642. void LLFloaterTexturePicker::setLocalTextureEnabled(bool b)
  643. {
  644. mModeSelector->setIndexEnabled(1, b);
  645. }
  646. void LLFloaterTexturePicker::setBakeTextureEnabled(bool b)
  647. {
  648. bool changed = b != mBakeTextureEnabled;
  649. mBakeTextureEnabled = b;
  650. mModeSelector->setIndexEnabled(2, b);
  651. S32 mode = mModeSelector->getSelectedIndex();
  652. if (!b && mode == 2)
  653. {
  654. mModeSelector->setSelectedIndex(0, 0);
  655. }
  656. if (changed && b && mode != 2 &&
  657. LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
  658. {
  659. mModeSelector->setSelectedIndex(2, 0);
  660. }
  661. onModeSelect((LLUICtrl*)mModeSelector, this);
  662. }
  663. void LLFloaterTexturePicker::stopUsingPipette()
  664. {
  665. if (gToolMgr.isCurrentTool(&gToolPipette))
  666. {
  667. gToolMgr.clearTransientTool();
  668. }
  669. }
  670. void LLFloaterTexturePicker::updateImageStats()
  671. {
  672. if (mTexturep.notNull())
  673. {
  674. // RN: have we received header data for this image ?
  675. if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0)
  676. {
  677. std::string formatted_dims = llformat("%d x %d",
  678. mTexturep->getFullWidth(),
  679. mTexturep->getFullHeight());
  680. mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
  681. }
  682. else
  683. {
  684. mResolutionLabel->setTextArg("[DIMENSIONS]",
  685. std::string("[? x ?]"));
  686. }
  687. }
  688. else
  689. {
  690. mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
  691. }
  692. }
  693. const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id,
  694. bool copyable_only)
  695. {
  696. LLViewerInventoryCategory::cat_array_t cats;
  697. LLViewerInventoryItem::item_array_t items;
  698. LLAssetIDMatches asset_id_matches(asset_id);
  699. gInventory.collectDescendentsIf(LLUUID::null, cats, items,
  700. LLInventoryModel::INCLUDE_TRASH,
  701. asset_id_matches);
  702. S32 count = items.size();
  703. if (count > 0)
  704. {
  705. // Search for copyable version first
  706. for (S32 i = 0; i < count; ++i)
  707. {
  708. LLInventoryItem* itemp = items[i];
  709. LLPermissions item_permissions = itemp->getPermissions();
  710. if (item_permissions.allowCopyBy(gAgentID, gAgent.getGroupID()))
  711. {
  712. return itemp->getUUID();
  713. }
  714. }
  715. // Otherwise just return first instance, unless copyable requested
  716. if (!copyable_only)
  717. {
  718. return items[0]->getUUID();
  719. }
  720. }
  721. return LLUUID::null;
  722. }
  723. PermissionMask LLFloaterTexturePicker::getFilterPermMask()
  724. {
  725. return mApplyImmediatelyCheck->get() ? mImmediateFilterPermMask
  726. : mNonImmediateFilterPermMask;
  727. }
  728. void LLFloaterTexturePicker::commitIfImmediateSet()
  729. {
  730. if (!mNoCopyTextureSelected && mOwner)
  731. {
  732. if (mCanApplyImmediately && mApplyImmediatelyCheck->get())
  733. {
  734. mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
  735. }
  736. }
  737. }
  738. //static
  739. void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
  740. {
  741. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  742. if (self)
  743. {
  744. if (self->mOwner)
  745. {
  746. self->setImageID(self->mOwner->getDefaultImageAssetID());
  747. }
  748. self->mSelectButton->setEnabled(true);
  749. self->commitIfImmediateSet();
  750. }
  751. }
  752. //static
  753. void LLFloaterTexturePicker::onBtnBlank(void* userdata)
  754. {
  755. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  756. if (self)
  757. {
  758. self->mSelectButton->setEnabled(true);
  759. self->setImageID(self->mBlankImageAssetID);
  760. self->commitIfImmediateSet();
  761. }
  762. }
  763. //static
  764. void LLFloaterTexturePicker::onBtnInvisible(void* userdata)
  765. {
  766. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  767. if (self)
  768. {
  769. self->mSelectButton->setEnabled(true);
  770. self->setImageID(self->mInvisibleImageAssetID);
  771. self->commitIfImmediateSet();
  772. }
  773. }
  774. //static
  775. void LLFloaterTexturePicker::onBtnNone(void* userdata)
  776. {
  777. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  778. if (self)
  779. {
  780. self->mSelectButton->setEnabled(true);
  781. self->setImageID(LLUUID::null);
  782. self->commitIfImmediateSet();
  783. }
  784. }
  785. //static
  786. void LLFloaterTexturePicker::onBtnCancel(void* userdata)
  787. {
  788. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  789. if (self)
  790. {
  791. self->setImageID(self->mOriginalImageAssetID);
  792. if (self->mOwner)
  793. {
  794. self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
  795. }
  796. self->mIsDirty = false;
  797. self->close();
  798. }
  799. }
  800. //static
  801. void LLFloaterTexturePicker::onBtnSelect(void* userdata)
  802. {
  803. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  804. if (self)
  805. {
  806. if (self->mOwner)
  807. {
  808. LLUUID local_id, tracking_id;
  809. if (self->mLocalScrollCtrl->getVisible() &&
  810. !self->mLocalScrollCtrl->getAllSelected().empty())
  811. {
  812. tracking_id = self->mLocalScrollCtrl->getCurrentID();
  813. local_id = LLLocalBitmap::getWorldID(tracking_id);
  814. }
  815. self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT,
  816. local_id, tracking_id);
  817. }
  818. self->close();
  819. }
  820. }
  821. //static
  822. void LLFloaterTexturePicker::onBtnPipette(void* userdata)
  823. {
  824. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  825. if (self)
  826. {
  827. bool pipette_active = self->mPipetteButton->getValue().asBoolean();
  828. pipette_active = !pipette_active;
  829. if (pipette_active)
  830. {
  831. gToolPipette.setSelectCallback(onTextureSelect, self);
  832. gToolMgr.setTransientTool(&gToolPipette);
  833. }
  834. else
  835. {
  836. gToolMgr.clearTransientTool();
  837. }
  838. }
  839. }
  840. //static
  841. void LLFloaterTexturePicker::onSelectionChange(LLFolderView* folderp,
  842. bool user_action, void* data)
  843. {
  844. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
  845. if (!self || !folderp) return;
  846. bool can_select = false;
  847. const LLFolderView::selected_items_t& items = folderp->getSelectedItems();
  848. if (items.size())
  849. {
  850. LLFolderViewItem* first_itemp = items.front();
  851. LLInventoryItem* itemp =
  852. gInventory.getItem(first_itemp->getListener()->getUUID());
  853. self->mNoCopyTextureSelected = false;
  854. if (itemp)
  855. {
  856. can_select = true;
  857. if (!itemp->getPermissions().allowCopyBy(gAgentID))
  858. {
  859. self->mNoCopyTextureSelected = true;
  860. }
  861. self->mImageAssetID = itemp->getAssetUUID();
  862. self->mIsDirty = true;
  863. if (user_action)
  864. {
  865. // Only commit intentional selections, not implicit ones
  866. self->commitIfImmediateSet();
  867. }
  868. }
  869. }
  870. self->mSelectButton->setEnabled(can_select);
  871. }
  872. //static
  873. void LLFloaterTexturePicker::onModeSelect(LLUICtrl*, void* userdata)
  874. {
  875. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  876. if (!self) return;
  877. S32 mode = self->mModeSelector->getSelectedIndex();
  878. bool inventory = mode == 0;
  879. bool local = mode == 1;
  880. bool bakes = mode == 2;
  881. self->mDefaultButton->setVisible(inventory);
  882. self->mBlankButton->setVisible(inventory);
  883. self->mNoneButton->setVisible(inventory);
  884. self->mInvisibleButton->setVisible(inventory);
  885. self->mPipetteButton->setVisible(inventory);
  886. self->mSearchEdit->setVisible(inventory);
  887. self->mPipetteButton->setVisible(inventory);
  888. self->mInventoryPanel->setVisible(inventory);
  889. self->mAddButton->setVisible(local);
  890. self->mRemoveButton->setVisible(local);
  891. self->mUploadButton->setVisible(local);
  892. self->mLocalScrollCtrl->setVisible(local);
  893. self->mBakeTextureCombo->setVisible(bakes);
  894. if (bakes)
  895. {
  896. self->stopUsingPipette();
  897. const LLUUID& image_id = self->mImageAssetID;
  898. S32 idx = -1;
  899. if (image_id == IMG_USE_BAKED_HEAD)
  900. {
  901. idx = 0;
  902. }
  903. else if (image_id == IMG_USE_BAKED_UPPER)
  904. {
  905. idx = 1;
  906. }
  907. else if (image_id == IMG_USE_BAKED_LOWER)
  908. {
  909. idx = 2;
  910. }
  911. else if (image_id == IMG_USE_BAKED_HAIR)
  912. {
  913. idx = 3;
  914. }
  915. else if (image_id == IMG_USE_BAKED_EYES)
  916. {
  917. idx = 4;
  918. }
  919. else if (image_id == IMG_USE_BAKED_SKIRT)
  920. {
  921. idx = 5;
  922. }
  923. else if (image_id == IMG_USE_BAKED_LEFTARM)
  924. {
  925. idx = 6;
  926. }
  927. else if (image_id == IMG_USE_BAKED_LEFTLEG)
  928. {
  929. idx = 7;
  930. }
  931. else if (image_id == IMG_USE_BAKED_AUX1)
  932. {
  933. idx = 8;
  934. }
  935. else if (image_id == IMG_USE_BAKED_AUX2)
  936. {
  937. idx = 9;
  938. }
  939. else if (image_id == IMG_USE_BAKED_AUX3)
  940. {
  941. idx = 10;
  942. }
  943. self->mBakeTextureCombo->setSelectedByValue(idx, true);
  944. self->mSelectButton->setEnabled(true);
  945. }
  946. }
  947. //static
  948. void LLFloaterTexturePicker::onBtnAdd(void* userdata)
  949. {
  950. LLLocalBitmap::addUnits();
  951. }
  952. //static
  953. void LLFloaterTexturePicker::onBtnRemove(void* userdata)
  954. {
  955. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  956. if (!self) return;
  957. std::vector<LLScrollListItem*> selected_items =
  958. self->mLocalScrollCtrl->getAllSelected();
  959. if (!selected_items.empty())
  960. {
  961. for (std::vector<LLScrollListItem*>::iterator
  962. iter = selected_items.begin(), end = selected_items.end();
  963. iter != end; ++iter)
  964. {
  965. LLScrollListItem* list_item = *iter;
  966. if (list_item)
  967. {
  968. LLUUID id = list_item->getUUID();
  969. LLLocalBitmap::delUnit(id);
  970. }
  971. }
  972. self->mRemoveButton->setEnabled(false);
  973. self->mUploadButton->setEnabled(false);
  974. }
  975. }
  976. //static
  977. void LLFloaterTexturePicker::onBtnUpload(void* userdata)
  978. {
  979. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  980. if (self)
  981. {
  982. std::vector<LLScrollListItem*> items =
  983. self->mLocalScrollCtrl->getAllSelected();
  984. for (std::vector<LLScrollListItem*>::iterator
  985. iter = items.begin(), end = items.end();
  986. iter != end; ++iter)
  987. {
  988. LLScrollListItem* list_item = *iter;
  989. if (list_item)
  990. {
  991. LLUUID tracking_id = list_item->getUUID();
  992. std::string filename = LLLocalBitmap::getFilename(tracking_id);
  993. new LLFloaterImagePreview(filename);
  994. }
  995. }
  996. }
  997. }
  998. //static
  999. void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl*, void* userdata)
  1000. {
  1001. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  1002. if (!self) return;
  1003. uuid_vec_t ids = self->mLocalScrollCtrl->getSelectedIDs();
  1004. S32 items = ids.size();
  1005. bool has_selection = items > 0;
  1006. bool has_one_selection = items == 1;
  1007. self->mRemoveButton->setEnabled(has_selection);
  1008. self->mUploadButton->setEnabled(has_selection);
  1009. self->mSelectButton->setEnabled(has_one_selection);
  1010. if (has_one_selection && self->mOwner)
  1011. {
  1012. const LLUUID& inworld_id = LLLocalBitmap::getWorldID(ids[0]);
  1013. self->mOwner->setImageAssetID(inworld_id);
  1014. if (self->mCanApplyImmediately && self->mApplyImmediatelyCheck->get())
  1015. {
  1016. self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE,
  1017. inworld_id, ids[0]);
  1018. }
  1019. }
  1020. }
  1021. //static
  1022. void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrlp,
  1023. void* user_data)
  1024. {
  1025. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data;
  1026. LLCheckBoxCtrl* checkp = (LLCheckBoxCtrl*)ctrlp;
  1027. if (self && checkp)
  1028. {
  1029. gSavedSettings.setBool("ApplyTextureImmediately", checkp->get());
  1030. self->updateFilterPermMask();
  1031. self->commitIfImmediateSet();
  1032. }
  1033. }
  1034. //static
  1035. void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrlp,
  1036. void* user_data)
  1037. {
  1038. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data;
  1039. LLComboBox* combop = (LLComboBox*)ctrlp;
  1040. if (!self || !combop) return;
  1041. LLUUID image_id = self->mOwner->getDefaultImageAssetID();
  1042. S32 type = combop->getValue().asInteger();
  1043. switch (type)
  1044. {
  1045. case 0: image_id = IMG_USE_BAKED_HEAD; break;
  1046. case 1: image_id = IMG_USE_BAKED_UPPER; break;
  1047. case 2: image_id = IMG_USE_BAKED_LOWER; break;
  1048. case 3: image_id = IMG_USE_BAKED_HAIR; break;
  1049. case 4: image_id = IMG_USE_BAKED_EYES; break;
  1050. case 5: image_id = IMG_USE_BAKED_SKIRT; break;
  1051. case 6: image_id = IMG_USE_BAKED_LEFTARM; break;
  1052. case 7: image_id = IMG_USE_BAKED_LEFTLEG; break;
  1053. case 8: image_id = IMG_USE_BAKED_AUX1; break;
  1054. case 9: image_id = IMG_USE_BAKED_AUX2; break;
  1055. case 10: image_id = IMG_USE_BAKED_AUX3; break;
  1056. default: break;
  1057. }
  1058. self->setImageID(image_id);
  1059. self->mSelectButton->setEnabled(true);
  1060. self->commitIfImmediateSet();
  1061. }
  1062. void LLFloaterTexturePicker::updateFilterPermMask()
  1063. {
  1064. mInventoryPanel->setFilterPermMask(getFilterPermMask());
  1065. }
  1066. void LLFloaterTexturePicker::setImmediateFilterPermMask(PermissionMask mask)
  1067. {
  1068. // Do not re-apply the same mask: it would cause an useless inventory
  1069. // re-filtering. HB
  1070. if (mImmediateFilterPermMask != mask)
  1071. {
  1072. mImmediateFilterPermMask = mask;
  1073. mInventoryPanel->setFilterPermMask(mask);
  1074. }
  1075. }
  1076. void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string,
  1077. void* user_data)
  1078. {
  1079. LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
  1080. if (!picker) return;
  1081. std::string upper_case_search_string = search_string;
  1082. LLStringUtil::toUpper(upper_case_search_string);
  1083. if (upper_case_search_string.empty())
  1084. {
  1085. if (picker->mInventoryPanel->getFilterSubString().empty())
  1086. {
  1087. // current filter and new filter empty, do nothing
  1088. return;
  1089. }
  1090. picker->mSavedFolderState.setApply(true);
  1091. picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
  1092. // Add folder with current item to list of previously opened folders
  1093. LLOpenFoldersWithSelection opener;
  1094. picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
  1095. picker->mInventoryPanel->getRootFolder()->scrollToShowSelection();
  1096. }
  1097. else if (picker->mInventoryPanel->getFilterSubString().empty())
  1098. {
  1099. // First letter in search term, save existing folder open state
  1100. if (!picker->mInventoryPanel->getRootFolder()->isFilterModified())
  1101. {
  1102. picker->mSavedFolderState.setApply(false);
  1103. picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
  1104. }
  1105. }
  1106. picker->mInventoryPanel->setFilterSubString(upper_case_search_string);
  1107. }
  1108. //static
  1109. void LLFloaterTexturePicker::onTextureSelect(const LLTextureEntry& te,
  1110. void* data)
  1111. {
  1112. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
  1113. if (!self) return;
  1114. LLUUID inventory_item_id = self->findItemID(te.getID(), true);
  1115. if (inventory_item_id.notNull())
  1116. {
  1117. gToolPipette.setResult(true, "");
  1118. self->setImageID(te.getID());
  1119. self->mNoCopyTextureSelected = false;
  1120. LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
  1121. if (itemp && !itemp->getPermissions().allowCopyBy(gAgentID))
  1122. {
  1123. // No-copy texture
  1124. self->mNoCopyTextureSelected = true;
  1125. }
  1126. self->commitIfImmediateSet();
  1127. self->mSelectButton->setEnabled(true);
  1128. }
  1129. else
  1130. {
  1131. self->mSelectButton->setEnabled(false);
  1132. gToolPipette.setResult(false, self->getString("not_in_inventory"));
  1133. }
  1134. }
  1135. void LLFloaterTexturePicker::onDragHandleClicked(S32 x, S32 y, void* userdata)
  1136. {
  1137. LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
  1138. if (!self || !self->mTexturep || self->mImageAssetID.isNull() ||
  1139. LLPreview::show(self->mImageAssetID))
  1140. {
  1141. return;
  1142. }
  1143. // Only react if the mouse pointer is within the preview area
  1144. const LLRect& rect = self->getRect();
  1145. LLRect preview_area(BORDER_PAD,
  1146. rect.getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD,
  1147. TEX_PICKER_MIN_WIDTH / 2 - TEXTURE_INVENTORY_PADDING -
  1148. HPAD - BORDER_PAD,
  1149. BORDER_PAD + FOOTER_HEIGHT + rect.getHeight() -
  1150. TEX_PICKER_MIN_HEIGHT);
  1151. if (preview_area.pointInRect(x, y))
  1152. {
  1153. S32 left, top;
  1154. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1155. LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
  1156. rect.translate(left - rect.mLeft, top - rect.mTop);
  1157. std::string title = "Texture preview";
  1158. LLPreviewTexture* preview = new LLPreviewTexture(title, rect, title,
  1159. self->mImageAssetID,
  1160. false);
  1161. preview->setNotCopyable();
  1162. preview->childSetText("desc", title);
  1163. preview->childSetEnabled("desc", false);
  1164. preview->setFocus(true);
  1165. }
  1166. }
  1167. ///////////////////////////////////////////////////////////////////////////////
  1168. // LLTextureCtrl class
  1169. ///////////////////////////////////////////////////////////////////////////////
  1170. static const std::string LL_TEXTURE_CTRL_TAG = "texture_picker";
  1171. static LLRegisterWidget<LLTextureCtrl> r(LL_TEXTURE_CTRL_TAG);
  1172. LLTextureCtrl::LLTextureCtrl(const std::string& name,
  1173. const LLRect& rect,
  1174. const std::string& label,
  1175. const LLUUID& image_id,
  1176. const LLUUID& default_image_id,
  1177. const std::string& default_image_name)
  1178. : LLUICtrl(name, rect, true, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
  1179. mDragCallback(NULL),
  1180. mDropCallback(NULL),
  1181. mOnCancelCallback(NULL),
  1182. mOnCloseCallback(NULL),
  1183. mOnSelectCallback(NULL),
  1184. mBorderColor(LLUI::sDefaultHighlightLight),
  1185. mImageAssetID(image_id),
  1186. mDefaultImageAssetID(default_image_id),
  1187. mDefaultImageName(default_image_name),
  1188. mBlankImageAssetID(gSavedSettings.getString("UIImgWhiteUUID")),
  1189. mDisplayRatio(0.f),
  1190. mLabel(label),
  1191. mAllowNoTexture(false),
  1192. mAllowInvisibleTexture(false),
  1193. mAllowLocalTexture(true),
  1194. mBakeTextureEnabled(false),
  1195. mImmediateFilterPermMask(PERM_NONE),
  1196. mNonImmediateFilterPermMask(PERM_NONE),
  1197. mCanApplyImmediately(false),
  1198. mValid(true),
  1199. mDirty(false),
  1200. mEnabled(true),
  1201. mCaptionAlwaysEnabled(false),
  1202. mShowLoadingPlaceholder(true)
  1203. {
  1204. mCaption = new LLTextBox(label,
  1205. LLRect(0, gBtnHeightSmall, getRect().getWidth(), 0),
  1206. label, LLFontGL::getFontSansSerifSmall());
  1207. mCaption->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
  1208. addChild(mCaption);
  1209. S32 image_top = getRect().getHeight();
  1210. S32 image_bottom = gBtnHeightSmall;
  1211. S32 image_middle = (image_top + image_bottom) / 2;
  1212. S32 line_height =
  1213. ll_roundp(LLFontGL::getFontSansSerifSmall()->getLineHeight());
  1214. mTentativeLabel = new LLTextBox(std::string("Multiple"),
  1215. LLRect(0, image_middle + line_height / 2,
  1216. getRect().getWidth(),
  1217. image_middle - line_height / 2),
  1218. std::string("Multiple"),
  1219. LLFontGL::getFontSansSerifSmall());
  1220. mTentativeLabel->setHAlign(LLFontGL::HCENTER);
  1221. mTentativeLabel->setFollowsAll();
  1222. addChild(mTentativeLabel);
  1223. LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
  1224. border_rect.mBottom += gBtnHeightSmall;
  1225. mBorder = new LLViewBorder(std::string("border"), border_rect,
  1226. LLViewBorder::BEVEL_IN);
  1227. mBorder->setFollowsAll();
  1228. addChild(mBorder);
  1229. setEnabled(true); // For the tooltip
  1230. mLoadingPlaceholderString = LLTrans::getWString("texture_loading");
  1231. }
  1232. //virtual
  1233. LLTextureCtrl::~LLTextureCtrl()
  1234. {
  1235. closeFloater();
  1236. }
  1237. //virtual
  1238. const std::string& LLTextureCtrl::getTag() const
  1239. {
  1240. return LL_TEXTURE_CTRL_TAG;
  1241. }
  1242. //virtual
  1243. LLXMLNodePtr LLTextureCtrl::getXML(bool save_children) const
  1244. {
  1245. LLXMLNodePtr node = LLUICtrl::getXML();
  1246. node->setName(LL_TEXTURE_CTRL_TAG);
  1247. node->createChild("label", true)->setStringValue(getLabel());
  1248. node->createChild("default_image_name", true)->setStringValue(getDefaultImageName());
  1249. node->createChild("allow_no_texture", true)->setBoolValue(mAllowNoTexture);
  1250. node->createChild("allow_invisible_texture", true)->setBoolValue(mAllowInvisibleTexture);
  1251. node->createChild("can_apply_immediately", true)->setBoolValue(mCanApplyImmediately);
  1252. return node;
  1253. }
  1254. LLView* LLTextureCtrl::fromXML(LLXMLNodePtr node, LLView* parent,
  1255. LLUICtrlFactory* factory)
  1256. {
  1257. std::string name = LL_TEXTURE_CTRL_TAG;
  1258. node->getAttributeString("name", name);
  1259. LLRect rect;
  1260. createRect(node, rect, parent);
  1261. std::string label;
  1262. node->getAttributeString("label", label);
  1263. std::string image_id("");
  1264. node->getAttributeString("image", image_id);
  1265. std::string default_image_id("");
  1266. node->getAttributeString("default_image", default_image_id);
  1267. std::string default_image_name("Default");
  1268. node->getAttributeString("default_image_name", default_image_name);
  1269. bool allow_no_texture = false;
  1270. node->getAttributeBool("allow_no_texture", allow_no_texture);
  1271. bool allow_invisible_texture = false;
  1272. node->getAttributeBool("allow_invisible_texture", allow_invisible_texture);
  1273. bool can_apply_immediately = false;
  1274. node->getAttributeBool("can_apply_immediately", can_apply_immediately);
  1275. bool can_use_bakes = false;
  1276. node->getAttributeBool("can_use_bakes", can_use_bakes);
  1277. if (label.empty())
  1278. {
  1279. label.assign(node->getValue());
  1280. }
  1281. LLTextureCtrl* self = new LLTextureCtrl(name, rect, label,
  1282. LLUUID(image_id),
  1283. LLUUID(default_image_id),
  1284. default_image_name);
  1285. self->setAllowNoTexture(allow_no_texture);
  1286. self->setAllowInvisibleTexture(allow_invisible_texture);
  1287. self->setCanApplyImmediately(can_apply_immediately);
  1288. self->setBakeTextureEnabled(can_use_bakes);
  1289. self->initFromXML(node, parent);
  1290. return self;
  1291. }
  1292. void LLTextureCtrl::setCaption(const std::string& caption)
  1293. {
  1294. mCaption->setText(caption);
  1295. }
  1296. void LLTextureCtrl::setCanApplyImmediately(bool b)
  1297. {
  1298. mCanApplyImmediately = b;
  1299. LLFloaterTexturePicker* floaterp =
  1300. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1301. if (floaterp)
  1302. {
  1303. floaterp->setCanApplyImmediately(b);
  1304. }
  1305. }
  1306. void LLTextureCtrl::setBakeTextureEnabled(bool b)
  1307. {
  1308. mBakeTextureEnabled = b;
  1309. LLFloaterTexturePicker* floaterp =
  1310. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1311. if (floaterp)
  1312. {
  1313. floaterp->setBakeTextureEnabled(b);
  1314. }
  1315. }
  1316. void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
  1317. {
  1318. mImmediateFilterPermMask = mask;
  1319. LLFloaterTexturePicker* floaterp =
  1320. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1321. if (floaterp)
  1322. {
  1323. floaterp->setImmediateFilterPermMask(mask);
  1324. }
  1325. }
  1326. //virtual
  1327. void LLTextureCtrl::setVisible(bool visible)
  1328. {
  1329. if (!visible)
  1330. {
  1331. closeFloater();
  1332. }
  1333. LLUICtrl::setVisible(visible);
  1334. }
  1335. //virtual
  1336. void LLTextureCtrl::setEnabled(bool enabled)
  1337. {
  1338. mEnabled = enabled;
  1339. LLFloaterTexturePicker* floaterp =
  1340. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1341. if (floaterp)
  1342. {
  1343. if (!enabled)
  1344. {
  1345. // *TODO: would be better to keep floater open and show disabled
  1346. // state.
  1347. closeFloater();
  1348. }
  1349. floaterp->setActive(enabled);
  1350. }
  1351. LLView::setEnabled(true);
  1352. mCaption->setEnabled(enabled || mCaptionAlwaysEnabled);
  1353. }
  1354. void LLTextureCtrl::setValid(bool valid)
  1355. {
  1356. mValid = valid;
  1357. if (!valid)
  1358. {
  1359. LLFloaterTexturePicker* pickerp =
  1360. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1361. if (pickerp)
  1362. {
  1363. pickerp->setActive(false);
  1364. }
  1365. }
  1366. }
  1367. void LLTextureCtrl::setFallbackImageName(const std::string& image_name)
  1368. {
  1369. mFallbackImagep =
  1370. LLViewerTextureManager::getFetchedTextureFromFile(image_name,
  1371. MIPMAP_YES,
  1372. LLGLTexture::BOOST_PREVIEW,
  1373. LLViewerTexture::LOD_TEXTURE);
  1374. }
  1375. //virtual
  1376. void LLTextureCtrl::clear()
  1377. {
  1378. setImageAssetID(LLUUID::null);
  1379. }
  1380. void LLTextureCtrl::setLabel(const std::string& label)
  1381. {
  1382. mLabel = label;
  1383. mCaption->setText(label);
  1384. }
  1385. void LLTextureCtrl::showPicker(bool take_focus)
  1386. {
  1387. LLFloater* floaterp = mFloaterHandle.get();
  1388. // Show the dialog
  1389. if (floaterp)
  1390. {
  1391. floaterp->open();
  1392. }
  1393. else
  1394. {
  1395. if (!mLastFloaterLeftTop.mX && !mLastFloaterLeftTop.mY)
  1396. {
  1397. gFloaterViewp->getNewFloaterPosition(&mLastFloaterLeftTop.mX,
  1398. &mLastFloaterLeftTop.mY);
  1399. }
  1400. LLRect rect = gSavedSettings.getRect("TexturePickerRect");
  1401. rect.translate(mLastFloaterLeftTop.mX - rect.mLeft,
  1402. mLastFloaterLeftTop.mY - rect.mTop);
  1403. floaterp = new LLFloaterTexturePicker(this, rect, mLabel,
  1404. mImmediateFilterPermMask,
  1405. mNonImmediateFilterPermMask,
  1406. mCanApplyImmediately,
  1407. mAllowLocalTexture,
  1408. mBakeTextureEnabled,
  1409. mFallbackImagep.get());
  1410. mFloaterHandle = floaterp->getHandle();
  1411. if (gFloaterViewp)
  1412. {
  1413. LLFloater* parentp = gFloaterViewp->getParentFloater(this);
  1414. if (parentp)
  1415. {
  1416. parentp->addDependentFloater(floaterp);
  1417. }
  1418. }
  1419. floaterp->open();
  1420. }
  1421. if (take_focus)
  1422. {
  1423. floaterp->setFocus(true);
  1424. }
  1425. }
  1426. void LLTextureCtrl::closeFloater()
  1427. {
  1428. LLFloaterTexturePicker* floaterp =
  1429. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1430. if (floaterp)
  1431. {
  1432. floaterp->setOwner(NULL);
  1433. floaterp->close();
  1434. }
  1435. }
  1436. //virtual
  1437. bool LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask)
  1438. {
  1439. gWindowp->setCursor(UI_CURSOR_HAND);
  1440. return true;
  1441. }
  1442. //virtual
  1443. bool LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
  1444. {
  1445. if (!LLUICtrl::handleMouseDown(x, y , mask))
  1446. {
  1447. return false;
  1448. }
  1449. if (mEnabled)
  1450. {
  1451. showPicker(false);
  1452. // Ensure textures default folder is loaded
  1453. const LLUUID& tex_folder_id =
  1454. gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE);
  1455. LLInventoryModelFetch::getInstance()->start(tex_folder_id);
  1456. }
  1457. else if (mImageAssetID.notNull() && !LLPreview::show(mImageAssetID))
  1458. {
  1459. // There is no preview, so make a new one
  1460. S32 left, top;
  1461. gFloaterViewp->getNewFloaterPosition(&left, &top);
  1462. LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
  1463. rect.translate(left - rect.mLeft, top - rect.mTop);
  1464. std::string title = "Texture Preview";
  1465. LLPreviewTexture* preview = new LLPreviewTexture(title, rect, title,
  1466. mImageAssetID, false);
  1467. preview->setNotCopyable();
  1468. preview->childSetText("desc", title);
  1469. preview->childSetEnabled("desc", false);
  1470. preview->setFocus(true);
  1471. }
  1472. return true;
  1473. }
  1474. void LLTextureCtrl::onFloaterClose()
  1475. {
  1476. LLFloaterTexturePicker* floaterp =
  1477. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1478. if (floaterp)
  1479. {
  1480. if (mOnCloseCallback)
  1481. {
  1482. mOnCloseCallback(this, mCallbackUserData);
  1483. }
  1484. floaterp->setOwner(NULL);
  1485. mLastFloaterLeftTop.set(floaterp->getRect().mLeft,
  1486. floaterp->getRect().mTop);
  1487. }
  1488. mFloaterHandle.markDead();
  1489. }
  1490. void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, const LLUUID& id,
  1491. const LLUUID& tracking_id)
  1492. {
  1493. LLFloaterTexturePicker* floaterp =
  1494. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1495. if (floaterp && getEnabled())
  1496. {
  1497. mLocalTrackingID = tracking_id;
  1498. mDirty = (op != TEXTURE_CANCEL);
  1499. if (floaterp->isDirty() || id.notNull())
  1500. {
  1501. setTentative(false);
  1502. if (id.notNull())
  1503. {
  1504. mImageItemID = id;
  1505. mImageAssetID = id;
  1506. }
  1507. else
  1508. {
  1509. mImageItemID = floaterp->findItemID(floaterp->getAssetID(),
  1510. false);
  1511. LL_DEBUGS("TextureCtrl") << "mImageItemID: " << mImageItemID
  1512. << LL_ENDL;
  1513. mImageAssetID = floaterp->getAssetID();
  1514. LL_DEBUGS("TextureCtrl") << "mImageAssetID: " << mImageAssetID
  1515. << LL_ENDL;
  1516. }
  1517. if (op == TEXTURE_SELECT && mOnSelectCallback)
  1518. {
  1519. mOnSelectCallback(this, mCallbackUserData);
  1520. }
  1521. else if (op == TEXTURE_CANCEL && mOnCancelCallback)
  1522. {
  1523. mOnCancelCallback(this, mCallbackUserData);
  1524. }
  1525. else
  1526. {
  1527. onCommit();
  1528. }
  1529. }
  1530. }
  1531. }
  1532. void LLTextureCtrl::setImageAssetID(const LLUUID& asset_id)
  1533. {
  1534. if (mImageAssetID != asset_id)
  1535. {
  1536. mImageItemID.setNull();
  1537. mLocalTrackingID.setNull();
  1538. mImageAssetID = asset_id;
  1539. LLFloaterTexturePicker* floaterp =
  1540. (LLFloaterTexturePicker*)mFloaterHandle.get();
  1541. if (floaterp && getEnabled())
  1542. {
  1543. floaterp->setImageID(asset_id);
  1544. floaterp->setDirty(false);
  1545. }
  1546. }
  1547. }
  1548. //virtual
  1549. bool LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
  1550. EDragAndDropType cargo_type,
  1551. void* cargo_data, EAcceptance* accept,
  1552. std::string& tooltip_msg)
  1553. {
  1554. // This downcast may be invalid, but if the second test below returns true,
  1555. // then the cast was valid, and we can perform the third test without
  1556. // problem.
  1557. LLInventoryItem* item = (LLInventoryItem*)cargo_data;
  1558. if (getEnabled() &&
  1559. #if LL_MESH_ASSET_SUPPORT
  1560. (cargo_type == DAD_TEXTURE || cargo_type == DAD_MESH) &&
  1561. #else
  1562. cargo_type == DAD_TEXTURE &&
  1563. #endif
  1564. allowDrop(item))
  1565. {
  1566. if (drop)
  1567. {
  1568. if (doDrop(item))
  1569. {
  1570. // This removes the 'Multiple' overlay, since there is now only
  1571. // one texture selected.
  1572. setTentative(false);
  1573. onCommit();
  1574. }
  1575. }
  1576. *accept = ACCEPT_YES_SINGLE;
  1577. }
  1578. else
  1579. {
  1580. *accept = ACCEPT_NO;
  1581. }
  1582. LL_DEBUGS("UserInput") << "dragAndDrop handled by LLTextureCtrl "
  1583. << getName() << LL_ENDL;
  1584. return true;
  1585. }
  1586. //virtual
  1587. void LLTextureCtrl::draw()
  1588. {
  1589. mBorder->setKeyboardFocusHighlight(hasFocus());
  1590. if (!mValid)
  1591. {
  1592. mTexturep = NULL;
  1593. }
  1594. else if (mImageAssetID.notNull())
  1595. {
  1596. LLPointer<LLViewerFetchedTexture> texture = NULL;
  1597. if (LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
  1598. {
  1599. LLViewerObject* obj = gSelectMgr.getSelection()->getFirstObject();
  1600. if (obj)
  1601. {
  1602. LLViewerTexture* baked_tex =
  1603. obj->getBakedTextureForMagicId(mImageAssetID);
  1604. if (baked_tex)
  1605. {
  1606. texture = baked_tex->asFetched();
  1607. }
  1608. }
  1609. }
  1610. if (texture.notNull())
  1611. {
  1612. mTexturep = texture;
  1613. }
  1614. else
  1615. {
  1616. mTexturep =
  1617. LLViewerTextureManager::getFetchedTexture(mImageAssetID,
  1618. FTT_DEFAULT, true,
  1619. LLGLTexture::BOOST_PREVIEW,
  1620. LLViewerTexture::LOD_TEXTURE);
  1621. }
  1622. mTexturep->forceToSaveRawImage(0);
  1623. }
  1624. else if (mFallbackImagep.notNull())
  1625. {
  1626. // Show fallback image.
  1627. mTexturep = mFallbackImagep;
  1628. }
  1629. else // mImageAssetID.notNull()
  1630. {
  1631. mTexturep = NULL;
  1632. }
  1633. // Border
  1634. LLRect border(0, getRect().getHeight(), getRect().getWidth(),
  1635. gBtnHeightSmall);
  1636. gl_rect_2d(border, mBorderColor, false);
  1637. // Interior
  1638. LLRect interior = border;
  1639. interior.stretch(-1);
  1640. if (mTexturep)
  1641. {
  1642. bool draw_checker_board = mTexturep->getComponents() == 4;
  1643. if (draw_checker_board)
  1644. {
  1645. gl_rect_2d_checkerboard(interior);
  1646. }
  1647. F32 left = interior.mLeft;
  1648. F32 bottom = interior.mBottom;
  1649. F32 width = interior.getWidth();
  1650. F32 height = interior.getHeight();
  1651. // Pump the priority
  1652. mTexturep->addTextureStats(width * height);
  1653. if (mDisplayRatio > 0.f &&
  1654. !is_approx_zero(mDisplayRatio - width / height))
  1655. {
  1656. if (!draw_checker_board)
  1657. {
  1658. // Draw a black background that will show as thick strips
  1659. // around the resized picture.
  1660. gl_rect_2d(interior, LLColor4::black);
  1661. }
  1662. F32 proportion = mDisplayRatio * height / width;
  1663. if (proportion < 1.f)
  1664. {
  1665. left += (width - width * proportion) * 0.5f;
  1666. width *= proportion;
  1667. }
  1668. else
  1669. {
  1670. bottom += (height - height / proportion) * 0.5f;
  1671. height /= proportion;
  1672. }
  1673. }
  1674. gl_draw_scaled_image(left, bottom, width, height, mTexturep);
  1675. }
  1676. else
  1677. {
  1678. gl_rect_2d(interior, LLColor4::grey);
  1679. // Draw X
  1680. gl_draw_x(interior, LLColor4::black);
  1681. }
  1682. mTentativeLabel->setVisible(mTexturep.notNull() && getTentative());
  1683. // Show "Loading..." string on the top left corner while this texture is
  1684. // loading. Using the discard level, do not show the string if the texture
  1685. // is almost but not fully loaded.
  1686. if (mTexturep.notNull() && mShowLoadingPlaceholder &&
  1687. !mTexturep->isFullyLoaded())
  1688. {
  1689. static LLFontGL* sans = LLFontGL::getFontSansSerif();
  1690. static LLFontGL* large = LLFontGL::getFontSansSerifLarge();
  1691. LLFontGL* font = interior.getWidth() < 128 ? sans : large;
  1692. font->render(mLoadingPlaceholderString, 0,
  1693. llfloor(interior.mLeft + 4), llfloor(interior.mTop - 20),
  1694. LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE,
  1695. LLFontGL::DROP_SHADOW);
  1696. }
  1697. LLUICtrl::draw();
  1698. }
  1699. bool LLTextureCtrl::allowDrop(LLInventoryItem* item)
  1700. {
  1701. const LLPermissions& perms = item->getPermissions();
  1702. PermissionMask item_perm_mask = 0;
  1703. if (perms.allowCopyBy(gAgentID))
  1704. {
  1705. item_perm_mask = PERM_COPY;
  1706. }
  1707. if (perms.allowModifyBy(gAgentID))
  1708. {
  1709. item_perm_mask |= PERM_MODIFY;
  1710. }
  1711. if (perms.allowTransferBy(gAgentID))
  1712. {
  1713. item_perm_mask |= PERM_TRANSFER;
  1714. }
  1715. // Never allow to apply no-copy textures by dropping them: the drop code
  1716. // would delete the texture from the inventory... HB
  1717. PermissionMask filter_perm_mask = PERM_COPY;
  1718. filter_perm_mask |= mCanApplyImmediately ? mImmediateFilterPermMask
  1719. : mNonImmediateFilterPermMask;
  1720. if ((item_perm_mask & filter_perm_mask) != filter_perm_mask)
  1721. {
  1722. return false;
  1723. }
  1724. if (!mDragCallback)
  1725. {
  1726. return true;
  1727. }
  1728. return mDragCallback(this, item, mCallbackUserData);
  1729. }
  1730. bool LLTextureCtrl::doDrop(LLInventoryItem* item)
  1731. {
  1732. if (!mDropCallback)
  1733. {
  1734. // No callback installed, so just set the image ids and carry on.
  1735. setImageAssetID(item->getAssetUUID());
  1736. mImageItemID = item->getUUID();
  1737. return true;
  1738. }
  1739. // Call callback; if it returns true, we return true, and therefore the
  1740. // commit is called above.
  1741. return mDropCallback(this, item, mCallbackUserData);
  1742. }
  1743. //virtual
  1744. bool LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
  1745. {
  1746. if (uni_char == ' ')
  1747. {
  1748. showPicker(true);
  1749. return true;
  1750. }
  1751. return LLUICtrl::handleUnicodeCharHere(uni_char);
  1752. }
  1753. //virtual
  1754. void LLTextureCtrl::setValue(const LLSD& value)
  1755. {
  1756. setImageAssetID(value.asUUID());
  1757. }
  1758. //virtual
  1759. LLSD LLTextureCtrl::getValue() const
  1760. {
  1761. return LLSD(getImageAssetID());
  1762. }