aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llpreviewtexture.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llpreviewtexture.cpp
parentREADME.txt (diff)
downloadmeta-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 'linden/indra/newview/llpreviewtexture.cpp')
-rw-r--r--linden/indra/newview/llpreviewtexture.cpp387
1 files changed, 387 insertions, 0 deletions
diff --git a/linden/indra/newview/llpreviewtexture.cpp b/linden/indra/newview/llpreviewtexture.cpp
new file mode 100644
index 0000000..7948db4
--- /dev/null
+++ b/linden/indra/newview/llpreviewtexture.cpp
@@ -0,0 +1,387 @@
1/**
2 * @file llpreviewtexture.cpp
3 * @brief LLPreviewTexture class implementation
4 *
5 * Copyright (c) 2002-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 "llpreviewtexture.h"
31
32#include "llviewerimage.h"
33#include "llviewerimagelist.h"
34#include "llresmgr.h"
35#include "llagent.h"
36#include "llbutton.h"
37#include "llui.h"
38#include "llinventoryview.h"
39#include "llinventory.h"
40#include "llviewerwindow.h"
41#include "lltextbox.h"
42#include "llimagetga.h"
43#include "llfilepicker.h"
44#include "llvieweruictrlfactory.h"
45
46const S32 PREVIEW_TEXTURE_MIN_WIDTH = 300;
47const S32 PREVIEW_TEXTURE_MIN_HEIGHT = 120;
48
49const S32 CLIENT_RECT_VPAD = 4;
50
51const F32 SECONDS_TO_SHOW_FILE_SAVED_MSG = 8.f;
52
53LLPreviewTexture::LLPreviewTexture(const std::string& name,
54 const LLRect& rect,
55 const std::string& title,
56 const LLUUID& item_uuid,
57 const LLUUID& object_id,
58 BOOL show_keep_discard)
59: LLPreview(name, rect, title, item_uuid, object_id, TRUE, PREVIEW_TEXTURE_MIN_WIDTH, PREVIEW_TEXTURE_MIN_HEIGHT ),
60 mLoadingFullImage( FALSE ),
61 mShowKeepDiscard(show_keep_discard),
62 mCopyToInv(FALSE),
63 mIsCopyable(FALSE),
64 mLastHeight(0),
65 mLastWidth(0)
66{
67 LLInventoryItem *item = getItem();
68 if(item)
69 {
70 mImageID = item->getAssetUUID();
71 const LLPermissions& perm = item->getPermissions();
72 U32 mask = PERM_NONE;
73 if(perm.getOwner() == gAgent.getID())
74 {
75 mask = perm.getMaskBase();
76 }
77 else if(gAgent.isInGroup(perm.getGroup()))
78 {
79 mask = perm.getMaskGroup();
80 }
81 else
82 {
83 mask = perm.getMaskEveryone();
84 }
85 if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
86 {
87 mIsCopyable = TRUE;
88 }
89 }
90
91 init();
92
93 setTitle(title);
94
95 if (!getHost())
96 {
97 LLRect curRect = getRect();
98 translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
99 }
100}
101
102
103// Note: uses asset_id as a dummy item id.
104LLPreviewTexture::LLPreviewTexture(
105 const std::string& name,
106 const LLRect& rect,
107 const std::string& title,
108 const LLUUID& asset_id,
109 BOOL copy_to_inv)
110 :
111 LLPreview(
112 name,
113 rect,
114 title,
115 asset_id,
116 LLUUID::null,
117 TRUE,
118 PREVIEW_TEXTURE_MIN_WIDTH,
119 PREVIEW_TEXTURE_MIN_HEIGHT ),
120 mImageID(asset_id),
121 mLoadingFullImage( FALSE ),
122 mShowKeepDiscard(FALSE),
123 mCopyToInv(copy_to_inv),
124 mIsCopyable(TRUE),
125 mLastHeight(0),
126 mLastWidth(0)
127{
128
129 init();
130
131 setTitle(title);
132
133 LLRect curRect = getRect();
134 translate(curRect.mLeft - rect.mLeft, curRect.mTop - rect.mTop);
135
136}
137
138
139LLPreviewTexture::~LLPreviewTexture()
140{
141 if( mLoadingFullImage )
142 {
143 getWindow()->decBusyCount();
144 }
145
146 mImage = NULL;
147}
148
149
150void LLPreviewTexture::init()
151{
152
153
154 if (mCopyToInv)
155 {
156 gUICtrlFactory->buildFloater(this,"floater_preview_embedded_texture.xml");
157
158 childSetAction("Copy To Inventory",LLPreview::onBtnCopyToInv,this);
159 }
160
161 else if (mShowKeepDiscard)
162 {
163 gUICtrlFactory->buildFloater(this,"floater_preview_texture_keep_discard.xml");
164
165 childSetAction("Keep",onKeepBtn,this);
166 childSetAction("Discard",onDiscardBtn,this);
167 }
168
169 else
170 {
171 gUICtrlFactory->buildFloater(this,"floater_preview_texture.xml");
172 }
173
174
175 if (!mCopyToInv)
176 {
177 LLInventoryItem* item = getItem();
178
179 if (item)
180 {
181 childSetCommitCallback("desc", LLPreview::onText, this);
182 childSetText("desc", item->getDescription());
183 childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
184 }
185 }
186}
187
188
189// virtual
190BOOL LLPreviewTexture::canSaveAs()
191{
192 return mIsCopyable && !mLoadingFullImage && mImage.notNull() && !mImage->isMissingAsset();
193}
194
195
196// virtual
197void LLPreviewTexture::saveAs()
198{
199 if( !mLoadingFullImage )
200 {
201 LLFilePicker& file_picker = LLFilePicker::instance();
202 if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA ) )
203 {
204 // User canceled save.
205 return;
206 }
207 mSaveFileName = file_picker.getFirstFile();
208 mLoadingFullImage = TRUE;
209 getWindow()->incBusyCount();
210 mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,
211 0,
212 TRUE,
213 new LLUUID( mItemUUID ) );
214 }
215}
216
217
218// static
219void LLPreviewTexture::onFileLoadedForSave(BOOL success,
220 LLViewerImage *src_vi,
221 LLImageRaw* src,
222 LLImageRaw* aux_src,
223 S32 discard_level,
224 BOOL final,
225 void* userdata)
226{
227 LLUUID* item_uuid = (LLUUID*) userdata;
228 LLPreviewTexture* self = NULL;
229 preview_map_t::iterator found_it = LLPreview::sInstances.find(*item_uuid);
230 if(found_it != LLPreview::sInstances.end())
231 {
232 self = (LLPreviewTexture*) found_it->second;
233 }
234
235 if( final || !success )
236 {
237 delete item_uuid;
238
239 if( self )
240 {
241 self->getWindow()->decBusyCount();
242 self->mLoadingFullImage = FALSE;
243 }
244 }
245
246 if( self && final && success )
247 {
248 LLPointer<LLImageTGA> image_tga = new LLImageTGA;
249 if( !image_tga->encode( src ) )
250 {
251 LLStringBase<char>::format_map_t args;
252 args["[FILE]"] = self->mSaveFileName;
253 gViewerWindow->alertXml("CannotEncodeFile", args);
254 }
255 else if( !image_tga->save( self->mSaveFileName ) )
256 {
257 LLStringBase<char>::format_map_t args;
258 args["[FILE]"] = self->mSaveFileName;
259 gViewerWindow->alertXml("CannotWriteFile", args);
260 }
261 else
262 {
263 self->mSavedFileTimer.reset();
264 self->mSavedFileTimer.setTimerExpirySec( SECONDS_TO_SHOW_FILE_SAVED_MSG );
265 }
266
267 self->mSaveFileName.clear();
268 }
269
270 if( self && !success )
271 {
272 gViewerWindow->alertXml("CannotDownloadFile");
273 }
274}
275
276
277// It takes a while until we get height and width information.
278// When we receive it, reshape the window accordingly.
279void LLPreviewTexture::updateAspectRatio()
280{
281 if (!mImage) return;
282
283 S32 image_height = llmax(1, mImage->getHeight(0));
284 S32 image_width = llmax(1, mImage->getWidth(0));
285 // Attempt to make the image 1:1 on screen.
286 // If that fails, cut width by half.
287 S32 client_width = image_width;
288 S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
289 S32 screen_width = gViewerWindow->getWindowWidth();
290 S32 max_client_width = screen_width - horiz_pad;
291
292 while (client_width > max_client_width)
293 {
294 client_width /= 2;
295 }
296
297 // Demand width at least 128
298 if (client_width < 128)
299 {
300 client_width = 128;
301 }
302
303 S32 view_width = client_width + horiz_pad;
304
305 // Adjust the height based on the width computed above.
306 F32 inv_aspect_ratio = (F32) image_height / (F32) image_width;
307 S32 client_height = llround(client_width * inv_aspect_ratio);
308 S32 view_height =
309 PREVIEW_HEADER_SIZE + // header (includes top border)
310 client_height + 2 * CLIENT_RECT_VPAD + // texture plus uniform spacing (which leaves room for resize handle)
311 LLPANEL_BORDER_WIDTH; // bottom border
312
313 // set text on dimensions display (should be moved out of here and into a callback of some sort)
314 childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth));
315 childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->mFullHeight));
316
317 // add space for dimensions
318 S32 info_height = 0;
319 LLRect dim_rect;
320 childGetRect("dimensions", dim_rect);
321 S32 dim_height = dim_rect.getHeight();
322 info_height += dim_height + CLIENT_RECT_VPAD;
323 view_height += info_height;
324
325 S32 button_height = 0;
326 if (mShowKeepDiscard || mCopyToInv) { //mCopyToInvBtn
327
328 // add space for buttons
329 view_height += BTN_HEIGHT + CLIENT_RECT_VPAD;
330 button_height = BTN_HEIGHT + PREVIEW_PAD;
331 }
332
333 LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0);
334 window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
335 window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD;
336 LLMultiFloater* hostp = getHost();
337 if (hostp)
338 {
339 // try to keep aspect ratio when hosted, as hosting view can resize without user input
340 mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height);
341 }
342 else
343 {
344 mClientRect.setLeftTopAndSize(LLPANEL_BORDER_WIDTH + PREVIEW_PAD + 6,
345 mRect.getHeight() - (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD),
346 mRect.getWidth() - horiz_pad,
347 mRect.getHeight() - (view_height - client_height) - 8);
348 }
349
350 if (mImage->mFullHeight > mLastHeight && mImage->mFullWidth > mLastWidth)
351 {
352 mLastWidth = image_width;
353 mLastHeight = image_height;
354
355 S32 old_top = mRect.mTop;
356 S32 old_left = mRect.mLeft;
357 if (hostp)
358 {
359 hostp->growToFit(this, view_width, view_height);
360 }
361 else
362 {
363 reshape( view_width, view_height );
364 S32 new_bottom = old_top - mRect.getHeight();
365 setOrigin( old_left, new_bottom );
366 }
367
368 // Try to keep whole view onscreen, don't allow partial offscreen.
369 gFloaterView->adjustToFitScreen(this, FALSE);
370 }
371}
372
373void LLPreviewTexture::loadAsset()
374{
375 mImage = gImageList.getImage(mImageID, MIPMAP_FALSE, FALSE);
376 mImage->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
377 mAssetStatus = PREVIEW_ASSET_LOADING;
378}
379
380LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus()
381{
382 if (mImage.notNull() && (mImage->mFullWidth * mImage->mFullHeight > 0))
383 {
384 mAssetStatus = PREVIEW_ASSET_LOADED;
385 }
386 return mAssetStatus;
387}