Merge branch 'DRTVWR-567' of https://github.com/secondlife/viewer
# Conflicts: # indra/llui/llfolderviewitem.cpp # indra/llui/llfolderviewitem.h # indra/newview/llappviewer.cpp # indra/newview/llinventorybridge.cpp # indra/newview/llinventorypanel.cpp # indra/newview/lloutfitgallery.cpp # indra/newview/llpanelmaininventory.cpp # indra/newview/llpanelmaininventory.h # indra/newview/llpanelprofile.cpp # indra/newview/llsidepanelinventory.cpp # indra/newview/llsidepanelinventory.h # indra/newview/llviewerfloaterreg.cpp # indra/newview/skins/default/textures/textures.xml # indra/newview/skins/default/xui/en/floater_my_inventory.xml # indra/newview/skins/default/xui/en/floater_simple_snapshot.xml # indra/newview/skins/default/xui/en/menu_inventory.xml # indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml # indra/newview/skins/default/xui/en/menu_viewer.xml # indra/newview/skins/default/xui/en/panel_main_inventory.xml # indra/newview/skins/default/xui/en/sidepanel_inventory.xmlmaster
|
|
@ -251,6 +251,8 @@ public:
|
|||
void dumpSelectionInformation();
|
||||
|
||||
virtual S32 notify(const LLSD& info) ;
|
||||
|
||||
void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; }
|
||||
|
||||
bool useLabelSuffix() { return mUseLabelSuffix; }
|
||||
virtual void updateMenu();
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ LLFolderViewItem::Params::Params()
|
|||
icon_width("icon_width", 0),
|
||||
text_pad("text_pad", 0),
|
||||
text_pad_right("text_pad_right", 0),
|
||||
single_folder_mode("single_folder_mode", false),
|
||||
arrow_size("arrow_size", 0),
|
||||
max_folder_item_overlap("max_folder_item_overlap", 0),
|
||||
// <FS:Ansariel> Inventory specials
|
||||
|
|
@ -158,6 +159,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
mTextPad(p.text_pad),
|
||||
mTextPadRight(p.text_pad_right),
|
||||
mArrowSize(p.arrow_size),
|
||||
mSingleFolderMode(p.single_folder_mode),
|
||||
mMaxFolderItemOverlap(p.max_folder_item_overlap),
|
||||
// <FS:Ansariel> Inventory specials
|
||||
mForInventory(p.for_inventory),
|
||||
|
|
@ -970,7 +972,10 @@ void LLFolderViewItem::draw()
|
|||
|
||||
getViewModelItem()->update();
|
||||
|
||||
drawOpenFolderArrow(default_params, sFgColor);
|
||||
if(!mSingleFolderMode)
|
||||
{
|
||||
drawOpenFolderArrow(default_params, sFgColor);
|
||||
}
|
||||
|
||||
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
|
||||
|
||||
|
|
@ -1945,7 +1950,14 @@ void LLFolderViewFolder::toggleOpen()
|
|||
// Force a folder open or closed
|
||||
void LLFolderViewFolder::setOpen(BOOL openitem)
|
||||
{
|
||||
setOpenArrangeRecursively(openitem);
|
||||
if(mSingleFolderMode)
|
||||
{
|
||||
getViewModelItem()->navigateToFolder();
|
||||
}
|
||||
else
|
||||
{
|
||||
setOpenArrangeRecursively(openitem);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
|
||||
|
|
@ -2148,7 +2160,8 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
|
|||
}
|
||||
if( !handled )
|
||||
{
|
||||
if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
|
||||
if((mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
|
||||
&& !mSingleFolderMode)
|
||||
{
|
||||
toggleOpen();
|
||||
handled = TRUE;
|
||||
|
|
@ -2166,6 +2179,11 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
|
|||
BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
if(mSingleFolderMode)
|
||||
{
|
||||
getViewModelItem()->navigateToFolder();
|
||||
return TRUE;
|
||||
}
|
||||
if( isOpen() )
|
||||
{
|
||||
handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ public:
|
|||
text_pad_right,
|
||||
arrow_size,
|
||||
max_folder_item_overlap;
|
||||
Optional<bool> single_folder_mode;
|
||||
|
||||
// <FS:Ansariel> Inventory specials
|
||||
Optional<bool> for_inventory;
|
||||
|
|
@ -125,6 +126,7 @@ protected:
|
|||
mIsMouseOverTitle,
|
||||
mAllowWear,
|
||||
mAllowDrop,
|
||||
mSingleFolderMode,
|
||||
mSelectPending,
|
||||
mIsItemCut;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ public:
|
|||
virtual void openItem( void ) = 0;
|
||||
virtual void closeItem( void ) = 0;
|
||||
virtual void selectItem(void) = 0;
|
||||
|
||||
virtual void navigateToFolder() = 0;
|
||||
|
||||
virtual BOOL isItemWearable() const { return FALSE; }
|
||||
|
||||
|
|
|
|||
|
|
@ -597,13 +597,13 @@ void LLMenuItemGL::onVisibilityChange(BOOL new_visibility)
|
|||
//
|
||||
// This class represents a separator.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LLMenuItemSeparatorGL::Params::Params()
|
||||
{
|
||||
}
|
||||
|
||||
LLMenuItemSeparatorGL::LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p) :
|
||||
LLMenuItemGL( p )
|
||||
{
|
||||
if (p.on_visible.isProvided())
|
||||
{
|
||||
mVisibleSignal.connect(initEnableCallback(p.on_visible));
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -620,6 +620,15 @@ void LLMenuItemSeparatorGL::draw( void )
|
|||
gl_line_2d( PAD, y, getRect().getWidth() - PAD, y );
|
||||
}
|
||||
|
||||
void LLMenuItemSeparatorGL::buildDrawLabel( void )
|
||||
{
|
||||
if (mVisibleSignal.num_slots() > 0)
|
||||
{
|
||||
bool visible = mVisibleSignal(this, LLSD());
|
||||
setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLMenuGL* parent_menu = getMenu();
|
||||
|
|
|
|||
|
|
@ -235,7 +235,9 @@ class LLMenuItemSeparatorGL : public LLMenuItemGL
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
|
||||
{
|
||||
Params();
|
||||
Optional<EnableCallbackParam > on_visible;
|
||||
Params() : on_visible("on_visible")
|
||||
{}
|
||||
};
|
||||
LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p = LLMenuItemSeparatorGL::Params());
|
||||
|
||||
|
|
@ -244,7 +246,12 @@ public:
|
|||
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual void buildDrawLabel();
|
||||
|
||||
/*virtual*/ U32 getNominalHeight( void ) const;
|
||||
|
||||
private:
|
||||
enable_signal_t mVisibleSignal;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterbuyland.cpp
|
||||
llfloatercamera.cpp
|
||||
llfloatercamerapresets.cpp
|
||||
llfloaterchangeitemthumbnail.cpp
|
||||
llfloaterchatvoicevolume.cpp
|
||||
llfloaterclassified.cpp
|
||||
llfloatercolorpicker.cpp
|
||||
|
|
@ -404,7 +405,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloateroutfitphotopreview.cpp
|
||||
llfloaterobjectweights.cpp
|
||||
llfloateropenobject.cpp
|
||||
llfloatersimpleoutfitsnapshot.cpp
|
||||
llfloatersimplesnapshot.cpp
|
||||
llfloaterpathfindingcharacters.cpp
|
||||
llfloaterpathfindingconsole.cpp
|
||||
llfloaterpathfindinglinksets.cpp
|
||||
|
|
@ -1130,6 +1131,7 @@ set(viewer_HEADER_FILES
|
|||
llfloaterbuycurrencyhtml.h
|
||||
llfloaterbuyland.h
|
||||
llfloatercamerapresets.h
|
||||
llfloaterchangeitemthumbnail.h
|
||||
llfloatercamera.h
|
||||
llfloaterchatvoicevolume.h
|
||||
llfloaterclassified.h
|
||||
|
|
@ -1190,7 +1192,7 @@ set(viewer_HEADER_FILES
|
|||
llfloateroutfitphotopreview.h
|
||||
llfloaterobjectweights.h
|
||||
llfloateropenobject.h
|
||||
llfloatersimpleoutfitsnapshot.h
|
||||
llfloatersimplesnapshot.h
|
||||
llfloaterpathfindingcharacters.h
|
||||
llfloaterpathfindingconsole.h
|
||||
llfloaterpathfindinglinksets.h
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@
|
|||
#include "llcommandlineparser.h"
|
||||
#include "llfloatermemleak.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersimpleoutfitsnapshot.h"
|
||||
#include "llfloatersimplesnapshot.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llsidepanelinventory.h"
|
||||
#include "llatmosphere.h"
|
||||
|
|
@ -1798,7 +1798,7 @@ bool LLAppViewer::doFrame()
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot")
|
||||
pingMainloopTimeout("Main:Snapshot");
|
||||
LLFloaterSnapshot::update(); // take snapshots
|
||||
LLFloaterSimpleOutfitSnapshot::update();
|
||||
LLFloaterSimpleSnapshot::update();
|
||||
gGLActive = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ public:
|
|||
virtual void previewItem( void );
|
||||
virtual void selectItem(void) { }
|
||||
virtual void showProperties(void);
|
||||
virtual void navigateToFolder() {}
|
||||
|
||||
// Methods used in sorting (see LLConversationSort::operator())
|
||||
EConversationType const getType() const { return mConvType; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,558 @@
|
|||
/**
|
||||
* @file llfloaterchangeitemthumbnail.cpp
|
||||
* @brief LLFloaterChangeItemThumbnail class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, 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 "llfloaterchangeitemthumbnail.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llclipboard.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryicon.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersimplesnapshot.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "llthumbnailctrl.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llviewermenufile.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llwindow.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
|
||||
class LLThumbnailImagePicker : public LLFilePickerThread
|
||||
{
|
||||
public:
|
||||
LLThumbnailImagePicker(const LLUUID &item_id);
|
||||
LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id);
|
||||
~LLThumbnailImagePicker();
|
||||
void notify(const std::vector<std::string>& filenames) override;
|
||||
|
||||
private:
|
||||
LLUUID mInventoryId;
|
||||
LLUUID mTaskId;
|
||||
};
|
||||
|
||||
LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id)
|
||||
: LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE)
|
||||
, mInventoryId(item_id)
|
||||
{
|
||||
}
|
||||
|
||||
LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id)
|
||||
: LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE)
|
||||
, mInventoryId(item_id)
|
||||
, mTaskId(task_id)
|
||||
{
|
||||
}
|
||||
|
||||
LLThumbnailImagePicker::~LLThumbnailImagePicker()
|
||||
{
|
||||
}
|
||||
|
||||
void LLThumbnailImagePicker::notify(const std::vector<std::string>& filenames)
|
||||
{
|
||||
if (filenames.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string file_path = filenames[0];
|
||||
if (file_path.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloaterSimpleSnapshot::uploadThumbnail(file_path, mInventoryId, mTaskId);
|
||||
}
|
||||
|
||||
LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
, mObserverInitialized(false)
|
||||
, mTooltipState(TOOLTIP_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterChangeItemThumbnail::~LLFloaterChangeItemThumbnail()
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
removeVOInventoryListener();
|
||||
}
|
||||
|
||||
BOOL LLFloaterChangeItemThumbnail::postBuild()
|
||||
{
|
||||
mItemNameText = getChild<LLUICtrl>("item_name");
|
||||
mItemTypeIcon = getChild<LLIconCtrl>("item_type_icon");
|
||||
mThumbnailCtrl = getChild<LLThumbnailCtrl>("item_thumbnail");
|
||||
mToolTipTextBox = getChild<LLTextBox>("tooltip_text");
|
||||
|
||||
LLSD tooltip_text;
|
||||
mToolTipTextBox->setValue(tooltip_text);
|
||||
|
||||
LLButton *upload_local = getChild<LLButton>("upload_local");
|
||||
upload_local->setClickedCallback(onUploadLocal, (void*)this);
|
||||
upload_local->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_LOCAL));
|
||||
upload_local->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_LOCAL));
|
||||
|
||||
LLButton *upload_snapshot = getChild<LLButton>("upload_snapshot");
|
||||
upload_snapshot->setClickedCallback(onUploadSnapshot, (void*)this);
|
||||
upload_snapshot->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT));
|
||||
upload_snapshot->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT));
|
||||
|
||||
LLButton *use_texture = getChild<LLButton>("use_texture");
|
||||
use_texture->setClickedCallback(onUseTexture, (void*)this);
|
||||
use_texture->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_USE_TEXTURE));
|
||||
use_texture->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_USE_TEXTURE));
|
||||
|
||||
mCopyToClipboardBtn = getChild<LLButton>("copy_to_clipboard");
|
||||
mCopyToClipboardBtn->setClickedCallback(onCopyToClipboard, (void*)this);
|
||||
mCopyToClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD));
|
||||
mCopyToClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD));
|
||||
|
||||
mPasteFromClipboardBtn = getChild<LLButton>("paste_from_clipboard");
|
||||
mPasteFromClipboardBtn->setClickedCallback(onPasteFromClipboard, (void*)this);
|
||||
mPasteFromClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD));
|
||||
mPasteFromClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD));
|
||||
|
||||
mRemoveImageBtn = getChild<LLButton>("remove_image");
|
||||
mRemoveImageBtn->setClickedCallback(onRemove, (void*)this);
|
||||
mRemoveImageBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_REMOVE));
|
||||
mRemoveImageBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_REMOVE));
|
||||
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key)
|
||||
{
|
||||
if (!key.has("item_id") && !key.isUUID())
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
if (key.isUUID())
|
||||
{
|
||||
mItemId = key.asUUID();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemId = key["item_id"].asUUID();
|
||||
mTaskId = key["task_id"].asUUID();
|
||||
}
|
||||
|
||||
refreshFromInventory();
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::changed(U32 mask)
|
||||
{
|
||||
//LLInventoryObserver
|
||||
|
||||
if (mTaskId.notNull() || mItemId.isNull())
|
||||
{
|
||||
// Task inventory or not set up yet
|
||||
return;
|
||||
}
|
||||
|
||||
const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs();
|
||||
std::set<LLUUID>::const_iterator it;
|
||||
|
||||
for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++)
|
||||
{
|
||||
// set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288)
|
||||
if (*it == mItemId)
|
||||
{
|
||||
// if there's a change we're interested in.
|
||||
if ((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
|
||||
{
|
||||
refreshFromInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object,
|
||||
LLInventoryObject::object_list_t* inventory,
|
||||
S32 serial_num,
|
||||
void* user_data)
|
||||
{
|
||||
//LLVOInventoryListener
|
||||
refreshFromInventory();
|
||||
}
|
||||
|
||||
LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject()
|
||||
{
|
||||
LLInventoryObject* obj = NULL;
|
||||
if (mTaskId.isNull())
|
||||
{
|
||||
// it is in agent inventory
|
||||
if (!mObserverInitialized)
|
||||
{
|
||||
gInventory.addObserver(this);
|
||||
mObserverInitialized = true;
|
||||
}
|
||||
|
||||
obj = gInventory.getObject(mItemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mTaskId);
|
||||
if (object)
|
||||
{
|
||||
if (!mObserverInitialized)
|
||||
{
|
||||
registerVOInventoryListener(object, NULL);
|
||||
mObserverInitialized = false;
|
||||
}
|
||||
|
||||
obj = object->getInventoryObject(mItemId);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::refreshFromInventory()
|
||||
{
|
||||
LLInventoryObject* obj = getInventoryObject();
|
||||
if (!obj)
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
if (obj)
|
||||
{
|
||||
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
bool in_trash = (obj->getUUID() == trash_id) || gInventory.isObjectDescendentOf(obj->getUUID(), trash_id);
|
||||
if (in_trash)
|
||||
{
|
||||
// Close properties when moving to trash
|
||||
// Aren't supposed to view properties from trash
|
||||
closeFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshFromObject(obj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
class LLIsOutfitTextureType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLIsOutfitTextureType() {}
|
||||
virtual ~LLIsOutfitTextureType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
};
|
||||
|
||||
bool LLIsOutfitTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
return item && (item->getType() == LLAssetType::AT_TEXTURE);
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj)
|
||||
{
|
||||
LLUIImagePtr icon_img;
|
||||
LLUUID thumbnail_id = obj->getThumbnailUUID();
|
||||
|
||||
LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(obj);
|
||||
if (item)
|
||||
{
|
||||
// This floater probably shouldn't be be possible to open
|
||||
// for imcomplete items
|
||||
llassert(item->isFinished());
|
||||
|
||||
icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE);
|
||||
mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && ((item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id)));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryCategory* cat = dynamic_cast<LLViewerInventoryCategory*>(obj);
|
||||
|
||||
if (cat)
|
||||
{
|
||||
icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true));
|
||||
|
||||
if (thumbnail_id.isNull() && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
|
||||
{
|
||||
// Legacy support, check if there is an image inside
|
||||
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
// Not LLIsOfAssetType, because we allow links
|
||||
LLIsOutfitTextureType f;
|
||||
gInventory.getDirectDescendentsOf(mItemId, cats, items, f);
|
||||
|
||||
if (1 == items.size())
|
||||
{
|
||||
LLViewerInventoryItem* item = items.front();
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
item = item->getLinkedItem();
|
||||
}
|
||||
if (item)
|
||||
{
|
||||
LL_INFOS() << "Setting image from outfit as a thumbnail" << LL_ENDL;
|
||||
thumbnail_id = item->getAssetUUID();
|
||||
|
||||
// per SL-19188, set this image as a thumbnail
|
||||
cat->setThumbnailUUID(thumbnail_id);
|
||||
// todo: needs to trigger send/update once server support is done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mRemoveImageBtn->setEnabled(thumbnail_id.notNull());
|
||||
}
|
||||
}
|
||||
mItemTypeIcon->setImage(icon_img);
|
||||
mItemNameText->setValue(obj->getName());
|
||||
|
||||
mThumbnailCtrl->setValue(thumbnail_id);
|
||||
|
||||
mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull());
|
||||
|
||||
// todo: some elements might not support setting thumbnails
|
||||
// since they already have them
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
|
||||
(new LLThumbnailImagePicker(self->mItemId, self->mTaskId))->getFile();
|
||||
|
||||
LLFloater* floaterp = self->mPickerHandle.get();
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->closeFloater();
|
||||
}
|
||||
floaterp = self->mSnapshotHandle.get();
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
|
||||
LLFloater* floaterp = self->mSnapshotHandle.get();
|
||||
// Show the dialog
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->openFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD key;
|
||||
key["item_id"] = self->mItemId;
|
||||
key["task_id"] = self->mTaskId;
|
||||
LLFloaterSimpleSnapshot* snapshot_floater = (LLFloaterSimpleSnapshot*)LLFloaterReg::showInstance("simple_snapshot", key, true);
|
||||
if (snapshot_floater)
|
||||
{
|
||||
self->addDependentFloater(snapshot_floater);
|
||||
self->mSnapshotHandle = snapshot_floater->getHandle();
|
||||
snapshot_floater->setOwner(self);
|
||||
}
|
||||
}
|
||||
|
||||
floaterp = self->mPickerHandle.get();
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
LLInventoryObject* obj = self->getInventoryObject();
|
||||
if (obj)
|
||||
{
|
||||
self->showTexturePicker(obj->getThumbnailUUID());
|
||||
}
|
||||
|
||||
LLFloater* floaterp = self->mSnapshotHandle.get();
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
LLInventoryObject* obj = self->getInventoryObject();
|
||||
if (obj)
|
||||
{
|
||||
LLClipboard::instance().addToClipboard(obj->getThumbnailUUID());
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
std::vector<LLUUID> objects;
|
||||
LLClipboard::instance().pasteFromClipboard(objects);
|
||||
if (objects.size() > 0)
|
||||
{
|
||||
LLInventoryObject* obj = self->getInventoryObject();
|
||||
if (obj)
|
||||
{
|
||||
obj->setThumbnailUUID(objects[0]);
|
||||
// todo: need to trigger send/update once server support is done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onRemove(void *userdata)
|
||||
{
|
||||
LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata;
|
||||
|
||||
LLSD payload;
|
||||
payload["item_id"] = self->mItemId;
|
||||
payload["object_id"] = self->mTaskId;
|
||||
LLNotificationsUtil::add("DeleteThumbnail", LLSD(), payload, boost::bind(&LLFloaterChangeItemThumbnail::onRemovalConfirmation, _1, _2, self->getHandle()));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0 && !handle.isDead() && !handle.get()->isDead())
|
||||
{
|
||||
LLFloaterChangeItemThumbnail* self = (LLFloaterChangeItemThumbnail*)handle.get();
|
||||
|
||||
LLInventoryObject* obj = self->getInventoryObject();
|
||||
if (obj)
|
||||
{
|
||||
obj->setThumbnailUUID(LLUUID::null);
|
||||
// todo: need to trigger send/update once server support is done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)
|
||||
{
|
||||
// show hourglass cursor when loading inventory window
|
||||
getWindow()->setCursor(UI_CURSOR_WAIT);
|
||||
|
||||
LLFloater* floaterp = mPickerHandle.get();
|
||||
// Show the dialog
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->openFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
floaterp = new LLFloaterTexturePicker(
|
||||
this,
|
||||
thumbnail_id,
|
||||
thumbnail_id,
|
||||
thumbnail_id,
|
||||
FALSE,
|
||||
TRUE,
|
||||
LLTrans::getString("TexturePickerOutfitHeader"), // "SELECT PHOTO", // <FS:Ansariel> Localizable floater header
|
||||
PERM_NONE,
|
||||
PERM_NONE,
|
||||
PERM_NONE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
mPickerHandle = floaterp->getHandle();
|
||||
|
||||
LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
|
||||
if (texture_floaterp)
|
||||
{
|
||||
//texture_floaterp->setTextureSelectedCallback();
|
||||
//texture_floaterp->setOnUpdateImageStatsCallback();
|
||||
texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
|
||||
{
|
||||
if (op == LLTextureCtrl::TEXTURE_SELECT)
|
||||
{
|
||||
onTexturePickerCommit(id);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
texture_floaterp->setLocalTextureEnabled(FALSE);
|
||||
texture_floaterp->setBakeTextureEnabled(FALSE);
|
||||
texture_floaterp->setCanApplyImmediately(false);
|
||||
texture_floaterp->setCanApply(false, true);
|
||||
|
||||
addDependentFloater(texture_floaterp);
|
||||
}
|
||||
|
||||
floaterp->openFloater();
|
||||
}
|
||||
floaterp->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id)
|
||||
{
|
||||
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get();
|
||||
LLInventoryObject* obj = getInventoryObject();
|
||||
|
||||
if (obj && floaterp)
|
||||
{
|
||||
obj->setThumbnailUUID(floaterp->getAssetID());
|
||||
// todo: need to trigger send/update once server support is done
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state)
|
||||
{
|
||||
mTooltipState = state;
|
||||
|
||||
std::string tooltip_text;
|
||||
std::string tooltip_name = "tooltip_" + button->getName();
|
||||
if (hasString(tooltip_name))
|
||||
{
|
||||
tooltip_text = getString(tooltip_name);
|
||||
}
|
||||
|
||||
mToolTipTextBox->setValue(tooltip_text);
|
||||
}
|
||||
|
||||
void LLFloaterChangeItemThumbnail::onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state)
|
||||
{
|
||||
if (mTooltipState == state)
|
||||
{
|
||||
mTooltipState = TOOLTIP_NONE;
|
||||
LLSD tooltip_text;
|
||||
mToolTipTextBox->setValue(tooltip_text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* @file llfloaterchangeitemthumbnail.h
|
||||
* @brief LLFloaterChangeItemThumbnail class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, 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_LLFLOATERCHANGEITEMTHUMBNAIL_H
|
||||
#define LL_LLFLOATERCHANGEITEMTHUMBNAIL_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llvoinventorylistener.h"
|
||||
|
||||
class LLButton;
|
||||
class LLIconCtrl;
|
||||
class LLTextBox;
|
||||
class LLThumbnailCtrl;
|
||||
class LLUICtrl;
|
||||
class LLViewerInventoryItem;
|
||||
|
||||
class LLFloaterChangeItemThumbnail : public LLFloater, public LLInventoryObserver, public LLVOInventoryListener
|
||||
{
|
||||
public:
|
||||
LLFloaterChangeItemThumbnail(const LLSD& key);
|
||||
~LLFloaterChangeItemThumbnail();
|
||||
|
||||
BOOL postBuild() override;
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void changed(U32 mask) override;
|
||||
void inventoryChanged(LLViewerObject* object,
|
||||
LLInventoryObject::object_list_t* inventory,
|
||||
S32 serial_num,
|
||||
void* user_data) override;
|
||||
|
||||
private:
|
||||
|
||||
LLInventoryObject* getInventoryObject();
|
||||
void refreshFromInventory();
|
||||
void refreshFromObject(LLInventoryObject* obj);
|
||||
|
||||
static void onUploadLocal(void*);
|
||||
static void onUploadSnapshot(void*);
|
||||
static void onUseTexture(void*);
|
||||
static void onCopyToClipboard(void*);
|
||||
static void onPasteFromClipboard(void*);
|
||||
static void onRemove(void*);
|
||||
static void onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle);
|
||||
|
||||
void showTexturePicker(const LLUUID &thumbnail_id);
|
||||
void onTexturePickerCommit(LLUUID id);
|
||||
|
||||
enum EToolTipState
|
||||
{
|
||||
TOOLTIP_NONE,
|
||||
TOOLTIP_UPLOAD_LOCAL,
|
||||
TOOLTIP_UPLOAD_SNAPSHOT,
|
||||
TOOLTIP_USE_TEXTURE,
|
||||
TOOLTIP_COPY_TO_CLIPBOARD,
|
||||
TOOLTIP_COPY_FROM_CLIPBOARD,
|
||||
TOOLTIP_REMOVE,
|
||||
};
|
||||
|
||||
void onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state);
|
||||
void onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state);
|
||||
|
||||
bool mObserverInitialized;
|
||||
EToolTipState mTooltipState;
|
||||
LLUUID mItemId;
|
||||
LLUUID mTaskId;
|
||||
|
||||
LLIconCtrl *mItemTypeIcon;
|
||||
LLUICtrl *mItemNameText;
|
||||
LLThumbnailCtrl *mThumbnailCtrl;
|
||||
LLTextBox *mToolTipTextBox;
|
||||
LLButton *mCopyToClipboardBtn;
|
||||
LLButton *mPasteFromClipboardBtn;
|
||||
LLButton *mRemoveImageBtn;
|
||||
|
||||
LLHandle<LLFloater> mPickerHandle;
|
||||
LLHandle<LLFloater> mSnapshotHandle;
|
||||
};
|
||||
#endif // LL_LLFLOATERCHANGEITEMTHUMBNAIL_H
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
/**
|
||||
* @file llfloatersimpleoutfitsnapshot.cpp
|
||||
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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 "llfloatersimpleoutfitsnapshot.h"
|
||||
|
||||
#include "llfloaterreg.h"
|
||||
#include "llimagefiltersmanager.h"
|
||||
#include "llstatusbar.h" // can_afford_transaction()
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llagentbenefits.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL;
|
||||
|
||||
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
|
||||
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view");
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterSimpleOutfitSnapshot::Impl
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
|
||||
}
|
||||
|
||||
LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
updateResolution(floater);
|
||||
if (previewp)
|
||||
{
|
||||
previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE);
|
||||
previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG);
|
||||
previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix()
|
||||
{
|
||||
return "panel_outfit_snapshot_";
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data)
|
||||
{
|
||||
LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)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("RenderHUDInSnapshot"))
|
||||
{ //clamp snapshot resolution to window size when showing UI HUD in snapshot
|
||||
width = llmin(width, gViewerWindow->getWindowWidthRaw());
|
||||
height = llmin(height, gViewerWindow->getWindowHeightRaw());
|
||||
}
|
||||
|
||||
llassert(width > 0 && height > 0);
|
||||
|
||||
previewp->setSize(width, height);
|
||||
|
||||
if (original_width != width || original_height != height)
|
||||
{
|
||||
// hide old preview as the aspect ratio could be wrong
|
||||
checkAutoSnapshot(previewp, FALSE);
|
||||
previewp->updateSnapshot(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_READY:
|
||||
mFloater->setCtrlsEnabled(true);
|
||||
break;
|
||||
case STATUS_WORKING:
|
||||
mFloater->setCtrlsEnabled(false);
|
||||
break;
|
||||
case STATUS_FINISHED:
|
||||
mFloater->setCtrlsEnabled(true);
|
||||
break;
|
||||
}
|
||||
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------re------------
|
||||
/// Class LLFloaterSimpleOutfitSnapshot
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key)
|
||||
: LLFloaterSnapshotBase(key),
|
||||
mOutfitGallery(NULL)
|
||||
{
|
||||
impl = new Impl(this);
|
||||
}
|
||||
|
||||
LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLFloaterSimpleOutfitSnapshot::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
|
||||
|
||||
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
|
||||
childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this));
|
||||
childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, 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->addChild(previewp);
|
||||
|
||||
//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(true);
|
||||
impl->setSkipReshaping(true);
|
||||
|
||||
previewp->mKeepAspectRatio = FALSE;
|
||||
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
|
||||
previewp->setAllowRenderUI(false);
|
||||
previewp->setThumbnailSubsampled(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const S32 PREVIEW_OFFSET_Y = 70;
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::draw()
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
|
||||
if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
|
||||
{
|
||||
// don't render snapshot window in snapshot, even if "show ui" is turned on
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
|
||||
if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
|
||||
{
|
||||
if(previewp->getThumbnailImage())
|
||||
{
|
||||
bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
|
||||
const S32 thumbnail_w = previewp->getThumbnailWidth();
|
||||
const S32 thumbnail_h = previewp->getThumbnailHeight();
|
||||
|
||||
LLRect local_rect = getLocalRect();
|
||||
S32 offset_x = (local_rect.getWidth() - thumbnail_w) / 2;
|
||||
S32 offset_y = PREVIEW_OFFSET_Y;
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
// Apply floater transparency to the texture unless the floater is focused.
|
||||
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
|
||||
gl_draw_scaled_image(offset_x, offset_y,
|
||||
thumbnail_w, thumbnail_h,
|
||||
previewp->getThumbnailImage(), color % alpha);
|
||||
}
|
||||
}
|
||||
impl->updateLayout(this);
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key)
|
||||
{
|
||||
LLSnapshotLivePreview* preview = getPreviewView();
|
||||
if (preview)
|
||||
{
|
||||
preview->updateSnapshot(TRUE);
|
||||
}
|
||||
focusFirstItem(FALSE);
|
||||
gSnapshotFloaterView->setEnabled(TRUE);
|
||||
gSnapshotFloaterView->setVisible(TRUE);
|
||||
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
|
||||
|
||||
impl->updateControls(this);
|
||||
impl->setStatus(ImplBase::STATUS_READY);
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::onCancel()
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::onSend()
|
||||
{
|
||||
S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
|
||||
if (can_afford_transaction(expected_upload_cost))
|
||||
{
|
||||
saveTexture();
|
||||
postSave();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["COST"] = llformat("%d", expected_upload_cost);
|
||||
LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
|
||||
inventorySaveFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::postSave()
|
||||
{
|
||||
impl->setStatus(ImplBase::STATUS_WORKING);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSimpleOutfitSnapshot::update()
|
||||
{
|
||||
LLFloaterSimpleOutfitSnapshot* inst = findInstance();
|
||||
if (inst != NULL)
|
||||
{
|
||||
inst->impl->updateLivePreview();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance()
|
||||
{
|
||||
return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
|
||||
}
|
||||
|
||||
// static
|
||||
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance()
|
||||
{
|
||||
return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
|
||||
}
|
||||
|
||||
void LLFloaterSimpleOutfitSnapshot::saveTexture()
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (!previewp)
|
||||
{
|
||||
llassert(previewp != NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOutfitGallery)
|
||||
{
|
||||
mOutfitGallery->onBeforeOutfitSnapshotSave();
|
||||
}
|
||||
previewp->saveTexture(TRUE, getOutfitID().asString());
|
||||
if (mOutfitGallery)
|
||||
{
|
||||
mOutfitGallery->onAfterOutfitSnapshotSave();
|
||||
}
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLSimpleOutfitSnapshotFloaterView
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
|
||||
{
|
||||
}
|
||||
|
||||
LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
/**
|
||||
* @file llfloatersimplesnapshot.cpp
|
||||
* @brief Snapshot preview window for saving as a thumbnail
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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 "llfloatersimplesnapshot.h"
|
||||
|
||||
#include "llfloaterreg.h"
|
||||
#include "llimagefiltersmanager.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llstatusbar.h" // can_afford_transaction()
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentbenefits.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
|
||||
|
||||
LLSimpleSnapshotFloaterView* gSimpleSnapshotFloaterView = NULL;
|
||||
|
||||
const S32 THUMBNAIL_SNAPSHOT_DIM = 256;
|
||||
|
||||
// Thumbnail posting coro
|
||||
|
||||
static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload";
|
||||
static const std::string THUMBNAIL_CATEGORY_UPLOAD_CAP = "InventoryCategoryThumbnailUpload";
|
||||
|
||||
void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpHeaders::ptr_t httpHeaders;
|
||||
|
||||
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
|
||||
httpOpts->setFollowRedirects(true);
|
||||
|
||||
LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
// todo: notification?
|
||||
LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
if (!result.has("uploader"))
|
||||
{
|
||||
// todo: notification?
|
||||
LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
std::string uploader_cap = result["uploader"].asString();
|
||||
if (uploader_cap.empty())
|
||||
{
|
||||
LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Upload the image
|
||||
|
||||
LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
|
||||
LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
|
||||
S64 length;
|
||||
|
||||
{
|
||||
llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
|
||||
if (!instream.is_open())
|
||||
{
|
||||
LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
length = instream.tellg();
|
||||
}
|
||||
|
||||
uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
|
||||
uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
|
||||
uploaderhttpOpts->setFollowRedirects(true);
|
||||
|
||||
result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
|
||||
|
||||
httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
LL_DEBUGS("Thumbnail") << result << LL_ENDL;
|
||||
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result["state"].asString() != "complete")
|
||||
{
|
||||
if (result.has("message"))
|
||||
{
|
||||
LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: issue an inventory udpate?
|
||||
//return result["new_asset"].asUUID();
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterSimpleSnapshot::Impl
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSnapshotModel::ESnapshotFormat LLFloaterSimpleSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
|
||||
}
|
||||
|
||||
LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
updateResolution(floater);
|
||||
if (previewp)
|
||||
{
|
||||
previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE);
|
||||
previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG);
|
||||
previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLFloaterSimpleSnapshot::Impl::getSnapshotPanelPrefix()
|
||||
{
|
||||
return "panel_outfit_snapshot_";
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::Impl::updateResolution(void* data)
|
||||
{
|
||||
LLFloaterSimpleSnapshot *view = (LLFloaterSimpleSnapshot *)data;
|
||||
|
||||
if (!view)
|
||||
{
|
||||
llassert(view);
|
||||
return;
|
||||
}
|
||||
|
||||
S32 width = THUMBNAIL_SNAPSHOT_DIM;
|
||||
S32 height = THUMBNAIL_SNAPSHOT_DIM;
|
||||
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (previewp)
|
||||
{
|
||||
S32 original_width = 0, original_height = 0;
|
||||
previewp->getSize(original_width, original_height);
|
||||
|
||||
if (gSavedSettings.getBOOL("RenderHUDInSnapshot"))
|
||||
{ //clamp snapshot resolution to window size when showing UI HUD in snapshot
|
||||
width = llmin(width, gViewerWindow->getWindowWidthRaw());
|
||||
height = llmin(height, gViewerWindow->getWindowHeightRaw());
|
||||
}
|
||||
|
||||
llassert(width > 0 && height > 0);
|
||||
|
||||
previewp->setSize(width, height);
|
||||
|
||||
if (original_width != width || original_height != height)
|
||||
{
|
||||
// hide old preview as the aspect ratio could be wrong
|
||||
checkAutoSnapshot(previewp, FALSE);
|
||||
previewp->updateSnapshot(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_READY:
|
||||
mFloater->setCtrlsEnabled(true);
|
||||
break;
|
||||
case STATUS_WORKING:
|
||||
mFloater->setCtrlsEnabled(false);
|
||||
break;
|
||||
case STATUS_FINISHED:
|
||||
mFloater->setCtrlsEnabled(true);
|
||||
break;
|
||||
}
|
||||
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------re------------
|
||||
/// Class LLFloaterSimpleSnapshot
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLFloaterSimpleSnapshot::LLFloaterSimpleSnapshot(const LLSD& key)
|
||||
: LLFloaterSnapshotBase(key)
|
||||
, mOwner(NULL)
|
||||
, mContextConeOpacity(0.f)
|
||||
{
|
||||
impl = new Impl(this);
|
||||
}
|
||||
|
||||
LLFloaterSimpleSnapshot::~LLFloaterSimpleSnapshot()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLFloaterSimpleSnapshot::postBuild()
|
||||
{
|
||||
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
|
||||
childSetAction("save_btn", boost::bind(&LLFloaterSimpleSnapshot::onSend, this));
|
||||
childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleSnapshot::onCancel, 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);
|
||||
|
||||
// Do not move LLFloaterSimpleSnapshot floater into gSnapshotFloaterView
|
||||
// since it can be a dependednt floater and does not draw UI
|
||||
|
||||
impl->mPreviewHandle = previewp->getHandle();
|
||||
previewp->setContainer(this);
|
||||
impl->updateControls(this);
|
||||
impl->setAdvanced(true);
|
||||
impl->setSkipReshaping(true);
|
||||
|
||||
previewp->mKeepAspectRatio = FALSE;
|
||||
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
|
||||
previewp->setAllowRenderUI(false);
|
||||
previewp->setThumbnailSubsampled(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const S32 PREVIEW_OFFSET_Y = 70;
|
||||
|
||||
void LLFloaterSimpleSnapshot::draw()
|
||||
{
|
||||
if (mOwner)
|
||||
{
|
||||
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
|
||||
drawConeToOwner(mContextConeOpacity, max_opacity, mOwner);
|
||||
}
|
||||
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
|
||||
if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
|
||||
{
|
||||
// don't render snapshot window in snapshot, even if "show ui" is turned on
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
|
||||
if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
|
||||
{
|
||||
if(previewp->getThumbnailImage())
|
||||
{
|
||||
bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
|
||||
const S32 thumbnail_w = previewp->getThumbnailWidth();
|
||||
const S32 thumbnail_h = previewp->getThumbnailHeight();
|
||||
|
||||
LLRect local_rect = getLocalRect();
|
||||
S32 offset_x = (local_rect.getWidth() - thumbnail_w) / 2;
|
||||
S32 offset_y = PREVIEW_OFFSET_Y;
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
// Apply floater transparency to the texture unless the floater is focused.
|
||||
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
|
||||
gl_draw_scaled_image(offset_x, offset_y,
|
||||
thumbnail_w, thumbnail_h,
|
||||
previewp->getThumbnailImage(), color % alpha);
|
||||
}
|
||||
}
|
||||
impl->updateLayout(this);
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::onOpen(const LLSD& key)
|
||||
{
|
||||
LLSnapshotLivePreview* preview = getPreviewView();
|
||||
if (preview)
|
||||
{
|
||||
preview->updateSnapshot(TRUE);
|
||||
}
|
||||
focusFirstItem(FALSE);
|
||||
gSnapshotFloaterView->setEnabled(TRUE);
|
||||
gSnapshotFloaterView->setVisible(TRUE);
|
||||
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
|
||||
|
||||
impl->updateControls(this);
|
||||
impl->setStatus(ImplBase::STATUS_READY);
|
||||
|
||||
mInventoryId = key["item_id"].asUUID();
|
||||
mTaskId = key["task_id"].asUUID();
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::onCancel()
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::onSend()
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
|
||||
std::string temp_file = gDirUtilp->getTempFilename();
|
||||
if (previewp->createUploadFile(temp_file, THUMBNAIL_SNAPSHOT_DIM))
|
||||
{
|
||||
uploadImageUploadFile(temp_file, mInventoryId, mTaskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD notif_args;
|
||||
notif_args["REASON"] = LLImage::getLastError().c_str();
|
||||
LLNotificationsUtil::add("CannotUploadTexture", notif_args);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::postSave()
|
||||
{
|
||||
impl->setStatus(ImplBase::STATUS_WORKING);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id)
|
||||
{
|
||||
// generate a temp texture file for coroutine
|
||||
std::string temp_file = gDirUtilp->getTempFilename();
|
||||
U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
|
||||
if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM))
|
||||
{
|
||||
LLSD notif_args;
|
||||
notif_args["REASON"] = LLImage::getLastError().c_str();
|
||||
LLNotificationsUtil::add("CannotUploadTexture", notif_args);
|
||||
LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
uploadImageUploadFile(temp_file, inventory_id, task_id);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id)
|
||||
{
|
||||
std::string cap_name;
|
||||
LLSD data;
|
||||
|
||||
if (task_id.notNull())
|
||||
{
|
||||
cap_name = THUMBNAIL_ITEM_UPLOAD_CAP;
|
||||
data["item_id"] = inventory_id;
|
||||
data["task_id"] = task_id;
|
||||
}
|
||||
else if (gInventory.getCategory(inventory_id))
|
||||
{
|
||||
cap_name = THUMBNAIL_CATEGORY_UPLOAD_CAP;
|
||||
data["category_id"] = inventory_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
cap_name = THUMBNAIL_ITEM_UPLOAD_CAP;
|
||||
data["item_id"] = inventory_id;
|
||||
}
|
||||
|
||||
std::string cap_url = gAgent.getRegionCapability(cap_name);
|
||||
if (cap_url.empty())
|
||||
{
|
||||
LLSD args;
|
||||
args["CAPABILITY"] = cap_url;
|
||||
LLNotificationsUtil::add("RegionCapabilityRequestError", args);
|
||||
LL_WARNS("Thumbnail") << "Failed to upload profile image for item " << inventory_id << " " << task_id << ", no cap found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLCoros::instance().launch("postAgentUserImageCoro",
|
||||
boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data));
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::update()
|
||||
{
|
||||
// initializes snapshots when needed
|
||||
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("simple_snapshot");
|
||||
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
|
||||
iter != inst_list.end(); ++iter)
|
||||
{
|
||||
LLFloaterSimpleSnapshot* floater = dynamic_cast<LLFloaterSimpleSnapshot*>(*iter);
|
||||
if (floater)
|
||||
{
|
||||
floater->impl->updateLivePreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::findInstance(const LLSD &key)
|
||||
{
|
||||
return LLFloaterReg::findTypedInstance<LLFloaterSimpleSnapshot>("simple_snapshot", key);
|
||||
}
|
||||
|
||||
// static
|
||||
LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::getInstance(const LLSD &key)
|
||||
{
|
||||
return LLFloaterReg::getTypedInstance<LLFloaterSimpleSnapshot>("simple_snapshot", key);
|
||||
}
|
||||
|
||||
void LLFloaterSimpleSnapshot::saveTexture()
|
||||
{
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (!previewp)
|
||||
{
|
||||
llassert(previewp != NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
previewp->saveTexture(TRUE, getInventoryId().asString());
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLSimpleOutfitSnapshotFloaterView
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSimpleSnapshotFloaterView::LLSimpleSnapshotFloaterView(const Params& p) : LLFloaterView(p)
|
||||
{
|
||||
}
|
||||
|
||||
LLSimpleSnapshotFloaterView::~LLSimpleSnapshotFloaterView()
|
||||
{
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llfloatersimpleoutfitsnapshot.h
|
||||
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
|
||||
* @file llfloatersimplesnapshot.h
|
||||
* @brief Snapshot preview window for saving as a thumbnail
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -24,26 +24,25 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
|
||||
#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
|
||||
#ifndef LL_LLFLOATERSIMPLESNAPSHOT_H
|
||||
#define LL_LLFLOATERSIMPLESNAPSHOT_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "lloutfitgallery.h"
|
||||
#include "llsnapshotlivepreview.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterSimpleOutfitSnapshot
|
||||
/// Class LLFloaterSimpleSnapshot
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase
|
||||
class LLFloaterSimpleSnapshot : public LLFloaterSnapshotBase
|
||||
{
|
||||
LOG_CLASS(LLFloaterSimpleOutfitSnapshot);
|
||||
LOG_CLASS(LLFloaterSimpleSnapshot);
|
||||
|
||||
public:
|
||||
|
||||
LLFloaterSimpleOutfitSnapshot(const LLSD& key);
|
||||
~LLFloaterSimpleOutfitSnapshot();
|
||||
LLFloaterSimpleSnapshot(const LLSD& key);
|
||||
~LLFloaterSimpleSnapshot();
|
||||
|
||||
BOOL postBuild();
|
||||
void onOpen(const LLSD& key);
|
||||
|
|
@ -51,17 +50,19 @@ public:
|
|||
|
||||
static void update();
|
||||
|
||||
static LLFloaterSimpleOutfitSnapshot* getInstance();
|
||||
static LLFloaterSimpleOutfitSnapshot* findInstance();
|
||||
static LLFloaterSimpleSnapshot* getInstance(const LLSD &key);
|
||||
static LLFloaterSimpleSnapshot* findInstance(const LLSD &key);
|
||||
void saveTexture();
|
||||
|
||||
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
|
||||
|
||||
void setOutfitID(LLUUID id) { mOutfitID = id; }
|
||||
LLUUID getOutfitID() { return mOutfitID; }
|
||||
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
|
||||
void setInventoryId(const LLUUID &inventory_id) { mInventoryId = inventory_id; }
|
||||
LLUUID getInventoryId() { return mInventoryId; }
|
||||
void setTaskId(const LLUUID &task_id) { mTaskId = task_id; }
|
||||
void setOwner(LLView *owner_view) { mOwner = owner_view; }
|
||||
|
||||
void postSave();
|
||||
static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id);
|
||||
|
||||
class Impl;
|
||||
friend class Impl;
|
||||
|
|
@ -70,17 +71,23 @@ private:
|
|||
void onSend();
|
||||
void onCancel();
|
||||
|
||||
LLUUID mOutfitID;
|
||||
LLOutfitGallery* mOutfitGallery;
|
||||
// uploads upload-ready file
|
||||
static void uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id);
|
||||
|
||||
LLUUID mInventoryId;
|
||||
LLUUID mTaskId;
|
||||
|
||||
LLView* mOwner;
|
||||
F32 mContextConeOpacity;
|
||||
};
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterSimpleOutfitSnapshot::Impl
|
||||
/// Class LLFloaterSimpleSnapshot::Impl
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
|
||||
class LLFloaterSimpleSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
|
||||
{
|
||||
LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl);
|
||||
LOG_CLASS(LLFloaterSimpleSnapshot::Impl);
|
||||
public:
|
||||
Impl(LLFloaterSnapshotBase* floater)
|
||||
: LLFloaterSnapshotBase::ImplBase(floater)
|
||||
|
|
@ -108,7 +115,7 @@ private:
|
|||
/// Class LLSimpleOutfitSnapshotFloaterView
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView
|
||||
class LLSimpleSnapshotFloaterView : public LLFloaterView
|
||||
{
|
||||
public:
|
||||
struct Params
|
||||
|
|
@ -117,13 +124,13 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
LLSimpleOutfitSnapshotFloaterView(const Params& p);
|
||||
LLSimpleSnapshotFloaterView(const Params& p);
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
virtual ~LLSimpleOutfitSnapshotFloaterView();
|
||||
virtual ~LLSimpleSnapshotFloaterView();
|
||||
};
|
||||
|
||||
extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
|
||||
extern LLSimpleSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
|
||||
|
||||
#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
|
||||
#endif // LL_LLFLOATERSIMPLESNAPSHOT_H
|
||||
|
|
@ -75,11 +75,11 @@ void LLInspectTexture::onOpen(const LLSD& sdData)
|
|||
// Start fade animation
|
||||
LLInspect::onOpen(sdData);
|
||||
|
||||
bool fIsAsset = sdData.has("asset_id");
|
||||
bool fIsAsset = sdData.has("thumbnail_id");
|
||||
bool fIsInventory = sdData.has("item_id");
|
||||
|
||||
// Skip if we're being asked to display the same thing
|
||||
const LLUUID idAsset = (fIsAsset) ? sdData["asset_id"].asUUID() : LLUUID::null;
|
||||
const LLUUID idAsset = (fIsAsset) ? sdData["thumbnail_id"].asUUID() : LLUUID::null;
|
||||
const LLUUID idItem = (fIsInventory) ? sdData["item_id"].asUUID() : LLUUID::null;
|
||||
if ( (getVisible()) && ( ((fIsAsset) && (idAsset == mAssetId)) || ((fIsInventory) && (idItem == mItemId)) ) )
|
||||
{
|
||||
|
|
@ -134,13 +134,27 @@ BOOL LLInspectTexture::postBuild()
|
|||
// Helper functions
|
||||
//
|
||||
|
||||
class LLIsTextureType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLIsTextureType() {}
|
||||
virtual ~LLIsTextureType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
};
|
||||
|
||||
bool LLIsTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
return item && (item->getType() == LLAssetType::AT_TEXTURE);
|
||||
}
|
||||
|
||||
LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p)
|
||||
{
|
||||
const LLSD& sdTooltip = p.create_params;
|
||||
|
||||
if (sdTooltip.has("thumbnail_id") && sdTooltip["thumbnail_id"].asUUID().notNull())
|
||||
{
|
||||
// go straight for tooltip regardless of type
|
||||
// go straight for thumbnail regardless of type
|
||||
return LLUICtrlFactory::create<LLTextureToolTip>(p);
|
||||
}
|
||||
|
||||
|
|
@ -152,18 +166,32 @@ LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p)
|
|||
if (sdTooltip.has("item_id"))
|
||||
{
|
||||
const LLUUID idCategory = sdTooltip["item_id"].asUUID();
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(idCategory);
|
||||
if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
// Not LLIsOfAssetType, because we allow links
|
||||
LLIsTextureType f;
|
||||
gInventory.getDirectDescendentsOf(idCategory, cats, items, f);
|
||||
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLIsOfAssetType f(LLAssetType::AT_TEXTURE);
|
||||
gInventory.getDirectDescendentsOf(idCategory, cats, items, f);
|
||||
|
||||
// Exactly one texture found => show the texture tooltip
|
||||
if (1 == items.size())
|
||||
{
|
||||
p.create_params.getValue()["asset_id"] = items.front()->getAssetUUID();
|
||||
return LLUICtrlFactory::create<LLTextureToolTip>(p);
|
||||
}
|
||||
// Exactly one texture found => show the texture tooltip
|
||||
if (1 == items.size())
|
||||
{
|
||||
LLViewerInventoryItem* item = items.front();
|
||||
if (item && item->getIsLinkType())
|
||||
{
|
||||
item = item->getLinkedItem();
|
||||
}
|
||||
if (item)
|
||||
{
|
||||
// Note: LLFloaterChangeItemThumbnail will attempt to write this
|
||||
// into folder's thumbnail id when opened
|
||||
p.create_params.getValue()["thumbnail_id"] = item->getAssetUUID();
|
||||
return LLUICtrlFactory::create<LLTextureToolTip>(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No or more than one texture found => show default tooltip
|
||||
|
|
|
|||
|
|
@ -161,6 +161,12 @@ bool isMarketplaceSendAction(const std::string& action)
|
|||
return ("send_to_marketplace" == action);
|
||||
}
|
||||
|
||||
bool isPanelActive(const std::string& panel_name)
|
||||
{
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
|
||||
return (active_panel && (active_panel->getName() == panel_name));
|
||||
}
|
||||
|
||||
// Used by LLFolderBridge as callback for directory fetching recursion
|
||||
class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
|
|
@ -455,6 +461,25 @@ void LLInvFVBridge::showProperties()
|
|||
}
|
||||
}
|
||||
|
||||
void LLInvFVBridge::navigateToFolder()
|
||||
{
|
||||
LLInventorySingleFolderPanel* panel = dynamic_cast<LLInventorySingleFolderPanel*>(mInventoryPanel.get());
|
||||
if (!panel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
if (!model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mUUID.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
panel->changeFolderRoot(mUUID);
|
||||
}
|
||||
|
||||
void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
|
||||
{
|
||||
// Deactivate gestures when moving them into Trash
|
||||
|
|
@ -919,6 +944,13 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
|
|||
disabled_items.push_back(std::string("Rename"));
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);
|
||||
items.push_back(std::string("thumbnail"));
|
||||
if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
|
||||
{
|
||||
disabled_items.push_back(std::string("thumbnail"));
|
||||
}
|
||||
|
||||
if (show_asset_id)
|
||||
{
|
||||
|
|
@ -926,7 +958,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
|
|||
|
||||
bool is_asset_knowable = false;
|
||||
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);
|
||||
if (inv_item)
|
||||
{
|
||||
is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType());
|
||||
|
|
@ -999,11 +1030,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
|
|||
|
||||
addDeleteContextMenuOptions(items, disabled_items);
|
||||
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
|
||||
// <FS:Zi> Don't offer "Show in Main View" for folders opened in separate inventory views
|
||||
// as there are no tabs to switch to
|
||||
// if (active_panel && (active_panel->getName() != "All Items"))
|
||||
if (active_panel && (active_panel->getName() != "All Items") && (active_panel->getName() != "inv_panel"))
|
||||
//if (!isPanelActive("All Items") && !isPanelActive("single_folder_inv"))
|
||||
if (!isPanelActive("All Items") && !isPanelActive("single_folder_inv") && !isPanelActive("inv_panel"))
|
||||
// </FS:Zi>
|
||||
{
|
||||
items.push_back(std::string("Show in Main Panel"));
|
||||
|
|
@ -1113,7 +1143,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
|
|||
|
||||
items.push_back(std::string("Delete"));
|
||||
|
||||
if (!isItemRemovable())
|
||||
if (!isItemRemovable() || isPanelActive("Favorite Items"))
|
||||
{
|
||||
disabled_items.push_back(std::string("Delete"));
|
||||
}
|
||||
|
|
@ -1862,6 +1892,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
restoreItem();
|
||||
return;
|
||||
}
|
||||
else if ("thumbnail" == action)
|
||||
{
|
||||
LLSD data(mUUID);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
return;
|
||||
}
|
||||
else if ("copy_uuid" == action)
|
||||
{
|
||||
// Single item only
|
||||
|
|
@ -3566,6 +3602,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
|
||||
return;
|
||||
}
|
||||
else if ("thumbnail" == action)
|
||||
{
|
||||
LLSD data(mUUID);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
return;
|
||||
}
|
||||
else if ("paste" == action)
|
||||
{
|
||||
pasteFromClipboard();
|
||||
|
|
@ -4537,12 +4579,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
}
|
||||
|
||||
disabled_items.push_back(std::string("New Folder"));
|
||||
disabled_items.push_back(std::string("New Script"));
|
||||
disabled_items.push_back(std::string("New Note"));
|
||||
disabled_items.push_back(std::string("New Settings"));
|
||||
disabled_items.push_back(std::string("New Gesture"));
|
||||
disabled_items.push_back(std::string("New Clothes"));
|
||||
disabled_items.push_back(std::string("New Body Parts"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
}
|
||||
if (favorites == mUUID)
|
||||
|
|
@ -4565,11 +4601,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)
|
||||
{
|
||||
disabled_items.push_back(std::string("New Folder"));
|
||||
disabled_items.push_back(std::string("New Script"));
|
||||
disabled_items.push_back(std::string("New Note"));
|
||||
disabled_items.push_back(std::string("New Gesture"));
|
||||
disabled_items.push_back(std::string("New Clothes"));
|
||||
disabled_items.push_back(std::string("New Body Parts"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
}
|
||||
if (marketplace_listings_id == mUUID)
|
||||
|
|
@ -4579,14 +4610,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
disabled_items.push_back(std::string("Cut"));
|
||||
disabled_items.push_back(std::string("Delete"));
|
||||
}
|
||||
|
||||
if (isPanelActive("Favorite Items"))
|
||||
{
|
||||
disabled_items.push_back(std::string("Delete"));
|
||||
}
|
||||
if(trash_id == mUUID)
|
||||
{
|
||||
bool is_recent_panel = false;
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
|
||||
if (active_panel && (active_panel->getName() == "Recent Items"))
|
||||
{
|
||||
is_recent_panel = true;
|
||||
}
|
||||
bool is_recent_panel = isPanelActive("Recent Items");
|
||||
|
||||
// This is the trash.
|
||||
items.push_back(std::string("Empty Trash"));
|
||||
|
|
@ -4636,19 +4667,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
if (!isMarketplaceListingsFolder() && !model->isObjectDescendentOf(mUUID, outfits_id))
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
items.push_back(std::string("New Script"));
|
||||
items.push_back(std::string("New Note"));
|
||||
items.push_back(std::string("New Gesture"));
|
||||
items.push_back(std::string("New Clothes"));
|
||||
items.push_back(std::string("New Body Parts"));
|
||||
items.push_back(std::string("New Settings"));
|
||||
items.push_back(std::string("upload_def"));
|
||||
|
||||
if (!LLEnvironment::instance().isInventoryEnabled())
|
||||
{
|
||||
disabled_items.push_back("New Settings");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
getClipboardEntries(false, items, disabled_items, flags);
|
||||
|
|
@ -4872,6 +4891,17 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
|
|||
disabled_items.push_back(std::string("New folder from selected"));
|
||||
}
|
||||
|
||||
|
||||
if ((flags & ITEM_IN_MULTI_SELECTION) == 0)
|
||||
{
|
||||
items.push_back(std::string("open_in_new_window"));
|
||||
items.push_back(std::string("Open Folder Separator"));
|
||||
if(isPanelActive("single_folder_inv"))
|
||||
{
|
||||
items.push_back(std::string("open_in_current_window"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ public:
|
|||
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
|
||||
virtual void openItem() {}
|
||||
virtual void closeItem() {}
|
||||
virtual void navigateToFolder();
|
||||
virtual void showProperties();
|
||||
virtual BOOL isItemRenameable() const { return TRUE; }
|
||||
virtual BOOL isMultiPreviewAllowed() { return TRUE; }
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
|
|||
mCurrentGeneration(0),
|
||||
mFirstRequiredGeneration(0),
|
||||
mFirstSuccessGeneration(0),
|
||||
mSearchType(SEARCHTYPE_NAME)
|
||||
mSearchType(SEARCHTYPE_NAME),
|
||||
mSingleFolderMode(false)
|
||||
{
|
||||
// copy mFilterOps into mDefaultFilterOps
|
||||
markDefault();
|
||||
|
|
@ -1841,7 +1842,7 @@ bool LLInventoryFilter::areDateLimitsSet()
|
|||
|
||||
bool LLInventoryFilter::showAllResults() const
|
||||
{
|
||||
return hasFilterString();
|
||||
return hasFilterString() && !mSingleFolderMode;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -252,6 +252,8 @@ public:
|
|||
std::string::size_type getFilterSubStringLen(U32 index) const;
|
||||
// </FS:Zi> Multi-substring inventory search
|
||||
|
||||
void setSingleFolderMode(bool is_single_folder) { mSingleFolderMode = is_single_folder; }
|
||||
|
||||
void setFilterPermissions(PermissionMask perms);
|
||||
PermissionMask getFilterPermissions() const;
|
||||
|
||||
|
|
@ -384,6 +386,8 @@ private:
|
|||
|
||||
std::vector<std::string> mFilterTokens;
|
||||
std::string mExactToken;
|
||||
|
||||
bool mSingleFolderMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
|
|||
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
|
||||
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
|
||||
mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2));
|
||||
mCommitCallbackRegistrar.add("Inventory.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, _2));
|
||||
mCommitCallbackRegistrar.add("Inventory.CustomAction", boost::bind(&LLInventoryPanel::onCustomAction, this, _2)); // <FS:Ansariel> Prevent warning "No callback found for: 'Inventory.CustomAction' in control: Find Links"
|
||||
}
|
||||
|
||||
|
|
@ -1797,6 +1798,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
|
|||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::openSingleViewInventory(const LLSD& userdata)
|
||||
{
|
||||
LLPanelMainInventory::newFolderWindow(LLFolderBridge::sSelf.get()->getUUID());
|
||||
}
|
||||
|
||||
void LLInventoryPanel::purgeSelectedItems()
|
||||
{
|
||||
if (!mFolderRoot.get()) return;
|
||||
|
|
@ -2284,6 +2290,138 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
|
|||
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
|
||||
}
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLInventorySingleFolderPanel> t_single_folder_inventory_panel("single_folder_inventory_panel");
|
||||
|
||||
LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params)
|
||||
: LLInventoryPanel(params)
|
||||
{
|
||||
getFilter().setSingleFolderMode(true);
|
||||
|
||||
mCommitCallbackRegistrar.add("Inventory.OpenSelectedFolder", boost::bind(&LLInventorySingleFolderPanel::openInCurrentWindow, this, _2));
|
||||
}
|
||||
|
||||
LLInventorySingleFolderPanel::~LLInventorySingleFolderPanel()
|
||||
{
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
|
||||
{
|
||||
if (mFolderRoot.get())
|
||||
{
|
||||
mFolderRoot.get()->setSelectCallback(cb);
|
||||
mSelectionCallback = cb;
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::initFromParams(const Params& p)
|
||||
{
|
||||
Params fav_params(p);
|
||||
fav_params.start_folder.id = gInventory.getRootFolderID();
|
||||
LLInventoryPanel::initFromParams(p);
|
||||
changeFolderRoot(gInventory.getRootFolderID());
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::openInCurrentWindow(const LLSD& userdata)
|
||||
{
|
||||
changeFolderRoot(LLFolderBridge::sSelf.get()->getUUID());
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::changeFolderRoot(const LLUUID& new_id)
|
||||
{
|
||||
if(mFolderID.notNull())
|
||||
{
|
||||
mBackwardFolders.push_back(mFolderID);
|
||||
}
|
||||
mFolderID = new_id;
|
||||
updateSingleFolderRoot();
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::onForwardFolder()
|
||||
{
|
||||
if(!mForwardFolders.empty() && (mFolderID != mForwardFolders.back()))
|
||||
{
|
||||
mBackwardFolders.push_back(mFolderID);
|
||||
mFolderID = mForwardFolders.back();
|
||||
mForwardFolders.pop_back();
|
||||
updateSingleFolderRoot();
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::onBackwardFolder()
|
||||
{
|
||||
if(!mBackwardFolders.empty() && (mFolderID != mBackwardFolders.back()))
|
||||
{
|
||||
mForwardFolders.push_back(mFolderID);
|
||||
mFolderID = mBackwardFolders.back();
|
||||
mBackwardFolders.pop_back();
|
||||
updateSingleFolderRoot();
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::clearNavigationHistory()
|
||||
{
|
||||
mForwardFolders.clear();
|
||||
mBackwardFolders.clear();
|
||||
}
|
||||
|
||||
boost::signals2::connection LLInventorySingleFolderPanel::setRootChangedCallback(root_changed_callback_t cb)
|
||||
{
|
||||
return mRootChangedSignal.connect(cb);
|
||||
}
|
||||
|
||||
void LLInventorySingleFolderPanel::updateSingleFolderRoot()
|
||||
{
|
||||
if (mFolderID != getRootFolderID())
|
||||
{
|
||||
mRootChangedSignal();
|
||||
|
||||
LLUUID root_id = mFolderID;
|
||||
if (mFolderRoot.get())
|
||||
{
|
||||
removeItemID(getRootFolderID());
|
||||
mFolderRoot.get()->destroyView();
|
||||
}
|
||||
|
||||
mCommitCallbackRegistrar.pushScope();
|
||||
{
|
||||
LLFolderView* folder_view = createFolderRoot(root_id);
|
||||
folder_view->setChildrenInited(false);
|
||||
mFolderRoot = folder_view->getHandle();
|
||||
|
||||
addItemID(root_id, mFolderRoot.get());
|
||||
|
||||
LLRect scroller_view_rect = getRect();
|
||||
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
|
||||
LLScrollContainer::Params scroller_params(mParams.scroll());
|
||||
scroller_params.rect(scroller_view_rect);
|
||||
|
||||
if (mScroller)
|
||||
{
|
||||
removeChild(mScroller);
|
||||
delete mScroller;
|
||||
mScroller = NULL;
|
||||
}
|
||||
mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
|
||||
addChild(mScroller);
|
||||
mScroller->addChild(mFolderRoot.get());
|
||||
mFolderRoot.get()->setScrollContainer(mScroller);
|
||||
mFolderRoot.get()->setFollowsAll();
|
||||
mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
|
||||
|
||||
if (!mSelectionCallback.empty())
|
||||
{
|
||||
mFolderRoot.get()->setSelectCallback(mSelectionCallback);
|
||||
}
|
||||
}
|
||||
mCommitCallbackRegistrar.popScope();
|
||||
mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
|
||||
|
||||
buildNewViews(mFolderID);
|
||||
|
||||
mFolderRoot.get()->setShowEmptyMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Asset Pre-Filtered Inventory Panel related class */
|
||||
/************************************************************************/
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ public:
|
|||
void doCreate(const LLSD& userdata);
|
||||
bool beginIMSession();
|
||||
void fileUploadLocation(const LLSD& userdata);
|
||||
void openSingleViewInventory(const LLSD& userdata);
|
||||
void purgeSelectedItems();
|
||||
bool attachObject(const LLSD& userdata);
|
||||
static void idle(void* user_data);
|
||||
|
|
@ -279,6 +280,8 @@ public:
|
|||
|
||||
void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void changeFolderRoot(const LLUUID& new_id) {};
|
||||
|
||||
protected:
|
||||
void openStartFolderOrMyInventory(); // open the first level of inventory
|
||||
void onItemsCompletion(); // called when selected items are complete
|
||||
|
|
@ -399,6 +402,44 @@ private:
|
|||
std::deque<LLUUID> mBuildViewsQueue;
|
||||
};
|
||||
|
||||
|
||||
class LLInventorySingleFolderPanel : public LLInventoryPanel
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
|
||||
{};
|
||||
|
||||
void initFromParams(const Params& p);
|
||||
bool isSelectionRemovable() { return false; }
|
||||
//void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
|
||||
|
||||
void openInCurrentWindow(const LLSD& userdata);
|
||||
void changeFolderRoot(const LLUUID& new_id);
|
||||
void onForwardFolder();
|
||||
void onBackwardFolder();
|
||||
void clearNavigationHistory();
|
||||
LLUUID getSingleFolderRoot() { return mFolderID; }
|
||||
|
||||
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
|
||||
|
||||
typedef boost::function<void()> root_changed_callback_t;
|
||||
boost::signals2::connection setRootChangedCallback(root_changed_callback_t cb);
|
||||
|
||||
protected:
|
||||
LLInventorySingleFolderPanel(const Params& params);
|
||||
~LLInventorySingleFolderPanel();
|
||||
void updateSingleFolderRoot();
|
||||
|
||||
boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
LLUUID mFolderID;
|
||||
std::list<LLUUID> mBackwardFolders;
|
||||
std::list<LLUUID> mForwardFolders;
|
||||
|
||||
boost::signals2::signal<void()> mRootChangedSignal;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* Asset Pre-Filtered Inventory Panel related class */
|
||||
/* Exchanges filter's flexibility for speed of generation and */
|
||||
|
|
|
|||
|
|
@ -36,12 +36,11 @@
|
|||
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llagentbenefits.h"
|
||||
#include "llerror.h"
|
||||
#include "llfilepicker.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersimpleoutfitsnapshot.h"
|
||||
#include "llfloatersimplesnapshot.h"
|
||||
#include "llimagedimensionsinfo.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
|
@ -125,7 +124,6 @@ void LLOutfitGallery::onOpen(const LLSD& info)
|
|||
LLOutfitListBase::onOpen(info);
|
||||
if (!mGalleryCreated)
|
||||
{
|
||||
loadPhotos();
|
||||
uuid_vec_t cats;
|
||||
getCurrentCategories(cats);
|
||||
int n = cats.size();
|
||||
|
|
@ -837,50 +835,20 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu()
|
|||
registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
|
||||
registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id));
|
||||
registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2));
|
||||
registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id));
|
||||
registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id));
|
||||
registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id));
|
||||
registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id));
|
||||
registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id));
|
||||
enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2));
|
||||
enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2));
|
||||
|
||||
return createFromFile("menu_gallery_outfit_tab.xml");
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id)
|
||||
void LLOutfitGalleryContextMenu::onThumbnail(const LLUUID& outfit_cat_id)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && outfit_cat_id.notNull())
|
||||
{
|
||||
gallery->uploadPhoto(outfit_cat_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && outfit_cat_id.notNull())
|
||||
{
|
||||
gallery->onSelectPhoto(outfit_cat_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && outfit_cat_id.notNull())
|
||||
{
|
||||
gallery->checkRemovePhoto(outfit_cat_id);
|
||||
gallery->refreshOutfit(outfit_cat_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && outfit_cat_id.notNull())
|
||||
{
|
||||
gallery->onTakeSnapshot(outfit_cat_id);
|
||||
LLSD data(outfit_cat_id);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -919,16 +887,6 @@ bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param)
|
|||
|
||||
bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param)
|
||||
{
|
||||
mMenuHandle.get()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
|
||||
if ("remove_photo" == param)
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
LLUUID selected_id = mUUIDs.front();
|
||||
if (gallery && selected_id.notNull())
|
||||
{
|
||||
return !gallery->hasDefaultImage(selected_id);
|
||||
}
|
||||
}
|
||||
return LLOutfitContextMenu::onVisible(param);
|
||||
}
|
||||
|
||||
|
|
@ -943,56 +901,12 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
|
|||
bool have_selection = getSelectedOutfitID().notNull();
|
||||
mMenu->setItemVisible("expand", FALSE);
|
||||
mMenu->setItemVisible("collapse", FALSE);
|
||||
mMenu->setItemVisible("upload_photo", have_selection);
|
||||
mMenu->setItemVisible("select_photo", have_selection);
|
||||
mMenu->setItemVisible("take_snapshot", have_selection);
|
||||
mMenu->setItemVisible("remove_photo", !hasDefaultImage());
|
||||
mMenu->setItemVisible("thumbnail", have_selection);
|
||||
mMenu->setItemVisible("sepatator3", TRUE);
|
||||
mMenu->setItemVisible("sort_folders_by_name", TRUE);
|
||||
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onUploadFoto()
|
||||
{
|
||||
LLUUID selected_outfit_id = getSelectedOutfitID();
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
if (gallery && selected_outfit_id.notNull())
|
||||
{
|
||||
gallery->uploadPhoto(selected_outfit_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onSelectPhoto()
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
LLUUID selected_outfit_id = getSelectedOutfitID();
|
||||
if (gallery && !selected_outfit_id.isNull())
|
||||
{
|
||||
gallery->onSelectPhoto(selected_outfit_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onRemovePhoto()
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
LLUUID selected_outfit_id = getSelectedOutfitID();
|
||||
if (gallery && !selected_outfit_id.isNull())
|
||||
{
|
||||
gallery->checkRemovePhoto(selected_outfit_id);
|
||||
gallery->refreshOutfit(selected_outfit_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onTakeSnapshot()
|
||||
{
|
||||
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
|
||||
LLUUID selected_outfit_id = getSelectedOutfitID();
|
||||
if (gallery && !selected_outfit_id.isNull())
|
||||
{
|
||||
gallery->onTakeSnapshot(selected_outfit_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGalleryGearMenu::onChangeSortOrder()
|
||||
{
|
||||
bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName");
|
||||
|
|
@ -1019,104 +933,82 @@ void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp)
|
|||
{
|
||||
}
|
||||
|
||||
void LLOutfitGallery::loadPhotos()
|
||||
{
|
||||
//Iterate over inventory
|
||||
mSnapshotFolderID = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE);
|
||||
LLViewerInventoryCategory* textures_category = gInventory.getCategory(mSnapshotFolderID);
|
||||
if (!textures_category)
|
||||
return;
|
||||
if (mTexturesObserver == NULL)
|
||||
{
|
||||
mTexturesObserver = new LLInventoryCategoriesObserver();
|
||||
gInventory.addObserver(mTexturesObserver);
|
||||
}
|
||||
|
||||
// Start observing changes in "Textures" category.
|
||||
mTexturesObserver->addCategory(mSnapshotFolderID,
|
||||
boost::bind(&LLOutfitGallery::refreshTextures, this, mSnapshotFolderID));
|
||||
|
||||
textures_category->fetch();
|
||||
}
|
||||
|
||||
void LLOutfitGallery::updateSnapshotFolderObserver()
|
||||
{
|
||||
if(mSnapshotFolderID != gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE))
|
||||
{
|
||||
if (gInventory.containsObserver(mTexturesObserver))
|
||||
{
|
||||
gInventory.removeObserver(mTexturesObserver);
|
||||
}
|
||||
delete mTexturesObserver;
|
||||
mTexturesObserver = NULL;
|
||||
loadPhotos();
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
|
||||
{
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(category_id);
|
||||
if (category)
|
||||
{
|
||||
bool photo_loaded = false;
|
||||
LLInventoryModel::cat_array_t sub_cat_array;
|
||||
LLInventoryModel::item_array_t outfit_item_array;
|
||||
// Collect all sub-categories of a given category.
|
||||
gInventory.collectDescendents(
|
||||
category->getUUID(),
|
||||
sub_cat_array,
|
||||
outfit_item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
|
||||
LLUUID asset_id = category->getThumbnailUUID();
|
||||
if (asset_id.isNull())
|
||||
{
|
||||
LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
|
||||
LLUUID asset_id, inv_id;
|
||||
std::string item_name;
|
||||
if (linked_item != NULL)
|
||||
LLInventoryModel::cat_array_t sub_cat_array;
|
||||
LLInventoryModel::item_array_t outfit_item_array;
|
||||
// Collect all sub-categories of a given category.
|
||||
gInventory.collectDescendents(
|
||||
category->getUUID(),
|
||||
sub_cat_array,
|
||||
outfit_item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
|
||||
{
|
||||
if (linked_item->getActualType() == LLAssetType::AT_TEXTURE)
|
||||
LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
|
||||
LLUUID asset_id, inv_id;
|
||||
std::string item_name;
|
||||
if (linked_item != NULL)
|
||||
{
|
||||
asset_id = linked_item->getAssetUUID();
|
||||
inv_id = linked_item->getUUID();
|
||||
item_name = linked_item->getName();
|
||||
}
|
||||
}
|
||||
else if (outfit_item->getActualType() == LLAssetType::AT_TEXTURE)
|
||||
{
|
||||
asset_id = outfit_item->getAssetUUID();
|
||||
inv_id = outfit_item->getUUID();
|
||||
item_name = outfit_item->getName();
|
||||
}
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
photo_loaded |= mOutfitMap[category_id]->setImageAssetId(asset_id);
|
||||
// Rename links
|
||||
if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == item_name)
|
||||
{
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending);
|
||||
LLStringUtil::format_map_t photo_string_args;
|
||||
photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
|
||||
std::string new_name = getString("outfit_photo_string", photo_string_args);
|
||||
LLSD updates;
|
||||
updates["name"] = new_name;
|
||||
update_inventory_item(inv_id, updates, NULL);
|
||||
mOutfitRenamePending.setNull();
|
||||
LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance");
|
||||
if (appearance_floater)
|
||||
if (linked_item->getActualType() == LLAssetType::AT_TEXTURE)
|
||||
{
|
||||
appearance_floater->setFocus(TRUE);
|
||||
asset_id = linked_item->getAssetUUID();
|
||||
inv_id = linked_item->getUUID();
|
||||
item_name = linked_item->getName();
|
||||
}
|
||||
}
|
||||
if (item_name == LLAppearanceMgr::sExpectedTextureName)
|
||||
else if (outfit_item->getActualType() == LLAssetType::AT_TEXTURE)
|
||||
{
|
||||
// Images with "appropriate" name take priority
|
||||
break;
|
||||
asset_id = outfit_item->getAssetUUID();
|
||||
inv_id = outfit_item->getUUID();
|
||||
item_name = outfit_item->getName();
|
||||
}
|
||||
if (category->getThumbnailUUID().notNull())
|
||||
{
|
||||
asset_id = category->getThumbnailUUID();
|
||||
}
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
photo_loaded |= mOutfitMap[category_id]->setImageAssetId(asset_id);
|
||||
// Rename links
|
||||
if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == item_name)
|
||||
{
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending);
|
||||
LLStringUtil::format_map_t photo_string_args;
|
||||
photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
|
||||
std::string new_name = getString("outfit_photo_string", photo_string_args);
|
||||
LLSD updates;
|
||||
updates["name"] = new_name;
|
||||
update_inventory_item(inv_id, updates, NULL);
|
||||
mOutfitRenamePending.setNull();
|
||||
LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance");
|
||||
if (appearance_floater)
|
||||
{
|
||||
appearance_floater->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
if (item_name == LLAppearanceMgr::sExpectedTextureName)
|
||||
{
|
||||
// Images with "appropriate" name take priority
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!photo_loaded)
|
||||
{
|
||||
mOutfitMap[category_id]->setDefaultImage();
|
||||
}
|
||||
}
|
||||
if (!photo_loaded)
|
||||
{
|
||||
mOutfitMap[category_id]->setDefaultImage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mOutfitMap[category_id]->setImageAssetId(asset_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1126,131 +1018,6 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
|
|||
}
|
||||
}
|
||||
|
||||
// Refresh linked textures from "textures" uploads folder
|
||||
void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
|
||||
// Collect all sub-categories of a given category.
|
||||
LLIsType is_texture(LLAssetType::AT_TEXTURE);
|
||||
gInventory.collectDescendentsIf(
|
||||
category_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_texture);
|
||||
|
||||
//Find texture which contain pending outfit ID string in name
|
||||
LLViewerInventoryItem* photo_upload_item = NULL;
|
||||
BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
|
||||
{
|
||||
std::string name = item->getName();
|
||||
if (!mOutfitLinkPending.isNull() && name == mOutfitLinkPending.asString())
|
||||
{
|
||||
photo_upload_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (photo_upload_item != NULL)
|
||||
{
|
||||
LLUUID photo_item_id = photo_upload_item->getUUID();
|
||||
LLInventoryObject* upload_object = gInventory.getObject(photo_item_id);
|
||||
if (!upload_object)
|
||||
{
|
||||
LL_WARNS() << "LLOutfitGallery::refreshTextures added_object is null!" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
linkPhotoToOutfit(photo_item_id, mOutfitLinkPending);
|
||||
mOutfitRenamePending = mOutfitLinkPending;
|
||||
mOutfitLinkPending.setNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
|
||||
{
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
(new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
|
||||
}
|
||||
|
||||
void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
|
||||
{
|
||||
std::string filename = filenames[0];
|
||||
LLLocalBitmap* unit = new LLLocalBitmap(filename);
|
||||
if (unit->getValid())
|
||||
{
|
||||
std::string exten = gDirUtilp->getExtension(filename);
|
||||
U32 codec = LLImageBase::getCodecFromExtension(exten);
|
||||
|
||||
LLImageDimensionsInfo image_info;
|
||||
std::string image_load_error;
|
||||
if (!image_info.load(filename, codec))
|
||||
{
|
||||
image_load_error = image_info.getLastError();
|
||||
}
|
||||
|
||||
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
|
||||
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
|
||||
|
||||
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["WIDTH"] = llformat("%d", max_width);
|
||||
args["HEIGHT"] = llformat("%d", max_height);
|
||||
|
||||
image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
|
||||
}
|
||||
|
||||
if (!image_load_error.empty())
|
||||
{
|
||||
LLSD subst;
|
||||
subst["REASON"] = image_load_error;
|
||||
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
|
||||
return;
|
||||
}
|
||||
|
||||
S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
|
||||
void *nruserdata = NULL;
|
||||
nruserdata = (void *)&outfit_id;
|
||||
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
|
||||
if (!outfit_cat) return;
|
||||
updateSnapshotFolderObserver();
|
||||
checkRemovePhoto(outfit_id);
|
||||
std::string upload_pending_name = outfit_id.asString();
|
||||
std::string upload_pending_desc = "";
|
||||
upload_new_resource(filename, // file
|
||||
upload_pending_name,
|
||||
upload_pending_desc,
|
||||
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
upload_pending_name, LLAssetStorage::LLStoreAssetCallback(), expected_upload_cost, nruserdata, false);
|
||||
mOutfitLinkPending = outfit_id;
|
||||
}
|
||||
delete unit;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked();
|
||||
link_inventory_object(outfit_id, photo_id, cb);
|
||||
}
|
||||
|
||||
bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
|
||||
{
|
||||
LLAppearanceMgr::instance().removeOutfitPhoto(outfit_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLUpdateGalleryOnPhotoLinked::fire(const LLUUID& inv_item_id)
|
||||
{
|
||||
}
|
||||
|
|
@ -1270,151 +1037,3 @@ LLUUID LLOutfitGallery::getDefaultPhoto()
|
|||
return LLUUID();
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id)
|
||||
{
|
||||
LLUUID selected_outfit_id = getSelectedOutfitUUID();
|
||||
|
||||
if (selected_outfit_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
|
||||
|
||||
if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT)
|
||||
{
|
||||
LLUUID image_item_id;
|
||||
if (id.notNull())
|
||||
{
|
||||
image_item_id = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE, TRUE);
|
||||
if (image_item_id.isNull())
|
||||
{
|
||||
LL_WARNS() << "id or image_item_id is NULL!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::string image_load_error;
|
||||
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
|
||||
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
|
||||
if (mTextureSelected.isNull() ||
|
||||
mTextureSelected->getFullWidth() == 0 ||
|
||||
mTextureSelected->getFullHeight() == 0)
|
||||
{
|
||||
image_load_error = LLTrans::getString("outfit_photo_verify_dimensions_error");
|
||||
LL_WARNS() << "Cannot verify selected texture dimensions" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
S32 width = mTextureSelected->getFullWidth();
|
||||
S32 height = mTextureSelected->getFullHeight();
|
||||
if ((width > max_width) || (height > max_height))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["WIDTH"] = llformat("%d", max_width);
|
||||
args["HEIGHT"] = llformat("%d", max_height);
|
||||
|
||||
image_load_error = LLTrans::getString("outfit_photo_select_dimensions_error", args);
|
||||
}
|
||||
|
||||
if (!image_load_error.empty())
|
||||
{
|
||||
LLSD subst;
|
||||
subst["REASON"] = image_load_error;
|
||||
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
|
||||
return;
|
||||
}
|
||||
|
||||
checkRemovePhoto(selected_outfit_id);
|
||||
linkPhotoToOutfit(image_item_id, selected_outfit_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
|
||||
{
|
||||
if (selected_outfit_id.notNull())
|
||||
{
|
||||
|
||||
// show hourglass cursor when loading inventory window
|
||||
// because inventory construction is slooow
|
||||
getWindow()->setCursor(UI_CURSOR_WAIT);
|
||||
LLFloater* floaterp = mFloaterHandle.get();
|
||||
|
||||
// Show the dialog
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->openFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
floaterp = new LLFloaterTexturePicker(
|
||||
this,
|
||||
getPhotoAssetId(selected_outfit_id),
|
||||
getPhotoAssetId(selected_outfit_id),
|
||||
getPhotoAssetId(selected_outfit_id),
|
||||
FALSE,
|
||||
TRUE,
|
||||
LLTrans::getString("TexturePickerOutfitHeader"), // "SELECT PHOTO", // <FS:Ansariel> Localizable floater header
|
||||
PERM_NONE,
|
||||
PERM_NONE,
|
||||
PERM_NONE,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
mFloaterHandle = floaterp->getHandle();
|
||||
mTextureSelected = NULL;
|
||||
|
||||
LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
|
||||
if (texture_floaterp)
|
||||
{
|
||||
texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1));
|
||||
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
|
||||
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
|
||||
texture_floaterp->setLocalTextureEnabled(FALSE);
|
||||
texture_floaterp->setBakeTextureEnabled(FALSE);
|
||||
texture_floaterp->setCanApply(false, true);
|
||||
}
|
||||
|
||||
floaterp->openFloater();
|
||||
}
|
||||
floaterp->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
|
||||
{
|
||||
LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot");
|
||||
LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance();
|
||||
if (snapshot_floater)
|
||||
{
|
||||
snapshot_floater->setOutfitID(selected_outfit_id);
|
||||
snapshot_floater->getInstance()->setGallery(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onBeforeOutfitSnapshotSave()
|
||||
{
|
||||
LLUUID selected_outfit_id = getSelectedOutfitUUID();
|
||||
if (!selected_outfit_id.isNull())
|
||||
{
|
||||
checkRemovePhoto(selected_outfit_id);
|
||||
updateSnapshotFolderObserver();
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onAfterOutfitSnapshotSave()
|
||||
{
|
||||
LLUUID selected_outfit_id = getSelectedOutfitUUID();
|
||||
if (!selected_outfit_id.isNull())
|
||||
{
|
||||
mOutfitLinkPending = selected_outfit_id;
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitGallery::onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture)
|
||||
{
|
||||
mTextureSelected = texture;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "lllayoutstack.h"
|
||||
#include "lloutfitslist.h"
|
||||
#include "llpanelappearancetab.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -106,14 +105,8 @@ public:
|
|||
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);
|
||||
|
|
@ -127,14 +120,10 @@ protected:
|
|||
void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring);
|
||||
|
||||
private:
|
||||
void loadPhotos();
|
||||
void uploadPhoto(LLUUID outfit_id);
|
||||
void uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id);
|
||||
void updateSnapshotFolderObserver();
|
||||
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);
|
||||
|
|
@ -190,8 +179,6 @@ private:
|
|||
|
||||
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;
|
||||
|
|
@ -215,10 +202,7 @@ 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 onThumbnail(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);
|
||||
|
|
@ -236,10 +220,6 @@ public:
|
|||
protected:
|
||||
/*virtual*/ void onUpdateItemsVisibility();
|
||||
private:
|
||||
/*virtual*/ void onUploadFoto();
|
||||
/*virtual*/ void onSelectPhoto();
|
||||
/*virtual*/ void onTakeSnapshot();
|
||||
/*virtual*/ void onRemovePhoto();
|
||||
/*virtual*/ void onChangeSortOrder();
|
||||
|
||||
bool hasDefaultImage();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "llaccordionctrltab.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llagentbenefits.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
|
@ -1255,10 +1255,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
|
|||
|
||||
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
|
||||
|
||||
registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
|
||||
registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this));
|
||||
registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this));
|
||||
registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this));
|
||||
registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this));
|
||||
registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this));
|
||||
|
||||
enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
|
||||
|
|
@ -1375,7 +1372,6 @@ bool LLOutfitListGearMenuBase::onEnable(LLSD::String param)
|
|||
|
||||
bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
|
||||
{
|
||||
getMenu()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
|
||||
const LLUUID& selected_outfit_id = getSelectedOutfitID();
|
||||
if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
|
||||
{
|
||||
|
|
@ -1394,24 +1390,11 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onUploadFoto()
|
||||
void LLOutfitListGearMenuBase::onThumbnail()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onSelectPhoto()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onTakeSnapshot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onRemovePhoto()
|
||||
{
|
||||
|
||||
const LLUUID& selected_outfit_id = getSelectedOutfitID();
|
||||
LLSD data(selected_outfit_id);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
|
||||
void LLOutfitListGearMenuBase::onChangeSortOrder()
|
||||
|
|
@ -1431,10 +1414,7 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
|
|||
if (!mMenu) return;
|
||||
mMenu->setItemVisible("expand", TRUE);
|
||||
mMenu->setItemVisible("collapse", TRUE);
|
||||
mMenu->setItemVisible("upload_photo", FALSE);
|
||||
mMenu->setItemVisible("select_photo", FALSE);
|
||||
mMenu->setItemVisible("take_snapshot", FALSE);
|
||||
mMenu->setItemVisible("remove_photo", FALSE);
|
||||
mMenu->setItemVisible("thumbnail", FALSE); // Never visible?
|
||||
mMenu->setItemVisible("sepatator3", FALSE);
|
||||
mMenu->setItemVisible("sort_folders_by_name", FALSE);
|
||||
LLOutfitListGearMenuBase::onUpdateItemsVisibility();
|
||||
|
|
|
|||
|
|
@ -170,10 +170,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void onUpdateItemsVisibility();
|
||||
virtual void onUploadFoto();
|
||||
virtual void onSelectPhoto();
|
||||
virtual void onTakeSnapshot();
|
||||
virtual void onRemovePhoto();
|
||||
virtual void onThumbnail();
|
||||
virtual void onChangeSortOrder();
|
||||
|
||||
const LLUUID& getSelectedOutfitID();
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llfiltereditor.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llfloaterreg.h"
|
||||
|
|
@ -129,6 +128,8 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
|
|||
mMenuAddHandle(),
|
||||
mNeedUploadCost(true),
|
||||
mMenuViewDefault(NULL),
|
||||
mSingleFolderMode(false),
|
||||
mFolderRootChangedConnection(),
|
||||
mViewMenuButton(nullptr), // <FS:Ansariel> Keep better inventory layout
|
||||
mSearchTypeCombo(NULL) // <FS:Ansariel> Properly initialize this
|
||||
{
|
||||
|
|
@ -176,6 +177,13 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
|
|||
mEnableCallbackRegistrar.add("Inventory.CoalescedObjects.Check", boost::bind(&LLPanelMainInventory::isCoalescedObjectsChecked, this, _2));
|
||||
// </FS:Zi>
|
||||
|
||||
// <FS:Ansariel> Register all callback handlers early
|
||||
mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2));
|
||||
// </FS:Ansariel>
|
||||
|
||||
mSavedFolderState = new LLSaveFolderState();
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
|
||||
|
|
@ -354,6 +362,10 @@ BOOL LLPanelMainInventory::postBuild()
|
|||
//mViewMenuButton = getChild<LLMenuButton>("view_btn");
|
||||
mViewMenuButton = findChild<LLMenuButton>("view_btn");
|
||||
|
||||
mSingleFolderPanelInventory = getChild<LLInventorySingleFolderPanel>("single_folder_inv");
|
||||
mFolderRootChangedConnection = mSingleFolderPanelInventory->setRootChangedCallback(boost::bind(&LLPanelMainInventory::updateTitle, this));
|
||||
mSingleFolderPanelInventory->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mSingleFolderPanelInventory, _1, _2));
|
||||
|
||||
initListCommandsHandlers();
|
||||
const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
|
||||
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
|
||||
|
|
@ -436,6 +448,11 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
|
|||
menu->die();
|
||||
mMenuAddHandle.markDead();
|
||||
}
|
||||
|
||||
if (mFolderRootChangedConnection.connected())
|
||||
{
|
||||
mFolderRootChangedConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel()
|
||||
|
|
@ -511,10 +528,17 @@ void LLPanelMainInventory::closeAllFolders()
|
|||
getPanel()->getRootFolder()->closeAllFolders();
|
||||
}
|
||||
|
||||
S32 get_instance_num()
|
||||
{
|
||||
static S32 instance_num = 0;
|
||||
instance_num = (instance_num + 1) % S32_MAX;
|
||||
|
||||
return instance_num;
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::newWindow()
|
||||
{
|
||||
static S32 instance_num = 0;
|
||||
instance_num = (instance_num + 1) % S32_MAX;
|
||||
S32 instance_num = get_instance_num();
|
||||
|
||||
if (!gAgentCamera.cameraMouselook())
|
||||
{
|
||||
|
|
@ -522,13 +546,48 @@ void LLPanelMainInventory::newWindow()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::newFolderWindow(const LLUUID& folder_id)
|
||||
{
|
||||
S32 instance_num = get_instance_num();
|
||||
|
||||
LLFloaterSidePanelContainer* inventory_container = LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
|
||||
if(inventory_container)
|
||||
{
|
||||
LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true));
|
||||
if (sidepanel_inventory)
|
||||
{
|
||||
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
|
||||
if (main_inventory)
|
||||
{
|
||||
main_inventory->onViewModeClick();
|
||||
if(folder_id.notNull())
|
||||
{
|
||||
main_inventory->setSingleFolderViewRoot(folder_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::doCreate(const LLSD& userdata)
|
||||
{
|
||||
// <FS:Ansariel> FIRE-20108: Can't create new folder in secondary inventory if view is filtered
|
||||
//reset_inventory_filter();
|
||||
onFilterEdit("");
|
||||
// </FS:Ansariel>
|
||||
menu_create_inventory_item(getPanel(), NULL, userdata);
|
||||
if(mSingleFolderMode)
|
||||
{
|
||||
LLFolderViewItem* current_folder = getActivePanel()->getRootFolder();
|
||||
if (current_folder)
|
||||
{
|
||||
LLFolderBridge* bridge = (LLFolderBridge*)current_folder->getViewModelItem();
|
||||
menu_create_inventory_item(getPanel(), bridge, userdata);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_create_inventory_item(getPanel(), NULL, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::resetFilters()
|
||||
|
|
@ -713,7 +772,7 @@ void LLPanelMainInventory::onClearSearch()
|
|||
}
|
||||
|
||||
// re-open folders that were initially open in case filter was active
|
||||
if (mActivePanel && (mFilterSubString.size() || initially_active))
|
||||
if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode)
|
||||
{
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
|
|
@ -724,7 +783,7 @@ void LLPanelMainInventory::onClearSearch()
|
|||
mFilterSubString = "";
|
||||
|
||||
// <FS:Ansariel> FIRE-22509: Only apply inbox filter on primary inventory window
|
||||
//LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
|
||||
//LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory();
|
||||
//if (sidepanel_inventory)
|
||||
//{
|
||||
// LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
|
||||
|
|
@ -798,7 +857,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
|
|||
// </FS:Ansariel> Separate search for inventory tabs from Satomi Ahn (FIRE-913 & FIRE-6862)
|
||||
|
||||
// <FS:Ansariel> FIRE-22509: Only apply inbox filter on primary inventory window
|
||||
//LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
|
||||
//LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory();
|
||||
//if (sidepanel_inventory)
|
||||
//{
|
||||
// LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox");
|
||||
|
|
@ -1629,6 +1688,10 @@ void LLPanelMainInventory::initListCommandsHandlers()
|
|||
{
|
||||
childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this)); // <FS:Ansariel> Keep better inventory layout
|
||||
childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
|
||||
childSetAction("view_mode_btn", boost::bind(&LLPanelMainInventory::onViewModeClick, this));
|
||||
childSetAction("up_btn", boost::bind(&LLPanelMainInventory::onUpFolderClicked, this));
|
||||
childSetAction("back_btn", boost::bind(&LLPanelMainInventory::onBackFolderClicked, this));
|
||||
childSetAction("forward_btn", boost::bind(&LLPanelMainInventory::onForwardFolderClicked, this));
|
||||
|
||||
// <FS:Ansariel> Keep better inventory layout
|
||||
mTrashButton = getChild<LLDragAndDropButton>("trash_btn");
|
||||
|
|
@ -1639,9 +1702,12 @@ void LLPanelMainInventory::initListCommandsHandlers()
|
|||
));
|
||||
// </FS:Ansariel>
|
||||
|
||||
mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
|
||||
// <FS:Ansariel> Moved to constructor to register early
|
||||
//mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
|
||||
//mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
|
||||
//mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
|
||||
//mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2));
|
||||
// </FS:Ansariel>
|
||||
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true);
|
||||
mMenuViewDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_view_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
|
|
@ -1681,6 +1747,64 @@ void LLPanelMainInventory::onAddButtonClick()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::onViewModeClick()
|
||||
{
|
||||
mSingleFolderMode = !mSingleFolderMode;
|
||||
|
||||
getChild<LLPanel>("default_inventory_panel")->setVisible(!mSingleFolderMode);
|
||||
getChild<LLPanel>("single_folder_inventory")->setVisible(mSingleFolderMode);
|
||||
getChild<LLLayoutPanel>("nav_buttons")->setVisible(mSingleFolderMode);
|
||||
getChild<LLButton>("view_mode_btn")->setImageOverlay(mSingleFolderMode ? getString("default_mode_btn") : getString("single_folder_mode_btn"));
|
||||
|
||||
// <FS:Ansariel> Disable Expand/Collapse buttons in single folder mode
|
||||
getChild<LLLayoutPanel>("collapse_expand_buttons")->setVisible(!mSingleFolderMode);
|
||||
|
||||
mActivePanel = mSingleFolderMode ? getChild<LLInventoryPanel>("single_folder_inv") : (LLInventoryPanel*)getChild<LLTabContainer>("inventory filter tabs")->getCurrentPanel();
|
||||
updateTitle();
|
||||
|
||||
LLSidepanelInventory* sidepanel_inventory = getParentSidepanelInventory();
|
||||
if (sidepanel_inventory)
|
||||
{
|
||||
if(mSingleFolderMode)
|
||||
{
|
||||
sidepanel_inventory->hideInbox();
|
||||
}
|
||||
else
|
||||
{
|
||||
sidepanel_inventory->toggleInbox();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::onUpFolderClicked()
|
||||
{
|
||||
const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot());
|
||||
if (cat)
|
||||
{
|
||||
if (cat->getParentUUID().notNull())
|
||||
{
|
||||
mSingleFolderPanelInventory->changeFolderRoot(cat->getParentUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::onBackFolderClicked()
|
||||
{
|
||||
mSingleFolderPanelInventory->onBackwardFolder();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::onForwardFolderClicked()
|
||||
{
|
||||
mSingleFolderPanelInventory->onForwardFolder();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::setSingleFolderViewRoot(const LLUUID& folder_id)
|
||||
{
|
||||
mSingleFolderPanelInventory->changeFolderRoot(folder_id);
|
||||
mSingleFolderPanelInventory->clearNavigationHistory();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
|
||||
{
|
||||
if (menu)
|
||||
|
|
@ -1731,6 +1855,27 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
|
|||
return;
|
||||
|
||||
const std::string command_name = userdata.asString();
|
||||
if (command_name == "new_single_folder_window")
|
||||
{
|
||||
newFolderWindow(LLUUID());
|
||||
}
|
||||
if ((command_name == "open_in_current_window") || (command_name == "open_in_new_window"))
|
||||
{
|
||||
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
|
||||
if (!current_item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const LLUUID& folder_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
|
||||
if((command_name == "open_in_current_window"))
|
||||
{
|
||||
mSingleFolderPanelInventory->changeFolderRoot(folder_id);
|
||||
}
|
||||
if((command_name == "open_in_new_window"))
|
||||
{
|
||||
newFolderWindow(folder_id);
|
||||
}
|
||||
}
|
||||
if (command_name == "new_window")
|
||||
{
|
||||
newWindow();
|
||||
|
|
@ -2003,6 +2148,33 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool LLPanelMainInventory::isActionVisible(const LLSD& userdata)
|
||||
{
|
||||
const std::string param_str = userdata.asString();
|
||||
if (param_str == "single_folder_view")
|
||||
{
|
||||
return mSingleFolderMode;
|
||||
}
|
||||
if (param_str == "multi_folder_view")
|
||||
{
|
||||
return !mSingleFolderMode;
|
||||
}
|
||||
if (param_str == "open_folder" || param_str == "open_new_folder")
|
||||
{
|
||||
if (!mSingleFolderMode && (param_str == "open_folder")) return false;
|
||||
|
||||
LLFolderView* root = getActivePanel()->getRootFolder();
|
||||
std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
|
||||
if (selection_set.size() != 1) return false;
|
||||
|
||||
LLFolderViewItem* current_item = *selection_set.begin();
|
||||
if (!current_item) return false;
|
||||
const LLUUID& folder_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
|
||||
return (gInventory.getCategory(folder_id) != NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
|
||||
{
|
||||
U32 sort_order_mask = getActivePanel()->getSortOrder();
|
||||
|
|
@ -2047,6 +2219,19 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
|
|||
return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;
|
||||
}
|
||||
|
||||
if (command_name == "list_view")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (command_name == "gallery_view")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (command_name == "combination_view")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (command_name == "add_objects_on_double_click")
|
||||
{
|
||||
return gSavedSettings.getBOOL("FSDoubleClickAddInventoryObjects");
|
||||
|
|
@ -2267,5 +2452,34 @@ bool LLPanelMainInventory::hasSettingsInventory()
|
|||
return LLEnvironment::instance().isInventoryEnabled();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::updateTitle()
|
||||
{
|
||||
LLFloater* inventory_floater = gFloaterView->getParentFloater(this);
|
||||
if(inventory_floater)
|
||||
{
|
||||
if(mSingleFolderMode)
|
||||
{
|
||||
const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot());
|
||||
if (cat)
|
||||
{
|
||||
inventory_floater->setTitle(cat->getName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory_floater->setTitle(getString("inventory_title"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLSidepanelInventory* LLPanelMainInventory::getParentSidepanelInventory()
|
||||
{
|
||||
LLFloaterSidePanelContainer* inventory_container = dynamic_cast<LLFloaterSidePanelContainer*>(gFloaterView->getParentFloater(this));
|
||||
if(inventory_container)
|
||||
{
|
||||
return dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
// List Commands //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llpanel.h"
|
||||
#include "llinventoryfilter.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "lldndbutton.h"
|
||||
|
||||
#include "llfolderview.h"
|
||||
|
|
@ -44,6 +45,7 @@ class LLTabContainer;
|
|||
class LLFloaterInventoryFinder;
|
||||
class LLMenuButton;
|
||||
class LLMenuGL;
|
||||
class LLSidepanelInventory;
|
||||
class LLToggleableMenu;
|
||||
class LLFloater;
|
||||
class LLComboBox; // <FS:Zi> Filter dropdown
|
||||
|
|
@ -99,10 +101,17 @@ public:
|
|||
void setFocusFilterEditor();
|
||||
|
||||
static void newWindow();
|
||||
static void newFolderWindow(const LLUUID& folder_id);
|
||||
|
||||
void toggleFindOptions();
|
||||
|
||||
void resetFilters();
|
||||
void onViewModeClick();
|
||||
void onUpFolderClicked();
|
||||
void onBackFolderClicked();
|
||||
void onForwardFolderClicked();
|
||||
void setSingleFolderViewRoot(const LLUUID& folder_id);
|
||||
bool isSingleFolderMode() { return mSingleFolderMode; }
|
||||
|
||||
// <FS:Zi> Filter dropdown
|
||||
void onFilterTypeSelected(const std::string& filter_type_name);
|
||||
|
|
@ -156,6 +165,8 @@ protected:
|
|||
void onSelectSearchType();
|
||||
void updateSearchTypeCombo();
|
||||
|
||||
LLSidepanelInventory* getParentSidepanelInventory();
|
||||
|
||||
private:
|
||||
LLFloaterInventoryFinder* getFinder();
|
||||
|
||||
|
|
@ -175,12 +186,16 @@ private:
|
|||
std::string mCategoryCountString;
|
||||
LLComboBox* mSearchTypeCombo;
|
||||
|
||||
bool mSingleFolderMode;
|
||||
LLInventorySingleFolderPanel* mSingleFolderPanelInventory;
|
||||
|
||||
// <FS:Zi> Filter dropdown
|
||||
LLComboBox* mFilterComboBox;
|
||||
std::map<std::string,U64> mFilterMap; // contains name-to-number mapping for dropdown filter types
|
||||
U64 mFilterMask; // contains the cumulated bit filter for all dropdown filter types
|
||||
// </FS:Zi> Filter dropdown
|
||||
|
||||
boost::signals2::connection mFolderRootChangedConnection;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// List Commands //
|
||||
|
|
@ -194,6 +209,7 @@ protected:
|
|||
BOOL isActionEnabled(const LLSD& command_name);
|
||||
BOOL isActionChecked(const LLSD& userdata);
|
||||
void onCustomAction(const LLSD& command_name);
|
||||
bool isActionVisible(const LLSD& userdata);
|
||||
|
||||
// <FS:Zi> FIRE-31369: Add inventory filter for coalesced objects
|
||||
void onCoalescedObjectsToggled(const LLSD& userdata);
|
||||
|
|
@ -218,6 +234,7 @@ protected:
|
|||
// <FS:Ansariel> Keep better inventory layout
|
||||
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
|
||||
static bool hasSettingsInventory();
|
||||
void updateTitle();
|
||||
/**
|
||||
* Set upload cost in "Upload" sub menu.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ public:
|
|||
virtual BOOL canOpenItem() const { return FALSE; }
|
||||
virtual void closeItem() {}
|
||||
virtual void selectItem() {}
|
||||
virtual void navigateToFolder() {}
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual BOOL isItemMovable() const;
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri
|
|||
httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
LL_WARNS("AvatarProperties") << result << LL_ENDL;
|
||||
LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
|
||||
|
||||
if (!status)
|
||||
{
|
||||
|
|
@ -1904,15 +1904,20 @@ void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
|
|||
const S32 MAX_DIM = 256;
|
||||
if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
|
||||
{
|
||||
//todo: image not supported notification
|
||||
LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
|
||||
LLSD notif_args;
|
||||
notif_args["REASON"] = LLImage::getLastError().c_str();
|
||||
LLNotificationsUtil::add("CannotUploadTexture", notif_args);
|
||||
LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)mType << ", " << notif_args["REASON"].asString() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
|
||||
if (cap_url.empty())
|
||||
{
|
||||
LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
|
||||
LLSD args;
|
||||
args["CAPABILITY"] = PROFILE_IMAGE_UPLOAD_CAP;
|
||||
LLNotificationsUtil::add("RegionCapabilityRequestError", args);
|
||||
LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)mType << ", no cap found" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ LLSidepanelInventory::LLSidepanelInventory()
|
|||
, mInboxEnabled(false)
|
||||
, mCategoriesObserver(NULL)
|
||||
, mInboxAddedObserver(NULL)
|
||||
, mInboxLayoutPanel(NULL)
|
||||
{
|
||||
//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
|
||||
}
|
||||
|
|
@ -134,14 +135,12 @@ LLSidepanelInventory::LLSidepanelInventory()
|
|||
LLSidepanelInventory::~LLSidepanelInventory()
|
||||
{
|
||||
// <FS:Ansariel> FIRE-17603: Received Items button sometimes vanishing
|
||||
//LLLayoutPanel* inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
LLLayoutPanel* inbox_layout_panel = findChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
if (inbox_layout_panel)
|
||||
if (mInboxLayoutPanel)
|
||||
{
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Save the InventoryMainPanelHeight in settings per account
|
||||
gSavedPerAccountSettings.setS32("InventoryInboxHeight", inbox_layout_panel->getTargetDim());
|
||||
gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->getTargetDim());
|
||||
// <FS:Ansariel> FIRE-17603: Received Items button sometimes vanishing
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
|
@ -209,11 +208,11 @@ BOOL LLSidepanelInventory::postBuild()
|
|||
bool is_inbox_collapsed = !inbox_button->getToggleState();
|
||||
|
||||
// Restore the collapsed inbox panel state
|
||||
LLLayoutPanel* inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
inv_stack->collapsePanel(inbox_panel, is_inbox_collapsed);
|
||||
mInboxLayoutPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
inv_stack->collapsePanel(mInboxLayoutPanel, is_inbox_collapsed);
|
||||
if (!is_inbox_collapsed)
|
||||
{
|
||||
inbox_panel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
|
||||
mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
|
||||
}
|
||||
|
||||
// Set the inbox visible based on debug settings (final setting comes from http request below)
|
||||
|
|
@ -329,16 +328,29 @@ void LLSidepanelInventory::enableInbox(bool enabled)
|
|||
{
|
||||
mInboxEnabled = enabled;
|
||||
|
||||
LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
if(!enabled || !mPanelMainInventory->isSingleFolderMode())
|
||||
{
|
||||
toggleInbox();
|
||||
}
|
||||
}
|
||||
|
||||
void LLSidepanelInventory::hideInbox()
|
||||
{
|
||||
if (mInboxLayoutPanel) // <FS:Ansariel> Inbox panel randomly shown on secondary inventory window
|
||||
mInboxLayoutPanel->setVisible(false);
|
||||
}
|
||||
|
||||
void LLSidepanelInventory::toggleInbox()
|
||||
{
|
||||
// <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
|
||||
//inbox_layout_panel->setVisible(enabled);
|
||||
inbox_layout_panel->setVisible(enabled && (!gSavedSettings.getBOOL("FSShowInboxFolder") || gSavedSettings.getBOOL("FSAlwaysShowInboxButton"))
|
||||
//mInboxLayoutPanel->setVisible(mInboxEnabled);
|
||||
if (mInboxLayoutPanel)
|
||||
mInboxLayoutPanel->setVisible(mInboxEnabled && (!gSavedSettings.getBOOL("FSShowInboxFolder") || gSavedSettings.getBOOL("FSAlwaysShowInboxButton"))
|
||||
// <FS:CR> Show Received Items panel only in Second Life
|
||||
#ifdef OPENSIM
|
||||
&& LLGridManager::getInstance()->isInSecondLife()
|
||||
#endif // OPENSIM
|
||||
);
|
||||
// </FS:CR>
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
|
||||
|
|
@ -375,25 +387,24 @@ void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
|
|||
void LLSidepanelInventory::onToggleInboxBtn()
|
||||
{
|
||||
LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
|
||||
LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
|
||||
LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
|
||||
|
||||
const bool inbox_expanded = inboxButton->getToggleState();
|
||||
|
||||
// Expand/collapse the indicated panel
|
||||
inv_stack->collapsePanel(inboxPanel, !inbox_expanded);
|
||||
inv_stack->collapsePanel(mInboxLayoutPanel, !inbox_expanded);
|
||||
|
||||
if (inbox_expanded)
|
||||
{
|
||||
inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
|
||||
if (inboxPanel->isInVisibleChain())
|
||||
mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
|
||||
if (mInboxLayoutPanel->isInVisibleChain())
|
||||
{
|
||||
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
|
||||
gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->getTargetDim());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ public:
|
|||
void onToggleInboxBtn();
|
||||
|
||||
void enableInbox(bool enabled);
|
||||
void toggleInbox();
|
||||
void hideInbox();
|
||||
|
||||
// <FS:Ansariel> Optional hiding of Received Items folder aka Inbox
|
||||
void refreshInboxVisibility();
|
||||
|
|
@ -104,6 +106,8 @@ private:
|
|||
LLHandle<LLInventoryPanel> mInventoryPanelInbox;
|
||||
LLPanelMainInventory* mPanelMainInventory;
|
||||
|
||||
LLLayoutPanel* mInboxLayoutPanel;
|
||||
|
||||
protected:
|
||||
public:
|
||||
void onBackButtonClicked();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llcallbacklist.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llgroupactions.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "lliconctrl.h"
|
||||
|
|
@ -163,6 +164,8 @@ BOOL LLSidepanelItemInfo::postBuild()
|
|||
getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
|
||||
getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this));
|
||||
getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this));
|
||||
// Thumnail edition
|
||||
getChild<LLUICtrl>("change_thumbnail_btn")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onEditThumbnail, this));
|
||||
// acquired date
|
||||
// owner permissions
|
||||
// Permissions debug text
|
||||
|
|
@ -800,7 +803,7 @@ void LLSidepanelItemInfo::changed(U32 mask)
|
|||
const LLUUID& item_id = getItemID();
|
||||
if (getObjectID().notNull() || item_id.isNull())
|
||||
{
|
||||
// Tasl inventory or not set up yet
|
||||
// Task inventory or not set up yet
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1087,7 +1090,14 @@ void LLSidepanelItemInfo::updatePermissions()
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSidepanelItemInfo::onEditThumbnail()
|
||||
{
|
||||
LLSD data;
|
||||
data["task_id"] = mObjectID;
|
||||
data["item_id"] = mItemID;
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
|
||||
void LLSidepanelItemInfo::onCommitSaleInfo(LLUICtrl* ctrl)
|
||||
{
|
||||
if (ctrl)
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ protected:
|
|||
void onCommitDescription();
|
||||
void onCommitPermissions(LLUICtrl* ctrl);
|
||||
void updatePermissions();
|
||||
void onEditThumbnail();
|
||||
void onCommitSaleInfo(LLUICtrl* ctrl);
|
||||
void updateSaleInfo();
|
||||
void onCommitChanges(LLPointer<LLViewerInventoryItem> item);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "llviewermenufile.h" // upload_new_resource()
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llwindow.h"
|
||||
#include "llworld.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
|
@ -986,6 +987,31 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
|
|||
return mPreviewImageEncoded;
|
||||
}
|
||||
|
||||
bool LLSnapshotLivePreview::createUploadFile(const std::string &out_filename, const S32 max_image_dimentions)
|
||||
{
|
||||
// make a copy, since convertToUploadFile modifies raw image
|
||||
LLPointer<LLImageRaw> raw_image = new LLImageRaw(
|
||||
mPreviewImage->getData(),
|
||||
mPreviewImage->getWidth(),
|
||||
mPreviewImage->getHeight(),
|
||||
mPreviewImage->getComponents());
|
||||
|
||||
LLPointer<LLImageJ2C> compressedImage = LLViewerTextureList::convertToUploadFile(raw_image, max_image_dimentions);
|
||||
if (compressedImage.isNull())
|
||||
{
|
||||
compressedImage->setLastError("Couldn't convert the image to jpeg2000.");
|
||||
LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (!compressedImage->save(out_filename))
|
||||
{
|
||||
compressedImage->setLastError("Couldn't create the jpeg2000 image for upload.");
|
||||
LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// We actually estimate the data size so that we do not require actual compression when showing the preview
|
||||
// Note : whenever formatted image is computed, mDataSize will be updated to reflect the true size
|
||||
void LLSnapshotLivePreview::estimateDataSize()
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ public:
|
|||
|
||||
LLPointer<LLImageFormatted> getFormattedImage();
|
||||
LLPointer<LLImageRaw> getEncodedImage();
|
||||
bool createUploadFile(const std::string &out_file, const S32 max_image_dimentions);
|
||||
|
||||
/// Sets size of preview thumbnail image and the surrounding rect.
|
||||
void setThumbnailPlaceholderRect(const LLRect& rect) {mThumbnailPlaceholderRect = rect; }
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "llfloaterbvhpreview.h"
|
||||
#include "llfloatercamera.h"
|
||||
#include "llfloatercamerapresets.h"
|
||||
#include "llfloaterchangeitemthumbnail.h"
|
||||
#include "llfloaterchatvoicevolume.h"
|
||||
#include "llfloaterclassified.h"
|
||||
#include "llfloaterconversationlog.h"
|
||||
|
|
@ -103,7 +104,7 @@
|
|||
#include "llfloaterobjectweights.h"
|
||||
#include "llfloateropenobject.h"
|
||||
#include "llfloateroutfitphotopreview.h"
|
||||
#include "llfloatersimpleoutfitsnapshot.h"
|
||||
#include "llfloatersimplesnapshot.h"
|
||||
#include "llfloaterpathfindingcharacters.h"
|
||||
#include "llfloaterpathfindingconsole.h"
|
||||
#include "llfloaterpathfindinglinksets.h"
|
||||
|
|
@ -396,6 +397,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("fs_camera_small", "floater_fs_camera_small.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
|
||||
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
|
||||
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
|
||||
LLFloaterReg::add("change_item_thumbnail", "floater_change_item_thumbnail.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChangeItemThumbnail>);
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
//LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
|
||||
LLFloaterReg::add("fs_nearby_chat", "floater_fs_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterNearbyChat>);
|
||||
|
|
@ -564,7 +566,7 @@ 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("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>);
|
||||
LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>);
|
||||
// <FS:CR> Search floater is deferred to login now so we can tell what grid we're in.
|
||||
//LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
|
||||
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
|
||||
|
|
|
|||
|
|
@ -12549,6 +12549,7 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new FSResetMeshLOD(), "Avatar.ResetMeshLOD");
|
||||
|
||||
commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow));
|
||||
commit.add("Inventory.NewFolderWindow", boost::bind(&LLPanelMainInventory::newFolderWindow, LLUUID()));
|
||||
|
||||
enable.add("EnablePayObject", boost::bind(&enable_pay_object));
|
||||
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
#include "llfloatermap.h"
|
||||
#include "llfloatermodelpreview.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llfloatersimpleoutfitsnapshot.h"
|
||||
#include "llfloatersimplesnapshot.h"
|
||||
#include "llimage.h"
|
||||
#include "llimagebmp.h"
|
||||
#include "llimagepng.h"
|
||||
|
|
@ -744,9 +744,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
|
|||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
|
||||
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
|
||||
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
|
||||
|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
|
||||
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain());
|
||||
bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
|
||||
return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown();
|
||||
}
|
||||
|
|
@ -761,9 +759,6 @@ class LLFileCloseAllWindows : public view_listener_t
|
|||
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
|
||||
if (floater_snapshot)
|
||||
floater_snapshot->closeFloater(app_quitting);
|
||||
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
|
||||
if (floater_outfit_snapshot)
|
||||
floater_outfit_snapshot->closeFloater(app_quitting);
|
||||
if (gMenuHolder) gMenuHolder->hideMenus();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3258,6 +3258,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
|
||||
capabilityNames.append("InterestList");
|
||||
|
||||
capabilityNames.append("InventoryCategoryThumbnailUpload");
|
||||
capabilityNames.append("InventoryItemThumbnailUpload");
|
||||
capabilityNames.append("GetDisplayNames");
|
||||
capabilityNames.append("GetExperiences");
|
||||
capabilityNames.append("AgentExperiences");
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
name="ItemcountUnknown">
|
||||
Fetched [ITEM_COUNT] Elements [FILTER]
|
||||
</panel.string>
|
||||
<panel.string name="inventory_title">Inventory</panel.string>
|
||||
<panel.string name="default_mode_btn">Multi_Folder_Mode</panel.string>
|
||||
<panel.string name="single_folder_mode_btn">Single_Folder_Mode</panel.string>
|
||||
|
||||
<menu_bar
|
||||
follows="left|top"
|
||||
|
|
@ -76,6 +79,53 @@
|
|||
function="Floater.Toggle"
|
||||
parameter="fs_protectedfolders" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_separator>
|
||||
<menu_item_check
|
||||
label="List view"
|
||||
layout="topleft"
|
||||
name="list_view">
|
||||
<menu_item_check.on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="list_view" />
|
||||
<menu_item_check.on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="list_view" />
|
||||
<menu_item_check.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Gallery view"
|
||||
layout="topleft"
|
||||
name="gallery_view">
|
||||
<menu_item_check.on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="gallery_view" />
|
||||
<menu_item_check.on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="gallery_view" />
|
||||
<menu_item_check.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Combination view"
|
||||
layout="topleft"
|
||||
name="combination_view">
|
||||
<menu_item_check.on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="combination_view" />
|
||||
<menu_item_check.on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="combination_view" />
|
||||
<menu_item_check.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator />
|
||||
<menu_item_check
|
||||
label="Add objects on double click"
|
||||
|
|
@ -115,13 +165,23 @@
|
|||
label="Close All Folders">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.CloseAllFolders" />
|
||||
<menu_item_call.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_separator>
|
||||
<menu_item_call
|
||||
name="inventory_empty_trash"
|
||||
label="Empty Trash">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.EmptyTrash" />
|
||||
<menu_item_call.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
|
||||
|
|
@ -363,6 +423,9 @@
|
|||
<on_check
|
||||
function="Inventory.SortBy.Check"
|
||||
parameter="systemfolderstotop" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
|
||||
|
|
@ -498,167 +561,304 @@
|
|||
</menu>
|
||||
</menu_bar>
|
||||
|
||||
|
||||
<filter_editor
|
||||
text_pad_left="4"
|
||||
<layout_stack
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Filter Inventory"
|
||||
layout="topleft"
|
||||
height="25"
|
||||
animate="false"
|
||||
top_pad="0"
|
||||
left="4"
|
||||
max_length_chars="300"
|
||||
highlight_text_field="true"
|
||||
name="inventory search editor"
|
||||
tool_tip="Type in one or more words to search for, separated by '+' "
|
||||
top_pad="4"
|
||||
right="-6" />
|
||||
|
||||
<button
|
||||
name="collapse_btn"
|
||||
image_overlay="MinusItem_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
left="4"
|
||||
top_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft"/>
|
||||
|
||||
<button
|
||||
name="expand_btn"
|
||||
image_overlay="AddItem_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
left_pad="2"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
<text
|
||||
name="filter_label"
|
||||
value="Filter:"
|
||||
width="40"
|
||||
height="18"
|
||||
left_pad="4"
|
||||
top_delta="2"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
<combo_box
|
||||
name="filter_combo_box"
|
||||
right="-79"
|
||||
height="18"
|
||||
left_pad="4"
|
||||
top_delta="-2"
|
||||
follows="top|left|right"
|
||||
layout="topleft">
|
||||
|
||||
<combo_box.item value="filter_type_all" label="All Types" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_animations" label="Animations" />
|
||||
<combo_box.item value="filter_type_calling_cards" label="Calling Cards" />
|
||||
<combo_box.item value="filter_type_clothing" label="Clothing / Body Parts" />
|
||||
<combo_box.item value="filter_type_gestures" label="Gestures" />
|
||||
<combo_box.item value="filter_type_landmarks" label="Landmarks" />
|
||||
<combo_box.item value="filter_type_notecards" label="Notecards" />
|
||||
<combo_box.item value="filter_type_objects" label="Objects" />
|
||||
<combo_box.item value="filter_type_scripts" label="Scripts" />
|
||||
<combo_box.item value="filter_type_sounds" label="Sounds" />
|
||||
<combo_box.item value="filter_type_textures" label="Textures" />
|
||||
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
|
||||
<combo_box.item value="filter_type_meshes" label="Meshes" />
|
||||
<combo_box.item value="filter_type_settings" label="Settings" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_custom" label="Custom..." />
|
||||
</combo_box>
|
||||
|
||||
<button
|
||||
commit_callback.function="Inventory.ShowFilters"
|
||||
name="filteroptions_btn"
|
||||
image_overlay="Script_Config"
|
||||
width="18"
|
||||
height="18"
|
||||
right="-59"
|
||||
top_delta="0"
|
||||
follows="top|right"
|
||||
layout="topleft"/>
|
||||
|
||||
<menu_button
|
||||
follows="top|right"
|
||||
tool_tip="Show search visibility options"
|
||||
height="18"
|
||||
image_overlay="Inv_Toolbar_SearchVisibility"
|
||||
layout="topleft"
|
||||
right="-26"
|
||||
top_delta="0"
|
||||
name="options_visibility_btn"
|
||||
width="31" />
|
||||
|
||||
<button
|
||||
commit_callback.function="Inventory.ResetFilters"
|
||||
name="resetfilters_btn"
|
||||
image_overlay="StopReload_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
right="-6"
|
||||
top_delta="0"
|
||||
follows="top|right"
|
||||
layout="topleft"/>
|
||||
|
||||
<tab_container
|
||||
bg_alpha_color="DkGray"
|
||||
bg_opaque_color="DkGray"
|
||||
background_visible="false"
|
||||
background_opaque="false"
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="322"
|
||||
layout="topleft"
|
||||
left="2"
|
||||
name="inventory filter tabs"
|
||||
open_tabs_on_drag_and_drop="true"
|
||||
tab_group="1"
|
||||
tab_position="top"
|
||||
top_pad="4"
|
||||
width="326">
|
||||
<inventory_panel
|
||||
right="-5"
|
||||
name="nav_stack"
|
||||
orientation="horizontal">
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
auto_resize="false"
|
||||
height="25"
|
||||
width="62"
|
||||
name="nav_buttons"
|
||||
visible="false">
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Back"
|
||||
image_pressed="Single_Folder_Back"
|
||||
image_unselected="Single_Folder_Back"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="2"
|
||||
name="back_btn"
|
||||
tool_tip="Back"
|
||||
width="20" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Forward"
|
||||
image_pressed="Single_Folder_Forward"
|
||||
image_unselected="Single_Folder_Forward"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="forward_btn"
|
||||
tool_tip="Forward"
|
||||
width="20" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Up"
|
||||
image_pressed="Single_Folder_Up"
|
||||
image_unselected="Single_Folder_Up"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="up_btn"
|
||||
tool_tip="Go up one level"
|
||||
width="20" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
height="25"
|
||||
width="324"
|
||||
name="filter_panel"
|
||||
visible="true">
|
||||
<filter_editor
|
||||
text_pad_left="4"
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Filter Inventory"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
max_length_chars="300"
|
||||
highlight_text_field="true"
|
||||
name="inventory search editor"
|
||||
tool_tip="Type in one or more words to search for, separated by '+' "
|
||||
top_pad="0"
|
||||
right="-1" />
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
<layout_stack
|
||||
follows="left|top|right"
|
||||
height="18"
|
||||
animate="false"
|
||||
top_pad="0"
|
||||
left="4"
|
||||
right="-5"
|
||||
name="ctrl_stack"
|
||||
orientation="horizontal">
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
auto_resize="false"
|
||||
height="18"
|
||||
width="38"
|
||||
name="collapse_expand_buttons">
|
||||
|
||||
<button
|
||||
name="collapse_btn"
|
||||
image_overlay="MinusItem_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
left="0"
|
||||
top="0"
|
||||
follows="top|left"
|
||||
layout="topleft"/>
|
||||
|
||||
<button
|
||||
name="expand_btn"
|
||||
image_overlay="AddItem_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
left_pad="2"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
height="18"
|
||||
width="200"
|
||||
name="filter_ctrls">
|
||||
|
||||
<text
|
||||
name="filter_label"
|
||||
value="Filter:"
|
||||
width="40"
|
||||
height="18"
|
||||
left="2"
|
||||
top="2"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
<combo_box
|
||||
name="filter_combo_box"
|
||||
right="-75"
|
||||
height="18"
|
||||
left_pad="4"
|
||||
top_delta="-2"
|
||||
follows="top|left|right"
|
||||
layout="topleft">
|
||||
<combo_box.item value="filter_type_all" label="All Types" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_animations" label="Animations" />
|
||||
<combo_box.item value="filter_type_calling_cards" label="Calling Cards" />
|
||||
<combo_box.item value="filter_type_clothing" label="Clothing / Body Parts" />
|
||||
<combo_box.item value="filter_type_gestures" label="Gestures" />
|
||||
<combo_box.item value="filter_type_landmarks" label="Landmarks" />
|
||||
<combo_box.item value="filter_type_notecards" label="Notecards" />
|
||||
<combo_box.item value="filter_type_objects" label="Objects" />
|
||||
<combo_box.item value="filter_type_scripts" label="Scripts" />
|
||||
<combo_box.item value="filter_type_sounds" label="Sounds" />
|
||||
<combo_box.item value="filter_type_textures" label="Textures" />
|
||||
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
|
||||
<combo_box.item value="filter_type_meshes" label="Meshes" />
|
||||
<combo_box.item value="filter_type_settings" label="Settings" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_custom" label="Custom..." />
|
||||
</combo_box>
|
||||
|
||||
<button
|
||||
commit_callback.function="Inventory.ShowFilters"
|
||||
name="filteroptions_btn"
|
||||
image_overlay="Script_Config"
|
||||
width="18"
|
||||
height="18"
|
||||
right="-54"
|
||||
top_delta="0"
|
||||
follows="top|right"
|
||||
layout="topleft"/>
|
||||
|
||||
<menu_button
|
||||
follows="top|right"
|
||||
tool_tip="Show search visibility options"
|
||||
height="18"
|
||||
image_overlay="Inv_Toolbar_SearchVisibility"
|
||||
layout="topleft"
|
||||
right="-21"
|
||||
top_delta="0"
|
||||
name="options_visibility_btn"
|
||||
width="31" />
|
||||
|
||||
<button
|
||||
commit_callback.function="Inventory.ResetFilters"
|
||||
name="resetfilters_btn"
|
||||
image_overlay="StopReload_Off"
|
||||
width="18"
|
||||
height="18"
|
||||
right="-1"
|
||||
top_delta="0"
|
||||
follows="top|right"
|
||||
layout="topleft"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
<panel
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="319"
|
||||
layout="topleft"
|
||||
left="2"
|
||||
name="default_inventory_panel"
|
||||
top_pad="4"
|
||||
width="326">
|
||||
<tab_container
|
||||
bg_alpha_color="DkGray"
|
||||
bg_opaque_color="DkGray"
|
||||
background_visible="false"
|
||||
background_opaque="false"
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="319"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="inventory filter tabs"
|
||||
open_tabs_on_drag_and_drop="true"
|
||||
tab_group="1"
|
||||
tab_position="top"
|
||||
top="0"
|
||||
width="326">
|
||||
<inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Inventory"
|
||||
help_topic="my_inventory_tab"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="All Items"
|
||||
sort_order_setting="InventorySortOrder"
|
||||
show_item_link_overlays="true"
|
||||
top="16"
|
||||
width="288"
|
||||
scroll.reserve_scroll_corner="false"/>
|
||||
<recent_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Recent"
|
||||
sort_order_setting="RecentItemsSortOrder"
|
||||
help_topic="recent_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Recent Items"
|
||||
show_item_link_overlays="true"
|
||||
width="288"
|
||||
scroll.reserve_scroll_corner="false"/>
|
||||
<worn_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Worn"
|
||||
help_topic="worn_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Worn Items"
|
||||
show_item_link_overlays="true"
|
||||
width="288"
|
||||
scroll.reserve_scroll_corner="false"/>
|
||||
</tab_container>
|
||||
</panel>
|
||||
<panel
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="319"
|
||||
layout="topleft"
|
||||
left="2"
|
||||
name="single_folder_inventory"
|
||||
top_delta="0"
|
||||
visible="false"
|
||||
width="326">
|
||||
<single_folder_inventory_panel
|
||||
name="single_folder_inv"
|
||||
show_empty_message="false"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Inventory"
|
||||
help_topic="my_inventory_tab"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="All Items"
|
||||
sort_order_setting="InventorySortOrder"
|
||||
show_item_link_overlays="true"
|
||||
top="16"
|
||||
width="288" />
|
||||
<recent_inventory_panel
|
||||
top="0"
|
||||
top_pad="5"
|
||||
height="319"
|
||||
width="324"
|
||||
layout="topleft"
|
||||
background_visible="true"
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Recent"
|
||||
sort_order_setting="RecentItemsSortOrder"
|
||||
help_topic="recent_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Recent Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
<worn_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Worn"
|
||||
help_topic="worn_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Worn Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
</tab_container>
|
||||
scroll.reserve_scroll_corner="false">
|
||||
<item folder_indentation="0"/>
|
||||
<folder
|
||||
single_folder_mode="true"
|
||||
folder_indentation="0"/>
|
||||
</single_folder_inventory_panel>
|
||||
</panel>
|
||||
<panel
|
||||
follows="left|right|bottom"
|
||||
height="25"
|
||||
|
|
@ -721,10 +921,10 @@
|
|||
<button
|
||||
follows="top|left"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_hover_unselected="Toolbar_Left_Over"
|
||||
image_overlay="inventory_18"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
image_selected="Toolbar_Left_Selected"
|
||||
image_unselected="Toolbar_Left_Off"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="new_inv_btn"
|
||||
|
|
@ -736,6 +936,27 @@
|
|||
parameter="secondary_inventory" />
|
||||
</button>
|
||||
</panel>
|
||||
<panel
|
||||
follows="top|left"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_pad="0"
|
||||
name="view_mode_panel"
|
||||
width="32">
|
||||
<button
|
||||
follows="top|left"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Single_Folder_Mode"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="view_mode_btn"
|
||||
tool_tip="Switch between views"
|
||||
top="0"
|
||||
width="31"/>
|
||||
</panel>
|
||||
<panel
|
||||
follows="top|left|right"
|
||||
height="25"
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -275,10 +275,16 @@ with the same filename but different name
|
|||
<texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" />
|
||||
<texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" />
|
||||
<texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Copy" file_name="icons/copy_clipboard.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Delete" file_name="icons/delete_icon.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" />
|
||||
<texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" />
|
||||
|
||||
<texture name="Icon_File_Upload" file_name="icons/file_upload.png" preload="true" />
|
||||
|
||||
<texture name="Icon_For_Sale" file_name="icons/Icon_For_Sale.png" preload="false" />
|
||||
|
||||
<texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" />
|
||||
|
|
@ -291,10 +297,16 @@ with the same filename but different name
|
|||
|
||||
<texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" />
|
||||
<texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Paste" file_name="icons/paste_clipboard.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" />
|
||||
<texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" />
|
||||
|
||||
<texture name="Icon_Snapshot" file_name="icons/snapshot_icon.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Use_Texture" file_name="icons/texture_icon.png" preload="true" />
|
||||
|
||||
<texture name="Icon_Snooze_Foreground" file_name="windows/Icon_Snooze_Foreground.png" preload="false" />
|
||||
<texture name="Icon_Snooze_Press" file_name="windows/Icon_Snooze_Press.png" preload="false" />
|
||||
|
||||
|
|
@ -1048,6 +1060,12 @@ with the same filename but different name
|
|||
<texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
|
||||
<texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png" preload="true"/>
|
||||
<texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png" preload="true"/>
|
||||
|
||||
<texture name="Single_Folder_Mode" file_name="icons/single_folder_mode.png" preload="true"/>
|
||||
<texture name="Multi_Folder_Mode" file_name="icons/multi_folder_mode.png" preload="true"/>
|
||||
<texture name="Single_Folder_Back" file_name="icons/single_folder_back.png" preload="true"/>
|
||||
<texture name="Single_Folder_Forward" file_name="icons/single_folder_forward.png" preload="true"/>
|
||||
<texture name="Single_Folder_Up" file_name="icons/single_folder_up.png" preload="true"/>
|
||||
|
||||
<!-- StarLight Textures -->
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
can_resize="false"
|
||||
height="366"
|
||||
layout="topleft"
|
||||
name="change_item_thumbnail"
|
||||
help_topic="change_item_thumbnail"
|
||||
title="Change Item Image"
|
||||
width="319">
|
||||
|
||||
<floater.string
|
||||
name="tooltip_upload_local">
|
||||
Upload from computer
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="tooltip_upload_snapshot">
|
||||
Use snapshot tool
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="tooltip_use_texture">
|
||||
Choose texture
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="tooltip_copy_to_clipboard">
|
||||
Copy to clipboard
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="tooltip_paste_from_clipboard">
|
||||
Paste from clipboard
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="tooltip_remove_image">
|
||||
Remove image
|
||||
</floater.string>
|
||||
|
||||
<icon
|
||||
follows="top|left"
|
||||
height="16"
|
||||
image_name="Inv_Object"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
mouse_opaque="true"
|
||||
name="item_type_icon"
|
||||
top="4"
|
||||
width="16" />
|
||||
<text
|
||||
follows="left|top|right"
|
||||
font="SansSerif"
|
||||
height="19"
|
||||
layout="topleft"
|
||||
top_delta="1"
|
||||
left_pad="3"
|
||||
max_length_bytes="127"
|
||||
name="item_name"
|
||||
width="286"/>
|
||||
|
||||
<thumbnail
|
||||
name="item_thumbnail"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
left="32"
|
||||
top_pad="9"
|
||||
height="256"
|
||||
width="256"
|
||||
/>
|
||||
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_File_Upload"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="upload_local"
|
||||
left="38"
|
||||
top_pad="9"
|
||||
height="32"
|
||||
width="32" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_Snapshot"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="upload_snapshot"
|
||||
left_pad="10"
|
||||
top_delta="0"
|
||||
height="32"
|
||||
width="32" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_Use_Texture"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="use_texture"
|
||||
left_pad="10"
|
||||
top_delta="0"
|
||||
height="32"
|
||||
width="32" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_Copy"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="copy_to_clipboard"
|
||||
left_pad="10"
|
||||
top_delta="0"
|
||||
height="32"
|
||||
width="32" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_Paste"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="paste_from_clipboard"
|
||||
left_pad="10"
|
||||
top_delta="0"
|
||||
height="32"
|
||||
width="32" />
|
||||
<button
|
||||
follows="right|bottom"
|
||||
layout="topleft"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Icon_Delete"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
name="remove_image"
|
||||
left_pad="10"
|
||||
top_delta="0"
|
||||
height="32"
|
||||
width="32" />
|
||||
|
||||
<text
|
||||
type="string"
|
||||
halign="center"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="17"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
right="-5"
|
||||
name="tooltip_text"
|
||||
top_pad="12"
|
||||
width="78">
|
||||
tooltip
|
||||
</text>
|
||||
|
||||
</floater>
|
||||
|
|
@ -2,17 +2,17 @@
|
|||
<floater
|
||||
positioning="cascading"
|
||||
legacy_header_height="18"
|
||||
can_minimize="true"
|
||||
can_minimize="false"
|
||||
can_resize="false"
|
||||
can_close="true"
|
||||
height="305"
|
||||
layout="topleft"
|
||||
name="simple_outfit_snapshot"
|
||||
single_instance="true"
|
||||
name="simple_snapshot"
|
||||
single_instance="false"
|
||||
help_topic="snapshot"
|
||||
save_rect="true"
|
||||
save_visibility="false"
|
||||
title="Outfit Snapshot"
|
||||
title="Item Snapshot"
|
||||
width="351">
|
||||
<ui_ctrl
|
||||
layout="topleft"
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
height="22"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
label="Save (L$[UPLOAD_COST])"
|
||||
label="Save"
|
||||
name="save_btn"
|
||||
width="90" />
|
||||
<button
|
||||
|
|
@ -42,35 +42,11 @@
|
|||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Upload Photo (L$[UPLOAD_COST])"
|
||||
layout="topleft"
|
||||
name="upload_photo">
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<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" />
|
||||
function="Outfit.Thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<menu
|
||||
|
|
|
|||
|
|
@ -612,6 +612,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Protect"
|
||||
layout="topleft"
|
||||
|
|
@ -628,6 +636,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="unprotect_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Reload Folder"
|
||||
layout="topleft"
|
||||
name="ReloadFolder">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="reload_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Copy Asset UUID"
|
||||
layout="topleft"
|
||||
|
|
@ -636,6 +652,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="copy_uuid" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Restore to Last Position"
|
||||
layout="topleft"
|
||||
name="Restore to Last Position">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="restoreToWorld" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Show in Main View"
|
||||
layout="topleft"
|
||||
|
|
@ -652,25 +676,26 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="show_in_new_window" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Reload Folder"
|
||||
layout="topleft"
|
||||
name="ReloadFolder">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="reload_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Restore to Last Position"
|
||||
layout="topleft"
|
||||
name="Restore to Last Position">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="restoreToWorld" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Copy Separator" />
|
||||
<menu_item_call
|
||||
label="Open"
|
||||
layout="topleft"
|
||||
name="open_in_current_window">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.OpenSelectedFolder"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open in new window"
|
||||
layout="topleft"
|
||||
name="open_in_new_window">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.OpenNewFolderWindow"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Open Folder Separator" />
|
||||
<menu_item_call
|
||||
label="Copy"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -6,15 +6,36 @@
|
|||
mouse_opaque="false"
|
||||
name="menu_gear_default"
|
||||
visible="false">
|
||||
<menu_item_call
|
||||
label="Open"
|
||||
layout="topleft"
|
||||
name="open_in_current_window">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="open_in_current_window" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="open_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open in new window"
|
||||
layout="topleft"
|
||||
name="open_in_new_window">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="open_in_new_window" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="open_new_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Folder Window"
|
||||
layout="topleft"
|
||||
shortcut="control|shift|J"
|
||||
enabled="false"
|
||||
name="new_single_folder">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="new_window" />
|
||||
parameter="new_single_folder_window" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Inventory Window"
|
||||
|
|
@ -35,6 +56,53 @@
|
|||
function="Floater.Toggle"
|
||||
parameter="fs_protectedfolders" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_separator>
|
||||
<menu_item_check
|
||||
label="List view"
|
||||
layout="topleft"
|
||||
name="list_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="list_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="list_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Gallery view"
|
||||
layout="topleft"
|
||||
name="gallery_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="gallery_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="gallery_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Combination view"
|
||||
layout="topleft"
|
||||
name="combination_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="combination_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="combination_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
<menu_item_check
|
||||
|
|
@ -80,6 +148,9 @@
|
|||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="sort_system_folders_to_top" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
|
|
@ -192,9 +263,15 @@
|
|||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="close_folders" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_separator>
|
||||
<menu_item_call
|
||||
label="Empty Lost and Found"
|
||||
layout="topleft"
|
||||
|
|
@ -205,6 +282,9 @@
|
|||
<on_enable
|
||||
function="Inventory.GearDefault.Enable"
|
||||
parameter="empty_lostnfound" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
|
|
@ -342,7 +422,11 @@
|
|||
function="Inventory.CoalescedObjects.Check"
|
||||
parameter="coalesced_objects_only" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator />
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_separator>
|
||||
<!-- </FS:Zi> -->
|
||||
|
||||
<menu_item_call
|
||||
|
|
@ -355,5 +439,8 @@
|
|||
<on_enable
|
||||
function="Inventory.GearDefault.Enable"
|
||||
parameter="empty_trash" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_call>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -49,5 +49,64 @@
|
|||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="sort_system_folders_to_top" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="multi_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator>
|
||||
<menu_item_separator.on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_separator>
|
||||
<menu_item_check
|
||||
label="List view"
|
||||
layout="topleft"
|
||||
name="list_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="list_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="list_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Gallery view"
|
||||
layout="topleft"
|
||||
name="gallery_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="gallery_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="gallery_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Combination view"
|
||||
layout="topleft"
|
||||
name="combination_view">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="combination_view" />
|
||||
<on_check
|
||||
function="Inventory.GearDefault.Check"
|
||||
parameter="combination_view" />
|
||||
<on_visible
|
||||
function="Inventory.GearDefault.Visible"
|
||||
parameter="single_folder_view" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator/>
|
||||
<menu_item_call
|
||||
label="Inventory settings..."
|
||||
layout="topleft"
|
||||
name="inv_settings">
|
||||
<on_click
|
||||
function="Inventory.GearDefault.Custom.Action"
|
||||
parameter="inv_settings" />
|
||||
</menu_item_call>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -40,32 +40,11 @@
|
|||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Upload Photo (L$[UPLOAD_COST])"
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="upload_photo">
|
||||
name="thumbnail">
|
||||
<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" />
|
||||
function="Gear.Thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="sepatator1" />
|
||||
<!-- copied (with minor modifications) from menu_inventory_add.xml -->
|
||||
|
|
|
|||
|
|
@ -69,6 +69,15 @@
|
|||
function="Inventory.NewWindow"
|
||||
parameter="" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Folder Window"
|
||||
name="new_single_folder"
|
||||
shortcut="control|shift|J"
|
||||
visible="false">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.NewFolderWindow"
|
||||
parameter="" />
|
||||
</menu_item_call>
|
||||
<menu_item_check
|
||||
label="Protected Folders"
|
||||
name="Protected Folders">
|
||||
|
|
|
|||
|
|
@ -6403,7 +6403,21 @@ Are you sure you want to delete them?
|
|||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="DeleteThumbnail"
|
||||
type="alertmodal">
|
||||
<unique/>
|
||||
Delete the image for this item? There is no undo.
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
ignoretext="Confirm before deleting a thumbnail."
|
||||
name="okcancelignore"
|
||||
notext="Cancel"
|
||||
yestext="Delete"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ConfirmUnlink"
|
||||
|
|
|
|||
|
|
@ -23,140 +23,277 @@
|
|||
name="ItemcountUnknown">
|
||||
Fetched [ITEM_COUNT] Elements [FILTER]
|
||||
</panel.string>
|
||||
<filter_editor
|
||||
text_pad_left="10"
|
||||
<panel.string name="inventory_title">Inventory</panel.string>
|
||||
<panel.string name="default_mode_btn">Multi_Folder_Mode</panel.string>
|
||||
<panel.string name="single_folder_mode_btn">Single_Folder_Mode</panel.string>
|
||||
|
||||
<layout_stack
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Filter Inventory"
|
||||
layout="topleft"
|
||||
height="25"
|
||||
animate="false"
|
||||
top_pad="4"
|
||||
left="10"
|
||||
max_length_chars="300"
|
||||
highlight_text_field="true"
|
||||
name="inventory search editor"
|
||||
tool_tip="Type in one or more words to search for, separated by '+' "
|
||||
top_pad="4"
|
||||
width="322" />
|
||||
name="nav_stack"
|
||||
orientation="horizontal">
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
auto_resize="false"
|
||||
height="25"
|
||||
width="62"
|
||||
name="nav_buttons"
|
||||
visible="false">
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Back"
|
||||
image_pressed="Single_Folder_Back"
|
||||
image_unselected="Single_Folder_Back"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="2"
|
||||
name="back_btn"
|
||||
tool_tip="Back"
|
||||
width="20" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Forward"
|
||||
image_pressed="Single_Folder_Forward"
|
||||
image_unselected="Single_Folder_Forward"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="forward_btn"
|
||||
tool_tip="Forward"
|
||||
width="20" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="23"
|
||||
image_selected="Single_Folder_Up"
|
||||
image_pressed="Single_Folder_Up"
|
||||
image_unselected="Single_Folder_Up"
|
||||
scale_image="false"
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
name="up_btn"
|
||||
tool_tip="Go up one level"
|
||||
width="20" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
height="25"
|
||||
width="324"
|
||||
name="filter_panel"
|
||||
visible="true">
|
||||
<filter_editor
|
||||
text_pad_left="10"
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
label="Filter Inventory"
|
||||
layout="topleft"
|
||||
left="2"
|
||||
max_length_chars="300"
|
||||
highlight_text_field="true"
|
||||
name="inventory search editor"
|
||||
tool_tip="Type in one or more words to search for, separated by '+' "
|
||||
top="0"
|
||||
width="322" />
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
<button
|
||||
name="collapse_btn"
|
||||
label="Collapse"
|
||||
width="80"
|
||||
<layout_stack
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
animate="false"
|
||||
top_pad="4"
|
||||
left="4"
|
||||
top_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft"/>
|
||||
name="ctrl_stack"
|
||||
orientation="horizontal">
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
auto_resize="false"
|
||||
height="16"
|
||||
width="168"
|
||||
name="collapse_expand_buttons">
|
||||
<button
|
||||
name="collapse_btn"
|
||||
label="Collapse"
|
||||
width="80"
|
||||
height="16"
|
||||
left="0"
|
||||
top="0"
|
||||
follows="top|left"
|
||||
layout="topleft"/>
|
||||
|
||||
<button
|
||||
name="expand_btn"
|
||||
label="Expand"
|
||||
width="80"
|
||||
height="16"
|
||||
left_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
<button
|
||||
name="expand_btn"
|
||||
label="Expand"
|
||||
width="80"
|
||||
height="16"
|
||||
left_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
<text
|
||||
name="filter_label"
|
||||
value="Filter:"
|
||||
width="40"
|
||||
height="16"
|
||||
left_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
border="false"
|
||||
bevel_style="in"
|
||||
user_resize="false"
|
||||
height="16"
|
||||
width="164"
|
||||
name="filter_ctrls">
|
||||
|
||||
<combo_box
|
||||
name="filter_combo_box"
|
||||
width="80"
|
||||
height="16"
|
||||
left_pad="4"
|
||||
follows="top|left"
|
||||
layout="topleft">
|
||||
<text
|
||||
name="filter_label"
|
||||
value="Filter:"
|
||||
width="40"
|
||||
height="16"
|
||||
left="0"
|
||||
top="0"
|
||||
follows="top|left"
|
||||
layout="topleft" />
|
||||
|
||||
<combo_box.item value="filter_type_all" label="All Types" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_animations" label="Animations" />
|
||||
<combo_box.item value="filter_type_calling_cards" label="Calling Cards" />
|
||||
<combo_box.item value="filter_type_clothing" label="Clothing / Body Parts" />
|
||||
<combo_box.item value="filter_type_gestures" label="Gestures" />
|
||||
<combo_box.item value="filter_type_landmarks" label="Landmarks" />
|
||||
<combo_box.item value="filter_type_notecards" label="Notecards" />
|
||||
<combo_box.item value="filter_type_objects" label="Objects" />
|
||||
<combo_box.item value="filter_type_scripts" label="Scripts" />
|
||||
<combo_box.item value="filter_type_sounds" label="Sounds" />
|
||||
<combo_box.item value="filter_type_textures" label="Textures" />
|
||||
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
|
||||
<combo_box.item value="filter_type_meshes" label="Meshes" />
|
||||
<combo_box.item value="filter_type_settings" label="Settings" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_custom" label="Custom..." />
|
||||
<combo_box
|
||||
name="filter_combo_box"
|
||||
right="-35"
|
||||
height="16"
|
||||
left_pad="4"
|
||||
follows="top|left|right"
|
||||
layout="topleft">
|
||||
<combo_box.item value="filter_type_all" label="All Types" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_animations" label="Animations" />
|
||||
<combo_box.item value="filter_type_calling_cards" label="Calling Cards" />
|
||||
<combo_box.item value="filter_type_clothing" label="Clothing / Body Parts" />
|
||||
<combo_box.item value="filter_type_gestures" label="Gestures" />
|
||||
<combo_box.item value="filter_type_landmarks" label="Landmarks" />
|
||||
<combo_box.item value="filter_type_notecards" label="Notecards" />
|
||||
<combo_box.item value="filter_type_objects" label="Objects" />
|
||||
<combo_box.item value="filter_type_scripts" label="Scripts" />
|
||||
<combo_box.item value="filter_type_sounds" label="Sounds" />
|
||||
<combo_box.item value="filter_type_textures" label="Textures" />
|
||||
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
|
||||
<combo_box.item value="filter_type_meshes" label="Meshes" />
|
||||
<combo_box.item value="filter_type_settings" label="Settings" />
|
||||
<combo_box.item value="filter_separator" label="------------" enabled="false" />
|
||||
<combo_box.item value="filter_type_custom" label="Custom..." />
|
||||
</combo_box>
|
||||
|
||||
</combo_box>
|
||||
<menu_button
|
||||
follows="top|left"
|
||||
tool_tip="Show search visibility options"
|
||||
height="16"
|
||||
image_overlay="Inv_Toolbar_SearchVisibility"
|
||||
<menu_button
|
||||
follows="top|right"
|
||||
tool_tip="Show search visibility options"
|
||||
height="16"
|
||||
image_overlay="Inv_Toolbar_SearchVisibility"
|
||||
layout="topleft"
|
||||
right="-1"
|
||||
top_delta="0"
|
||||
name="options_visibility_btn"
|
||||
width="31" />
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
<panel
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="338"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
name="options_visibility_btn"
|
||||
width="31" />
|
||||
|
||||
<tab_container
|
||||
bg_alpha_color="DkGray"
|
||||
bg_opaque_color="DkGray"
|
||||
background_visible="false"
|
||||
background_opaque="false"
|
||||
left="4"
|
||||
name="default_inventory_panel"
|
||||
top_pad="4"
|
||||
width="322">
|
||||
<tab_container
|
||||
bg_alpha_color="DkGray"
|
||||
bg_opaque_color="DkGray"
|
||||
background_visible="false"
|
||||
background_opaque="false"
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="338"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="inventory filter tabs"
|
||||
open_tabs_on_drag_and_drop="true"
|
||||
tab_position="top"
|
||||
top="0"
|
||||
width="322">
|
||||
<inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Inventory"
|
||||
help_topic="my_inventory_tab"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="All Items"
|
||||
sort_order_setting="InventorySortOrder"
|
||||
show_item_link_overlays="true"
|
||||
top="16"
|
||||
width="288" />
|
||||
<recent_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Recent"
|
||||
sort_order_setting="RecentItemsSortOrder"
|
||||
help_topic="recent_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Recent Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
<worn_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Worn"
|
||||
help_topic="worn_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Worn Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
</tab_container>
|
||||
</panel>
|
||||
<panel
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="338"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="single_folder_inventory"
|
||||
top_delta="0"
|
||||
visible="false"
|
||||
width="322">
|
||||
<single_folder_inventory_panel
|
||||
name="single_folder_inv"
|
||||
show_empty_message="false"
|
||||
follows="all"
|
||||
halign="center"
|
||||
height="340"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="inventory filter tabs"
|
||||
open_tabs_on_drag_and_drop="true"
|
||||
tab_position="top"
|
||||
top_pad="4"
|
||||
width="322">
|
||||
<inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Inventory"
|
||||
help_topic="my_inventory_tab"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="All Items"
|
||||
sort_order_setting="InventorySortOrder"
|
||||
show_item_link_overlays="true"
|
||||
top="16"
|
||||
width="288" />
|
||||
<recent_inventory_panel
|
||||
top="0"
|
||||
top_pad="5"
|
||||
height="338"
|
||||
width="322"
|
||||
layout="topleft"
|
||||
background_visible="true"
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Recent"
|
||||
sort_order_setting="RecentItemsSortOrder"
|
||||
help_topic="recent_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Recent Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
<worn_inventory_panel
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="all"
|
||||
height="338"
|
||||
label="Worn"
|
||||
help_topic="worn_inventory_tab"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="Worn Items"
|
||||
show_item_link_overlays="true"
|
||||
width="290" />
|
||||
</tab_container>
|
||||
scroll.reserve_scroll_corner="false">
|
||||
<item folder_indentation="0"/>
|
||||
<folder
|
||||
single_folder_mode="true"
|
||||
folder_indentation="0"/>
|
||||
</single_folder_inventory_panel>
|
||||
</panel>
|
||||
<panel
|
||||
follows="left|right|bottom"
|
||||
height="25"
|
||||
|
|
@ -232,6 +369,27 @@
|
|||
parameter="secondary_inventory" />
|
||||
</button>
|
||||
</panel>
|
||||
<panel
|
||||
follows="top|left"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_pad="0"
|
||||
name="view_mode_panel"
|
||||
width="32">
|
||||
<button
|
||||
follows="top|left"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="Single_Folder_Mode"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="view_mode_btn"
|
||||
tool_tip="Switch between views"
|
||||
top="0"
|
||||
width="31"/>
|
||||
</panel>
|
||||
<panel
|
||||
follows="top|left|right"
|
||||
height="25"
|
||||
|
|
|
|||
|
|
@ -89,14 +89,14 @@
|
|||
name="layout_item_details"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
height="130">
|
||||
height="133">
|
||||
|
||||
<thumbnail
|
||||
name="item_thumbnail"
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
top="0"
|
||||
top="2"
|
||||
height="128"
|
||||
width="128"
|
||||
/>
|
||||
|
|
@ -105,7 +105,7 @@
|
|||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="17"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
name="LabelOwnerTitle"
|
||||
|
|
@ -131,7 +131,7 @@ TestString PleaseIgnore
|
|||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="17"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="LabelCreatorTitle"
|
||||
|
|
@ -157,7 +157,7 @@ TestString PleaseIgnore
|
|||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="17"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="LabelAcquiredTitle"
|
||||
|
|
@ -169,13 +169,23 @@ TestString PleaseIgnore
|
|||
type="string"
|
||||
length="1"
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="LabelAcquiredDate"
|
||||
top_pad="0"
|
||||
width="187">
|
||||
00/00/00
|
||||
</text>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="21"
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="change_thumbnail_btn"
|
||||
top_pad="0"
|
||||
width="120" />
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel
|
||||
|
|
|
|||
|
|
@ -3256,7 +3256,7 @@ Your current position: [AVATAR_POS]
|
|||
<string name="Yes">Yes</string>
|
||||
<string name="No">No</string>
|
||||
<string name="FSUrlEntryWearLabel">Wear inventory folder</string>
|
||||
<string name="TexturePickerOutfitHeader">Picture for Outfit</string>
|
||||
<string name="TexturePickerOutfitHeader">Item Snapshot</string>
|
||||
<string name="unknown_script">(Unknown script)</string>
|
||||
<string name="FSAreaSearch_Cost_Label">L$[COST]</string>
|
||||
|
||||
|
|
|
|||