diff options
author | Leyla Farazha <leyla@lindenlab.com> | 2010-06-22 16:53:49 -0700 |
---|---|---|
committer | Leyla Farazha <leyla@lindenlab.com> | 2010-06-22 16:53:49 -0700 |
commit | 204603e201ae4f3e088c5e14eefc536c4f567398 (patch) | |
tree | 7d14cbb5b385532302d8e792e0167e71f8c7a55a | |
parent | 25de07a379aaacfc7eb37dd91f33005acd3791ae (diff) | |
parent | 6296390cdee1102eb7b0ea5e1625a1d4c268b490 (diff) |
Merge
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> |