EXP-856 FIX -- Inbox item count reflected as badge on inventory button

* Modified badges to be parented to their owners if their owners have no parents
* Modified side tray tab panels to create badges on side tab buttons when the
  xml specifies a badge.
* Modified inbox to drive the badge value of the sidebar_inventory button.
* Updated inbox and outbox sizes so scroll bars function as expected
* Updated inventory_panel.xml to allow scroll tag to specify scroll bar
  properties, instead of just having them hardcoded.

Reviewed by Richard
master
Leslie Linden 2011-06-10 16:20:30 -07:00
parent 7ed78f9274
commit 3eeb14ee0a
10 changed files with 255 additions and 151 deletions

View File

@ -79,26 +79,28 @@ void LLBadgeOwner::addBadgeToParentPanel()
if (mBadge && owner_view)
{
// Find the appropriate parent panel for the badge
// Badge parent is badge owner by default
LLView * badge_parent = owner_view;
// Find the appropriate parent for the badge
LLView * parent = owner_view->getParent();
LLPanel * parent_panel = NULL;
while (parent)
{
parent_panel = dynamic_cast<LLPanel *>(parent);
LLPanel * parent_panel = dynamic_cast<LLPanel *>(parent);
if (parent_panel && parent_panel->acceptsBadge())
{
badge_parent = parent;
break;
}
parent = parent->getParent();
}
if (parent_panel)
if (badge_parent)
{
parent_panel->addChild(mBadge);
badge_parent->addChild(mBadge);
}
else
{

View File

@ -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"
@ -184,13 +183,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);

View File

@ -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")
{}
};

View File

@ -28,6 +28,7 @@
#include "llpanelmarketplaceinbox.h"
#include "llappviewer.h"
#include "llbutton.h"
#include "llinventorypanel.h"
@ -35,7 +36,8 @@ static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_
// protected
LLPanelMarketplaceInbox::LLPanelMarketplaceInbox()
: LLPanel()
: LLPanel()
, mInventoryPanel(NULL)
{
}
@ -50,16 +52,24 @@ BOOL LLPanelMarketplaceInbox::postBuild()
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
return TRUE;
}
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);
}
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;
}
void LLPanelMarketplaceInbox::draw()
U32 LLPanelMarketplaceInbox::getItemCount() const
{
LLInventoryModel* model = mInventoryPanel->getModel();
@ -68,8 +78,8 @@ void LLPanelMarketplaceInbox::draw()
model->getDirectDescendentsOf(model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false), cats, items);
S32 item_count = 0;
U32 item_count = 0;
if (cats)
{
item_count += cats->size();
@ -80,10 +90,30 @@ void LLPanelMarketplaceInbox::draw()
item_count += items->size();
}
return item_count;
}
std::string LLPanelMarketplaceInbox::getBadgeString() const
{
std::string item_count_str("");
U32 item_count = getItemCount();
if (item_count)
{
item_count_str = llformat("%d", item_count);
}
return item_count_str;
}
void LLPanelMarketplaceInbox::draw()
{
std::string item_count_str = getBadgeString();
if (item_count_str.length() > 0)
{
LLStringUtil::format_map_t args;
args["[NUM]"] = llformat ("%d", item_count);
args["[NUM]"] = item_count_str;
getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
}
else

View File

@ -28,10 +28,11 @@
#define LL_LLPANELMARKETPLACEINBOX_H
#include "llpanel.h"
#include "llsidetray.h"
class LLInventoryPanel;
class LLPanelMarketplaceInbox : public LLPanel
class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver
{
public:
@ -46,6 +47,12 @@ public:
/*virtual*/ void draw();
U32 getItemCount() const;
std::string getBadgeString() const;
private:
void handleLoginComplete();
private:
LLInventoryPanel* mInventoryPanel;
};

View File

@ -30,7 +30,7 @@
#include "llagentcamera.h"
#include "llappviewer.h"
#include "llbadgeowner.h"
#include "llbadge.h"
#include "llbottomtray.h"
#include "llfloaterreg.h"
#include "llfirstuse.h"
@ -41,6 +41,7 @@
#include "llfocusmgr.h"
#include "llrootview.h"
#include "llnavigationbar.h"
#include "llpanelmarketplaceinbox.h"
#include "llaccordionctrltab.h"
@ -99,7 +100,7 @@ bool LLSideTray::instanceCreated ()
// Represents a single tab in the side tray, only used by LLSideTray
//////////////////////////////////////////////////////////////////////////////
class LLSideTrayTab: public LLPanel, public LLBadgeOwner
class LLSideTrayTab: public LLPanel
{
LOG_CLASS(LLSideTrayTab);
friend class LLUICtrlFactory;
@ -144,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);
@ -154,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;
@ -162,21 +165,21 @@ private:
std::string mDescription;
LLView* mMainPanel;
bool mHasBadge;
LLBadge::Params mBadgeParams;
};
LLSideTrayTab::LLSideTrayTab(const Params& p)
: LLPanel(),
LLBadgeOwner(LLView::getHandle()),
mTabTitle(p.tab_title),
mImage(p.image),
mImageSelected(p.image_selected),
mDescription(p.description),
mMainPanel(NULL)
mMainPanel(NULL),
mBadgeParams(p.badge)
{
if (p.badge.isProvided())
{
LLBadgeOwner::initBadgeParams(p.badge());
}
mHasBadge = p.badge.isProvided();
}
LLSideTrayTab::~LLSideTrayTab()
@ -191,8 +194,6 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
//return res;
}
//virtual
BOOL LLSideTrayTab::postBuild()
{
@ -205,8 +206,6 @@ BOOL LLSideTrayTab::postBuild()
getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, false));
getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, true));
addBadgeToParentPanel();
return LLPanel::postBuild();
}
@ -534,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;
};
//////////////////////////////////////////////////////////////////////////////
@ -626,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();
}
@ -777,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);
@ -949,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();
@ -962,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());
}

View File

@ -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;

View File

@ -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"

View File

@ -26,13 +26,13 @@
top="0"
orientation="vertical"
name="inventory_layout_stack"
height="535"
height="535"
width="330">
<layout_panel
name="main_inventory_layout_panel"
min_dim="150"
width="330"
follows="bottom|left|right"
follows="bottom|left|right"
user_resize="false"
height="480">
<panel
@ -50,12 +50,12 @@
<layout_panel
width="330"
auto_resize="true"
user_resize="false"
follows="bottom|left|right"
user_resize="false"
follows="bottom|left|right"
min_dim="35"
name="inbox_layout_panel"
max_dim="125"
height="35">
height="125">
<panel
follows="all"
layout="topleft"
@ -69,59 +69,62 @@
<string name="InboxLabelWithArg">MARKETPLACE INBOX ([NUM])</string>
<string name="InboxLabelNoArg">MARKETPLACE INBOX</string>
<button
label="MARKETPLACE INBOX"
name="inbox_btn"
height="35"
width="308"
image_unselected="MarketplaceBtn_Off"
image_selected="MarketplaceBtn_Selected"
halign="left"
follows="top|left|right"
is_toggle="true"
tab_stop="false"
pad_left="35"
top="0"
label="MARKETPLACE INBOX"
name="inbox_btn"
height="35"
width="308"
image_unselected="MarketplaceBtn_Off"
image_selected="MarketplaceBtn_Selected"
halign="left"
follows="top|left|right"
is_toggle="true"
tab_stop="false"
pad_left="35"
top="0"
left="10" />
<panel
follows="all"
left="10"
height="90"
width="308"
top="35"
bg_opaque_color="InventoryBackgroundColor"
background_visible="true"
background_opaque="true"
>
<text
type="string"
length="1"
follows="top|left|right"
font="SansSerifSmall"
use_ellipses="true"
name="move_items_text"
top="10"
left="4"
height="20"
width="304"
>Move items to your inventory to manage and use them.</text>
<inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
background_opaque="true"
border="false"
bevel_style="none"
follows="all"
height="70"
start_folder="Inbox"
layout="topleft"
left="0"
name="inventory_inbox"
sort_order_setting="InventorySortOrder"
show_item_link_overlays="true"
top_pad="0"
width="308" />
</panel>
<panel
follows="all"
left="10"
height="90"
width="308"
top="35"
bg_opaque_color="InventoryBackgroundColor"
background_visible="true"
background_opaque="true"
>
<text
type="string"
length="1"
follows="top|left|right"
font="SansSerifSmall"
use_ellipses="true"
name="move_items_text"
top="5"
left="4"
height="20"
width="304"
>Move items to your inventory to manage and use them.</text>
<inventory_panel
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
background_opaque="true"
border="false"
bevel_style="none"
follows="all"
top="25"
height="70"
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
@ -132,7 +135,7 @@
name="outbox_layout_panel"
min_dim="35"
max_dim="125"
height="35">
height="125">
<panel
follows="all"
layout="topleft"
@ -200,7 +203,7 @@
<panel
follows="all"
left="0"
height="90"
bottom="125"
width="330"
top="35"
>
@ -220,7 +223,9 @@
sort_order_setting="InventorySortOrder"
show_item_link_overlays="true"
top="0"
width="308" />
width="308">
<scroll reserve_scroll_corner="false" />
</inventory_panel>
</panel>
</panel>

View File

@ -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>