From c18fbbc1879cdd9bfcb6f013cb25eef2c8ffa91f Mon Sep 17 00:00:00 2001 From: Tank_Master Date: Tue, 6 Sep 2011 10:49:48 -0700 Subject: [PATCH] implment old version of bitmap browser, work done by Vaalith Jinn --- indra/llmath/llvolumemgr.cpp | 9 + indra/llmath/llvolumemgr.h | 1 + indra/newview/CMakeLists.txt | 2 + indra/newview/llfloaterlocalbitmap.cpp | 940 ++++++++++++++++++ indra/newview/llfloaterlocalbitmap.h | 264 +++++ indra/newview/lltexturectrl.cpp | 132 ++- indra/newview/lltexturectrl.h | 1 + indra/newview/llviewerfloaterreg.cpp | 3 + indra/newview/llviewerobjectlist.h | 1 + indra/newview/llviewertexturelist.h | 2 + indra/newview/llvovolume.h | 1 + .../default/xui/en/floater_local_bitmap.xml | 203 ++++ .../default/xui/en/floater_texture_ctrl.xml | 138 ++- .../skins/default/xui/en/menu_viewer.xml | 7 + 14 files changed, 1693 insertions(+), 11 deletions(-) create mode 100644 indra/newview/llfloaterlocalbitmap.cpp create mode 100644 indra/newview/llfloaterlocalbitmap.h create mode 100644 indra/newview/skins/default/xui/en/floater_local_bitmap.xml diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index c60b750088..4440ea1bac 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -327,6 +327,15 @@ BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) return FALSE; } +LLVolume* LLVolumeLODGroup::getVolByLOD(S32 lod) const +{ + if ( lod >= NUM_LODS ) { return NULL; } + if ( mVolumeLODs[lod].isNull() ) { return NULL; } + + LLVolume* vol = mVolumeLODs[lod]; + return vol; +} + S32 LLVolumeLODGroup::getDetailFromTan(const F32 tan_angle) { S32 i = 0; diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h index c75906f675..ec7a79e810 100644 --- a/indra/llmath/llvolumemgr.h +++ b/indra/llmath/llvolumemgr.h @@ -58,6 +58,7 @@ public: LLVolume* refLOD(const S32 detail); BOOL derefLOD(LLVolume *volumep); S32 getNumRefs() const { return mRefs; } + LLVolume* getVolByLOD(S32 lod) const; const LLVolumeParams* getVolumeParams() const { return &mVolumeParams; }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1909fc5532..1689513afa 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -227,6 +227,7 @@ set(viewer_SOURCE_FILES llfloaterlagmeter.cpp llfloaterland.cpp llfloaterlandholdings.cpp + llfloaterlocalbitmap.cpp llfloatermap.cpp llfloatermediabrowser.cpp llfloatermediasettings.cpp @@ -829,6 +830,7 @@ set(viewer_HEADER_FILES llfloaterlagmeter.h llfloaterland.h llfloaterlandholdings.h + llfloaterlocalbitmap.h llfloatermap.h llfloatermediabrowser.h llfloatermediasettings.h diff --git a/indra/newview/llfloaterlocalbitmap.cpp b/indra/newview/llfloaterlocalbitmap.cpp new file mode 100644 index 0000000000..2d4e6d85b6 --- /dev/null +++ b/indra/newview/llfloaterlocalbitmap.cpp @@ -0,0 +1,940 @@ +/** + * @file llfloaterlocalbitmap.h + * @author Vaalith Jinn + * @brief Local Bitmap Browser source + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +/* basic headers */ +#include "llviewerprecompiledheaders.h" +#include "lluictrlfactory.h" + +/* boost */ +#include +/* in case of unexpected crashes - check if someone defined 'equivalent' and undef it before the above header. */ + +/* own class header */ +#include "llfloaterlocalbitmap.h" + +/* image compression headers. */ +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +/* misc headers */ +#include +#include +#include "llfloaterreg.h" +#include "llviewertexturelist.h" +#include "llviewerobjectlist.h" +#include "llfilepicker.h" +#include "llviewermenufile.h" +#include "llfloaterimagepreview.h" + +/* xui elements */ +#include "lltexturectrl.h" +#include "llscrolllistctrl.h" +#include "llviewercontrol.h" +#include "lllineeditor.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" + +/* including to force rebakes when needed */ +#include "llagent.h" +#include "llvoavatarself.h" + +/* sculpt refresh */ +#include "llvovolume.h" +#include "llface.h" +#include "llvolumemgr.h" + +/*=======================================*/ +/* Instantiating manager class */ +/* and formally declaring it's list */ +/*=======================================*/ +LLLocalBitmapBrowser* gLocalBrowser; +LLLocalBitmapBrowserTimer* gLocalBrowserTimer; +std::vector LLLocalBitmapBrowser::sLoadedBitmaps; +bool LLLocalBitmapBrowser::sLayerUpdated; +bool LLLocalBitmapBrowser::sSculptUpdated; + +/*=======================================*/ +/* LLLocalBitmap: unit class */ +/*=======================================*/ +LLLocalBitmap::LLLocalBitmap(std::string fullpath) +{ + if ( gDirUtilp->fileExists(fullpath) ) + { + /* taking care of basic properties */ + this->mId.generate(); + this->mFilename = fullpath; + this->mLinkStatus = LS_OFF; + this->mKeepUpdating = false; + this->mShortName = gDirUtilp->getBaseFileName(this->mFilename, true); + this->mBitmapType = BT_TEXTURE; + this->mSculptDirty = false; + this->mVolumeDirty = false; + this->mValid = false; + + /* taking care of extension type now to avoid switch madness */ + std::string temp_exten = gDirUtilp->getExtension(this->mFilename); + + if (temp_exten == "bmp") { this->mExtension = ET_IMG_BMP; } + else if (temp_exten == "tga") { this->mExtension = ET_IMG_TGA; } + else if (temp_exten == "jpg" || temp_exten == "jpeg") { this->mExtension = ET_IMG_JPG; } + else if (temp_exten == "png") { this->mExtension = ET_IMG_PNG; } + else { return; } // no valid extension. + + /* getting file's last modified */ + const std::time_t time = boost::filesystem::last_write_time( boost::filesystem::path( this->mFilename ) ); + this->mLastModified = asctime( localtime(&time) ); + + /* checking if the bitmap is valid && decoding if it is */ + LLImageRaw* raw_image = new LLImageRaw(); + if ( this->decodeSelf(raw_image) ) + { + /* creating a shell LLViewerImage and fusing raw image into it */ + LLViewerFetchedTexture* viewer_texture = new LLViewerFetchedTexture( "file://"+this->mFilename, this->mId, LOCAL_USE_MIPMAPS ); + viewer_texture->createGLTexture( LOCAL_DISCARD_LEVEL, raw_image ); + viewer_texture->setCachedRawImage( LOCAL_DISCARD_LEVEL, raw_image ); + + /* making damn sure gImageList will not delete it prematurely */ + viewer_texture->ref(); + + /* finalizing by adding LLViewerImage instance into gImageList */ + gTextureList.addImage(viewer_texture); + + /* filename is valid, bitmap is decoded and valid, we're done. */ + this->mValid = true; + } + } +} + +LLLocalBitmap::~LLLocalBitmap() +{ +} + +/* [maintenence functions] */ +void LLLocalBitmap::updateSelf() +{ + if ( this->mLinkStatus == LS_ON || this->mLinkStatus == LS_UPDATING ) + { + /* making sure file still exists */ + if ( !gDirUtilp->fileExists(this->mFilename) ) + { + this->mLinkStatus = LS_BROKEN; + LLFloaterLocalBitmapBrowser::updateRightSide(); + return; + } + + /* exists, let's check if it's lastmod has changed */ + const std::time_t temp_time = boost::filesystem::last_write_time( boost::filesystem::path( this->mFilename ) ); + LLSD new_last_modified = asctime( localtime(&temp_time) ); + if ( this->mLastModified.asString() == new_last_modified.asString() ) { return; } + + /* here we update the image */ + LLImageRaw* new_imgraw = new LLImageRaw(); + + if ( !decodeSelf(new_imgraw) ) { this->mLinkStatus = LS_UPDATING; return; } + else { this->mLinkStatus = LS_ON; } + + LLViewerFetchedTexture* image = gTextureList.findImage(this->mId); + + // here was a check if isForSculptOnly, but it appears the function is broken. + image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); + image->setCachedRawImage( LOCAL_DISCARD_LEVEL, new_imgraw ); + + /* finalizing by updating lastmod to current */ + this->mLastModified = new_last_modified; + + /* setting unit property to reflect that it has been changed */ + switch (this->mBitmapType) + { + case BT_TEXTURE: + { break; } + + case BT_SCULPT: + { + /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ + this->mSculptDirty = true; + this->mVolumeDirty = true; + gLocalBrowser->setSculptUpdated( true ); + break; + } + + case BT_LAYER: + { + /* sets a bool to rebake layers after the iteration is done with */ + gLocalBrowser->setLayerUpdated( true ); + break; + } + + default: + { break; } + + } + } + +} + +bool LLLocalBitmap::decodeSelf(LLImageRaw* rawimg) +{ + switch (this->mExtension) + { + case ET_IMG_BMP: + { + LLPointer bmp_image = new LLImageBMP; + if ( !bmp_image->load(mFilename) ) { break; } + if ( !bmp_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case ET_IMG_TGA: + { + LLPointer tga_image = new LLImageTGA; + if ( !tga_image->load(mFilename) ) { break; } + if ( !tga_image->decode(rawimg) ) { break; } + + if( ( tga_image->getComponents() != 3) && + ( tga_image->getComponents() != 4) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case ET_IMG_JPG: + { + LLPointer jpeg_image = new LLImageJPEG; + if ( !jpeg_image->load(mFilename) ) { break; } + if ( !jpeg_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case ET_IMG_PNG: + { + LLPointer png_image = new LLImagePNG; + if ( !png_image->load(mFilename) ) { break; } + if ( !png_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + default: + break; + } + return false; +} + +void LLLocalBitmap::setUpdateBool() +{ + if ( this->mLinkStatus != LS_BROKEN ) + { + if ( !this->mKeepUpdating ) + { + this->mLinkStatus = LS_ON; + this->mKeepUpdating = true; + } + else + { + this->mLinkStatus = LS_OFF; + this->mKeepUpdating = false; + } + } + else + { + this->mKeepUpdating = false; + } +} + +void LLLocalBitmap::setType( S32 type ) +{ + this->mBitmapType = type; +} + +/* [information query functions] */ +std::string LLLocalBitmap::getShortName() +{ + return this->mShortName; +} + +std::string LLLocalBitmap::getFileName() +{ + return this->mFilename; +} + +LLUUID LLLocalBitmap::getID() +{ + return this->mId; +} + +LLSD LLLocalBitmap::getLastModified() +{ + return this->mLastModified; +} + +std::string LLLocalBitmap::getLinkStatus() +{ + switch(this->mLinkStatus) + { + case LS_ON: + return "On"; + + case LS_OFF: + return "Off"; + + case LS_BROKEN: + return "Broken"; + + case LS_UPDATING: + return "Updating"; + + default: + return "Unknown"; + } +} + +bool LLLocalBitmap::getUpdateBool() +{ + return this->mKeepUpdating; +} + +bool LLLocalBitmap::getIfValidBool() +{ + return this->mValid; +} + +LLLocalBitmap* LLLocalBitmap::getThis() +{ + return this; +} + +S32 LLLocalBitmap::getType() +{ + return this->mBitmapType; +} + +std::vector LLLocalBitmap::getFaceUsesThis(LLDrawable* drawable) +{ + std::vector matching_faces; + + for ( S32 face_iter = 0; face_iter < drawable->getNumFaces(); face_iter++ ) + { + LLFace* newface = drawable->getFace(face_iter); + + if (!newface) { continue; } + if (!newface->getTexture()) { continue; } + + if ( this->mId == newface->getTexture()->getID() ) + { + matching_faces.push_back(face_iter); + } + } + + return matching_faces; +} + +std::vector LLLocalBitmap::getUsingObjects(bool seek_by_type, bool seek_textures, bool seek_sculptmaps) +{ + std::vector affected_vector; + + for( LLDynamicArrayPtr< LLPointer, 256 >::iterator iter = gObjectList.mObjects.begin(); + iter != gObjectList.mObjects.end(); iter++ ) + { + LLViewerObject* obj = *iter; + LLAffectedObject shell; + shell.object = obj; + shell.local_sculptmap = false; + bool obj_relevant = false; + + if ( obj && obj->mDrawable ) + { + /* looking for textures */ + if ( seek_textures || ( seek_by_type && this->mBitmapType == BT_TEXTURE ) ) + { + std::vector affected_faces = this->getFaceUsesThis( obj->mDrawable ); + if ( !affected_faces.empty() ) + { + shell.face_list = affected_faces; + obj_relevant = true; + } + } + + /* looking for sculptmaps */ + if ( ( seek_sculptmaps || ( seek_by_type && this->mBitmapType == BT_SCULPT ) ) + && obj->isSculpted() && obj->getVolume() + && this->mId == obj->getVolume()->getParams().getSculptID() + ) + { + shell.local_sculptmap = true; + obj_relevant = true; + } + } + + if (obj_relevant) + { affected_vector.push_back(shell); } + } + + return affected_vector; +} + +void LLLocalBitmap::getDebugInfo() +{ + /* debug function: dumps everything human readable into llinfos */ + llinfos << "===[local bitmap debug]===" << "\n" + << "path: " << this->mFilename << "\n" + << "name: " << this->mShortName << "\n" + << "extension: " << this->mExtension << "\n" + << "uuid: " << this->mId << "\n" + << "last modified: " << this->mLastModified << "\n" + << "link status: " << this->getLinkStatus() << "\n" + << "keep updated: " << this->mKeepUpdating << "\n" + << "type: " << this->mBitmapType << "\n" + << "is valid: " << this->mValid << "\n" + << "==========================" << llendl; + +} + +/*=======================================*/ +/* LLLocalBitmapBrowser: main class */ +/*=======================================*/ +LLLocalBitmapBrowser::LLLocalBitmapBrowser() +{ + this->sLayerUpdated = false; + this->sSculptUpdated = false; +} + +LLLocalBitmapBrowser::~LLLocalBitmapBrowser() +{ + +} + +void LLLocalBitmapBrowser::addBitmap() +{ + LLFilePicker& picker = LLFilePicker::instance(); + if ( !picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE) ) + { return; } + + bool change_happened = false; + std::string filename = picker.getFirstFile(); + while( !filename.empty() ) + { + LLLocalBitmap* unit = new LLLocalBitmap( filename ); + + if ( unit->getIfValidBool() ) + { + sLoadedBitmaps.push_back( unit ); + change_happened = true; + } + + filename = picker.getNextFile(); + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LLLocalBitmapBrowser::delBitmap( std::vector delete_vector, S32 column ) +{ + bool change_happened = false; + for( std::vector::iterator list_iter = delete_vector.begin(); + list_iter != delete_vector.end(); list_iter++ ) + { + LLScrollListItem* list_item = *list_iter; + if ( list_item ) + { + LLUUID id = list_item->getColumn(column)->getValue().asUUID(); + for (local_list_iter iter = sLoadedBitmaps.begin(); + iter != sLoadedBitmaps.end();) + { + LLLocalBitmap* unit = (*iter)->getThis(); + + if ( unit->getID() == id ) + { + LLViewerFetchedTexture* image = gTextureList.findImage(id); + gTextureList.deleteImage( image ); + image->unref(); + + iter = sLoadedBitmaps.erase(iter); + delete unit; + unit = NULL; + + change_happened = true; + } + else + { iter++; } + } + } + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LLLocalBitmapBrowser::onUpdateBool(LLUUID id) +{ + LLLocalBitmap* unit = getBitmapUnit( id ); + if ( unit ) + { + unit->setUpdateBool(); + pingTimer(); + } +} + +void LLLocalBitmapBrowser::onSetType(LLUUID id, S32 type) +{ + LLLocalBitmap* unit = getBitmapUnit( id ); + if ( unit ) + { unit->setType(type); } +} + +LLLocalBitmap* LLLocalBitmapBrowser::getBitmapUnit(LLUUID id) +{ + local_list_iter iter = sLoadedBitmaps.begin(); + for (; iter != sLoadedBitmaps.end(); iter++) + { + if ( (*iter)->getID() == id ) + { + return (*iter)->getThis(); + } + } + + return NULL; +} + +bool LLLocalBitmapBrowser::isDoingUpdates() +{ + local_list_iter iter = sLoadedBitmaps.begin(); + for (; iter != sLoadedBitmaps.end(); iter++) + { + if ( (*iter)->getUpdateBool() ) + { return true; } /* if at least one unit in the list needs updates - we need a timer. */ + } + + return false; +} + + +/* Reaction to a change in bitmaplist, this function finds a texture picker floater's appropriate scrolllist + and passes this scrolllist's pointer to UpdateTextureCtrlList for processing. */ +void LLLocalBitmapBrowser::onChangeHappened() +{ + /* own floater update */ + LLFloaterLocalBitmapBrowser::updateBitmapScrollList(); + + /* texturepicker related */ + const LLView::child_list_t* child_list = gFloaterView->getChildList(); + LLView::child_list_const_iter_t child_list_iter = child_list->begin(); + + for (; child_list_iter != child_list->end(); child_list_iter++) + { + LLView* view = *child_list_iter; + if ( view->getName() == LOCAL_TEXTURE_PICKER_NAME ) + { + LLScrollListCtrl* ctrl = view->getChild + ( LOCAL_TEXTURE_PICKER_LIST_NAME, + LOCAL_TEXTURE_PICKER_RECURSE ); + + if ( ctrl ) { updateTextureCtrlList(ctrl); } + } + } + + /* poking timer to see if it's still needed/still not needed */ + pingTimer(); + +} + +void LLLocalBitmapBrowser::pingTimer() +{ + if ( !sLoadedBitmaps.empty() && isDoingUpdates() ) + { + if (!gLocalBrowserTimer) + { gLocalBrowserTimer = new LLLocalBitmapBrowserTimer(); } + + if ( !gLocalBrowserTimer->isRunning() ) + { gLocalBrowserTimer->start(); } + } + + else + { + if (gLocalBrowserTimer) + { + if ( gLocalBrowserTimer->isRunning() ) + { gLocalBrowserTimer->stop(); } + } + } +} + +/* This function refills the texture picker floater's scrolllist with the updated contents of bitmaplist */ +void LLLocalBitmapBrowser::updateTextureCtrlList(LLScrollListCtrl* ctrl) +{ + if ( ctrl ) // checking again in case called externally for some silly reason. + { + ctrl->clearRows(); + if ( !sLoadedBitmaps.empty() ) + { + local_list_iter iter = sLoadedBitmaps.begin(); + for ( ; iter != sLoadedBitmaps.end(); iter++ ) + { + LLSD element; + element["columns"][0]["column"] = "unit_name"; + element["columns"][0]["type"] = "text"; + element["columns"][0]["value"] = (*iter)->mShortName; + + element["columns"][1]["column"] = "unit_id_HIDDEN"; + element["columns"][1]["type"] = "text"; + element["columns"][1]["value"] = (*iter)->mId; + + ctrl->addElement(element); + } + } + } +} + +void LLLocalBitmapBrowser::performTimedActions(void) +{ + // perform checking if updates are needed && update if so. + local_list_iter iter; + for (iter = sLoadedBitmaps.begin(); iter != sLoadedBitmaps.end(); iter++) + { (*iter)->updateSelf(); } + + // one or more sculpts have been updated, refreshing them. + if ( sSculptUpdated ) + { + LLLocalBitmapBrowser::local_list_iter iter; + for(iter = sLoadedBitmaps.begin(); iter != sLoadedBitmaps.end(); iter++) + { + if ( (*iter)->mSculptDirty ) + { + performSculptUpdates( (*iter)->getThis() ); + (*iter)->mSculptDirty = false; + } + } + sSculptUpdated = false; + } + + // one of the layer bitmaps has been updated, we need to rebake. + if ( sLayerUpdated ) + { + if ( !isAgentAvatarValid() ) { return; } + gAgentAvatarp->forceBakeAllTextures( SLAM_FOR_DEBUG ); + + sLayerUpdated = false; + } +} + +void LLLocalBitmapBrowser::performSculptUpdates(LLLocalBitmap* unit) +{ + + /* looking for sculptmap using objects only */ + std::vector object_list = unit->getUsingObjects(false, false, true); + if (object_list.empty()) { return; } + + for( std::vector::iterator iter = object_list.begin(); + iter != object_list.end(); iter++ ) + { + LLAffectedObject aobj = *iter; + if ( aobj.object ) + { + if ( !aobj.local_sculptmap ) { continue; } // should never get here. only in case of misuse. + + // update code [begin] + if ( unit->mVolumeDirty ) + { + LLImageRaw* rawimage = gTextureList.findImage( unit->getID() )->getCachedRawImage(); + + LLVolumeParams params = aobj.object->getVolume()->getParams(); + LLVolumeLODGroup* lodgroup = aobj.object->mDrawable->getVOVolume()->getVolumeManager()->getGroup(params); + + for (S32 i = 0; i < LLVolumeLODGroup::NUM_LODS; i++) + { + LLVolume* vol = lodgroup->getVolByLOD(i); + + if (vol) + { vol->sculpt(rawimage->getWidth(), rawimage->getHeight(), rawimage->getComponents(), rawimage->getData(), 0); } + } + + // doing this again to fix the weirdness with selected-for-edit objects not updating otherwise. + aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), + rawimage->getComponents(), rawimage->getData(), 0); + + unit->mVolumeDirty = false; + } + + aobj.object->mDrawable->getVOVolume()->setSculptChanged( true ); + aobj.object->mDrawable->getVOVolume()->markForUpdate( true ); + // update code [end] + } + + } + +} + +/*==================================================*/ +/* LLFloaterLocalBitmapBrowser : floater class */ +/*==================================================*/ +std::list LLFloaterLocalBitmapBrowser::sSelfInstances; + +LLFloaterLocalBitmapBrowser::LLFloaterLocalBitmapBrowser( const LLSD& key ) +: LLFloater( key ) +{ + sSelfInstances.push_back(this); +} + +BOOL LLFloaterLocalBitmapBrowser::postBuild() +{ + // setting element/xui children: + mAddBtn = getChild("add_btn"); + mDelBtn = getChild("del_btn"); + mUploadBtn = getChild("upload_btn"); + + mBitmapList = getChild("bitmap_list"); + mTextureView = getChild("texture_view"); + mUpdateChkBox = getChild("keep_updating_checkbox"); + + mPathTxt = getChild("path_text"); + mUUIDTxt = getChild("uuid_text"); + + mLinkTxt = getChild("link_text"); + mTimeTxt = getChild("time_text"); + mTypeComboBox = getChild("type_combobox"); + + mCaptionPathTxt = getChild("path_caption_text"); + mCaptionUUIDTxt = getChild("uuid_caption_text"); + mCaptionLinkTxt = getChild("link_caption_text"); + mCaptionTimeTxt = getChild("time_caption_text"); + + // pre-disabling line editors, they're for view only and buttons that shouldn't be on on-spawn. + mPathTxt->setEnabled( false ); + mUUIDTxt->setEnabled( false ); + + mDelBtn->setEnabled( false ); + mUploadBtn->setEnabled( false ); + + // setting button callbacks: + mAddBtn->setClickedCallback( onClickAdd, this); + mDelBtn->setClickedCallback( onClickDel, this); + mUploadBtn->setClickedCallback( onClickUpload, this); + + // combo callback + mTypeComboBox->setCommitCallback(onCommitTypeCombo, this); + + // scrolllist callbacks + mBitmapList->setCommitCallback(onChooseBitmapList, this); + + // checkbox callbacks + mUpdateChkBox->setCommitCallback(onClickUpdateChkbox, this); + + this->updateBitmapScrollList(); + + return true; +} + +LLFloaterLocalBitmapBrowser::~LLFloaterLocalBitmapBrowser() +{ + sSelfInstances.remove( this ); +} + +void LLFloaterLocalBitmapBrowser::onClickAdd(void* userdata) +{ + gLocalBrowser->addBitmap(); +} + +void LLFloaterLocalBitmapBrowser::onClickDel(void* userdata) +{ + LLFloaterLocalBitmapBrowser* self = (LLFloaterLocalBitmapBrowser*) userdata; + gLocalBrowser->delBitmap( self->mBitmapList->getAllSelected() ); +} + +void LLFloaterLocalBitmapBrowser::onClickUpload(void* userdata) +{ + LLFloaterLocalBitmapBrowser* self = (LLFloaterLocalBitmapBrowser*) userdata; + if ( self->mBitmapList->getAllSelected().empty() ) { return; } + + std::string filename = gLocalBrowser->getBitmapUnit( + (LLUUID)self->mBitmapList->getSelectedItemLabel(BLIST_COL_ID) )->getFileName(); + + if ( !filename.empty() ) + { + LLFloaterReg::showInstance("upload_image", LLSD(filename)); + } +} + +void LLFloaterLocalBitmapBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata) +{ + LLFloaterLocalBitmapBrowser* self = (LLFloaterLocalBitmapBrowser*) userdata; + + bool button_status = self->mBitmapList->isEmpty(); + self->mDelBtn->setEnabled(!button_status); + self->mUploadBtn->setEnabled(!button_status); + + self->updateRightSide(); +} + +void LLFloaterLocalBitmapBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata) +{ + LLFloaterLocalBitmapBrowser* self = (LLFloaterLocalBitmapBrowser*) userdata; + + std::string temp_str = self->mBitmapList->getSelectedItemLabel(BLIST_COL_ID); + if ( !temp_str.empty() ) + { + gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); + self->updateRightSide(); + } +} + +void LLFloaterLocalBitmapBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata) +{ + LLFloaterLocalBitmapBrowser* self = (LLFloaterLocalBitmapBrowser*) userdata; + + std::string temp_str = self->mBitmapList->getSelectedItemLabel(BLIST_COL_ID); + + if ( !temp_str.empty() ) + { + S32 selection = self->mTypeComboBox->getCurrentIndex(); + gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); + + } +} + +void LLFloaterLocalBitmapBrowser::updateBitmapScrollList() +{ + + if ( sSelfInstances.empty() ) { return; } + + std::list::iterator iter; + for( iter = sSelfInstances.begin(); iter != sSelfInstances.end(); iter++ ) + { + LLFloaterLocalBitmapBrowser* sLFInstance = *iter; + + sLFInstance->mBitmapList->clearRows(); + if (!gLocalBrowser->sLoadedBitmaps.empty()) + { + + LLLocalBitmapBrowser::local_list_iter iter; + for(iter = gLocalBrowser->sLoadedBitmaps.begin(); iter != gLocalBrowser->sLoadedBitmaps.end(); iter++) + { + LLSD element; + element["columns"][BLIST_COL_NAME]["column"] = "bitmap_name"; + element["columns"][BLIST_COL_NAME]["type"] = "text"; + element["columns"][BLIST_COL_NAME]["value"] = (*iter)->getShortName(); + + element["columns"][BLIST_COL_ID]["column"] = "bitmap_uuid"; + element["columns"][BLIST_COL_ID]["type"] = "text"; + element["columns"][BLIST_COL_ID]["value"] = (*iter)->getID(); + + sLFInstance->mBitmapList->addElement(element); + } + + } + LLFloaterLocalBitmapBrowser::updateRightSide(); + } +} + +void LLFloaterLocalBitmapBrowser::updateRightSide() +{ + if ( sSelfInstances.empty() ) { return; } + + std::list::iterator iter; + for( iter = sSelfInstances.begin(); iter != sSelfInstances.end(); iter++ ) + { + LLFloaterLocalBitmapBrowser* sLFInstance = *iter; + + if ( !sLFInstance->mBitmapList->getAllSelected().empty() ) + { + LLLocalBitmap* unit = gLocalBrowser->getBitmapUnit( LLUUID(sLFInstance->mBitmapList->getSelectedItemLabel(BLIST_COL_ID)) ); + + if ( unit ) + { + sLFInstance->mTextureView->setImageAssetID( unit->getID() ); + sLFInstance->mUpdateChkBox->set( unit->getUpdateBool() ); + sLFInstance->mPathTxt->setText( unit->getFileName() ); + sLFInstance->mUUIDTxt->setText( unit->getID().asString() ); + sLFInstance->mTimeTxt->setText( unit->getLastModified().asString() ); + sLFInstance->mLinkTxt->setText( unit->getLinkStatus() ); + sLFInstance->mTypeComboBox->selectNthItem( unit->getType() ); + + sLFInstance->mTextureView->setEnabled(true); + sLFInstance->mUpdateChkBox->setEnabled(true); + sLFInstance->mTypeComboBox->setEnabled(true); + } + } + else + { + sLFInstance->mTextureView->setImageAssetID( NO_IMAGE ); + sLFInstance->mTextureView->setEnabled( false ); + sLFInstance->mUpdateChkBox->set( false ); + sLFInstance->mUpdateChkBox->setEnabled( false ); + + sLFInstance->mTypeComboBox->selectFirstItem(); + sLFInstance->mTypeComboBox->setEnabled( false ); + + sLFInstance->mPathTxt->setText( LLStringExplicit("None") ); + sLFInstance->mUUIDTxt->setText( LLStringExplicit("None") ); + sLFInstance->mLinkTxt->setText( LLStringExplicit("None") ); + sLFInstance->mTimeTxt->setText( LLStringExplicit("None") ); + } + + } +} + + +/*==================================================*/ +/* LLLocalBitmapBrowserTimer: timer class */ +/*==================================================*/ +LLLocalBitmapBrowserTimer::LLLocalBitmapBrowserTimer() : LLEventTimer( (F32)TIMER_HEARTBEAT ) +{ + +} + +LLLocalBitmapBrowserTimer::~LLLocalBitmapBrowserTimer() +{ + +} + +BOOL LLLocalBitmapBrowserTimer::tick() +{ + gLocalBrowser->performTimedActions(); + return FALSE; +} + +void LLLocalBitmapBrowserTimer::start() +{ + mEventTimer.start(); +} + +void LLLocalBitmapBrowserTimer::stop() +{ + mEventTimer.stop(); +} + +bool LLLocalBitmapBrowserTimer::isRunning() +{ + return mEventTimer.getStarted(); +} + diff --git a/indra/newview/llfloaterlocalbitmap.h b/indra/newview/llfloaterlocalbitmap.h new file mode 100644 index 0000000000..fc176a0c5b --- /dev/null +++ b/indra/newview/llfloaterlocalbitmap.h @@ -0,0 +1,264 @@ +/** + * @file llfloaterlocalbitmap.h + * @author Vaalith Jinn + * @brief Local Bitmap Browser header + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#ifndef LL_LOCALBITMAP_H +#define LL_LOCALBITMAP_H + +/* Local Bitmap Browser: header */ + +#include "llfloater.h" +#include "lleventtimer.h" + +class LLViewerObject; +class LLImageRaw; +class LLDrawable; +class LLScrollListCtrl; +class LLTextureCtrl; +class LLLineEditor; +class LLComboBox; +class LLCheckBoxCtrl; +class LLTextBox; + + +/*=======================================*/ +/* Global structs / enums / defines */ +/*=======================================*/ + +#define LOCAL_USE_MIPMAPS true +#define LOCAL_DISCARD_LEVEL 0 +#define NO_IMAGE LLUUID::null + +#define TIMER_HEARTBEAT 3.0 +#define SLAM_FOR_DEBUG true + +enum EBitmapListCols +{ + BLIST_COL_NAME, + BLIST_COL_ID +}; + +/* update related */ +struct LLAffectedObject +{ + LLViewerObject* object; + std::vector face_list; + bool local_sculptmap; + +}; + +/* for finding texture pickers */ +#define LOCAL_TEXTURE_PICKER_NAME "texture picker" +#define LOCAL_TEXTURE_PICKER_LIST_NAME "local_name_list" +#define LOCAL_TEXTURE_PICKER_RECURSE true + +/* texture picker uses these */ +#define LOCALLIST_COL_ID 1 +#define LOCALLIST_LOCAL_TAB "local_tab" + +/*=======================================*/ +/* LLLocalBitmap: unit class */ +/*=======================================*/ +class LLLocalBitmap +{ + public: + LLLocalBitmap(std::string filename); + virtual ~LLLocalBitmap(void); + friend class LLLocalBitmapBrowser; + + public: /* [enums, typedefs, etc] */ + enum ELinkStatus + { + LS_UNKNOWN, /* default fallback */ + LS_ON, + LS_OFF, + LS_BROKEN, + LS_UPDATING + }; + + enum EExtensionType + { + ET_IMG_BMP, + ET_IMG_TGA, + ET_IMG_JPG, + ET_IMG_PNG + }; + + enum EBitmapType + { + BT_TEXTURE = 0, + BT_SCULPT = 1, + BT_LAYER = 2 + }; + + public: /* [information query functions] */ + std::string getShortName(void); + std::string getFileName(void); + LLUUID getID(void); + LLSD getLastModified(void); + std::string getLinkStatus(void); + bool getUpdateBool(void); + void setType( S32 ); + bool getIfValidBool(void); + S32 getType(void); + void getDebugInfo(void); + + private: /* [maintenence functions] */ + void updateSelf(void); + bool decodeSelf(LLImageRaw* rawimg); + void setUpdateBool(void); + + LLLocalBitmap* getThis(void); + std::vector getFaceUsesThis(LLDrawable*); + std::vector getUsingObjects(bool seek_by_type = true, + bool seek_textures = false, bool seek_sculptmaps = false); + + protected: /* [basic properties] */ + std::string mShortName; + std::string mFilename; + EExtensionType mExtension; + LLUUID mId; + LLSD mLastModified; + ELinkStatus mLinkStatus; + bool mKeepUpdating; + bool mValid; + S32 mBitmapType; + bool mSculptDirty; + bool mVolumeDirty; +}; + +/*=======================================*/ +/* LLLocalBitmapBrowser: main class */ +/*=======================================*/ +class LLLocalBitmapBrowser +{ + public: + LLLocalBitmapBrowser(); + virtual ~LLLocalBitmapBrowser(); + + friend class LLFloaterLocalBitmapBrowser; + friend class LLLocalBitmapBrowserTimer; + friend class LLFloaterTexturePicker; + + static void updateTextureCtrlList(LLScrollListCtrl*); + static void setLayerUpdated(bool toggle) { sLayerUpdated = toggle; } + static void setSculptUpdated(bool toggle) { sSculptUpdated = toggle; } + static void addBitmap(void); + static void loadBitmaps(void); + static void delBitmap( std::vector, S32 column = BLIST_COL_ID ); + + private: + static void onChangeHappened(void); + static void onUpdateBool(LLUUID); + static void onSetType(LLUUID, S32); + static LLLocalBitmap* getBitmapUnit(LLUUID); + static bool isDoingUpdates(void); + static void pingTimer(void); + static void performTimedActions(void); + static void performSculptUpdates(LLLocalBitmap*); + + protected: + static std::vector sLoadedBitmaps; + typedef std::vector::iterator local_list_iter; + static bool sLayerUpdated; + static bool sSculptUpdated; +}; + +/*==================================================*/ +/* LLFloaterLocalBitmapBrowser : floater class */ +/*==================================================*/ +class LLFloaterLocalBitmapBrowser : public LLFloater +{ +public: + LLFloaterLocalBitmapBrowser( const LLSD& key ); + virtual ~LLFloaterLocalBitmapBrowser(); + BOOL postBuild(void); + + +private: + // Button callback declarations + static void onClickAdd(void* userdata); + static void onClickDel(void* userdata); + static void onClickUpload(void* userdata); + + // ScrollList callback declarations + static void onChooseBitmapList(LLUICtrl* ctrl, void* userdata); + + // Checkbox callback declarations + static void onClickUpdateChkbox(LLUICtrl* ctrl, void* userdata); + + // Combobox type select + static void onCommitTypeCombo(LLUICtrl* ctrl, void* userdata); + + // Widgets + LLButton* mAddBtn; + LLButton* mDelBtn; + LLButton* mUploadBtn; + + LLScrollListCtrl* mBitmapList; + LLScrollListCtrl* mUsedList; + LLTextureCtrl* mTextureView; + LLCheckBoxCtrl* mUpdateChkBox; + + LLLineEditor* mPathTxt; + LLLineEditor* mUUIDTxt; + + LLTextBox* mLinkTxt; + LLTextBox* mTimeTxt; + LLComboBox* mTypeComboBox; + + LLTextBox* mCaptionPathTxt; + LLTextBox* mCaptionUUIDTxt; + LLTextBox* mCaptionLinkTxt; + LLTextBox* mCaptionTimeTxt; + + /* to ensure no crashing happens if, for some reason, someone opens two instances of the floater + we're keeping a list of selves for the static functions to go through */ + static std::list sSelfInstances; + + // non-widget functions +public: + static void updateBitmapScrollList(void); + static void updateRightSide(void); + +}; + +/*==================================================*/ +/* LLLocalBitmapBrowserTimer : timer class */ +/*==================================================*/ +class LLLocalBitmapBrowserTimer : public LLEventTimer +{ + public: + LLLocalBitmapBrowserTimer(); + ~LLLocalBitmapBrowserTimer(); + virtual BOOL tick(); + void start(); + void stop(); + bool isRunning(); +}; + +#endif // LL_LOCALBITMAP_H + diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index de22f2ae6b..e5cb710847 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -67,6 +67,11 @@ #include "lluictrlfactory.h" #include "lltrans.h" +#include "llfloaterlocalbitmap.h" +#include "llscrolllistctrl.h" +#include "llfilepicker.h" +#include "llfloaterreg.h" +#include "lltabcontainer.h" static const S32 HPAD = 4; static const S32 VPAD = 4; @@ -142,6 +147,11 @@ public: static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata); void onTextureSelect( const LLTextureEntry& te ); + static void onBtnAdd( void* userdata ); + static void onBtnRemove( void* userdata ); + static void onBtnUpload( void* userdata ); + static void onBtnBrowser( void* userdata ); + static void onLocalScrollCommit( LLUICtrl* ctrl, void* userdata ); protected: LLPointer mTexturep; LLTextureCtrl* mOwner; @@ -171,6 +181,8 @@ protected: LLSaveFolderState mSavedFolderState; BOOL mSelectedItemPinned; + LLScrollListCtrl* mLocalScrollCtrl; + LLTabContainer* mServerLocalTabCont; }; LLFloaterTexturePicker::LLFloaterTexturePicker( @@ -400,7 +412,16 @@ BOOL LLFloaterTexturePicker::postBuild() childSetAction("None", LLFloaterTexturePicker::onBtnNone,this); childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); + childSetAction( "l_add_btn", LLFloaterTexturePicker::onBtnAdd, this ); + childSetAction( "l_del_btn", LLFloaterTexturePicker::onBtnRemove, this ); + childSetAction( "l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this ); + childSetAction( "l_brws_btn", LLFloaterTexturePicker::onBtnBrowser, this ); + mLocalScrollCtrl = getChild("local_name_list"); + mLocalScrollCtrl->setCommitCallback( onLocalScrollCommit, this ); + LLLocalBitmapBrowser::updateTextureCtrlList( mLocalScrollCtrl ); + + mServerLocalTabCont = getChild("servloc_tabcont"); childSetCommitCallback("show_folders_check", onShowFolders, this); getChildView("show_folders_check")->setVisible( FALSE); @@ -683,9 +704,19 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask() void LLFloaterTexturePicker::commitIfImmediateSet() { bool apply_immediate = getChild("apply_immediate_check")->getValue().asBoolean(); - if (!mNoCopyTextureSelected && apply_immediate && mOwner) + std::string panel_name = mServerLocalTabCont->getCurrentPanel()->getName(); + + if ( apply_immediate && mOwner ) { - mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE); + if (panel_name != LOCALLIST_LOCAL_TAB && !mNoCopyTextureSelected) + { + mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE); + } + else if ( panel_name == LOCALLIST_LOCAL_TAB && !mLocalScrollCtrl->isEmpty() ) + { + mOwner->onFloaterCommit + ( LLTextureCtrl::TEXTURE_CHANGE, (LLUUID)mLocalScrollCtrl->getSelectedItemLabel( LOCALLIST_COL_ID ) ); + } } } @@ -748,11 +779,67 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata) LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; if (self->mOwner) { - self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT); + std::string panel_name = self->mServerLocalTabCont->getCurrentPanel()->getName(); + + // checking if we're on server or local tab + if ( panel_name != LOCALLIST_LOCAL_TAB ) + { self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT); } + else if ( panel_name == LOCALLIST_LOCAL_TAB && !self->mLocalScrollCtrl->isEmpty() ) + { + self->mOwner->onFloaterCommit + ( LLTextureCtrl::TEXTURE_CHANGE, + (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel( LOCALLIST_COL_ID ) ); + } } self->closeFloater(); } +// static +void LLFloaterTexturePicker::onBtnAdd(void *userdata) +{ + LLLocalBitmapBrowser::addBitmap(); +} + +// static +void LLFloaterTexturePicker::onBtnRemove(void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLLocalBitmapBrowser::delBitmap( self->mLocalScrollCtrl->getAllSelected(), LOCALLIST_COL_ID ); +} + +// static +void LLFloaterTexturePicker::onBtnUpload(void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + if ( self->mLocalScrollCtrl->getAllSelected().empty() ) { return; } + + std::string filename = LLLocalBitmapBrowser::getBitmapUnit + ( (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCALLIST_COL_ID) )->getFileName(); + + if ( !filename.empty() ) + { + LLFloaterReg::showInstance("upload_image", LLSD(filename)); + } + +} + +// static +void LLFloaterTexturePicker::onBtnBrowser(void *userdata) +{ + LLFloaterReg::showInstance("local_bitmap_browser", NULL); // NULL works but i don't feel comfortable with it. +} + +// static +void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl *ctrl, void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LLUUID id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel( LOCALLIST_COL_ID ); + + self->mOwner->setImageAssetID( id ); + if ( self->childGetValue("apply_immediate_check").asBoolean() ) + { self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, id); } // calls an overridden function. +} + void LLFloaterTexturePicker::onBtnPipette() { BOOL pipette_active = getChild("Pipette")->getValue().asBoolean(); @@ -1167,6 +1254,45 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) } } +/* overridden for local bitmaps */ +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + + if( floaterp && getEnabled() ) + { + if (op == TEXTURE_CANCEL) + mViewModel->resetDirty(); + // If the "no_commit_on_selection" parameter is set + // we get dirty only when user presses OK in the picker + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. + else if (mCommitOnSelection || op == TEXTURE_SELECT) + mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + setTentative( FALSE ); + + mImageItemID = id; + mImageAssetID = id; + + if (op == TEXTURE_SELECT && mOnSelectCallback) + { + mOnSelectCallback( this, LLSD() ); + } + else if (op == TEXTURE_CANCEL && mOnCancelCallback) + { + mOnCancelCallback( this, LLSD() ); + } + else + { + // If the "no_commit_on_selection" parameter is set + // we commit only when user presses OK in the picker + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. + if (mCommitOnSelection || op == TEXTURE_SELECT) + onCommit(); + } + + } +} void LLTextureCtrl::setImageAssetName(const std::string& name) { LLPointer imagep = LLUI::getUIImage(name); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index fdfbee400e..22a4e7ec82 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -162,6 +162,7 @@ public: void onFloaterClose(); void onFloaterCommit(ETexturePickOp op); + void onFloaterCommit(ETexturePickOp op, LLUUID id); // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7776f65d52..21014b8013 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -80,6 +80,7 @@ #include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterlandholdings.h" +#include "llfloaterlocalbitmap.h" #include "llfloatermap.h" #include "llfloatermemleak.h" #include "llfloatermodelwizard.h" @@ -254,6 +255,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("local_bitmap_browser", "floater_local_bitmap.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("lgg_beamcolormap", "floater_beamcolor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("lgg_beamshape", "floater_beamshape.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9d1b5cb56f..f135f5e7cf 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -226,6 +226,7 @@ protected: std::set mSelectPickList; friend class LLViewerObject; + friend class LLLocalBitmap; }; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 7f4dd0ae88..009fbbb9a1 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -65,6 +65,8 @@ class LLViewerTextureList friend class LLTextureView; friend class LLViewerTextureManager; + friend class LLLocalBitmap; + friend class LLLocalBitmapBrowser; public: static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index fdec50596e..56e607b6d0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -214,6 +214,7 @@ public: void preRebuild(); virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); + void setSculptChanged(BOOL has_changed) { mSculptChanged = has_changed; mFaceMappingChanged = has_changed; mVolumeChanged = has_changed; } virtual U32 getPartitionType() const; diff --git a/indra/newview/skins/default/xui/en/floater_local_bitmap.xml b/indra/newview/skins/default/xui/en/floater_local_bitmap.xml new file mode 100644 index 0000000000..f46af0a9c0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_local_bitmap.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + +