diff options
Diffstat (limited to 'indra/newview')
67 files changed, 1611 insertions, 285 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 523ea8a394..d79d3f1f72 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -361,6 +361,8 @@ set(viewer_SOURCE_FILES llpanellogin.cpp llpanelloginlistener.cpp llpanelmaininventory.cpp + llpanelmarketplaceinbox.cpp + llpanelmarketplaceoutbox.cpp llpanelmediasettingsgeneral.cpp llpanelmediasettingspermissions.cpp llpanelmediasettingssecurity.cpp @@ -909,6 +911,8 @@ set(viewer_HEADER_FILES llpanellogin.h llpanelloginlistener.h llpanelmaininventory.h + llpanelmarketplaceinbox.h + llpanelmarketplaceoutbox.h llpanelmediasettingsgeneral.h llpanelmediasettingspermissions.h llpanelmediasettingssecurity.h @@ -1465,7 +1469,7 @@ set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") if (WINDOWS) - set_target_properties(${VIEWER_BINARY_NAME} + set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES # *TODO -reenable this once we get server usage sorted out #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 218a0534e6..bae127d217 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4180,7 +4180,29 @@ <key>Value</key> <real>1.0</real> </map> - <key>InventoryLinking</key> + <key>InventoryDisplayInbox</key> + <map> + <key>Comment</key> + <string>Override received items inventory inbox display</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>InventoryDisplayOutbox</key> + <map> + <key>Comment</key> + <string>Override merchant inventory outbox display</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>InventoryLinking</key> <map> <key>Comment</key> <string>Enable ability to create links to folders and items via "Paste as link".</string> @@ -4422,6 +4444,17 @@ <key>Value</key> <real>2.0</real> </map> + <key>LastInventoryInboxExpand</key> + <map> + <key>Comment</key> + <string>The last time the received items inbox was expanded.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> <key>LCDDestination</key> <map> <key>Comment</key> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index cbbdcb2983..eeb4ec8458 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -69,6 +69,7 @@ #include "lltrans.h" #include "llcallingcard.h" #include "llslurl.h" // IDEVO +#include "llsidepanelinventory.h" // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -444,8 +445,6 @@ void LLAvatarActions::share(const LLUUID& id) namespace action_give_inventory { - typedef std::set<LLUUID> uuid_set_t; - /** * Returns a pointer to 'Add More' inventory panel of Edit Outfit SP. */ @@ -475,18 +474,16 @@ namespace action_give_inventory /** * Checks My Inventory visibility. */ + static bool is_give_inventory_acceptable() { - LLInventoryPanel* active_panel = get_active_inventory_panel(); - if (!active_panel) return false; - // check selection in the panel - const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); if (inventory_selected_uuids.empty()) return false; // nothing selected bool acceptable = false; - uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); - const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); + const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end(); for (; it != it_end; ++it) { LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); @@ -529,12 +526,12 @@ namespace action_give_inventory } } - static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) + static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string) { llassert(inventory_selected_uuids.size() > 0); const std::string& separator = LLTrans::getString("words_separator"); - for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; ) + for (std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); ; ) { LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); if (NULL != inv_cat) @@ -570,10 +567,7 @@ namespace action_give_inventory return; } - LLInventoryPanel* active_panel = get_active_inventory_panel(); - if (!active_panel) return; - - const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); if (inventory_selected_uuids.empty()) { return; @@ -590,8 +584,8 @@ namespace action_give_inventory // We souldn't open IM session, just calculate session ID for logging purpose. See EXT-6710 const LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, avatar_uuid); - uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); - const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); + const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end(); const std::string& separator = LLTrans::getString("words_separator"); std::string noncopy_item_names; @@ -654,10 +648,7 @@ namespace action_give_inventory { llassert(avatar_names.size() == avatar_uuids.size()); - LLInventoryPanel* active_panel = get_active_inventory_panel(); - if (!active_panel) return; - - const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); if (inventory_selected_uuids.empty()) { return; @@ -678,6 +669,33 @@ namespace action_give_inventory } } + + +//static +std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() +{ + std::set<LLUUID> inventory_selected_uuids; + + LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel(); + if (active_panel) + { + inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + } + + if (inventory_selected_uuids.empty()) + { + LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + LLInventoryPanel * inbox = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + if (inbox) + { + inventory_selected_uuids = inbox->getRootFolder()->getSelectionList(); + } + + } + + return inventory_selected_uuids; +} + //static void LLAvatarActions::shareWithAvatars() { @@ -705,12 +723,12 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL // check selection in the panel LLFolderView* root_folder = inv_panel->getRootFolder(); - const uuid_set_t inventory_selected_uuids = root_folder->getSelectionList(); + const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList(); if (inventory_selected_uuids.empty()) return false; // nothing selected bool can_share = true; - uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); - const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); + const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end(); for (; it != it_end; ++it) { LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 956fed7461..fbfd815f41 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -36,6 +36,7 @@ class LLInventoryPanel; + /** * Friend-related actions (add, remove, offer teleport, etc) */ @@ -196,6 +197,8 @@ public: */ static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); + static std::set<LLUUID> getInventorySelectedUUIDs(); + private: static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static bool handleRemove(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 260693ebc7..866eae8d3d 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -815,6 +815,11 @@ void LLFolderView::sanitizeSelection() { // nothing selected to start with, so pick "My Inventory" as best guess new_selection = getItemByID(gInventory.getRootFolderID()); + // ... except if it's hidden from the UI. + if (new_selection && new_selection->getHidden()) + { + new_selection = NULL; + } } if (new_selection) @@ -1646,8 +1651,8 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) LLFolderViewItem* parent_folder = last_selected->getParentFolder(); if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder()) { - setSelection(parent_folder, FALSE, TRUE); - } + setSelection(parent_folder, FALSE, TRUE); + } else { last_selected->setOpen( FALSE ); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 1f53586ccc..38b36af6f0 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -30,6 +30,7 @@ // viewer includes #include "llfolderview.h" // Items depend extensively on LLFolderViews #include "llfoldervieweventlistener.h" +#include "llviewerfoldertype.h" #include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator() #include "llinventoryfilter.h" #include "llinventorymodelbackgroundfetch.h" @@ -357,7 +358,7 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection, LLFolderView* root = getRoot(); if (getParentFolder()) { - getParentFolder()->requestArrange(); + getParentFolder()->requestArrange(); } if(set_selection) { @@ -1202,10 +1203,11 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) } else { - folderp->setVisible( - folderp->getFilteredFolder(filter_generation) // folder must pass folder filters - && (folderp->getFiltered(filter_generation) - || folderp->hasFilteredDescendants(filter_generation))); // passed item filter or has descendants that passed filter + bool is_hidden = folderp->getListener() && LLViewerFolderType::lookupIsHiddenType(folderp->getListener()->getPreferredType()); + + folderp->setVisible( !is_hidden + && (show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS + || (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter } if (folderp->getVisible()) @@ -2023,6 +2025,13 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) item->dirtyFilter(); requestArrange(); requestSort(); + LLFolderViewFolder* parentp = getParentFolder(); + while (parentp && !parentp->getCreationDate()) + { + // parent folder doesn't have a time stamp yet, so get it from us + parentp->requestSort(); + parentp = parentp->getParentFolder(); + } return TRUE; } @@ -2042,6 +2051,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) // rearrange all descendants too, as our indentation level might have changed folder->requestArrange(TRUE); requestSort(); + LLFolderViewFolder* parentp = getParentFolder(); + while (parentp && !parentp->getCreationDate()) + { + // parent folder doesn't have a time stamp yet, so get it from us + parentp->requestSort(); + parentp = parentp->getParentFolder(); + } return TRUE; } @@ -2377,6 +2393,21 @@ void LLFolderViewFolder::draw() time_t LLFolderViewFolder::getCreationDate() const { + // folders have no creation date so use first non-folder descendent's date + if (!mCreationDate) + { + for(items_t::const_iterator iit = mItems.begin(); + iit != mItems.end(); ++iit) + { + LLFolderViewItem* itemp = (*iit); + if (itemp->getCreationDate()) + { + mCreationDate = itemp->getCreationDate(); + break; + } + } + } + return llmax<time_t>(mCreationDate, mSubtreeCreationDate); } @@ -2648,8 +2679,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde // We sort by name if we aren't sorting by date // OR if these are folders and we are sorting folders by name. bool by_name = (!mByDate - || (mFoldersByName - && (a->getSortGroup() != SG_ITEM))); + || (mFoldersByName + && (a->getSortGroup() != SG_ITEM))); if (a->getSortGroup() != b->getSortGroup()) { diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 7d640adf2e..40c8eaa0a4 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -135,7 +135,7 @@ protected: std::string mSearchableLabel; S32 mLabelWidth; bool mLabelWidthDirty; - time_t mCreationDate; + mutable time_t mCreationDate; LLFolderViewFolder* mParentFolder; LLFolderViewEventListener* mListener; BOOL mIsCurSelection; @@ -166,7 +166,7 @@ protected: void extendSelectionFromRoot(LLFolderViewItem* selection); // this is an internal method used for adding items to folders. A - // no-op at this leve, but reimplemented in derived classes. + // no-op at this level, but reimplemented in derived classes. virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; } @@ -362,6 +362,9 @@ public: UNKNOWN, TRASH, NOT_TRASH } ETrash; + typedef std::list<LLFolderViewItem*> items_t; + typedef std::list<LLFolderViewFolder*> folders_t; + private: S32 mNumDescendantsSelected; @@ -370,8 +373,6 @@ public: // Accessed needed by LLFolderViewItem S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); } protected: - typedef std::list<LLFolderViewItem*> items_t; - typedef std::list<LLFolderViewFolder*> folders_t; items_t mItems; folders_t mFolders; LLInventorySort mSortFunction; @@ -430,7 +431,7 @@ public: virtual void filter( LLInventoryFilter& filter); virtual void setFiltered(BOOL filtered, S32 filter_generation); virtual void dirtyFilter(); - + // folder-specific filtering (filter status propagates top down instead of bottom up) void filterFolder(LLInventoryFilter& filter); void setFilteredFolder(bool filtered, S32 filter_generation); @@ -540,6 +541,9 @@ public: time_t getCreationDate() const; bool isTrash() const; S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; } + + folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); } + folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); } }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 86c8a1a9b5..58579bdf4f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -571,8 +571,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } - // Don't allow items to be pasted directly into the COF. - if (!isCOFFolder()) + // Don't allow items to be pasted directly into the COF or the inbox + if (!isCOFFolder() && !isInboxFolder()) { items.push_back(std::string("Paste")); } @@ -781,6 +781,18 @@ BOOL LLInvFVBridge::isCOFFolder() const return LLAppearanceMgr::instance().getIsInCOF(mUUID); } +BOOL LLInvFVBridge::isInboxFolder() const +{ + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); + + if (inbox_id.isNull()) + { + return FALSE; + } + + return gInventory.isObjectDescendentOf(mUUID, inbox_id); +} + BOOL LLInvFVBridge::isItemPermissive() const { return FALSE; @@ -2525,6 +2537,7 @@ void LLFolderBridge::folderOptionsMenu() { mItems.push_back(std::string("Add To Outfit")); } + mItems.push_back(std::string("Replace Outfit")); } if (is_ensemble) @@ -2614,15 +2627,17 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. - if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) - mItems.push_back(std::string("New Folder")); - mItems.push_back(std::string("New Script")); - mItems.push_back(std::string("New Note")); - mItems.push_back(std::string("New Gesture")); - mItems.push_back(std::string("New Clothes")); - mItems.push_back(std::string("New Body Parts")); - + if (!isInboxFolder()) // don't allow creation in inbox + { + // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. + if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) + mItems.push_back(std::string("New Folder")); + mItems.push_back(std::string("New Script")); + mItems.push_back(std::string("New Note")); + mItems.push_back(std::string("New Gesture")); + mItems.push_back(std::string("New Clothes")); + mItems.push_back(std::string("New Body Parts")); + } #if SUPPORT_ENSEMBLES // Changing folder types is an unfinished unsupported feature // and can lead to unexpected behavior if enabled. diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 1e849c8812..15629c0c75 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -139,6 +139,7 @@ protected: BOOL isAgentInventory() const; // false if lost or in the inventory library BOOL isCOFFolder() const; // true if COF or descendent of + BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox virtual BOOL isItemPermissive() const; static void changeItemParent(LLInventoryModel* model, LLViewerInventoryItem* item, @@ -584,6 +585,9 @@ protected: }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Recent Inventory Panel related classes +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Overridden version of the Inventory-Folder-View-Bridge for Folders class LLRecentItemsFolderBridge : public LLFolderBridge diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 1ff423056a..61dec963c5 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -42,7 +42,6 @@ #include "llinventorymodelbackgroundfetch.h" #include "llsidepanelinventory.h" #include "llsidetray.h" -#include "llscrollcontainer.h" #include "llviewerattachmenu.h" #include "llviewerfoldertype.h" #include "llvoavatarself.h" @@ -144,7 +143,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2)); mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars)); - + } void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) @@ -154,7 +153,7 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder); LLUUID root_id; - + if ("LIBRARY" == params.start_folder()) { root_id = gInventory.getLibraryRootFolderID(); @@ -162,31 +161,31 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) else { root_id = (preferred_type != LLFolderType::FT_NONE) - ? gInventory.findCategoryUUIDForType(preferred_type) + ? gInventory.findCategoryUUIDForType(preferred_type, false, false) : LLUUID::null; } - LLRect folder_rect(0, - 0, - getRect().getWidth(), - 0); - LLFolderView::Params p; - p.name = getName(); - p.title = getLabel(); - p.rect = folder_rect; - p.parent_panel = this; - p.tool_tip = p.name; + LLRect folder_rect(0, + 0, + getRect().getWidth(), + 0); + LLFolderView::Params p; + p.name = getName(); + p.title = getLabel(); + p.rect = folder_rect; + p.parent_panel = this; + p.tool_tip = p.name; p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, LLAssetType::AT_CATEGORY, LLInventoryType::IT_CATEGORY, this, NULL, root_id); - p.use_label_suffix = params.use_label_suffix; + p.use_label_suffix = params.use_label_suffix; p.allow_multiselect = mAllowMultiSelect; - mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); + mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); -} + } void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) { @@ -204,13 +203,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) { LLRect scroller_view_rect = getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); - LLScrollContainer::Params p; - p.name("Inventory Scroller"); - p.rect(scroller_view_rect); - p.follows.flags(FOLLOWS_ALL); - p.reserve_scroll_corner(true); - p.tab_stop(true); - mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); + LLScrollContainer::Params scroller_params(params.scroll()); + scroller_params.rect(scroller_view_rect); + mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params); addChild(mScroller); mScroller->addChild(mFolderRoot); mFolderRoot->setScrollContainer(mScroller); @@ -570,88 +565,88 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) LLFolderViewFolder* parent_folder = NULL; if (id == root_id) - { - parent_folder = mFolderRoot; - } + { + parent_folder = mFolderRoot; + } else if (objectp) - { + { LLFolderViewItem* itemp = NULL; const LLUUID &parent_id = objectp->getParentUUID(); parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); - + if (parent_folder) { - if (objectp->getType() <= LLAssetType::AT_NONE || - objectp->getType() >= LLAssetType::AT_COUNT) - { - llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " + if (objectp->getType() <= LLAssetType::AT_NONE || + objectp->getType() >= LLAssetType::AT_COUNT) + { + llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() - << llendl; - return; - } - - if ((objectp->getType() == LLAssetType::AT_CATEGORY) && - (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) - { - LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), - objectp->getType(), - LLInventoryType::IT_CATEGORY, - this, - mFolderRoot, - objectp->getUUID()); - if (new_listener) - { - LLFolderViewFolder::Params params; - params.name = new_listener->getDisplayName(); - params.icon = new_listener->getIcon(); - params.icon_open = new_listener->getOpenIcon(); - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.root = mFolderRoot; - params.listener = new_listener; - params.tool_tip = params.name; - LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params); - folderp->setItemSortOrder(mFolderRoot->getSortOrder()); - itemp = folderp; - } - } + << llendl; + return; + } + + if ((objectp->getType() == LLAssetType::AT_CATEGORY) && + (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) + { + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), + objectp->getType(), + LLInventoryType::IT_CATEGORY, + this, + mFolderRoot, + objectp->getUUID()); + if (new_listener) + { + LLFolderViewFolder::Params params; + params.name = new_listener->getDisplayName(); + params.icon = new_listener->getIcon(); + params.icon_open = new_listener->getOpenIcon(); + if (mShowItemLinkOverlays) // if false, then links show up just like normal items + { + params.icon_overlay = LLUI::getUIImage("Inv_Link"); + } + params.root = mFolderRoot; + params.listener = new_listener; + params.tool_tip = params.name; + LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params); + folderp->setItemSortOrder(mFolderRoot->getSortOrder()); + itemp = folderp; + } + } else - { - // Build new view for item. - LLInventoryItem* item = (LLInventoryItem*)objectp; - LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), - item->getActualType(), - item->getInventoryType(), - this, - mFolderRoot, - item->getUUID(), - item->getFlags()); - - if (new_listener) - { - LLFolderViewItem::Params params; - params.name = new_listener->getDisplayName(); - params.icon = new_listener->getIcon(); - params.icon_open = new_listener->getOpenIcon(); - if (mShowItemLinkOverlays) // if false, then links show up just like normal items - { - params.icon_overlay = LLUI::getUIImage("Inv_Link"); - } - params.creation_date = new_listener->getCreationDate(); - params.root = mFolderRoot; - params.listener = new_listener; - params.rect = LLRect (0, 0, 0, 0); - params.tool_tip = params.name; - itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); - } - } - - if (itemp) - { - itemp->addToFolder(parent_folder, mFolderRoot); - } + { + // Build new view for item. + LLInventoryItem* item = (LLInventoryItem*)objectp; + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), + item->getActualType(), + item->getInventoryType(), + this, + mFolderRoot, + item->getUUID(), + item->getFlags()); + + if (new_listener) + { + LLFolderViewItem::Params params; + params.name = new_listener->getDisplayName(); + params.icon = new_listener->getIcon(); + params.icon_open = new_listener->getOpenIcon(); + if (mShowItemLinkOverlays) // if false, then links show up just like normal items + { + params.icon_overlay = LLUI::getUIImage("Inv_Link"); + } + params.creation_date = new_listener->getCreationDate(); + params.root = mFolderRoot; + params.listener = new_listener; + params.rect = LLRect (0, 0, 0, 0); + params.tool_tip = params.name; + itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); + } + } + + if (itemp) + { + itemp->addToFolder(parent_folder, mFolderRoot); + } } } @@ -693,20 +688,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) // bit of a hack to make sure the inventory is open. void LLInventoryPanel::openStartFolderOrMyInventory() { - // Find My Inventory folder and open it up by name - for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child)) - { - LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); + // Find My Inventory folder and open it up by name + for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child)) + { + LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); if (fchild && fchild->getListener() && fchild->getListener()->getUUID() == gInventory.getRootFolderID()) - { - const std::string& child_name = child->getName(); - mFolderRoot->openFolder(child_name); - break; + { + const std::string& child_name = child->getName(); + mFolderRoot->openFolder(child_name); + break; + } } } -} void LLInventoryPanel::onItemsCompletion() { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index da67da13b2..864c403397 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -35,6 +35,7 @@ #include "llinventoryfilter.h" #include "llfolderview.h" #include "llinventorymodel.h" +#include "llscrollcontainer.h" #include "lluictrlfactory.h" #include <set> @@ -46,7 +47,6 @@ class LLInventoryFVBridgeBuilder; class LLMenuBarGL; class LLCheckBoxCtrl; class LLSpinCtrl; -class LLScrollContainer; class LLTextBox; class LLIconCtrl; class LLSaveFolderState; @@ -83,6 +83,7 @@ public: Optional<Filter> filter; Optional<std::string> start_folder; Optional<bool> use_label_suffix; + Optional<LLScrollContainer::Params> scroll; Params() : sort_order_setting("sort_order_setting"), @@ -91,7 +92,8 @@ public: show_item_link_overlays("show_item_link_overlays", false), filter("filter"), start_folder("start_folder"), - use_label_suffix("use_label_suffix", true) + use_label_suffix("use_label_suffix", true), + scroll("scroll") {} }; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 6435126fc0..10887aa53a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -364,8 +364,8 @@ LLOutfitsList::~LLOutfitsList() if (gInventory.containsObserver(mCategoriesObserver)) { gInventory.removeObserver(mCategoriesObserver); - delete mCategoriesObserver; } + delete mCategoriesObserver; } BOOL LLOutfitsList::postBuild() diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index bc4998dd0c..728642e4c7 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -193,6 +193,9 @@ BOOL LLPanelMainInventory::postBuild() mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost); mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); + // Trigger callback for focus received so we can deselect items in inbox/outbox + LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); + return TRUE; } @@ -572,6 +575,25 @@ void LLPanelMainInventory::updateItemcountText() getChild<LLUICtrl>("ItemcountText")->setValue(text); } +void LLPanelMainInventory::onFocusReceived() +{ + LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + + LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + + if (inbox_panel) + { + inbox_panel->clearSelection(); + } + + LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox"); + + if (outbox_panel) + { + outbox_panel->clearSelection(); + } +} + void LLPanelMainInventory::setFilterTextFromFilter() { mFilterText = mActivePanel->getFilter()->getFilterText(); diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 2b2ee1c0c9..86b2c87e0b 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -114,6 +114,8 @@ protected: bool isSaveTextureEnabled(const LLSD& userdata); void updateItemcountText(); + void onFocusReceived(); + private: LLFloaterInventoryFinder* getFinder(); diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp new file mode 100644 index 0000000000..14c4c46fe7 --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -0,0 +1,222 @@ +/**
+ * @file llpanelmarketplaceinbox.cpp
+ * @brief Panel for marketplace inbox
+ *
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelmarketplaceinbox.h"
+
+#include "llappviewer.h"
+#include "llbutton.h"
+#include "llinventorypanel.h"
+#include "llsidepanelinventory.h"
+
+
+#define SUPPORTING_FRESH_ITEM_COUNT 0
+
+
+static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
+
+const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams()
+{
+ return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceInbox>();
+}
+
+// protected
+LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
+ : LLPanel(p)
+ , mInventoryPanel(NULL)
+{
+}
+
+LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
+{
+}
+
+// virtual
+BOOL LLPanelMarketplaceInbox::postBuild()
+{
+ mInventoryPanel = getChild<LLInventoryPanel>("inventory_inbox");
+
+ mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
+
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
+
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
+
+ mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
+
+ return TRUE;
+}
+
+void LLPanelMarketplaceInbox::onSelectionChange()
+{
+ LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
+
+ sidepanel_inventory->updateVerbs();
+}
+
+
+void LLPanelMarketplaceInbox::handleLoginComplete()
+{
+ // Set us up as the class to drive the badge value for the sidebar_inventory button
+ LLSideTray::getInstance()->setTabButtonBadgeDriver("sidebar_inventory", this);
+}
+
+void LLPanelMarketplaceInbox::onFocusReceived()
+{
+ LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
+
+ if (sidepanel_inventory)
+ {
+ LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
+
+ if (inv_panel)
+ {
+ inv_panel->clearSelection();
+ }
+
+ LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
+
+ if (outbox_panel)
+ {
+ outbox_panel->clearSelection();
+ }
+ }
+}
+
+BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
+{
+ *accept = ACCEPT_NO;
+ return TRUE;
+}
+
+U32 LLPanelMarketplaceInbox::getFreshItemCount() const
+{
+#if SUPPORTING_FRESH_ITEM_COUNT
+ U32 fresh_item_count = 0;
+
+ LLFolderView * root_folder = mInventoryPanel->getRootFolder();
+
+ const LLFolderViewFolder * inbox_folder = *(root_folder->getFoldersBegin());
+
+ LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
+ LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
+
+ for (; folders_it != folders_end; ++folders_it)
+ {
+ const LLFolderViewFolder * folder = *folders_it;
+
+ if (folder->getCreationDate() > 1500)
+ {
+ fresh_item_count++;
+ }
+ }
+
+ return fresh_item_count;
+#else
+ return getTotalItemCount();
+#endif
+}
+
+U32 LLPanelMarketplaceInbox::getTotalItemCount() const
+{
+ LLInventoryModel* model = mInventoryPanel->getModel();
+
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+
+ model->getDirectDescendentsOf(model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false), cats, items);
+
+ U32 item_count = 0;
+
+ if (cats)
+ {
+ item_count += cats->size();
+ }
+
+ if (items)
+ {
+ item_count += items->size();
+ }
+
+ return item_count;
+}
+
+std::string LLPanelMarketplaceInbox::getBadgeString() const
+{
+ std::string item_count_str("");
+
+ // If the inbox is visible, and the side panel is collapsed or expanded and not the inventory panel
+ if (getParent()->getVisible() &&
+ (LLSideTray::getInstance()->getCollapsed() || !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory")))
+ {
+ U32 item_count = getFreshItemCount();
+
+ if (item_count)
+ {
+ item_count_str = llformat("%d", item_count);
+ }
+ }
+
+ return item_count_str;
+}
+
+void LLPanelMarketplaceInbox::draw()
+{
+ U32 item_count = getTotalItemCount();
+
+ LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count");
+
+ if (item_count > 0)
+ {
+ std::string item_count_str = llformat("%d", item_count);
+
+ LLStringUtil::format_map_t args;
+ args["[NUM]"] = item_count_str;
+ getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
+
+#if SUPPORTING_FRESH_ITEM_COUNT
+ // set green text to fresh item count
+ U32 fresh_item_count = getFreshItemCount();
+ fresh_new_count_view->setVisible((fresh_item_count > 0));
+
+ if (fresh_item_count > 0)
+ {
+ getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count));
+ }
+#else
+ fresh_new_count_view->setVisible(FALSE);
+#endif
+ }
+ else
+ {
+ getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg"));
+
+ fresh_new_count_view->setVisible(FALSE);
+ }
+
+ LLPanel::draw();
+}
diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h new file mode 100644 index 0000000000..b176d57d3f --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.h @@ -0,0 +1,76 @@ +/** + * @file llpanelmarketplaceinbox.h + * @brief Panel for marketplace inbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEINBOX_H +#define LL_LLPANELMARKETPLACEINBOX_H + +#include "llpanel.h" +#include "llsidetray.h" + +class LLInventoryPanel; + +class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver +{ +public: + + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Params() {} + }; + + LOG_CLASS(LLPanelMarketplaceInbox); + + // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 + static const LLPanelMarketplaceInbox::Params& getDefaultParams(); + + LLPanelMarketplaceInbox(const Params& p = getDefaultParams()); + ~LLPanelMarketplaceInbox(); + + /*virtual*/ BOOL postBuild(); + + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); + + /*virtual*/ void draw(); + + U32 getFreshItemCount() const; + U32 getTotalItemCount() const; + + std::string getBadgeString() const; + +private: + void handleLoginComplete(); + + void onSelectionChange(); + + void onFocusReceived(); + +private: + LLInventoryPanel* mInventoryPanel; +}; + + +#endif //LL_LLPANELMARKETPLACEINBOX_H + diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp new file mode 100644 index 0000000000..c8752b3e0f --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.cpp @@ -0,0 +1,164 @@ +/** + * @file llpanelmarketplaceoutbox.cpp + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmarketplaceoutbox.h" + +#include "llbutton.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llinventorypanel.h" +#include "llloadingindicator.h" +#include "llpanelmarketplaceinbox.h" +#include "llsidepanelinventory.h" +#include "llsidetray.h" +#include "lltimer.h" + + +static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox"); + +// protected +LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox() + : LLPanel() + , mSyncButton(NULL) + , mSyncIndicator(NULL) + , mSyncInProgress(false) +{ +} + +LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox() +{ +} + +// virtual +BOOL LLPanelMarketplaceOutbox::postBuild() +{ + mSyncButton = getChild<LLButton>("outbox_sync_btn"); + mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this)); + + mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator"); + + mSyncButton->setEnabled(!isOutboxEmpty()); + + LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this)); + + return TRUE; +} + +void LLPanelMarketplaceOutbox::onFocusReceived() +{ + LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + + if (sidepanel_inventory) + { + LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel(); + + if (inv_panel) + { + inv_panel->clearSelection(); + } + + LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + + if (inbox_panel) + { + inbox_panel->clearSelection(); + } + } +} + +bool LLPanelMarketplaceOutbox::isOutboxEmpty() const +{ + // TODO: Check for contents of outbox + + return false; +} + +bool LLPanelMarketplaceOutbox::isSyncInProgress() const +{ + return mSyncInProgress; +} + + +std::string gTimeDelayDebugFunc = ""; + +void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) +{ + waitForEventOn(self, "mainloop"); + + LLTimer delayTimer; + delayTimer.reset(); + delayTimer.setTimerExpirySec(5.0f); + + while (!delayTimer.hasExpired()) + { + waitForEventOn(self, "mainloop"); + } + + outboxPanel->onSyncComplete(); + + gTimeDelayDebugFunc = ""; +} + +void LLPanelMarketplaceOutbox::onSyncButtonClicked() +{ + // TODO: Actually trigger sync to marketplace + + mSyncInProgress = true; + updateSyncButtonStatus(); + + // Set a timer (for testing only) + + gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); +} + +void LLPanelMarketplaceOutbox::onSyncComplete() +{ + mSyncInProgress = false; + + updateSyncButtonStatus(); +} + +void LLPanelMarketplaceOutbox::updateSyncButtonStatus() +{ + if (isSyncInProgress()) + { + mSyncButton->setVisible(false); + + mSyncIndicator->setVisible(true); + mSyncIndicator->reset(); + mSyncIndicator->start(); + } + else + { + mSyncIndicator->stop(); + mSyncIndicator->setVisible(false); + + mSyncButton->setVisible(true); + mSyncButton->setEnabled(!isOutboxEmpty()); + } +} diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h new file mode 100644 index 0000000000..94bc066224 --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.h @@ -0,0 +1,67 @@ +/** + * @file llpanelmarketplaceoutbox.h + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEOUTBOX_H +#define LL_LLPANELMARKETPLACEOUTBOX_H + +#include "llpanel.h" + + +class LLButton; +class LLLoadingIndicator; + + +class LLPanelMarketplaceOutbox : public LLPanel +{ +public: + + LOG_CLASS(LLPanelMarketplaceOutbox); + + LLPanelMarketplaceOutbox(); + ~LLPanelMarketplaceOutbox(); + + /*virtual*/ BOOL postBuild(); + + bool isOutboxEmpty() const; + bool isSyncInProgress() const; + + void onSyncComplete(); + +protected: + void onSyncButtonClicked(); + void updateSyncButtonStatus(); + + void onFocusReceived(); + +private: + LLButton * mSyncButton; + LLLoadingIndicator * mSyncIndicator; + bool mSyncInProgress; +}; + + +#endif //LL_LLPANELMARKETPLACEOUTBOX_H + diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 911a9e5dda..0645fd8a54 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -174,8 +174,8 @@ LLPanelWearing::~LLPanelWearing() if (gInventory.containsObserver(mCategoriesObserver)) { gInventory.removeObserver(mCategoriesObserver); - delete mCategoriesObserver; } + delete mCategoriesObserver; } BOOL LLPanelWearing::postBuild() diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 31ea542743..f9e029be19 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -29,33 +29,87 @@ #include "llagent.h" #include "llappearancemgr.h" +#include "llappviewer.h" #include "llavataractions.h" #include "llbutton.h" +#include "lldate.h" #include "llfirstuse.h" +#include "llfoldertype.h" +#include "llhttpclient.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventoryobserver.h" #include "llinventorypanel.h" +#include "lllayoutstack.h" #include "lloutfitobserver.h" #include "llpanelmaininventory.h" +#include "llpanelmarketplaceinbox.h" +#include "llselectmgr.h" #include "llsidepaneliteminfo.h" #include "llsidepaneltaskinfo.h" +#include "llstring.h" #include "lltabcontainer.h" -#include "llselectmgr.h" +#include "llviewermedia.h" #include "llweb.h" static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory"); +// +// Constants +// + +static const char * const INBOX_EXPAND_TIME_SETTING = "LastInventoryInboxExpand"; + +static const char * const INBOX_BUTTON_NAME = "inbox_btn"; +static const char * const OUTBOX_BUTTON_NAME = "outbox_btn"; + +static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel"; +static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel"; +static const char * const MAIN_INVENTORY_LAYOUT_PANEL = "main_inventory_layout_panel"; + +static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox"; +static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox"; + +static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack"; + +static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox"; + +// +// Helpers +// + + +// +// Implementation +// + LLSidepanelInventory::LLSidepanelInventory() - : LLPanel(), - mItemPanel(NULL), - mPanelMainInventory(NULL) + : LLPanel() + , mItemPanel(NULL) + , mPanelMainInventory(NULL) + , mInboxEnabled(false) + , mOutboxEnabled(false) + , mCategoriesObserver(NULL) { - //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } LLSidepanelInventory::~LLSidepanelInventory() { + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; +} + +void handleInventoryDisplayInboxChanged() +{ + LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + + sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); } BOOL LLSidepanelInventory::postBuild() @@ -119,13 +173,171 @@ BOOL LLSidepanelInventory::postBuild() } } + // Marketplace inbox/outbox setup + { + LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + + LLLayoutPanel * inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + LLLayoutPanel * outbox_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + + stack->collapsePanel(inbox_panel, true); + stack->collapsePanel(outbox_panel, true); + + // Disable user_resize on main inventory panel by default + stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL, false); + + LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME); + LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME); + + inbox_button->setToggleState(false); + outbox_button->setToggleState(false); + + inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); + outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); + + // Set the inbox and outbox visible based on debug settings (final setting comes from http request below) + enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); + enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox")); + + // Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::handleLoginComplete, this)); + } + + gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); + return TRUE; } +void LLSidepanelInventory::handleLoginComplete() +{ + // + // Track inbox and outbox folder changes + // + + const bool do_not_create_folder = false; + const bool do_not_find_in_library = false; + + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library); + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); + + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + + mCategoriesObserver->addCategory(inbox_id, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inbox_id)); + mCategoriesObserver->addCategory(outbox_id, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outbox_id)); + + // + // Trigger a load for the entire contents of the Inbox + // + + LLInventoryModelBackgroundFetch::instance().start(inbox_id); +} + +void LLSidepanelInventory::enableInbox(bool enabled) +{ + mInboxEnabled = enabled; + getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::enableOutbox(bool enabled) +{ + mOutboxEnabled = enabled; + getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) +{ + // Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting + LLInventoryModelBackgroundFetch::instance().start(inbox_id); + + // Expand the inbox since we have fresh items + LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); + if (inbox && (inbox->getFreshItemCount() > 0)) + { + getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); + onToggleInboxBtn(); + } +} + +void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id) +{ + // Perhaps use this to track outbox changes? +} + +bool manageInboxOutboxPanels(LLLayoutStack * stack, + LLButton * pressedButton, LLLayoutPanel * pressedPanel, + LLButton * otherButton, LLLayoutPanel * otherPanel) +{ + bool expand = pressedButton->getToggleState(); + bool otherExpanded = otherButton->getToggleState(); + + // + // NOTE: Ideally we could have two panel sizes stored for a collapsed and expanded minimum size. + // For now, leave this code disabled because it creates some bad artifacts when expanding + // and collapsing the inbox/outbox. + // + //S32 smallMinSize = (expand ? pressedPanel->getMinDim() : otherPanel->getMinDim()); + //S32 pressedMinSize = (expand ? 2 * smallMinSize : smallMinSize); + //otherPanel->setMinDim(smallMinSize); + //pressedPanel->setMinDim(pressedMinSize); + + if (expand && otherExpanded) + { + // Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size + pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight()); + + stack->collapsePanel(otherPanel, true); + otherButton->setToggleState(false); + } + + stack->collapsePanel(pressedPanel, !expand); + + // Enable user_resize on main inventory panel only when a marketplace box is expanded + stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL, expand); + + return expand; +} + +void LLSidepanelInventory::onToggleInboxBtn() +{ + LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + LLButton* pressedButton = getChild<LLButton>(INBOX_BUTTON_NAME); + LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + LLButton* otherButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); + LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + + bool inboxExpanded = manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); + + if (inboxExpanded) + { + // Save current time as a setting for future new-ness tests + gSavedSettings.setString(INBOX_EXPAND_TIME_SETTING, LLDate::now().asString()); + } +} + +void LLSidepanelInventory::onToggleOutboxBtn() +{ + LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + LLButton* pressedButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); + LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + LLButton* otherButton = getChild<LLButton>(INBOX_BUTTON_NAME); + LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + + manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); +} + void LLSidepanelInventory::onOpen(const LLSD& key) { LLFirstUse::newInventory(false); + // Expand the inbox if we have fresh items + LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); + if (inbox && (inbox->getFreshItemCount() > 0)) + { + getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); + onToggleInboxBtn(); + } + if(key.size() == 0) return; @@ -175,22 +387,24 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action) LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) { - return; + LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); + if (inbox) + { + current_item = inbox->getRootFolder()->getCurSelectedItem(); + if (!current_item) + { + return; + } + } } + current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action); } void LLSidepanelInventory::onWearButtonClicked() { - LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); - if (!panel_main_inventory) - { - llassert(panel_main_inventory != NULL); - return; - } - // Get selected items set. - const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); + const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs(); if (selected_uuids_set.empty()) return; // nothing selected // Convert the set to a vector. @@ -329,31 +543,24 @@ bool LLSidepanelInventory::canShare() LLPanelMainInventory* panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); - if (!panel_main_inventory) - { - llwarns << "Failed to get the main inventory panel" << llendl; - return false; - } + LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); - LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel(); + return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false) + || (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) ); + // Avoid flicker in the Recent tab while inventory is being loaded. - if (!active_panel->getRootFolder()->hasVisibleChildren()) return false; - - return LLAvatarActions::canShareSelectedItems(active_panel); + //if (!active_panel->getRootFolder()->hasVisibleChildren()) return false; } + bool LLSidepanelInventory::canWearSelected() { - LLPanelMainInventory* panel_main_inventory = - mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); - if (!panel_main_inventory) - { - llassert(panel_main_inventory != NULL); + std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); + + if (selected_uuids.empty()) return false; - } - std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); for (std::set<LLUUID>::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it) @@ -370,7 +577,15 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem() LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) { - return NULL; + LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); + if (inbox) + { + current_item = inbox->getRootFolder()->getCurSelectedItem(); + if (!current_item) + { + return NULL; + } + } } const LLUUID &item_id = current_item->getListener()->getUUID(); LLInventoryItem *item = gInventory.getItem(item_id); @@ -379,9 +594,20 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem() U32 LLSidepanelInventory::getSelectedCount() { + int count = 0; + LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); - return selection_list.size(); + count += selection_list.size(); + + LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); + if (inbox) + { + selection_list = inbox->getRootFolder()->getSelectionList(); + count += selection_list.size(); + } + + return count; } LLInventoryPanel *LLSidepanelInventory::getActivePanel() diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 32c98bc034..df29cbceba 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -30,6 +30,7 @@ #include "llpanel.h" class LLFolderViewItem; +class LLInventoryCategoriesObserver; class LLInventoryItem; class LLInventoryPanel; class LLPanelMainInventory; @@ -42,6 +43,10 @@ public: LLSidepanelInventory(); virtual ~LLSidepanelInventory(); +private: + void handleLoginComplete(); + +public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); @@ -56,6 +61,17 @@ public: // checks can share selected item(s) bool canShare(); + void onToggleInboxBtn(); + void onToggleOutboxBtn(); + + void enableInbox(bool enabled); + void enableOutbox(bool enabled); + + bool isInboxEnabled() const { return mInboxEnabled; } + bool isOutboxEnabled() const { return mOutboxEnabled; } + + void updateVerbs(); + protected: // Tracks highlighted (selected) item in inventory panel. LLInventoryItem *getSelectedItem(); @@ -63,10 +79,12 @@ protected: void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); // "wear", "teleport", etc. void performActionOnSelection(const std::string &action); - void updateVerbs(); bool canWearSelected(); // check whether selected items can be worn + void onInboxChanged(const LLUUID& inbox_id); + void onOutboxChanged(const LLUUID& outbox_id); + // // UI Elements // @@ -85,6 +103,7 @@ protected: void onTeleportButtonClicked(); void onOverflowButtonClicked(); void onBackButtonClicked(); + private: LLButton* mInfoBtn; LLButton* mShareBtn; @@ -94,6 +113,10 @@ private: LLButton* mOverflowBtn; LLButton* mShopBtn; + bool mInboxEnabled; + bool mOutboxEnabled; + + LLInventoryCategoriesObserver* mCategoriesObserver; }; #endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 631b244785..651897a217 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -30,6 +30,7 @@ #include "llagentcamera.h" #include "llappviewer.h" +#include "llbadge.h" #include "llbottomtray.h" #include "llfloaterreg.h" #include "llfirstuse.h" @@ -40,6 +41,7 @@ #include "llfocusmgr.h" #include "llrootview.h" #include "llnavigationbar.h" +#include "llpanelmarketplaceinbox.h" #include "llaccordionctrltab.h" @@ -113,11 +115,14 @@ public: Optional<std::string> image_selected; Optional<std::string> tab_title; Optional<std::string> description; + Optional<LLBadge::Params> badge; + Params() : image("image"), image_selected("image_selected"), tab_title("tab_title","no title"), - description("description","no description") + description("description","no description"), + badge("badge") {}; }; protected: @@ -140,7 +145,6 @@ public: static LLSideTrayTab* createInstance (); const std::string& getDescription () const { return mDescription;} - const std::string& getTabTitle() const { return mTabTitle;} void onOpen (const LLSD& key); @@ -150,7 +154,10 @@ public: BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - LLPanel *getPanel(); + LLPanel* getPanel(); + + LLButton* createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback); + private: std::string mTabTitle; std::string mImage; @@ -158,6 +165,9 @@ private: std::string mDescription; LLView* mMainPanel; + + bool mHasBadge; + LLBadge::Params mBadgeParams; }; LLSideTrayTab::LLSideTrayTab(const Params& p) @@ -166,8 +176,10 @@ LLSideTrayTab::LLSideTrayTab(const Params& p) mImage(p.image), mImageSelected(p.image_selected), mDescription(p.description), - mMainPanel(NULL) + mMainPanel(NULL), + mBadgeParams(p.badge) { + mHasBadge = p.badge.isProvided(); } LLSideTrayTab::~LLSideTrayTab() @@ -182,8 +194,6 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group) //return res; } - - //virtual BOOL LLSideTrayTab::postBuild() { @@ -196,7 +206,7 @@ BOOL LLSideTrayTab::postBuild() getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, false)); getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, true)); - return true; + return LLPanel::postBuild(); } static const S32 splitter_margin = 1; @@ -523,18 +533,36 @@ public: return FALSE; } + void setBadgeDriver(LLSideTrayTabBadgeDriver* driver) + { + mBadgeDriver = driver; + } + protected: LLSideTrayButton(const LLButton::Params& p) - : LLButton(p) - , mDragLastScreenX(0) - , mDragLastScreenY(0) + : LLButton(p) + , mDragLastScreenX(0) + , mDragLastScreenY(0) + , mBadgeDriver(NULL) {} friend class LLUICtrlFactory; + void draw() + { + if (mBadgeDriver) + { + setBadgeLabel(mBadgeDriver->getBadgeString()); + } + + LLButton::draw(); + } + private: S32 mDragLastScreenX; S32 mDragLastScreenY; + + LLSideTrayTabBadgeDriver* mBadgeDriver; }; ////////////////////////////////////////////////////////////////////////////// @@ -615,11 +643,31 @@ BOOL LLSideTray::postBuild() return true; } +void LLSideTray::setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver) +{ + mTabButtonBadgeDrivers[tabName] = driver; +} + void LLSideTray::handleLoginComplete() { //reset tab to "home" tab if it was changesd during login process selectTabByName("sidebar_home"); + for (badge_map_t::iterator it = mTabButtonBadgeDrivers.begin(); it != mTabButtonBadgeDrivers.end(); ++it) + { + LLButton* button = mTabButtons[it->first]; + LLSideTrayButton* side_button = dynamic_cast<LLSideTrayButton*>(button); + + if (side_button) + { + side_button->setBadgeDriver(it->second); + } + else + { + llwarns << "Unable to find button " << it->first << " to set the badge driver. " << llendl; + } + } + detachTabs(); } @@ -766,51 +814,6 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible return true; } -LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,const std::string& tooltip, - LLUICtrl::commit_callback_t callback) -{ - static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); - - LLButton::Params bparams; - - LLRect rect; - rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height); - - bparams.name(name); - bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); - bparams.rect (rect); - bparams.tab_stop(false); - bparams.image_unselected(sidetray_params.tab_btn_image_normal); - bparams.image_selected(sidetray_params.tab_btn_image_selected); - bparams.image_disabled(sidetray_params.tab_btn_image_normal); - bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); - - LLButton* button; - if (name == "sidebar_openclose") - { - // "Open/Close" button shouldn't allow "tear off" - // hence it is created as LLButton instance. - button = LLUICtrlFactory::create<LLButton>(bparams); - } - else - { - button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); - } - - button->setClickedCallback(callback); - - button->setToolTip(tooltip); - - if(image.length()) - { - button->setImageOverlay(image); - } - - mButtonsPanel->addChildInBack(button); - - return button; -} - bool LLSideTray::addChild(LLView* view, S32 tab_group) { LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view); @@ -938,7 +941,56 @@ bool LLSideTray::addTab(LLSideTrayTab* tab) return true; } -void LLSideTray::createButtons () +LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback) +{ + static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>()); + + LLRect rect; + rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height); + + LLButton::Params bparams; + + // Append "_button" to the side tray tab name + std::string button_name = getName() + "_button"; + bparams.name(button_name); + bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); + bparams.rect (rect); + bparams.tab_stop(false); + bparams.image_unselected(sidetray_params.tab_btn_image_normal); + bparams.image_selected(sidetray_params.tab_btn_image_selected); + bparams.image_disabled(sidetray_params.tab_btn_image_normal); + bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); + + if (mHasBadge) + { + bparams.badge = mBadgeParams; + } + + LLButton* button; + if (allowTearOff) + { + button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); + } + else + { + // "Open/Close" button shouldn't allow "tear off" + // hence it is created as LLButton instance. + button = LLUICtrlFactory::create<LLButton>(bparams); + } + + button->setClickedCallback(callback); + + button->setToolTip(mTabTitle); + + if(mImage.length()) + { + button->setImageOverlay(mImage); + } + + return button; +} + +void LLSideTray::createButtons() { //create buttons for tabs child_vector_const_iter_t child_it = mTabs.begin(); @@ -951,17 +1003,22 @@ void LLSideTray::createButtons () // The "OpenClose" button will open/close the whole panel if (name == "sidebar_openclose") { - mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), - boost::bind(&LLSideTray::onToggleCollapse, this)); + mCollapseButton = sidebar_tab->createButton(false, boost::bind(&LLSideTray::onToggleCollapse, this)); + + mButtonsPanel->addChildInBack(mCollapseButton); + LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle()); } else { - LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), - boost::bind(&LLSideTray::onTabButtonClick, this, name)); + LLButton* button = sidebar_tab->createButton(true, boost::bind(&LLSideTray::onTabButtonClick, this, name)); + + mButtonsPanel->addChildInBack(button); + mTabButtons[name] = button; } } + LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle()); } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 24882411f4..17158329dc 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -33,6 +33,13 @@ class LLAccordionCtrl; class LLSideTrayTab; +// Define an interface for side tab button badge values +class LLSideTrayTabBadgeDriver +{ +public: + virtual std::string getBadgeString() const = 0; +}; + // Deal with LLSideTrayTab being opaque. Generic do-nothing cast... template <class T> T tab_cast(LLSideTrayTab* tab) { return tab; } @@ -166,6 +173,8 @@ public: bool getCollapsed() { return mCollapsed; } + void setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver); + public: virtual ~LLSideTray(){}; @@ -204,8 +213,6 @@ protected: void createButtons (); - LLButton* createButton (const std::string& name,const std::string& image,const std::string& tooltip, - LLUICtrl::commit_callback_t callback); void arrange (); void detachTabs (); void reflectCollapseChange(); @@ -234,6 +241,8 @@ private: LLPanel* mButtonsPanel; typedef std::map<std::string,LLButton*> button_map_t; button_map_t mTabButtons; + typedef std::map<std::string,LLSideTrayTabBadgeDriver*> badge_map_t; + badge_map_t mTabButtonBadgeDrivers; child_vector_t mTabs; child_vector_t mDetachedTabs; tab_order_vector_t mOriginalTabOrder; diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 42f780a8a3..0ddbe8c040 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -40,6 +40,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry const std::string &icon_name_open, // name of the folder icon const std::string &icon_name_closed, BOOL is_quiet, // folder doesn't need a UI update when changed + bool is_hidden = false, const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank ) : @@ -47,7 +48,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry mNewCategoryName(new_category_name), mIconNameOpen(icon_name_open), mIconNameClosed(icon_name_closed), - mIsQuiet(is_quiet) + mIsQuiet(is_quiet), + mIsHidden(is_hidden) { mAllowedNames.clear(); } @@ -66,7 +68,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry */ mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"), mNewCategoryName(new_category_name), - mIsQuiet(FALSE) + mIsQuiet(FALSE), + mIsHidden(false) { const std::string delims (","); LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims); @@ -91,6 +94,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry typedef std::vector<std::string> name_vec_t; name_vec_t mAllowedNames; BOOL mIsQuiet; + bool mIsHidden; }; class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>, @@ -128,10 +132,10 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE)); addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE)); - - addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); - addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, "default")); + addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, false, "default")); #if SUPPORT_ENSEMBLES initEnsemblesFromFile(); @@ -258,6 +262,17 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type) } +BOOL LLViewerFolderType::lookupIsHiddenType(LLFolderType::EType folder_type) +{ + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); + if (entry) + { + return entry->mIsHidden; + } + return FALSE; +} + + const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type) { const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index f5938de619..a348274e8f 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -40,6 +40,7 @@ public: static const std::string& lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name static BOOL lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured + static BOOL lookupIsHiddenType(EType folder_type); // folder doesn't require UI update when changes have occured static const std::string& lookupNewCategoryName(EType folder_type); // default name when creating new category static LLFolderType::EType lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 9e58acdcd3..22666cec0d 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1269,7 +1269,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons { std::string type_name = userdata.asString(); - if (("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name)) + if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name)) { LLFolderType::EType preferred_type = LLFolderType::lookup(type_name); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 1e53274cd6..4be39bb88e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -64,8 +64,10 @@ #include "llappviewer.h" #include "lllogininstance.h" //#include "llfirstuse.h" +#include "llviewernetwork.h" #include "llwindow.h" + #include "llfloatermediabrowser.h" // for handling window close requests and geometry change requests in media browser windows. #include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. @@ -1360,6 +1362,34 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom } +class LLInventoryUserStatusResponder : public LLHTTPClient::Responder +{ +public: + LLInventoryUserStatusResponder() + : LLCurl::Responder() + { + } + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (isGoodStatus(status)) + { + // Complete success + gSavedSettings.setBOOL("InventoryDisplayInbox", true); + } + else if (status == 401) + { + // API is available for use but OpenID authorization failed + gSavedSettings.setBOOL("InventoryDisplayInbox", true); + } + else + { + // API in unavailable + llinfos << "Marketplace API is unavailable -- Inbox Disabled" << llendl; + } + } +}; + ///////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerMedia::setOpenIDCookie() @@ -1406,6 +1436,25 @@ void LLViewerMedia::setOpenIDCookie() LLHTTPClient::get(profile_url, new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()), headers); + + std::string url = "https://marketplace.secondlife.com/"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); + url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); + } + + url += "api/1/users/"; + url += gAgent.getID().getString(); + url += "/user_status"; + + headers = LLSD::emptyMap(); + headers["Accept"] = "*/*"; + headers["Cookie"] = sOpenIDCookie; + headers["User-Agent"] = getCurrentUserAgent(); + + LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), headers); } } diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index faa86d43dd..252183b6d7 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -33,6 +33,8 @@ // in viewer. // It is used to precompile headers for improved build speed. +#include <boost/coroutine/coroutine.hpp> + #include "linden_common.h" // Work around stupid Microsoft STL warning @@ -118,8 +120,8 @@ // Library includes from llvfs #include "lldir.h" - -// Library includes from llmessage project +
+// Library includes from llmessage project
#include "llcachename.h" #endif diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 973df6998a..dc810cbf7c 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -133,6 +133,15 @@ name="AvatarListItemIconVoiceLeftColor" reference="AvatarListItemIconOfflineColor" /> <color + name="BadgeImageColor" + value="0.44 0.69 0.56 1.0" /> + <color + name="BadgeBorderColor" + value="0.9 0.9 0.9 1.0" /> + <color + name="BadgeLabelColor" + reference="White" /> + <color name="ButtonBorderColor" reference="Unused?" /> <color @@ -760,7 +769,7 @@ <color name="MenuBarProjectBgColor" reference="MdBlue" /> - + <color name="MeshImportTableNormalColor" value="1 1 1 1"/> diff --git a/indra/newview/skins/default/textures/icons/Inv_Gift.png b/indra/newview/skins/default/textures/icons/Inv_Gift.png Binary files differnew file mode 100644 index 0000000000..5afe85d72d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Gift.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png Binary files differnew file mode 100644 index 0000000000..be58114aa1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png Binary files differnew file mode 100644 index 0000000000..e6b9480ab1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.png Binary files differnew file mode 100644 index 0000000000..ffda2e92d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png Binary files differnew file mode 100644 index 0000000000..6b5911014f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png Binary files differnew file mode 100644 index 0000000000..0e60b417b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png Binary files differnew file mode 100644 index 0000000000..9c26b92e73 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png Binary files differnew file mode 100644 index 0000000000..3b5d462975 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png Binary files differnew file mode 100644 index 0000000000..f85be047b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png Binary files differnew file mode 100644 index 0000000000..cd4e482216 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png Binary files differnew file mode 100644 index 0000000000..d212a871ce --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png Binary files differnew file mode 100644 index 0000000000..e5b6023e36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png Binary files differnew file mode 100644 index 0000000000..e1911a092f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png Binary files differnew file mode 100644 index 0000000000..9e59f7843a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png Binary files differnew file mode 100644 index 0000000000..51e8bff646 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..300e2e69e1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png Binary files differnew file mode 100644 index 0000000000..32fb236381 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..827f343b1e --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Disabled.png b/indra/newview/skins/default/textures/icons/Sync_Disabled.png Binary files differnew file mode 100644 index 0000000000..ca2e8def97 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Enabled.png b/indra/newview/skins/default/textures/icons/Sync_Enabled.png Binary files differnew file mode 100644 index 0000000000..bc236c8b98 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_1.png b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png Binary files differnew file mode 100644 index 0000000000..624e556376 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_2.png b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png Binary files differnew file mode 100644 index 0000000000..5769803b3f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_3.png b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png Binary files differnew file mode 100644 index 0000000000..92d4bfb020 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_4.png b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png Binary files differnew file mode 100644 index 0000000000..6d43eb3a9f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_5.png b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png Binary files differnew file mode 100644 index 0000000000..766d063c99 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_6.png b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png Binary files differnew file mode 100644 index 0000000000..dfe7f68b72 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index cc7cce99c9..c2757f2c94 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -72,8 +72,11 @@ with the same filename but different name <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> + <texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="Blank" file_name="Blank.png" preload="false" /> - + <texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/> <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/> <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> @@ -88,7 +91,6 @@ with the same filename but different name <texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/> <texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/> <texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/> - <texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" /> <texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> @@ -266,6 +268,8 @@ with the same filename but different name <texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" /> + <texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> + <texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> <texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" /> @@ -349,6 +353,23 @@ with the same filename but different name <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> + <texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" /> + <texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" /> + <texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" /> + <texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" /> + <texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" /> + <texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" /> + <texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" /> + <texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" /> + <texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" /> + <texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" /> + <texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" /> + <texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" /> + <texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" /> + <texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" /> + <texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" /> + <texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" /> + <texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" /> <texture name="Parcel_Exp_Color" file_name="icons/Parcel_Exp_Color.png" preload="false" /> @@ -496,6 +517,15 @@ with the same filename but different name <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" /> <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" /> + <texture name="Sync_Disabled" file_name="icons/Sync_Disabled.png" preload="true" /> + <texture name="Sync_Enabled" file_name="icons/Sync_Enabled.png" preload="true" /> + <texture name="Sync_Progress_1" file_name="icons/Sync_Progress_1.png" preload="true" /> + <texture name="Sync_Progress_2" file_name="icons/Sync_Progress_2.png" preload="true" /> + <texture name="Sync_Progress_3" file_name="icons/Sync_Progress_3.png" preload="true" /> + <texture name="Sync_Progress_4" file_name="icons/Sync_Progress_4.png" preload="true" /> + <texture name="Sync_Progress_5" file_name="icons/Sync_Progress_5.png" preload="true" /> + <texture name="Sync_Progress_6" file_name="icons/Sync_Progress_6.png" preload="true" /> + <texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" /> <texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" /> <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" /> @@ -649,6 +679,7 @@ with the same filename but different name <texture name="inv_folder_mesh.tga"/> <texture name="inv_item_mesh.tga"/> + <texture name="lag_status_critical.tga" /> <texture name="lag_status_good.tga" /> <texture name="lag_status_warning.tga" /> diff --git a/indra/newview/skins/default/textures/widgets/Badge_Background.png b/indra/newview/skins/default/textures/widgets/Badge_Background.png Binary files differnew file mode 100644 index 0000000000..5089c30312 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Background.png diff --git a/indra/newview/skins/default/textures/widgets/Badge_Border.png b/indra/newview/skins/default/textures/widgets/Badge_Border.png Binary files differnew file mode 100644 index 0000000000..4b086a63fb --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Border.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png Binary files differnew file mode 100644 index 0000000000..e603c44384 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png Binary files differnew file mode 100644 index 0000000000..fbc164123f --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index b36b82ebd8..e0ccb18c08 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -42,7 +42,7 @@ <menu_item_call.on_enable function="File.EnableUpload" /> </menu_item_call> - <menu_item_call + <menu_item_call label="Model..." layout="topleft" name="Upload Model"> @@ -263,4 +263,4 @@ parameter="eyes" /> </menu_item_call> </menu> -</menu> +</menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index 6ef93406ec..0f330a7b98 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -142,6 +142,7 @@ mouse_opaque="false" background_visible="true" > + <badge location="top_left" location_percent_vcenter="50" location_percent_hcenter="95" /> <panel class="sidepanel_inventory" name="sidepanel_inventory" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 8997c1a6d7..00f3135035 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -9,7 +9,7 @@ min_width="240" name="objects panel" width="333"> - <panel + <panel follows="all" layout="topleft" left="0" @@ -19,24 +19,234 @@ height="570" visible="true" width="330"> - <panel - class="panel_main_inventory" - filename="panel_main_inventory.xml" - follows="all" - layout="topleft" - left="0" - name="panel_main_inventory" - top="0" - label="" - height="545" - width="330" /> + <layout_stack + follows="left|right|top|bottom" + layout="topleft" + left="0" + top="0" + orientation="vertical" + name="inventory_layout_stack" + height="535" + width="330"> + <layout_panel + name="main_inventory_layout_panel" + min_dim="150" + width="330" + follows="bottom|left|right" + user_resize="false" + height="480"> + <panel + class="panel_main_inventory" + filename="panel_main_inventory.xml" + follows="all" + layout="topleft" + left="0" + name="panel_main_inventory" + top="0" + label="" + height="480" + width="330" /> + </layout_panel> + <layout_panel + width="330" + auto_resize="true" + user_resize="false" + follows="bottom|left|right" + name="inbox_layout_panel" + min_dim="35" + max_dim="200" + expanded_min_dim="90" + height="200"> + <panel + follows="all" + layout="topleft" + left="0" + name="marketplace_inbox" + class="panel_marketplace_inbox" + top="0" + label="" + height="200" + width="330"> + <string name="InboxLabelWithArg">Received Items ([NUM])</string> + <string name="InboxLabelNoArg">Received Items</string> + <button + label="Received Items" + name="inbox_btn" + height="35" + width="308" + image_unselected="MarketplaceBtn_Off" + image_selected="MarketplaceBtn_Selected" + halign="left" + handle_right_mouse="false" + follows="top|left|right" + is_toggle="true" + tab_stop="false" + pad_left="35" + top="0" + left="10" /> + <text + type="string" + length="1" + follows="right|top" + layout="topleft" + height="13" + top="10" + right="-20" + name="inbox_fresh_new_count" + font="SansSerifMedium" + halign="right" + text_color="EmphasisColor" + top_pad="0" + width="300"> + [NUM] New + </text> + <panel + follows="all" + left="10" + bottom="200" + width="308" + top="35" + bg_opaque_color="InventoryBackgroundColor" + background_visible="true" + background_opaque="true" + tool_tip="Drag and drop items to your inventory to manage and use them" + > + <inventory_panel + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + background_opaque="true" + border="false" + bevel_style="none" + follows="all" + top="0" + height="165" + start_folder="Inbox" + layout="topleft" + left="0" + name="inventory_inbox" + sort_order_setting="InventorySortOrder" + show_item_link_overlays="true" + top_pad="0" + width="308"> + <scroll reserve_scroll_corner="false" /> + </inventory_panel> + </panel> + </panel> + </layout_panel> + <layout_panel + width="330" + auto_resize="true" + user_resize="false" + follows="bottom|left|right" + name="outbox_layout_panel" + min_dim="35" + max_dim="200" + expanded_min_dim="90" + height="200"> + <panel + follows="all" + layout="topleft" + left="10" + name="marketplace_outbox" + class="panel_marketplace_outbox" + top="0" + label="" + height="200" + width="310"> + <button + label="Merchant Outbox" + is_toggle="true" + handle_right_mouse="false" + name="outbox_btn" + follows="top|left|right" + image_unselected="MarketplaceBtn_Off" + image_selected="MarketplaceBtn_Selected" + height="35" + tab_stop="false" + width="308" + halign="left" + pad_left="35" + top="0" + left="0" /> + <button + image_unselected="OutboxPush_Off" + image_selected="OutboxPush_Selected" + image_hover_selected="OutboxPush_Selected_Over" + image_hover_unselected="OutboxPush_Over" + image_disabled_selected="OutboxPush_Selected_Disabled" + image_disabled="OutboxPush_Disabled" + image_pressed="OutboxPush_Press" + image_pressed_selected="OutboxPush_Selected_Press" + label="" + tool_tip="Push to my Marketplace Storefront" + is_toggle="false" + name="outbox_sync_btn" + follows="top|right" + tab_stop="false" + halign="center" + top="6" + left="-50" + height="23" + width="32" + enabled="false" /> + <loading_indicator + follows="top|right" + name="outbox_sync_indicator" + top="6" + left="-50" + height="23" + width="32" + images_per_sec="1.15" + tab_stop="false" + visible="false"> + <images> + <image name="OutboxPush_Progress_1"/> + <image name="OutboxPush_Progress_2"/> + <image name="OutboxPush_Progress_3"/> + <image name="OutboxPush_Progress_4"/> + <image name="OutboxPush_Progress_5"/> + <image name="OutboxPush_Progress_6"/> + </images> + </loading_indicator> + <panel + follows="all" + left="0" + bottom="200" + width="330" + top="35" + > + <inventory_panel + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + background_opaque="true" + border="false" + bevel_style="none" + follows="all" + height="165" + start_folder="Outbox" + layout="topleft" + left="0" + name="inventory_outbox" + sort_order_setting="InventorySortOrder" + show_item_link_overlays="true" + top="0" + width="308"> + <scroll reserve_scroll_corner="false" /> + </inventory_panel> + </panel> + + </panel> + </layout_panel> + </layout_stack> <panel follows="bottom|left|right" - height="25" + height="30" layout="topleft" name="button_panel" left="9" - top_pad="-2" + top_pad="7" width="308"> <layout_stack follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/widgets/badge.xml b/indra/newview/skins/default/xui/en/widgets/badge.xml new file mode 100644 index 0000000000..f77c4b7178 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/badge.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Additional attributes: + --> +<badge border_image="Badge_Border" + border_color="BadgeBorderColor" + font="SansSerifSmall" + image="Badge_Background" + image_color="BadgeImageColor" + label_color="BadgeLabelColor" + location="top_left" + location_percent_hcenter="85" + location_percent_vcenter="85" + padding_horiz="7" + padding_vert="4" + requests_front="true" + > +</badge> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 16241ed84e..302014eb24 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -25,5 +25,6 @@ pad_bottom="3" height="23" scale_image="true" + handle_right_mouse="true" use_draw_context_alpha="true"> </button> diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml index 93875d66e6..3164cc5eba 100644 --- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml @@ -3,4 +3,11 @@ bg_opaque_color="InventoryBackgroundColor" background_visible="true" background_opaque="true" - /> + > + <scroll + name="Inventory Scroller" + follows="all" + reserve_scroll_corner="true" + tab_stop="true" + /> +</panel> diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml index 9bf99fa363..47a210d9b7 100644 --- a/indra/newview/skins/default/xui/en/widgets/panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/panel.xml @@ -10,4 +10,5 @@ bg_alpha_image_overlay="White" background_visible="false" background_opaque="false" - chrome="false"/>
\ No newline at end of file + chrome="false" + accepts_badge="true"/>
\ No newline at end of file |