Merged lindenlab/viewer-release into default

master
Rider Linden 2016-09-26 10:39:21 -07:00
commit 42dce67664
62 changed files with 5775 additions and 1891 deletions

View File

@ -518,3 +518,4 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
450de775fff66a011be1a001acd117cc623c445d 4.0.5-release
4070611edd95eb3a683d1cd97c4c07fe67793812 4.0.6-release
33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release
45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release

View File

@ -90,4 +90,3 @@ EDU_viewer_channel_suffix = "edu"
# environment variable 'email' to a space-separated list of email addresses

View File

@ -942,6 +942,12 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
{
llassert( getComponents() <= 4 );
// This is fairly bogus, but it'll do for now.
if (isBufferInvalid())
{
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
return;
}
U8 *pos = getData();
U32 x, y;
for (x = 0; x < getWidth(); x++)
@ -1069,6 +1075,11 @@ void LLImageRaw::composite( LLImageRaw* src )
{
LLImageRaw* dst = this; // Just for clarity.
if (!validateSrcAndDst("LLImageRaw::composite", src, dst))
{
return;
}
llassert(3 == src->getComponents());
llassert(3 == dst->getComponents());
@ -1136,7 +1147,6 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
U8* src_data = src->getData();
U8* dst_data = dst->getData();
S32 pixels = getWidth() * getHeight();
@ -1171,6 +1181,11 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
{
LLImageRaw* dst = this; // Just for clarity.
if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))
{
return;
}
llassert( 1 == src->getComponents() );
llassert( 4 == dst->getComponents() );
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
@ -1193,6 +1208,12 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
// Fill the buffer with a constant color
void LLImageRaw::fill( const LLColor4U& color )
{
if (isBufferInvalid())
{
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
return;
}
S32 pixels = getWidth() * getHeight();
if( 4 == getComponents() )
{
@ -1231,14 +1252,13 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate()
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void LLImageRaw::copy(LLImageRaw* src)
{
if (!src)
LLImageRaw* dst = this; // Just for clarity.
if (!validateSrcAndDst("LLImageRaw::copy", src, dst))
{
LL_WARNS() << "LLImageRaw::copy called with a null src pointer" << LL_ENDL;
return;
}
LLImageRaw* dst = this; // Just for clarity.
if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
{
// No scaling needed
@ -1365,6 +1385,11 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
{
LLImageRaw* dst = this; // Just for clarity.
if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))
{
return;
}
llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
llassert_always( src->getComponents() == dst->getComponents() );
@ -1403,6 +1428,12 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
{
llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
if (isBufferInvalid())
{
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
return false;
}
S32 old_width = getWidth();
S32 old_height = getHeight();
@ -1692,6 +1723,25 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
}
}
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
{
if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
{
LL_WARNS() << func << ": Source: ";
if (!src) LL_CONT << "Null pointer";
else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer";
else LL_CONT << "OK";
LL_CONT << "; Destination: ";
if (!dst) LL_CONT << "Null pointer";
else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer";
else LL_CONT << "OK";
LL_CONT << "." << LL_ENDL;
return false;
}
return true;
}
//----------------------------------------------------------------------------

View File

@ -277,6 +277,9 @@ protected:
public:
static S32 sGlobalRawMemory;
static S32 sRawImageCount;
private:
bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
};
// Compressed representation of image.

View File

@ -201,7 +201,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress (&cinfo);
mHeight = cinfo.output_width;
mWidth = cinfo.output_width;
mHeight = cinfo.output_height;
jpeg_destroy_decompress(&cinfo);

View File

@ -31,9 +31,31 @@
#include "llpointer.h"
#include "llmath.h"
#include "llkdumem.h"
#include "stringize.h"
#include "kdu_block_coding.h"
#include <stdexcept>
#include <iostream>
namespace {
// exception used to keep KDU from terminating entire program -- see comments
// in LLKDUMessageError::flush()
struct KDUError: public std::runtime_error
{
KDUError(const std::string& msg): std::runtime_error(msg) {}
};
} // anonymous namespace
// stream kdu_dims to std::ostream
// Turns out this must NOT be in the anonymous namespace!
inline
std::ostream& operator<<(std::ostream& out, const kdu_dims& dims)
{
return out << "(" << dims.pos.x << "," << dims.pos.y << "),"
"[" << dims.size.x << "x" << dims.size.y << "]";
}
class kdc_flow_control {
public:
@ -165,9 +187,15 @@ struct LLKDUMessageError : public LLKDUMessage
// terminating handler→flush call."
// So throwing an exception here isn't arbitrary: we MUST throw an
// exception if we want to recover from a KDU error.
// Because this confused me: the above quote specifically refers to
// the kdu_error class, which is constructed internally within KDU at
// the point where a fatal error is discovered and reported. It is NOT
// talking about the kdu_message subclass passed to
// kdu_customize_errors(). Destroying this static object at program
// shutdown will NOT engage the behavior described above.
if (end_of_message)
{
throw "KDU throwing an exception";
throw KDUError("LLKDUMessageError::flush()");
}
}
};
@ -196,6 +224,10 @@ LLImageJ2CKDU::~LLImageJ2CKDU()
// Stuff for new simple decode
void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
// This is called by the real (private) initDecode() (keep_codestream true)
// and getMetadata() methods (keep_codestream false). As far as nat can tell,
// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries()
// as well, when that still existed, with keep_codestream true and MODE_FAST.
void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode)
{
S32 data_size = base.getDataSize();
@ -206,6 +238,12 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
//
mCodeStreamp.reset();
// It's not clear to nat under what circumstances we would reuse a
// pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of
// two U32s and a pointer, so it's not as if it would be a huge overhead
// to allocate a new one every time.
// Also -- why is base.getData() tested specifically here? If that returns
// NULL, shouldn't we bail out of the whole method?
if (!mInputp && base.getData())
{
// The compressed data has been loaded
@ -262,13 +300,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
S32 components = mCodeStreamp->get_num_components();
if (components >= 3)
{ // Check that components have consistent dimensions (for PPM file)
kdu_dims dims1; mCodeStreamp->get_dims(1,dims1);
kdu_dims dims2; mCodeStreamp->get_dims(2,dims2);
if ((dims1 != dims) || (dims2 != dims))
// Check that components have consistent dimensions (for PPM file)
for (int idx = 1; idx < components; ++idx)
{
kdu_dims other_dims;
mCodeStreamp->get_dims(idx, other_dims);
if (other_dims != dims)
{
LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL;
// This method is only called from methods that catch KDUError.
// We want to fail the image load, not crash the viewer.
throw KDUError(STRINGIZE("Component " << idx << " dimensions "
<< other_dims
<< " do not match component 0 dimensions "
<< dims << "!"));
}
}
@ -295,6 +339,9 @@ void LLImageJ2CKDU::cleanupCodeStream()
mTileIndicesp.reset();
}
// This is the protected virtual method called by LLImageJ2C::initDecode().
// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by
// llimage_libtest.cpp's load_image() function. No detectable production use.
bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
{
return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);
@ -327,6 +374,9 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
return true;
}
// This is the real (private) initDecode() called both by the protected
// initDecode() method and by decodeImpl(). As far as nat can tell, only the
// decodeImpl() usage matters for production.
bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
{
base.resetLastError();
@ -384,9 +434,9 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
mTPosp->x = 0;
}
}
catch (const char* msg)
catch (const KDUError& msg)
{
base.setLastError(ll_safe_string(msg));
base.setLastError(msg.what());
return false;
}
catch (...)
@ -480,9 +530,9 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
return false;
}
}
catch (const char* msg)
catch (const KDUError& msg)
{
base.setLastError(ll_safe_string(msg));
base.setLastError(msg.what());
base.decodeFailed();
cleanupCodeStream();
return true; // done
@ -673,9 +723,9 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
base.updateData(); // set width, height
delete[] output_buffer;
}
catch(const char* msg)
catch(const KDUError& msg)
{
base.setLastError(ll_safe_string(msg));
base.setLastError(msg.what());
return false;
}
catch( ... )
@ -697,9 +747,9 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
setupCodeStream(base, false, MODE_FAST);
return true;
}
catch (const char* msg)
catch (const KDUError& msg)
{
base.setLastError(ll_safe_string(msg));
base.setLastError(msg.what());
return false;
}
catch (...)

View File

@ -2318,7 +2318,8 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLFloaterView::restoreAll()
{
// make sure all subwindows aren't minimized
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
child_list_t child_list = *(getChildList());
for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it)
{
LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
if (floaterp)

View File

@ -186,7 +186,6 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
LLUI::removePopup(view);
}
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
{
// notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)

View File

@ -263,6 +263,7 @@ set(viewer_SOURCE_FILES
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloateroutfitsnapshot.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloaterpathfindingcharacters.cpp
@ -403,6 +404,7 @@ set(viewer_SOURCE_FILES
llnotificationscripthandler.cpp
llnotificationstorage.cpp
llnotificationtiphandler.cpp
lloutfitgallery.cpp
lloutfitslist.cpp
lloutfitobserver.cpp
lloutputmonitorctrl.cpp
@ -879,6 +881,7 @@ set(viewer_HEADER_FILES
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloateroutfitsnapshot.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloaterpathfindingcharacters.h
@ -1009,6 +1012,7 @@ set(viewer_HEADER_FILES
llnotificationlistview.h
llnotificationmanager.h
llnotificationstorage.h
lloutfitgallery.h
lloutfitslist.h
lloutfitobserver.h
lloutputmonitorctrl.h
@ -1140,6 +1144,7 @@ set(viewer_HEADER_FILES
llsky.h
llslurl.h
llsnapshotlivepreview.h
llsnapshotmodel.h
llspatialpartition.h
llspeakers.h
llspeakingindicatormanager.h

View File

@ -1 +1 @@
4.0.8
4.0.9

View File

@ -137,6 +137,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>AdvanceOutfitSnapshot</key>
<map>
<key>Comment</key>
<string>Display advanced parameter settings in outfit snaphot interface</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>AgentPause</key>
<map>
<key>Comment</key>
@ -14625,6 +14636,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>OutfitGallerySortByName</key>
<map>
<key>Comment</key>
<string>Always sort outfits by name in Outfit Gallery</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>OutfitOperationsTimeout</key>
<map>
<key>Comment</key>

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentcamera.h"
@ -1517,6 +1518,26 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit)
wearInventoryCategory(cat, false, false);
}
// Remove existing photo link from outfit folder.
void LLAppearanceMgr::removeOutfitPhoto(const LLUUID& outfit_id)
{
LLInventoryModel::cat_array_t sub_cat_array;
LLInventoryModel::item_array_t outfit_item_array;
gInventory.collectDescendents(
outfit_id,
sub_cat_array,
outfit_item_array,
LLInventoryModel::EXCLUDE_TRASH);
BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
{
LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
{
gInventory.removeItem(outfit_item->getUUID());
}
}
}
// Open outfit renaming dialog.
void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id)
{
@ -2945,6 +2966,16 @@ void LLAppearanceMgr::updateIsDirty()
gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items,
LLInventoryModel::EXCLUDE_TRASH, collector);
for (U32 i = 0; i < outfit_items.size(); ++i)
{
LLViewerInventoryItem* linked_item = outfit_items.at(i)->getLinkedItem();
if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
{
outfit_items.erase(outfit_items.begin() + i);
break;
}
}
if(outfit_items.size() != cof_items.size())
{
LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL;
@ -3092,6 +3123,14 @@ void appearance_mgr_update_dirty_state()
{
if (LLAppearanceMgr::instanceExists())
{
LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
LLUUID image_id = app_mgr.getOutfitImage();
if(image_id.notNull())
{
LLPointer<LLInventoryCallback> cb = NULL;
link_inventory_object(app_mgr.getBaseOutfitUUID(), image_id, cb);
}
LLAppearanceMgr::getInstance()->updateIsDirty();
LLAppearanceMgr::getInstance()->setOutfitLocked(false);
gAgentWearables.notifyLoadingFinished();
@ -3101,7 +3140,21 @@ void appearance_mgr_update_dirty_state()
void update_base_outfit_after_ordering()
{
LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
LLInventoryModel::cat_array_t sub_cat_array;
LLInventoryModel::item_array_t outfit_item_array;
gInventory.collectDescendents(app_mgr.getBaseOutfitUUID(),
sub_cat_array,
outfit_item_array,
LLInventoryModel::EXCLUDE_TRASH);
BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
{
LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
{
app_mgr.setOutfitImage(linked_item->getLinkedUUID());
}
}
LLPointer<LLInventoryCallback> dirty_state_updater =
new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);

View File

@ -61,6 +61,7 @@ public:
void changeOutfit(bool proceed, const LLUUID& category, bool append);
void replaceCurrentOutfit(const LLUUID& new_outfit);
void renameOutfit(const LLUUID& outfit_id);
void removeOutfitPhoto(const LLUUID& outfit_id);
void takeOffOutfit(const LLUUID& cat_id);
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
@ -184,6 +185,9 @@ public:
void wearBaseOutfit();
void setOutfitImage(const LLUUID& image_id) {mCOFImageID = image_id;}
LLUUID getOutfitImage() {return mCOFImageID;}
// Overrides the base outfit with the content from COF
// @return false if there is no base outfit
bool updateBaseOutfit();
@ -268,6 +272,8 @@ private:
LLTimer mInFlightTimer;
static bool mActive;
LLUUID mCOFImageID;
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
// Set of temp attachment UUIDs that should be removed

View File

@ -201,6 +201,7 @@
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llfloaterinventory.h"
@ -1447,6 +1448,7 @@ bool LLAppViewer::mainLoop()
display();
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
gGLActive = FALSE;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -238,8 +238,8 @@ void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible)
mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG);
previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode

View File

@ -0,0 +1,377 @@
/**
* @file llfloateroutfitsnapshot.cpp
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llagent.h"
#include "llfacebookconnect.h"
#include "llfloaterreg.h"
#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llpostcard.h"
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llsidetraypanelcontainer.h"
#include "llspinctrl.h"
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
// virtual
LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
{
LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
if (!ok_if_not_found)
{
llassert_always(active_panel != NULL);
}
return active_panel;
}
// virtual
LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
// virtual
LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
}
// This is the main function that keeps all the GUI controls in sync with the saved settings.
// It should be called anytime a setting is changed that could affect the controls.
// No other methods should be changing any of the controls directly except for helpers called by this method.
// The basic pattern for programmatically changing the GUI settings is to first set the
// appropriate saved settings and then call this method to sync the GUI with them.
// FIXME: The above comment seems obsolete now.
// virtual
void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
{
LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
LLSnapshotLivePreview* previewp = getPreviewView();
BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
// *TODO: Separate maximum size for Web images from postcards
LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
LLLocale locale(LLLocale::USER_LOCALE);
std::string bytes_string;
if (got_snap)
{
LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10);
}
// Update displayed image resolution.
LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
image_res_tb->setVisible(got_snap);
if (got_snap)
{
image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
}
floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor"));
updateResolution(floater);
if (previewp)
{
previewp->setSnapshotType(shot_type);
previewp->setSnapshotFormat(shot_format);
previewp->setSnapshotBufferType(layer_type);
}
LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
if (current_panel)
{
LLSD info;
info["have-snapshot"] = got_snap;
current_panel->updateControls(info);
}
LL_DEBUGS() << "finished updating controls" << LL_ENDL;
}
// virtual
std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix()
{
return "panel_outfit_snapshot_";
}
// Show/hide upload status message.
// virtual
void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
{
mFloater->setSuccessLabelPanelVisible(finished && ok);
mFloater->setFailureLabelPanelVisible(finished && !ok);
if (finished)
{
LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
finished_lbl->setValue(result_text);
LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
}
}
void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
{
LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
if (!view)
{
llassert(view);
return;
}
S32 width = OUTFIT_SNAPSHOT_WIDTH;
S32 height = OUTFIT_SNAPSHOT_HEIGHT;
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
S32 original_width = 0, original_height = 0;
previewp->getSize(original_width, original_height);
if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
{ //clamp snapshot resolution to window size when showing UI or HUD in snapshot
width = llmin(width, gViewerWindow->getWindowWidthRaw());
height = llmin(height, gViewerWindow->getWindowHeightRaw());
}
llassert(width > 0 && height > 0);
// use the resolution from the selected pre-canned drop-down choice
LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
previewp->setSize(width, height);
if (original_width != width || original_height != height)
{
// hide old preview as the aspect ratio could be wrong
checkAutoSnapshot(previewp, FALSE);
LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
previewp->updateSnapshot(TRUE);
}
}
}
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
// Default constructor
LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
: LLFloaterSnapshotBase(key),
mOutfitGallery(NULL)
{
impl = new Impl(this);
}
LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
{
}
// virtual
BOOL LLFloaterOutfitSnapshot::postBuild()
{
mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
// Filters
LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
for (U32 i = 0; i < filter_list.size(); i++)
{
filterbox->add(filter_list[i]);
}
childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
// create preview window
LLRect full_screen_rect = getRootView()->getRect();
LLSnapshotLivePreview::Params p;
p.rect(full_screen_rect);
LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
LLView* parent_view = gSnapshotFloaterView->getParent();
parent_view->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
parent_view->addChild(previewp);
parent_view->addChild(gSnapshotFloaterView);
//move snapshot floater to special purpose snapshotfloaterview
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
impl->mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
previewp->mKeepAspectRatio = FALSE;
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
return TRUE;
}
// virtual
void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
{
LLSnapshotLivePreview* preview = getPreviewView();
if (preview)
{
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
postPanelSwitch();
}
void LLFloaterOutfitSnapshot::onExtendFloater()
{
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
}
// static
void LLFloaterOutfitSnapshot::update()
{
LLFloaterOutfitSnapshot* inst = findInstance();
if (inst != NULL)
{
inst->impl->updateLivePreview();
}
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// virtual
void LLFloaterOutfitSnapshot::saveTexture()
{
LL_DEBUGS() << "saveTexture" << LL_ENDL;
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
{
llassert(previewp != NULL);
return;
}
if (mOutfitGallery)
{
mOutfitGallery->onBeforeOutfitSnapshotSave();
}
previewp->saveTexture(TRUE, getOutfitID().asString());
if (mOutfitGallery)
{
mOutfitGallery->onAfterOutfitSnapshotSave();
}
closeFloater();
}
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
{
}
LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
{
}

View File

@ -0,0 +1,123 @@
/**
* @file llfloateroutfitsnapshot.h
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, 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_LLFLOATEROUTFITSNAPSHOT_H
#define LL_LLFLOATEROUTFITSNAPSHOT_H
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "lloutfitgallery.h"
#include "llsnapshotlivepreview.h"
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterOutfitSnapshot);
public:
LLFloaterOutfitSnapshot(const LLSD& key);
/*virtual*/ ~LLFloaterOutfitSnapshot();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
static void update();
void onExtendFloater();
static LLFloaterOutfitSnapshot* getInstance();
static LLFloaterOutfitSnapshot* findInstance();
/*virtual*/ void saveTexture();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setOutfitID(LLUUID id) { mOutfitID = id; }
LLUUID getOutfitID() { return mOutfitID; }
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
class Impl;
friend class Impl;
private:
LLUUID mOutfitID;
LLOutfitGallery* mOutfitGallery;
};
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void updateResolution(void* data);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
/*virtual*/ std::string getSnapshotPanelPrefix();
/*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
private:
/*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
/*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
};
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
class LLOutfitSnapshotFloaterView : public LLFloaterView
{
public:
struct Params
: public LLInitParam::Block<Params, LLFloaterView::Params>
{
};
protected:
LLOutfitSnapshotFloaterView(const Params& p);
friend class LLUICtrlFactory;
public:
virtual ~LLOutfitSnapshotFloaterView();
};
extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
#endif // LL_LLFLOATEROUTFITSNAPSHOT_H

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2016, 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
@ -27,54 +27,184 @@
#ifndef LL_LLFLOATERSNAPSHOT_H
#define LL_LLFLOATERSNAPSHOT_H
#include "llagent.h"
#include "llfloater.h"
#include "llpanelsnapshot.h"
#include "llsnapshotmodel.h"
class LLSpinCtrl;
class LLSnapshotLivePreview;
class LLFloaterSnapshot : public LLFloater
class LLFloaterSnapshotBase : public LLFloater
{
LOG_CLASS(LLFloaterSnapshotBase);
public:
LLFloaterSnapshotBase(const LLSD& key);
virtual ~LLFloaterSnapshotBase();
/*virtual*/ void draw();
/*virtual*/ void onClose(bool app_quitting);
virtual S32 notify(const LLSD& info);
// TODO: create a snapshot model instead
virtual void saveTexture() = 0;
void postSave();
virtual void postPanelSwitch();
LLPointer<LLImageFormatted> getImageData();
LLSnapshotLivePreview* getPreviewView();
const LLVector3d& getPosTakenGlobal();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
void inventorySaveFailed();
class ImplBase;
friend class ImplBase;
ImplBase* impl;
protected:
LLUICtrl* mThumbnailPlaceholder;
LLUICtrl *mRefreshBtn, *mRefreshLabel;
LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
};
class LLFloaterSnapshotBase::ImplBase
{
public:
typedef enum e_status
{
STATUS_READY,
STATUS_WORKING,
STATUS_FINISHED
} EStatus;
ImplBase(LLFloaterSnapshotBase* floater) : mAvatarPauseHandles(),
mLastToolset(NULL),
mAspectRatioCheckOff(false),
mNeedRefresh(false),
mStatus(STATUS_READY),
mFloater(floater)
{}
virtual ~ImplBase()
{
//unpause avatars
mAvatarPauseHandles.clear();
}
static void onClickNewSnapshot(void* data);
static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
static void onClickFilter(LLUICtrl *ctrl, void* data);
static void onClickUICheck(LLUICtrl *ctrl, void* data);
static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
virtual LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) = 0;
virtual LLSnapshotModel::ESnapshotType getActiveSnapshotType(LLFloaterSnapshotBase* floater);
virtual LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater) = 0;
virtual std::string getSnapshotPanelPrefix() = 0;
LLSnapshotLivePreview* getPreviewView();
virtual void updateControls(LLFloaterSnapshotBase* floater) = 0;
virtual void updateLayout(LLFloaterSnapshotBase* floater);
virtual void updateLivePreview();
virtual void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
virtual EStatus getStatus() const { return mStatus; }
virtual void setNeedRefresh(bool need);
static BOOL updatePreviewList(bool initialized);
void setAdvanced(bool advanced) { mAdvanced = advanced; }
virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
void setWorking(bool working);
virtual void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) = 0;
public:
LLFloaterSnapshotBase* mFloater;
std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
LLToolset* mLastToolset;
LLHandle<LLView> mPreviewHandle;
bool mAspectRatioCheckOff;
bool mNeedRefresh;
bool mAdvanced;
EStatus mStatus;
};
class LLFloaterSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterSnapshot);
public:
typedef enum e_snapshot_format
{
SNAPSHOT_FORMAT_PNG,
SNAPSHOT_FORMAT_JPEG,
SNAPSHOT_FORMAT_BMP
} ESnapshotFormat;
LLFloaterSnapshot(const LLSD& key);
virtual ~LLFloaterSnapshot();
/*virtual*/ ~LLFloaterSnapshot();
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
/*virtual*/ S32 notify(const LLSD& info);
static void update();
// TODO: create a snapshot model instead
void onExtendFloater();
static LLFloaterSnapshot* getInstance();
static LLFloaterSnapshot* findInstance();
static void saveTexture();
static BOOL saveLocal();
static void postSave();
static void postPanelSwitch();
static void inventorySaveFailed();
static LLPointer<LLImageFormatted> getImageData();
static const LLVector3d& getPosTakenGlobal();
/*virtual*/ void saveTexture();
BOOL saveLocal();
static void setAgentEmail(const std::string& email);
static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
class Impl;
friend class Impl;
};
///----------------------------------------------------------------------------
/// Class LLFloaterSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void applyKeepAspectCheck(LLFloaterSnapshotBase* view, BOOL checked);
void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
void onImageQualityChange(LLFloaterSnapshotBase* view, S32 quality_val);
void onImageFormatChange(LLFloaterSnapshotBase* view);
void applyCustomResolution(LLFloaterSnapshotBase* view, S32 w, S32 h);
static void onSendingPostcardFinished(LLFloaterSnapshotBase* floater, bool status);
BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
void setImageSizeSpinnersValues(LLFloaterSnapshotBase *view, S32 width, S32 height);
void updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
LLSpinCtrl* getWidthSpinner(LLFloaterSnapshotBase* floater);
LLSpinCtrl* getHeightSpinner(LLFloaterSnapshotBase* floater);
void enableAspectRatioCheckbox(LLFloaterSnapshotBase* floater, BOOL enable);
void setAspectRatioCheckboxValue(LLFloaterSnapshotBase* floater, BOOL checked);
/*virtual*/ std::string getSnapshotPanelPrefix();
void setResolution(LLFloaterSnapshotBase* floater, const std::string& comboname);
/*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
private:
static LLUICtrl* sThumbnailPlaceholder;
LLUICtrl *mRefreshBtn, *mRefreshLabel;
LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
class Impl;
Impl& impl;
/*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
void comboSetCustom(LLFloaterSnapshotBase *floater, const std::string& comboname);
void checkAspectRatio(LLFloaterSnapshotBase *view, S32 index);
void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
};
class LLSnapshotFloaterView : public LLFloaterView

View File

@ -241,8 +241,8 @@ void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible)
mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode

View File

@ -4358,10 +4358,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
// Returns true if the item can be moved to Current Outfit or any outfit folder.
static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
{
if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
(inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
(inv_item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) &&
(inv_item->getInventoryType() != LLInventoryType::IT_OBJECT))
LLInventoryType::EType inv_type = inv_item->getInventoryType();
if ((inv_type != LLInventoryType::IT_WEARABLE) &&
(inv_type != LLInventoryType::IT_GESTURE) &&
(inv_type != LLInventoryType::IT_ATTACHMENT) &&
(inv_type != LLInventoryType::IT_OBJECT) &&
(inv_type != LLInventoryType::IT_SNAPSHOT) &&
(inv_type != LLInventoryType::IT_TEXTURE))
{
return FALSE;
}
@ -4372,6 +4375,11 @@ static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_curr
return FALSE;
}
if((inv_type == LLInventoryType::IT_TEXTURE) || (inv_type == LLInventoryType::IT_SNAPSHOT))
{
return TRUE;
}
if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
{
return FALSE;
@ -4422,6 +4430,14 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
{
if((inv_item->getInventoryType() == LLInventoryType::IT_TEXTURE) || (inv_item->getInventoryType() == LLInventoryType::IT_SNAPSHOT))
{
LLAppearanceMgr::instance().removeOutfitPhoto(mUUID);
LLPointer<LLInventoryCallback> cb = NULL;
link_inventory_object(mUUID, LLConstPointer<LLInventoryObject>(inv_item), cb);
return;
}
// BAP - should skip if dup.
if (move_is_into_current_outfit)
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,284 @@
/**
* @file lloutfitgallery.h
* @author Pavlo Kryvych
* @brief Visual gallery of agent's outfits for My Appearance side panel
*
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2015, 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_LLOUTFITGALLERYCTRL_H
#define LL_LLOUTFITGALLERYCTRL_H
#include "llextendedstatus.h"
#include "lliconctrl.h"
#include "lllayoutstack.h"
#include "lloutfitslist.h"
#include "llpanelappearancetab.h"
#include "lltexturectrl.h"
#include "llviewertexture.h"
#include <vector>
class LLVFS;
class LLOutfitGallery;
class LLOutfitGalleryItem;
class LLOutfitListGearMenuBase;
class LLOutfitGalleryGearMenu;
class LLOutfitGalleryContextMenu;
class LLUpdateGalleryOnPhotoLinked : public LLInventoryCallback
{
public:
LLUpdateGalleryOnPhotoLinked(){}
virtual ~LLUpdateGalleryOnPhotoLinked(){}
/* virtual */ void fire(const LLUUID& inv_item_id);
private:
};
class LLOutfitGallery : public LLOutfitListBase
{
public:
friend class LLOutfitGalleryGearMenu;
friend class LLOutfitGalleryContextMenu;
friend class LLUpdateGalleryOnPhotoLinked;
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> row_panel_height;
Optional<S32> row_panel_width_factor;
Optional<S32> gallery_width_factor;
Optional<S32> vertical_gap;
Optional<S32> horizontal_gap;
Optional<S32> item_width;
Optional<S32> item_height;
Optional<S32> item_horizontal_gap;
Optional<S32> items_in_row;
Params();
};
static const LLOutfitGallery::Params& getDefaultParams();
LLOutfitGallery(const LLOutfitGallery::Params& params = getDefaultParams());
virtual ~LLOutfitGallery();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& info);
/*virtual*/ void draw();
void onSelectPhoto(LLUUID selected_outfit_id);
void onTakeSnapshot(LLUUID selected_outfit_id);
void wearSelectedOutfit();
/*virtual*/ void setFilterSubString(const std::string& string);
/*virtual*/ void getCurrentCategories(uuid_vec_t& vcur);
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
/*virtual*/ void updateRemovedCategory(LLUUID cat_id);
/*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
/*virtual*/ bool hasItemSelected();
/*virtual*/ bool canWearSelected();
/*virtual*/ bool getHasExpandableFolders() { return FALSE; }
void updateMessageVisibility();
bool hasDefaultImage(const LLUUID& outfit_cat_id);
void refreshTextures(const LLUUID& category_id);
void refreshOutfit(const LLUUID& category_id);
void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id);
void onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture);
void onBeforeOutfitSnapshotSave();
void onAfterOutfitSnapshotSave();
protected:
/*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
/*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
/*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
/*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
/*virtual*/ void onCollapseAllFolders() {}
/*virtual*/ void onExpandAllFolders() {}
/*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring);
private:
void loadPhotos();
void uploadPhoto(LLUUID outfit_id);
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
LLUUID getDefaultPhoto();
void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id);
bool checkRemovePhoto(LLUUID outfit_id);
void addToGallery(LLOutfitGalleryItem* item);
void removeFromGalleryLast(LLOutfitGalleryItem* item);
void removeFromGalleryMiddle(LLOutfitGalleryItem* item);
LLPanel* addLastRow();
void removeLastRow();
void moveRowUp(int row);
void moveRowDown(int row);
void moveRow(int row, int pos);
LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap);
void removeFromLastRow(LLOutfitGalleryItem* item);
void reArrangeRows(S32 row_diff = 0);
void updateRowsIfNeeded();
void updateGalleryWidth();
LLOutfitGalleryItem* buildGalleryItem(std::string name);
void onTextureSelectionChanged(LLInventoryItem* itemp);
void buildGalleryPanel(int row_count);
void reshapeGalleryPanel(int row_count);
LLPanel* buildItemPanel(int left);
LLPanel* buildRowPanel(int left, int bottom);
void moveRowPanel(LLPanel* stack, int left, int bottom);
std::vector<LLPanel*> mRowPanels;
std::vector<LLPanel*> mItemPanels;
std::vector<LLOutfitGalleryItem*> mItems;
std::vector<LLOutfitGalleryItem*> mHiddenItems;
LLScrollContainer* mScrollPanel;
LLPanel* mGalleryPanel;
LLPanel* mLastRowPanel;
LLUUID mOutfitLinkPending;
LLUUID mOutfitRenamePending;
LLTextBox* mMessageTextBox;
bool mGalleryCreated;
int mRowCount;
int mItemsAddedCount;
LLPointer<LLViewerTexture> mTextureSelected;
/* Params */
int mRowPanelHeight;
int mVerticalGap;
int mHorizontalGap;
int mItemWidth;
int mItemHeight;
int mItemHorizontalGap;
int mItemsInRow;
int mRowPanelWidth;
int mGalleryWidth;
int mRowPanWidthFactor;
int mGalleryWidthFactor;
LLListContextMenu* mOutfitGalleryMenu;
LLHandle<LLFloater> mFloaterHandle;
typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t;
typedef outfit_map_t::value_type outfit_map_value_t;
outfit_map_t mOutfitMap;
typedef std::map<LLOutfitGalleryItem*, int> item_num_map_t;
typedef item_num_map_t::value_type item_numb_map_value_t;
item_num_map_t mItemIndexMap;
LLInventoryCategoriesObserver* mTexturesObserver;
LLInventoryCategoriesObserver* mOutfitsObserver;
};
class LLOutfitGalleryContextMenu : public LLOutfitContextMenu
{
public:
friend class LLOutfitGallery;
LLOutfitGalleryContextMenu(LLOutfitListBase* outfit_list)
: LLOutfitContextMenu(outfit_list),
mOutfitList(outfit_list){}
protected:
/* virtual */ LLContextMenu* createMenu();
bool onEnable(LLSD::String param);
bool onVisible(LLSD::String param);
void onUploadPhoto(const LLUUID& outfit_cat_id);
void onSelectPhoto(const LLUUID& outfit_cat_id);
void onRemovePhoto(const LLUUID& outfit_cat_id);
void onTakeSnapshot(const LLUUID& outfit_cat_id);
void onCreate(const LLSD& data);
void onRemoveOutfit(const LLUUID& outfit_cat_id);
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id);
private:
LLOutfitListBase* mOutfitList;
};
class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase
{
public:
friend class LLOutfitGallery;
LLOutfitGalleryGearMenu(LLOutfitListBase* olist);
protected:
/*virtual*/ void onUpdateItemsVisibility();
private:
/*virtual*/ void onUploadFoto();
/*virtual*/ void onSelectPhoto();
/*virtual*/ void onTakeSnapshot();
/*virtual*/ void onRemovePhoto();
/*virtual*/ void onChangeSortOrder();
bool hasDefaultImage();
};
class LLOutfitGalleryItem : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{};
LLOutfitGalleryItem(const Params& p);
virtual ~LLOutfitGalleryItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
void setDefaultImage();
void setImageAssetId(LLUUID asset_id);
LLUUID getImageAssetId();
void setOutfitName(std::string name);
void setOutfitWorn(bool value);
void setSelected(bool value);
std::string getItemName() {return mOutfitName;}
bool isDefaultImage() {return mDefaultImage;}
bool isHidden() {return mHidden;}
void setHidden(bool hidden) {mHidden = hidden;}
private:
LLPointer<LLViewerFetchedTexture> mTexturep;
LLUUID mImageAssetId;
LLTextBox* mOutfitNameText;
LLTextBox* mOutfitWornText;
LLPanel* mTextBgPanel;
LLPanel* mFotoBgPanel;
bool mSelected;
bool mWorn;
bool mDefaultImage;
bool mHidden;
std::string mOutfitName;
};
#endif // LL_LLOUTFITGALLERYCTRL_H

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,14 @@
// newview
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
#include "llpanelappearancetab.h"
#include "lltoggleablemenu.h"
#include "llviewermenu.h"
class LLAccordionCtrlTab;
class LLInventoryCategoriesObserver;
class LLOutfitListGearMenu;
class LLOutfitListGearMenuBase;
class LLWearableItemsList;
class LLListContextMenu;
@ -57,6 +60,142 @@ public:
/*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const;
};
class LLOutfitListBase : public LLPanelAppearanceTab
{
public:
typedef boost::function<void(const LLUUID&)> selection_change_callback_t;
typedef boost::signals2::signal<void(const LLUUID&)> selection_change_signal_t;
LLOutfitListBase();
virtual ~LLOutfitListBase();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& info);
void refreshList(const LLUUID& category_id);
void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
// highlights currently worn outfit in list and unhighlights previously worn
void highlightBaseOutfit();
void ChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
virtual void getCurrentCategories(uuid_vec_t& vcur) = 0;
virtual void updateAddedCategory(LLUUID cat_id) = 0;
virtual void updateRemovedCategory(LLUUID cat_id) = 0;
virtual void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) = 0;
virtual void sortOutfits();
void removeSelected();
void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
void outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
virtual bool isActionEnabled(const LLSD& userdata);
virtual void performAction(std::string action);
virtual bool hasItemSelected() = 0;
virtual bool canWearSelected() = 0;
virtual void deselectOutfit(const LLUUID& category_id);
void signalSelectionOutfitUUID(const LLUUID& category_id);
void collapseAllFolders();
virtual void onCollapseAllFolders() = 0;
void expandAllFolders();
virtual void onExpandAllFolders() = 0;
virtual bool getHasExpandableFolders() = 0;
protected:
virtual LLOutfitListGearMenuBase* createGearMenu() = 0;
virtual void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) = 0;
virtual void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) = 0;
virtual void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) = 0;
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0;
bool mIsInitialized;
LLInventoryCategoriesObserver* mCategoriesObserver;
LLUUID mSelectedOutfitUUID;
// id of currently highlited outfit
LLUUID mHighlightedOutfitUUID;
selection_change_signal_t mSelectionChangeSignal;
LLListContextMenu* mOutfitMenu;
LLOutfitListGearMenuBase* mGearMenu;
};
//////////////////////////////////////////////////////////////////////////
class LLOutfitContextMenu : public LLListContextMenu
{
public:
LLOutfitContextMenu(LLOutfitListBase* outfit_list)
: LLListContextMenu(),
mOutfitList(outfit_list)
{}
protected:
/* virtual */ LLContextMenu* createMenu();
bool onEnable(LLSD::String param);
bool onVisible(LLSD::String param);
static void editOutfit();
static void renameOutfit(const LLUUID& outfit_cat_id);
private:
LLOutfitListBase* mOutfitList;
};
class LLOutfitListGearMenuBase
{
public:
LLOutfitListGearMenuBase(LLOutfitListBase* olist);
virtual ~LLOutfitListGearMenuBase();
void updateItemsVisibility();
LLToggleableMenu* getMenu();
protected:
virtual void onUpdateItemsVisibility();
virtual void onUploadFoto();
virtual void onSelectPhoto();
virtual void onTakeSnapshot();
virtual void onRemovePhoto();
virtual void onChangeSortOrder();
const LLUUID& getSelectedOutfitID();
LLOutfitListBase* mOutfitList;
LLToggleableMenu* mMenu;
private:
LLViewerInventoryCategory* getSelectedOutfit();
void onWear();
void onAdd();
void onTakeOff();
void onRename();
void onCreate(const LLSD& data);
bool onEnable(LLSD::String param);
bool onVisible(LLSD::String param);
};
class LLOutfitListGearMenu : public LLOutfitListGearMenuBase
{
public:
LLOutfitListGearMenu(LLOutfitListBase* olist);
virtual ~LLOutfitListGearMenu();
protected:
/*virtual*/ void onUpdateItemsVisibility();
};
/**
* @class LLOutfitsList
*
@ -66,11 +205,9 @@ public:
*
* Starts fetching necessary inventory content on first opening.
*/
class LLOutfitsList : public LLPanelAppearanceTab
class LLOutfitsList : public LLOutfitListBase
{
public:
typedef boost::function<void (const LLUUID&)> selection_change_callback_t;
typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t;
LLOutfitsList();
virtual ~LLOutfitsList();
@ -79,78 +216,76 @@ public:
/*virtual*/ void onOpen(const LLSD& info);
void refreshList(const LLUUID& category_id);
//virtual void refreshList(const LLUUID& category_id);
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
/*virtual*/ void updateRemovedCategory(LLUUID cat_id);
// highlits currently worn outfit tab text and unhighlights previously worn
void highlightBaseOutfit();
/*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
void performAction(std::string action);
//void performAction(std::string action);
void removeSelected();
void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
/*virtual*/ void setFilterSubString(const std::string& string);
/*virtual*/ bool isActionEnabled(const LLSD& userdata);
const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
// Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
// Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
void wearSelectedItems();
/**
* Returns true if there is a selection inside currently selected outfit
*/
bool hasItemSelected();
/*virtual*/ bool hasItemSelected();
/**
Collapses all outfit accordions.
*/
void collapse_all_folders();
/*virtual*/ void onCollapseAllFolders();
/**
Expands all outfit accordions.
*/
void expand_all_folders();
void onExpandAllFolders();
/*virtual*/ bool getHasExpandableFolders() { return TRUE; }
protected:
LLOutfitListGearMenuBase* createGearMenu();
private:
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
/**
* Wrapper for LLCommonUtils::computeDifference. @see LLCommonUtils::computeDifference
*/
void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
//void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
void getCurrentCategories(uuid_vec_t& vcur);
/**
* Updates tab displaying outfit identified by category_id.
*/
void updateOutfitTab(const LLUUID& category_id);
/*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
/*virtual*/ void sortOutfits();
/*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
/**
* Resets previous selection and stores newly selected list and outfit id.
*/
void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
/*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
/**
*Resets items selection inside outfit
*/
void resetItemSelection(LLWearableItemsList* list, const LLUUID& category_id);
/**
* Saves newly selected outfit ID.
*/
void setSelectedOutfitUUID(const LLUUID& category_id);
/**
* Removes the outfit from selection.
*/
void deselectOutfit(const LLUUID& category_id);
/*virtual*/ void deselectOutfit(const LLUUID& category_id);
/**
* Try restoring selection for a temporary hidden tab.
@ -182,15 +317,16 @@ private:
*/
bool canWearSelected();
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
void onCOFChanged();
void onSelectionChange(LLUICtrl* ctrl);
void onListSelectionChange(LLUICtrl* ctrl);
/*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
static void onOutfitRename(const LLSD& notification, const LLSD& response);
LLInventoryCategoriesObserver* mCategoriesObserver;
//LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
LLPanel* mListCommands;
@ -199,11 +335,6 @@ private:
typedef wearables_lists_map_t::value_type wearables_lists_map_value_t;
wearables_lists_map_t mSelectedListsMap;
LLUUID mSelectedOutfitUUID;
// id of currently highlited outfit
LLUUID mHighlightedOutfitUUID;
selection_change_signal_t mSelectionChangeSignal;
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
typedef outfits_map_t::value_type outfits_map_value_t;
outfits_map_t mOutfitsMap;
@ -212,10 +343,9 @@ private:
// Used to monitor COF changes for updating items worn state. See EXT-8636.
uuid_vec_t mCOFLinkedItems;
LLOutfitListGearMenu* mGearMenu;
LLListContextMenu* mOutfitMenu;
//LLOutfitListGearMenu* mGearMenu;
bool mIsInitialized;
//bool mIsInitialized;
/**
* True if there is a selection inside currently selected outfit
*/

View File

@ -106,7 +106,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mSavedFolderState(NULL),
mFilterText(""),
mMenuGearDefault(NULL),
mMenuAdd(NULL),
mMenuAddHandle(),
mNeedUploadCost(true)
{
// Menu Callbacks (non contex menus)
@ -200,10 +200,15 @@ BOOL LLPanelMainInventory::postBuild()
// *TODO:Get the cost info from the server
const std::string upload_cost("10");
mMenuAdd->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
}
// Trigger callback for focus received so we can deselect items in inbox/outbox
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
@ -983,7 +988,8 @@ void LLPanelMainInventory::initListCommandsHandlers()
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGearMenuButton->setMenu(mMenuGearDefault);
mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAddHandle = menu->getHandle();
// Update the trash button when selected item(s) get worn or taken off.
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
@ -1001,11 +1007,15 @@ void LLPanelMainInventory::onAddButtonClick()
// Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
// unless "Always show folders" is checked in the filter options.
bool recent_active = ("Recent Items" == mActivePanel->getName());
mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
setUploadCostIfNeeded();
setUploadCostIfNeeded();
showActionMenu(mMenuAdd,"add_btn");
showActionMenu(menu,"add_btn");
}
}
void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
@ -1156,7 +1166,11 @@ void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
{
if(!new_visibility)
{
mMenuAdd->setVisible(FALSE);
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
menu->setVisible(FALSE);
}
getActivePanel()->getRootFolder()->finishRenamingItem();
}
}
@ -1289,9 +1303,10 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
// have two instances of Inventory panel at the moment(and two instances of context menu),
// call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances.
if(mNeedUploadCost && mMenuAdd)
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if(mNeedUploadCost && menu)
{
LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild<LLMenuItemBranchGL>("upload");
LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload");
if(upload_menu)
{
S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();

View File

@ -156,8 +156,8 @@ protected:
private:
LLDragAndDropButton* mTrashButton;
LLToggleableMenu* mMenuGearDefault;
LLMenuGL* mMenuAdd;
LLMenuButton* mGearMenuButton;
LLHandle<LLView> mMenuAddHandle;
bool mNeedUploadCost;
// List Commands //

View File

@ -37,6 +37,7 @@
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "lloutfitobserver.h"
#include "lloutfitgallery.h"
#include "lloutfitslist.h"
#include "llpanelwearing.h"
#include "llsaveoutfitcombobtn.h"
@ -44,6 +45,7 @@
#include "llviewerfoldertype.h"
static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";
static const std::string COF_TAB_NAME = "cof_tab";
static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
@ -165,14 +167,22 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
void LLPanelOutfitsInventory::onWearButtonClick()
{
if (mMyOutfitsPanel->hasItemSelected())
if(isOutfitsListPanelActive())
{
mMyOutfitsPanel->wearSelectedItems();
if (mMyOutfitsPanel->hasItemSelected())
{
mMyOutfitsPanel->wearSelectedItems();
}
else
{
mMyOutfitsPanel->performAction("replaceoutfit");
}
}
else
else if(isOutfitsGalleryPanelActive())
{
mMyOutfitsPanel->performAction("replaceoutfit");
mOutfitGalleryPanel->wearSelectedOutfit();
}
}
bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response)
@ -234,6 +244,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
mListCommands = getChild<LLPanel>("bottom_panel");
mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
}
void LLPanelOutfitsInventory::updateListCommands()
@ -245,15 +256,23 @@ void LLPanelOutfitsInventory::updateListCommands()
LLButton* wear_btn = mListCommands->getChild<LLButton>("wear_btn");
mMyOutfitsPanel->childSetEnabled("trash_btn", trash_enabled);
mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled);
wear_btn->setEnabled(wear_enabled);
wear_btn->setVisible(wear_visible);
mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
wear_btn->setToolTip(getString(mMyOutfitsPanel->hasItemSelected() ? "wear_items_tooltip" : "wear_outfit_tooltip"));
wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip"));
}
void LLPanelOutfitsInventory::onTrashButtonClick()
{
mMyOutfitsPanel->removeSelected();
if(isOutfitsListPanelActive())
{
mMyOutfitsPanel->removeSelected();
}
else if(isOutfitsGalleryPanelActive())
{
mOutfitGalleryPanel->removeSelected();
}
}
bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
@ -268,12 +287,16 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
void LLPanelOutfitsInventory::initTabPanels()
{
//TODO: Add LLOutfitGallery change callback
mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME);
mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME);
mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
mOutfitGalleryPanel = findChild<LLOutfitGallery>(OUTFIT_GALLERY_TAB_NAME);
mOutfitGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
}
@ -296,6 +319,22 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const
return mActivePanel->getName() == COF_TAB_NAME;
}
bool LLPanelOutfitsInventory::isOutfitsListPanelActive() const
{
if (!mActivePanel) return false;
return mActivePanel->getName() == OUTFITS_TAB_NAME;
}
bool LLPanelOutfitsInventory::isOutfitsGalleryPanelActive() const
{
if (!mActivePanel) return false;
return mActivePanel->getName() == OUTFIT_GALLERY_TAB_NAME;
}
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
updateVerbs();

View File

@ -30,8 +30,9 @@
#include "llpanel.h"
class LLOutfitGallery;
class LLOutfitsList;
class LLOutfitListGearMenu;
class LLOutfitListGearMenuBase;
class LLPanelAppearanceTab;
class LLPanelWearing;
class LLMenuGL;
@ -72,10 +73,13 @@ protected:
void initTabPanels();
void onTabChange();
bool isCOFPanelActive() const;
bool isOutfitsListPanelActive() const;
bool isOutfitsGalleryPanelActive() const;
private:
LLPanelAppearanceTab* mActivePanel;
LLOutfitsList* mMyOutfitsPanel;
LLOutfitGallery* mOutfitGalleryPanel;
LLPanelWearing* mCurrentOutfitPanel;
// tab panels //

View File

@ -29,6 +29,8 @@
// libs
#include "llcombobox.h"
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "lltrans.h"
@ -50,15 +52,29 @@ S32 power_of_two(S32 sz, S32 upper)
return res;
}
LLPanelSnapshot::LLPanelSnapshot()
: mSnapshotFloater(NULL)
{}
// virtual
BOOL LLPanelSnapshot::postBuild()
{
getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));
getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
if (!getWidthSpinnerName().empty())
{
getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
}
if (!getHeightSpinnerName().empty())
{
getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
}
if (!getAspectRatioCBName().empty())
{
getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
}
updateControls(LLSD());
mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>();
return TRUE;
}
@ -76,13 +92,13 @@ void LLPanelSnapshot::onOpen(const LLSD& key)
// e.g. attempt to send a large BMP image by email.
if (old_format != new_format)
{
LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));
getParentByType<LLFloater>()->notify(LLSD().with("image-format-change", true));
}
}
LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
LLSnapshotModel::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
{
return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG;
}
void LLPanelSnapshot::enableControls(BOOL enable)
@ -92,27 +108,32 @@ void LLPanelSnapshot::enableControls(BOOL enable)
LLSpinCtrl* LLPanelSnapshot::getWidthSpinner()
{
llassert(!getWidthSpinnerName().empty());
return getChild<LLSpinCtrl>(getWidthSpinnerName());
}
LLSpinCtrl* LLPanelSnapshot::getHeightSpinner()
{
llassert(!getHeightSpinnerName().empty());
return getChild<LLSpinCtrl>(getHeightSpinnerName());
}
S32 LLPanelSnapshot::getTypedPreviewWidth() const
{
llassert(!getWidthSpinnerName().empty());
return getChild<LLUICtrl>(getWidthSpinnerName())->getValue().asInteger();
}
S32 LLPanelSnapshot::getTypedPreviewHeight() const
{
return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
llassert(!getHeightSpinnerName().empty());
return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
}
void LLPanelSnapshot::enableAspectRatioCheckbox(BOOL enable)
{
getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable);
llassert(!getAspectRatioCBName().empty());
getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable);
}
LLSideTrayPanelContainer* LLPanelSnapshot::getParentContainer()
@ -171,14 +192,17 @@ void LLPanelSnapshot::goBack()
void LLPanelSnapshot::cancel()
{
goBack();
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-ready", true));
getParentByType<LLFloater>()->notify(LLSD().with("set-ready", true));
}
void LLPanelSnapshot::onCustomResolutionCommit()
{
LLSD info;
LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(getWidthSpinnerName());
LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(getHeightSpinnerName());
std::string widthSpinnerName = getWidthSpinnerName();
std::string heightSpinnerName = getHeightSpinnerName();
llassert(!widthSpinnerName.empty() && !heightSpinnerName.empty());
LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(widthSpinnerName);
LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(heightSpinnerName);
if (getName() == "panel_snapshot_inventory")
{
S32 width = widthSpinner->getValue().asInteger();
@ -197,17 +221,22 @@ void LLPanelSnapshot::onCustomResolutionCommit()
info["w"] = widthSpinner->getValue().asInteger();
info["h"] = heightSpinner->getValue().asInteger();
}
LLFloaterSnapshot::getInstance()->notify(LLSD().with("custom-res-change", info));
getParentByType<LLFloater>()->notify(LLSD().with("custom-res-change", info));
}
void LLPanelSnapshot::onResolutionComboCommit(LLUICtrl* ctrl)
{
LLSD info;
info["combo-res-change"]["control-name"] = ctrl->getName();
LLFloaterSnapshot::getInstance()->notify(info);
getParentByType<LLFloater>()->notify(info);
}
void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl)
{
LLFloaterSnapshot::getInstance()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
getParentByType<LLFloater>()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
}
LLSnapshotModel::ESnapshotType LLPanelSnapshot::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_WEB;
}

View File

@ -27,9 +27,13 @@
#ifndef LL_LLPANELSNAPSHOT_H
#define LL_LLPANELSNAPSHOT_H
#include "llfloatersnapshot.h"
//#include "llfloatersnapshot.h"
#include "llpanel.h"
#include "llsnapshotmodel.h"
class LLSpinCtrl;
class LLSideTrayPanelContainer;
class LLFloaterSnapshotBase;
/**
* Snapshot panel base class.
@ -37,6 +41,8 @@ class LLSideTrayPanelContainer;
class LLPanelSnapshot: public LLPanel
{
public:
LLPanelSnapshot();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
@ -51,7 +57,8 @@ public:
virtual LLSpinCtrl* getWidthSpinner();
virtual LLSpinCtrl* getHeightSpinner();
virtual void enableAspectRatioCheckbox(BOOL enable);
virtual LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
virtual LLSnapshotModel::ESnapshotFormat getImageFormat() const;
virtual LLSnapshotModel::ESnapshotType getSnapshotType();
virtual void updateControls(const LLSD& info) = 0; ///< Update controls from saved settings
void enableControls(BOOL enable);
@ -59,12 +66,14 @@ protected:
LLSideTrayPanelContainer* getParentContainer();
void updateImageQualityLevel();
void goBack(); ///< Switch to the default (Snapshot Options) panel
void cancel();
virtual void cancel();
// common UI callbacks
void onCustomResolutionCommit();
void onResolutionComboCommit(LLUICtrl* ctrl);
void onKeepAspectRatioCommit(LLUICtrl* ctrl);
LLFloaterSnapshotBase* mSnapshotFloater;
};
#endif // LL_LLPANELSNAPSHOT_H

View File

@ -33,6 +33,7 @@
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
#include "llpanelsnapshot.h"
#include "llsnapshotlivepreview.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llstatusbar.h" // can_afford_transaction()
#include "llnotificationsutil.h"
@ -40,8 +41,22 @@
/**
* The panel provides UI for saving snapshot as an inventory texture.
*/
class LLPanelSnapshotInventoryBase
: public LLPanelSnapshot
{
LOG_CLASS(LLPanelSnapshotInventoryBase);
public:
LLPanelSnapshotInventoryBase();
/*virtual*/ BOOL postBuild();
protected:
void onSend();
/*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
};
class LLPanelSnapshotInventory
: public LLPanelSnapshot
: public LLPanelSnapshotInventoryBase
{
LOG_CLASS(LLPanelSnapshotInventory);
@ -60,10 +75,46 @@ private:
/*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; }
/*virtual*/ void updateControls(const LLSD& info);
void onSend();
};
static LLPanelInjector<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory");
class LLPanelOutfitSnapshotInventory
: public LLPanelSnapshotInventoryBase
{
LOG_CLASS(LLPanelOutfitSnapshotInventory);
public:
LLPanelOutfitSnapshotInventory();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
private:
/*virtual*/ std::string getWidthSpinnerName() const { return ""; }
/*virtual*/ std::string getHeightSpinnerName() const { return ""; }
/*virtual*/ std::string getAspectRatioCBName() const { return ""; }
/*virtual*/ std::string getImageSizeComboName() const { return "texture_size_combo"; }
/*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; }
/*virtual*/ void updateControls(const LLSD& info);
/*virtual*/ void cancel();
};
static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory");
static LLPanelInjector<LLPanelOutfitSnapshotInventory> panel_class2("llpaneloutfitsnapshotinventory");
LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase()
{
}
BOOL LLPanelSnapshotInventoryBase::postBuild()
{
return LLPanelSnapshot::postBuild();
}
LLSnapshotModel::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_TEXTURE;
}
LLPanelSnapshotInventory::LLPanelSnapshotInventory()
{
@ -78,7 +129,7 @@ BOOL LLPanelSnapshotInventory::postBuild()
getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE);
getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1));
return LLPanelSnapshot::postBuild();
return LLPanelSnapshotInventoryBase::postBuild();
}
// virtual
@ -102,19 +153,59 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected);
}
void LLPanelSnapshotInventory::onSend()
void LLPanelSnapshotInventoryBase::onSend()
{
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
if (can_afford_transaction(expected_upload_cost))
{
LLFloaterSnapshot::saveTexture();
LLFloaterSnapshot::postSave();
if (mSnapshotFloater)
{
mSnapshotFloater->saveTexture();
mSnapshotFloater->postSave();
}
}
else
{
LLSD args;
args["COST"] = llformat("%d", expected_upload_cost);
LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
LLFloaterSnapshot::inventorySaveFailed();
if (mSnapshotFloater)
{
mSnapshotFloater->inventorySaveFailed();
}
}
}
LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory()
{
mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this));
mCommitCallbackRegistrar.add("Inventory.SaveOutfitCancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this));
}
// virtual
BOOL LLPanelOutfitSnapshotInventory::postBuild()
{
return LLPanelSnapshotInventoryBase::postBuild();
}
// virtual
void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key)
{
getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()));
LLPanelSnapshot::onOpen(key);
}
// virtual
void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info)
{
const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
}
void LLPanelOutfitSnapshotInventory::cancel()
{
if (mSnapshotFloater)
{
mSnapshotFloater->closeFloater();
}
}

View File

@ -33,6 +33,7 @@
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
#include "llpanelsnapshot.h"
#include "llsnapshotlivepreview.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerwindow.h"
@ -55,7 +56,8 @@ private:
/*virtual*/ std::string getAspectRatioCBName() const { return "local_keep_aspect_check"; }
/*virtual*/ std::string getImageSizeComboName() const { return "local_size_combo"; }
/*virtual*/ std::string getImageSizePanelName() const { return "local_image_size_lp"; }
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const;
/*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
/*virtual*/ void updateControls(const LLSD& info);
S32 mLocalFormat;
@ -94,23 +96,23 @@ void LLPanelSnapshotLocal::onOpen(const LLSD& key)
}
// virtual
LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
LLSnapshotModel::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
{
LLFloaterSnapshot::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
LLSnapshotModel::ESnapshotFormat fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
LLComboBox* local_format_combo = getChild<LLComboBox>("local_format_combo");
const std::string id = local_format_combo->getValue().asString();
if (id == "PNG")
{
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
else if (id == "JPEG")
{
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
fmt = LLSnapshotModel::SNAPSHOT_FORMAT_JPEG;
}
else if (id == "BMP")
{
fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP;
fmt = LLSnapshotModel::SNAPSHOT_FORMAT_BMP;
}
return fmt;
@ -119,11 +121,11 @@ LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
// virtual
void LLPanelSnapshotLocal::updateControls(const LLSD& info)
{
LLFloaterSnapshot::ESnapshotFormat fmt =
(LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
LLSnapshotModel::ESnapshotFormat fmt =
(LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
getChild<LLComboBox>("local_format_combo")->selectNthItem((S32) fmt);
const bool show_quality_ctrls = (fmt == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
const bool show_quality_ctrls = (fmt == LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
getChild<LLUICtrl>("image_quality_slider")->setVisible(show_quality_ctrls);
getChild<LLUICtrl>("image_quality_level")->setVisible(show_quality_ctrls);
@ -162,10 +164,10 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
floater->notify(LLSD().with("set-working", true));
BOOL saved = LLFloaterSnapshot::saveLocal();
BOOL saved = floater->saveLocal();
if (saved)
{
LLFloaterSnapshot::postSave();
mSnapshotFloater->postSave();
goBack();
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
}
@ -174,3 +176,8 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
cancel();
}
}
LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_LOCAL;
}

View File

@ -62,6 +62,8 @@ private:
void onSendToFacebook();
void onSendToTwitter();
void onSendToFlickr();
LLFloaterSnapshotBase* mSnapshotFloater;
};
static LLPanelInjector<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions");
@ -86,6 +88,7 @@ LLPanelSnapshotOptions::~LLPanelSnapshotOptions()
// virtual
BOOL LLPanelSnapshotOptions::postBuild()
{
mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>();
return LLPanel::postBuild();
}
@ -112,7 +115,7 @@ void LLPanelSnapshotOptions::openPanel(const std::string& panel_name)
parent->openPanel(panel_name);
parent->getCurrentPanel()->onOpen(LLSD());
LLFloaterSnapshot::postPanelSwitch();
mSnapshotFloater->postPanelSwitch();
}
void LLPanelSnapshotOptions::onSaveToProfile()

View File

@ -38,6 +38,7 @@
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
#include "llpanelsnapshot.h"
#include "llpostcard.h"
#include "llsnapshotlivepreview.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerwindow.h"
#include "llviewerregion.h"
@ -64,12 +65,13 @@ private:
/*virtual*/ std::string getAspectRatioCBName() const { return "postcard_keep_aspect_check"; }
/*virtual*/ std::string getImageSizeComboName() const { return "postcard_size_combo"; }
/*virtual*/ std::string getImageSizePanelName() const { return "postcard_image_size_lp"; }
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; }
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; }
/*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
/*virtual*/ void updateControls(const LLSD& info);
bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
static void sendPostcardFinished(LLSD result);
void sendPostcard();
static void sendPostcardFinished(LLSD result);
void sendPostcard();
void onMsgFormFocusRecieved();
void onFormatComboCommit(LLUICtrl* ctrl);
@ -93,13 +95,6 @@ LLPanelSnapshotPostcard::LLPanelSnapshotPostcard()
// virtual
BOOL LLPanelSnapshotPostcard::postBuild()
{
// pick up the user's up-to-date email address
gAgent.sendAgentUserInfoRequest();
std::string name_string;
LLAgentUI::buildFullname(name_string);
getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
// For the first time a user focuses to .the msg box, all text will be selected.
getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(&LLPanelSnapshotPostcard::onMsgFormFocusRecieved, this));
@ -113,6 +108,16 @@ BOOL LLPanelSnapshotPostcard::postBuild()
// virtual
void LLPanelSnapshotPostcard::onOpen(const LLSD& key)
{
// pick up the user's up-to-date email address
if (mAgentEmail.empty())
{
gAgent.sendAgentUserInfoRequest();
std::string name_string;
LLAgentUI::buildFullname(name_string);
getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
}
LLPanelSnapshot::onOpen(key);
}
@ -190,8 +195,8 @@ void LLPanelSnapshotPostcard::sendPostcard()
getChild<LLUICtrl>("to_form")->getValue().asString(),
getChild<LLUICtrl>("subject_form")->getValue().asString(),
getChild<LLUICtrl>("msg_form")->getValue().asString(),
LLFloaterSnapshot::getPosTakenGlobal(),
LLFloaterSnapshot::getImageData(),
mSnapshotFloater->getPosTakenGlobal(),
mSnapshotFloater->getImageData(),
boost::bind(&LLPanelSnapshotPostcard::sendPostcardFinished, _4)));
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
@ -205,7 +210,7 @@ void LLPanelSnapshotPostcard::sendPostcard()
// Give user feedback of the event.
gViewerWindow->playSnapshotAnimAndSound();
LLFloaterSnapshot::postSave();
mSnapshotFloater->postSave();
}
void LLPanelSnapshotPostcard::onMsgFormFocusRecieved()
@ -264,3 +269,8 @@ void LLPanelSnapshotPostcard::onSend()
// Send postcard.
sendPostcard();
}
LLSnapshotModel::ESnapshotType LLPanelSnapshotPostcard::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_POSTCARD;
}

View File

@ -58,7 +58,7 @@ private:
/*virtual*/ std::string getAspectRatioCBName() const { return "profile_keep_aspect_check"; }
/*virtual*/ std::string getImageSizeComboName() const { return "profile_size_combo"; }
/*virtual*/ std::string getImageSizePanelName() const { return "profile_image_size_lp"; }
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; }
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; }
/*virtual*/ void updateControls(const LLSD& info);
void onSend();
@ -96,6 +96,6 @@ void LLPanelSnapshotProfile::onSend()
std::string caption = getChild<LLUICtrl>("caption")->getValue().asString();
bool add_location = getChild<LLUICtrl>("add_location_cb")->getValue().asBoolean();
LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location);
LLFloaterSnapshot::postSave();
LLWebProfile::uploadImage(mSnapshotFloater->getImageData(), caption, add_location);
mSnapshotFloater->postSave();
}

View File

@ -86,13 +86,13 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param
mNeedsFlash(TRUE),
mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
mDataSize(0),
mSnapshotType(SNAPSHOT_POSTCARD),
mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
mSnapshotType(LLSnapshotModel::SNAPSHOT_POSTCARD),
mSnapshotFormat(LLSnapshotModel::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
mSnapshotUpToDate(FALSE),
mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
mSnapshotActive(FALSE),
mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR),
mSnapshotBufferType(LLSnapshotModel::SNAPSHOT_TYPE_COLOR),
mFilterName(""),
mAllowRenderUI(TRUE),
mAllowFullScreenPreview(TRUE),
@ -737,7 +737,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
previewp->getWidth(),
previewp->getHeight(),
previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
previewp->getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE,
previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
FALSE,
previewp->mSnapshotBufferType,
@ -813,7 +813,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex];
gGL.getTexUnit(0)->bind(curr_preview_image);
curr_preview_image->setFilteringOption(getSnapshotType() == SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
curr_preview_image->setFilteringOption(getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
@ -827,7 +827,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
S32 LLSnapshotLivePreview::getEncodedImageWidth() const
{
S32 width = getWidth();
if (getSnapshotType() == SNAPSHOT_TEXTURE)
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
{
width = LLImageRaw::biasedDimToPowerOfTwo(width,MAX_TEXTURE_SIZE);
}
@ -836,7 +836,7 @@ S32 LLSnapshotLivePreview::getEncodedImageWidth() const
S32 LLSnapshotLivePreview::getEncodedImageHeight() const
{
S32 height = getHeight();
if (getSnapshotType() == SNAPSHOT_TEXTURE)
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
{
height = LLImageRaw::biasedDimToPowerOfTwo(height,MAX_TEXTURE_SIZE);
}
@ -854,7 +854,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
mPreviewImage->getHeight(),
mPreviewImage->getComponents());
if (getSnapshotType() == SNAPSHOT_TEXTURE)
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
{
// We don't store the intermediate formatted image in mFormattedImage in the J2C case
LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
@ -881,7 +881,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
{
// Update mFormattedImage if necessary
getFormattedImage();
if (getSnapshotFormat() == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
if (getSnapshotFormat() == LLSnapshotModel::SNAPSHOT_FORMAT_BMP)
{
// BMP hack : copy instead of decode otherwise decode will crash.
mPreviewImageEncoded->copy(mPreviewImage);
@ -903,23 +903,23 @@ void LLSnapshotLivePreview::estimateDataSize()
// Compression ratio
F32 ratio = 1.0;
if (getSnapshotType() == SNAPSHOT_TEXTURE)
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
{
ratio = 8.0; // This is what we shoot for when compressing to J2C
}
else
{
LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat();
LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
switch (format)
{
case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
ratio = 3.0; // Average observed PNG compression ratio
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
// Observed from JPG compression tests
ratio = (110 - mSnapshotQuality) / 2;
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
ratio = 1.0; // No compression with BMP
break;
}
@ -947,18 +947,18 @@ LLPointer<LLImageFormatted> LLSnapshotLivePreview::getFormattedImage()
}
// Create the new formatted image of the appropriate format.
LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat();
LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL;
switch (format)
{
case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
mFormattedImage = new LLImagePNG();
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
mFormattedImage = new LLImageJPEG(mSnapshotQuality);
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
mFormattedImage = new LLImageBMP();
break;
}
@ -978,7 +978,7 @@ void LLSnapshotLivePreview::setSize(S32 w, S32 h)
setHeight(h);
}
void LLSnapshotLivePreview::setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format)
void LLSnapshotLivePreview::setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format)
{
if (mSnapshotFormat != format)
{
@ -993,7 +993,7 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
h = getHeight();
}
void LLSnapshotLivePreview::saveTexture()
void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
{
LL_DEBUGS() << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
// gen a new uuid for this asset
@ -1033,12 +1033,14 @@ void LLSnapshotLivePreview::saveTexture()
std::string who_took_it;
LLAgentUI::buildFullname(who_took_it);
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
std::string name = "Snapshot: " + pos_string;
std::string desc = "Taken by " + who_took_it + " at " + pos_string;
std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;
std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;
LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY;
LLInventoryType::EType inv_type = outfit_snapshot ? LLInventoryType::IT_NONE : LLInventoryType::IT_SNAPSHOT;
LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
tid, LLAssetType::AT_TEXTURE, name, desc, 0,
LLFolderType::FT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT,
tid, LLAssetType::AT_TEXTURE, res_name, res_desc, 0,
folder_type, inv_type,
PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost));

View File

@ -27,7 +27,7 @@
#ifndef LL_LLSNAPSHOTLIVEPREVIEW_H
#define LL_LLSNAPSHOTLIVEPREVIEW_H
#include "llpanelsnapshot.h"
#include "llsnapshotmodel.h"
#include "llviewertexture.h"
#include "llviewerwindow.h"
@ -40,14 +40,6 @@ class LLSnapshotLivePreview : public LLView
{
LOG_CLASS(LLSnapshotLivePreview);
public:
enum ESnapshotType
{
SNAPSHOT_POSTCARD,
SNAPSHOT_TEXTURE,
SNAPSHOT_LOCAL,
SNAPSHOT_WEB
};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
@ -80,8 +72,8 @@ public:
void setMaxImageSize(S32 size) ;
S32 getMaxImageSize() {return mMaxImageSize ;}
ESnapshotType getSnapshotType() const { return mSnapshotType; }
LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
LLSnapshotModel::ESnapshotType getSnapshotType() const { return mSnapshotType; }
LLSnapshotModel::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
BOOL isSnapshotActive() { return mSnapshotActive; }
LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
@ -98,16 +90,16 @@ public:
void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format);
void setSnapshotType(LLSnapshotModel::ESnapshotType type) { mSnapshotType = type; }
void setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format);
bool setSnapshotQuality(S32 quality, bool set_by_user = true);
void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
void setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType type) { mSnapshotBufferType = type; }
void setAllowRenderUI(BOOL allow) { mAllowRenderUI = allow; }
void setAllowFullScreenPreview(BOOL allow) { mAllowFullScreenPreview = allow; }
void setFilter(std::string filter_name) { mFilterName = filter_name; }
std::string getFilter() const { return mFilterName; }
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
void saveTexture();
void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = "");
BOOL saveLocal();
LLPointer<LLImageFormatted> getFormattedImage();
@ -169,14 +161,14 @@ private:
LLVector3d mPosTakenGlobal;
S32 mSnapshotQuality;
S32 mDataSize;
ESnapshotType mSnapshotType;
LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat;
LLSnapshotModel::ESnapshotType mSnapshotType;
LLSnapshotModel::ESnapshotFormat mSnapshotFormat;
BOOL mSnapshotUpToDate;
LLFrameTimer mFallAnimTimer;
LLVector3 mCameraPos;
LLQuaternion mCameraRot;
BOOL mSnapshotActive;
LLViewerWindow::ESnapshotType mSnapshotBufferType;
LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType;
std::string mFilterName;
public:

View File

@ -0,0 +1,55 @@
/**
* @file llsnapshotmodel.h
* @brief Snapshot model for storing snapshot data etc.
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, 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_LLSNAPSHOTMODEL_H
#define LL_LLSNAPSHOTMODEL_H
class LLSnapshotModel
{
public:
enum ESnapshotType
{
SNAPSHOT_POSTCARD,
SNAPSHOT_TEXTURE,
SNAPSHOT_LOCAL,
SNAPSHOT_WEB
};
typedef enum e_snapshot_format
{
SNAPSHOT_FORMAT_PNG,
SNAPSHOT_FORMAT_JPEG,
SNAPSHOT_FORMAT_BMP
} ESnapshotFormat;
typedef enum
{
SNAPSHOT_TYPE_COLOR,
SNAPSHOT_TYPE_DEPTH
} ESnapshotLayerType;
};
#endif // LL_LLSNAPSHOTMODEL_H

View File

@ -37,8 +37,6 @@
#include "llbutton.h"
#include "lldraghandle.h"
#include "llfocusmgr.h"
#include "llviewertexture.h"
#include "llfolderview.h"
#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
@ -71,6 +69,7 @@
#include "llradiogroup.h"
#include "llfloaterreg.h"
#include "lllocalbitmaps.h"
#include "llerror.h"
static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
@ -82,118 +81,13 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
//static const char NO_IMAGE_NAME[] = "None";
//////////////////////////////////////////////////////////////////////////////////////////
// LLFloaterTexturePicker
class LLFloaterTexturePicker : public LLFloater
{
public:
LLFloaterTexturePicker(
LLTextureCtrl* owner,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image_name);
virtual ~LLFloaterTexturePicker();
// LLView overrides
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
std::string& tooltip_msg);
/*virtual*/ void draw();
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
// LLFloater overrides
/*virtual*/ BOOL postBuild();
/*virtual*/ void onClose(bool app_settings);
// New functions
void setImageID( const LLUUID& image_asset_id, bool set_selection = true);
void updateImageStats();
const LLUUID& getAssetID() { return mImageAssetID; }
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
void setCanApplyImmediately(BOOL b);
void setActive( BOOL active );
LLTextureCtrl* getOwner() const { return mOwner; }
void setOwner(LLTextureCtrl* owner) { mOwner = owner; }
void stopUsingPipette();
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
void commitCancel();
void onFilterEdit(const std::string& search_string );
void setCanApply(bool can_preview, bool can_apply);
void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;}
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
static void onBtnCancel( void* userdata );
void onBtnPipette( );
//static void onBtnRevert( void* userdata );
static void onBtnBlank( void* userdata );
static void onBtnNone( void* userdata );
static void onBtnClear( void* userdata );
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
void onTextureSelect( const LLTextureEntry& te );
static void onModeSelect(LLUICtrl* ctrl, void *userdata);
static void onBtnAdd(void* userdata);
static void onBtnRemove(void* userdata);
static void onBtnUpload(void* userdata);
static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
protected:
LLPointer<LLViewerTexture> mTexturep;
LLTextureCtrl* mOwner;
LLUUID mImageAssetID; // Currently selected texture
LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
LLUUID mOriginalImageAssetID;
std::string mLabel;
LLTextBox* mTentativeLabel;
LLTextBox* mResolutionLabel;
std::string mPendingName;
BOOL mActive;
LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
BOOL mSelectedItemPinned;
LLRadioGroup* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
private:
bool mCanApply;
bool mCanPreview;
bool mPreviewSettingChanged;
texture_selected_callback mTextureSelectedCallback;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLTextureCtrl* owner,
LLView* owner,
LLUUID image_asset_id,
LLUUID default_image_asset_id,
LLUUID blank_image_asset_id,
BOOL tentative,
BOOL allow_no_texture,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask dnd_filter_perm_mask,
@ -202,9 +96,13 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
LLUIImagePtr fallback_image)
: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
mFallbackImage( fallback_image ),
mOriginalImageAssetID(owner->getImageAssetID()),
mImageAssetID( image_asset_id ),
mOriginalImageAssetID(image_asset_id),
mFallbackImage(fallback_image),
mDefaultImageAssetID(default_image_asset_id),
mBlankImageAssetID(blank_image_asset_id),
mTentative(tentative),
mAllowNoTexture(allow_no_texture),
mLabel(label),
mTentativeLabel(NULL),
mResolutionLabel(NULL),
@ -217,7 +115,11 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mSelectedItemPinned( FALSE ),
mCanApply(true),
mCanPreview(true),
mPreviewSettingChanged(false)
mPreviewSettingChanged(false),
mOnFloaterCommitCallback(NULL),
mOnFloaterCloseCallback(NULL),
mSetImageAssetIDCallback(NULL),
mOnUpdateImageStatsCallback(NULL)
{
buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
@ -294,6 +196,10 @@ void LLFloaterTexturePicker::updateImageStats()
{
std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight());
mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
if (mOnUpdateImageStatsCallback)
{
mOnUpdateImageStatsCallback(mTexturep);
}
}
else
{
@ -400,9 +306,9 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
void LLFloaterTexturePicker::onClose(bool app_quitting)
{
if (mOwner)
if (mOwner && mOnFloaterCloseCallback)
{
mOwner->onFloaterClose();
mOnFloaterCloseCallback();
}
stopUsingPipette();
}
@ -582,9 +488,9 @@ void LLFloaterTexturePicker::draw()
mTentativeLabel->setVisible( FALSE );
}
getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID() || mOwner->getTentative());
getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID() || mOwner->getTentative());
getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && (!mImageAssetID.isNull() || mOwner->getTentative()));
getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
LLFloater::draw();
@ -629,7 +535,7 @@ void LLFloaterTexturePicker::draw()
}
// Draw Tentative Label over the image
if( mOwner->getTentative() && !mViewModel->isDirty() )
if( mTentative && !mViewModel->isDirty() )
{
mTentativeLabel->setVisible( TRUE );
drawChild(mTentativeLabel);
@ -704,17 +610,17 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()
void LLFloaterTexturePicker::commitIfImmediateSet()
{
if (!mNoCopyTextureSelected && mOwner && mCanApply)
if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, LLUUID::null);
}
}
void LLFloaterTexturePicker::commitCancel()
{
if (!mNoCopyTextureSelected && mOwner && mCanApply)
if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
}
}
@ -725,7 +631,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
self->setCanApply(true, true);
if (self->mOwner)
{
self->setImageID( self->mOwner->getDefaultImageAssetID() );
self->setImageID( self->getDefaultImageAssetID() );
}
self->commitIfImmediateSet();
}
@ -735,7 +641,7 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setCanApply(true, true);
self->setImageID( self->mOwner->getBlankImageAssetID() );
self->setImageID( self->getBlankImageAssetID() );
self->commitIfImmediateSet();
}
@ -765,9 +671,9 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setImageID( self->mOriginalImageAssetID );
if (self->mOwner)
if (self->mOnFloaterCommitCallback)
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
}
self->mViewModel->resetDirty();
self->closeFloater();
@ -777,17 +683,18 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
LLUUID local_id = LLUUID::null;
if (self->mOwner)
{
LLUUID local_id = LLUUID::null;
if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
{
LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
local_id = LLLocalBitmapMgr::getWorldID(temp_id);
}
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT, local_id);
}
if (self->mOnFloaterCommitCallback)
{
self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_SELECT, local_id);
}
self->closeFloater();
}
@ -941,11 +848,17 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
{
LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id);
self->mOwner->setImageAssetID(inworld_id);
if (self->mSetImageAssetIDCallback)
{
self->mSetImageAssetIDCallback(inworld_id);
}
if (self->childGetValue("apply_immediate_check").asBoolean())
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, inworld_id);
if (self->mOnFloaterCommitCallback)
{
self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, inworld_id);
}
}
}
}
@ -1028,6 +941,11 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
mInventoryPanel->setFilterSubString(search_string);
}
void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
{
mModeSelector->setIndexEnabled(1,enabled);
}
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
@ -1238,13 +1156,17 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
{
floaterp = new LLFloaterTexturePicker(
this,
getImageAssetID(),
getDefaultImageAssetID(),
getBlankImageAssetID(),
getTentative(),
getAllowNoTexture(),
mLabel,
mImmediateFilterPermMask,
mDnDFilterPermMask,
mNonImmediateFilterPermMask,
mCanApplyImmediately,
mFallbackImage);
mFloaterHandle = floaterp->getHandle();
LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
@ -1252,6 +1174,18 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
{
texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
}
if (texture_floaterp && mOnCloseCallback)
{
texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this));
}
if (texture_floaterp)
{
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2));
}
if (texture_floaterp)
{
texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
}
LLFloater* root_floater = gFloaterView->getParentFloater(this);
if (root_floater)

View File

@ -29,12 +29,20 @@
#define LL_LLTEXTURECTRL_H
#include "llcoord.h"
#include "llfiltereditor.h"
#include "llfloater.h"
#include "llfolderview.h"
#include "lllocalbitmaps.h"
#include "llstring.h"
#include "lluictrl.h"
#include "llpermissionsflags.h"
#include "llradiogroup.h"
#include "lltextbox.h" // for params
#include "llviewerinventory.h"
#include "llviewborder.h" // for params
#include "llviewerobject.h"
#include "llviewertexture.h"
#include "llwindow.h"
class LLButton;
class LLFloaterTexturePicker;
@ -166,7 +174,7 @@ public:
void closeDependentFloater();
void onFloaterClose();
void onFloaterCommit(ETexturePickOp op, LLUUID id = LLUUID::null);
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.
@ -227,4 +235,140 @@ private:
S32 mLabelWidth;
};
//////////////////////////////////////////////////////////////////////////////////////////
// LLFloaterTexturePicker
typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLUUID id)> floater_commit_callback;
typedef boost::function<void()> floater_close_callback;
typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback;
class LLFloaterTexturePicker : public LLFloater
{
public:
LLFloaterTexturePicker(
LLView* owner,
LLUUID image_asset_id,
LLUUID default_image_asset_id,
LLUUID blank_image_asset_id,
BOOL tentative,
BOOL allow_no_texture,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image_name
);
virtual ~LLFloaterTexturePicker();
// LLView overrides
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
std::string& tooltip_msg);
/*virtual*/ void draw();
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
// LLFloater overrides
/*virtual*/ BOOL postBuild();
/*virtual*/ void onClose(bool app_settings);
// New functions
void setImageID(const LLUUID& image_asset_id, bool set_selection = true);
void updateImageStats();
const LLUUID& getAssetID() { return mImageAssetID; }
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
void setCanApplyImmediately(BOOL b);
void setActive(BOOL active);
LLView* getOwner() const { return mOwner; }
void setOwner(LLView* owner) { mOwner = owner; }
void stopUsingPipette();
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
void commitCancel();
void onFilterEdit(const std::string& search_string);
void setCanApply(bool can_preview, bool can_apply);
void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }
void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; }
const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
static void onBtnSetToDefault(void* userdata);
static void onBtnSelect(void* userdata);
static void onBtnCancel(void* userdata);
void onBtnPipette();
//static void onBtnRevert( void* userdata );
static void onBtnBlank(void* userdata);
static void onBtnNone(void* userdata);
static void onBtnClear(void* userdata);
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
void onTextureSelect(const LLTextureEntry& te);
static void onModeSelect(LLUICtrl* ctrl, void *userdata);
static void onBtnAdd(void* userdata);
static void onBtnRemove(void* userdata);
static void onBtnUpload(void* userdata);
static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
void setLocalTextureEnabled(BOOL enabled);
protected:
LLPointer<LLViewerTexture> mTexturep;
LLView* mOwner;
LLUUID mImageAssetID; // Currently selected texture
LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
LLUUID mDefaultImageAssetID;
LLUUID mBlankImageAssetID;
BOOL mTentative;
BOOL mAllowNoTexture;
LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
LLUUID mOriginalImageAssetID;
std::string mLabel;
LLTextBox* mTentativeLabel;
LLTextBox* mResolutionLabel;
std::string mPendingName;
BOOL mActive;
LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
BOOL mSelectedItemPinned;
LLRadioGroup* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
private:
bool mCanApply;
bool mCanPreview;
bool mPreviewSettingChanged;
texture_selected_callback mTextureSelectedCallback;
floater_close_callback mOnFloaterCloseCallback;
floater_commit_callback mOnFloaterCommitCallback;
set_image_asset_id_callback mSetImageAssetIDCallback;
set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
};
#endif // LL_LLTEXTURECTRL_H

View File

@ -779,12 +779,17 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
if (uploadInfo->showUploadDialog())
LLUploadDialog::modalUploadFinished();
// Let the Snapshot floater know we have finished uploading a snapshot to inventory.
// Let the Snapshot floater know we have finished uploading a snapshot to inventory
LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
{
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
}
//=========================================================================
@ -839,10 +844,14 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
// Let the Snapshot floater know we have failed uploading.
LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
{
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
}

View File

@ -93,6 +93,7 @@
#include "llfloaternotificationstabbed.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindinglinksets.h"
@ -333,7 +334,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);

View File

@ -37,6 +37,7 @@
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagepng.h"
@ -507,9 +508,11 @@ class LLFileEnableCloseAllWindows : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
bool is_floater_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain();
bool open_children = gFloaterView->allChildrenClosed() && !is_floater_snapshot_opened;
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
return !open_children;
}
};
@ -520,7 +523,12 @@ class LLFileCloseAllWindows : public view_listener_t
{
bool app_quitting = false;
gFloaterView->closeAllChildren(app_quitting);
LLFloaterSnapshot::getInstance()->closeFloater(app_quitting);
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
if (floater_snapshot)
floater_snapshot->closeFloater(app_quitting);
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
if (floater_outfit_snapshot)
floater_outfit_snapshot->closeFloater(app_quitting);
if (gMenuHolder) gMenuHolder->hideMenus();
return true;
}
@ -551,18 +559,18 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
{
gViewerWindow->playSnapshotAnimAndSound();
LLPointer<LLImageFormatted> formatted;
LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
switch (fmt)
{
case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
break;
default:
LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
formatted = new LLImagePNG;
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
formatted = new LLImageBMP;
break;
}

View File

@ -4364,7 +4364,7 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
}
}
BOOL LLViewerWindow::saveSnapshot( const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
{
LL_INFOS() << "Saving snapshot to: " << filepath << LL_ENDL;
@ -4403,7 +4403,7 @@ void LLViewerWindow::playSnapshotAnimAndSound()
send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
}
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
{
return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
}
@ -4412,7 +4412,7 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
// the results over to the final raw image.
BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)
BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
{
if (!raw)
{
@ -4620,7 +4620,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
}
if (type == SNAPSHOT_TYPE_COLOR)
if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
{
glReadPixels(
subimage_x_offset, out_y + subimage_y_offset,
@ -4629,7 +4629,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
raw->getData() + output_buffer_offset
);
}
else // SNAPSHOT_TYPE_DEPTH
else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
{
LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
glReadPixels(

View File

@ -46,6 +46,7 @@
#include "llhandle.h"
#include "llinitparam.h"
#include "lltrace.h"
#include "llsnapshotmodel.h"
#include <boost/function.hpp>
#include <boost/signals2.hpp>
@ -342,15 +343,11 @@ public:
// snapshot functionality.
// perhaps some of this should move to llfloatershapshot? -MG
typedef enum
{
SNAPSHOT_TYPE_COLOR,
SNAPSHOT_TYPE_DEPTH
} ESnapshotType;
BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);
BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR);
BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE );
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
void resetSnapshotLoc() const { sSnapshotDir.clear(); }
BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false);

View File

@ -65,9 +65,9 @@ LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow):
void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
{
typedef std::map<LLSD::String, LLViewerWindow::ESnapshotType> TypeMap;
typedef std::map<LLSD::String, LLSnapshotModel::ESnapshotLayerType> TypeMap;
TypeMap types;
#define tp(name) types[#name] = LLViewerWindow::SNAPSHOT_TYPE_##name
#define tp(name) types[#name] = LLSnapshotModel::SNAPSHOT_TYPE_##name
tp(COLOR);
tp(DEPTH);
#undef tp
@ -84,7 +84,7 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
if (event.has("showui"))
showui = event["showui"].asBoolean();
bool rebuild(event["rebuild"]); // defaults to false
LLViewerWindow::ESnapshotType type(LLViewerWindow::SNAPSHOT_TYPE_COLOR);
LLSnapshotModel::ESnapshotLayerType type(LLSnapshotModel::SNAPSHOT_TYPE_COLOR);
if (event.has("type"))
{
TypeMap::const_iterator found = types.find(event["type"]);

View File

@ -948,4 +948,13 @@
<color
name="SyntaxLslStringLiteral"
value="1 0.14 0 1" />
<color
name="OutfitGalleryItemSelected"
value="0.22 0.45 0.35 1" />
<color
name="OutfitGalleryItemWorn"
value="0.33 0.58 0.47 1" />
<color
name="OutfitGalleryItemUnselected"
value="0.4 0.4 0.4 1" />
</colors>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -806,6 +806,7 @@ with the same filename but different name
<texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
<texture name="NavBar Separator" file_name="navbar/separator.png"/>
<texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/>
<texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
<texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
<texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 332 KiB

View File

@ -0,0 +1,351 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
positioning="cascading"
legacy_header_height="18"
can_minimize="true"
can_resize="false"
can_close="true"
height="455"
layout="topleft"
name="outfit_snapshot"
single_instance="true"
help_topic="snapshot"
save_rect="true"
save_visibility="false"
title="OUTFIT SNAPSHOT"
width="624"
min_height="455">
<floater.string
name="unknown">
unknown
</floater.string>
<string
name="inventory_progress_str">
Saving to Inventory
</string>
<string
name="inventory_succeeded_str">
Saved to Inventory!
</string>
<string
name="inventory_failed_str">
Failed to save to inventory.
</string>
<button
follows="left|top"
height="25"
image_overlay="Refresh_Off"
image_hover_unselected="Toolbar_Middle_Over"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
image_overlay_alignment="left"
imgoverlay_label_space="5"
pad_bottom="0"
halign="left"
layout="topleft"
left="10"
label="REFRESH"
name="new_snapshot_btn"
top_pad="26"
width="167" />
<button
follows="left|top"
control_name="AdvanceOutfitSnapshot"
invisibility_control="AdvanceOutfitSnapshot"
height="25"
is_toggle="true"
layout="topleft"
image_hover_unselected="Toolbar_Middle_Over"
image_selected="Toolbar_Middle_Off"
image_unselected="Toolbar_Middle_Off"
image_overlay="Conv_toolbar_expand"
name="retract_btn"
left_pad="1"
top_delta="0"
width="31" />
<button
follows="left|top"
control_name="AdvanceOutfitSnapshot"
visibility_control="AdvanceOutfitSnapshot"
height="25"
is_toggle="true"
layout="topleft"
image_overlay="Conv_toolbar_collapse"
image_hover_unselected="Toolbar_Middle_Over"
image_selected="Toolbar_Middle_Off"
image_unselected="Toolbar_Middle_Off"
name="extend_btn"
left_delta="0"
top_delta="0"
width="31" />
<panel
height="154"
layout="topleft"
follows="top|left"
left="0"
name="advanced_options_panel"
top_pad="-6"
width="210">
<view_border
bevel_style="in"
follows="left|top|right"
height="1"
left="10"
layout="topleft"
name="advanced_options_hr"
right="-1"
top_pad="5"
/>
<text
type="string"
length="1"
follows="left|top"
height="13"
layout="topleft"
left="10"
name="layer_type_label"
top_pad="10"
width="100">
Capture:
</text>
<check_box
label="Interface"
layout="topleft"
left="30"
height="16"
top_pad="8"
width="180"
name="ui_check" />
<check_box
label="HUDs"
layout="topleft"
height="16"
left="30"
top_pad="1"
width="180"
name="hud_check" />
<check_box
label="Freeze frame (fullscreen)"
layout="topleft"
height="16"
left="10"
top_pad="1"
width="180"
name="freeze_frame_check" />
<check_box
label="Auto-refresh"
layout="topleft"
height="16"
left="10"
top_pad="1"
width="180"
name="auto_snapshot_check" />
<text
type="string"
length="1"
follows="left|top"
height="13"
layout="topleft"
left="10"
name="filter_list_label"
top_pad="10"
width="50">
Filter:
</text>
<combo_box
control_name="PhotoFilters"
follows="left|right|top"
name="filters_combobox"
tool_tip="Image filters"
top_delta="-3"
left="50"
right="-1"
height="21"
width="135">
<combo_box.item
label="No Filter"
name="NoFilter"
value="NoFilter" />
</combo_box>
<view_border
bevel_style="in"
follows="left|top|right"
height="1"
left="10"
layout="topleft"
name="advanced_options_hr"
right="-1"
top_pad="7"
/>
</panel>
<panel
class="llpaneloutfitsnapshotinventory"
follows="left|top"
height="230"
layout="topleft"
left="0"
name="panel_outfit_snapshot_inventory"
filename="panel_outfit_snapshot_inventory.xml"
top_pad="10"
width="215"
/>
<view_border
bevel_style="in"
follows="left|top"
height="1"
left="10"
layout="topleft"
name="status_hr"
width="199"
top_pad="-16"/>
<panel
background_visible="false"
follows="left|top"
font="SansSerifLarge"
halign="center"
height="20"
layout="topleft"
left="10"
length="1"
name="succeeded_panel"
width="198"
top_pad="1"
type="string"
visible="false">
<text
follows="all"
font="SansSerif"
halign="center"
height="18"
layout="topleft"
left="1"
length="1"
name="succeeded_lbl"
right="-1"
text_color="0.2 0.85 0.2 1"
top="4"
translate="false"
type="string">
Succeeded
</text>
</panel>
<panel
background_visible="false"
follows="left|top"
font="SansSerifLarge"
halign="center"
height="20"
layout="topleft"
left="10"
length="1"
name="failed_panel"
width="198"
top_delta="0"
type="string"
visible="false">
<text
follows="all"
font="SansSerif"
halign="center"
height="18"
layout="topleft"
left="1"
length="1"
name="failed_lbl"
right="-1"
text_color="0.95 0.4 0.4 1"
top="4"
translate="false"
type="string">
Failed
</text>
</panel>
<loading_indicator
follows="left|top"
height="24"
layout="topleft"
name="working_indicator"
left="10"
top_delta="0"
visible="false"
width="24" />
<text
follows="left|top"
font="SansSerifBold"
height="14"
layout="topleft"
left_pad="3"
length="1"
halign="left"
name="working_lbl"
top_delta="5"
translate="false"
type="string"
visible="false"
width="162">
Working
</text>
<text
follows="left|top"
font="SansSerifBold"
halign="left"
height="18"
layout="topleft"
left="10"
length="1"
name="refresh_lbl"
text_color="0.95 0.4 0.4 1"
top_delta="0"
translate="false"
type="string"
visible="false"
width="130">
Refresh to save.
</text>
<ui_ctrl
layout="topleft"
name="thumbnail_placeholder"
top="23"
left="215"
width="400"
height="400"
follows="top|left"/>
<view_border
bevel_style="in"
height="21"
layout="topleft"
name="img_info_border"
top_pad="0"
right="-10"
follows="left|top|right"
left_delta="0"/>
<text
type="string"
font="SansSerifSmall"
length="1"
follows="left|top|right"
height="14"
layout="topleft"
left="220"
right="-20"
halign="left"
name="image_res_text"
top_delta="5"
width="200">
[WIDTH]px (width) x [HEIGHT]px (height)
</text>
<text
follows="right|top"
font="SansSerifSmall"
height="14"
layout="topleft"
left="-65"
length="1"
halign="right"
name="file_size_label"
top_delta="0"
type="string"
width="50">
[SIZE] KB
</text>
</floater>

View File

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="Outfit">
<menu_item_call
label="Wear - Replace Current Outfit"
layout="topleft"
name="wear_replace">
<on_click
function="Outfit.WearReplace" />
<on_enable
function="Outfit.OnEnable"
parameter="wear_replace" />
<on_visible
function="Outfit.OnVisible"
parameter="wear_replace" />
</menu_item_call>
<menu_item_call
label="Wear - Add to Current Outfit"
layout="topleft"
name="wear_add">
<on_click
function="Outfit.WearAdd" />
<on_enable
function="Outfit.OnEnable"
parameter="wear_add" />
<on_visible
function="Outfit.OnVisible"
parameter="wear_add" />
</menu_item_call>
<menu_item_call
label="Take Off - Remove from Current Outfit"
layout="topleft"
name="take_off">
<on_click
function="Outfit.TakeOff" />
<on_enable
function="Outfit.OnEnable"
parameter="take_off" />
<on_visible
function="Outfit.OnVisible"
parameter="take_off" />
</menu_item_call>
<menu_item_call
label="Upload Photo (L$10)"
layout="topleft"
name="upload_photo">
<on_click
function="Outfit.UploadPhoto" />
</menu_item_call>
<menu_item_call
label="Select Photo"
layout="topleft"
name="select_photo">
<on_click
function="Outfit.SelectPhoto" />
</menu_item_call>
<menu_item_call
label="Take a Snapshot"
layout="topleft"
name="take_snapshot">
<on_click
function="Outfit.TakeSnapshot" />
</menu_item_call>
<menu_item_call
label="Remove Photo"
layout="topleft"
name="remove_photo">
<on_click
function="Outfit.RemovePhoto" />
<on_visible
function="Outfit.OnVisible"
parameter="remove_photo" />
</menu_item_call>
<menu_item_separator name="sepatator1" />
<menu
height="175"
label="New Clothes"
layout="topleft"
left_delta="0"
mouse_opaque="false"
name="New Clothes"
top_pad="514"
width="125">
<menu_item_call
label="New Shirt"
layout="topleft"
name="New Shirt">
<menu_item_call.on_click
function="Outfit.Create"
parameter="shirt" />
</menu_item_call>
<menu_item_call
label="New Pants"
layout="topleft"
name="New Pants">
<menu_item_call.on_click
function="Outfit.Create"
parameter="pants" />
</menu_item_call>
<menu_item_call
label="New Shoes"
layout="topleft"
name="New Shoes">
<menu_item_call.on_click
function="Outfit.Create"
parameter="shoes" />
</menu_item_call>
<menu_item_call
label="New Socks"
layout="topleft"
name="New Socks">
<menu_item_call.on_click
function="Outfit.Create"
parameter="socks" />
</menu_item_call>
<menu_item_call
label="New Jacket"
layout="topleft"
name="New Jacket">
<menu_item_call.on_click
function="Outfit.Create"
parameter="jacket" />
</menu_item_call>
<menu_item_call
label="New Skirt"
layout="topleft"
name="New Skirt">
<menu_item_call.on_click
function="Outfit.Create"
parameter="skirt" />
</menu_item_call>
<menu_item_call
label="New Gloves"
layout="topleft"
name="New Gloves">
<menu_item_call.on_click
function="Outfit.Create"
parameter="gloves" />
</menu_item_call>
<menu_item_call
label="New Undershirt"
layout="topleft"
name="New Undershirt">
<menu_item_call.on_click
function="Outfit.Create"
parameter="undershirt" />
</menu_item_call>
<menu_item_call
label="New Underpants"
layout="topleft"
name="New Underpants">
<menu_item_call.on_click
function="Outfit.Create"
parameter="underpants" />
</menu_item_call>
<menu_item_call
label="New Alpha"
layout="topleft"
name="New Alpha">
<menu_item_call.on_click
function="Outfit.Create"
parameter="alpha" />
</menu_item_call>
<menu_item_call
label="New Physics"
layout="topleft"
name="New Physics">
<menu_item_call.on_click
function="Outfit.Create"
parameter="physics" />
</menu_item_call>
<menu_item_call
label="New Tattoo"
layout="topleft"
name="New Tattoo">
<menu_item_call.on_click
function="Outfit.Create"
parameter="tattoo" />
</menu_item_call>
</menu>
<menu
height="85"
label="New Body Parts"
layout="topleft"
left_delta="0"
mouse_opaque="false"
name="New Body Parts"
top_pad="514"
width="118">
<menu_item_call
label="New Shape"
layout="topleft"
name="New Shape">
<menu_item_call.on_click
function="Outfit.Create"
parameter="shape" />
</menu_item_call>
<menu_item_call
label="New Skin"
layout="topleft"
name="New Skin">
<menu_item_call.on_click
function="Outfit.Create"
parameter="skin" />
</menu_item_call>
<menu_item_call
label="New Hair"
layout="topleft"
name="New Hair">
<menu_item_call.on_click
function="Outfit.Create"
parameter="hair" />
</menu_item_call>
<menu_item_call
label="New Eyes"
layout="topleft"
name="New Eyes">
<menu_item_call.on_click
function="Outfit.Create"
parameter="eyes" />
</menu_item_call>
</menu>
<menu_item_separator name="sepatator2" />
<menu_item_call
label="Edit Outfit"
layout="topleft"
name="edit">
<on_click
function="Outfit.Edit" />
<on_visible
function="Outfit.OnVisible"
parameter="edit" />
</menu_item_call>
<menu_item_call
label="Rename Outfit"
layout="topleft"
name="rename">
<on_click
function="Outfit.Rename" />
<on_enable
function="Outfit.OnEnable"
parameter="rename" />
</menu_item_call>
<menu_item_call
label="Delete Outfit"
layout="topleft"
name="delete">
<on_click
function="Outfit.Delete" />
<on_visible
function="Outfit.OnVisible"
parameter="delete" />
</menu_item_call>
</context_menu>

View File

@ -39,8 +39,35 @@
function="Gear.OnVisible"
parameter="take_off" />
</menu_item_call>
<menu_item_separator name="sepatator1" />
<menu_item_call
label="Upload Photo (L$10)"
layout="topleft"
name="upload_photo">
<on_click
function="Gear.UploadPhoto" />
</menu_item_call>
<menu_item_call
label="Select Photo"
layout="topleft"
name="select_photo">
<on_click
function="Gear.SelectPhoto" />
</menu_item_call>
<menu_item_call
label="Take a Snapshot"
layout="topleft"
name="take_snapshot">
<on_click
function="Gear.TakeSnapshot" />
</menu_item_call>
<menu_item_call
label="Remove Photo"
layout="topleft"
name="remove_photo">
<on_click
function="Gear.RemovePhoto" />
</menu_item_call>
<menu_item_separator name="sepatator1" />
<!-- copied (with minor modifications) from menu_inventory_add.xml -->
<!-- *TODO: generate dynamically? -->
<menu
@ -234,4 +261,15 @@
function="Gear.OnVisible"
parameter="delete" />
</menu_item_call>
<menu_item_separator name="sepatator3" />
<menu_item_check
label="Sort Folders Always by Name"
layout="topleft"
name="sort_folders_by_name">
<on_click
function="Gear.SortByName" />
<on_check
function="CheckControl"
parameter="OutfitGallerySortByName" />
</menu_item_check>
</toggleable_menu>

View File

@ -11068,4 +11068,16 @@ Cannot create large prims that intersect other players. Please re-try when othe
yestext="OK"/>
</notification>
<notification
icon="alert.tga"
name="OutfitPhotoLoadError"
type="alertmodal">
[REASON]
<tag>fail</tag>
<usetemplate
name="okbutton"
yestext="OK"/>
</notification>
</notifications>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
background_visible="true"
bg_alpha_color="DkGray"
border="false"
follows="all"
height="430"
name="Outfit Gallery"
layout="topleft"
left="0"
top="0"
width="318">
<string name="outfit_photo_string">
Photo of "[OUTFIT_NAME]" outfit
</string>
<string name="no_outfits_msg">
You don't have any outfits yet. Try [secondlife:///app/search/all/ Search]
</string>
<string name="no_matched_outfits_msg">
Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].
</string>
<text
type="string"
clip_partial="false"
follows="left|top"
layout="topleft"
left="13"
name="no_outfits_txt"
top="0"
height="32"
valign="center"
parse_urls="true"
wrap="true">
Searching...
</text>
<scroll_container
border="true"
bevel_style="none"
follows="all"
height="400"
width="312"
min_width="312"
layout="topleft"
left="4"
top="0"
name="gallery_scroll_panel"
opaque="false"
top_pad="0">
<!--outfit_gallery_item
layout="topleft"
left="10"
name="preview_outfit1"
height="175"
width="150"
follows="left|top"/-->
<!--layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="0" name="top_gallery_stack" orientation="horizontal">
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
</layout_stack>
<layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="190" name="top_gallery_stack" orientation="horizontal">
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
</layout_stack>
<layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="380" name="top_gallery_stack" orientation="horizontal">
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
<layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
<outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
</layout_panel>
</layout_stack-->
<!--</panel>-->
</scroll_container>
<panel
background_visible="true"
follows="bottom|left|right"
height="28"
layout="topleft"
left="4"
top_pad="0"
visible="true"
name="bottom_panel"
width="312">
<menu_button
follows="bottom|left"
tool_tip="Show additional options"
height="25"
image_hover_unselected="Toolbar_Left_Over"
image_overlay="OptionsMenu_Off"
image_selected="Toolbar_Left_Selected"
image_unselected="Toolbar_Left_Off"
layout="topleft"
left="0"
name="options_gear_btn"
top="1"
width="31" />
<icon
follows="bottom|left|right"
height="25"
image_name="Toolbar_Middle_Off"
layout="topleft"
left_pad="1"
name="dummy_icon"
width="243"/>
<button
follows="bottom|right"
height="25"
image_hover_unselected="Toolbar_Right_Over"
image_overlay="TrashItem_Off"
image_selected="Toolbar_Right_Selected"
image_unselected="Toolbar_Right_Off"
layout="topleft"
left_pad="1"
name="trash_btn"
tool_tip="Delete selected outfit"
width="31"/>
</panel>
</panel>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
background_visible="false"
background_opaque="false"
bg_alpha_color="FrogGreen"
bg_opaque_color="FrogGreen"
border="false"
bevel_style="none"
follows="left|top"
height="169"
width="150"
name="gallery_item_panel"
layout="topleft"
left="0"
top="0"
>
<string name="worn_string">
(worn)
</string>
<icon
left="1"
top="0"
layout="topleft"
name="preview_outfit"
height="149"
width="147"
follows="left|top"
visible="true"
image_name="Default_Outfit_Photo"
/>
<panel
background_visible="false"
background_opaque="true"
bg_opaque_color="OutfitGalleryItemSelected"
border="false"
bevel_style="none"
follows="left|top"
left="0"
top="149"
height="25"
width="148"
name="text_bg_panel"
>
<text
read_only="true"
length="1"
follows="left|top"
left="1"
height="10"
layout="topleft"
name="outfit_name"
top="2"
width="150"
use_ellipses="true">
Summer hipster, Pierce Pierce Pierce Pierce
</text>
<text
read_only="true"
length="1"
follows="left|top"
left="1"
height="10"
layout="topleft"
name="outfit_worn_text"
top="12"
width="150">
(worn)
</text>
</panel>
</panel>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
height="380"
layout="topleft"
name="panel_outfit_snapshot_inventory"
width="490">
<icon
follows="top|left"
height="18"
image_name="Snapshot_Inventory"
layout="topleft"
left="12"
mouse_opaque="true"
name="title_icon"
top="6"
width="18" />
<text
follows="top|left|right"
font="SansSerifBold"
height="14"
layout="topleft"
left_pad="12"
length="1"
name="title"
right="-10"
text_color="white"
type="string"
top_delta="3">
Inventory
</text>
<view_border
bevel_style="in"
follows="left|top|right"
height="1"
left="9"
layout="topleft"
name="hr"
right="-5"
top_pad="5"
/>
<text
follows="top|left"
font="SansSerif"
height="56"
layout="topleft"
left="10"
length="1"
name="hint_lbl"
top_pad="6"
width="200"
type="string"
word_wrap="true">
Uploading an image to your inventory costs L$[UPLOAD_COST].
</text>
<button
follows="right|bottom"
height="23"
label="Cancel"
layout="topleft"
name="cancel_btn"
right="-5"
top="337"
width="97">
<button.commit_callback
function="Inventory.SaveOutfitCancel" />
</button>
<button
follows="left|bottom"
height="23"
label="UPLOAD L$10"
layout="topleft"
left="10"
name="save_btn"
top_delta="0"
width="97">
<button.commit_callback
function="Inventory.SaveOutfitPhoto" />
</button>
</panel>

View File

@ -32,6 +32,17 @@
halign="center"
top="8"
width="315">
<panel
class="outfit_gallery"
filename="panel_outfit_gallery.xml"
height="520"
name="outfit_gallery_tab"
background_visible="true"
help_topic="outfit_gallery_tab"
follows="all"
label="OUTFIT GALLERY"
layout="topleft"
width="315" />
<panel
class="outfits_list"
filename="panel_outfits_list.xml"

View File

@ -3807,6 +3807,9 @@ Abuse Report</string>
<string name="DefaultMimeType">none/none</string>
<string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string>
<string name="outfit_photo_load_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image</string>
<string name="outfit_photo_select_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please select another texture</string>
<string name="outfit_photo_verify_dimensions_error">Cannot verify photo dimensions. Please wait until photo size is displayed in picker</string>
<!-- language specific white-space characters, delimiters, spacers, item separation symbols -->
<string name="sentences_separator" value=" "></string>