summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llstring.cpp9
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm5
-rw-r--r--indra/media_plugins/webkit/CMakeLists.txt10
-rw-r--r--indra/media_plugins/webkit/linux_volume_catcher.cpp5
-rw-r--r--indra/media_plugins/webkit/media_plugin_webkit.cpp24
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/Info-SecondLife.plist48
-rw-r--r--indra/newview/llagent.cpp8
-rw-r--r--indra/newview/llagentwearablesfetch.cpp28
-rw-r--r--indra/newview/llfloaterbuyland.cpp1
-rw-r--r--indra/newview/llinventoryitemslist.cpp337
-rw-r--r--indra/newview/llinventoryitemslist.h180
-rw-r--r--indra/newview/llinventorylistitem.cpp400
-rw-r--r--indra/newview/llinventorylistitem.h235
-rw-r--r--indra/newview/llpaneloutfitedit.cpp11
-rw-r--r--indra/newview/llpaneloutfitedit.h2
-rw-r--r--indra/newview/llstartup.h2
-rw-r--r--indra/newview/llwearableitemslist.cpp31
-rw-r--r--indra/newview/llwearableitemslist.h8
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_wearable.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_scrolling_param.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml18
23 files changed, 801 insertions, 575 deletions
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f14d947734..1561bda201 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -994,7 +994,14 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
convertToS32 (decimals, intDecimals);
if (!sLocale.empty())
{
- strStream.imbue (std::locale(sLocale.c_str()));
+ // std::locale() throws if the locale is unknown! (EXT-7926)
+ try
+ {
+ strStream.imbue(std::locale(sLocale.c_str()));
+ } catch (const std::exception &)
+ {
+ LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL;
+ }
}
if (!intDecimals)
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 59b25e1726..3a822a93a6 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -49,6 +49,11 @@ void setupCocoa()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
+ // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+ // when init'ing the Cocoa App window.
+ [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
+
// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
// http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
index 1a559ed39c..d576638dd7 100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -50,8 +50,10 @@ set(media_plugin_webkit_LINK_LIBRARIES
)
# Select which VolumeCatcher implementation to use
-if (LINUX AND PULSEAUDIO)
- list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
+if (LINUX)
+ if (PULSEAUDIO)
+ list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
+ endif (PULSEAUDIO)
list(APPEND media_plugin_webkit_LINK_LIBRARIES
${UI_LIBRARIES} # for glib/GTK
)
@@ -65,10 +67,10 @@ elseif (DARWIN)
)
elseif (WINDOWS)
list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp)
-else (LINUX AND PULSEAUDIO)
+else (LINUX)
# All other platforms use the dummy volume catcher for now.
list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp)
-endif (LINUX AND PULSEAUDIO)
+endif (LINUX)
set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
index 2e7fda865e..5eaef0e1c3 100644
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp
@@ -47,6 +47,7 @@
extern "C" {
#include <glib.h>
+#include <glib-object.h>
#include <pulse/introspect.h>
#include <pulse/context.h>
@@ -220,6 +221,10 @@ void VolumeCatcherImpl::init()
mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
if (!mGotSyms) return;
+ // better make double-sure glib itself is initialized properly.
+ if (!g_thread_supported ()) g_thread_init (NULL);
+ g_type_init();
+
mMainloop = llpa_glib_mainloop_new(g_main_context_default());
if (mMainloop)
{
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index 6990354486..3b00edec4e 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -46,6 +46,10 @@
// set to 1 if you're using the version of llqtwebkit that's QPixmap-ified
#if LL_LINUX
# define LL_QTWEBKIT_USES_PIXMAPS 0
+extern "C" {
+# include <glib.h>
+# include <glib-object.h>
+}
#else
# define LL_QTWEBKIT_USES_PIXMAPS 0
#endif // LL_LINUX
@@ -60,7 +64,7 @@
#endif
#if LL_WINDOWS
- // *NOTE:Mani - This captures the module handle fo rthe dll. This is used below
+ // *NOTE:Mani - This captures the module handle for the dll. This is used below
// to get the path to this dll for webkit initialization.
// I don't know how/if this can be done with apr...
namespace { HMODULE gModuleHandle;};
@@ -129,6 +133,16 @@ private:
//
void update(int milliseconds)
{
+#if LL_QTLINUX_DOESNT_HAVE_GLIB
+ // pump glib generously, as Linux browser plugins are on the
+ // glib main loop, even if the browser itself isn't - ugh
+ // This is NOT NEEDED if Qt itself was built with glib
+ // mainloop integration.
+ GMainContext *mainc = g_main_context_default();
+ while(g_main_context_iteration(mainc, FALSE));
+#endif // LL_QTLINUX_DOESNT_HAVE_GLIB
+
+ // pump qt
LLQtWebKit::getInstance()->pump( milliseconds );
mVolumeCatcher.pump();
@@ -200,6 +214,14 @@ private:
}
std::string application_dir = std::string( cwd );
+#if LL_LINUX
+ // take care to initialize glib properly, because some
+ // versions of Qt don't, and we indirectly need it for (some
+ // versions of) Flash to not crash the browser.
+ if (!g_thread_supported ()) g_thread_init (NULL);
+ g_type_init();
+#endif
+
#if LL_DARWIN
// When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on.
// This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger.
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 24811db3cb..c1b2d680be 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -260,6 +260,7 @@ set(viewer_SOURCE_FILES
llinventoryfunctions.cpp
llinventoryicon.cpp
llinventoryitemslist.cpp
+ llinventorylistitem.cpp
llinventorymodel.cpp
llinventorymodelbackgroundfetch.cpp
llinventoryobserver.cpp
@@ -783,6 +784,7 @@ set(viewer_HEADER_FILES
llinventoryfunctions.h
llinventoryicon.h
llinventoryitemslist.h
+ llinventorylistitem.h
llinventorymodel.h
llinventorymodelbackgroundfetch.h
llinventoryobserver.h
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 97e24a0bd5..9bc95f9b95 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
@@ -18,33 +18,33 @@
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
- <key>CFBundleDocumentTypes</key>
- <array>
- <dict>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>slurl</string>
- </array>
- <key>CFBundleTypeIconFile</key>
- <string>seconlife</string>
- <key>CFBundleTypeMIMETypes</key>
- <array>
- <string>application/x-grid-location-info</string>
- </array>
- <key>CFBundleTypeName</key>
- <string>Secondlife SLURL</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>slurl</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>seconlife</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/x-grid-location-info</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Secondlife SLURL</string>
<key>CFBundleTypeOSTypes</key>
<array>
- <string>SLRL</string>
+ <string>SLRL</string>
</array>
- <key>CFBundleTypeRole</key>
- <string>Viewer</string>
- <key>LSTypeIsPackage</key>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSTypeIsPackage</key>
<true/>
- <key>NSDocumentClass</key>
- <string>SecondLifeSLURL</string>
- </dict>
- </array>
+ <key>NSDocumentClass</key>
+ <string>SecondLifeSLURL</string>
+ </dict>
+ </array>
<key>CFBundleURLTypes</key>
<array>
<dict>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 03efcadc98..217fb0f988 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -57,6 +57,7 @@
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
#include "llnearbychatbar.h"
#include "llnotificationsutil.h"
+#include "llpaneltopinfobar.h"
#include "llparcel.h"
#include "llrendersphere.h"
#include "llsdutil.h"
@@ -1693,6 +1694,11 @@ void LLAgent::endAnimationUpdateUI()
LLNavigationBar::getInstance()->setVisible(TRUE);
gStatusBar->setVisibleForMouselook(true);
+ if (gSavedSettings.getBOOL("ShowMiniLocationPanel"))
+ {
+ LLPanelTopInfoBar::getInstance()->setVisible(TRUE);
+ }
+
LLBottomTray::getInstance()->onMouselookModeOut();
LLSideTray::getInstance()->getButtonsPanel()->setVisible(TRUE);
@@ -1791,6 +1797,8 @@ void LLAgent::endAnimationUpdateUI()
LLNavigationBar::getInstance()->setVisible(FALSE);
gStatusBar->setVisibleForMouselook(false);
+ LLPanelTopInfoBar::getInstance()->setVisible(FALSE);
+
LLBottomTray::getInstance()->onMouselookModeIn();
LLSideTray::getInstance()->getButtonsPanel()->setVisible(FALSE);
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 931aba1d41..0a2f0e9399 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -48,6 +48,12 @@ public:
virtual ~LLOrderMyOutfitsOnDestroy()
{
+ if (LLApp::isExiting())
+ {
+ llwarns << "called during shutdown, skipping" << llendl;
+ return;
+ }
+
const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if (my_outfits_id.isNull()) return;
@@ -241,6 +247,8 @@ LLLibraryOutfitsFetch::LLLibraryOutfitsFetch(const LLUUID& my_outfits_id) :
mCurrFetchStep(LOFS_FOLDER),
mOutfitsPopulated(false)
{
+ llinfos << "created" << llendl;
+
mMyOutfitsID = LLUUID::null;
mClothingID = LLUUID::null;
mLibraryClothingID = LLUUID::null;
@@ -250,10 +258,13 @@ LLLibraryOutfitsFetch::LLLibraryOutfitsFetch(const LLUUID& my_outfits_id) :
LLLibraryOutfitsFetch::~LLLibraryOutfitsFetch()
{
+ llinfos << "destroyed" << llendl;
}
void LLLibraryOutfitsFetch::done()
{
+ llinfos << "start" << llendl;
+
// Delay this until idle() routine, since it's a heavy operation and
// we also can't have it run within notifyObservers.
doOnIdleOneTime(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this));
@@ -262,6 +273,8 @@ void LLLibraryOutfitsFetch::done()
void LLLibraryOutfitsFetch::doneIdle()
{
+ llinfos << "start" << llendl;
+
gInventory.addObserver(this); // Add this back in since it was taken out during ::done()
switch (mCurrFetchStep)
@@ -302,6 +315,8 @@ void LLLibraryOutfitsFetch::doneIdle()
void LLLibraryOutfitsFetch::folderDone()
{
+ llinfos << "start" << llendl;
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,
@@ -309,8 +324,7 @@ void LLLibraryOutfitsFetch::folderDone()
// Early out if we already have items in My Outfits
// except the case when My Outfits contains just initial outfit
- if (cat_array.count() > 1 ||
- cat_array.count() == 1 && cat_array[0]->getUUID() != LLAppearanceMgr::getInstance()->getBaseOutfitUUID())
+ if (cat_array.count() > 1)
{
mOutfitsPopulated = true;
return;
@@ -348,6 +362,8 @@ void LLLibraryOutfitsFetch::folderDone()
void LLLibraryOutfitsFetch::outfitsDone()
{
+ llinfos << "start" << llendl;
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
uuid_vec_t folders;
@@ -425,6 +441,8 @@ private:
// Copy the clothing folders from the library into the imported clothing folder
void LLLibraryOutfitsFetch::libraryDone()
{
+ llinfos << "start" << llendl;
+
if (mImportedClothingID != LLUUID::null)
{
// Skip straight to fetching the contents of the imported folder
@@ -480,6 +498,8 @@ void LLLibraryOutfitsFetch::libraryDone()
void LLLibraryOutfitsFetch::importedFolderFetch()
{
+ llinfos << "start" << llendl;
+
// Fetch the contents of the Imported Clothing Folder
uuid_vec_t folders;
folders.push_back(mImportedClothingID);
@@ -495,6 +515,8 @@ void LLLibraryOutfitsFetch::importedFolderFetch()
void LLLibraryOutfitsFetch::importedFolderDone()
{
+ llinfos << "start" << llendl;
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
uuid_vec_t folders;
@@ -525,6 +547,8 @@ void LLLibraryOutfitsFetch::importedFolderDone()
void LLLibraryOutfitsFetch::contentsDone()
{
+ llinfos << "start" << llendl;
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 7ca7ace0fc..9379b3f5a8 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -668,6 +668,7 @@ void LLFloaterBuyLandUI::updateWebSiteInfo()
keywordArgs.appendString(
"secureSessionId",
gAgent.getSecureSessionID().asString());
+ keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendInt("billableArea", mPreflightAskBillableArea);
keywordArgs.appendInt("currencyBuy", mPreflightAskCurrencyBuy);
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 14de5442d6..fbb3774917 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -3,8 +3,6 @@
* @brief A list of inventory items represented by LLFlatListView.
*
* Class LLInventoryItemsList implements a flat list of inventory items.
- * Class LLPanelInventoryListItem displays inventory item as an element
- * of LLInventoryItemsList.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
@@ -40,341 +38,12 @@
// llcommon
#include "llcommonutils.h"
-// llui
-#include "lliconctrl.h"
-#include "lltextutil.h"
+#include "lltrans.h"
#include "llcallbacklist.h"
-#include "llinventoryfunctions.h"
+#include "llinventorylistitem.h"
#include "llinventorymodel.h"
-#include "lltrans.h"
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-static const S32 WIDGET_SPACING = 3;
-
-LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
-{
- LLPanelInventoryListItemBase* list_item = NULL;
- if (item)
- {
- list_item = new LLPanelInventoryListItemBase(item);
- list_item->init();
- }
- return list_item;
-}
-
-void LLPanelInventoryListItemBase::draw()
-{
- if (getNeedsRefresh())
- {
- if (mItem)
- {
- updateItem(mItem->getName());
- }
- setNeedsRefresh(false);
- }
- LLPanel::draw();
-}
-
-// virtual
-void LLPanelInventoryListItemBase::updateItem(const std::string& name,
- const LLStyle::Params& input_params)
-{
- setIconImage(mIconImage);
- setTitle(name, mHighlightedText, input_params);
-}
-
-void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
-{
- LLUICtrl* ctrl = findChild<LLUICtrl>(name);
- if(ctrl)
- {
- addWidgetToLeftSide(ctrl, show_widget);
- }
-}
-
-void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
-{
- mLeftSideWidgets.push_back(ctrl);
- setShowWidget(ctrl, show_widget);
-}
-
-void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/)
-{
- LLUICtrl* ctrl = findChild<LLUICtrl>(name);
- if(ctrl)
- {
- addWidgetToRightSide(ctrl, show_widget);
- }
-}
-
-void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
-{
- mRightSideWidgets.push_back(ctrl);
- setShowWidget(ctrl, show_widget);
-}
-
-void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show)
-{
- LLUICtrl* widget = findChild<LLUICtrl>(name);
- if(widget)
- {
- setShowWidget(widget, show);
- }
-}
-
-void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
-{
- // Enable state determines whether widget may become visible in setWidgetsVisible()
- ctrl->setEnabled(show);
-}
-
-BOOL LLPanelInventoryListItemBase::postBuild()
-{
- setIconCtrl(getChild<LLIconCtrl>("item_icon"));
- setTitleCtrl(getChild<LLTextBox>("item_name"));
-
- if (mItem)
- {
- mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
- updateItem(mItem->getName());
- }
-
- setNeedsRefresh(true);
-
- setWidgetsVisible(false);
- reshapeWidgets();
-
- return TRUE;
-}
-
-void LLPanelInventoryListItemBase::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;
- if (!value.has("selected")) return;
- childSetVisible("selected_icon", value["selected"]);
-}
-
-void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
-{
- childSetVisible("hovered_icon", true);
- LLPanel::onMouseEnter(x, y, mask);
-}
-
-void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- childSetVisible("hovered_icon", false);
- LLPanel::onMouseLeave(x, y, mask);
-}
-
-const std::string& LLPanelInventoryListItemBase::getItemName() const
-{
- if (!mItem)
- {
- return LLStringUtil::null;
- }
- return mItem->getName();
-}
-
-LLAssetType::EType LLPanelInventoryListItemBase::getType() const
-{
- if (!mItem)
- {
- return LLAssetType::AT_NONE;
- }
- return mItem->getType();
-}
-
-LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const
-{
- if (!mItem)
- {
- return LLWearableType::WT_NONE;
- }
- return mItem->getWearableType();
-}
-
-const std::string& LLPanelInventoryListItemBase::getDescription() const
-{
- if (!mItem)
- {
- return LLStringUtil::null;
- }
- return mItem->getDescription();
-}
-
-S32 LLPanelInventoryListItemBase::notify(const LLSD& info)
-{
- S32 rv = 0;
- if(info.has("match_filter"))
- {
- mHighlightedText = info["match_filter"].asString();
-
- std::string test(mTitleCtrl->getText());
- LLStringUtil::toUpper(test);
-
- if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText))
- {
- rv = 0; // substring is found
- }
- else
- {
- rv = -1;
- }
-
- setNeedsRefresh(true);
- }
- else
- {
- rv = LLPanel::notify(info);
- }
- return rv;
-}
-
-LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
-: LLPanel()
-, mItem(item)
-, mIconCtrl(NULL)
-, mTitleCtrl(NULL)
-, mWidgetSpacing(WIDGET_SPACING)
-, mLeftWidgetsWidth(0)
-, mRightWidgetsWidth(0)
-, mNeedsRefresh(false)
-{
-}
-
-void LLPanelInventoryListItemBase::init()
-{
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
-}
-
-class WidgetVisibilityChanger
-{
-public:
- WidgetVisibilityChanger(bool visible) : mVisible(visible){}
- void operator()(LLUICtrl* widget)
- {
- // Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget()
- widget->setVisible(mVisible && widget->getEnabled());
- }
-private:
- bool mVisible;
-};
-
-void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
-{
- std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
- std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
-}
-
-void LLPanelInventoryListItemBase::reshapeWidgets()
-{
- // disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
- /*reshapeLeftWidgets();*/
- reshapeRightWidgets();
- reshapeMiddleWidgets();
-}
-
-void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
-{
- if(image)
- {
- mIconImage = image;
- mIconCtrl->setImage(mIconImage);
- }
-}
-
-void LLPanelInventoryListItemBase::setTitle(const std::string& title,
- const std::string& highlit_text,
- const LLStyle::Params& input_params)
-{
- mTitleCtrl->setToolTip(title);
-
- LLTextUtil::textboxSetHighlightedVal(
- mTitleCtrl,
- input_params,
- title,
- highlit_text);
-}
-
-BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask)
-{
- LLRect text_box_rect = mTitleCtrl->getRect();
- if (text_box_rect.pointInRect(x, y) &&
- mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth())
- {
- return FALSE;
- }
- return LLPanel::handleToolTip(x, y, mask);
-}
-
-void LLPanelInventoryListItemBase::reshapeLeftWidgets()
-{
- S32 widget_left = 0;
- mLeftWidgetsWidth = 0;
-
- widget_array_t::const_iterator it = mLeftSideWidgets.begin();
- const widget_array_t::const_iterator it_end = mLeftSideWidgets.end();
- for( ; it_end != it; ++it)
- {
- LLUICtrl* widget = *it;
- if(!widget->getVisible())
- {
- continue;
- }
- LLRect widget_rect(widget->getRect());
- widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
- widget->setShape(widget_rect);
-
- widget_left += widget_rect.getWidth() + getWidgetSpacing();
- mLeftWidgetsWidth = widget_rect.mRight;
- }
-}
-
-void LLPanelInventoryListItemBase::reshapeRightWidgets()
-{
- S32 widget_right = getLocalRect().getWidth();
- S32 widget_left = widget_right;
-
- widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin();
- const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend();
- for( ; it_end != it; ++it)
- {
- LLUICtrl* widget = *it;
- if(!widget->getVisible())
- {
- continue;
- }
- LLRect widget_rect(widget->getRect());
- widget_left = widget_right - widget_rect.getWidth();
- widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
- widget->setShape(widget_rect);
-
- widget_right = widget_left - getWidgetSpacing();
- }
- mRightWidgetsWidth = getLocalRect().getWidth() - widget_left;
-}
-
-void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
-{
- LLRect icon_rect(mIconCtrl->getRect());
- icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop,
- icon_rect.getWidth(), icon_rect.getHeight());
- mIconCtrl->setShape(icon_rect);
-
- S32 name_left = icon_rect.mRight + getWidgetSpacing();
- S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
- LLRect name_rect(mTitleCtrl->getRect());
- name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
- mTitleCtrl->setShape(name_rect);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
+#include "llviewerinventory.h"
LLInventoryItemsList::Params::Params()
{}
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 5dc0bfe3de..71c7b6a675 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -3,8 +3,6 @@
* @brief A list of inventory items represented by LLFlatListView.
*
* Class LLInventoryItemsList implements a flat list of inventory items.
- * Class LLPanelInventoryListItem displays inventory item as an element
- * of LLInventoryItemsList.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
@@ -38,189 +36,11 @@
#include "lldarray.h"
-#include "llpanel.h"
-
// newview
#include "llflatlistview.h"
-#include "llviewerinventory.h"
-class LLIconCtrl;
-class LLTextBox;
class LLViewerInventoryItem;
-/**
- * @class LLPanelInventoryListItemBase
- *
- * Base class for Inventory flat list item. Panel consists of inventory icon
- * and inventory item name.
- * This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides
- * of panel.
- *
- * How to use (see LLPanelClothingListItem for example):
- * - implement init() to build panel from xml
- * - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides
- * - redefine postBuild()(call base implementation) and add needed widgets to needed sides,
- *
- */
-class LLPanelInventoryListItemBase : public LLPanel
-{
-public:
- static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
-
- virtual void draw();
-
- /**
- * Let item know it need to be refreshed in next draw()
- */
- void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
-
- bool getNeedsRefresh(){ return mNeedsRefresh; }
-
- /**
- * Add widget to left side
- */
- void addWidgetToLeftSide(const std::string& name, bool show_widget = true);
- void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true);
-
- /**
- * Add widget to right side, widget is supposed to be child of calling panel
- */
- void addWidgetToRightSide(const std::string& name, bool show_widget = true);
- void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true);
-
- /**
- * Mark widgets as visible. Only visible widgets take part in reshaping children
- */
- void setShowWidget(const std::string& name, bool show);
- void setShowWidget(LLUICtrl* ctrl, bool show);
-
- /**
- * Set spacing between widgets during reshape
- */
- void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; }
-
- S32 getWidgetSpacing() { return mWidgetSpacing; }
-
- /**
- * Inheritors need to call base implementation of postBuild()
- */
- /*virtual*/ BOOL postBuild();
-
- /**
- * Handles item selection
- */
- /*virtual*/ void setValue(const LLSD& value);
-
- /**
- * Handles filter request
- */
- /*virtual*/ S32 notify(const LLSD& info);
-
- /* Highlights item */
- /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
- /* Removes item highlight */
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-
- /** Get the name of a corresponding inventory item */
- const std::string& getItemName() const;
-
- /** Get the asset type of a corresponding inventory item */
- LLAssetType::EType getType() const;
-
- /** Get the wearable type of a corresponding inventory item */
- LLWearableType::EType getWearableType() const;
-
- /** Get the description of a corresponding inventory item */
- const std::string& getDescription() const;
-
- /** Get the associated inventory item */
- LLViewerInventoryItem* getItem() const { return mItem; }
-
- virtual ~LLPanelInventoryListItemBase(){}
-
-protected:
-
- LLPanelInventoryListItemBase(LLViewerInventoryItem* item);
-
- typedef std::vector<LLUICtrl*> widget_array_t;
-
- /**
- * Use it from a factory function to build panel, do not build panel in constructor
- */
- virtual void init();
-
- /**
- * Called after inventory item was updated, update panel widgets to reflect inventory changes.
- */
- virtual void updateItem(const std::string& name,
- const LLStyle::Params& input_params = LLStyle::Params());
-
- /** setter for mIconCtrl */
- void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; }
- /** setter for MTitleCtrl */
- void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; }
-
- void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
- void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; }
-
- /**
- * Set all widgets from both side visible/invisible. Only enabled widgets
- * (see setShowWidget()) can become visible
- */
- virtual void setWidgetsVisible(bool visible);
-
- /**
- * Reshape all child widgets - icon, text-box and side widgets
- */
- virtual void reshapeWidgets();
-
- /** set wearable type icon image */
- void setIconImage(const LLUIImagePtr& image);
-
- /** Set item title - inventory item name usually */
- virtual void setTitle(const std::string& title,
- const std::string& highlit_text,
- const LLStyle::Params& input_params = LLStyle::Params());
-
- /**
- * Show tool tip if item name text size > panel size
- */
- virtual BOOL handleToolTip( S32 x, S32 y, MASK mask);
-
- LLViewerInventoryItem* mItem;
-
-private:
-
- /** reshape left side widgets
- * Deprecated for now. Disabled reshape left for now to reserve space for 'delete'
- * button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/)
- */
- void reshapeLeftWidgets();
-
- /** reshape right side widgets */
- void reshapeRightWidgets();
-
- /** reshape remaining widgets */
- void reshapeMiddleWidgets();
-
-
- LLIconCtrl* mIconCtrl;
- LLTextBox* mTitleCtrl;
-
- LLUIImagePtr mIconImage;
- std::string mHighlightedText;
-
- widget_array_t mLeftSideWidgets;
- widget_array_t mRightSideWidgets;
- S32 mWidgetSpacing;
-
- S32 mLeftWidgetsWidth;
- S32 mRightWidgetsWidth;
- bool mNeedsRefresh;
-};
-
-//////////////////////////////////////////////////////////////////////////
-
class LLInventoryItemsList : public LLFlatListViewEx
{
public:
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
new file mode 100644
index 0000000000..c487aa10a7
--- /dev/null
+++ b/indra/newview/llinventorylistitem.cpp
@@ -0,0 +1,400 @@
+/**
+ * @file llinventorylistitem.cpp
+ * @brief Inventory list item panel.
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinventorylistitem.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llinventorymodel.h"
+#include "llviewerinventory.h"
+
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
+
+static const S32 WIDGET_SPACING = 3;
+
+LLPanelInventoryListItemBase::Params::Params()
+: default_style("default_style"),
+ worn_style("worn_style")
+{};
+
+LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
+{
+ LLPanelInventoryListItemBase* list_item = NULL;
+ if (item)
+ {
+ list_item = new LLPanelInventoryListItemBase(item);
+ list_item->init();
+ }
+ return list_item;
+}
+
+void LLPanelInventoryListItemBase::draw()
+{
+ if (getNeedsRefresh())
+ {
+ LLViewerInventoryItem* inv_item = getItem();
+ if (inv_item)
+ {
+ updateItem(inv_item->getName());
+ }
+ setNeedsRefresh(false);
+ }
+ LLPanel::draw();
+}
+
+// virtual
+void LLPanelInventoryListItemBase::updateItem(const std::string& name,
+ EItemState item_state)
+{
+ setIconImage(mIconImage);
+ setTitle(name, mHighlightedText, item_state);
+}
+
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
+{
+ LLUICtrl* ctrl = findChild<LLUICtrl>(name);
+ if(ctrl)
+ {
+ addWidgetToLeftSide(ctrl, show_widget);
+ }
+}
+
+void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
+{
+ mLeftSideWidgets.push_back(ctrl);
+ setShowWidget(ctrl, show_widget);
+}
+
+void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/)
+{
+ LLUICtrl* ctrl = findChild<LLUICtrl>(name);
+ if(ctrl)
+ {
+ addWidgetToRightSide(ctrl, show_widget);
+ }
+}
+
+void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
+{
+ mRightSideWidgets.push_back(ctrl);
+ setShowWidget(ctrl, show_widget);
+}
+
+void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show)
+{
+ LLUICtrl* widget = findChild<LLUICtrl>(name);
+ if(widget)
+ {
+ setShowWidget(widget, show);
+ }
+}
+
+void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
+{
+ // Enable state determines whether widget may become visible in setWidgetsVisible()
+ ctrl->setEnabled(show);
+}
+
+BOOL LLPanelInventoryListItemBase::postBuild()
+{
+ setIconCtrl(getChild<LLIconCtrl>("item_icon"));
+ setTitleCtrl(getChild<LLTextBox>("item_name"));
+
+ LLViewerInventoryItem* inv_item = getItem();
+ if (inv_item)
+ {
+ mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), FALSE);
+ updateItem(inv_item->getName());
+ }
+
+ setNeedsRefresh(true);
+
+ setWidgetsVisible(false);
+ reshapeWidgets();
+
+ return TRUE;
+}
+
+void LLPanelInventoryListItemBase::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
+
+void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", true);
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ childSetVisible("hovered_icon", false);
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+const std::string& LLPanelInventoryListItemBase::getItemName() const
+{
+ LLViewerInventoryItem* inv_item = getItem();
+ if (NULL == inv_item)
+ {
+ return LLStringUtil::null;
+ }
+ return inv_item->getName();
+}
+
+LLAssetType::EType LLPanelInventoryListItemBase::getType() const
+{
+ LLViewerInventoryItem* inv_item = getItem();
+ if (NULL == inv_item)
+ {
+ return LLAssetType::AT_NONE;
+ }
+ return inv_item->getType();
+}
+
+LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const
+{
+ LLViewerInventoryItem* inv_item = getItem();
+ if (NULL == inv_item)
+ {
+ return LLWearableType::WT_NONE;
+ }
+ return inv_item->getWearableType();
+}
+
+const std::string& LLPanelInventoryListItemBase::getDescription() const
+{
+ LLViewerInventoryItem* inv_item = getItem();
+ if (NULL == inv_item)
+ {
+ return LLStringUtil::null;
+ }
+ return inv_item->getDescription();
+}
+
+LLViewerInventoryItem* LLPanelInventoryListItemBase::getItem() const
+{
+ return gInventory.getItem(mInventoryItemUUID);
+}
+
+S32 LLPanelInventoryListItemBase::notify(const LLSD& info)
+{
+ S32 rv = 0;
+ if(info.has("match_filter"))
+ {
+ mHighlightedText = info["match_filter"].asString();
+
+ std::string test(mTitleCtrl->getText());
+ LLStringUtil::toUpper(test);
+
+ if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText))
+ {
+ rv = 0; // substring is found
+ }
+ else
+ {
+ rv = -1;
+ }
+
+ setNeedsRefresh(true);
+ }
+ else
+ {
+ rv = LLPanel::notify(info);
+ }
+ return rv;
+}
+
+LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
+: LLPanel()
+, mInventoryItemUUID(item ? item->getUUID() : LLUUID::null)
+, mIconCtrl(NULL)
+, mTitleCtrl(NULL)
+, mWidgetSpacing(WIDGET_SPACING)
+, mLeftWidgetsWidth(0)
+, mRightWidgetsWidth(0)
+, mNeedsRefresh(false)
+{
+}
+
+void LLPanelInventoryListItemBase::init()
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
+}
+
+class WidgetVisibilityChanger
+{
+public:
+ WidgetVisibilityChanger(bool visible) : mVisible(visible){}
+ void operator()(LLUICtrl* widget)
+ {
+ // Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget()
+ widget->setVisible(mVisible && widget->getEnabled());
+ }
+private:
+ bool mVisible;
+};
+
+void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
+{
+ std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
+ std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
+}
+
+void LLPanelInventoryListItemBase::reshapeWidgets()
+{
+ // disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
+ /*reshapeLeftWidgets();*/
+ reshapeRightWidgets();
+ reshapeMiddleWidgets();
+}
+
+void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
+{
+ if(image)
+ {
+ mIconImage = image;
+ mIconCtrl->setImage(mIconImage);
+ }
+}
+
+void LLPanelInventoryListItemBase::setTitle(const std::string& title,
+ const std::string& highlit_text,
+ EItemState item_state)
+{
+ mTitleCtrl->setToolTip(title);
+
+ LLStyle::Params style_params;
+
+ const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>();
+
+ switch(item_state)
+ {
+ case IS_DEFAULT:
+ style_params = params.default_style();
+ break;
+ case IS_WORN:
+ style_params = params.worn_style();
+ break;
+ default:;
+ }
+
+ LLTextUtil::textboxSetHighlightedVal(
+ mTitleCtrl,
+ style_params,
+ title,
+ highlit_text);
+}
+
+BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask)
+{
+ LLRect text_box_rect = mTitleCtrl->getRect();
+ if (text_box_rect.pointInRect(x, y) &&
+ mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth())
+ {
+ return FALSE;
+ }
+ return LLPanel::handleToolTip(x, y, mask);
+}
+
+void LLPanelInventoryListItemBase::reshapeLeftWidgets()
+{
+ S32 widget_left = 0;
+ mLeftWidgetsWidth = 0;
+
+ widget_array_t::const_iterator it = mLeftSideWidgets.begin();
+ const widget_array_t::const_iterator it_end = mLeftSideWidgets.end();
+ for( ; it_end != it; ++it)
+ {
+ LLUICtrl* widget = *it;
+ if(!widget->getVisible())
+ {
+ continue;
+ }
+ LLRect widget_rect(widget->getRect());
+ widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
+ widget->setShape(widget_rect);
+
+ widget_left += widget_rect.getWidth() + getWidgetSpacing();
+ mLeftWidgetsWidth = widget_rect.mRight;
+ }
+}
+
+void LLPanelInventoryListItemBase::reshapeRightWidgets()
+{
+ S32 widget_right = getLocalRect().getWidth();
+ S32 widget_left = widget_right;
+
+ widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin();
+ const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend();
+ for( ; it_end != it; ++it)
+ {
+ LLUICtrl* widget = *it;
+ if(!widget->getVisible())
+ {
+ continue;
+ }
+ LLRect widget_rect(widget->getRect());
+ widget_left = widget_right - widget_rect.getWidth();
+ widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
+ widget->setShape(widget_rect);
+
+ widget_right = widget_left - getWidgetSpacing();
+ }
+ mRightWidgetsWidth = getLocalRect().getWidth() - widget_left;
+}
+
+void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
+{
+ LLRect icon_rect(mIconCtrl->getRect());
+ icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop,
+ icon_rect.getWidth(), icon_rect.getHeight());
+ mIconCtrl->setShape(icon_rect);
+
+ S32 name_left = icon_rect.mRight + getWidgetSpacing();
+ S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
+ LLRect name_rect(mTitleCtrl->getRect());
+ name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
+ mTitleCtrl->setShape(name_rect);
+}
+
+// EOF
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
new file mode 100644
index 0000000000..f29d92d51c
--- /dev/null
+++ b/indra/newview/llinventorylistitem.h
@@ -0,0 +1,235 @@
+/**
+ * @file llinventorylistitem.h
+ * @brief Inventory list item panel.
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYLISTITEM_H
+#define LL_LLINVENTORYLISTITEM_H
+
+// llcommon
+#include "llassettype.h"
+
+// llui
+#include "llpanel.h"
+#include "llstyle.h"
+
+// newview
+#include "llwearabletype.h"
+
+class LLIconCtrl;
+class LLTextBox;
+class LLViewerInventoryItem;
+
+/**
+ * @class LLPanelInventoryListItemBase
+ *
+ * Base class for Inventory flat list item. Panel consists of inventory icon
+ * and inventory item name.
+ * This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides
+ * of panel.
+ *
+ * How to use (see LLPanelClothingListItem for example):
+ * - implement init() to build panel from xml
+ * - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides
+ * - redefine postBuild()(call base implementation) and add needed widgets to needed sides,
+ *
+ */
+class LLPanelInventoryListItemBase : public LLPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<LLStyle::Params> default_style,
+ worn_style;
+ Params();
+ };
+
+ typedef enum e_item_state {
+ IS_DEFAULT,
+ IS_WORN,
+ } EItemState;
+
+ static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
+
+ virtual void draw();
+
+ /**
+ * Let item know it need to be refreshed in next draw()
+ */
+ void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
+
+ bool getNeedsRefresh(){ return mNeedsRefresh; }
+
+ /**
+ * Add widget to left side
+ */
+ void addWidgetToLeftSide(const std::string& name, bool show_widget = true);
+ void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true);
+
+ /**
+ * Add widget to right side, widget is supposed to be child of calling panel
+ */
+ void addWidgetToRightSide(const std::string& name, bool show_widget = true);
+ void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true);
+
+ /**
+ * Mark widgets as visible. Only visible widgets take part in reshaping children
+ */
+ void setShowWidget(const std::string& name, bool show);
+ void setShowWidget(LLUICtrl* ctrl, bool show);
+
+ /**
+ * Set spacing between widgets during reshape
+ */
+ void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; }
+
+ S32 getWidgetSpacing() { return mWidgetSpacing; }
+
+ /**
+ * Inheritors need to call base implementation of postBuild()
+ */
+ /*virtual*/ BOOL postBuild();
+
+ /**
+ * Handles item selection
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+ /**
+ * Handles filter request
+ */
+ /*virtual*/ S32 notify(const LLSD& info);
+
+ /* Highlights item */
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+ /* Removes item highlight */
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ /** Get the name of a corresponding inventory item */
+ const std::string& getItemName() const;
+
+ /** Get the asset type of a corresponding inventory item */
+ LLAssetType::EType getType() const;
+
+ /** Get the wearable type of a corresponding inventory item */
+ LLWearableType::EType getWearableType() const;
+
+ /** Get the description of a corresponding inventory item */
+ const std::string& getDescription() const;
+
+ /** Get the associated inventory item */
+ LLViewerInventoryItem* getItem() const;
+
+ virtual ~LLPanelInventoryListItemBase(){}
+
+protected:
+
+ LLPanelInventoryListItemBase(LLViewerInventoryItem* item);
+
+ typedef std::vector<LLUICtrl*> widget_array_t;
+
+ /**
+ * Use it from a factory function to build panel, do not build panel in constructor
+ */
+ virtual void init();
+
+ /**
+ * Called after inventory item was updated, update panel widgets to reflect inventory changes.
+ */
+ virtual void updateItem(const std::string& name,
+ EItemState item_state = IS_DEFAULT);
+
+ /** setter for mIconCtrl */
+ void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; }
+ /** setter for MTitleCtrl */
+ void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; }
+
+ void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
+ void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; }
+
+ /**
+ * Set all widgets from both side visible/invisible. Only enabled widgets
+ * (see setShowWidget()) can become visible
+ */
+ virtual void setWidgetsVisible(bool visible);
+
+ /**
+ * Reshape all child widgets - icon, text-box and side widgets
+ */
+ virtual void reshapeWidgets();
+
+ /** set wearable type icon image */
+ void setIconImage(const LLUIImagePtr& image);
+
+ /** Set item title - inventory item name usually */
+ void setTitle(const std::string& title,
+ const std::string& highlit_text,
+ EItemState item_state = IS_DEFAULT);
+
+ /**
+ * Show tool tip if item name text size > panel size
+ */
+ virtual BOOL handleToolTip( S32 x, S32 y, MASK mask);
+
+ const LLUUID mInventoryItemUUID;
+
+private:
+
+ /** reshape left side widgets
+ * Deprecated for now. Disabled reshape left for now to reserve space for 'delete'
+ * button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/)
+ */
+ void reshapeLeftWidgets();
+
+ /** reshape right side widgets */
+ void reshapeRightWidgets();
+
+ /** reshape remaining widgets */
+ void reshapeMiddleWidgets();
+
+
+ LLIconCtrl* mIconCtrl;
+ LLTextBox* mTitleCtrl;
+
+ LLUIImagePtr mIconImage;
+ std::string mHighlightedText;
+
+ widget_array_t mLeftSideWidgets;
+ widget_array_t mRightSideWidgets;
+ S32 mWidgetSpacing;
+
+ S32 mLeftWidgetsWidth;
+ S32 mRightWidgetsWidth;
+ bool mNeedsRefresh;
+};
+
+#endif //LL_LLINVENTORYLISTITEM_H
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 5fac7efb84..6b5eb23a9b 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -371,7 +371,7 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::onAddMoreButtonClicked, this));
- childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));
+ childSetAction("plus_btn", boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
mEditWearableBtn = getChild<LLButton>("edit_wearable_btn");
mEditWearableBtn->setEnabled(FALSE);
@@ -452,6 +452,10 @@ void LLPanelOutfitEdit::showWearablesFilter()
mSearchFilter->clear();
onSearchEdit(LLStringUtil::null);
}
+ else
+ {
+ mSearchFilter->setFocus(TRUE);
+ }
}
void LLPanelOutfitEdit::showWearablesListView()
@@ -553,7 +557,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
}
-void LLPanelOutfitEdit::onAddToOutfitClicked(void)
+void LLPanelOutfitEdit::onPlusBtnClicked(void)
{
LLUUID selected_id;
if (mInventoryItemsPanel->getVisible())
@@ -573,7 +577,8 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)
if (selected_id.isNull()) return;
- LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id);
+ //replacing instead of adding the item
+ LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id, true, true);
}
void LLPanelOutfitEdit::onAddWearableClicked(void)
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 484f3fcb9f..f449fbca27 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -146,7 +146,7 @@ public:
void onListViewFilterCommitted(LLUICtrl* ctrl);
void onSearchEdit(const std::string& string);
void onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- void onAddToOutfitClicked(void);
+ void onPlusBtnClicked(void);
void applyFolderViewFilter(EFolderViewItemType type);
void applyListViewFilter(EListViewItemType type);
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 5aa46686e8..cf3c030f08 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -93,7 +93,7 @@ public:
// Load default fonts not already loaded at start screen
static void fontInit();
- static void LLStartUp::copyLibraryGestures(const std::string& same_gender_gestures);
+ static void copyLibraryGestures(const std::string& same_gender_gestures);
// outfit_folder_name can be a folder anywhere in your inventory,
// but the name must be a case-sensitive exact match.
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 9c308359fa..832d4a2fe6 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,11 +34,11 @@
#include "llwearableitemslist.h"
#include "lliconctrl.h"
+#include "llmenugl.h" // for LLContextMenu
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
-#include "llmenugl.h" // for LLContextMenu
#include "lltransutil.h"
#include "llviewerattachmenu.h"
#include "llvoavatarself.h"
@@ -113,18 +113,17 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item
// virtual
void LLPanelWearableOutfitItem::updateItem(const std::string& name,
- const LLStyle::Params& input_params)
+ EItemState item_state)
{
std::string search_label = name;
- LLStyle::Params style_params = input_params;
- if (mItem && get_is_item_worn(mItem->getUUID()))
+ if (get_is_item_worn(mInventoryItemUUID))
{
search_label += LLTrans::getString("worn");
- style_params.font.style("BOLD");
+ item_state = IS_WORN;
}
- LLPanelInventoryListItemBase::updateItem(search_label, style_params);
+ LLPanelInventoryListItemBase::updateItem(search_label, item_state);
}
//////////////////////////////////////////////////////////////////////////
@@ -264,19 +263,19 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt
return list_item;
}
-void LLPanelAttachmentListItem::setTitle(const std::string& title,
- const std::string& highlit_text,
- const LLStyle::Params& input_params)
+void LLPanelAttachmentListItem::updateItem(const std::string& name,
+ EItemState item_state)
{
- std::string title_joint = title;
+ std::string title_joint;
- if (mItem && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(mItem->getLinkedUUID()))
+ LLViewerInventoryItem* inv_item = getItem();
+ if (inv_item && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(inv_item->getLinkedUUID()))
{
- std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(mItem->getLinkedUUID()));
- title_joint = title + " (" + joint + ")";
+ std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID()));
+ title_joint = name + " (" + joint + ")";
}
- LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text, input_params);
+ LLPanelInventoryListItemBase::updateItem(title_joint, item_state);
}
//////////////////////////////////////////////////////////////////////////
@@ -503,6 +502,9 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids)
{
+ // nothing to update
+ if (changed_items_uuids.empty()) return;
+
typedef std::vector<LLPanel*> item_panel_list_t;
item_panel_list_t items;
@@ -527,6 +529,7 @@ void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_ite
if (linked_uuid == *iter)
{
item->setNeedsRefresh(true);
+ break;
}
}
}
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 5dc06284c3..2bfb90e3ec 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -38,6 +38,7 @@
// newview
#include "llinventoryitemslist.h"
+#include "llinventorylistitem.h"
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
#include "llwearabletype.h"
@@ -87,7 +88,7 @@ public:
* Updates item name and (worn) suffix.
*/
/*virtual*/ void updateItem(const std::string& name,
- const LLStyle::Params& input_params = LLStyle::Params());
+ EItemState item_state = IS_DEFAULT);
protected:
LLPanelWearableOutfitItem(LLViewerInventoryItem* item);
@@ -124,9 +125,8 @@ public:
virtual ~LLPanelAttachmentListItem() {};
/** Set item title. Joint name is added to the title in parenthesis */
- /*virtual*/ void setTitle(const std::string& title,
- const std::string& highlit_text,
- const LLStyle::Params& input_params = LLStyle::Params());
+ /*virtual*/ void updateItem(const std::string& name,
+ EItemState item_state = IS_DEFAULT);
protected:
LLPanelAttachmentListItem(LLViewerInventoryItem* item) : LLPanelDeletableWearableListItem(item) {};
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index 3106ed34ff..00c5325039 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -230,7 +230,7 @@ left="0"
height="23"
layout="topleft"
left="10"
- max_length="300"
+ max_length="63"
name="description"
prevalidate_callback="ascii"
text_color="black"
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index 1ed73e6c15..819ba7f878 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -168,7 +168,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
<layout_panel
layout="topleft"
height="187"
- min_height="100"
+ min_height="155"
name="outfit_wearables_panel"
width="313"
auto_resize="true"
@@ -293,7 +293,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
auto_resize="true"
default_tab_group="3"
height="450"
- min_height="210"
+ min_height="53"
name="add_wearables_panel"
width="313"
tab_group="2"
@@ -459,7 +459,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
label=""
layout="topleft"
left_pad="1"
- name="add_to_outfit_btn"
+ name="plus_btn"
top="1"
width="31" />
<icon
diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
index 78d64620a5..a8cd380f20 100644
--- a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
@@ -12,7 +12,7 @@
layout="topleft"
left="12"
name="min param text"
- text_color="EmphasisColor"
+ text_color="White"
font_shadow="hard"
top="120"
width="120" />
@@ -22,7 +22,7 @@
layout="topleft"
left="155"
name="max param text"
- text_color="EmphasisColor"
+ text_color="White"
font_shadow="hard"
top_delta="0"
width="120" />
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
new file mode 100644
index 0000000000..dbe1ea2874
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<inventory_list_item
+ height="0"
+ layout="topleft"
+ left="0"
+ name="inventory_list_item"
+ top="0"
+ width="0">
+ <!-- DEFAULT style for inventory list item -->
+ <default_style
+ font="SansSerifSmall"
+ font.style="NORMAL" />
+
+ <!-- style for inventory list item WORN on avatar -->
+ <worn_style
+ font="SansSerifSmall"
+ font.style="BOLD" />
+</inventory_list_item>