From 9d1040b71f98716d066751538dde6cfb58dea93d Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Wed, 2 Mar 2011 02:55:18 +0100 Subject: [PATCH 1/7] Object hovertips from Emerald - primcount, position --- indra/newview/llhoverview.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/indra/newview/llhoverview.cpp b/indra/newview/llhoverview.cpp index 84a66247c..1b3fe90e7 100644 --- a/indra/newview/llhoverview.cpp +++ b/indra/newview/llhoverview.cpp @@ -500,6 +500,27 @@ void LLHoverView::updateText() } mText.push_back(line); } + line.clear(); + S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount(); + line.append(llformat("Prims: %d", prim_count)); + mText.push_back(line); + + line.clear(); + line.append("Position: "); + + LLViewerRegion *region = gAgent.getRegion(); + LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent(); + LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal()); + + + LLVector3 delta = position - mypos; + F32 distance = (F32)delta.magVec(); + + line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2])); + mText.push_back(line); + line.clear(); + line.append(llformat("Distance: %.02fm",distance)); + mText.push_back(line); // If the hover tip shouldn't be shown, delete all the object text if (suppressObjectHoverDisplay) From 5cad5a4cfde8c6351c34990211e93602b935587c Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Wed, 2 Mar 2011 15:11:51 +0100 Subject: [PATCH 2/7] About text --- indra/newview/skins/default/xui/en-us/floater_about.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/xui/en-us/floater_about.xml b/indra/newview/skins/default/xui/en-us/floater_about.xml index 3aa908d14..f41797f6a 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about.xml @@ -58,7 +58,7 @@ bottom="0" width="446" word_wrap="true"> -Singularity Viewer is developed and maintained by Siana Gearz with contributions by Shyotl Kuhr and Narv Czervik. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. +Singularity Viewer is developed and maintained by Siana Gearz, Shyotl Kuhr and Narv Czervik, with contributions by Henri Beauchamp, Kitty Barnett, Thickbrick Sleaford, Wolfspirit Magic and others. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. Singularity Viewer includes source code contributions of the following residents: Able Whitman, Adam Marker, Agathos Frascati, Aimee Trescothick, Alejandro Rosenthal, Aleric Inglewood, Alissa Sabre, Angus Boyd, Ann Congrejo, Argent Stonecutter, Asuka Neely, Balp Allen, Benja Kepler, Biancaluce Robbiani, Blakar Ogre, blino Nakamura, Boroondas Gupte, Bulli Schumann, bushing Spatula, Carjay McGinnis, Catherine Pfeffer, Celierra Darling, Cron Stardust, Dale Glass, Drewan Keats, Dylan Haskell, Dzonatas Sol, Eddy Stryker, EponymousDylan Ra, Eva Nowicka, Farallon Greyskin, Feep Larsson, Flemming Congrejo, Fluf Fredriksson, Fremont Cunningham, Geneko Nemeth, Gigs Taggart, Ginko Bayliss, Grazer Kline, Gudmund Shepherd, Hamncheese Omlet, HappySmurf Papp, Henri Beauchamp, Hikkoshi Sakai, Hiro Sommambulist, Hoze Menges, Ian Kas, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Joghert LeSabre, Kage Pixel, Ken March, Kerutsen Sellery, Khyota Wulluf, Kunnis Basiat, Lisa Lowe, Lockhart Cordoso, maciek marksman, Magnus Balczo, Malwina Dollinger, march Korda, Matthew Dowd, McCabe Maxsted, Michelle2 Zenovka, Mm Alder, Mr Greggan, Nicholaz Beresford, Nounouch Hapmouche, Patric Mills, Paul Churchill, Paula Innis, Peekay Semyorka, Peter Lameth, Pf Shan, princess niven, Renault Clio, Ringo Tuxing, Robin Cornelius, Ryozu Kojima, Salahzar Stenvaag, Sammy Frederix, Scrippy Scofield, Seg Baphomet, Sergen Davies, SignpostMarv Martin, Simon Nolan, SpacedOut Frye, Sporked Friis, Stevex Janus, Still Defiant, Strife Onizuka, Tayra Dagostino, TBBle Kurosawa, Teardrops Fall, tenebrous pau, Tharax Ferraris, Thickbrick Sleaford, Thraxis Epsilon, tiamat bingyi, TraductoresAnonimos Alter, Tue Torok, Vadim Bigbear, Vixen Heron, Whoops Babii, Wilton Lundquist, Zarkonnen Decosta, Zi Ree, Zipherius Turas From 633b6d22f2eb465687fe3edef8fee90f7a9e9b9e Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Thu, 3 Mar 2011 02:01:52 +0100 Subject: [PATCH 3/7] Emerald Local Assets --- indra/cmake/Boost.cmake | 6 + indra/llplugin/slplugin/CMakeLists.txt | 1 + indra/newview/CMakeLists.txt | 5 + indra/newview/app_settings/settings.xml | 25 +- indra/newview/floaterlocalassetbrowse.cpp | 1030 +++++++++++++++++ indra/newview/floaterlocalassetbrowse.h | 305 +++++ indra/newview/lltexturectrl.cpp | 129 +++ indra/newview/lltexturectrl.h | 1 + indra/newview/llviewerimage.h | 2 + indra/newview/llviewerobjectlist.h | 2 + indra/newview/llvovolume.h | 3 + .../xui/en-us/floater_local_asset_browse.xml | 261 +++++ .../xui/en-us/floater_texture_ctrl.xml | 71 +- 13 files changed, 1816 insertions(+), 25 deletions(-) create mode 100644 indra/newview/floaterlocalassetbrowse.cpp create mode 100644 indra/newview/floaterlocalassetbrowse.h create mode 100644 indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index c6677e1ac..9942a08a5 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -7,9 +7,11 @@ set(Boost_FIND_REQUIRED ON) if (STANDALONE) include(FindBoost) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) else (STANDALONE) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) @@ -42,12 +44,16 @@ else (STANDALONE) debug libboost_signals-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION}) elseif (DARWIN) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) elseif (LINUX) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_SYSTEM_LIBRARY boost_system-mt) endif (WINDOWS) endif (STANDALONE) diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index d6735a76f..fd555d394 100755 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -6,6 +6,7 @@ include(LLPlugin) include(Linking) include(PluginAPI) include(LLMessage) +include(GooglePerfTools) include_directories( ${LLPLUGIN_INCLUDE_DIRS} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 44bfe9d7a..3dcf25c0d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ) set(viewer_SOURCE_FILES + floaterlocalassetbrowse.cpp aoremotectrl.cpp floaterao.cpp floatervoicelicense.cpp @@ -533,6 +534,7 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + floaterlocalassetbrowse.h aoremotectrl.h floaterao.h floatervoicelicense.h @@ -1418,8 +1420,11 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLCOMMON_LIBRARIES} ${NDOF_LIBRARY} ${viewer_LIBRARIES} + ${BOOST_FILESYSTEM_LIBRARY} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} + ${BOOST_SIGNALS_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${FMODWRAPPER_LIBRARY} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1d5664fbc..10d560556 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,23 @@ settings_rlv.xml + FloaterLocalbitmapbrowserRect + + Comment + LOLRectangle + Persist + 1 + Type + Rect + Value + + 0 + 400 + 400 + 0 + + + ShowAOSitPopup @@ -6170,7 +6187,7 @@ Type F32 Value - 12.0 + 11.5 FontSizeMedium @@ -6181,7 +6198,7 @@ Type F32 Value - 10.0 + 9.5 FontSizeMonospace @@ -6192,7 +6209,7 @@ Type F32 Value - 8.1 + 9.0 FontSizeSmall @@ -6203,7 +6220,7 @@ Type F32 Value - 9.0 + 8.5 ForceNotecardDragCargoPermissive diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp new file mode 100644 index 000000000..7b707deff --- /dev/null +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -0,0 +1,1030 @@ +/** +* @file floaterlocalassetbrowse.cpp +* @brief Local texture support +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, author unknown +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +/* + +tag: vaa emerald local_asset_browser + +this feature is still a work in progress. + +*/ + +/* basic headers */ +#include "llviewerprecompiledheaders.h" +#include "lluictrlfactory.h" + +/* own class header && upload floater header */ +#include "floaterlocalassetbrowse.h" +//#include "floaterlocaluploader.h" <- in development. + +/* image compression headers. */ +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +/* misc headers */ +#include +#include +#include "llviewerimagelist.h" +#include "llviewerobjectlist.h" +#include "llfilepicker.h" +#include "llviewermenufile.h" +#include "llfloaterimagepreview.h" +#include "llfile.h" + +/* repeated in header */ +#include "lltexturectrl.h" +#include "llscrolllistctrl.h" +#include "llviewercontrol.h" + +/* including to force rebakes when needed */ +#include "llagent.h" +#include "llvoavatar.h" + +/* sculpt refresh */ +#include "llvovolume.h" +#include "llface.h" + + +/*=======================================*/ +/* Instantiating manager class */ +/* and formally declaring it's list */ +/*=======================================*/ +LocalAssetBrowser* gLocalBrowser; +LocalAssetBrowserTimer* gLocalBrowserTimer; +std::vector LocalAssetBrowser::loaded_bitmaps; +bool LocalAssetBrowser::mLayerUpdated; +bool LocalAssetBrowser::mSculptUpdated; + +/*=======================================*/ +/* LocalBitmap: unit class */ +/*=======================================*/ +/* + The basic unit class responsible for + containing one loaded local texture. +*/ + +LocalBitmap::LocalBitmap(std::string fullpath) +{ + this->valid = false; + if ( gDirUtilp->fileExists(fullpath) ) + { + /* taking care of basic properties */ + this->id.generate(); + this->filename = fullpath; + this->linkstatus = LINK_OFF; + this->keep_updating = false; + this->shortname = gDirUtilp->getBaseFileName(this->filename, true); + this->bitmap_type = TYPE_TEXTURE; + this->sculpt_dirty = false; + this->volume_dirty = false; + this->valid = false; + + /* taking care of extension type now to avoid switch madness */ + std::string temp_exten = gDirUtilp->getExtension(this->filename); + + if (temp_exten == "bmp") { this->extension = IMG_EXTEN_BMP; } + else if (temp_exten == "tga") { this->extension = IMG_EXTEN_TGA; } + else if (temp_exten == "jpg" || temp_exten == "jpeg") { this->extension = IMG_EXTEN_JPG; } + else if (temp_exten == "png") { this->extension = IMG_EXTEN_PNG; } + else { return; } // no valid extension. + + /* getting file's last modified */ + + llstat temp_stat; + LLFile::stat(this->filename, &temp_stat); + std::time_t time = temp_stat.st_mtime; + + this->last_modified = 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 */ + LLViewerImage* viewer_image = new LLViewerImage( "file://"+this->filename, this->id, LOCAL_USE_MIPMAPS ); + viewer_image->createGLTexture( LOCAL_DISCARD_LEVEL, raw_image ); + viewer_image->mCachedRawImage = raw_image; + + /* making damn sure gImageList will not delete it prematurely */ + viewer_image->ref(); + + /* finalizing by adding LLViewerImage instance into gImageList */ + gImageList.addImage(viewer_image); + + /* filename is valid, bitmap is decoded and valid, i can haz liftoff! */ + this->valid = true; + } + } +} + +LocalBitmap::~LocalBitmap() +{ +} + +/* [maintenence functions] */ +void LocalBitmap::updateSelf() +{ + if ( this->linkstatus == LINK_ON || this->linkstatus == LINK_UPDATING ) + { + /* making sure file still exists */ + if ( !gDirUtilp->fileExists(this->filename) ) { this->linkstatus = LINK_BROKEN; return; } + + /* exists, let's check if it's lastmod has changed */ + llstat temp_stat; + LLFile::stat(this->filename, &temp_stat); + std::time_t temp_time = temp_stat.st_mtime; + + LLSD new_last_modified = asctime( localtime(&temp_time) ); + if ( this->last_modified.asString() == new_last_modified.asString() ) { return; } + + /* here we update the image */ + LLImageRaw* new_imgraw = new LLImageRaw(); + + if ( !decodeSelf(new_imgraw) ) { this->linkstatus = LINK_UPDATING; return; } + else { this->linkstatus = LINK_ON; } + + LLViewerImage* image = gImageList.hasImage(this->id); + + if (!image->mForSculpt) + { image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); } + else + { image->mCachedRawImage = new_imgraw; } + + /* finalizing by updating lastmod to current */ + this->last_modified = new_last_modified; + + /* setting unit property to reflect that it has been changed */ + switch (this->bitmap_type) + { + case TYPE_TEXTURE: + { break; } + + case TYPE_SCULPT: + { + /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ + this->sculpt_dirty = true; + this->volume_dirty = true; + gLocalBrowser->setSculptUpdated( true ); + break; + } + + case TYPE_LAYER: + { + /* sets a bool to rebake layers after the iteration is done with */ + gLocalBrowser->setLayerUpdated( true ); + break; + } + + default: + { break; } + + } + } + +} + +bool LocalBitmap::decodeSelf(LLImageRaw* rawimg) +{ + switch (this->extension) + { + case IMG_EXTEN_BMP: + { + LLPointer bmp_image = new LLImageBMP; + if ( !bmp_image->load(filename) ) { break; } + if ( !bmp_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_TGA: + { + LLPointer tga_image = new LLImageTGA; + if ( !tga_image->load(filename) ) { break; } + if ( !tga_image->decode(rawimg) ) { break; } + + if( ( tga_image->getComponents() != 3) && + ( tga_image->getComponents() != 4) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_JPG: + { + LLPointer jpeg_image = new LLImageJPEG; + if ( !jpeg_image->load(filename) ) { break; } + if ( !jpeg_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + case IMG_EXTEN_PNG: + { + LLPointer png_image = new LLImagePNG; + if ( !png_image->load(filename) ) { break; } + if ( !png_image->decode(rawimg, 0.0f) ) { break; } + + rawimg->biasedScaleToPowerOfTwo( LLViewerImage::MAX_IMAGE_SIZE_DEFAULT ); + return true; + } + + default: + break; + } + return false; +} + +void LocalBitmap::setUpdateBool() +{ + if ( this->linkstatus != LINK_BROKEN ) + { + if ( !this->keep_updating ) + { + this->linkstatus = LINK_ON; + this->keep_updating = true; + } + else + { + this->linkstatus = LINK_OFF; + this->keep_updating = false; + } + } + else + { + this->keep_updating = false; + } +} + +void LocalBitmap::setType( S32 type ) +{ + this->bitmap_type = type; +} + +/* [information query functions] */ +std::string LocalBitmap::getShortName() +{ + return this->shortname; +} + +std::string LocalBitmap::getFileName() +{ + return this->filename; +} + +LLUUID LocalBitmap::getID() +{ + return this->id; +} + +LLSD LocalBitmap::getLastModified() +{ + return this->last_modified; +} + +std::string LocalBitmap::getLinkStatus() +{ + switch(this->linkstatus) + { + case LINK_ON: + return "On"; + + case LINK_OFF: + return "Off"; + + case LINK_BROKEN: + return "Broken"; + + case LINK_UPDATING: + return "Updating"; + + default: + return "Unknown"; + } +} + +bool LocalBitmap::getUpdateBool() +{ + return this->keep_updating; +} + +bool LocalBitmap::getIfValidBool() +{ + return this->valid; +} + +LocalBitmap* LocalBitmap::getThis() +{ + return this; +} + +S32 LocalBitmap::getType() +{ + return this->bitmap_type; +} + +std::vector LocalBitmap::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 ( this->id == newface->getTexture()->getID() ) + { matching_faces.push_back(newface); } + } + + return matching_faces; +} + +std::vector LocalBitmap::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; + affected_object 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->bitmap_type == TYPE_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->bitmap_type == TYPE_SCULPT ) ) + && obj->isSculpted() && obj->getVolume() + && this->id == obj->getVolume()->getParams().getSculptID() + ) + { + shell.local_sculptmap = true; + obj_relevant = true; + } + } + + if (obj_relevant) + { affected_vector.push_back(shell); } + } + + + + return affected_vector; +} + +void LocalBitmap::getDebugInfo() +{ + /* debug function: dumps everything human readable into llinfos */ + llinfos << "===[local bitmap debug]===" << "\n" + << "path: " << this->filename << "\n" + << "name: " << this->shortname << "\n" + << "extension: " << this->extension << "\n" + << "uuid: " << this->id << "\n" + << "last modified: " << this->last_modified << "\n" + << "link status: " << this->getLinkStatus() << "\n" + << "keep updated: " << this->keep_updating << "\n" + << "type: " << this->bitmap_type << "\n" + << "is valid: " << this->valid << "\n" + << "==========================" << llendl; + +} + +/*=======================================*/ +/* LocalAssetBrowser: internal class */ +/*=======================================*/ +/* + Responsible for internal workings. + Instantiated at the top of the source file. + Sits in memory until the viewer is closed. +*/ + +LocalAssetBrowser::LocalAssetBrowser() +{ + this->mLayerUpdated = false; + this->mSculptUpdated = false; +} + +LocalAssetBrowser::~LocalAssetBrowser() +{ + +} + +void LocalAssetBrowser::AddBitmap() +{ + LLFilePicker& picker = LLFilePicker::instance(); + if ( !picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE) ) + { return; } + + bool change_happened = false; + std::string filename = picker.getFirstFile(); + while( !filename.empty() ) + { + LocalBitmap* unit = new LocalBitmap( filename ); + + if ( unit->getIfValidBool() ) + { + loaded_bitmaps.push_back( unit ); + change_happened = true; + } + + filename = picker.getNextFile(); + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LocalAssetBrowser::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 = loaded_bitmaps.begin(); + iter != loaded_bitmaps.end();) + { + LocalBitmap* unit = (*iter)->getThis(); + + if ( unit->getID() == id ) + { + LLViewerImage* image = gImageList.hasImage(id); + gImageList.deleteImage( image ); + image->unref(); + + iter = loaded_bitmaps.erase(iter); + delete unit; + unit = NULL; + + change_happened = true; + } + else + { iter++; } + } + } + } + + if ( change_happened ) + { onChangeHappened(); } +} + +void LocalAssetBrowser::onUpdateBool(LLUUID id) +{ + LocalBitmap* unit = GetBitmapUnit( id ); + if ( unit ) + { + unit->setUpdateBool(); + PingTimer(); + } +} + +void LocalAssetBrowser::onSetType(LLUUID id, S32 type) +{ + LocalBitmap* unit = GetBitmapUnit( id ); + if ( unit ) + { unit->setType(type); } +} + +LocalBitmap* LocalAssetBrowser::GetBitmapUnit(LLUUID id) +{ + local_list_iter iter = loaded_bitmaps.begin(); + for (; iter != loaded_bitmaps.end(); iter++) + { + if ( (*iter)->getID() == id ) + { + return (*iter)->getThis(); + } + } + + return NULL; +} + +bool LocalAssetBrowser::IsDoingUpdates() +{ + local_list_iter iter = loaded_bitmaps.begin(); + for (; iter != loaded_bitmaps.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. + it also processes timer start/stops as needed */ +void LocalAssetBrowser::onChangeHappened() +{ + /* own floater update */ + FloaterLocalAssetBrowser::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, + LOCAL_TEXTURE_PICKER_CREATEIFMISSING ); + + if ( ctrl ) { UpdateTextureCtrlList(ctrl); } + } + } + + /* poking timer to see if it's still needed/still not needed */ + PingTimer(); + +} + +void LocalAssetBrowser::PingTimer() +{ + if ( !loaded_bitmaps.empty() && IsDoingUpdates() ) + { + if (!gLocalBrowserTimer) + { gLocalBrowserTimer = new LocalAssetBrowserTimer(); } + + 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 LocalAssetBrowser::UpdateTextureCtrlList(LLScrollListCtrl* ctrl) +{ + if ( ctrl ) // checking again in case called externally for some silly reason. + { + ctrl->clearRows(); + if ( !loaded_bitmaps.empty() ) + { + local_list_iter iter = loaded_bitmaps.begin(); + for ( ; iter != loaded_bitmaps.end(); iter++ ) + { + LLSD element; + element["columns"][0]["column"] = "unit_name"; + element["columns"][0]["type"] = "text"; + element["columns"][0]["value"] = (*iter)->shortname; + + element["columns"][1]["column"] = "unit_id_HIDDEN"; + element["columns"][1]["type"] = "text"; + element["columns"][1]["value"] = (*iter)->id; + + ctrl->addElement(element); + } + } + } +} + +void LocalAssetBrowser::PerformTimedActions(void) +{ + // perform checking if updates are needed && update if so. + local_list_iter iter; + for (iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) + { (*iter)->updateSelf(); } + + // one or more sculpts have been updated, refreshing them. + if ( mSculptUpdated ) + { + LocalAssetBrowser::local_list_iter iter; + for(iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); iter++) + { + if ( (*iter)->sculpt_dirty ) + { + PerformSculptUpdates( (*iter)->getThis() ); + (*iter)->sculpt_dirty = false; + } + } + mSculptUpdated = false; + } + + // one of the layer bitmaps has been updated, we need to rebake. + if ( mLayerUpdated ) + { + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if (avatar) { avatar->forceBakeAllTextures(SLAM_FOR_DEBUG); } + + mLayerUpdated = false; + } +} + +void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap* 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++ ) + { + affected_object aobj = *iter; + if ( aobj.object ) + { + if ( !aobj.local_sculptmap ) { continue; } // should never get here. only in case of misuse. + + // update code [begin] + if ( unit->volume_dirty ) + { + LLImageRaw* rawimage = gImageList.hasImage( unit->getID() )->getCachedRawImage(); + + aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), + rawimage->getComponents(), rawimage->getData(), 0); + unit->volume_dirty = false; + } + + // tell affected drawable it's got updated + aobj.object->mDrawable->getVOVolume()->setSculptChanged( true ); + aobj.object->mDrawable->getVOVolume()->markForUpdate( true ); + // update code [end] + } + + } + +} + +/*==================================================*/ +/* FloaterLocalAssetBrowser : floater class */ +/*==================================================*/ +/* + Responsible for talking to the user. + Instantiated by user request. + Destroyed when the floater is closed. + +*/ + +// Floater Globals +FloaterLocalAssetBrowser* FloaterLocalAssetBrowser::sLFInstance = NULL; + +// widgets: + LLButton* mAddBtn; + LLButton* mDelBtn; + LLButton* mMoreBtn; + LLButton* mLessBtn; + LLButton* mUploadBtn; + + + LLScrollListCtrl* mBitmapList; + LLTextureCtrl* mTextureView; + LLCheckBoxCtrl* mUpdateChkBox; + + LLLineEditor* mPathTxt; + LLLineEditor* mUUIDTxt; + LLLineEditor* mNameTxt; + + LLTextBox* mLinkTxt; + LLTextBox* mTimeTxt; + LLComboBox* mTypeComboBox; + + LLTextBox* mCaptionPathTxt; + LLTextBox* mCaptionUUIDTxt; + LLTextBox* mCaptionLinkTxt; + LLTextBox* mCaptionNameTxt; + LLTextBox* mCaptionTimeTxt; + +FloaterLocalAssetBrowser::FloaterLocalAssetBrowser() +: LLFloater(std::string("local_bitmap_browser_floater")) +{ + // xui creation: + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_local_asset_browse.xml"); + + // setting element/xui children: + mAddBtn = getChild("add_btn"); + mDelBtn = getChild("del_btn"); + mMoreBtn = getChild("more_btn"); + mLessBtn = getChild("less_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"); + mNameTxt = getChild("name_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"); + mCaptionNameTxt = getChild("name_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 ); + mNameTxt->setEnabled( false ); + + mDelBtn->setEnabled( false ); + mUploadBtn->setEnabled( false ); + + // setting button callbacks: + mAddBtn->setClickedCallback( onClickAdd, this); + mDelBtn->setClickedCallback( onClickDel, this); + mMoreBtn->setClickedCallback( onClickMore, this); + mLessBtn->setClickedCallback( onClickLess, this); + mUploadBtn->setClickedCallback( onClickUpload, this); + + // combo callback + mTypeComboBox->setCommitCallback(onCommitTypeCombo); + + // scrolllist callbacks + mBitmapList->setCommitCallback(onChooseBitmapList); + + // checkbox callbacks + mUpdateChkBox->setCommitCallback(onClickUpdateChkbox); + +} + +void FloaterLocalAssetBrowser::show(void*) +{ + if (!sLFInstance) + sLFInstance = new FloaterLocalAssetBrowser(); + sLFInstance->open(); + sLFInstance->UpdateBitmapScrollList(); +} + +FloaterLocalAssetBrowser::~FloaterLocalAssetBrowser() +{ + sLFInstance=NULL; +} + +void FloaterLocalAssetBrowser::onClickAdd(void* userdata) +{ + gLocalBrowser->AddBitmap(); +} + +void FloaterLocalAssetBrowser::onClickDel(void* userdata) +{ + gLocalBrowser->DelBitmap( sLFInstance->mBitmapList->getAllSelected() ); +} + +/* what stopped me from using a single button and simply changing it's label + is the fact that i'd need to hardcode the button labels here, and that is griff. */ +void FloaterLocalAssetBrowser::onClickMore(void* userdata) +{ + FloaterResize(true); +} + +void FloaterLocalAssetBrowser::onClickLess(void* userdata) +{ + FloaterResize(false); +} + +void FloaterLocalAssetBrowser::onClickUpload(void* userdata) +{ + std::string filename = gLocalBrowser->GetBitmapUnit( + (LLUUID)sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID) )->getFileName(); + + if ( !filename.empty() ) + { + LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); + LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_image_preview.xml"); + } +} + +void FloaterLocalAssetBrowser::onChooseBitmapList(LLUICtrl* ctrl, void *userdata) +{ + bool button_status = sLFInstance->mBitmapList->isEmpty(); + sLFInstance->mDelBtn->setEnabled(!button_status); + sLFInstance->mUploadBtn->setEnabled(!button_status); + + sLFInstance->UpdateRightSide(); +} + +void FloaterLocalAssetBrowser::onClickUpdateChkbox(LLUICtrl *ctrl, void *userdata) +{ + std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + if ( !temp_str.empty() ) + { + gLocalBrowser->onUpdateBool( (LLUUID)temp_str ); + sLFInstance->UpdateRightSide(); + } +} + +void FloaterLocalAssetBrowser::onCommitTypeCombo(LLUICtrl* ctrl, void *userdata) +{ + std::string temp_str = sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID); + + if ( !temp_str.empty() ) + { + S32 selection = sLFInstance->mTypeComboBox->getCurrentIndex(); + gLocalBrowser->onSetType( (LLUUID)temp_str, selection ); + + } +} + +void FloaterLocalAssetBrowser::FloaterResize(bool expand) +{ + sLFInstance->mMoreBtn->setVisible(!expand); + sLFInstance->mLessBtn->setVisible(expand); + sLFInstance->mTextureView->setVisible(expand); + sLFInstance->mUpdateChkBox->setVisible(expand); + sLFInstance->mCaptionPathTxt->setVisible(expand); + sLFInstance->mCaptionUUIDTxt->setVisible(expand); + sLFInstance->mCaptionLinkTxt->setVisible(expand); + sLFInstance->mCaptionNameTxt->setVisible(expand); + sLFInstance->mCaptionTimeTxt->setVisible(expand); + sLFInstance->mTypeComboBox->setVisible(expand); + + sLFInstance->mTimeTxt->setVisible(expand); + sLFInstance->mPathTxt->setVisible(expand); + sLFInstance->mUUIDTxt->setVisible(expand); + sLFInstance->mLinkTxt->setVisible(expand); + sLFInstance->mNameTxt->setVisible(expand); + + if(expand) + { + sLFInstance->reshape(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->setResizeLimits(LF_FLOATER_EXPAND_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->UpdateRightSide(); + } + else + { + sLFInstance->reshape(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + sLFInstance->setResizeLimits(LF_FLOATER_CONTRACT_WIDTH, LF_FLOATER_HEIGHT); + } + +} + +void FloaterLocalAssetBrowser::UpdateBitmapScrollList() +{ + if ( !sLFInstance ) { return; } + + sLFInstance->mBitmapList->clearRows(); + if (!gLocalBrowser->loaded_bitmaps.empty()) + { + + LocalAssetBrowser::local_list_iter iter; + for(iter = gLocalBrowser->loaded_bitmaps.begin(); iter != gLocalBrowser->loaded_bitmaps.end(); iter++) + { + LLSD element; + element["columns"][BITMAPLIST_COL_NAME]["column"] = "bitmap_name"; + element["columns"][BITMAPLIST_COL_NAME]["type"] = "text"; + element["columns"][BITMAPLIST_COL_NAME]["value"] = (*iter)->getShortName(); + + element["columns"][BITMAPLIST_COL_ID]["column"] = "bitmap_uuid"; + element["columns"][BITMAPLIST_COL_ID]["type"] = "text"; + element["columns"][BITMAPLIST_COL_ID]["value"] = (*iter)->getID(); + + sLFInstance->mBitmapList->addElement(element); + } + + } + sLFInstance->UpdateRightSide(); +} + +void FloaterLocalAssetBrowser::UpdateRightSide() +{ + /* + Since i'm not keeping a bool on if the floater is expanded or not, i'll + just check if one of the widgets that shows when the floater is expanded is visible. + + Also obviously before updating - checking if something IS actually selected :o + */ + + if ( !sLFInstance->mTextureView->getVisible() ) { return; } + + if ( !sLFInstance->mBitmapList->getAllSelected().empty() ) + { + LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(sLFInstance->mBitmapList->getSelectedItemLabel(BITMAPLIST_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->mNameTxt->setText( unit->getShortName() ); + 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->mNameTxt->setText( LLStringExplicit("None") ); + sLFInstance->mLinkTxt->setText( LLStringExplicit("None") ); + sLFInstance->mTimeTxt->setText( LLStringExplicit("None") ); + } +} + + +/*==================================================*/ +/* LocalAssetBrowserTimer: timer class */ +/*==================================================*/ +/* + A small, simple timer class inheriting from + LLEventTimer, responsible for pinging the + LocalAssetBrowser class to perform it's + updates / checks / etc. + +*/ + +LocalAssetBrowserTimer::LocalAssetBrowserTimer() : LLEventTimer( (F32)TIMER_HEARTBEAT ) +{ + +} + +LocalAssetBrowserTimer::~LocalAssetBrowserTimer() +{ + +} + +BOOL LocalAssetBrowserTimer::tick() +{ + gLocalBrowser->PerformTimedActions(); + return FALSE; +} + +void LocalAssetBrowserTimer::start() +{ + mEventTimer.start(); +} + +void LocalAssetBrowserTimer::stop() +{ + mEventTimer.stop(); +} + +bool LocalAssetBrowserTimer::isRunning() +{ + return mEventTimer.getStarted(); +} + diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h new file mode 100644 index 000000000..6ee1c75a3 --- /dev/null +++ b/indra/newview/floaterlocalassetbrowse.h @@ -0,0 +1,305 @@ +/** +* @file floaterlocalassetbrowse.h +* @brief Local texture support +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, author unknown +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +/* Local Asset Browser: header + +tag: vaa emerald local_asset_browser + +*/ + + +#ifndef VAA_LOCALBROWSER +#define VAA_LOCALBROWSER + +#include "llfloater.h" +#include "llscrolllistctrl.h" +#include "lltexturectrl.h" +#include "lldrawable.h" + + +/*=======================================*/ +/* Global structs / enums / defines */ +/*=======================================*/ + +#define LF_FLOATER_EXPAND_WIDTH 735 +#define LF_FLOATER_CONTRACT_WIDTH 415 +#define LF_FLOATER_HEIGHT 260 + +#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 bitmaplist_cols +{ + BITMAPLIST_COL_NAME, + BITMAPLIST_COL_ID +}; + +/* upload & sculpt update related */ +struct affected_object +{ + LLViewerObject* object; + std::vector face_list; + bool local_sculptmap; + +}; + +/* texture picker defines */ + +#define LOCAL_TEXTURE_PICKER_NAME "texture picker" +#define LOCAL_TEXTURE_PICKER_LIST_NAME "local_name_list" +#define LOCAL_TEXTURE_PICKER_RECURSE true +#define LOCAL_TEXTURE_PICKER_CREATEIFMISSING true + + +/*=======================================*/ +/* LocalBitmap: unit class */ +/*=======================================*/ +/* + The basic unit class responsible for + containing one loaded local texture. +*/ + +class LocalBitmap +{ + public: + LocalBitmap(std::string filename); + virtual ~LocalBitmap(void); + friend class LocalAssetBrowser; + + public: /* [enums, typedefs, etc] */ + enum link_status + { + LINK_UNKNOWN, /* default fallback */ + LINK_ON, + LINK_OFF, + LINK_BROKEN, + LINK_UPDATING /* currently redundant, but left in case necessary later. */ + }; + + enum extension_type + { + IMG_EXTEN_BMP, + IMG_EXTEN_TGA, + IMG_EXTEN_JPG, + IMG_EXTEN_PNG + }; + + enum bitmap_type + { + TYPE_TEXTURE = 0, + TYPE_SCULPT = 1, + TYPE_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); + + LocalBitmap* 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 shortname; + std::string filename; + extension_type extension; + LLUUID id; + LLSD last_modified; + link_status linkstatus; + bool keep_updating; + bool valid; + S32 bitmap_type; + bool sculpt_dirty; + bool volume_dirty; +}; + +/*=======================================*/ +/* LocalAssetBrowser: main class */ +/*=======================================*/ +/* + Responsible for internal workings. + Instantiated at the top of the source file. + Sits in memory until the viewer is closed. + +*/ + + +class LocalAssetBrowser +{ + public: + LocalAssetBrowser(); + virtual ~LocalAssetBrowser(); + friend class FloaterLocalAssetBrowser; + friend class LocalAssetBrowserTimer; + static void UpdateTextureCtrlList(LLScrollListCtrl*); + static void setLayerUpdated(bool toggle) { mLayerUpdated = toggle; } + static void setSculptUpdated(bool toggle) { mSculptUpdated = toggle; } + static void AddBitmap(void); + static void DelBitmap( std::vector, S32 column = BITMAPLIST_COL_ID ); + + /* UpdateTextureCtrlList was made public cause texturectrl requests it once on spawn + ( added: when it's own add/remove funcs are used. ) + i've made it update on spawn instead of on pressing 'local' because the former does it once, + the latter - each time the button's pressed. */ + + private: + static void onChangeHappened(void); + static void onUpdateBool(LLUUID); + static void onSetType(LLUUID, S32); + static LocalBitmap* GetBitmapUnit(LLUUID); + static bool IsDoingUpdates(void); + static void PingTimer(void); + static void PerformTimedActions(void); + static void PerformSculptUpdates(LocalBitmap*); + + protected: + static std::vector loaded_bitmaps; + typedef std::vector::iterator local_list_iter; + static bool mLayerUpdated; + static bool mSculptUpdated; +}; + +/*==================================================*/ +/* FloaterLocalAssetBrowser : interface class */ +/*==================================================*/ +/* + Responsible for talking to the user. + Instantiated by user request. + Destroyed when the floater is closed. + +*/ +class FloaterLocalAssetBrowser : public LLFloater +{ +public: + FloaterLocalAssetBrowser(); + virtual ~FloaterLocalAssetBrowser(); + static void show(void*); + + + +private: + /* Widget related callbacks */ + // Button callback declarations + static void onClickAdd(void* userdata); + static void onClickDel(void* userdata); + static void onClickMore(void* userdata); + static void onClickLess(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* mMoreBtn; + LLButton* mLessBtn; + LLButton* mUploadBtn; + + LLScrollListCtrl* mBitmapList; + LLScrollListCtrl* mUsedList; + LLTextureCtrl* mTextureView; + LLCheckBoxCtrl* mUpdateChkBox; + + LLLineEditor* mPathTxt; + LLLineEditor* mUUIDTxt; + LLLineEditor* mNameTxt; + + LLTextBox* mLinkTxt; + LLTextBox* mTimeTxt; + LLComboBox* mTypeComboBox; + + LLTextBox* mCaptionPathTxt; + LLTextBox* mCaptionUUIDTxt; + LLTextBox* mCaptionLinkTxt; + LLTextBox* mCaptionNameTxt; + LLTextBox* mCaptionTimeTxt; + + /* static pointer to self, wai? oh well. */ + static FloaterLocalAssetBrowser* sLFInstance; + + // non-widget functions + static void FloaterResize(bool expand); + static void UpdateRightSide(void); + +public: + static void UpdateBitmapScrollList(void); + + +}; + +/*==================================================*/ +/* LocalAssetBrowserTimer : timer class */ +/*==================================================*/ +/* + A small, simple timer class inheriting from + LLEventTimer, responsible for pinging the + LocalAssetBrowser class to perform it's + updates / checks / etc. + +*/ +class LocalAssetBrowserTimer : public LLEventTimer +{ + public: + LocalAssetBrowserTimer(); + ~LocalAssetBrowserTimer(); + virtual BOOL tick(); + void start(); + void stop(); + bool isRunning(); +}; + +#endif + diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ffca05686..4df2f6dd0 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -72,6 +72,12 @@ #include "lllocalinventory.h" // +// tag: vaa emerald local_asset_browser [begin] +#include "floaterlocalassetbrowse.h" +#include "llscrolllistctrl.h" +#include "llfilepicker.h" +#define LOCALLIST_COL_ID 1 +// tag: vaa emerald local_asset_browser [end] static const S32 CLOSE_BTN_WIDTH = 100; const S32 PIPETTE_BTN_WIDTH = 32; @@ -168,6 +174,18 @@ public: static void onSearchEdit(const std::string& search_string, void* user_data ); static void onTextureSelect( const LLTextureEntry& te, void *data ); + // tag: vaa emerald local_asset_browser [begin] +// static void onBtnLocal( void* userdata ); +// static void onBtnServer( void* userdata ); +// static void switchModes( bool localmode, void* userdata ); + + static void onBtnAdd( void* userdata ); + static void onBtnRemove( void* userdata ); + static void onBtnBrowser( void* userdata ); + + static void onLocalScrollCommit ( LLUICtrl* ctrl, void *userdata ); + // tag: vaa emerald local_asset_browser [end] + protected: LLPointer mTexturep; LLTextureCtrl* mOwner; @@ -198,6 +216,7 @@ protected: BOOL mNoCopyTextureSelected; F32 mContextConeOpacity; LLSaveFolderState mSavedFolderState; + LLScrollListCtrl* mLocalScrollCtrl; // tag: vaa emerald local_asset_browser }; LLFloaterTexturePicker::LLFloaterTexturePicker( @@ -243,6 +262,18 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); childSetAction("Invisible", LLFloaterTexturePicker::onBtnInvisible,this); + // tag: vaa emerald local_asset_browser [begin] +// childSetAction("Local", LLFloaterTexturePicker::onBtnLocal, this); +// childSetAction("Server", LLFloaterTexturePicker::onBtnServer, this); + childSetAction("Add", LLFloaterTexturePicker::onBtnAdd, this); + childSetAction("Remove", LLFloaterTexturePicker::onBtnRemove, this); + childSetAction("Browser", LLFloaterTexturePicker::onBtnBrowser, this); + + mLocalScrollCtrl = getChild("local_name_list"); + mLocalScrollCtrl->setCallbackUserData(this); + mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit); + LocalAssetBrowser::UpdateTextureCtrlList( mLocalScrollCtrl ); + // tag: vaa emerald local_asset_browser [end] childSetCommitCallback("show_folders_check", onShowFolders, this); childSetVisible("show_folders_check", FALSE); @@ -779,6 +810,70 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata) self->close(); } +// tag: vaa emerald local_asset_browser [begin] + +// static, switches between showing inventory instance for global bitmaps +// to showing the scroll list for local ones and back. +/* +void LLFloaterTexturePicker::onBtnLocal(void *userdata) +{ + switchModes( true, userdata ); +} + +void LLFloaterTexturePicker::onBtnServer(void *userdata) +{ + switchModes( false, userdata ); +} + +void LLFloaterTexturePicker::switchModes(bool localmode, void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + + // servermode widgets + self->childSetVisible("Local", !localmode); + self->childSetVisible("Default", !localmode); + self->childSetVisible("None", !localmode); + self->childSetVisible("Blank", !localmode); + self->mSearchEdit->setVisible(!localmode); + self->mInventoryPanel->setVisible(!localmode); + + // localmode widgets + self->childSetVisible("Server", localmode); + self->childSetVisible("Add", localmode); + self->childSetVisible("Remove", localmode); + self->childSetVisible("Browser", localmode); + self->mLocalScrollCtrl->setVisible(localmode); +} +*/ +void LLFloaterTexturePicker::onBtnAdd(void *userdata) +{ + LocalAssetBrowser::AddBitmap(); +} + +void LLFloaterTexturePicker::onBtnRemove(void *userdata) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + LocalAssetBrowser::DelBitmap( self->mLocalScrollCtrl->getAllSelected(), LOCALLIST_COL_ID ); +} + +void LLFloaterTexturePicker::onBtnBrowser(void *userdata) +{ + FloaterLocalAssetBrowser::show(NULL); +} + +// static, reacts to user clicking a valid field in the local scroll list. +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. +} + +// tag: vaa emerald local_asset_browser [end] + // static void LLFloaterTexturePicker::onBtnPipette( void* userdata ) { @@ -1322,6 +1417,40 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) } } +// tag: vaa emerald local_asset_browser [begin] + +/* + overriding onFloaterCommit to forcefeed it a uuid. + also, i still don't get the difference beween mImageItemID and mImageAssetID, + they seem to affect the same thing? using mImageAssetID. +*/ +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + + if( floaterp && getEnabled()) + { + mImageItemID = id; + mImageAssetID = id; //floaterp->getAssetID(); // using same as on above func. + // seems to work anyway. + + if (op == TEXTURE_SELECT && mOnSelectCallback) + { + mOnSelectCallback(this, mCallbackUserData); + } + else if (op == TEXTURE_CANCEL && mOnCancelCallback) + { + mOnCancelCallback(this, mCallbackUserData); + } + else + { + onCommit(); + } + } +} + +// tag: vaa emerald local_asset_browser [end] + void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { if( mImageAssetID != asset_id ) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index a39a18988..79c0f29ef 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -141,6 +141,7 @@ public: void onFloaterClose(); void onFloaterCommit(ETexturePickOp op); + void onFloaterCommit(ETexturePickOp op, LLUUID id); // tag: vaa emerald local_asset_browser // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. diff --git a/indra/newview/llviewerimage.h b/indra/newview/llviewerimage.h index 58e596c85..abff3ed64 100644 --- a/indra/newview/llviewerimage.h +++ b/indra/newview/llviewerimage.h @@ -335,6 +335,8 @@ public: void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}; + friend class LocalBitmap; // tag: vaa emerald local_asset_browser + private: /*virtual*/ void cleanup(); // Cleanup the LLViewerImage (so we can reinitialize it) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 61292b343..66a386a9e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -65,6 +65,8 @@ public: ~LLViewerObjectList(); void destroy(); + + friend class LocalBitmap; // tag: vaa emerald local_asset_browser // For internal use only. Does NOT take a local id, takes an index into // an internal dynamic array. diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 8cc1331f5..70206a944 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -213,6 +213,9 @@ public: BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); + + // tag: vaa emerald local_asset_browser + void setSculptChanged(BOOL has_changed) { mSculptChanged = has_changed; } protected: S32 computeLODDetail(F32 distance, F32 radius); diff --git a/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml b/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml new file mode 100644 index 000000000..3ea7ce4af --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_local_asset_browse.xml @@ -0,0 +1,261 @@ + + + + + + + + +