/** * @file llfloateroutfitphotopreview.cpp * @brief LLFloaterOutfitPhotoPreview class implementation * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llwindow.h" #include "llfloateroutfitphotopreview.h" #include "llagent.h" #include "llappearancemgr.h" #include "llbutton.h" #include "llcombobox.h" #include "llfilepicker.h" #include "llfloaterreg.h" #include "llimagetga.h" #include "llimagepng.h" #include "llinventory.h" #include "llinventorymodel.h" #include "llnotificationsutil.h" #include "llresmgr.h" #include "lltrans.h" #include "lltextbox.h" #include "lltextureview.h" #include "llui.h" #include "llviewerinventory.h" #include "llviewertexture.h" #include "llviewertexturelist.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "lllineeditor.h" const S32 MAX_OUTFIT_PHOTO_WIDTH = 256; const S32 MAX_OUTFIT_PHOTO_HEIGHT = 256; const S32 CLIENT_RECT_VPAD = 4; LLFloaterOutfitPhotoPreview::LLFloaterOutfitPhotoPreview(const LLSD& key) : LLPreview(key), mUpdateDimensions(TRUE), mImage(NULL), mOutfitID(LLUUID()), mImageOldBoostLevel(LLGLTexture::BOOST_NONE), mExceedLimits(FALSE) { updateImageID(); } LLFloaterOutfitPhotoPreview::~LLFloaterOutfitPhotoPreview() { LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; if (mImage.notNull()) { mImage->setBoostLevel(mImageOldBoostLevel); mImage = NULL; } } // virtual BOOL LLFloaterOutfitPhotoPreview::postBuild() { getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onOkBtn, this)); getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onCancelBtn, this)); return LLPreview::postBuild(); } void LLFloaterOutfitPhotoPreview::draw() { updateDimensions(); LLPreview::draw(); if (!isMinimized()) { LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLRect& border = mClientRect; LLRect interior = mClientRect; interior.stretch( -PREVIEW_BORDER_WIDTH ); // ...border gl_rect_2d( border, LLColor4(0.f, 0.f, 0.f, 1.f)); gl_rect_2d_checkerboard( interior ); if ( mImage.notNull() ) { // Draw the texture gGL.diffuseColor3f( 1.f, 1.f, 1.f ); gl_draw_scaled_image(interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mImage); // Pump the texture priority F32 pixel_area = (F32)(interior.getWidth() * interior.getHeight() ); mImage->addTextureStats( pixel_area ); S32 int_width = interior.getWidth(); S32 int_height = interior.getHeight(); mImage->setKnownDrawSize(int_width, int_height); } } } // virtual void LLFloaterOutfitPhotoPreview::reshape(S32 width, S32 height, BOOL called_from_parent) { LLPreview::reshape(width, height, called_from_parent); LLRect dim_rect(getChildView("dimensions")->getRect()); S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE; S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD; LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0); client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ; S32 client_width = client_rect.getWidth(); S32 client_height = client_width; if(client_height > client_rect.getHeight()) { client_height = client_rect.getHeight(); client_width = client_height; } mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() + (client_height / 2), client_width, client_height); } void LLFloaterOutfitPhotoPreview::updateDimensions() { if (!mImage) { return; } if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) { return; } if (mAssetStatus != PREVIEW_ASSET_LOADED) { mAssetStatus = PREVIEW_ASSET_LOADED; mUpdateDimensions = TRUE; } getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth())); getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight())); if ((mImage->getFullWidth() <= MAX_OUTFIT_PHOTO_WIDTH) && (mImage->getFullHeight() <= MAX_OUTFIT_PHOTO_HEIGHT)) { getChild<LLButton>("ok_btn")->setEnabled(TRUE); mExceedLimits = FALSE; } else { mExceedLimits = TRUE; LLStringUtil::format_map_t args; args["MAX_WIDTH"] = llformat("%d", MAX_OUTFIT_PHOTO_WIDTH); args["MAX_HEIGHT"] = llformat("%d", MAX_OUTFIT_PHOTO_HEIGHT); std::string label = getString("exceed_limits", args); getChild<LLUICtrl>("notification")->setValue(label); getChild<LLUICtrl>("notification")->setColor(LLColor4::yellow); getChild<LLButton>("ok_btn")->setEnabled(FALSE); } if (mUpdateDimensions) { mUpdateDimensions = FALSE; reshape(getRect().getWidth(), getRect().getHeight()); gFloaterView->adjustToFitScreen(this, FALSE); } } void LLFloaterOutfitPhotoPreview::loadAsset() { if (mImage.notNull()) { mImage->setBoostLevel(mImageOldBoostLevel); } mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); mImageOldBoostLevel = mImage->getBoostLevel(); mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); mImage->forceToSaveRawImage(0) ; mAssetStatus = PREVIEW_ASSET_LOADING; mUpdateDimensions = TRUE; updateDimensions(); } LLPreview::EAssetStatus LLFloaterOutfitPhotoPreview::getAssetStatus() { if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0)) { mAssetStatus = PREVIEW_ASSET_LOADED; } return mAssetStatus; } void LLFloaterOutfitPhotoPreview::updateImageID() { const LLViewerInventoryItem *item = static_cast<const LLViewerInventoryItem*>(getItem()); if(item) { mImageID = item->getAssetUUID(); LLPermissions perm(item->getPermissions()); } else { mImageID = mItemUUID; } } /* virtual */ void LLFloaterOutfitPhotoPreview::setObjectID(const LLUUID& object_id) { mObjectUUID = object_id; const LLUUID old_image_id = mImageID; updateImageID(); if (mImageID != old_image_id) { mAssetStatus = PREVIEW_ASSET_UNLOADED; loadAsset(); } refreshFromItem(); } void LLFloaterOutfitPhotoPreview::setOutfitID(const LLUUID& outfit_id) { mOutfitID = outfit_id; LLViewerInventoryCategory* outfit_folder = gInventory.getCategory(mOutfitID); if(outfit_folder && !mExceedLimits) { getChild<LLUICtrl>("notification")->setValue( getString("photo_confirmation")); getChild<LLUICtrl>("notification")->setTextArg("[OUTFIT]", outfit_folder->getName()); getChild<LLUICtrl>("notification")->setColor(LLColor4::white); } } void LLFloaterOutfitPhotoPreview::onOkBtn() { if(mOutfitID.notNull() && getItem()) { LLAppearanceMgr::instance().removeOutfitPhoto(mOutfitID); LLPointer<LLInventoryCallback> cb = NULL; link_inventory_object(mOutfitID, LLConstPointer<LLInventoryObject>(getItem()), cb); } closeFloater(); } void LLFloaterOutfitPhotoPreview::onCancelBtn() { closeFloater(); }