llfloatersnapshot.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:68k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfloatersnapshot.cpp
  3.  * @brief Snapshot preview window, allowing saving, e-mailing, etc.
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llfloatersnapshot.h"
  34. #include "llfloaterreg.h"
  35. // Viewer includes
  36. #include "llagent.h"
  37. #include "llcallbacklist.h"
  38. #include "llcriticaldamp.h"
  39. #include "llui.h"
  40. #include "llfocusmgr.h"
  41. #include "llbutton.h"
  42. #include "llcombobox.h"
  43. #include "lleconomy.h"
  44. #include "llsliderctrl.h"
  45. #include "llspinctrl.h"
  46. #include "llviewercontrol.h"
  47. #include "lluictrlfactory.h"
  48. #include "llviewerstats.h"
  49. #include "llviewercamera.h"
  50. #include "llviewerwindow.h"
  51. #include "llviewermenufile.h" // upload_new_resource()
  52. #include "llfloaterpostcard.h"
  53. #include "llcheckboxctrl.h"
  54. #include "llradiogroup.h"
  55. #include "lltoolfocus.h"
  56. #include "lltoolmgr.h"
  57. #include "llworld.h"
  58. #include "llagentui.h"
  59. // Linden library includes
  60. #include "llfontgl.h"
  61. #include "llsys.h"
  62. #include "llrender.h"
  63. #include "v3dmath.h"
  64. #include "llmath.h"
  65. #include "lldir.h"
  66. #include "llsdserialize.h"
  67. #include "llgl.h"
  68. #include "llglheaders.h"
  69. #include "llimagejpeg.h"
  70. #include "llimagepng.h"
  71. #include "llimagebmp.h"
  72. #include "llimagej2c.h"
  73. #include "lllocalcliprect.h"
  74. #include "llnotificationsutil.h"
  75. #include "llresmgr.h" // LLLocale
  76. #include "llvfile.h"
  77. #include "llvfs.h"
  78. #include "llwindow.h"
  79. ///----------------------------------------------------------------------------
  80. /// Local function declarations, constants, enums, and typedefs
  81. ///----------------------------------------------------------------------------
  82. S32 LLFloaterSnapshot::sUIWinHeightLong = 526 ;
  83. S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 230 ;
  84. S32 LLFloaterSnapshot::sUIWinWidth = 215 ;
  85. LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
  86. const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
  87. F32 SHINE_TIME = 0.5f;
  88. F32 SHINE_WIDTH = 0.6f;
  89. F32 SHINE_OPACITY = 0.3f;
  90. F32 FALL_TIME = 0.6f;
  91. S32 BORDER_WIDTH = 6;
  92. const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
  93. const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
  94. static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
  95. ///----------------------------------------------------------------------------
  96. /// Class LLSnapshotLivePreview 
  97. ///----------------------------------------------------------------------------
  98. class LLSnapshotLivePreview : public LLView
  99. {
  100. public:
  101. enum ESnapshotType
  102. {
  103. SNAPSHOT_POSTCARD,
  104. SNAPSHOT_TEXTURE,
  105. SNAPSHOT_LOCAL
  106. };
  107. struct Params : public LLInitParam::Block<Params, LLView::Params>
  108. {
  109. Params()
  110. {
  111. name = "snapshot_live_preview";
  112. mouse_opaque = false;
  113. }
  114. };
  115. LLSnapshotLivePreview(const LLSnapshotLivePreview::Params& p);
  116. ~LLSnapshotLivePreview();
  117. /*virtual*/ void draw();
  118. /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
  119. void setSize(S32 w, S32 h);
  120. void getSize(S32& w, S32& h) const;
  121. S32 getDataSize() const { return mDataSize; }
  122. void setMaxImageSize(S32 size) ;
  123. S32  getMaxImageSize() {return mMaxImageSize ;}
  124. ESnapshotType getSnapshotType() const { return mSnapshotType; }
  125. LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
  126. BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
  127. BOOL isSnapshotActive() { return mSnapshotActive; }
  128. LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
  129. S32  getThumbnailWidth() const { return mThumbnailWidth ; }
  130. S32  getThumbnailHeight() const { return mThumbnailHeight ; }
  131. BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
  132. BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
  133. LLViewerTexture* getCurrentImage();
  134. F32 getImageAspect();
  135. F32 getAspect() ;
  136. LLRect getImageRect();
  137. BOOL isImageScaled();
  138. void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
  139. void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
  140. void setSnapshotQuality(S32 quality);
  141. void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
  142. void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
  143. LLFloaterPostcard* savePostcard();
  144. void saveTexture();
  145. BOOL saveLocal();
  146. BOOL setThumbnailImageSize() ;
  147. void generateThumbnailImage(BOOL force_update = FALSE) ;
  148. void resetThumbnailImage() { mThumbnailImage = NULL ; }
  149. void drawPreviewRect(S32 offset_x, S32 offset_y) ;
  150. // Returns TRUE when snapshot generated, FALSE otherwise.
  151. static BOOL onIdle( void* snapshot_preview );
  152. private:
  153. LLColor4 mColor;
  154. LLPointer<LLViewerTexture> mViewerImage[2]; //used to represent the scene when the frame is frozen.
  155. LLRect mImageRect[2];
  156. S32 mWidth[2];
  157. S32 mHeight[2];
  158. BOOL mImageScaled[2];
  159. S32                         mMaxImageSize ;
  160. //thumbnail image
  161. LLPointer<LLViewerTexture> mThumbnailImage ;
  162. S32                         mThumbnailWidth ;
  163. S32                         mThumbnailHeight ;
  164. LLRect                      mPreviewRect ;
  165. BOOL                        mThumbnailUpdateLock ;
  166. BOOL                        mThumbnailUpToDate ;
  167. S32 mCurImageIndex;
  168. LLPointer<LLImageRaw> mPreviewImage;
  169. LLPointer<LLImageRaw> mPreviewImageEncoded;
  170. LLPointer<LLImageFormatted> mFormattedImage;
  171. LLFrameTimer mSnapshotDelayTimer;
  172. S32 mShineCountdown;
  173. LLFrameTimer mShineAnimTimer;
  174. F32 mFlashAlpha;
  175. BOOL mNeedsFlash;
  176. LLVector3d mPosTakenGlobal;
  177. S32 mSnapshotQuality;
  178. S32 mDataSize;
  179. ESnapshotType mSnapshotType;
  180. LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat;
  181. BOOL mSnapshotUpToDate;
  182. LLFrameTimer mFallAnimTimer;
  183. LLVector3 mCameraPos;
  184. LLQuaternion mCameraRot;
  185. BOOL mSnapshotActive;
  186. LLViewerWindow::ESnapshotType mSnapshotBufferType;
  187. public:
  188. static std::set<LLSnapshotLivePreview*> sList;
  189. BOOL                        mKeepAspectRatio ;
  190. };
  191. std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
  192. LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p) 
  193. : LLView(p),
  194. mColor(1.f, 0.f, 0.f, 0.5f), 
  195. mCurImageIndex(0),
  196. mPreviewImage(NULL),
  197. mThumbnailImage(NULL) ,
  198. mThumbnailWidth(0),
  199. mThumbnailHeight(0),
  200. mPreviewImageEncoded(NULL),
  201. mFormattedImage(NULL),
  202. mShineCountdown(0),
  203. mFlashAlpha(0.f),
  204. mNeedsFlash(TRUE),
  205. mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
  206. mDataSize(0),
  207. mSnapshotType(SNAPSHOT_POSTCARD),
  208. mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
  209. mSnapshotUpToDate(FALSE),
  210. mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
  211. mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
  212. mSnapshotActive(FALSE),
  213. mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR)
  214. {
  215. setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
  216. mSnapshotDelayTimer.setTimerExpirySec(0.0f);
  217. mSnapshotDelayTimer.start();
  218. //  gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
  219. sList.insert(this);
  220. setFollowsAll();
  221. mWidth[0] = gViewerWindow->getWindowWidthRaw();
  222. mWidth[1] = gViewerWindow->getWindowWidthRaw();
  223. mHeight[0] = gViewerWindow->getWindowHeightRaw();
  224. mHeight[1] = gViewerWindow->getWindowHeightRaw();
  225. mImageScaled[0] = FALSE;
  226. mImageScaled[1] = FALSE;
  227. mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
  228. mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
  229. mThumbnailUpdateLock = FALSE ;
  230. mThumbnailUpToDate   = FALSE ;
  231. }
  232. LLSnapshotLivePreview::~LLSnapshotLivePreview()
  233. {
  234. // delete images
  235. mPreviewImage = NULL;
  236. mPreviewImageEncoded = NULL;
  237. mFormattedImage = NULL;
  238. //  gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
  239. sList.erase(this);
  240. }
  241. void LLSnapshotLivePreview::setMaxImageSize(S32 size) 
  242. {
  243. if(size < MAX_SNAPSHOT_IMAGE_SIZE)
  244. {
  245. mMaxImageSize = size;
  246. }
  247. else
  248. {
  249. mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
  250. }
  251. }
  252. LLViewerTexture* LLSnapshotLivePreview::getCurrentImage()
  253. {
  254. return mViewerImage[mCurImageIndex];
  255. }
  256. F32 LLSnapshotLivePreview::getAspect()
  257. {
  258. F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
  259. F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
  260. if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
  261. {
  262. return image_aspect_ratio;
  263. }
  264. else
  265. {
  266. return window_aspect_ratio;
  267. }
  268. }
  269. F32 LLSnapshotLivePreview::getImageAspect()
  270. {
  271. if (!mViewerImage[mCurImageIndex])
  272. {
  273. return 0.f;
  274. }
  275. return getAspect() ;
  276. }
  277. LLRect LLSnapshotLivePreview::getImageRect()
  278. {
  279. return mImageRect[mCurImageIndex];
  280. }
  281. BOOL LLSnapshotLivePreview::isImageScaled()
  282. {
  283. return mImageScaled[mCurImageIndex];
  284. }
  285. void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) 
  286. if (mSnapshotUpToDate)
  287. {
  288. S32 old_image_index = mCurImageIndex;
  289. mCurImageIndex = (mCurImageIndex + 1) % 2; 
  290. mWidth[mCurImageIndex] = mWidth[old_image_index];
  291. mHeight[mCurImageIndex] = mHeight[old_image_index];
  292. mFallAnimTimer.start();
  293. }
  294. mSnapshotUpToDate = FALSE; 
  295. LLRect& rect = mImageRect[mCurImageIndex];
  296. rect.set(0, getRect().getHeight(), getRect().getWidth(), 0);
  297. F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
  298. F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
  299. if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
  300. {
  301. if (image_aspect_ratio > window_aspect_ratio)
  302. {
  303. // trim off top and bottom
  304. S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio); 
  305. rect.mBottom += (getRect().getHeight() - new_height) / 2;
  306. rect.mTop -= (getRect().getHeight() - new_height) / 2;
  307. }
  308. else if (image_aspect_ratio < window_aspect_ratio)
  309. {
  310. // trim off left and right
  311. S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio); 
  312. rect.mLeft += (getRect().getWidth() - new_width) / 2;
  313. rect.mRight -= (getRect().getWidth() - new_width) / 2;
  314. }
  315. }
  316. mShineAnimTimer.stop();
  317. if (new_snapshot)
  318. {
  319. mSnapshotDelayTimer.start();
  320. mSnapshotDelayTimer.setTimerExpirySec(delay);
  321. }
  322. if(new_thumbnail)
  323. {
  324. mThumbnailUpToDate = FALSE ;
  325. }
  326. setThumbnailImageSize();
  327. }
  328. void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
  329. {
  330. llclamp(quality, 0, 100);
  331. if (quality != mSnapshotQuality)
  332. {
  333. mSnapshotQuality = quality;
  334. gSavedSettings.setS32("SnapshotQuality", quality);
  335. mSnapshotUpToDate = FALSE;
  336. }
  337. }
  338. void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
  339. {
  340. F32 line_width ; 
  341. glGetFloatv(GL_LINE_WIDTH, &line_width) ;
  342. glLineWidth(2.0f * line_width) ;
  343. LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
  344. gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
  345. mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
  346. glLineWidth(line_width) ;
  347. //draw four alpha rectangles to cover areas outside of the snapshot image
  348. if(!mKeepAspectRatio)
  349. {
  350. LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
  351. S32 dwl = 0, dwr = 0 ;
  352. if(mThumbnailWidth > mPreviewRect.getWidth())
  353. {
  354. dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ;
  355. dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
  356. gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
  357. mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
  358. gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
  359. mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
  360. }
  361. if(mThumbnailHeight > mPreviewRect.getHeight())
  362. {
  363. S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
  364. gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
  365. mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
  366. dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
  367. gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
  368. mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
  369. }
  370. }
  371. }
  372. //called when the frame is frozen.
  373. void LLSnapshotLivePreview::draw()
  374. {
  375. if (mViewerImage[mCurImageIndex].notNull() &&
  376.     mPreviewImageEncoded.notNull() &&
  377.     mSnapshotUpToDate)
  378. {
  379. LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
  380. gl_rect_2d(getRect(), bg_color);
  381. LLRect &rect = mImageRect[mCurImageIndex];
  382. LLRect shadow_rect = mImageRect[mCurImageIndex];
  383. shadow_rect.stretch(BORDER_WIDTH);
  384. gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10);
  385. LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
  386. gGL.color4fv(image_color.mV);
  387. gGL.getTexUnit(0)->bind(mViewerImage[mCurImageIndex]);
  388. // calculate UV scale
  389. F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f);
  390. F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f);
  391. glPushMatrix();
  392. {
  393. glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
  394. gGL.begin(LLRender::QUADS);
  395. {
  396. gGL.texCoord2f(uv_width, uv_height);
  397. gGL.vertex2i(rect.getWidth(), rect.getHeight() );
  398. gGL.texCoord2f(0.f, uv_height);
  399. gGL.vertex2i(0, rect.getHeight() );
  400. gGL.texCoord2f(0.f, 0.f);
  401. gGL.vertex2i(0, 0);
  402. gGL.texCoord2f(uv_width, 0.f);
  403. gGL.vertex2i(rect.getWidth(), 0);
  404. }
  405. gGL.end();
  406. }
  407. glPopMatrix();
  408. gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
  409. gl_rect_2d(getRect());
  410. if (mNeedsFlash)
  411. {
  412. if (mFlashAlpha < 1.f)
  413. {
  414. mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
  415. }
  416. else
  417. {
  418. mNeedsFlash = FALSE;
  419. }
  420. }
  421. else
  422. {
  423. mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
  424. }
  425. if (mShineCountdown > 0)
  426. {
  427. mShineCountdown--;
  428. if (mShineCountdown == 0)
  429. {
  430. mShineAnimTimer.start();
  431. }
  432. }
  433. else if (mShineAnimTimer.getStarted())
  434. {
  435. F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
  436. // draw "shine" effect
  437. LLLocalClipRect clip(getLocalRect());
  438. {
  439. // draw diagonal stripe with gradient that passes over screen
  440. S32 x1 = gViewerWindow->getWindowWidthScaled() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
  441. S32 x2 = x1 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
  442. S32 x3 = x2 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
  443. S32 y1 = 0;
  444. S32 y2 = gViewerWindow->getWindowHeightScaled();
  445. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  446. gGL.begin(LLRender::QUADS);
  447. {
  448. gGL.color4f(1.f, 1.f, 1.f, 0.f);
  449. gGL.vertex2i(x1, y1);
  450. gGL.vertex2i(x1 + gViewerWindow->getWindowWidthScaled(), y2);
  451. gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
  452. gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
  453. gGL.vertex2i(x2, y1);
  454. gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
  455. gGL.vertex2i(x2, y1);
  456. gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
  457. gGL.color4f(1.f, 1.f, 1.f, 0.f);
  458. gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2);
  459. gGL.vertex2i(x3, y1);
  460. }
  461. gGL.end();
  462. }
  463. // if we're at the end of the animation, stop
  464. if (shine_interp >= 1.f)
  465. {
  466. mShineAnimTimer.stop();
  467. }
  468. }
  469. }
  470. // draw framing rectangle
  471. {
  472. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  473. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  474. LLRect outline_rect = mImageRect[mCurImageIndex];
  475. gGL.begin(LLRender::QUADS);
  476. {
  477. gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
  478. gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
  479. gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
  480. gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
  481. gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
  482. gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
  483. gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
  484. gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
  485. gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
  486. gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
  487. gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
  488. gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
  489. gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
  490. gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
  491. gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
  492. gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
  493. }
  494. gGL.end();
  495. }
  496. // draw old image dropping away
  497. if (mFallAnimTimer.getStarted())
  498. {
  499. S32 old_image_index = (mCurImageIndex + 1) % 2;
  500. if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
  501. {
  502. F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
  503. F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
  504. LLColor4 image_color(1.f, 1.f, 1.f, alpha);
  505. gGL.color4fv(image_color.mV);
  506. gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]);
  507. // calculate UV scale
  508. // *FIX get this to work with old image
  509. BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
  510. F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
  511. F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
  512. glPushMatrix();
  513. {
  514. LLRect& rect = mImageRect[old_image_index];
  515. glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
  516. glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
  517. gGL.begin(LLRender::QUADS);
  518. {
  519. gGL.texCoord2f(uv_width, uv_height);
  520. gGL.vertex2i(rect.getWidth(), rect.getHeight() );
  521. gGL.texCoord2f(0.f, uv_height);
  522. gGL.vertex2i(0, rect.getHeight() );
  523. gGL.texCoord2f(0.f, 0.f);
  524. gGL.vertex2i(0, 0);
  525. gGL.texCoord2f(uv_width, 0.f);
  526. gGL.vertex2i(rect.getWidth(), 0);
  527. }
  528. gGL.end();
  529. }
  530. glPopMatrix();
  531. }
  532. }
  533. }
  534. /*virtual*/ 
  535. void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent)
  536. {
  537. LLRect old_rect = getRect();
  538. LLView::reshape(width, height, called_from_parent);
  539. if (old_rect.getWidth() != width || old_rect.getHeight() != height)
  540. {
  541. updateSnapshot(FALSE, TRUE);
  542. }
  543. }
  544. BOOL LLSnapshotLivePreview::setThumbnailImageSize()
  545. {
  546. if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10)
  547. {
  548. return FALSE ;
  549. }
  550. S32 window_width = gViewerWindow->getWindowWidthRaw() ;
  551. S32 window_height = gViewerWindow->getWindowHeightRaw() ;
  552. F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height);
  553. // UI size for thumbnail
  554. S32 max_width = LLFloaterSnapshot::getUIWinWidth() - 20;
  555. S32 max_height = 90;
  556. if (window_aspect_ratio > (F32)max_width / max_height)
  557. {
  558. // image too wide, shrink to width
  559. mThumbnailWidth = max_width;
  560. mThumbnailHeight = llround((F32)max_width / window_aspect_ratio);
  561. }
  562. else
  563. {
  564. // image too tall, shrink to height
  565. mThumbnailHeight = max_height;
  566. mThumbnailWidth = llround((F32)max_height * window_aspect_ratio);
  567. }
  568. if(mThumbnailWidth > window_width || mThumbnailHeight > window_height)
  569. {
  570. return FALSE ;//if the window is too small, ignore thumbnail updating.
  571. }
  572. S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ;
  573. if(!mKeepAspectRatio)
  574. {
  575. F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ;
  576. F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ;
  577. //if(mWidth[mCurImageIndex] > window_width ||
  578. // mHeight[mCurImageIndex] > window_height )
  579. {
  580. if(ratio_x > ratio_y)
  581. {
  582. top = (S32)(top * ratio_y / ratio_x) ;
  583. }
  584. else
  585. {
  586. right = (S32)(right * ratio_x / ratio_y) ;
  587. }
  588. }
  589. //else
  590. //{
  591. // right = (S32)(right * ratio_x) ;
  592. // top = (S32)(top * ratio_y) ;
  593. //}
  594. left = (S32)((mThumbnailWidth - right) * 0.5f) ;
  595. bottom = (S32)((mThumbnailHeight - top) * 0.5f) ;
  596. top += bottom ;
  597. right += left ;
  598. }
  599. mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ;
  600. return TRUE ;
  601. }
  602. void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
  603. {
  604. if(mThumbnailUpdateLock) //in the process of updating
  605. {
  606. return ;
  607. }
  608. if(mThumbnailUpToDate && !force_update)//already updated
  609. {
  610. return ;
  611. }
  612. if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10)
  613. {
  614. return ;
  615. }
  616. ////lock updating
  617. mThumbnailUpdateLock = TRUE ;
  618. if(!setThumbnailImageSize())
  619. {
  620. mThumbnailUpdateLock = FALSE ;
  621. mThumbnailUpToDate = TRUE ;
  622. return ;
  623. }
  624. if(mThumbnailImage)
  625. {
  626. resetThumbnailImage() ;
  627. }
  628. LLPointer<LLImageRaw> raw = NULL ;
  629. S32 w , h ;
  630. w = get_lower_power_two(mThumbnailWidth, 512) * 2 ;
  631. h = get_lower_power_two(mThumbnailHeight, 512) * 2 ;
  632. {
  633. raw = new LLImageRaw ;
  634. if(!gViewerWindow->thumbnailSnapshot(raw,
  635. w, h,
  636. gSavedSettings.getBOOL("RenderUIInSnapshot"),
  637. FALSE,
  638. mSnapshotBufferType) )
  639. {
  640. raw = NULL ;
  641. }
  642. }
  643. if(raw)
  644. {
  645. mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); 
  646. mThumbnailUpToDate = TRUE ;
  647. }
  648. //unlock updating
  649. mThumbnailUpdateLock = FALSE ;
  650. }
  651. // Called often. Checks whether it's time to grab a new snapshot and if so, does it.
  652. // Returns TRUE if new snapshot generated, FALSE otherwise.
  653. //static 
  654. BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
  655. {
  656. LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
  657. LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();
  658. LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion();
  659. if (gSavedSettings.getBOOL("FreezeTime") && 
  660. (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))
  661. {
  662. previewp->mCameraPos = new_camera_pos;
  663. previewp->mCameraRot = new_camera_rot;
  664. // request a new snapshot whenever the camera moves, with a time delay
  665. BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
  666. previewp->updateSnapshot(
  667. autosnap, // whether a new snapshot is needed or merely invalidate the existing one
  668. FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
  669. autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true.
  670. }
  671. // see if it's time yet to snap the shot and bomb out otherwise.
  672. previewp->mSnapshotActive = 
  673. (previewp->mSnapshotDelayTimer.getStarted() && previewp->mSnapshotDelayTimer.hasExpired())
  674. && !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
  675. if ( ! previewp->mSnapshotActive)
  676. {
  677. return FALSE;
  678. }
  679. // time to produce a snapshot
  680. if (!previewp->mPreviewImage)
  681. {
  682. previewp->mPreviewImage = new LLImageRaw;
  683. }
  684. if (!previewp->mPreviewImageEncoded)
  685. {
  686. previewp->mPreviewImageEncoded = new LLImageRaw;
  687. }
  688. previewp->setVisible(FALSE);
  689. previewp->setEnabled(FALSE);
  690. previewp->getWindow()->incBusyCount();
  691. previewp->mImageScaled[previewp->mCurImageIndex] = FALSE;
  692. // grab the raw image and encode it into desired format
  693. if(gViewerWindow->rawSnapshot(
  694. previewp->mPreviewImage,
  695. previewp->mWidth[previewp->mCurImageIndex],
  696. previewp->mHeight[previewp->mCurImageIndex],
  697. previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
  698. previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
  699. gSavedSettings.getBOOL("RenderUIInSnapshot"),
  700. FALSE,
  701. previewp->mSnapshotBufferType,
  702. previewp->getMaxImageSize()))
  703. {
  704. previewp->mPreviewImageEncoded->resize(
  705. previewp->mPreviewImage->getWidth(), 
  706. previewp->mPreviewImage->getHeight(), 
  707. previewp->mPreviewImage->getComponents());
  708. if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
  709. {
  710. LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
  711. LLPointer<LLImageRaw> scaled = new LLImageRaw(
  712. previewp->mPreviewImage->getData(),
  713. previewp->mPreviewImage->getWidth(),
  714. previewp->mPreviewImage->getHeight(),
  715. previewp->mPreviewImage->getComponents());
  716. scaled->biasedScaleToPowerOfTwo(512);
  717. previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
  718. if (formatted->encode(scaled, 0.f))
  719. {
  720. previewp->mDataSize = formatted->getDataSize();
  721. formatted->decode(previewp->mPreviewImageEncoded, 0);
  722. }
  723. }
  724. else
  725. {
  726. // delete any existing image
  727. previewp->mFormattedImage = NULL;
  728. // now create the new one of the appropriate format.
  729. // note: postcards hardcoded to use jpeg always.
  730. LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotType() == SNAPSHOT_POSTCARD
  731. ? LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG : previewp->getSnapshotFormat();
  732. switch(format)
  733. {
  734. case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
  735. previewp->mFormattedImage = new LLImagePNG(); 
  736. break;
  737. case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
  738. previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality); 
  739. break;
  740. case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
  741. previewp->mFormattedImage = new LLImageBMP(); 
  742. break;
  743. }
  744. if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
  745. {
  746. previewp->mDataSize = previewp->mFormattedImage->getDataSize();
  747. // special case BMP to copy instead of decode otherwise decode will crash.
  748. if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
  749. {
  750. previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
  751. }
  752. else
  753. {
  754. previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
  755. }
  756. }
  757. }
  758. LLPointer<LLImageRaw> scaled = new LLImageRaw(
  759. previewp->mPreviewImageEncoded->getData(),
  760. previewp->mPreviewImageEncoded->getWidth(),
  761. previewp->mPreviewImageEncoded->getHeight(),
  762. previewp->mPreviewImageEncoded->getComponents());
  763. if(!scaled->isBufferInvalid())
  764. {
  765. // leave original image dimensions, just scale up texture buffer
  766. if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
  767. {
  768. // go ahead and shrink image to appropriate power of 2 for display
  769. scaled->biasedScaleToPowerOfTwo(1024);
  770. previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
  771. }
  772. else
  773. {
  774. // expand image but keep original image data intact
  775. scaled->expandToPowerOfTwo(1024, FALSE);
  776. }
  777. previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
  778. LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
  779. gGL.getTexUnit(0)->bind(curr_preview_image);
  780. if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE)
  781. {
  782. curr_preview_image->setFilteringOption(LLTexUnit::TFO_POINT);
  783. }
  784. else
  785. {
  786. curr_preview_image->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
  787. }
  788. curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
  789. previewp->mSnapshotUpToDate = TRUE;
  790. previewp->generateThumbnailImage(TRUE) ;
  791. previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
  792. previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
  793. }
  794. }
  795. previewp->getWindow()->decBusyCount();
  796. // only show fullscreen preview when in freeze frame mode
  797. previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
  798. previewp->mSnapshotDelayTimer.stop();
  799. previewp->mSnapshotActive = FALSE;
  800. if(!previewp->getThumbnailUpToDate())
  801. {
  802. previewp->generateThumbnailImage() ;
  803. }
  804. return TRUE;
  805. }
  806. void LLSnapshotLivePreview::setSize(S32 w, S32 h)
  807. {
  808. mWidth[mCurImageIndex] = w;
  809. mHeight[mCurImageIndex] = h;
  810. }
  811. void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
  812. {
  813. w = mWidth[mCurImageIndex];
  814. h = mHeight[mCurImageIndex];
  815. }
  816. LLFloaterPostcard* LLSnapshotLivePreview::savePostcard()
  817. {
  818. if(mViewerImage[mCurImageIndex].isNull())
  819. {
  820. //this should never happen!!
  821. llwarns << "The snapshot image has not been generated!" << llendl ;
  822. return NULL ;
  823. }
  824. // calculate and pass in image scale in case image data only use portion
  825. // of viewerimage buffer
  826. LLVector2 image_scale(1.f, 1.f);
  827. if (!isImageScaled())
  828. {
  829. image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight()));
  830. }
  831. LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
  832. if(!jpg)
  833. {
  834. llwarns << "Formatted image not a JPEG" << llendl;
  835. return NULL;
  836. }
  837. LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);
  838. // relinquish lifetime of jpeg image to postcard floater
  839. mFormattedImage = NULL;
  840. mDataSize = 0;
  841. updateSnapshot(FALSE, FALSE);
  842. return floater;
  843. }
  844. void LLSnapshotLivePreview::saveTexture()
  845. {
  846. // gen a new uuid for this asset
  847. LLTransactionID tid;
  848. tid.generate();
  849. LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  850. LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
  851. LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
  852.   mPreviewImage->getWidth(),
  853.   mPreviewImage->getHeight(),
  854.   mPreviewImage->getComponents());
  855. scaled->biasedScaleToPowerOfTwo(512);
  856. if (formatted->encode(scaled, 0.0f))
  857. {
  858. LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
  859. std::string pos_string;
  860. LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
  861. std::string who_took_it;
  862. LLAgentUI::buildFullname(who_took_it);
  863. LLAssetStorage::LLStoreAssetCallback callback = NULL;
  864. S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
  865. void *userdata = NULL;
  866. upload_new_resource(tid, // tid
  867.     LLAssetType::AT_TEXTURE,
  868.     "Snapshot : " + pos_string,
  869.     "Taken by " + who_took_it + " at " + pos_string,
  870.     0,
  871.     LLFolderType::FT_SNAPSHOT_CATEGORY,
  872.     LLInventoryType::IT_SNAPSHOT,
  873.     PERM_ALL,  // Note: Snapshots to inventory is a special case of content upload
  874.     PERM_NONE, // that ignores the user's premissions preferences and continues to
  875.     PERM_NONE, // always use these fairly permissive hard-coded initial perms. - MG
  876.     "Snapshot : " + pos_string,
  877.     callback, expected_upload_cost, userdata);
  878. gViewerWindow->playSnapshotAnimAndSound();
  879. }
  880. else
  881. {
  882. LLNotificationsUtil::add("ErrorEncodingSnapshot");
  883. llwarns << "Error encoding snapshot" << llendl;
  884. }
  885. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
  886. mDataSize = 0;
  887. }
  888. BOOL LLSnapshotLivePreview::saveLocal()
  889. {
  890. BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
  891. // Relinquish image memory. Save button will be disabled as a side-effect.
  892. mFormattedImage = NULL;
  893. mDataSize = 0;
  894. updateSnapshot(FALSE, FALSE);
  895. if(success)
  896. {
  897. gViewerWindow->playSnapshotAnimAndSound();
  898. }
  899. return success;
  900. }
  901. ///----------------------------------------------------------------------------
  902. /// Class LLFloaterSnapshot::Impl
  903. ///----------------------------------------------------------------------------
  904. class LLFloaterSnapshot::Impl
  905. {
  906. public:
  907. Impl()
  908. : mAvatarPauseHandles(),
  909. mLastToolset(NULL),
  910. mAspectRatioCheckOff(false)
  911. {
  912. }
  913. ~Impl()
  914. {
  915. //unpause avatars
  916. mAvatarPauseHandles.clear();
  917. }
  918. static void onClickDiscard(void* data);
  919. static void onClickKeep(void* data);
  920. static void onCommitSave(LLUICtrl* ctrl, void* data);
  921. static void onClickNewSnapshot(void* data);
  922. static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
  923. //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
  924. static void onClickLess(void* data) ;
  925. static void onClickMore(void* data) ;
  926. static void onClickUICheck(LLUICtrl *ctrl, void* data);
  927. static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
  928. static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data);
  929. static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data);
  930. static void onCommitQuality(LLUICtrl* ctrl, void* data);
  931. static void onCommitResolution(LLUICtrl* ctrl, void* data) { updateResolution(ctrl, data); }
  932. static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
  933. static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
  934. static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
  935. static void onCommitSnapshotType(LLUICtrl* ctrl, void* data);
  936. static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data);
  937. static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);
  938. static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;
  939. static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
  940. static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater);
  941. static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);
  942. static void updateControls(LLFloaterSnapshot* floater);
  943. static void updateLayout(LLFloaterSnapshot* floater);
  944. static void updateResolutionTextEntry(LLFloaterSnapshot* floater);
  945. private:
  946. static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater);
  947. static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater);
  948. static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);
  949. static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);
  950. static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
  951. static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ;
  952. public:
  953. std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
  954. LLToolset* mLastToolset;
  955. LLHandle<LLView> mPreviewHandle;
  956. bool mAspectRatioCheckOff ;
  957. };
  958. // static
  959. LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
  960. {
  961. LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get();
  962. return previewp;
  963. }
  964. // static
  965. LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFloaterSnapshot* floater)
  966. {
  967. LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
  968. LLSD value = floater->childGetValue("snapshot_type_radio");
  969. const std::string id = value.asString();
  970. if (id == "postcard")
  971. index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
  972. else if (id == "texture")
  973. index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
  974. else if (id == "local")
  975. index = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
  976. return index;
  977. }
  978. // static
  979. LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFloaterSnapshot* floater)
  980. {
  981. ESnapshotFormat index = SNAPSHOT_FORMAT_PNG;
  982. if(floater->hasChild("local_format_combo"))
  983. {
  984. LLComboBox* local_format_combo = floater->findChild<LLComboBox>("local_format_combo");
  985. const std::string id  = local_format_combo->getSelectedItemLabel();
  986. if (id == "PNG")
  987. index = SNAPSHOT_FORMAT_PNG;
  988. else if (id == "JPEG")
  989. index = SNAPSHOT_FORMAT_JPEG;
  990. else if (id == "BMP")
  991. index = SNAPSHOT_FORMAT_BMP;
  992. }
  993. return index;
  994. }
  995. // static
  996. LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)
  997. {
  998. LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
  999. LLSD value = floater->childGetValue("layer_types");
  1000. const std::string id = value.asString();
  1001. if (id == "colors")
  1002. type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
  1003. else if (id == "depth")
  1004. type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH;
  1005. else if (id == "objects")
  1006. type = LLViewerWindow::SNAPSHOT_TYPE_OBJECT_ID;
  1007. return type;
  1008. }
  1009. // static
  1010. void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname)
  1011. {
  1012. LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
  1013. combo->setVisible(TRUE);
  1014. updateResolution(combo, floater, FALSE); // to sync spinners with combo
  1015. }
  1016. //static 
  1017. void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
  1018. {
  1019. LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
  1020. S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ;
  1021. if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution
  1022. {
  1023. previewp->mKeepAspectRatio = TRUE;
  1024. floaterp->getChild<LLComboBox>("postcard_size_combo")->setCurrentByIndex(0);
  1025. gSavedSettings.setS32("SnapshotPostcardLastResolution", 0);
  1026. floaterp->getChild<LLComboBox>("texture_size_combo")->setCurrentByIndex(0);
  1027. gSavedSettings.setS32("SnapshotTextureLastResolution", 0);
  1028. floaterp->getChild<LLComboBox>("local_size_combo")->setCurrentByIndex(0);
  1029. gSavedSettings.setS32("SnapshotLocalLastResolution", 0);
  1030. LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
  1031. previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
  1032. }
  1033. bool use_freeze_frame = floaterp->childGetValue("freeze_frame_check").asBoolean();
  1034. if (use_freeze_frame)
  1035. {
  1036. // stop all mouse events at fullscreen preview layer
  1037. floaterp->getParent()->setMouseOpaque(TRUE);
  1038. // shrink to smaller layout
  1039. floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height);
  1040. // can see and interact with fullscreen preview now
  1041. if (previewp)
  1042. {
  1043. previewp->setVisible(TRUE);
  1044. previewp->setEnabled(TRUE);
  1045. }
  1046. //RN: freeze all avatars
  1047. LLCharacter* avatarp;
  1048. for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
  1049. iter != LLCharacter::sInstances.end(); ++iter)
  1050. {
  1051. avatarp = *iter;
  1052. floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
  1053. }
  1054. // freeze everything else
  1055. gSavedSettings.setBOOL("FreezeTime", TRUE);
  1056. if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
  1057. {
  1058. floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
  1059. LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
  1060. }
  1061. }
  1062. else // turning off freeze frame mode
  1063. {
  1064. floaterp->getParent()->setMouseOpaque(FALSE);
  1065. floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height);
  1066. if (previewp)
  1067. {
  1068. previewp->setVisible(FALSE);
  1069. previewp->setEnabled(FALSE);
  1070. }
  1071. //RN: thaw all avatars
  1072. floaterp->impl.mAvatarPauseHandles.clear();
  1073. // thaw everything else
  1074. gSavedSettings.setBOOL("FreezeTime", FALSE);
  1075. // restore last tool (e.g. pie menu, etc)
  1076. if (floaterp->impl.mLastToolset)
  1077. {
  1078. LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset);
  1079. }
  1080. }
  1081. }
  1082. // This is the main function that keeps all the GUI controls in sync with the saved settings.
  1083. // It should be called anytime a setting is changed that could affect the controls.
  1084. // No other methods should be changing any of the controls directly except for helpers called by this method.
  1085. // The basic pattern for programmatically changing the GUI settings is to first set the
  1086. // appropriate saved settings and then call this method to sync the GUI with them.
  1087. // static
  1088. void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
  1089. {
  1090. LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio");
  1091. snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType"));
  1092. LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater);
  1093. ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater); LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
  1094. LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
  1095. floater->childSetVisible("postcard_size_combo", FALSE);
  1096. floater->childSetVisible("texture_size_combo", FALSE);
  1097. floater->childSetVisible("local_size_combo", FALSE);
  1098. floater->getChild<LLComboBox>("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
  1099. floater->getChild<LLComboBox>("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
  1100. floater->getChild<LLComboBox>("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
  1101. floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
  1102. floater->childSetVisible("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE);
  1103. floater->childSetVisible("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
  1104. floater->childSetVisible("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
  1105. floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !floater->impl.mAspectRatioCheckOff);
  1106. floater->childSetEnabled("layer_types", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
  1107. BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot");
  1108. BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL;
  1109. BOOL show_slider = 
  1110. shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
  1111. || (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
  1112. floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode
  1113. floater->childSetVisible("less_btn", is_advance);
  1114. floater->childSetVisible("type_label2", is_advance);
  1115. floater->childSetVisible("format_label", is_advance && is_local);
  1116. floater->childSetVisible("local_format_combo", is_advance && is_local);
  1117. floater->childSetVisible("layer_types", is_advance);
  1118. floater->childSetVisible("layer_type_label", is_advance);
  1119. floater->childSetVisible("snapshot_width", is_advance);
  1120. floater->childSetVisible("snapshot_height", is_advance);
  1121. floater->childSetVisible("keep_aspect_check", is_advance);
  1122. floater->childSetVisible("ui_check", is_advance);
  1123. floater->childSetVisible("hud_check", is_advance);
  1124. floater->childSetVisible("keep_open_check", is_advance);
  1125. floater->childSetVisible("freeze_frame_check", is_advance);
  1126. floater->childSetVisible("auto_snapshot_check", is_advance);
  1127. floater->childSetVisible("image_quality_slider", is_advance && show_slider);
  1128. LLSnapshotLivePreview* previewp = getPreviewView(floater);
  1129. BOOL got_bytes = previewp && previewp->getDataSize() > 0;
  1130. BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
  1131. floater->childSetEnabled("send_btn",   shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_snap && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE);
  1132. floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE  && got_snap);
  1133. floater->childSetEnabled("save_btn",   shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL    && got_snap);
  1134. LLLocale locale(LLLocale::USER_LOCALE);
  1135. std::string bytes_string;
  1136. if (got_snap)
  1137. {
  1138. LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
  1139. }
  1140. S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
  1141. floater->childSetLabelArg("texture", "[AMOUNT]", llformat("%d",upload_cost));
  1142. floater->childSetLabelArg("upload_btn", "[AMOUNT]", llformat("%d",upload_cost));
  1143. floater->childSetTextArg("file_size_label", "[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
  1144. floater->childSetColor("file_size_label", 
  1145. shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD 
  1146. && got_bytes
  1147. && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
  1148. switch(shot_type)
  1149. {
  1150.   case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
  1151. layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
  1152. floater->childSetValue("layer_types", "colors");
  1153. if(is_advance)
  1154. {
  1155. setResolution(floater, "postcard_size_combo");
  1156. }
  1157. break;
  1158.   case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
  1159. layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
  1160. floater->childSetValue("layer_types", "colors");
  1161. if(is_advance)
  1162. {
  1163. setResolution(floater, "texture_size_combo");
  1164. }
  1165. break;
  1166.   case  LLSnapshotLivePreview::SNAPSHOT_LOCAL:
  1167. if(is_advance)
  1168. {
  1169. setResolution(floater, "local_size_combo");
  1170. }
  1171. break;
  1172.   default:
  1173. break;
  1174. }
  1175. updateResolutionTextEntry(floater);
  1176. if (previewp)
  1177. {
  1178. previewp->setSnapshotType(shot_type);
  1179. previewp->setSnapshotFormat(shot_format);
  1180. previewp->setSnapshotBufferType(layer_type);
  1181. }
  1182. }
  1183. // static
  1184. void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* floater)
  1185. {
  1186. LLSpinCtrl* width_spinner = floater->getChild<LLSpinCtrl>("snapshot_width");
  1187. LLSpinCtrl* height_spinner = floater->getChild<LLSpinCtrl>("snapshot_height");
  1188. if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
  1189. {
  1190. width_spinner->setAllowEdit(FALSE);
  1191. height_spinner->setAllowEdit(FALSE);
  1192. }
  1193. else
  1194. {
  1195. width_spinner->setAllowEdit(TRUE);
  1196. height_spinner->setAllowEdit(TRUE);
  1197. }
  1198. }
  1199. // static
  1200. void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
  1201. {
  1202. if (previewp)
  1203. {
  1204. BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
  1205. previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
  1206. }
  1207. }
  1208. // static
  1209. void LLFloaterSnapshot::Impl::onClickDiscard(void* data)
  1210. {
  1211. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1212. if (view)
  1213. {
  1214. view->closeFloater();
  1215. }
  1216. }
  1217. // static
  1218. void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data)
  1219. {
  1220. if (ctrl->getValue().asString() == "save as")
  1221. {
  1222. gViewerWindow->resetSnapshotLoc();
  1223. }
  1224. onClickKeep(data);
  1225. }
  1226. // static
  1227. void LLFloaterSnapshot::Impl::onClickKeep(void* data)
  1228. {
  1229. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1230. LLSnapshotLivePreview* previewp = getPreviewView(view);
  1231. if (previewp)
  1232. {
  1233. if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD)
  1234. {
  1235. LLFloaterPostcard* floater = previewp->savePostcard();
  1236. // if still in snapshot mode, put postcard floater in snapshot floaterview
  1237. // and link it to snapshot floater
  1238. if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
  1239. {
  1240. gFloaterView->removeChild(floater);
  1241. gSnapshotFloaterView->addChild(floater);
  1242. view->addDependentFloater(floater, FALSE);
  1243. }
  1244. }
  1245. else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
  1246. {
  1247. previewp->saveTexture();
  1248. }
  1249. else
  1250. {
  1251. previewp->saveLocal();
  1252. }
  1253. if (gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
  1254. {
  1255. view->closeFloater();
  1256. }
  1257. else
  1258. {
  1259. checkAutoSnapshot(previewp);
  1260. }
  1261. updateControls(view);
  1262. }
  1263. }
  1264. // static
  1265. void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data)
  1266. {
  1267. LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data);
  1268. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1269. if (previewp && view)
  1270. {
  1271. previewp->updateSnapshot(TRUE);
  1272. }
  1273. }
  1274. // static
  1275. void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
  1276. {
  1277. LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
  1278. gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
  1279. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1280. if (view)
  1281. {
  1282. checkAutoSnapshot(getPreviewView(view));
  1283. updateControls(view);
  1284. }
  1285. }
  1286. void LLFloaterSnapshot::Impl::onClickMore(void* data)
  1287. {
  1288. gSavedSettings.setBOOL( "AdvanceSnapshot", TRUE );
  1289. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1290. if (view)
  1291. {
  1292. view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() );
  1293. view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong());
  1294. updateControls(view) ;
  1295. updateLayout(view) ;
  1296. if(getPreviewView(view))
  1297. {
  1298. getPreviewView(view)->setThumbnailImageSize() ;
  1299. }
  1300. }
  1301. }
  1302. void LLFloaterSnapshot::Impl::onClickLess(void* data)
  1303. {
  1304. gSavedSettings.setBOOL( "AdvanceSnapshot", FALSE );
  1305. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1306. if (view)
  1307. {
  1308. view->translate( 0, view->getUIWinHeightLong() - view->getUIWinHeightShort() );
  1309. view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort());
  1310. updateControls(view) ;
  1311. updateLayout(view) ;
  1312. if(getPreviewView(view))
  1313. {
  1314. getPreviewView(view)->setThumbnailImageSize() ;
  1315. }
  1316. }
  1317. }
  1318. // static
  1319. void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
  1320. {
  1321. LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
  1322. gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() );
  1323. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1324. if (view)
  1325. {
  1326. checkAutoSnapshot(getPreviewView(view), TRUE);
  1327. updateControls(view);
  1328. }
  1329. }
  1330. // static
  1331. void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
  1332. {
  1333. LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
  1334. gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() );
  1335. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1336. if (view)
  1337. {
  1338. checkAutoSnapshot(getPreviewView(view), TRUE);
  1339. updateControls(view);
  1340. }
  1341. }
  1342. // static
  1343. void LLFloaterSnapshot::Impl::onClickKeepOpenCheck(LLUICtrl* ctrl, void* data)
  1344. {
  1345. LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
  1346. gSavedSettings.setBOOL( "CloseSnapshotOnKeep", !check->get() );
  1347. }
  1348. // static
  1349. void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data)
  1350. {
  1351. LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
  1352. gSavedSettings.setBOOL( "KeepAspectForSnapshot", check->get() );
  1353. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1354. if (view)
  1355. {
  1356. LLSnapshotLivePreview* previewp = getPreviewView(view) ;
  1357. if(previewp)
  1358. {
  1359. previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
  1360. S32 w, h ;
  1361. previewp->getSize(w, h) ;
  1362. if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize()))
  1363. {
  1364. resetSnapshotSizeOnUI(view, w, h) ;
  1365. }
  1366. previewp->setSize(w, h) ;
  1367. previewp->updateSnapshot(FALSE, TRUE);
  1368. checkAutoSnapshot(previewp, TRUE);
  1369. }
  1370. }
  1371. }
  1372. // static
  1373. void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data)
  1374. {
  1375. LLSliderCtrl* slider = (LLSliderCtrl*)ctrl;
  1376. S32 quality_val = llfloor((F32)slider->getValue().asReal());
  1377. LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data);
  1378. if (previewp)
  1379. {
  1380. previewp->setSnapshotQuality(quality_val);
  1381. }
  1382. checkAutoSnapshot(previewp, TRUE);
  1383. }
  1384. // static
  1385. void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
  1386. {
  1387. LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
  1388. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1389. if (!view || !check_box)
  1390. {
  1391. return;
  1392. }
  1393. gSavedSettings.setBOOL("UseFreezeFrame", check_box->get());
  1394. updateLayout(view);
  1395. }
  1396. // static
  1397. void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index)
  1398. {
  1399. LLSnapshotLivePreview *previewp = getPreviewView(view) ;
  1400. // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
  1401. #if 0
  1402. if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view))
  1403. {
  1404. previewp->mKeepAspectRatio = FALSE ;
  1405. return ;
  1406. }
  1407. #endif
  1408. if(0 == index) //current window size
  1409. {
  1410. view->impl.mAspectRatioCheckOff = true ;
  1411. view->childSetEnabled("keep_aspect_check", FALSE) ;
  1412. if(previewp)
  1413. {
  1414. previewp->mKeepAspectRatio = TRUE ;
  1415. }
  1416. }
  1417. else if(-1 == index) //custom
  1418. {
  1419. view->impl.mAspectRatioCheckOff = false ;
  1420. //if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType"))
  1421. {
  1422. view->childSetEnabled("keep_aspect_check", TRUE) ;
  1423. if(previewp)
  1424. {
  1425. previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
  1426. }
  1427. }
  1428. }
  1429. else
  1430. {
  1431. view->impl.mAspectRatioCheckOff = true ;
  1432. view->childSetEnabled("keep_aspect_check", FALSE) ;
  1433. if(previewp)
  1434. {
  1435. previewp->mKeepAspectRatio = FALSE ;
  1436. }
  1437. }
  1438. return ;
  1439. }
  1440. static std::string lastSnapshotWidthName()
  1441. {
  1442. switch(gSavedSettings.getS32("LastSnapshotType"))
  1443. {
  1444. case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailWidth";
  1445. case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:  return "LastSnapshotToInventoryWidth";
  1446. default:                                       return "LastSnapshotToDiskWidth";
  1447. }
  1448. }
  1449. static std::string lastSnapshotHeightName()
  1450. {
  1451. switch(gSavedSettings.getS32("LastSnapshotType"))
  1452. {
  1453. case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailHeight";
  1454. case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:  return "LastSnapshotToInventoryHeight";
  1455. default:                                       return "LastSnapshotToDiskHeight";
  1456. }
  1457. }
  1458. // static
  1459. void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update)
  1460. {
  1461. LLComboBox* combobox = (LLComboBox*)ctrl;
  1462. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1463. if (!view || !combobox)
  1464. {
  1465. return;
  1466. }
  1467. // save off all selected resolution values
  1468. gSavedSettings.setS32("SnapshotPostcardLastResolution", view->getChild<LLComboBox>("postcard_size_combo")->getCurrentIndex());
  1469. gSavedSettings.setS32("SnapshotTextureLastResolution",  view->getChild<LLComboBox>("texture_size_combo")->getCurrentIndex());
  1470. gSavedSettings.setS32("SnapshotLocalLastResolution",    view->getChild<LLComboBox>("local_size_combo")->getCurrentIndex());
  1471. std::string sdstring = combobox->getSelectedValue();
  1472. LLSD sdres;
  1473. std::stringstream sstream(sdstring);
  1474. LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
  1475. S32 width = sdres[0];
  1476. S32 height = sdres[1];
  1477. LLSnapshotLivePreview* previewp = getPreviewView(view);
  1478. if (previewp && combobox->getCurrentIndex() >= 0)
  1479. {
  1480. S32 original_width = 0 , original_height = 0 ;
  1481. previewp->getSize(original_width, original_height) ;
  1482. if (width == 0 || height == 0)
  1483. {
  1484. // take resolution from current window size
  1485. previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
  1486. }
  1487. else if (width == -1 || height == -1)
  1488. {
  1489. // load last custom value
  1490. previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName()));
  1491. }
  1492. else
  1493. {
  1494. // use the resolution from the selected pre-canned drop-down choice
  1495. previewp->setSize(width, height);
  1496. }
  1497. checkAspectRatio(view, width) ;
  1498. previewp->getSize(width, height);
  1499. if(checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize()))
  1500. {
  1501. resetSnapshotSizeOnUI(view, width, height) ;
  1502. }
  1503. if(view->childGetValue("snapshot_width").asInteger() != width || view->childGetValue("snapshot_height").asInteger() != height)
  1504. {
  1505. view->childSetValue("snapshot_width", width);
  1506. view->childSetValue("snapshot_height", height);
  1507. }
  1508. if(original_width != width || original_height != height)
  1509. {
  1510. previewp->setSize(width, height);
  1511. // hide old preview as the aspect ratio could be wrong
  1512. checkAutoSnapshot(previewp, FALSE);
  1513. getPreviewView(view)->updateSnapshot(FALSE, TRUE);
  1514. if(do_update)
  1515. {
  1516. updateControls(view);
  1517. }
  1518. }
  1519. }
  1520. }
  1521. // static
  1522. void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
  1523. {
  1524. LLComboBox* combobox = (LLComboBox*)ctrl;
  1525. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1526. if (view)
  1527. {
  1528. LLSnapshotLivePreview* previewp = getPreviewView(view);
  1529. if (previewp)
  1530. {
  1531. previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex());
  1532. }
  1533. checkAutoSnapshot(previewp, TRUE);
  1534. }
  1535. }
  1536. //static 
  1537. void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)
  1538. {
  1539. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1540. if (view)
  1541. {
  1542. gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view));
  1543. getPreviewView(view)->updateSnapshot(TRUE);
  1544. updateControls(view);
  1545. }
  1546. }
  1547. //static 
  1548. void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data)
  1549. {
  1550. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1551. if (view)
  1552. {
  1553. gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view));
  1554. getPreviewView(view)->updateSnapshot(TRUE);
  1555. updateControls(view);
  1556. }
  1557. }
  1558. // Sets the named size combo to "custom" mode.
  1559. // static
  1560. void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
  1561. {
  1562. LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
  1563. combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
  1564. if(comboname == "postcard_size_combo") 
  1565. {
  1566. gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex());
  1567. }
  1568. else if(comboname == "texture_size_combo") 
  1569. {
  1570. gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex());
  1571. }
  1572. else if(comboname == "local_size_combo") 
  1573. {
  1574. gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex());
  1575. }
  1576. checkAspectRatio(floater, -1); // -1 means custom
  1577. }
  1578. //static
  1579. BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
  1580. {
  1581. S32 w = width ;
  1582. S32 h = height ;
  1583. //if texture, ignore aspect ratio setting, round image size to power of 2.
  1584. #if 0 // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
  1585. if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
  1586. {
  1587. if(width > max_value)
  1588. {
  1589. width = max_value ;
  1590. }
  1591. if(height > max_value)
  1592. {
  1593. height = max_value ;
  1594. }
  1595. //round to nearest power of 2 based on the direction of movement
  1596. // i.e. higher power of two if increasing texture resolution
  1597. if(gSavedSettings.getS32("LastSnapshotToInventoryWidth") < width ||
  1598. gSavedSettings.getS32("LastSnapshotToInventoryHeight") < height)
  1599. {
  1600. // Up arrow pressed
  1601. width = get_next_power_two(width, MAX_TEXTURE_SIZE) ;
  1602. height = get_next_power_two(height, MAX_TEXTURE_SIZE) ;
  1603. }
  1604. else
  1605. {
  1606. // Down or no change
  1607. width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ;
  1608. height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ;
  1609. }
  1610. }
  1611. else
  1612. #endif
  1613. if(previewp && previewp->mKeepAspectRatio)
  1614. {
  1615. if(gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1)
  1616. {
  1617. return FALSE ;
  1618. }
  1619. //aspect ratio of the current window
  1620. F32 aspect_ratio = (F32)gViewerWindow->getWindowWidthRaw() / gViewerWindow->getWindowHeightRaw() ;
  1621. //change another value proportionally
  1622. if(isWidthChanged)
  1623. {
  1624. height = (S32)(width / aspect_ratio) ;
  1625. }
  1626. else
  1627. {
  1628. width = (S32)(height * aspect_ratio) ;
  1629. }
  1630. //bound w/h by the max_value
  1631. if(width > max_value || height > max_value)
  1632. {
  1633. if(width > height)
  1634. {
  1635. width = max_value ;
  1636. height = (S32)(width / aspect_ratio) ;
  1637. }
  1638. else
  1639. {
  1640. height = max_value ;
  1641. width = (S32)(height * aspect_ratio) ;
  1642. }
  1643. }
  1644. }
  1645. else
  1646. {
  1647. }
  1648. return (w != width || h != height) ;
  1649. }
  1650. //static
  1651. void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height)
  1652. {
  1653. view->getChild<LLSpinCtrl>("snapshot_width")->forceSetValue(width);
  1654. view->getChild<LLSpinCtrl>("snapshot_height")->forceSetValue(height);
  1655. gSavedSettings.setS32(lastSnapshotWidthName(), width);
  1656. gSavedSettings.setS32(lastSnapshotHeightName(), height);
  1657. }
  1658. //static
  1659. void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* data)
  1660. {
  1661. LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
  1662. if (view)
  1663. {
  1664. S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
  1665. S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
  1666. LLSnapshotLivePreview* previewp = getPreviewView(view);
  1667. if (previewp)
  1668. {
  1669. S32 curw,curh;
  1670. previewp->getSize(curw, curh);
  1671. if (w != curw || h != curh)
  1672. {
  1673. BOOL update_ = FALSE ;
  1674. //if to upload a snapshot, process spinner input in a special way.
  1675. #if 0  // Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
  1676. if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
  1677. {
  1678. S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ;
  1679. S32 dw = w - curw ;
  1680. S32 dh = h - curh ;
  1681. dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ;
  1682. dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ;
  1683. if(dw)
  1684. {
  1685. w = (dw > 0) ? curw << dw : curw >> -dw ;
  1686. update_ = TRUE ;
  1687. }
  1688. if(dh)
  1689. {
  1690. h = (dh > 0) ? curh << dh : curh >> -dh ;
  1691. update_ = TRUE ;
  1692. }
  1693. }
  1694. #endif
  1695. previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ;
  1696. // Check image size changes the value of height and width
  1697. if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize())
  1698. || update_)
  1699. {
  1700. resetSnapshotSizeOnUI(view, w, h) ;
  1701. }
  1702. previewp->setSize(w,h);
  1703. checkAutoSnapshot(previewp, FALSE);
  1704. previewp->updateSnapshot(FALSE, TRUE);
  1705. comboSetCustom(view, "postcard_size_combo");
  1706. comboSetCustom(view, "texture_size_combo");
  1707. comboSetCustom(view, "local_size_combo");
  1708. }
  1709. }
  1710. gSavedSettings.setS32(lastSnapshotWidthName(), w);
  1711. gSavedSettings.setS32(lastSnapshotHeightName(), h);
  1712. updateControls(view);
  1713. }
  1714. }
  1715. ///----------------------------------------------------------------------------
  1716. /// Class LLFloaterSnapshot
  1717. ///----------------------------------------------------------------------------
  1718. // Default constructor
  1719. LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)
  1720. : LLFloater(key),
  1721.   impl (*(new Impl))
  1722. {
  1723. //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_snapshot.xml", FALSE);
  1724. }
  1725. // Destroys the object
  1726. LLFloaterSnapshot::~LLFloaterSnapshot()
  1727. {
  1728. LLView::deleteViewByHandle(impl.mPreviewHandle);
  1729. //unfreeze everything else
  1730. gSavedSettings.setBOOL("FreezeTime", FALSE);
  1731. if (impl.mLastToolset)
  1732. {
  1733. LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
  1734. }
  1735. delete &impl;
  1736. }
  1737. BOOL LLFloaterSnapshot::postBuild()
  1738. {
  1739. childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this);
  1740. childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this);
  1741. childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
  1742. childSetAction("more_btn", Impl::onClickMore, this);
  1743. childSetAction("less_btn", Impl::onClickLess, this);
  1744. childSetAction("upload_btn", Impl::onClickKeep, this);
  1745. childSetAction("send_btn", Impl::onClickKeep, this);
  1746. childSetCommitCallback("save_btn", Impl::onCommitSave, this);
  1747. childSetAction("discard_btn", Impl::onClickDiscard, this);
  1748. childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this);
  1749. childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality"));
  1750. childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this);
  1751. childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this);
  1752. childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
  1753. childSetValue("ui_check", gSavedSettings.getBOOL("RenderUIInSnapshot"));
  1754. childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
  1755. childSetValue("hud_check", gSavedSettings.getBOOL("RenderHUDInSnapshot"));
  1756. childSetCommitCallback("keep_open_check", Impl::onClickKeepOpenCheck, this);
  1757. childSetValue("keep_open_check", !gSavedSettings.getBOOL("CloseSnapshotOnKeep"));
  1758. childSetCommitCallback("keep_aspect_check", Impl::onClickKeepAspectCheck, this);
  1759. childSetValue("keep_aspect_check", gSavedSettings.getBOOL("KeepAspectForSnapshot"));
  1760. childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this);
  1761. childSetValue("layer_types", "colors");
  1762. childSetEnabled("layer_types", FALSE);
  1763. childSetValue("snapshot_width", gSavedSettings.getS32(lastSnapshotWidthName()));
  1764. childSetValue("snapshot_height", gSavedSettings.getS32(lastSnapshotHeightName()));
  1765. childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame"));
  1766. childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
  1767. childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot"));
  1768. childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
  1769. childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this);
  1770. childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this);
  1771. childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this);
  1772. // create preview window
  1773. LLRect full_screen_rect = getRootView()->getRect();
  1774. LLSnapshotLivePreview::Params p;
  1775. p.rect(full_screen_rect);
  1776. LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
  1777. LLView* parent_view = gSnapshotFloaterView->getParent();
  1778. parent_view->removeChild(gSnapshotFloaterView);
  1779. // make sure preview is below snapshot floater
  1780. parent_view->addChild(previewp);
  1781. parent_view->addChild(gSnapshotFloaterView);
  1782. //move snapshot floater to special purpose snapshotfloaterview
  1783. gFloaterView->removeChild(this);
  1784. gSnapshotFloaterView->addChild(this);
  1785. impl.mPreviewHandle = previewp->getHandle();
  1786. impl.updateControls(this);
  1787. impl.updateLayout(this);
  1788. return TRUE;
  1789. }
  1790. void LLFloaterSnapshot::draw()
  1791. {
  1792. LLSnapshotLivePreview* previewp = impl.getPreviewView(this);
  1793. if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
  1794. {
  1795. // don't render snapshot window in snapshot, even if "show ui" is turned on
  1796. return;
  1797. }
  1798. LLFloater::draw();
  1799. if (previewp)
  1800. {
  1801. if(previewp->getThumbnailImage())
  1802. {
  1803. LLRect thumbnail_rect = getChild<LLUICtrl>("thumbnail_placeholder")->getRect();
  1804. S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ;
  1805. S32 offset_y = thumbnail_rect.mBottom + (thumbnail_rect.getHeight() - previewp->getThumbnailHeight()) / 2 ;
  1806. glMatrixMode(GL_MODELVIEW);
  1807. gl_draw_scaled_image(offset_x, offset_y, 
  1808. previewp->getThumbnailWidth(), previewp->getThumbnailHeight(), 
  1809. previewp->getThumbnailImage(), LLColor4::white);
  1810. previewp->drawPreviewRect(offset_x, offset_y) ;
  1811. }
  1812. }
  1813. }
  1814. void LLFloaterSnapshot::onOpen(const LLSD& key)
  1815. {
  1816. LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(this);
  1817. if(preview)
  1818. {
  1819. preview->updateSnapshot(TRUE);
  1820. }
  1821. focusFirstItem(FALSE);
  1822. gSnapshotFloaterView->setEnabled(TRUE);
  1823. gSnapshotFloaterView->setVisible(TRUE);
  1824. gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
  1825. }
  1826. void LLFloaterSnapshot::onClose(bool app_quitting)
  1827. {
  1828. getParent()->setMouseOpaque(FALSE);
  1829. }
  1830. //static 
  1831. void LLFloaterSnapshot::update()
  1832. {
  1833. LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
  1834. if (!inst)
  1835. return;
  1836. BOOL changed = FALSE;
  1837. for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
  1838.  iter != LLSnapshotLivePreview::sList.end(); ++iter)
  1839. {
  1840. changed |= LLSnapshotLivePreview::onIdle(*iter);
  1841. }
  1842. if(changed)
  1843. {
  1844. inst->impl.updateControls(inst);
  1845. }
  1846. }
  1847. ///----------------------------------------------------------------------------
  1848. /// Class LLSnapshotFloaterView
  1849. ///----------------------------------------------------------------------------
  1850. LLSnapshotFloaterView::LLSnapshotFloaterView (const Params& p) : LLFloaterView (p)
  1851. {
  1852. }
  1853. LLSnapshotFloaterView::~LLSnapshotFloaterView()
  1854. {
  1855. }
  1856. BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
  1857. {
  1858. // use default handler when not in freeze-frame mode
  1859. if(!gSavedSettings.getBOOL("FreezeTime"))
  1860. {
  1861. return LLFloaterView::handleKey(key, mask, called_from_parent);
  1862. }
  1863. if (called_from_parent)
  1864. {
  1865. // pass all keystrokes down
  1866. LLFloaterView::handleKey(key, mask, called_from_parent);
  1867. }
  1868. else
  1869. {
  1870. // bounce keystrokes back down
  1871. LLFloaterView::handleKey(key, mask, TRUE);
  1872. }
  1873. return TRUE;
  1874. }
  1875. BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
  1876. {
  1877. // use default handler when not in freeze-frame mode
  1878. if(!gSavedSettings.getBOOL("FreezeTime"))
  1879. {
  1880. return LLFloaterView::handleMouseDown(x, y, mask);
  1881. }
  1882. // give floater a change to handle mouse, else camera tool
  1883. if (childrenHandleMouseDown(x, y, mask) == NULL)
  1884. {
  1885. LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask );
  1886. }
  1887. return TRUE;
  1888. }
  1889. BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
  1890. {
  1891. // use default handler when not in freeze-frame mode
  1892. if(!gSavedSettings.getBOOL("FreezeTime"))
  1893. {
  1894. return LLFloaterView::handleMouseUp(x, y, mask);
  1895. }
  1896. // give floater a change to handle mouse, else camera tool
  1897. if (childrenHandleMouseUp(x, y, mask) == NULL)
  1898. {
  1899. LLToolMgr::getInstance()->getCurrentTool()->handleMouseUp( x, y, mask );
  1900. }
  1901. return TRUE;
  1902. }
  1903. BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)
  1904. {
  1905. // use default handler when not in freeze-frame mode
  1906. if(!gSavedSettings.getBOOL("FreezeTime"))
  1907. {
  1908. return LLFloaterView::handleHover(x, y, mask);
  1909. }
  1910. // give floater a change to handle mouse, else camera tool
  1911. if (childrenHandleHover(x, y, mask) == NULL)
  1912. {
  1913. LLToolMgr::getInstance()->getCurrentTool()->handleHover( x, y, mask );
  1914. }
  1915. return TRUE;
  1916. }