00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llfloatersnapshot.h"
00035
00036 #include "llfontgl.h"
00037 #include "llsys.h"
00038 #include "llgl.h"
00039 #include "llglimmediate.h"
00040 #include "v3dmath.h"
00041 #include "llmath.h"
00042 #include "lldir.h"
00043 #include "llsdserialize.h"
00044
00045 #include "llagent.h"
00046 #include "llcallbacklist.h"
00047 #include "llcriticaldamp.h"
00048 #include "llui.h"
00049 #include "llviewertexteditor.h"
00050 #include "llfocusmgr.h"
00051 #include "llbutton.h"
00052 #include "llcombobox.h"
00053 #include "llsliderctrl.h"
00054 #include "llspinctrl.h"
00055 #include "llviewercontrol.h"
00056 #include "lluictrlfactory.h"
00057 #include "llviewerstats.h"
00058 #include "llviewercamera.h"
00059 #include "llviewerwindow.h"
00060 #include "llviewermenufile.h"
00061 #include "llfloaterpostcard.h"
00062 #include "llcheckboxctrl.h"
00063 #include "llradiogroup.h"
00064 #include "lltoolfocus.h"
00065 #include "lltoolmgr.h"
00066 #include "llworld.h"
00067
00068 #include "llgl.h"
00069 #include "llglheaders.h"
00070 #include "llimagejpeg.h"
00071 #include "llimagej2c.h"
00072 #include "llvfile.h"
00073 #include "llvfs.h"
00074
00078 S32 LLFloaterSnapshot::sUIWinHeightLong = 526 ;
00079 S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 230 ;
00080 S32 LLFloaterSnapshot::sUIWinWidth = 215 ;
00081
00082 LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
00083
00084 LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL;
00085
00086 const F32 SNAPSHOT_TIME_DELAY = 1.f;
00087
00088 F32 SHINE_TIME = 0.5f;
00089 F32 SHINE_WIDTH = 0.6f;
00090 F32 SHINE_OPACITY = 0.3f;
00091 F32 FALL_TIME = 0.6f;
00092 S32 BORDER_WIDTH = 6;
00093
00094 const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024;
00095 const S32 MAX_TEXTURE_SIZE = 512 ;
00099 class LLSnapshotLivePreview : public LLView
00100 {
00101 public:
00102 enum ESnapshotType
00103 {
00104 SNAPSHOT_POSTCARD,
00105 SNAPSHOT_TEXTURE,
00106 SNAPSHOT_BITMAP
00107 };
00108
00109 LLSnapshotLivePreview(const LLRect& rect);
00110 ~LLSnapshotLivePreview();
00111
00112 void draw();
00113 void reshape(S32 width, S32 height, BOOL called_from_parent);
00114
00115 void setSize(S32 w, S32 h);
00116 void getSize(S32& w, S32& h) const;
00117 S32 getDataSize() const { return mDataSize; }
00118 void setMaxImageSize(S32 size) ;
00119 S32 getMaxImageSize() {return mMaxImageSize ;}
00120
00121 ESnapshotType getSnapshotType() const { return mSnapshotType; }
00122 BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
00123 BOOL isSnapshotActive() { return mSnapshotActive; }
00124 LLImageGL* getThumbnailImage() const { return mThumbnailImage ; }
00125 S32 getThumbnailWidth() const { return mThumbnailWidth ; }
00126 S32 getThumbnailHeight() const { return mThumbnailHeight ; }
00127 BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
00128 BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
00129 LLImageGL* getCurrentImage();
00130 F32 getImageAspect();
00131 F32 getAspect() ;
00132 LLRect getImageRect();
00133 BOOL isImageScaled();
00134
00135 void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
00136 void setSnapshotQuality(S32 quality);
00137 void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
00138 void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE);
00139 LLFloaterPostcard* savePostcard();
00140 void saveTexture();
00141 BOOL saveLocal();
00142
00143 BOOL setThumbnailImageSize() ;
00144 void generateThumbnailImage(BOOL force_update = FALSE) ;
00145 void resetThumbnailImage() { mThumbnailImage = NULL ; }
00146 void drawPreviewRect(S32 offset_x, S32 offset_y) ;
00147
00148 static void onIdle( void* snapshot_preview );
00149
00150 protected:
00151 LLColor4 mColor;
00152 LLPointer<LLImageGL> mViewerImage[2];
00153 LLRect mImageRect[2];
00154 S32 mWidth[2];
00155 S32 mHeight[2];
00156 BOOL mImageScaled[2];
00157 S32 mMaxImageSize ;
00158
00159
00160 LLPointer<LLImageGL> mThumbnailImage ;
00161 S32 mThumbnailWidth ;
00162 S32 mThumbnailHeight ;
00163 LLRect mPreviewRect ;
00164 BOOL mThumbnailUpdateLock ;
00165 BOOL mThumbnailUpToDate ;
00166
00167 S32 mCurImageIndex;
00168 LLPointer<LLImageRaw> mRawImage;
00169 LLPointer<LLImageRaw> mRawImageEncoded;
00170 LLPointer<LLImageJPEG> mJPEGImage;
00171 LLFrameTimer mSnapshotDelayTimer;
00172 S32 mShineCountdown;
00173 LLFrameTimer mShineAnimTimer;
00174 F32 mFlashAlpha;
00175 BOOL mNeedsFlash;
00176 LLVector3d mPosTakenGlobal;
00177 S32 mSnapshotQuality;
00178 S32 mDataSize;
00179 ESnapshotType mSnapshotType;
00180 BOOL mSnapshotUpToDate;
00181 LLFrameTimer mFallAnimTimer;
00182 LLVector3 mCameraPos;
00183 LLQuaternion mCameraRot;
00184 BOOL mSnapshotActive;
00185 LLViewerWindow::ESnapshotType mSnapshotBufferType;
00186 bool mSnapshotSoundPlayed;
00187
00188 public:
00189 static std::set<LLSnapshotLivePreview*> sList;
00190 BOOL mKeepAspectRatio ;
00191 };
00192
00193 std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
00194 LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
00195 LLView("snapshot_live_preview", rect, FALSE),
00196 mColor(1.f, 0.f, 0.f, 0.5f),
00197 mCurImageIndex(0),
00198 mRawImage(NULL),
00199 mThumbnailImage(NULL) ,
00200 mRawImageEncoded(NULL),
00201 mJPEGImage(NULL),
00202 mShineCountdown(0),
00203 mFlashAlpha(0.f),
00204 mNeedsFlash(TRUE),
00205 mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
00206 mDataSize(0),
00207 mSnapshotType(SNAPSHOT_POSTCARD),
00208 mSnapshotUpToDate(FALSE),
00209 mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
00210 mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
00211 mSnapshotActive(FALSE),
00212 mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR),
00213 mSnapshotSoundPlayed(false)
00214 {
00215 mSnapshotDelayTimer.setTimerExpirySec(0.0f);
00216 mSnapshotDelayTimer.start();
00217
00218 sList.insert(this);
00219 setFollowsAll();
00220 mWidth[0] = gViewerWindow->getWindowDisplayWidth();
00221 mWidth[1] = gViewerWindow->getWindowDisplayWidth();
00222 mHeight[0] = gViewerWindow->getWindowDisplayHeight();
00223 mHeight[1] = gViewerWindow->getWindowDisplayHeight();
00224 mImageScaled[0] = FALSE;
00225 mImageScaled[1] = FALSE;
00226
00227 mMaxImageSize = MAX_IMAGE_SIZE ;
00228 mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
00229 mThumbnailUpdateLock = FALSE ;
00230 mThumbnailUpToDate = FALSE ;
00231 }
00232
00233 LLSnapshotLivePreview::~LLSnapshotLivePreview()
00234 {
00235
00236 mRawImage = NULL;
00237 mRawImageEncoded = NULL;
00238 mJPEGImage = NULL;
00239
00240
00241 sList.erase(this);
00242 }
00243
00244 void LLSnapshotLivePreview::setMaxImageSize(S32 size)
00245 {
00246 if(size < MAX_IMAGE_SIZE)
00247 {
00248 mMaxImageSize = size;
00249 }
00250 else
00251 {
00252 mMaxImageSize = MAX_IMAGE_SIZE ;
00253 }
00254 }
00255
00256 LLImageGL* LLSnapshotLivePreview::getCurrentImage()
00257 {
00258 return mViewerImage[mCurImageIndex];
00259 }
00260
00261 F32 LLSnapshotLivePreview::getAspect()
00262 {
00263 F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
00264 F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
00265
00266 if (!mKeepAspectRatio)
00267 {
00268 return image_aspect_ratio;
00269 }
00270 else
00271 {
00272 return window_aspect_ratio;
00273 }
00274 }
00275
00276 F32 LLSnapshotLivePreview::getImageAspect()
00277 {
00278 if (!mViewerImage[mCurImageIndex])
00279 {
00280 return 0.f;
00281 }
00282
00283 return getAspect() ;
00284 }
00285
00286 LLRect LLSnapshotLivePreview::getImageRect()
00287 {
00288 return mImageRect[mCurImageIndex];
00289 }
00290
00291 BOOL LLSnapshotLivePreview::isImageScaled()
00292 {
00293 return mImageScaled[mCurImageIndex];
00294 }
00295
00296 void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail)
00297 {
00298 if (mSnapshotUpToDate)
00299 {
00300 S32 old_image_index = mCurImageIndex;
00301 mCurImageIndex = (mCurImageIndex + 1) % 2;
00302 mWidth[mCurImageIndex] = mWidth[old_image_index];
00303 mHeight[mCurImageIndex] = mHeight[old_image_index];
00304 mFallAnimTimer.start();
00305 }
00306 mSnapshotUpToDate = FALSE;
00307
00308 LLRect& rect = mImageRect[mCurImageIndex];
00309 rect.set(0, getRect().getHeight(), getRect().getWidth(), 0);
00310
00311 F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
00312 F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
00313
00314 if (mKeepAspectRatio)
00315 {
00316 if (image_aspect_ratio > window_aspect_ratio)
00317 {
00318
00319 S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio);
00320 rect.mBottom += (getRect().getHeight() - new_height) / 2;
00321 rect.mTop -= (getRect().getHeight() - new_height) / 2;
00322 }
00323 else if (image_aspect_ratio < window_aspect_ratio)
00324 {
00325
00326 S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio);
00327 rect.mLeft += (getRect().getWidth() - new_width) / 2;
00328 rect.mRight -= (getRect().getWidth() - new_width) / 2;
00329 }
00330 }
00331
00332 mShineAnimTimer.stop();
00333 if (new_snapshot)
00334 {
00335 mSnapshotDelayTimer.start();
00336 mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY);
00337 }
00338 else if(new_thumbnail)
00339 {
00340 mThumbnailUpToDate = FALSE ;
00341 }
00342 else
00343 {
00344 setThumbnailImageSize() ;
00345 }
00346 }
00347
00348 void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
00349 {
00350 if (quality != mSnapshotQuality)
00351 {
00352 mSnapshotQuality = quality;
00353 gSavedSettings.setS32("SnapshotQuality", quality);
00354 }
00355 }
00356
00357 void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
00358 {
00359 F32 line_width ;
00360 glGetFloatv(GL_LINE_WIDTH, &line_width) ;
00361 glLineWidth(2.0f * line_width) ;
00362 LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
00363 gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
00364 mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
00365 glLineWidth(line_width) ;
00366
00367
00368 if(!mKeepAspectRatio)
00369 {
00370 LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
00371 S32 dwl = 0, dwr = 0 ;
00372 if(mThumbnailWidth > mPreviewRect.getWidth())
00373 {
00374 dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ;
00375 dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
00376
00377 gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
00378 mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
00379 gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
00380 mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
00381 }
00382
00383 if(mThumbnailHeight > mPreviewRect.getHeight())
00384 {
00385 S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
00386 gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
00387 mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
00388
00389 dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
00390 gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
00391 mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
00392 }
00393 }
00394 }
00395
00396 void LLSnapshotLivePreview::draw()
00397 {
00398 if (mViewerImage[mCurImageIndex].notNull() &&
00399 mRawImageEncoded.notNull() &&
00400 mSnapshotUpToDate)
00401 {
00402 LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
00403 gl_rect_2d(getRect(), bg_color);
00404 LLRect &rect = mImageRect[mCurImageIndex];
00405 LLRect shadow_rect = mImageRect[mCurImageIndex];
00406 shadow_rect.stretch(BORDER_WIDTH);
00407 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);
00408
00409 LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
00410 gGL.color4fv(image_color.mV);
00411 LLViewerImage::bindTexture(mViewerImage[mCurImageIndex]);
00412
00413 F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f);
00414 F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f);
00415 glPushMatrix();
00416 {
00417 glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
00418 gGL.begin(LLVertexBuffer::QUADS);
00419 {
00420 gGL.texCoord2f(uv_width, uv_height);
00421 gGL.vertex2i(rect.getWidth(), rect.getHeight() );
00422
00423 gGL.texCoord2f(0.f, uv_height);
00424 gGL.vertex2i(0, rect.getHeight() );
00425
00426 gGL.texCoord2f(0.f, 0.f);
00427 gGL.vertex2i(0, 0);
00428
00429 gGL.texCoord2f(uv_width, 0.f);
00430 gGL.vertex2i(rect.getWidth(), 0);
00431 }
00432 gGL.end();
00433 }
00434 glPopMatrix();
00435
00436 gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
00437 gl_rect_2d(getRect());
00438 if (mNeedsFlash)
00439 {
00440 if (mFlashAlpha < 1.f)
00441 {
00442 mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
00443 }
00444 else
00445 {
00446 mNeedsFlash = FALSE;
00447 }
00448 }
00449 else
00450 {
00451 mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
00452 }
00453
00454 if (mShineCountdown > 0)
00455 {
00456 mShineCountdown--;
00457 if (mShineCountdown == 0)
00458 {
00459 mShineAnimTimer.start();
00460 }
00461 }
00462 else if (mShineAnimTimer.getStarted())
00463 {
00464
00465
00466
00467
00468 F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
00469
00470
00471 LLLocalClipRect clip(getLocalRect());
00472 {
00473
00474 S32 x1 = gViewerWindow->getWindowWidth() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
00475 S32 x2 = x1 + llround(gViewerWindow->getWindowWidth() * SHINE_WIDTH);
00476 S32 x3 = x2 + llround(gViewerWindow->getWindowWidth() * SHINE_WIDTH);
00477 S32 y1 = 0;
00478 S32 y2 = gViewerWindow->getWindowHeight();
00479
00480 LLGLSNoTexture no_texture;
00481 gGL.begin(LLVertexBuffer::QUADS);
00482 {
00483 gGL.color4f(1.f, 1.f, 1.f, 0.f);
00484 gGL.vertex2i(x1, y1);
00485 gGL.vertex2i(x1 + gViewerWindow->getWindowWidth(), y2);
00486 gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
00487 gGL.vertex2i(x2 + gViewerWindow->getWindowWidth(), y2);
00488 gGL.vertex2i(x2, y1);
00489
00490 gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
00491 gGL.vertex2i(x2, y1);
00492 gGL.vertex2i(x2 + gViewerWindow->getWindowWidth(), y2);
00493 gGL.color4f(1.f, 1.f, 1.f, 0.f);
00494 gGL.vertex2i(x3 + gViewerWindow->getWindowWidth(), y2);
00495 gGL.vertex2i(x3, y1);
00496 }
00497 gGL.end();
00498 }
00499
00500 if (mShineAnimTimer.getElapsedTimeF32() > SHINE_TIME)
00501 {
00502 mShineAnimTimer.stop();
00503 }
00504 }
00505 }
00506
00507
00508 {
00509 LLGLSNoTexture no_texture;
00510 gGL.color4f(1.f, 1.f, 1.f, 1.f);
00511 LLRect outline_rect = mImageRect[mCurImageIndex];
00512 gGL.begin(LLVertexBuffer::QUADS);
00513 {
00514 gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
00515 gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
00516 gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
00517 gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
00518
00519 gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
00520 gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
00521 gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
00522 gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
00523
00524 gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
00525 gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
00526 gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
00527 gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
00528
00529 gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
00530 gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
00531 gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
00532 gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
00533 }
00534 gGL.end();
00535 }
00536
00537
00538 if (mFallAnimTimer.getStarted())
00539 {
00540 S32 old_image_index = (mCurImageIndex + 1) % 2;
00541 if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
00542 {
00543 F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
00544 F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
00545 LLColor4 image_color(1.f, 1.f, 1.f, alpha);
00546 gGL.color4fv(image_color.mV);
00547 LLViewerImage::bindTexture(mViewerImage[old_image_index]);
00548
00549
00550 BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
00551 F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
00552 F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
00553 glPushMatrix();
00554 {
00555 LLRect& rect = mImageRect[old_image_index];
00556 glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
00557 glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
00558 gGL.begin(LLVertexBuffer::QUADS);
00559 {
00560 gGL.texCoord2f(uv_width, uv_height);
00561 gGL.vertex2i(rect.getWidth(), rect.getHeight() );
00562
00563 gGL.texCoord2f(0.f, uv_height);
00564 gGL.vertex2i(0, rect.getHeight() );
00565
00566 gGL.texCoord2f(0.f, 0.f);
00567 gGL.vertex2i(0, 0);
00568
00569 gGL.texCoord2f(uv_width, 0.f);
00570 gGL.vertex2i(rect.getWidth(), 0);
00571 }
00572 gGL.end();
00573 }
00574 glPopMatrix();
00575 }
00576 }
00577 }
00578
00579
00580 void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent)
00581 {
00582 LLRect old_rect = getRect();
00583 LLView::reshape(width, height, called_from_parent);
00584 if (old_rect.getWidth() != width || old_rect.getHeight() != height)
00585 {
00586 updateSnapshot(FALSE, TRUE);
00587 }
00588 }
00589
00590 BOOL LLSnapshotLivePreview::setThumbnailImageSize()
00591 {
00592 if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10)
00593 {
00594 return FALSE ;
00595 }
00596 S32 window_width = gViewerWindow->getWindowDisplayWidth() ;
00597 S32 window_height = gViewerWindow->getWindowDisplayHeight() ;
00598
00599 F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height);
00600
00601
00602 S32 max_width = LLFloaterSnapshot::getUIWinWidth() - 20;
00603 S32 max_height = 90;
00604
00605 if (window_aspect_ratio > (F32)max_width / max_height)
00606 {
00607
00608 mThumbnailWidth = max_width;
00609 mThumbnailHeight = llround((F32)max_width / window_aspect_ratio);
00610 }
00611 else
00612 {
00613
00614 mThumbnailHeight = max_height;
00615 mThumbnailWidth = llround((F32)max_height * window_aspect_ratio);
00616 }
00617
00618 if(mThumbnailWidth > window_width || mThumbnailHeight > window_height)
00619 {
00620 return FALSE ;
00621 }
00622
00623 S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ;
00624 if(!mKeepAspectRatio)
00625 {
00626 F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ;
00627 F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ;
00628
00629
00630
00631 {
00632 if(ratio_x > ratio_y)
00633 {
00634 top = (S32)(top * ratio_y / ratio_x) ;
00635 }
00636 else
00637 {
00638 right = (S32)(right * ratio_x / ratio_y) ;
00639 }
00640 }
00641
00642
00643
00644
00645
00646 left = (S32)((mThumbnailWidth - right) * 0.5f) ;
00647 bottom = (S32)((mThumbnailHeight - top) * 0.5f) ;
00648 top += bottom ;
00649 right += left ;
00650 }
00651 mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ;
00652
00653 return TRUE ;
00654 }
00655
00656 void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
00657 {
00658 if(mThumbnailUpdateLock)
00659 {
00660 return ;
00661 }
00662 if(mThumbnailUpToDate && !force_update)
00663 {
00664 return ;
00665 }
00666 if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10)
00667 {
00668 return ;
00669 }
00670
00672 mThumbnailUpdateLock = TRUE ;
00673
00674 if(!setThumbnailImageSize())
00675 {
00676 mThumbnailUpdateLock = FALSE ;
00677 mThumbnailUpToDate = TRUE ;
00678 return ;
00679 }
00680
00681 if(mThumbnailImage)
00682 {
00683 resetThumbnailImage() ;
00684 }
00685
00686 LLPointer<LLImageRaw> raw = NULL ;
00687 S32 w , h ;
00688 w = get_nearest_power_two(mThumbnailWidth, 512) * 2 ;
00689 h = get_nearest_power_two(mThumbnailHeight, 512) * 2 ;
00690
00691 {
00692 raw = new LLImageRaw ;
00693 if(!gViewerWindow->thumbnailSnapshot(raw,
00694 w, h,
00695 gSavedSettings.getBOOL("RenderUIInSnapshot"),
00696 FALSE,
00697 mSnapshotBufferType) )
00698 {
00699 raw = NULL ;
00700 }
00701 }
00702
00703 if(raw)
00704 {
00705 mThumbnailImage = new LLImageGL(raw, FALSE);
00706 mThumbnailUpToDate = TRUE ;
00707 }
00708
00709
00710 mThumbnailUpdateLock = FALSE ;
00711 }
00712
00713
00714 void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
00715 {
00716 LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
00717
00718 LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();
00719 LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion();
00720 if (gSavedSettings.getBOOL("FreezeTime") &&
00721 (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))
00722 {
00723 previewp->mCameraPos = new_camera_pos;
00724 previewp->mCameraRot = new_camera_rot;
00725
00726 previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"));
00727 }
00728
00729 previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() &&
00730 previewp->mSnapshotDelayTimer.hasExpired());
00731
00732
00733 if (LLToolCamera::getInstance()->hasMouseCapture())
00734 {
00735 previewp->mSnapshotActive = FALSE;
00736 }
00737
00738 if (previewp->mSnapshotActive)
00739 {
00740 if (!previewp->mRawImage)
00741 {
00742 previewp->mRawImage = new LLImageRaw;
00743 }
00744
00745 if (!previewp->mRawImageEncoded)
00746 {
00747 previewp->mRawImageEncoded = new LLImageRaw;
00748 }
00749
00750 previewp->setVisible(FALSE);
00751 previewp->setEnabled(FALSE);
00752
00753 previewp->getWindow()->incBusyCount();
00754 previewp->mImageScaled[previewp->mCurImageIndex] = FALSE;
00755
00756
00757 if(gViewerWindow->rawSnapshot(previewp->mRawImage,
00758 previewp->mWidth[previewp->mCurImageIndex],
00759 previewp->mHeight[previewp->mCurImageIndex],
00760 previewp->mKeepAspectRatio,
00761 previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
00762 gSavedSettings.getBOOL("RenderUIInSnapshot"),
00763 FALSE,
00764 previewp->mSnapshotBufferType,
00765 previewp->getMaxImageSize()))
00766 {
00767 previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents());
00768
00769 if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
00770 {
00771
00772
00773
00774 if (!previewp->mSnapshotSoundPlayed
00775 || !gSavedSettings.getBOOL("AutoSnapshot") )
00776 {
00777 gViewerWindow->playSnapshotAnimAndSound();
00778 previewp->mSnapshotSoundPlayed = true;
00779 }
00780 }
00781
00782 if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD)
00783 {
00784
00785 previewp->mJPEGImage = NULL;
00786 previewp->mJPEGImage = new LLImageJPEG();
00787 previewp->mJPEGImage->setEncodeQuality(llclamp(previewp->mSnapshotQuality, 0, 100));
00788 if (previewp->mJPEGImage->encode(previewp->mRawImage, 0.0f))
00789 {
00790 previewp->mDataSize = previewp->mJPEGImage->getDataSize();
00791 previewp->mJPEGImage->decode(previewp->mRawImageEncoded, 0.0f);
00792 }
00793 }
00794 else if (previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
00795 {
00796 LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
00797 LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImage->getData(),
00798 previewp->mRawImage->getWidth(),
00799 previewp->mRawImage->getHeight(),
00800 previewp->mRawImage->getComponents());
00801
00802 scaled->biasedScaleToPowerOfTwo(512);
00803 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
00804 if (formatted->encode(scaled, 0.0f))
00805 {
00806 previewp->mDataSize = formatted->getDataSize();
00807 formatted->decode(previewp->mRawImageEncoded, 0.0f);
00808 }
00809 }
00810 else
00811 {
00812 previewp->mRawImageEncoded->copy(previewp->mRawImage);
00813 previewp->mDataSize = previewp->mRawImage->getDataSize();
00814 }
00815
00816 LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImageEncoded->getData(),
00817 previewp->mRawImageEncoded->getWidth(),
00818 previewp->mRawImageEncoded->getHeight(),
00819 previewp->mRawImageEncoded->getComponents());
00820
00821
00822 if (previewp->mRawImageEncoded->getWidth() > 1024 || previewp->mRawImageEncoded->getHeight() > 1024)
00823 {
00824
00825 scaled->biasedScaleToPowerOfTwo(1024);
00826 previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
00827 }
00828 else
00829 {
00830
00831 scaled->expandToPowerOfTwo(1024, FALSE);
00832 }
00833
00834 previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
00835 previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
00836 LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
00837 previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
00838
00839 previewp->mSnapshotUpToDate = TRUE;
00840 previewp->generateThumbnailImage(TRUE) ;
00841
00842 previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
00843 previewp->mShineCountdown = 4;
00844 }
00845 previewp->getWindow()->decBusyCount();
00846
00847 previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
00848 previewp->mSnapshotDelayTimer.stop();
00849 previewp->mSnapshotActive = FALSE;
00850 }
00851 if(!previewp->getThumbnailUpToDate())
00852 {
00853 previewp->generateThumbnailImage() ;
00854 }
00855 }
00856
00857 void LLSnapshotLivePreview::setSize(S32 w, S32 h)
00858 {
00859 mWidth[mCurImageIndex] = w;
00860 mHeight[mCurImageIndex] = h;
00861 }
00862
00863 void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
00864 {
00865 w = mWidth[mCurImageIndex];
00866 h = mHeight[mCurImageIndex];
00867 }
00868
00869 LLFloaterPostcard* LLSnapshotLivePreview::savePostcard()
00870 {
00871
00872
00873 LLVector2 image_scale(1.f, 1.f);
00874 if (!isImageScaled())
00875 {
00876 image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight()));
00877 }
00878
00879
00880 LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(mJPEGImage, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);
00881
00882 mViewerImage[mCurImageIndex] = NULL;
00883 mJPEGImage = NULL;
00884
00885 return floater;
00886 }
00887
00888 void LLSnapshotLivePreview::saveTexture()
00889 {
00890
00891 LLTransactionID tid;
00892 tid.generate();
00893 LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00894
00895 LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
00896 LLPointer<LLImageRaw> scaled = new LLImageRaw(mRawImage->getData(),
00897 mRawImage->getWidth(),
00898 mRawImage->getHeight(),
00899 mRawImage->getComponents());
00900
00901 scaled->biasedScaleToPowerOfTwo(512);
00902
00903 if (formatted->encode(scaled, 0.0f))
00904 {
00905 LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
00906 std::string pos_string;
00907 gAgent.buildLocationString(pos_string);
00908 std::string who_took_it;
00909 gAgent.buildFullname(who_took_it);
00910 upload_new_resource(tid,
00911 LLAssetType::AT_TEXTURE,
00912 "Snapshot : " + pos_string,
00913 "Taken by " + who_took_it + " at " + pos_string,
00914 0,
00915 LLAssetType::AT_SNAPSHOT_CATEGORY,
00916 LLInventoryType::IT_SNAPSHOT,
00917 PERM_ALL,
00918 "Snapshot : " + pos_string);
00919 }
00920 else
00921 {
00922 gViewerWindow->alertXml("ErrorEncodingSnapshot");
00923 llwarns << "Error encoding snapshot" << llendl;
00924 }
00925
00926 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
00927 }
00928
00929 BOOL LLSnapshotLivePreview::saveLocal()
00930 {
00931 return gViewerWindow->saveImageNumbered(mRawImage);
00932 }
00933
00937
00938 class LLFloaterSnapshot::Impl
00939 {
00940 public:
00941 Impl()
00942 : mAvatarPauseHandles(),
00943 mLastToolset(NULL)
00944 {
00945 }
00946 ~Impl()
00947 {
00948
00949 mAvatarPauseHandles.clear();
00950
00951 }
00952 static void onClickDiscard(void* data);
00953 static void onClickKeep(void* data);
00954 static void onClickNewSnapshot(void* data);
00955 static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
00956
00957 static void onClickLess(void* data) ;
00958 static void onClickMore(void* data) ;
00959 static void onClickUICheck(LLUICtrl *ctrl, void* data);
00960 static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
00961 static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data);
00962 static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data);
00963 static void onCommitQuality(LLUICtrl* ctrl, void* data);
00964 static void onCommitResolution(LLUICtrl* ctrl, void* data);
00965 static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
00966 static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
00967 static void onCommitSnapshotType(LLUICtrl* ctrl, void* data);
00968 static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);
00969 static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;
00970 static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
00971
00972 static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater);
00973 static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);
00974 static void updateControls(LLFloaterSnapshot* floater);
00975 static void updateLayout(LLFloaterSnapshot* floater);
00976
00977 static LLHandle<LLView> sPreviewHandle;
00978 static BOOL sAspectRatioCheckOff ;
00979
00980 private:
00981 static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater);
00982 static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);
00983 static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);
00984 static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
00985 static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ;
00986
00987 public:
00988 std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
00989
00990 LLToolset* mLastToolset;
00991 };
00992
00993
00994 LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;
00995
00996
00997 BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ;
00998
00999 LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
01000 {
01001 LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)sPreviewHandle.get();
01002 return previewp;
01003 }
01004
01005
01006 LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFloaterSnapshot* floater)
01007 {
01008 LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
01009 LLSD value = floater->childGetValue("snapshot_type_radio");
01010 const std::string id = value.asString();
01011 if (id == "postcard")
01012 index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
01013 else if (id == "texture")
01014 index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
01015 else if (id == "local")
01016 index = LLSnapshotLivePreview::SNAPSHOT_BITMAP;
01017 return index;
01018 }
01019
01020
01021 LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)
01022 {
01023 LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
01024 LLSD value = floater->childGetValue("layer_types");
01025 const std::string id = value.asString();
01026 if (id == "colors")
01027 type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
01028 else if (id == "depth")
01029 type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH;
01030 else if (id == "objects")
01031 type = LLViewerWindow::SNAPSHOT_TYPE_OBJECT_ID;
01032 return type;
01033 }
01034
01035
01036 void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname)
01037 {
01038 LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
01039 if (combo)
01040 {
01041 combo->setVisible(TRUE);
01042 onCommitResolution(combo, floater);
01043 }
01044 }
01045
01046
01047 void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
01048 {
01049 LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
01050
01051 S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ;
01052
01053 LLComboBox* combo;
01054 if(!gSavedSettings.getBOOL("AdvanceSnapshot"))
01055 {
01056 previewp->mKeepAspectRatio = TRUE ;
01057
01058 combo = floaterp->getChild<LLComboBox>("postcard_size_combo");
01059 combo->setCurrentByIndex(0) ;
01060 gSavedSettings.setS32("SnapshotPostcardLastResolution", 0) ;
01061
01062 combo = floaterp->getChild<LLComboBox>("texture_size_combo");
01063 combo->setCurrentByIndex(0) ;
01064 gSavedSettings.setS32("SnapshotTextureLastResolution", 0) ;
01065
01066 combo = floaterp->getChild<LLComboBox>("local_size_combo");
01067 combo->setCurrentByIndex(0) ;
01068 gSavedSettings.setS32("SnapshotLocalLastResolution", 0) ;
01069
01070 LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
01071 previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
01072 }
01073
01074 bool use_freeze_frame = floaterp->childGetValue("freeze_frame_check").asBoolean();
01075
01076
01077
01078 floaterp->childSetEnabled("auto_snapshot_check", use_freeze_frame);
01079
01080 if (use_freeze_frame)
01081 {
01082
01083 floaterp->getParent()->setMouseOpaque(TRUE);
01084
01085
01086 floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height);
01087
01088
01089 if (previewp)
01090 {
01091 previewp->setVisible(TRUE);
01092 previewp->setEnabled(TRUE);
01093 }
01094
01095
01096 LLCharacter* avatarp;
01097 for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
01098 iter != LLCharacter::sInstances.end(); ++iter)
01099 {
01100 avatarp = *iter;
01101 sInstance->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
01102 }
01103
01104
01105 gSavedSettings.setBOOL("FreezeTime", TRUE);
01106
01107 if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
01108 {
01109 sInstance->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
01110 LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
01111 }
01112 }
01113 else
01114 {
01115
01116 gSavedSettings.setBOOL("AutoSnapshot", FALSE);
01117
01118 floaterp->getParent()->setMouseOpaque(FALSE);
01119 floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height);
01120 if (previewp)
01121 {
01122 previewp->setVisible(FALSE);
01123 previewp->setEnabled(FALSE);
01124 }
01125
01126
01127 sInstance->impl.mAvatarPauseHandles.clear();
01128
01129
01130 gSavedSettings.setBOOL("FreezeTime", FALSE);
01131
01132
01133 if (sInstance->impl.mLastToolset)
01134 {
01135 LLToolMgr::getInstance()->setCurrentToolset(sInstance->impl.mLastToolset);
01136 }
01137 }
01138 }
01139
01140
01141
01142 void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
01143 {
01144 BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot") ;
01145 LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio");
01146 snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType"));
01147 LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater);
01148 LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
01149
01150 floater->childSetVisible("postcard_size_combo", FALSE);
01151 floater->childSetVisible("texture_size_combo", FALSE);
01152 floater->childSetVisible("local_size_combo", FALSE);
01153
01154 LLComboBox* combo;
01155 combo = floater->getChild<LLComboBox>("postcard_size_combo");
01156 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
01157 combo = floater->getChild<LLComboBox>("texture_size_combo");
01158 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
01159 combo = floater->getChild<LLComboBox>("local_size_combo");
01160 if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
01161
01162 floater->childSetVisible("upload_btn", FALSE);
01163 floater->childSetVisible("send_btn", FALSE);
01164 floater->childSetVisible("save_btn", FALSE);
01165 floater->childSetEnabled("keep_aspect_check", FALSE) ;
01166
01167 switch(shot_type)
01168 {
01169 case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
01170 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
01171 floater->childSetValue("layer_types", "colors");
01172 floater->childSetEnabled("layer_types", FALSE);
01173
01174 if(is_advance)
01175 {
01176 floater->childSetEnabled("image_quality_slider", TRUE);
01177 setResolution(floater, "postcard_size_combo");
01178
01179 if(!sAspectRatioCheckOff)
01180 {
01181 floater->childSetEnabled("keep_aspect_check", TRUE) ;
01182 }
01183 }
01184
01185 floater->childSetVisible("send_btn", TRUE);
01186 break;
01187 case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
01188 layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
01189 floater->childSetValue("layer_types", "colors");
01190 floater->childSetEnabled("layer_types", FALSE);
01191 floater->childSetEnabled("image_quality_slider", FALSE);
01192
01193 if(is_advance)
01194 {
01195 setResolution(floater, "texture_size_combo");
01196 }
01197
01198 floater->childSetVisible("upload_btn", TRUE);
01199 break;
01200 case LLSnapshotLivePreview::SNAPSHOT_BITMAP:
01201 floater->childSetEnabled("layer_types", TRUE);
01202 floater->childSetEnabled("image_quality_slider", FALSE);
01203
01204 if(is_advance)
01205 {
01206 setResolution(floater, "local_size_combo");
01207
01208 if(!sAspectRatioCheckOff)
01209 {
01210 floater->childSetEnabled("keep_aspect_check", TRUE) ;
01211 }
01212 }
01213
01214 floater->childSetVisible("save_btn", TRUE);
01215 break;
01216 default:
01217 break;
01218 }
01219
01220 if(is_advance)
01221 {
01222 floater->childSetVisible("type_label2", TRUE) ;
01223 floater->childSetVisible("layer_types", TRUE) ;
01224 floater->childSetVisible("layer_type_label", TRUE) ;
01225 floater->childSetVisible("snapshot_width", TRUE) ;
01226 floater->childSetVisible("snapshot_height", TRUE) ;
01227 floater->childSetVisible("keep_aspect_check", TRUE) ;
01228 floater->childSetVisible("ui_check", TRUE) ;
01229 floater->childSetVisible("hud_check", TRUE) ;
01230 floater->childSetVisible("keep_open_check", TRUE) ;
01231 floater->childSetVisible("freeze_frame_check", TRUE) ;
01232 floater->childSetVisible("auto_snapshot_check", TRUE) ;
01233 floater->childSetVisible("image_quality_slider", TRUE);
01234 floater->childSetVisible("more_btn", FALSE);
01235 floater->childSetVisible("less_btn", TRUE);
01236 }
01237 else
01238 {
01239 floater->childSetVisible("type_label2", FALSE) ;
01240 floater->childSetVisible("layer_types", FALSE) ;
01241 floater->childSetVisible("layer_type_label", FALSE) ;
01242 floater->childSetVisible("snapshot_width", FALSE) ;
01243 floater->childSetVisible("snapshot_height", FALSE) ;
01244 floater->childSetVisible("keep_aspect_check", FALSE) ;
01245 floater->childSetVisible("ui_check", FALSE) ;
01246 floater->childSetVisible("hud_check", FALSE) ;
01247 floater->childSetVisible("keep_open_check", FALSE) ;
01248 floater->childSetVisible("freeze_frame_check", FALSE) ;
01249 floater->childSetVisible("auto_snapshot_check", FALSE) ;
01250 floater->childSetVisible("image_quality_slider", FALSE);
01251 floater->childSetVisible("more_btn", TRUE);
01252 floater->childSetVisible("less_btn", FALSE);
01253 }
01254
01255 LLSnapshotLivePreview* previewp = getPreviewView(floater);
01256 if (previewp)
01257 {
01258 previewp->setSnapshotType(shot_type);
01259 previewp->setSnapshotBufferType(layer_type);
01260 }
01261 }
01262
01263
01264 void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
01265 {
01266 if (previewp)
01267 {
01268 previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"), update_thumbnail);
01269 }
01270 }
01271
01272
01273 void LLFloaterSnapshot::Impl::onClickDiscard(void* data)
01274 {
01275 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01276 if (view)
01277 {
01278 view->close();
01279 }
01280 }
01281
01282
01283 void LLFloaterSnapshot::Impl::onClickKeep(void* data)
01284 {
01285 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01286 LLSnapshotLivePreview* previewp = getPreviewView(view);
01287
01288 if (previewp)
01289 {
01290 BOOL succeeded = TRUE;
01291
01292 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD)
01293 {
01294 LLFloaterPostcard* floater = previewp->savePostcard();
01295
01296
01297 if (!gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
01298 {
01299 gFloaterView->removeChild(floater);
01300 gSnapshotFloaterView->addChild(floater);
01301 view->addDependentFloater(floater, FALSE);
01302 }
01303 }
01304 else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
01305 {
01306 previewp->saveTexture();
01307 }
01308 else
01309 {
01310 succeeded = previewp->saveLocal();
01311 }
01312
01313 if (gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
01314 {
01315 view->close();
01316 }
01317 else
01318 {
01319 checkAutoSnapshot(previewp);
01320 }
01321 }
01322 }
01323
01324
01325 void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data)
01326 {
01327 LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data);
01328 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01329 if (previewp && view)
01330 {
01331 previewp->updateSnapshot(TRUE);
01332 }
01333 }
01334
01335
01336 void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
01337 {
01338 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
01339 gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
01340
01341 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01342 if (view)
01343 {
01344 checkAutoSnapshot(getPreviewView(view));
01345 }
01346 }
01347
01348 void LLFloaterSnapshot::Impl::onClickMore(void* data)
01349 {
01350 gSavedSettings.setBOOL( "AdvanceSnapshot", TRUE );
01351
01352 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01353 if (view)
01354 {
01355 view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() );
01356 view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong());
01357
01358 updateControls(view) ;
01359 updateLayout(view) ;
01360 }
01361 }
01362 void LLFloaterSnapshot::Impl::onClickLess(void* data)
01363 {
01364 gSavedSettings.setBOOL( "AdvanceSnapshot", FALSE );
01365
01366 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01367 if (view)
01368 {
01369 view->translate( 0, view->getUIWinHeightLong() - view->getUIWinHeightShort() );
01370 view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort());
01371
01372 updateControls(view) ;
01373 updateLayout(view) ;
01374
01375 if(getPreviewView(view))
01376 {
01377 getPreviewView(view)->setThumbnailImageSize() ;
01378 }
01379 }
01380 }
01381
01382
01383 void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
01384 {
01385 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
01386 gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() );
01387
01388 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01389 if (view)
01390 {
01391 checkAutoSnapshot(getPreviewView(view), TRUE);
01392 }
01393 }
01394
01395
01396 void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
01397 {
01398 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
01399 gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() );
01400
01401 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01402 if (view)
01403 {
01404 checkAutoSnapshot(getPreviewView(view), TRUE);
01405 }
01406 }
01407
01408
01409 void LLFloaterSnapshot::Impl::onClickKeepOpenCheck(LLUICtrl* ctrl, void* data)
01410 {
01411 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
01412
01413 gSavedSettings.setBOOL( "CloseSnapshotOnKeep", !check->get() );
01414 }
01415
01416
01417 void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data)
01418 {
01419 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
01420 gSavedSettings.setBOOL( "KeepAspectForSnapshot", check->get() );
01421
01422 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01423 if (view)
01424 {
01425 LLSnapshotLivePreview* previewp = getPreviewView(view) ;
01426 if(previewp)
01427 {
01428 previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
01429
01430 S32 w, h ;
01431 previewp->getSize(w, h) ;
01432 if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize()))
01433 {
01434 resetSnapshotSizeOnUI(view, w, h) ;
01435 }
01436
01437 previewp->setSize(w, h) ;
01438 checkAutoSnapshot(previewp, TRUE);
01439 }
01440 }
01441 }
01442
01443
01444 void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data)
01445 {
01446 LLSliderCtrl* slider = (LLSliderCtrl*)ctrl;
01447 S32 quality_val = llfloor((F32)slider->getValue().asReal());
01448
01449 LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data);
01450 if (previewp)
01451 {
01452 previewp->setSnapshotQuality(quality_val);
01453 }
01454 checkAutoSnapshot(previewp, TRUE);
01455 }
01456
01457
01458 void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
01459 {
01460 LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
01461 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01462
01463 if (!view || !check_box)
01464 {
01465 return;
01466 }
01467
01468 gSavedSettings.setBOOL("UseFreezeFrame", check_box->get());
01469
01470 updateLayout(view);
01471 }
01472
01473
01474 void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index)
01475 {
01476 LLSnapshotLivePreview *previewp = getPreviewView(view) ;
01477
01478 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view))
01479 {
01480 previewp->mKeepAspectRatio = FALSE ;
01481 return ;
01482 }
01483
01484 if(!index)
01485 {
01486 sAspectRatioCheckOff = TRUE ;
01487 view->childSetEnabled("keep_aspect_check", FALSE) ;
01488
01489 if(previewp)
01490 {
01491 previewp->mKeepAspectRatio = TRUE ;
01492 }
01493 }
01494 else if(-1 == index)
01495 {
01496 sAspectRatioCheckOff = FALSE ;
01497 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType"))
01498 {
01499 view->childSetEnabled("keep_aspect_check", TRUE) ;
01500
01501 if(previewp)
01502 {
01503 previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
01504 }
01505 }
01506 }
01507 else
01508 {
01509 sAspectRatioCheckOff = TRUE ;
01510 view->childSetEnabled("keep_aspect_check", FALSE) ;
01511
01512 if(previewp)
01513 {
01514 previewp->mKeepAspectRatio = FALSE ;
01515 }
01516 }
01517
01518 return ;
01519 }
01520
01521
01522 void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
01523 {
01524 LLComboBox* combobox = (LLComboBox*)ctrl;
01525 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01526
01527 if (!view || !combobox)
01528 {
01529 return;
01530 }
01531
01532
01533 LLComboBox* combo;
01534 combo = view->getChild<LLComboBox>("postcard_size_combo");
01535 gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex());
01536 combo = view->getChild<LLComboBox>("texture_size_combo");
01537 gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex());
01538 combo = view->getChild<LLComboBox>("local_size_combo");
01539 gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex());
01540
01541 std::string sdstring = combobox->getSelectedValue();
01542 LLSD sdres;
01543 std::stringstream sstream(sdstring);
01544 LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
01545
01546 S32 width = sdres[0];
01547 S32 height = sdres[1];
01548
01549 LLSnapshotLivePreview* previewp = getPreviewView(view);
01550 if (previewp && combobox->getCurrentIndex() >= 0)
01551 {
01552 if (width == 0 || height == 0)
01553 {
01554 previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
01555 }
01556 else if (width == -1 || height == -1)
01557 {
01558
01559 previewp->setSize(gSavedSettings.getS32("LastSnapshotWidth"), gSavedSettings.getS32("LastSnapshotHeight"));
01560 }
01561 else
01562 {
01563 previewp->setSize(width, height);
01564 }
01565
01566 checkAspectRatio(view, width) ;
01567
01568 previewp->getSize(width, height);
01569
01570 if(checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize()))
01571 {
01572 resetSnapshotSizeOnUI(view, width, height) ;
01573 }
01574 previewp->setSize(width, height);
01575
01576 view->childSetValue("snapshot_width", width);
01577 view->childSetValue("snapshot_height", height);
01578
01579 checkAutoSnapshot(previewp, FALSE);
01580 }
01581 }
01582
01583
01584 void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
01585 {
01586 LLComboBox* combobox = (LLComboBox*)ctrl;
01587
01588 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01589
01590 if (view)
01591 {
01592 LLSnapshotLivePreview* previewp = getPreviewView(view);
01593 if (previewp)
01594 {
01595 previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex());
01596 }
01597 checkAutoSnapshot(previewp, TRUE);
01598 }
01599 }
01600
01601
01602 void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)
01603 {
01604 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01605 if (view)
01606 {
01607 gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view));
01608 getPreviewView(view)->updateSnapshot(TRUE);
01609 updateControls(view);
01610 }
01611 }
01612
01613
01614 void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
01615 {
01616 LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
01617 if (combo)
01618 {
01619 combo->setCurrentByIndex(combo->getItemCount() - 1);
01620
01621 checkAspectRatio(floater, -1);
01622 }
01623 }
01624
01625
01626
01627
01628 BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
01629 {
01630 S32 w = width ;
01631 S32 h = height ;
01632
01633
01634 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
01635 {
01636 if(width > max_value)
01637 {
01638 width = max_value ;
01639 }
01640 if(height > max_value)
01641 {
01642 height = max_value ;
01643 }
01644
01645
01646 width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ;
01647 height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ;
01648 }
01649 else if(previewp && previewp->mKeepAspectRatio)
01650 {
01651 if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1)
01652 {
01653 return FALSE ;
01654 }
01655
01656
01657 F32 aspect_ratio = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight() ;
01658
01659
01660 if(isWidthChanged)
01661 {
01662 height = (S32)(width / aspect_ratio) ;
01663 }
01664 else
01665 {
01666 width = (S32)(height * aspect_ratio) ;
01667 }
01668
01669
01670 if(width > max_value || height > max_value)
01671 {
01672 if(width > height)
01673 {
01674 width = max_value ;
01675 height = (S32)(width / aspect_ratio) ;
01676 }
01677 else
01678 {
01679 height = max_value ;
01680 width = (S32)(height * aspect_ratio) ;
01681 }
01682 }
01683 }
01684 else
01685 {
01686 }
01687
01688 return (w != width || h != height) ;
01689 }
01690
01691
01692 void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height)
01693 {
01694 LLSpinCtrl *sctrl = view->getChild<LLSpinCtrl>("snapshot_width") ;
01695 if(sctrl)
01696 {
01697 sctrl->forceSetValue(width) ;
01698 }
01699
01700 sctrl = view->getChild<LLSpinCtrl>("snapshot_height") ;
01701 if(sctrl)
01702 {
01703 sctrl->forceSetValue(height) ;
01704 }
01705
01706 gSavedSettings.setS32("LastSnapshotWidth", width);
01707 gSavedSettings.setS32("LastSnapshotHeight", height);
01708 }
01709
01710
01711 void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* data)
01712 {
01713 LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
01714 if (view)
01715 {
01716 S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
01717 S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
01718
01719 gSavedSettings.setS32("LastSnapshotWidth", w);
01720 gSavedSettings.setS32("LastSnapshotHeight", h);
01721
01722 LLSnapshotLivePreview* previewp = getPreviewView(view);
01723 if (previewp)
01724 {
01725 S32 curw,curh;
01726 previewp->getSize(curw, curh);
01727
01728 if (w != curw || h != curh)
01729 {
01730 BOOL update_ = FALSE ;
01731
01732 if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType"))
01733 {
01734 S32 spinner_increment = (S32)((LLSpinCtrl*)ctrl)->getIncrement() ;
01735 S32 dw = w - curw ;
01736 S32 dh = h - curh ;
01737 dw = (dw == spinner_increment) ? 1 : ((dw == -spinner_increment) ? -1 : 0) ;
01738 dh = (dh == spinner_increment) ? 1 : ((dh == -spinner_increment) ? -1 : 0) ;
01739
01740 if(dw)
01741 {
01742 w = (dw > 0) ? curw << dw : curw >> -dw ;
01743 update_ = TRUE ;
01744 }
01745 if(dh)
01746 {
01747 h = (dh > 0) ? curh << dh : curh >> -dh ;
01748 update_ = TRUE ;
01749 }
01750 }
01751
01752 previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ;
01753 if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) || update_)
01754 {
01755 resetSnapshotSizeOnUI(view, w, h) ;
01756 }
01757
01758 previewp->setSize(w,h);
01759 checkAutoSnapshot(previewp, FALSE);
01760 comboSetCustom(view, "postcard_size_combo");
01761 comboSetCustom(view, "texture_size_combo");
01762 comboSetCustom(view, "local_size_combo");
01763 }
01764 }
01765 }
01766 }
01767
01771
01772
01773 LLFloaterSnapshot::LLFloaterSnapshot()
01774 : LLFloater("Snapshot Floater"),
01775 impl (*(new Impl))
01776 {
01777 }
01778
01779
01780 LLFloaterSnapshot::~LLFloaterSnapshot()
01781 {
01782 if (sInstance == this)
01783 {
01784 LLView::deleteViewByHandle(Impl::sPreviewHandle);
01785 Impl::sPreviewHandle = LLHandle<LLView>();
01786 sInstance = NULL;
01787 }
01788
01789
01790 gSavedSettings.setBOOL("FreezeTime", FALSE);
01791
01792 if (impl.mLastToolset)
01793 {
01794 LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
01795 }
01796
01797 delete &impl;
01798 }
01799
01800 BOOL LLFloaterSnapshot::postBuild()
01801 {
01802 childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this);
01803
01804 childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
01805
01806 childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot"));
01807 childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
01808
01809
01810
01811 childSetAction("more_btn", Impl::onClickMore, this);
01812 childSetAction("less_btn", Impl::onClickLess, this);
01813
01814 childSetAction("upload_btn", Impl::onClickKeep, this);
01815 childSetAction("send_btn", Impl::onClickKeep, this);
01816 childSetAction("save_btn", Impl::onClickKeep, this);
01817 childSetAction("discard_btn", Impl::onClickDiscard, this);
01818
01819 childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this);
01820 childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality"));
01821
01822 childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this);
01823
01824 childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this);
01825
01826 childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
01827
01828 childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
01829 childSetValue("hud_check", gSavedSettings.getBOOL("RenderHUDInSnapshot"));
01830
01831 childSetCommitCallback("keep_open_check", Impl::onClickKeepOpenCheck, this);
01832 childSetValue("keep_open_check", !gSavedSettings.getBOOL("CloseSnapshotOnKeep"));
01833
01834 childSetCommitCallback("keep_aspect_check", Impl::onClickKeepAspectCheck, this);
01835 childSetValue("keep_aspect_check", gSavedSettings.getBOOL("KeepAspectForSnapshot"));
01836
01837 childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this);
01838 childSetValue("layer_types", "colors");
01839 childSetEnabled("layer_types", FALSE);
01840
01841 childSetValue("snapshot_width", gSavedSettings.getS32("LastSnapshotWidth"));
01842 childSetValue("snapshot_height", gSavedSettings.getS32("LastSnapshotHeight"));
01843
01844 childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame"));
01845 childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
01846
01847 childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this);
01848 childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this);
01849 childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this);
01850
01851
01852 LLRect full_screen_rect = sInstance->getRootView()->getRect();
01853 LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(full_screen_rect);
01854 sInstance->getRootView()->removeChild(gSnapshotFloaterView);
01855
01856 sInstance->getRootView()->addChild(previewp);
01857 sInstance->getRootView()->addChild(gSnapshotFloaterView);
01858
01859 Impl::sPreviewHandle = previewp->getHandle();
01860
01861 impl.updateControls(this);
01862
01863 return TRUE;
01864 }
01865
01866 void LLFloaterSnapshot::draw()
01867 {
01868 LLSnapshotLivePreview* previewp = impl.getPreviewView(this);
01869
01870 if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
01871 {
01872
01873 return;
01874 }
01875
01876 if(!isMinimized())
01877 {
01878 if (previewp && previewp->getDataSize() > 0)
01879 {
01880 LLLocale locale(LLLocale::USER_LOCALE);
01881
01882 LLString bytes_string;
01883 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD &&
01884 previewp->getDataSize() > MAX_POSTCARD_DATASIZE)
01885 {
01886 childSetColor("file_size_label", LLColor4::red);
01887 childSetEnabled("send_btn", FALSE);
01888 }
01889 else
01890 {
01891 childSetColor("file_size_label", gColors.getColor( "LabelTextColor" ));
01892 childSetEnabled("send_btn", previewp->getSnapshotUpToDate());
01893 }
01894
01895 if (previewp->getSnapshotUpToDate())
01896 {
01897 LLString bytes_string;
01898 LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
01899 childSetTextArg("file_size_label", "[SIZE]", bytes_string);
01900 }
01901 else
01902 {
01903 childSetTextArg("file_size_label", "[SIZE]", getString("unknown"));
01904 childSetColor("file_size_label", gColors.getColor( "LabelTextColor" ));
01905 }
01906 childSetEnabled("upload_btn", previewp->getSnapshotUpToDate());
01907 childSetEnabled("save_btn", previewp->getSnapshotUpToDate());
01908
01909 }
01910 else
01911 {
01912 childSetTextArg("file_size_label", "[SIZE]", LLString("???"));
01913 childSetEnabled("upload_btn", FALSE);
01914 childSetEnabled("send_btn", FALSE);
01915 childSetEnabled("save_btn", FALSE);
01916 }
01917
01918 BOOL ui_in_snapshot = gSavedSettings.getBOOL("RenderUIInSnapshot");
01919 childSetValue("ui_check", ui_in_snapshot);
01920 childSetToolTip("ui_check", "If selected shows the UI in the snapshot");
01921 }
01922
01923 LLFloater::draw();
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964 if (previewp)
01965 {
01966 if(previewp->getThumbnailImage())
01967 {
01968 S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ;
01969 S32 offset_y = getRect().getHeight() - 205 + (90 - previewp->getThumbnailHeight()) / 2 ;
01970
01971 glMatrixMode(GL_MODELVIEW);
01972 gl_draw_scaled_image(offset_x, offset_y,
01973 previewp->getThumbnailWidth(), previewp->getThumbnailHeight(),
01974 previewp->getThumbnailImage(), LLColor4::white);
01975
01976 previewp->drawPreviewRect(offset_x, offset_y) ;
01977 }
01978 }
01979 }
01980
01981 void LLFloaterSnapshot::onClose(bool app_quitting)
01982 {
01983 gSnapshotFloaterView->setEnabled(FALSE);
01984 destroy();
01985 }
01986
01987
01988 void LLFloaterSnapshot::show(void*)
01989 {
01990 if (!sInstance)
01991 {
01992 sInstance = new LLFloaterSnapshot();
01993
01994 LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE);
01995
01996 gFloaterView->removeChild(sInstance);
01997 gSnapshotFloaterView->addChild(sInstance);
01998
01999 sInstance->impl.updateLayout(sInstance);
02000 }
02001
02002 sInstance->open();
02003 sInstance->focusFirstItem(FALSE);
02004 gSnapshotFloaterView->setEnabled(TRUE);
02005 gSnapshotFloaterView->adjustToFitScreen(sInstance, FALSE);
02006 }
02007
02008 void LLFloaterSnapshot::hide(void*)
02009 {
02010 if (sInstance && !sInstance->isDead())
02011 {
02012 sInstance->close();
02013 }
02014 }
02015
02016
02017 void LLFloaterSnapshot::update()
02018 {
02019 for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
02020 iter != LLSnapshotLivePreview::sList.end(); ++iter)
02021 {
02022 LLSnapshotLivePreview::onIdle(*iter);
02023 }
02024 }
02025
02026
02027
02028 LLSnapshotFloaterView::LLSnapshotFloaterView( const LLString& name, const LLRect& rect ) : LLFloaterView(name, rect)
02029 {
02030 setMouseOpaque(TRUE);
02031 setEnabled(FALSE);
02032 }
02033
02034 LLSnapshotFloaterView::~LLSnapshotFloaterView()
02035 {
02036 }
02037
02038 BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
02039 {
02040
02041 if(!gSavedSettings.getBOOL("FreezeTime"))
02042 {
02043 return LLFloaterView::handleKey(key, mask, called_from_parent);
02044 }
02045
02046 if (called_from_parent)
02047 {
02048
02049 LLFloaterView::handleKey(key, mask, called_from_parent);
02050 }
02051 else
02052 {
02053
02054 LLFloaterView::handleKey(key, mask, TRUE);
02055 }
02056 return TRUE;
02057 }
02058
02059 BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
02060 {
02061
02062 if(!gSavedSettings.getBOOL("FreezeTime"))
02063 {
02064 return LLFloaterView::handleMouseDown(x, y, mask);
02065 }
02066
02067 if (childrenHandleMouseDown(x, y, mask) == NULL)
02068 {
02069 LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask );
02070 }
02071 return TRUE;
02072 }
02073
02074 BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
02075 {
02076
02077 if(!gSavedSettings.getBOOL("FreezeTime"))
02078 {
02079 return LLFloaterView::handleMouseUp(x, y, mask);
02080 }
02081
02082 if (childrenHandleMouseUp(x, y, mask) == NULL)
02083 {
02084 LLToolMgr::getInstance()->getCurrentTool()->handleMouseUp( x, y, mask );
02085 }
02086 return TRUE;
02087 }
02088
02089 BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)
02090 {
02091
02092 if(!gSavedSettings.getBOOL("FreezeTime"))
02093 {
02094 return LLFloaterView::handleHover(x, y, mask);
02095 }
02096
02097 if (childrenHandleHover(x, y, mask) == NULL)
02098 {
02099 LLToolMgr::getInstance()->getCurrentTool()->handleHover( x, y, mask );
02100 }
02101 return TRUE;
02102 }