diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloatersnapshot.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloatersnapshot.cpp | 1542 |
1 files changed, 1542 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp new file mode 100644 index 0000000..01f86af --- /dev/null +++ b/linden/indra/newview/llfloatersnapshot.cpp | |||
@@ -0,0 +1,1542 @@ | |||
1 | /** | ||
2 | * @file llfloatersnapshot.cpp | ||
3 | * @brief Snapshot preview window, allowing saving, e-mailing, etc. | ||
4 | * | ||
5 | * Copyright (c) 2004-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llfloatersnapshot.h" | ||
31 | |||
32 | #include "llfontgl.h" | ||
33 | #include "llsys.h" | ||
34 | #include "llgl.h" | ||
35 | #include "v3dmath.h" | ||
36 | #include "lldir.h" | ||
37 | #include "llsdserialize.h" | ||
38 | |||
39 | #include "llagent.h" | ||
40 | #include "llcallbacklist.h" | ||
41 | #include "llcriticaldamp.h" | ||
42 | #include "llui.h" | ||
43 | #include "llviewertexteditor.h" | ||
44 | #include "llfocusmgr.h" | ||
45 | #include "llbutton.h" | ||
46 | #include "llcombobox.h" | ||
47 | #include "llsliderctrl.h" | ||
48 | #include "llspinctrl.h" | ||
49 | #include "llviewercontrol.h" | ||
50 | #include "viewer.h" | ||
51 | #include "llvieweruictrlfactory.h" | ||
52 | #include "llviewerstats.h" | ||
53 | #include "llviewercamera.h" | ||
54 | #include "llviewerwindow.h" | ||
55 | #include "llviewermenu.h" | ||
56 | #include "llfloaterpostcard.h" | ||
57 | #include "llcheckboxctrl.h" | ||
58 | #include "llradiogroup.h" | ||
59 | #include "lltoolfocus.h" | ||
60 | #include "lltoolmgr.h" | ||
61 | #include "llworld.h" | ||
62 | |||
63 | #include "llgl.h" | ||
64 | #include "llglheaders.h" | ||
65 | #include "llimagejpeg.h" | ||
66 | #include "llimagej2c.h" | ||
67 | #include "llvfile.h" | ||
68 | #include "llvfs.h" | ||
69 | |||
70 | ///---------------------------------------------------------------------------- | ||
71 | /// Local function declarations, constants, enums, and typedefs | ||
72 | ///---------------------------------------------------------------------------- | ||
73 | |||
74 | LLSnapshotFloaterView* gSnapshotFloaterView = NULL; | ||
75 | |||
76 | LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL; | ||
77 | const F32 SNAPSHOT_TIME_DELAY = 1.f; | ||
78 | |||
79 | F32 SHINE_TIME = 0.5f; | ||
80 | F32 SHINE_WIDTH = 0.6f; | ||
81 | F32 SHINE_OPACITY = 0.3f; | ||
82 | F32 FALL_TIME = 0.6f; | ||
83 | S32 BORDER_WIDTH = 6; | ||
84 | |||
85 | const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte | ||
86 | |||
87 | ///---------------------------------------------------------------------------- | ||
88 | /// Class LLSnapshotLivePreview | ||
89 | ///---------------------------------------------------------------------------- | ||
90 | class LLSnapshotLivePreview : public LLView | ||
91 | { | ||
92 | public: | ||
93 | enum ESnapshotType | ||
94 | { | ||
95 | SNAPSHOT_POSTCARD, | ||
96 | SNAPSHOT_TEXTURE, | ||
97 | SNAPSHOT_BITMAP | ||
98 | }; | ||
99 | |||
100 | LLSnapshotLivePreview(const LLRect& rect); | ||
101 | ~LLSnapshotLivePreview(); | ||
102 | |||
103 | virtual EWidgetType getWidgetType() const; | ||
104 | virtual LLString getWidgetTag() const; | ||
105 | |||
106 | /*virtual*/ void draw(); | ||
107 | /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); | ||
108 | |||
109 | void setSize(S32 w, S32 h); | ||
110 | void getSize(S32& w, S32& h) const; | ||
111 | S32 getDataSize() const { return mDataSize; } | ||
112 | |||
113 | ESnapshotType getSnapshotType() const { return mSnapshotType; } | ||
114 | BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } | ||
115 | BOOL isSnapshotActive() { return mSnapshotActive; } | ||
116 | LLImageGL* getCurrentImage(); | ||
117 | F32 getImageAspect(); | ||
118 | LLRect getImageRect(); | ||
119 | BOOL isImageScaled(); | ||
120 | |||
121 | void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } | ||
122 | void setSnapshotQuality(S32 quality); | ||
123 | void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } | ||
124 | void updateSnapshot(BOOL new_snapshot); | ||
125 | LLFloaterPostcard* savePostcard(); | ||
126 | void saveTexture(); | ||
127 | void saveLocal(); | ||
128 | |||
129 | static void onIdle( void* snapshot_preview ); | ||
130 | |||
131 | protected: | ||
132 | LLColor4 mColor; | ||
133 | LLPointer<LLImageGL> mViewerImage[2]; | ||
134 | LLRect mImageRect[2]; | ||
135 | S32 mWidth[2]; | ||
136 | S32 mHeight[2]; | ||
137 | BOOL mImageScaled[2]; | ||
138 | |||
139 | S32 mCurImageIndex; | ||
140 | LLPointer<LLImageRaw> mRawImage; | ||
141 | LLPointer<LLImageRaw> mRawImageEncoded; | ||
142 | LLPointer<LLImageJPEG> mJPEGImage; | ||
143 | LLFrameTimer mSnapshotDelayTimer; | ||
144 | S32 mShineCountdown; | ||
145 | LLFrameTimer mShineAnimTimer; | ||
146 | F32 mFlashAlpha; | ||
147 | BOOL mNeedsFlash; | ||
148 | LLVector3d mPosTakenGlobal; | ||
149 | S32 mSnapshotQuality; | ||
150 | S32 mDataSize; | ||
151 | ESnapshotType mSnapshotType; | ||
152 | BOOL mSnapshotUpToDate; | ||
153 | LLFrameTimer mFallAnimTimer; | ||
154 | LLVector3 mCameraPos; | ||
155 | LLQuaternion mCameraRot; | ||
156 | BOOL mSnapshotActive; | ||
157 | LLViewerWindow::ESnapshotType mSnapshotBufferType; | ||
158 | |||
159 | public: | ||
160 | static std::set<LLSnapshotLivePreview*> sList; | ||
161 | }; | ||
162 | |||
163 | std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList; | ||
164 | |||
165 | LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : | ||
166 | LLView("snapshot_live_preview", rect, FALSE), | ||
167 | mColor(1.f, 0.f, 0.f, 0.5f), | ||
168 | mCurImageIndex(0), | ||
169 | mRawImage(NULL), | ||
170 | mRawImageEncoded(NULL), | ||
171 | mJPEGImage(NULL), | ||
172 | mShineCountdown(0), | ||
173 | mFlashAlpha(0.f), | ||
174 | mNeedsFlash(TRUE), | ||
175 | mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")), | ||
176 | mDataSize(0), | ||
177 | mSnapshotType(SNAPSHOT_POSTCARD), | ||
178 | mSnapshotUpToDate(FALSE), | ||
179 | mCameraPos(gCamera->getOrigin()), | ||
180 | mCameraRot(gCamera->getQuaternion()), | ||
181 | mSnapshotActive(FALSE), | ||
182 | mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR) | ||
183 | { | ||
184 | mSnapshotDelayTimer.setTimerExpirySec(0.0f); | ||
185 | mSnapshotDelayTimer.start(); | ||
186 | // gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); | ||
187 | sList.insert(this); | ||
188 | setFollowsAll(); | ||
189 | mWidth[0] = gViewerWindow->getWindowDisplayWidth(); | ||
190 | mWidth[1] = gViewerWindow->getWindowDisplayWidth(); | ||
191 | mHeight[0] = gViewerWindow->getWindowDisplayHeight(); | ||
192 | mHeight[1] = gViewerWindow->getWindowDisplayHeight(); | ||
193 | mImageScaled[0] = FALSE; | ||
194 | mImageScaled[1] = FALSE; | ||
195 | } | ||
196 | |||
197 | LLSnapshotLivePreview::~LLSnapshotLivePreview() | ||
198 | { | ||
199 | // delete images | ||
200 | mRawImage = NULL; | ||
201 | mRawImageEncoded = NULL; | ||
202 | mJPEGImage = NULL; | ||
203 | |||
204 | // gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this ); | ||
205 | sList.erase(this); | ||
206 | } | ||
207 | |||
208 | LLImageGL* LLSnapshotLivePreview::getCurrentImage() | ||
209 | { | ||
210 | return mViewerImage[mCurImageIndex]; | ||
211 | } | ||
212 | |||
213 | F32 LLSnapshotLivePreview::getImageAspect() | ||
214 | { | ||
215 | if (!mViewerImage[mCurImageIndex]) | ||
216 | { | ||
217 | return 0.f; | ||
218 | } | ||
219 | |||
220 | F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); | ||
221 | F32 window_aspect_ratio = ((F32)mRect.getWidth()) / ((F32)mRect.getHeight()); | ||
222 | |||
223 | if (gSavedSettings.getBOOL("KeepAspectForSnapshot")) | ||
224 | { | ||
225 | return image_aspect_ratio; | ||
226 | } | ||
227 | else | ||
228 | { | ||
229 | return window_aspect_ratio; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | LLRect LLSnapshotLivePreview::getImageRect() | ||
234 | { | ||
235 | return mImageRect[mCurImageIndex]; | ||
236 | } | ||
237 | |||
238 | BOOL LLSnapshotLivePreview::isImageScaled() | ||
239 | { | ||
240 | return mImageScaled[mCurImageIndex]; | ||
241 | } | ||
242 | |||
243 | void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot) | ||
244 | { | ||
245 | if (mSnapshotUpToDate) | ||
246 | { | ||
247 | S32 old_image_index = mCurImageIndex; | ||
248 | mCurImageIndex = (mCurImageIndex + 1) % 2; | ||
249 | mWidth[mCurImageIndex] = mWidth[old_image_index]; | ||
250 | mHeight[mCurImageIndex] = mHeight[old_image_index]; | ||
251 | mFallAnimTimer.start(); | ||
252 | } | ||
253 | mSnapshotUpToDate = FALSE; | ||
254 | mShineAnimTimer.stop(); | ||
255 | if (new_snapshot) | ||
256 | { | ||
257 | mSnapshotDelayTimer.start(); | ||
258 | mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY); | ||
259 | } | ||
260 | |||
261 | LLRect& rect = mImageRect[mCurImageIndex]; | ||
262 | rect.set(0, mRect.getHeight(), mRect.getWidth(), 0); | ||
263 | |||
264 | F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); | ||
265 | F32 window_aspect_ratio = ((F32)mRect.getWidth()) / ((F32)mRect.getHeight()); | ||
266 | |||
267 | if (gSavedSettings.getBOOL("KeepAspectForSnapshot")) | ||
268 | { | ||
269 | if (image_aspect_ratio > window_aspect_ratio) | ||
270 | { | ||
271 | // trim off top and bottom | ||
272 | S32 new_height = llround((F32)mRect.getWidth() / image_aspect_ratio); | ||
273 | rect.mBottom += (mRect.getHeight() - new_height) / 2; | ||
274 | rect.mTop -= (mRect.getHeight() - new_height) / 2; | ||
275 | } | ||
276 | else if (image_aspect_ratio < window_aspect_ratio) | ||
277 | { | ||
278 | // trim off left and right | ||
279 | S32 new_width = llround((F32)mRect.getHeight() * image_aspect_ratio); | ||
280 | rect.mLeft += (mRect.getWidth() - new_width) / 2; | ||
281 | rect.mRight -= (mRect.getWidth() - new_width) / 2; | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | |||
286 | void LLSnapshotLivePreview::setSnapshotQuality(S32 quality) | ||
287 | { | ||
288 | if (quality != mSnapshotQuality) | ||
289 | { | ||
290 | mSnapshotQuality = quality; | ||
291 | gSavedSettings.setS32("SnapshotQuality", quality); | ||
292 | } | ||
293 | } | ||
294 | |||
295 | EWidgetType LLSnapshotLivePreview::getWidgetType() const | ||
296 | { | ||
297 | return WIDGET_TYPE_SNAPSHOT_LIVE_PREVIEW; | ||
298 | } | ||
299 | |||
300 | LLString LLSnapshotLivePreview::getWidgetTag() const | ||
301 | { | ||
302 | return LL_SNAPSHOT_LIVE_PREVIEW_TAG; | ||
303 | } | ||
304 | |||
305 | void LLSnapshotLivePreview::draw() | ||
306 | { | ||
307 | if(getVisible()) | ||
308 | { | ||
309 | if (mViewerImage[mCurImageIndex].notNull() && | ||
310 | mRawImageEncoded.notNull() && | ||
311 | mSnapshotUpToDate) | ||
312 | { | ||
313 | LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); | ||
314 | gl_rect_2d(mRect, bg_color); | ||
315 | LLRect &rect = mImageRect[mCurImageIndex]; | ||
316 | LLRect shadow_rect = mImageRect[mCurImageIndex]; | ||
317 | shadow_rect.stretch(BORDER_WIDTH); | ||
318 | 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); | ||
319 | |||
320 | LLGLSTexture set_texture; | ||
321 | LLColor4 image_color(1.f, 1.f, 1.f, 1.f); | ||
322 | glColor4fv(image_color.mV); | ||
323 | LLViewerImage::bindTexture(mViewerImage[mCurImageIndex]); | ||
324 | // calculate UV scale | ||
325 | F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f); | ||
326 | F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f); | ||
327 | glPushMatrix(); | ||
328 | { | ||
329 | glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f); | ||
330 | glBegin(GL_QUADS); | ||
331 | { | ||
332 | glTexCoord2f(uv_width, uv_height); | ||
333 | glVertex2i(rect.getWidth(), rect.getHeight() ); | ||
334 | |||
335 | glTexCoord2f(0.f, uv_height); | ||
336 | glVertex2i(0, rect.getHeight() ); | ||
337 | |||
338 | glTexCoord2f(0.f, 0.f); | ||
339 | glVertex2i(0, 0); | ||
340 | |||
341 | glTexCoord2f(uv_width, 0.f); | ||
342 | glVertex2i(rect.getWidth(), 0); | ||
343 | } | ||
344 | glEnd(); | ||
345 | } | ||
346 | glPopMatrix(); | ||
347 | |||
348 | glColor4f(1.f, 1.f, 1.f, mFlashAlpha); | ||
349 | gl_rect_2d(mRect); | ||
350 | if (mNeedsFlash) | ||
351 | { | ||
352 | if (mFlashAlpha < 1.f) | ||
353 | { | ||
354 | mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f)); | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | mNeedsFlash = FALSE; | ||
359 | } | ||
360 | } | ||
361 | else | ||
362 | { | ||
363 | mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); | ||
364 | } | ||
365 | |||
366 | if (mShineCountdown > 0) | ||
367 | { | ||
368 | mShineCountdown--; | ||
369 | if (mShineCountdown == 0) | ||
370 | { | ||
371 | mShineAnimTimer.start(); | ||
372 | } | ||
373 | } | ||
374 | else if (mShineAnimTimer.getStarted()) | ||
375 | { | ||
376 | //LLDebugVarMessageBox::show("Shine time", &SHINE_TIME, 10.f, 0.1f); | ||
377 | //LLDebugVarMessageBox::show("Shine width", &SHINE_WIDTH, 2.f, 0.05f); | ||
378 | //LLDebugVarMessageBox::show("Shine opacity", &SHINE_OPACITY, 1.f, 0.05f); | ||
379 | |||
380 | F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME); | ||
381 | |||
382 | // draw "shine" effect | ||
383 | LLGLEnable scissor_test(GL_SCISSOR_TEST); | ||
384 | LLUI::setScissorRegionLocal(LLRect(0, mRect.getHeight(), mRect.getWidth(), 0)); | ||
385 | { | ||
386 | // draw diagonal stripe with gradient that passes over screen | ||
387 | S32 x1 = gViewerWindow->getWindowWidth() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f))); | ||
388 | S32 x2 = x1 + llround(gViewerWindow->getWindowWidth() * SHINE_WIDTH); | ||
389 | S32 x3 = x2 + llround(gViewerWindow->getWindowWidth() * SHINE_WIDTH); | ||
390 | S32 y1 = 0; | ||
391 | S32 y2 = gViewerWindow->getWindowHeight(); | ||
392 | |||
393 | LLGLSNoTexture no_texture; | ||
394 | glBegin(GL_QUADS); | ||
395 | { | ||
396 | glColor4f(1.f, 1.f, 1.f, 0.f); | ||
397 | glVertex2i(x1, y1); | ||
398 | glVertex2i(x1 + gViewerWindow->getWindowWidth(), y2); | ||
399 | glColor4f(1.f, 1.f, 1.f, SHINE_OPACITY); | ||
400 | glVertex2i(x2 + gViewerWindow->getWindowWidth(), y2); | ||
401 | glVertex2i(x2, y1); | ||
402 | |||
403 | glColor4f(1.f, 1.f, 1.f, SHINE_OPACITY); | ||
404 | glVertex2i(x2, y1); | ||
405 | glVertex2i(x2 + gViewerWindow->getWindowWidth(), y2); | ||
406 | glColor4f(1.f, 1.f, 1.f, 0.f); | ||
407 | glVertex2i(x3 + gViewerWindow->getWindowWidth(), y2); | ||
408 | glVertex2i(x3, y1); | ||
409 | } | ||
410 | glEnd(); | ||
411 | } | ||
412 | |||
413 | if (mShineAnimTimer.getElapsedTimeF32() > SHINE_TIME) | ||
414 | { | ||
415 | mShineAnimTimer.stop(); | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | // draw framing rectangle | ||
421 | { | ||
422 | LLGLSNoTexture no_texture; | ||
423 | glColor4f(1.f, 1.f, 1.f, 1.f); | ||
424 | LLRect outline_rect = mImageRect[mCurImageIndex]; | ||
425 | glBegin(GL_QUADS); | ||
426 | { | ||
427 | glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); | ||
428 | glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); | ||
429 | glVertex2i(outline_rect.mRight, outline_rect.mTop); | ||
430 | glVertex2i(outline_rect.mLeft, outline_rect.mTop); | ||
431 | |||
432 | glVertex2i(outline_rect.mLeft, outline_rect.mBottom); | ||
433 | glVertex2i(outline_rect.mRight, outline_rect.mBottom); | ||
434 | glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); | ||
435 | glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); | ||
436 | |||
437 | glVertex2i(outline_rect.mLeft, outline_rect.mTop); | ||
438 | glVertex2i(outline_rect.mLeft, outline_rect.mBottom); | ||
439 | glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); | ||
440 | glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); | ||
441 | |||
442 | glVertex2i(outline_rect.mRight, outline_rect.mBottom); | ||
443 | glVertex2i(outline_rect.mRight, outline_rect.mTop); | ||
444 | glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); | ||
445 | glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); | ||
446 | } | ||
447 | glEnd(); | ||
448 | } | ||
449 | |||
450 | // draw old image dropping away | ||
451 | if (mFallAnimTimer.getStarted()) | ||
452 | { | ||
453 | S32 old_image_index = (mCurImageIndex + 1) % 2; | ||
454 | if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) | ||
455 | { | ||
456 | LLGLSTexture texture_set; | ||
457 | |||
458 | F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME; | ||
459 | F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f); | ||
460 | LLColor4 image_color(1.f, 1.f, 1.f, alpha); | ||
461 | glColor4fv(image_color.mV); | ||
462 | LLViewerImage::bindTexture(mViewerImage[old_image_index]); | ||
463 | // calculate UV scale | ||
464 | // *FIX get this to work with old image | ||
465 | BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull(); | ||
466 | F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f; | ||
467 | F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f; | ||
468 | glPushMatrix(); | ||
469 | { | ||
470 | LLRect& rect = mImageRect[old_image_index]; | ||
471 | glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(mRect.getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); | ||
472 | glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f); | ||
473 | glBegin(GL_QUADS); | ||
474 | { | ||
475 | glTexCoord2f(uv_width, uv_height); | ||
476 | glVertex2i(rect.getWidth(), rect.getHeight() ); | ||
477 | |||
478 | glTexCoord2f(0.f, uv_height); | ||
479 | glVertex2i(0, rect.getHeight() ); | ||
480 | |||
481 | glTexCoord2f(0.f, 0.f); | ||
482 | glVertex2i(0, 0); | ||
483 | |||
484 | glTexCoord2f(uv_width, 0.f); | ||
485 | glVertex2i(rect.getWidth(), 0); | ||
486 | } | ||
487 | glEnd(); | ||
488 | } | ||
489 | glPopMatrix(); | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | |||
495 | /*virtual*/ | ||
496 | void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent) | ||
497 | { | ||
498 | LLRect old_rect = mRect; | ||
499 | LLView::reshape(width, height, called_from_parent); | ||
500 | if (old_rect.getWidth() != width || old_rect.getHeight() != height) | ||
501 | { | ||
502 | updateSnapshot(getSnapshotUpToDate()); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | //static | ||
507 | void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) | ||
508 | { | ||
509 | LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview; | ||
510 | |||
511 | LLVector3 new_camera_pos = gCamera->getOrigin(); | ||
512 | LLQuaternion new_camera_rot = gCamera->getQuaternion(); | ||
513 | if (gSavedSettings.getBOOL("FreezeTime") && | ||
514 | (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f)) | ||
515 | { | ||
516 | previewp->mCameraPos = new_camera_pos; | ||
517 | previewp->mCameraRot = new_camera_rot; | ||
518 | // request a new snapshot whenever the camera moves, with a time delay | ||
519 | previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); | ||
520 | } | ||
521 | |||
522 | previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() && | ||
523 | previewp->mSnapshotDelayTimer.hasExpired()); | ||
524 | |||
525 | // don't take snapshots while ALT-zoom active | ||
526 | if (gFocusMgr.getMouseCapture() == gToolCamera) | ||
527 | { | ||
528 | previewp->mSnapshotActive = FALSE; | ||
529 | } | ||
530 | |||
531 | if (previewp->mSnapshotActive) | ||
532 | { | ||
533 | if (!previewp->mRawImage) | ||
534 | { | ||
535 | previewp->mRawImage = new LLImageRaw; | ||
536 | } | ||
537 | |||
538 | if (!previewp->mRawImageEncoded) | ||
539 | { | ||
540 | previewp->mRawImageEncoded = new LLImageRaw; | ||
541 | } | ||
542 | |||
543 | previewp->setVisible(FALSE); | ||
544 | previewp->setEnabled(FALSE); | ||
545 | |||
546 | previewp->getWindow()->incBusyCount(); | ||
547 | previewp->mImageScaled[previewp->mCurImageIndex] = FALSE; | ||
548 | |||
549 | // do update | ||
550 | if(gViewerWindow->rawSnapshot(previewp->mRawImage, | ||
551 | previewp->mWidth[previewp->mCurImageIndex], | ||
552 | previewp->mHeight[previewp->mCurImageIndex], | ||
553 | !gSavedSettings.getBOOL("KeepAspectForSnapshot"), | ||
554 | gSavedSettings.getBOOL("RenderUIInSnapshot"), | ||
555 | FALSE, | ||
556 | previewp->mSnapshotBufferType)) | ||
557 | { | ||
558 | previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents()); | ||
559 | |||
560 | if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD) | ||
561 | { | ||
562 | // *FIX: just resize and reuse existing jpeg? | ||
563 | previewp->mJPEGImage = NULL; // deletes image | ||
564 | previewp->mJPEGImage = new LLImageJPEG(); | ||
565 | previewp->mJPEGImage->setEncodeQuality(llclamp(previewp->mSnapshotQuality, 0, 100)); | ||
566 | if (previewp->mJPEGImage->encode(previewp->mRawImage)) | ||
567 | { | ||
568 | previewp->mDataSize = previewp->mJPEGImage->getDataSize(); | ||
569 | previewp->mJPEGImage->decode(previewp->mRawImageEncoded); | ||
570 | } | ||
571 | } | ||
572 | else if (previewp->getSnapshotType() == SNAPSHOT_TEXTURE) | ||
573 | { | ||
574 | LLPointer<LLImageJ2C> formatted = new LLImageJ2C; | ||
575 | LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImage->getData(), | ||
576 | previewp->mRawImage->getWidth(), | ||
577 | previewp->mRawImage->getHeight(), | ||
578 | previewp->mRawImage->getComponents()); | ||
579 | |||
580 | scaled->biasedScaleToPowerOfTwo(512); | ||
581 | previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; | ||
582 | if (formatted->encode(scaled)) | ||
583 | { | ||
584 | previewp->mDataSize = formatted->getDataSize(); | ||
585 | formatted->decode(previewp->mRawImageEncoded); | ||
586 | } | ||
587 | } | ||
588 | else | ||
589 | { | ||
590 | previewp->mRawImageEncoded->copy(previewp->mRawImage); | ||
591 | previewp->mDataSize = previewp->mRawImage->getDataSize(); | ||
592 | } | ||
593 | |||
594 | LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImageEncoded->getData(), | ||
595 | previewp->mRawImageEncoded->getWidth(), | ||
596 | previewp->mRawImageEncoded->getHeight(), | ||
597 | previewp->mRawImageEncoded->getComponents()); | ||
598 | |||
599 | // leave original image dimensions, just scale up texture buffer | ||
600 | if (previewp->mRawImageEncoded->getWidth() > 1024 || previewp->mRawImageEncoded->getHeight() > 1024) | ||
601 | { | ||
602 | // go ahead and shrink image to appropriate power of 2 for display | ||
603 | scaled->biasedScaleToPowerOfTwo(1024); | ||
604 | previewp->mImageScaled[previewp->mCurImageIndex] = TRUE; | ||
605 | } | ||
606 | else | ||
607 | { | ||
608 | // expand image but keep original image data intact | ||
609 | scaled->expandToPowerOfTwo(1024, FALSE); | ||
610 | } | ||
611 | |||
612 | previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE); | ||
613 | previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE); | ||
614 | LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]); | ||
615 | previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE); | ||
616 | |||
617 | previewp->mSnapshotUpToDate = TRUE; | ||
618 | |||
619 | previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); | ||
620 | previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame | ||
621 | } | ||
622 | previewp->getWindow()->decBusyCount(); | ||
623 | // only show fullscreen preview when in freeze frame mode | ||
624 | previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame")); | ||
625 | previewp->mSnapshotDelayTimer.stop(); | ||
626 | previewp->mSnapshotActive = FALSE; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | void LLSnapshotLivePreview::setSize(S32 w, S32 h) | ||
631 | { | ||
632 | mWidth[mCurImageIndex] = w; | ||
633 | mHeight[mCurImageIndex] = h; | ||
634 | } | ||
635 | |||
636 | void LLSnapshotLivePreview::getSize(S32& w, S32& h) const | ||
637 | { | ||
638 | w = mWidth[mCurImageIndex]; | ||
639 | h = mHeight[mCurImageIndex]; | ||
640 | } | ||
641 | |||
642 | LLFloaterPostcard* LLSnapshotLivePreview::savePostcard() | ||
643 | { | ||
644 | // calculate and pass in image scale in case image data only use portion | ||
645 | // of viewerimage buffer | ||
646 | LLVector2 image_scale(1.f, 1.f); | ||
647 | if (!isImageScaled()) | ||
648 | { | ||
649 | image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight())); | ||
650 | } | ||
651 | |||
652 | |||
653 | LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(mJPEGImage, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal); | ||
654 | // relinquish lifetime of viewerimage and jpeg image to postcard floater | ||
655 | mViewerImage[mCurImageIndex] = NULL; | ||
656 | mJPEGImage = NULL; | ||
657 | |||
658 | return floater; | ||
659 | } | ||
660 | |||
661 | void LLSnapshotLivePreview::saveTexture() | ||
662 | { | ||
663 | // gen a new uuid for this asset | ||
664 | LLTransactionID tid; | ||
665 | tid.generate(); | ||
666 | LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
667 | |||
668 | LLPointer<LLImageJ2C> formatted = new LLImageJ2C; | ||
669 | LLPointer<LLImageRaw> scaled = new LLImageRaw(mRawImage->getData(), | ||
670 | mRawImage->getWidth(), | ||
671 | mRawImage->getHeight(), | ||
672 | mRawImage->getComponents()); | ||
673 | |||
674 | scaled->biasedScaleToPowerOfTwo(512); | ||
675 | |||
676 | if (formatted->encode(scaled)) | ||
677 | { | ||
678 | LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE); | ||
679 | std::string pos_string; | ||
680 | gAgent.buildLocationString(pos_string); | ||
681 | upload_new_resource(tid, // tid | ||
682 | LLAssetType::AT_TEXTURE, | ||
683 | "Snapshot", | ||
684 | pos_string, | ||
685 | 0, | ||
686 | LLAssetType::AT_SNAPSHOT_CATEGORY, | ||
687 | LLInventoryType::IT_SNAPSHOT, | ||
688 | PERM_ALL, | ||
689 | "Snapshot"); | ||
690 | } | ||
691 | else | ||
692 | { | ||
693 | gViewerWindow->alertXml("ErrorEncodingSnapshot"); | ||
694 | llwarns << "Error encoding snapshot" << llendl; | ||
695 | } | ||
696 | |||
697 | gViewerStats->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); | ||
698 | } | ||
699 | |||
700 | void LLSnapshotLivePreview::saveLocal() | ||
701 | { | ||
702 | gViewerWindow->saveImageNumbered(mRawImage); | ||
703 | } | ||
704 | |||
705 | ///---------------------------------------------------------------------------- | ||
706 | /// Class LLFloaterSnapshot::Impl | ||
707 | ///---------------------------------------------------------------------------- | ||
708 | |||
709 | class LLFloaterSnapshot::Impl | ||
710 | { | ||
711 | public: | ||
712 | Impl() : mLastToolset(NULL) | ||
713 | { | ||
714 | } | ||
715 | ~Impl() | ||
716 | { | ||
717 | //unpause avatars | ||
718 | mAvatarPauseHandles.clear(); | ||
719 | |||
720 | } | ||
721 | static void onClickDiscard(void* data); | ||
722 | static void onClickKeep(void* data); | ||
723 | static void onClickNewSnapshot(void* data); | ||
724 | static void onClickAutoSnap(LLUICtrl *ctrl, void* data); | ||
725 | static void onClickUICheck(LLUICtrl *ctrl, void* data); | ||
726 | static void onClickHUDCheck(LLUICtrl *ctrl, void* data); | ||
727 | static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); | ||
728 | static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data); | ||
729 | static void onCommitQuality(LLUICtrl* ctrl, void* data); | ||
730 | static void onCommitResolution(LLUICtrl* ctrl, void* data); | ||
731 | static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data); | ||
732 | static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); | ||
733 | static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); | ||
734 | static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); | ||
735 | |||
736 | static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); | ||
737 | static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); | ||
738 | static void updateControls(LLFloaterSnapshot* floater); | ||
739 | static void updateLayout(LLFloaterSnapshot* floater); | ||
740 | |||
741 | static LLViewHandle sPreviewHandle; | ||
742 | |||
743 | private: | ||
744 | static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); | ||
745 | static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); | ||
746 | static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); | ||
747 | static void checkAutoSnapshot(LLSnapshotLivePreview* floater); | ||
748 | |||
749 | public: | ||
750 | std::vector<LLAnimPauseRequest> mAvatarPauseHandles; | ||
751 | |||
752 | LLToolset* mLastToolset; | ||
753 | }; | ||
754 | |||
755 | // static | ||
756 | LLViewHandle LLFloaterSnapshot::Impl::sPreviewHandle; | ||
757 | |||
758 | // static | ||
759 | LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) | ||
760 | { | ||
761 | LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)LLView::getViewByHandle(sPreviewHandle); | ||
762 | return previewp; | ||
763 | } | ||
764 | |||
765 | // static | ||
766 | LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFloaterSnapshot* floater) | ||
767 | { | ||
768 | LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; | ||
769 | LLSD value = floater->childGetValue("snapshot_type_radio"); | ||
770 | const std::string id = value.asString(); | ||
771 | if (id == "postcard") | ||
772 | index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; | ||
773 | else if (id == "texture") | ||
774 | index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE; | ||
775 | else if (id == "local") | ||
776 | index = LLSnapshotLivePreview::SNAPSHOT_BITMAP; | ||
777 | return index; | ||
778 | } | ||
779 | |||
780 | // static | ||
781 | LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) | ||
782 | { | ||
783 | LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; | ||
784 | LLSD value = floater->childGetValue("layer_types"); | ||
785 | const std::string id = value.asString(); | ||
786 | if (id == "colors") | ||
787 | type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; | ||
788 | else if (id == "depth") | ||
789 | type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH; | ||
790 | else if (id == "objects") | ||
791 | type = LLViewerWindow::SNAPSHOT_TYPE_OBJECT_ID; | ||
792 | return type; | ||
793 | } | ||
794 | |||
795 | // static | ||
796 | void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname) | ||
797 | { | ||
798 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(floater, comboname); | ||
799 | if (combo) | ||
800 | { | ||
801 | combo->setVisible(TRUE); | ||
802 | onCommitResolution(combo, floater); | ||
803 | } | ||
804 | } | ||
805 | |||
806 | //static | ||
807 | void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) | ||
808 | { | ||
809 | LLSnapshotLivePreview* previewp = getPreviewView(floaterp); | ||
810 | if (floaterp->childGetValue("freeze_frame_check").asBoolean()) | ||
811 | { | ||
812 | // stop all mouse events at fullscreen preview layer | ||
813 | floaterp->getParent()->setMouseOpaque(TRUE); | ||
814 | |||
815 | // shrink to smaller layout | ||
816 | floaterp->reshape(floaterp->mRect.getWidth(), 410); | ||
817 | |||
818 | // can see and interact with fullscreen preview now | ||
819 | if (previewp) | ||
820 | { | ||
821 | previewp->setVisible(TRUE); | ||
822 | previewp->setEnabled(TRUE); | ||
823 | } | ||
824 | |||
825 | //RN: freeze all avatars | ||
826 | LLCharacter* avatarp; | ||
827 | for (avatarp = LLCharacter::sInstances.getFirstData(); avatarp; avatarp = LLCharacter::sInstances.getNextData()) | ||
828 | { | ||
829 | sInstance->impl.mAvatarPauseHandles.push_back(avatarp->requestPause()); | ||
830 | } | ||
831 | |||
832 | // freeze everything else | ||
833 | gSavedSettings.setBOOL("FreezeTime", TRUE); | ||
834 | |||
835 | if (gCurrentToolset != gCameraToolset) | ||
836 | { | ||
837 | sInstance->impl.mLastToolset = gCurrentToolset; | ||
838 | gCurrentToolset = gCameraToolset; | ||
839 | if (gToolMgr) | ||
840 | { | ||
841 | gToolMgr->useSelectedTool( gCurrentToolset ); | ||
842 | } | ||
843 | } | ||
844 | } | ||
845 | else // turning off freeze frame mode | ||
846 | { | ||
847 | floaterp->getParent()->setMouseOpaque(FALSE); | ||
848 | floaterp->reshape(floaterp->mRect.getWidth(), 510); | ||
849 | if (previewp) | ||
850 | { | ||
851 | previewp->setVisible(FALSE); | ||
852 | previewp->setEnabled(FALSE); | ||
853 | } | ||
854 | |||
855 | //RN: thaw all avatars | ||
856 | sInstance->impl.mAvatarPauseHandles.clear(); | ||
857 | |||
858 | // thaw everything else | ||
859 | gSavedSettings.setBOOL("FreezeTime", FALSE); | ||
860 | |||
861 | // restore last tool (e.g. pie menu, etc) | ||
862 | if (sInstance->impl.mLastToolset) | ||
863 | { | ||
864 | gCurrentToolset = sInstance->impl.mLastToolset; | ||
865 | if (gToolMgr) | ||
866 | { | ||
867 | gToolMgr->useSelectedTool( gCurrentToolset ); | ||
868 | } | ||
869 | } | ||
870 | } | ||
871 | } | ||
872 | |||
873 | |||
874 | // static | ||
875 | void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) | ||
876 | { | ||
877 | LLRadioGroup* snapshot_type_radio = LLUICtrlFactory::getRadioGroupByName(floater, "snapshot_type_radio"); | ||
878 | snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType")); | ||
879 | LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); | ||
880 | LLViewerWindow::ESnapshotType layer_type = getLayerType(floater); | ||
881 | |||
882 | floater->childSetVisible("postcard_size_combo", FALSE); | ||
883 | floater->childSetVisible("texture_size_combo", FALSE); | ||
884 | floater->childSetVisible("local_size_combo", FALSE); | ||
885 | |||
886 | LLComboBox* combo; | ||
887 | combo = LLUICtrlFactory::getComboBoxByName(floater, "postcard_size_combo"); | ||
888 | if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); | ||
889 | combo = LLUICtrlFactory::getComboBoxByName(floater, "texture_size_combo"); | ||
890 | if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); | ||
891 | combo = LLUICtrlFactory::getComboBoxByName(floater, "local_size_combo"); | ||
892 | if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); | ||
893 | |||
894 | |||
895 | floater->childSetVisible("upload_btn", FALSE); | ||
896 | floater->childSetVisible("send_btn", FALSE); | ||
897 | floater->childSetVisible("save_btn", FALSE); | ||
898 | |||
899 | switch(shot_type) | ||
900 | { | ||
901 | case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: | ||
902 | layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; | ||
903 | floater->childSetValue("layer_types", "colors"); | ||
904 | floater->childSetEnabled("layer_types", FALSE); | ||
905 | floater->childSetEnabled("image_quality_slider", TRUE); | ||
906 | setResolution(floater, "postcard_size_combo"); | ||
907 | floater->childSetVisible("send_btn", TRUE); | ||
908 | break; | ||
909 | case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: | ||
910 | layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; | ||
911 | floater->childSetValue("layer_types", "colors"); | ||
912 | floater->childSetEnabled("layer_types", FALSE); | ||
913 | floater->childSetEnabled("image_quality_slider", FALSE); | ||
914 | setResolution(floater, "texture_size_combo"); | ||
915 | floater->childSetVisible("upload_btn", TRUE); | ||
916 | break; | ||
917 | case LLSnapshotLivePreview::SNAPSHOT_BITMAP: | ||
918 | floater->childSetEnabled("layer_types", TRUE); | ||
919 | floater->childSetEnabled("image_quality_slider", FALSE); | ||
920 | setResolution(floater, "local_size_combo"); | ||
921 | floater->childSetVisible("save_btn", TRUE); | ||
922 | break; | ||
923 | default: | ||
924 | break; | ||
925 | } | ||
926 | LLSnapshotLivePreview* previewp = getPreviewView(floater); | ||
927 | if (previewp) | ||
928 | { | ||
929 | previewp->setSnapshotType(shot_type); | ||
930 | previewp->setSnapshotBufferType(layer_type); | ||
931 | } | ||
932 | } | ||
933 | |||
934 | // static | ||
935 | void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp) | ||
936 | { | ||
937 | if (previewp) | ||
938 | { | ||
939 | previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); | ||
940 | } | ||
941 | } | ||
942 | |||
943 | // static | ||
944 | void LLFloaterSnapshot::Impl::onClickDiscard(void* data) | ||
945 | { | ||
946 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
947 | if (view) | ||
948 | { | ||
949 | view->close(); | ||
950 | } | ||
951 | } | ||
952 | |||
953 | // static | ||
954 | void LLFloaterSnapshot::Impl::onClickKeep(void* data) | ||
955 | { | ||
956 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
957 | LLSnapshotLivePreview* previewp = getPreviewView(view); | ||
958 | |||
959 | if (previewp) | ||
960 | { | ||
961 | if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) | ||
962 | { | ||
963 | LLFloaterPostcard* floater = previewp->savePostcard(); | ||
964 | // if still in snapshot mode, put postcard floater in snapshot floaterview | ||
965 | // and link it to snapshot floater | ||
966 | if (!gSavedSettings.getBOOL("CloseSnapshotOnKeep")) | ||
967 | { | ||
968 | gFloaterView->removeChild(floater); | ||
969 | gSnapshotFloaterView->addChild(floater); | ||
970 | view->addDependentFloater(floater, FALSE); | ||
971 | } | ||
972 | } | ||
973 | else if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE) | ||
974 | { | ||
975 | previewp->saveTexture(); | ||
976 | } | ||
977 | else | ||
978 | { | ||
979 | previewp->saveLocal(); | ||
980 | } | ||
981 | |||
982 | if (gSavedSettings.getBOOL("CloseSnapshotOnKeep")) | ||
983 | { | ||
984 | view->close(); | ||
985 | // only plays sound and anim when keeping a snapshot, and closing the snapshot UI | ||
986 | gViewerWindow->playSnapshotAnimAndSound(); | ||
987 | } | ||
988 | else | ||
989 | { | ||
990 | checkAutoSnapshot(previewp); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | } | ||
995 | |||
996 | // static | ||
997 | void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data) | ||
998 | { | ||
999 | LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data); | ||
1000 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1001 | if (previewp && view) | ||
1002 | { | ||
1003 | previewp->updateSnapshot(TRUE); | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | // static | ||
1008 | void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) | ||
1009 | { | ||
1010 | LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; | ||
1011 | gSavedSettings.setBOOL( "AutoSnapshot", check->get() ); | ||
1012 | |||
1013 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1014 | if (view) | ||
1015 | { | ||
1016 | checkAutoSnapshot(getPreviewView(view)); | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1020 | // static | ||
1021 | void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) | ||
1022 | { | ||
1023 | LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; | ||
1024 | gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() ); | ||
1025 | |||
1026 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1027 | if (view) | ||
1028 | { | ||
1029 | checkAutoSnapshot(getPreviewView(view)); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | // static | ||
1034 | void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) | ||
1035 | { | ||
1036 | LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; | ||
1037 | gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() ); | ||
1038 | |||
1039 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1040 | if (view) | ||
1041 | { | ||
1042 | checkAutoSnapshot(getPreviewView(view)); | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | // static | ||
1047 | void LLFloaterSnapshot::Impl::onClickKeepOpenCheck(LLUICtrl* ctrl, void* data) | ||
1048 | { | ||
1049 | LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; | ||
1050 | |||
1051 | gSavedSettings.setBOOL( "CloseSnapshotOnKeep", !check->get() ); | ||
1052 | } | ||
1053 | |||
1054 | // static | ||
1055 | void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) | ||
1056 | { | ||
1057 | LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; | ||
1058 | gSavedSettings.setBOOL( "KeepAspectForSnapshot", check->get() ); | ||
1059 | |||
1060 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1061 | if (view) | ||
1062 | { | ||
1063 | checkAutoSnapshot(getPreviewView(view)); | ||
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | // static | ||
1068 | void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data) | ||
1069 | { | ||
1070 | LLSliderCtrl* slider = (LLSliderCtrl*)ctrl; | ||
1071 | S32 quality_val = llfloor((F32)slider->getValue().asReal()); | ||
1072 | |||
1073 | LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data); | ||
1074 | if (previewp) | ||
1075 | { | ||
1076 | previewp->setSnapshotQuality(quality_val); | ||
1077 | } | ||
1078 | checkAutoSnapshot(previewp); | ||
1079 | } | ||
1080 | |||
1081 | // static | ||
1082 | void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) | ||
1083 | { | ||
1084 | LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; | ||
1085 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1086 | |||
1087 | if (!view || !check_box) | ||
1088 | { | ||
1089 | return; | ||
1090 | } | ||
1091 | |||
1092 | gSavedSettings.setBOOL("UseFreezeFrame", check_box->get()); | ||
1093 | |||
1094 | updateLayout(view); | ||
1095 | } | ||
1096 | |||
1097 | // static | ||
1098 | void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data) | ||
1099 | { | ||
1100 | LLComboBox* combobox = (LLComboBox*)ctrl; | ||
1101 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1102 | |||
1103 | if (!view || !combobox) | ||
1104 | { | ||
1105 | return; | ||
1106 | } | ||
1107 | |||
1108 | // save off all selected resolution values | ||
1109 | LLComboBox* combo; | ||
1110 | combo = LLUICtrlFactory::getComboBoxByName(view, "postcard_size_combo"); | ||
1111 | gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex()); | ||
1112 | combo = LLUICtrlFactory::getComboBoxByName(view, "texture_size_combo"); | ||
1113 | gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex()); | ||
1114 | combo = LLUICtrlFactory::getComboBoxByName(view, "local_size_combo"); | ||
1115 | gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex()); | ||
1116 | |||
1117 | std::string sdstring = combobox->getSimpleSelectedValue(); | ||
1118 | LLSD sdres; | ||
1119 | std::stringstream sstream(sdstring); | ||
1120 | LLSDSerialize::fromNotation(sdres, sstream); | ||
1121 | |||
1122 | S32 width = sdres[0]; | ||
1123 | S32 height = sdres[1]; | ||
1124 | |||
1125 | LLSnapshotLivePreview* previewp = getPreviewView(view); | ||
1126 | if (previewp && combobox->getCurrentIndex() >= 0) | ||
1127 | { | ||
1128 | if (width == 0 || height == 0) | ||
1129 | { | ||
1130 | previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); | ||
1131 | } | ||
1132 | else if (width == -1 || height == -1) | ||
1133 | { | ||
1134 | // leave width and height when entering custom value | ||
1135 | } | ||
1136 | else | ||
1137 | { | ||
1138 | previewp->setSize(width, height); | ||
1139 | } | ||
1140 | |||
1141 | previewp->getSize(width, height); | ||
1142 | view->childSetValue("snapshot_width", width); | ||
1143 | view->childSetValue("snapshot_height", height); | ||
1144 | // hide old preview as the aspect ratio could be wrong | ||
1145 | checkAutoSnapshot(previewp); | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | // static | ||
1150 | void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) | ||
1151 | { | ||
1152 | LLComboBox* combobox = (LLComboBox*)ctrl; | ||
1153 | |||
1154 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1155 | |||
1156 | if (view) | ||
1157 | { | ||
1158 | LLSnapshotLivePreview* previewp = getPreviewView(view); | ||
1159 | if (previewp) | ||
1160 | { | ||
1161 | previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex()); | ||
1162 | } | ||
1163 | checkAutoSnapshot(previewp); | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | //static | ||
1168 | void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) | ||
1169 | { | ||
1170 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1171 | if (view) | ||
1172 | { | ||
1173 | gSavedSettings.setS32("LastSnapshotType", getTypeIndex(view)); | ||
1174 | getPreviewView(view)->updateSnapshot(TRUE); | ||
1175 | updateControls(view); | ||
1176 | } | ||
1177 | } | ||
1178 | |||
1179 | // static | ||
1180 | void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) | ||
1181 | { | ||
1182 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(floater, comboname); | ||
1183 | if (combo) | ||
1184 | { | ||
1185 | combo->setCurrentByIndex(combo->getItemCount() - 1); | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | //static | ||
1190 | void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* data) | ||
1191 | { | ||
1192 | LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; | ||
1193 | if (view) | ||
1194 | { | ||
1195 | LLSnapshotLivePreview* previewp = getPreviewView(view); | ||
1196 | if (previewp) | ||
1197 | { | ||
1198 | S32 curw,curh; | ||
1199 | previewp->getSize(curw, curh); | ||
1200 | |||
1201 | S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal()); | ||
1202 | S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal()); | ||
1203 | |||
1204 | if (w != curw || h != curh) | ||
1205 | { | ||
1206 | previewp->setSize(w,h); | ||
1207 | checkAutoSnapshot(previewp); | ||
1208 | comboSetCustom(view, "postcard_size_combo"); | ||
1209 | comboSetCustom(view, "texture_size_combo"); | ||
1210 | comboSetCustom(view, "local_size_combo"); | ||
1211 | } | ||
1212 | } | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | ///---------------------------------------------------------------------------- | ||
1217 | /// Class LLFloaterSnapshot | ||
1218 | ///---------------------------------------------------------------------------- | ||
1219 | |||
1220 | // Default constructor | ||
1221 | LLFloaterSnapshot::LLFloaterSnapshot() | ||
1222 | : LLFloater("Snapshot Floater"), | ||
1223 | impl (*(new Impl)) | ||
1224 | { | ||
1225 | } | ||
1226 | |||
1227 | // Destroys the object | ||
1228 | LLFloaterSnapshot::~LLFloaterSnapshot() | ||
1229 | { | ||
1230 | if (sInstance == this) | ||
1231 | { | ||
1232 | delete LLView::getViewByHandle(Impl::sPreviewHandle); | ||
1233 | Impl::sPreviewHandle = LLViewHandle::sDeadHandle; | ||
1234 | sInstance = NULL; | ||
1235 | } | ||
1236 | |||
1237 | //unfreeze everything else | ||
1238 | gSavedSettings.setBOOL("FreezeTime", FALSE); | ||
1239 | |||
1240 | if (impl.mLastToolset) | ||
1241 | { | ||
1242 | gCurrentToolset = impl.mLastToolset; | ||
1243 | if (gToolMgr && gCurrentToolset) | ||
1244 | { | ||
1245 | gToolMgr->useSelectedTool( gCurrentToolset ); | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | delete &impl; | ||
1250 | } | ||
1251 | |||
1252 | BOOL LLFloaterSnapshot::postBuild() | ||
1253 | { | ||
1254 | childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this); | ||
1255 | |||
1256 | childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); | ||
1257 | |||
1258 | childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot")); | ||
1259 | childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); | ||
1260 | |||
1261 | childSetAction("upload_btn", Impl::onClickKeep, this); | ||
1262 | childSetAction("send_btn", Impl::onClickKeep, this); | ||
1263 | childSetAction("save_btn", Impl::onClickKeep, this); | ||
1264 | childSetAction("discard_btn", Impl::onClickDiscard, this); | ||
1265 | |||
1266 | childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this); | ||
1267 | childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality")); | ||
1268 | |||
1269 | childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this); | ||
1270 | |||
1271 | childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this); | ||
1272 | |||
1273 | childSetCommitCallback("ui_check", Impl::onClickUICheck, this); | ||
1274 | |||
1275 | childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this); | ||
1276 | childSetValue("hud_check", gSavedSettings.getBOOL("RenderHUDInSnapshot")); | ||
1277 | |||
1278 | childSetCommitCallback("keep_open_check", Impl::onClickKeepOpenCheck, this); | ||
1279 | childSetValue("keep_open_check", !gSavedSettings.getBOOL("CloseSnapshotOnKeep")); | ||
1280 | |||
1281 | childSetCommitCallback("keep_aspect_check", Impl::onClickKeepAspectCheck, this); | ||
1282 | childSetValue("keep_aspect_check", gSavedSettings.getBOOL("KeepAspectForSnapshot")); | ||
1283 | |||
1284 | childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this); | ||
1285 | childSetValue("layer_types", "colors"); | ||
1286 | childSetEnabled("layer_types", FALSE); | ||
1287 | |||
1288 | childSetValue("snapshot_width", gViewerWindow->getWindowDisplayWidth()); | ||
1289 | childSetValue("snapshot_height", gViewerWindow->getWindowDisplayHeight()); | ||
1290 | |||
1291 | childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame")); | ||
1292 | childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this); | ||
1293 | |||
1294 | childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this); | ||
1295 | childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this); | ||
1296 | childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this); | ||
1297 | |||
1298 | // create preview window | ||
1299 | LLRect full_screen_rect = sInstance->getRootView()->getRect(); | ||
1300 | LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(full_screen_rect); | ||
1301 | sInstance->getRootView()->removeChild(gSnapshotFloaterView); | ||
1302 | // make sure preview is below snapshot floater | ||
1303 | sInstance->getRootView()->addChild(previewp); | ||
1304 | sInstance->getRootView()->addChild(gSnapshotFloaterView); | ||
1305 | |||
1306 | Impl::sPreviewHandle = previewp->mViewHandle; | ||
1307 | |||
1308 | impl.updateControls(this); | ||
1309 | |||
1310 | return TRUE; | ||
1311 | } | ||
1312 | |||
1313 | void LLFloaterSnapshot::draw() | ||
1314 | { | ||
1315 | LLSnapshotLivePreview* previewp = impl.getPreviewView(this); | ||
1316 | |||
1317 | if (previewp && previewp->isSnapshotActive()) | ||
1318 | { | ||
1319 | // don't render snapshot window in snapshot, even if "show ui" is turned on | ||
1320 | return; | ||
1321 | } | ||
1322 | |||
1323 | if(getVisible() && !mMinimized) | ||
1324 | { | ||
1325 | if (previewp && previewp->getDataSize() > 0) | ||
1326 | { | ||
1327 | LLLocale locale(LLLocale::USER_LOCALE); | ||
1328 | |||
1329 | LLString bytes_string; | ||
1330 | if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && | ||
1331 | previewp->getDataSize() > MAX_POSTCARD_DATASIZE) | ||
1332 | { | ||
1333 | childSetColor("file_size_label", LLColor4::red); | ||
1334 | childSetEnabled("send_btn", FALSE); | ||
1335 | } | ||
1336 | else | ||
1337 | { | ||
1338 | childSetColor("file_size_label", gColors.getColor( "LabelTextColor" )); | ||
1339 | childSetEnabled("send_btn", previewp->getSnapshotUpToDate()); | ||
1340 | } | ||
1341 | |||
1342 | //XUI:translate | ||
1343 | if (previewp->getSnapshotUpToDate()) | ||
1344 | { | ||
1345 | LLString bytes_string; | ||
1346 | gResMgr->getIntegerString(bytes_string, previewp->getDataSize()); | ||
1347 | childSetTextArg("file_size_label", "[SIZE]", llformat("%s bytes", bytes_string.c_str())); | ||
1348 | } | ||
1349 | else | ||
1350 | { | ||
1351 | childSetTextArg("file_size_label", "[SIZE]", "unknown"); | ||
1352 | childSetColor("file_size_label", gColors.getColor( "LabelTextColor" )); | ||
1353 | } | ||
1354 | childSetEnabled("upload_btn", previewp->getSnapshotUpToDate()); | ||
1355 | childSetEnabled("save_btn", previewp->getSnapshotUpToDate()); | ||
1356 | |||
1357 | } | ||
1358 | else | ||
1359 | { | ||
1360 | childSetTextArg("file_size_label", "[SIZE]", "unknown"); | ||
1361 | childSetEnabled("upload_btn", FALSE); | ||
1362 | childSetEnabled("send_btn", FALSE); | ||
1363 | childSetEnabled("save_btn", FALSE); | ||
1364 | } | ||
1365 | |||
1366 | BOOL ui_in_snapshot = gSavedSettings.getBOOL("RenderUIInSnapshot"); | ||
1367 | childSetValue("ui_check", ui_in_snapshot); | ||
1368 | childSetToolTip("ui_check", "If selected shows the UI in the snapshot"); | ||
1369 | } | ||
1370 | |||
1371 | LLFloater::draw(); | ||
1372 | |||
1373 | // draw snapshot thumbnail if not in fullscreen preview mode | ||
1374 | if (!gSavedSettings.getBOOL("UseFreezeFrame") && previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) | ||
1375 | { | ||
1376 | F32 aspect = previewp->getImageAspect(); | ||
1377 | // UI size for thumbnail | ||
1378 | S32 max_width = mRect.getWidth() - 20; | ||
1379 | S32 max_height = 90; | ||
1380 | |||
1381 | S32 img_render_width = 0; | ||
1382 | S32 img_render_height = 0; | ||
1383 | if (aspect > max_width / max_height) | ||
1384 | { | ||
1385 | // image too wide, shrink to width | ||
1386 | img_render_width = max_width; | ||
1387 | img_render_height = llround((F32)max_width / aspect); | ||
1388 | } | ||
1389 | else | ||
1390 | { | ||
1391 | // image too tall, shrink to height | ||
1392 | img_render_height = max_height; | ||
1393 | img_render_width = llround((F32)max_height * aspect); | ||
1394 | } | ||
1395 | S32 image_width, image_height; | ||
1396 | previewp->getSize(image_width, image_height); | ||
1397 | glMatrixMode(GL_TEXTURE); | ||
1398 | glPushMatrix(); | ||
1399 | { | ||
1400 | // handle case where image is only a portion of image buffer | ||
1401 | if (!previewp->isImageScaled()) | ||
1402 | { | ||
1403 | glScalef(llmin(1.f, (F32)image_width / (F32)previewp->getCurrentImage()->getWidth()), llmin(1.f, (F32)image_height / (F32)previewp->getCurrentImage()->getHeight()), 1.f); | ||
1404 | } | ||
1405 | glMatrixMode(GL_MODELVIEW); | ||
1406 | gl_draw_scaled_image((mRect.getWidth() - img_render_width) / 2, 35 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white); | ||
1407 | } | ||
1408 | glMatrixMode(GL_TEXTURE); | ||
1409 | glPopMatrix(); | ||
1410 | glMatrixMode(GL_MODELVIEW); | ||
1411 | } | ||
1412 | } | ||
1413 | |||
1414 | void LLFloaterSnapshot::onClose(bool app_quitting) | ||
1415 | { | ||
1416 | gSnapshotFloaterView->setEnabled(FALSE); | ||
1417 | destroy(); | ||
1418 | } | ||
1419 | |||
1420 | // static | ||
1421 | void LLFloaterSnapshot::show(void*) | ||
1422 | { | ||
1423 | if (!sInstance) | ||
1424 | { | ||
1425 | sInstance = new LLFloaterSnapshot(); | ||
1426 | |||
1427 | gUICtrlFactory->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE); | ||
1428 | //move snapshot floater to special purpose snapshotfloaterview | ||
1429 | gFloaterView->removeChild(sInstance); | ||
1430 | gSnapshotFloaterView->addChild(sInstance); | ||
1431 | |||
1432 | sInstance->impl.updateLayout(sInstance); | ||
1433 | } | ||
1434 | |||
1435 | sInstance->open(); | ||
1436 | sInstance->focusFirstItem(FALSE); | ||
1437 | gSnapshotFloaterView->setEnabled(TRUE); | ||
1438 | gSnapshotFloaterView->adjustToFitScreen(sInstance, FALSE); | ||
1439 | } | ||
1440 | |||
1441 | void LLFloaterSnapshot::hide(void*) | ||
1442 | { | ||
1443 | if (sInstance && !sInstance->isDead()) | ||
1444 | { | ||
1445 | sInstance->close(); | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | //static | ||
1450 | void LLFloaterSnapshot::update() | ||
1451 | { | ||
1452 | for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin(); | ||
1453 | iter != LLSnapshotLivePreview::sList.end(); ++iter) | ||
1454 | { | ||
1455 | LLSnapshotLivePreview::onIdle(*iter); | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | //============================================================================ | ||
1460 | |||
1461 | LLSnapshotFloaterView::LLSnapshotFloaterView( const LLString& name, const LLRect& rect ) : LLFloaterView(name, rect) | ||
1462 | { | ||
1463 | setMouseOpaque(TRUE); | ||
1464 | setEnabled(FALSE); | ||
1465 | } | ||
1466 | |||
1467 | LLSnapshotFloaterView::~LLSnapshotFloaterView() | ||
1468 | { | ||
1469 | } | ||
1470 | |||
1471 | BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent) | ||
1472 | { | ||
1473 | // use default handler when not in freeze-frame mode | ||
1474 | if(!gSavedSettings.getBOOL("FreezeTime")) | ||
1475 | { | ||
1476 | return LLFloaterView::handleKey(key, mask, called_from_parent); | ||
1477 | } | ||
1478 | |||
1479 | if (!getEnabled()) | ||
1480 | { | ||
1481 | return FALSE; | ||
1482 | } | ||
1483 | else | ||
1484 | { | ||
1485 | if (called_from_parent) | ||
1486 | { | ||
1487 | // pass all keystrokes down | ||
1488 | LLFloaterView::handleKey(key, mask, called_from_parent); | ||
1489 | } | ||
1490 | else | ||
1491 | { | ||
1492 | // bounce keystrokes back down | ||
1493 | LLFloaterView::handleKey(key, mask, TRUE); | ||
1494 | } | ||
1495 | return TRUE; | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask) | ||
1500 | { | ||
1501 | // use default handler when not in freeze-frame mode | ||
1502 | if(!gSavedSettings.getBOOL("FreezeTime")) | ||
1503 | { | ||
1504 | return LLFloaterView::handleMouseDown(x, y, mask); | ||
1505 | } | ||
1506 | // give floater a change to handle mouse, else camera tool | ||
1507 | if (childrenHandleMouseDown(x, y, mask) == NULL) | ||
1508 | { | ||
1509 | gToolMgr->getCurrentTool(mask)->handleMouseDown( x, y, mask ); | ||
1510 | } | ||
1511 | return TRUE; | ||
1512 | } | ||
1513 | |||
1514 | BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask) | ||
1515 | { | ||
1516 | // use default handler when not in freeze-frame mode | ||
1517 | if(!gSavedSettings.getBOOL("FreezeTime")) | ||
1518 | { | ||
1519 | return LLFloaterView::handleMouseUp(x, y, mask); | ||
1520 | } | ||
1521 | // give floater a change to handle mouse, else camera tool | ||
1522 | if (childrenHandleMouseUp(x, y, mask) == NULL) | ||
1523 | { | ||
1524 | gToolMgr->getCurrentTool(mask)->handleMouseUp( x, y, mask ); | ||
1525 | } | ||
1526 | return TRUE; | ||
1527 | } | ||
1528 | |||
1529 | BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask) | ||
1530 | { | ||
1531 | // use default handler when not in freeze-frame mode | ||
1532 | if(!gSavedSettings.getBOOL("FreezeTime")) | ||
1533 | { | ||
1534 | return LLFloaterView::handleHover(x, y, mask); | ||
1535 | } | ||
1536 | // give floater a change to handle mouse, else camera tool | ||
1537 | if (childrenHandleHover(x, y, mask) == NULL) | ||
1538 | { | ||
1539 | gToolMgr->getCurrentTool(mask)->handleHover( x, y, mask ); | ||
1540 | } | ||
1541 | return TRUE; | ||
1542 | } | ||