diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index 4c47cc267c..7c44478848 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -86,6 +86,8 @@ public: */ void start(); + void reset() { mCurImageIdx = 0; } + private: LLLoadingIndicator(const Params&); void initFromParams(const Params&); 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/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp index b401087345..6cebc5dd5a 100644 --- a/indra/newview/llpanelmarketplaceinbox.cpp +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -68,7 +68,17 @@ void LLPanelMarketplaceInbox::draw() model->getDirectDescendentsOf(model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false), cats, items); - S32 item_count = cats->size() + items->size(); + S32 item_count = 0; + + if (cats) + { + item_count += cats->size(); + } + + if (items) + { + item_count += items->size(); + } if (item_count) { diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp index 0151276f99..822286783f 100644 --- a/indra/newview/llpanelmarketplaceoutbox.cpp +++ b/indra/newview/llpanelmarketplaceoutbox.cpp @@ -81,7 +81,7 @@ std::string gTimeDelayDebugFunc = ""; void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) { - waitForEventOn(self, "mainloop"); + waitForEventOn(self, "mainloop"); LLTimer delayTimer; delayTimer.reset(); @@ -89,7 +89,7 @@ void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) while (!delayTimer.hasExpired()) { - waitForEventOn(self, "mainloop"); + waitForEventOn(self, "mainloop"); } outboxPanel->onSyncComplete(); @@ -123,6 +123,7 @@ void LLPanelMarketplaceOutbox::updateSyncButtonStatus() mSyncButton->setVisible(false); mSyncIndicator->setVisible(true); + mSyncIndicator->reset(); mSyncIndicator->start(); } else 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 301322d24b..ae2ac4b5e5 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -31,32 +31,116 @@ #include "llappearancemgr.h" #include "llavataractions.h" #include "llbutton.h" +#include "lldate.h" #include "llfirstuse.h" +#include "llfoldertype.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 "llselectmgr.h" #include "llsidepaneliteminfo.h" #include "llsidepaneltaskinfo.h" #include "lltabcontainer.h" -#include "llselectmgr.h" #include "llweb.h" -#include "lllayoutstack.h" static LLRegisterPanelClassWrapper t_inventory("sidepanel_inventory"); -LLSidepanelInventory::LLSidepanelInventory() - : LLPanel(), - mItemPanel(NULL), - mPanelMainInventory(NULL) -{ +// +// 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 INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack"; + +// +// Helpers +// + +class LLInboxOutboxInventoryAddedObserver : public LLInventoryAddedObserver +{ +public: + LLInboxOutboxInventoryAddedObserver(LLSidepanelInventory * sidepanelInventory) + : LLInventoryAddedObserver() + , mSidepanelInventory(sidepanelInventory) + {} + +protected: + virtual void done() + { + uuid_vec_t::const_iterator it = mAdded.begin(); + uuid_vec_t::const_iterator it_end = mAdded.end(); + + for(; it != it_end; ++it) + { + LLInventoryObject* item = gInventory.getObject(*it); + + // NOTE: This doesn't actually work because folder creation does not trigger this observer + if (item && item->getType() == LLAssetType::AT_CATEGORY) + { + // Check for FolderType FT_INBOX or FT_OUTBOX and report back to mSidepanelInventory + LLInventoryCategory * item_cat = static_cast(item); + LLFolderType::EType folderType = item_cat->getPreferredType(); + + if (folderType == LLFolderType::FT_INBOX) + { + mSidepanelInventory->enableInbox(true); + } + else if (folderType == LLFolderType::FT_OUTBOX) + { + mSidepanelInventory->enableOutbox(true); + } + } + } + + mAdded.clear(); + } + +private: + LLSidepanelInventory * mSidepanelInventory; +}; + +// +// Implementation +// + +LLSidepanelInventory::LLSidepanelInventory() + : LLPanel() + , mItemPanel(NULL) + , mPanelMainInventory(NULL) + , mInventoryFetched(false) + , mCategoriesObserver(NULL) + , mInboxOutboxAddedObserver(NULL) +{ //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } LLSidepanelInventory::~LLSidepanelInventory() { + if (mInboxOutboxAddedObserver && gInventory.containsObserver(mInboxOutboxAddedObserver)) + { + gInventory.removeObserver(mInboxOutboxAddedObserver); + } + delete mInboxOutboxAddedObserver; + + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; } BOOL LLSidepanelInventory::postBuild() @@ -122,32 +206,110 @@ BOOL LLSidepanelInventory::postBuild() // Marketplace inbox/outbox setup { - LLButton * inboxButton = getChild("inbox_btn"); - LLButton * outboxButton = getChild("outbox_btn"); + LLButton * inbox_button = getChild(INBOX_BUTTON_NAME); + LLButton * outbox_button = getChild(OUTBOX_BUTTON_NAME); - inboxButton->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); - outboxButton->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); + LLLayoutStack* stack = getChild(INVENTORY_LAYOUT_STACK_NAME); - LLLayoutStack* stack = getChild("inventory_layout_stack"); + LLLayoutPanel * inbox_panel = getChild(INBOX_LAYOUT_PANEL_NAME); + LLLayoutPanel * outbox_panel = getChild(OUTBOX_LAYOUT_PANEL_NAME); - stack->collapsePanel(getChild("inbox_layout_panel"), true); - stack->collapsePanel(getChild("outbox_layout_panel"), true); + stack->collapsePanel(inbox_panel, true); + stack->collapsePanel(outbox_panel, true); - inboxButton->setToggleState(false); - outboxButton->setToggleState(false); + inbox_button->setToggleState(false); + outbox_button->setToggleState(false); + + inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); + outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); + + // TODO: Hide inbox/outbox panels until we determine the status of the feature + //inbox_panel->setVisible(false); + //outbox_panel->setVisible(false); + + // Track added items + mInboxOutboxAddedObserver = new LLInboxOutboxInventoryAddedObserver(this); + gInventory.addObserver(mInboxOutboxAddedObserver); + + // 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)); } return TRUE; } +void LLSidepanelInventory::draw() +{ + if (!mInventoryFetched && LLInventoryModelBackgroundFetch::instance().isEverythingFetched()) + { + mInventoryFetched = true; + + updateInboxOutboxPanels(); + } -void manageInboxOutboxPanels(LLLayoutStack * stack, + LLPanel::draw(); +} + +void LLSidepanelInventory::updateInboxOutboxPanels() +{ + // Iterate through gInventory looking for inbox and outbox + 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); + + enableInbox(inbox_id.notNull()); + enableOutbox(outbox_id.notNull()); +} + +void LLSidepanelInventory::enableInbox(bool enabled) +{ + getChild(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::enableOutbox(bool enabled) +{ + getChild(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) +{ + // Perhaps use this to track inbox changes? +} + +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 @@ -159,33 +321,46 @@ void manageInboxOutboxPanels(LLLayoutStack * stack, stack->collapsePanel(pressedPanel, !expand); - // Enable user_resize on main inventory panel when at least one marketplace box is expanded - stack->setPanelUserResize("main_inventory_layout_panel", 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("inventory_layout_stack"); - LLButton* pressedButton = getChild("inbox_btn"); - LLLayoutPanel* pressedPanel = getChild("inbox_layout_panel"); - LLButton* otherButton = getChild("outbox_btn"); - LLLayoutPanel* otherPanel = getChild("outbox_layout_panel"); + LLLayoutStack* stack = getChild(INVENTORY_LAYOUT_STACK_NAME); + LLButton* pressedButton = getChild(INBOX_BUTTON_NAME); + LLLayoutPanel* pressedPanel = getChild(INBOX_LAYOUT_PANEL_NAME); + LLButton* otherButton = getChild(OUTBOX_BUTTON_NAME); + LLLayoutPanel* otherPanel = getChild(OUTBOX_LAYOUT_PANEL_NAME); - manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); + 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()); + + // TODO: Hide inbox badge + } + else + { + // TODO: Show inbox badge + } } void LLSidepanelInventory::onToggleOutboxBtn() { - LLLayoutStack* stack = getChild("inventory_layout_stack"); - LLButton* pressedButton = getChild("outbox_btn"); - LLLayoutPanel* pressedPanel = getChild("outbox_layout_panel"); - LLButton* otherButton = getChild("inbox_btn"); - LLLayoutPanel* otherPanel = getChild("inbox_layout_panel"); + LLLayoutStack* stack = getChild(INVENTORY_LAYOUT_STACK_NAME); + LLButton* pressedButton = getChild(OUTBOX_BUTTON_NAME); + LLLayoutPanel* pressedPanel = getChild(OUTBOX_LAYOUT_PANEL_NAME); + LLButton* otherButton = getChild(INBOX_BUTTON_NAME); + LLLayoutPanel* otherPanel = getChild(INBOX_LAYOUT_PANEL_NAME); manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); } - void LLSidepanelInventory::onOpen(const LLSD& key) { LLFirstUse::newInventory(false); diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index a4e8d0e8e8..8047e11566 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -30,6 +30,8 @@ #include "llpanel.h" class LLFolderViewItem; +class LLInboxOutboxInventoryAddedObserver; +class LLInventoryCategoriesObserver; class LLInventoryItem; class LLInventoryPanel; class LLPanelMainInventory; @@ -59,6 +61,12 @@ public: void onToggleInboxBtn(); void onToggleOutboxBtn(); + void updateInboxOutboxPanels(); + void enableInbox(bool enabled); + void enableOutbox(bool enabled); + + virtual void draw(); + protected: // Tracks highlighted (selected) item in inventory panel. LLInventoryItem *getSelectedItem(); @@ -70,6 +78,9 @@ protected: bool canWearSelected(); // check whether selected items can be worn + void onInboxChanged(const LLUUID& inbox_id); + void onOutboxChanged(const LLUUID& outbox_id); + // // UI Elements // @@ -88,6 +99,7 @@ protected: void onTeleportButtonClicked(); void onOverflowButtonClicked(); void onBackButtonClicked(); + private: LLButton* mInfoBtn; LLButton* mShareBtn; @@ -97,6 +109,10 @@ private: LLButton* mOverflowBtn; LLButton* mShopBtn; + bool mInventoryFetched; + + LLInventoryCategoriesObserver* mCategoriesObserver; + LLInboxOutboxInventoryAddedObserver* mInboxOutboxAddedObserver; }; #endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png new file mode 100644 index 0000000000..be58114aa1 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png new file mode 100644 index 0000000000..e6b9480ab1 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.png new file mode 100644 index 0000000000..ffda2e92d4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_On.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png new file mode 100644 index 0000000000..6b5911014f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png new file mode 100644 index 0000000000..0e60b417b0 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png new file mode 100644 index 0000000000..9c26b92e73 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png new file mode 100644 index 0000000000..3b5d462975 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png new file mode 100644 index 0000000000..f85be047b0 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png new file mode 100644 index 0000000000..cd4e482216 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png new file mode 100644 index 0000000000..d212a871ce Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png new file mode 100644 index 0000000000..e5b6023e36 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png new file mode 100644 index 0000000000..e1911a092f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png new file mode 100644 index 0000000000..9e59f7843a Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png new file mode 100644 index 0000000000..51e8bff646 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png new file mode 100644 index 0000000000..300e2e69e1 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png new file mode 100644 index 0000000000..32fb236381 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png differ diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png new file mode 100644 index 0000000000..827f343b1e Binary files /dev/null and b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index a6e71cc38e..7888674b04 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -332,6 +332,23 @@ with the same filename but different name + + + + + + + + + + + + + + + + + @@ -488,7 +505,7 @@ with the same filename but different name - + diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 91de3047e6..c945f27ac6 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -89,21 +89,21 @@ width="308" top="35" bg_opaque_color="InventoryBackgroundColor" - background_visible="true" - background_opaque="true" + background_visible="true" + background_opaque="true" > Move items to your inventory to manage and use them. + top="10" + left="4" + height="20" + width="304" + >Move items to your inventory to manage and use them. + follows="bottom|left|right" + name="outbox_layout_panel" + min_dim="35" + max_dim="125" + height="35">