summaryrefslogtreecommitdiff
path: root/indra/newview/llfavoritesbar.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-09-07 22:55:07 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-09-07 22:55:07 +0000
commit79653dfed48105019b8ecca9cf4bfaa2a390e100 (patch)
tree455943795bf3371bbff0689604cf5eedd903fae4 /indra/newview/llfavoritesbar.cpp
parenta9b2296b2b5664cfc8d86c7f99c00c10268e250a (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1566 https://svn.aws.productengine.com/secondlife/pe/stable-2@1580 -> viewer-2.0.0-3
* Bugs: EXT-807 EXT-810 EXT-811 EXT-784 EXT-820 EXT-393 EXT-826 EXT-811 EXT-801 EXT-808 EXT-393 EXT-743 EXT-699 EXT-397 EXT-812 EXT-736 EXT-744 EXT-809 EXT-306 EXT-854 EXT-857 EXT-790 * New Dev: EXT-694 EXT-393 EXT-367 EXT-819 EXT-795 EXT-827 EXT-788 * EXT-272 - Draggable Landmarks * EXT-715 - Block List Panel * EXT-782 - Implement advanced place information accordions
Diffstat (limited to 'indra/newview/llfavoritesbar.cpp')
-rw-r--r--indra/newview/llfavoritesbar.cpp349
1 files changed, 304 insertions, 45 deletions
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 7ad60232c7..a7f0a8ff9a 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -55,6 +55,7 @@
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewermenu.h"
+#include "lltooldraganddrop.h"
static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
@@ -73,6 +74,7 @@ public:
, mLoaded(false) {}
void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
+ const LLUUID& getLandmarkId() const { return mLandmarkID; }
const std::string& getSLURL()
{
@@ -130,8 +132,21 @@ public:
msg = mUrlGetter.getSLURL();
return TRUE;
}
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ LLFavoritesBarCtrl* fb = dynamic_cast<LLFavoritesBarCtrl*>(getParent());
+
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return LLButton::handleHover(x, y, mask);
+ }
void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+ const LLUUID& getLandmarkId() const { return mUrlGetter.getLandmarkId(); }
protected:
LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
@@ -141,6 +156,33 @@ private:
LLSLURLGetter mUrlGetter;
};
+class LLFavoritesToggleableMenu : public LLToggleableMenu
+{
+public:
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return LLToggleableMenu::handleHover(x, y, mask);
+ }
+
+ void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; }
+
+protected:
+ LLFavoritesToggleableMenu(const LLToggleableMenu::Params& p):
+ LLToggleableMenu(p)
+ {
+ }
+
+ friend class LLUICtrlFactory;
+
+private:
+ LLFavoritesBarCtrl* fb;
+};
+
/**
* This class is needed to override LLMenuItemCallGL default handleToolTip function and
* show SLURL as button tooltip.
@@ -164,6 +206,18 @@ public:
void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+ {
+ mMouseDownSignal(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseDown(x, y, mask);
+ }
+
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask)
+ {
+ mMouseUpSignal(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseUp(x, y, mask);
+ }
+
protected:
LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {}
@@ -181,6 +235,14 @@ struct LLFavoritesSort
// TODO - made it customizible using gSavedSettings
bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
{
+ S32 sortField1 = a->getSortField();
+ S32 sortField2 = b->getSortField();
+
+ if (!(sortField1 < 0 && sortField2 < 0))
+ {
+ return sortField2 > sortField1;
+ }
+
time_t first_create = a->getCreationDate();
time_t second_create = b->getCreationDate();
if (first_create == second_create)
@@ -239,29 +301,34 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_LANDMARK:
{
// Copy the item into the favorites folder (if it's not already there).
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
- LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
- if (item->getParentUUID() == favorites_id)
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+ // check if we are dragging an existing item from the favorites bar
+ if (item && mDragItemId == item->getUUID())
{
- llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
- break;
+ *accept = ACCEPT_YES_SINGLE;
+
+ if (drop)
+ {
+ handleExistingFavoriteDragAndDrop(x, y);
+ }
}
+ else
+ {
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ if (item->getParentUUID() == favorites_id)
+ {
+ llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
+ break;
+ }
- *accept = ACCEPT_YES_COPY_SINGLE;
+ *accept = ACCEPT_YES_COPY_SINGLE;
- if (drop)
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- favorites_id,
- std::string(),
- LLPointer<LLInventoryCallback>(NULL));
-
- llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+ if (drop)
+ {
+ handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
+ }
}
-
}
break;
default:
@@ -271,6 +338,61 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
return TRUE;
}
+void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
+{
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+ if (dest)
+ {
+ updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId());
+ }
+ else
+ {
+ mItems.push_back(gInventory.getItem(mDragItemId));
+ }
+
+ saveItemsOrder(mItems);
+
+ LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*) mPopupMenuHandle.get();
+
+ if (menu && menu->getVisible())
+ {
+ menu->setVisible(FALSE);
+ showDropDownMenu();
+ }
+
+ mDragItemId = LLUUID::null;
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+}
+
+void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
+{
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+ if (dest)
+ {
+ insertBeforeItem(mItems, dest->getLandmarkId(), item->getUUID());
+ }
+ else
+ {
+ mItems.push_back(gInventory.getItem(item->getUUID()));
+ }
+
+ saveItemsOrder(mItems);
+
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ favorites_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+
+ llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+}
+
//virtual
void LLFavoritesBarCtrl::changed(U32 mask)
{
@@ -311,9 +433,9 @@ LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()
void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
{
- LLInventoryModel::item_array_t items;
+ mItems.clear();
- if (!collectFavoriteItems(items))
+ if (!collectFavoriteItems(mItems))
{
return;
}
@@ -331,7 +453,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
const S32 buttonVGap = 2;
- S32 count = items.count();
+ S32 count = mItems.count();
const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad");
const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2;
@@ -369,7 +491,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
S32 i;
for (i = 0; i < mFirstDropDownItem; ++i)
{
- if (mItemNamesCache.get(i) != items.get(i)->getName())
+ if (mItemNamesCache.get(i) != mItems.get(i)->getName())
{
break;
}
@@ -387,7 +509,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
mItemNamesCache.clear();
for (S32 i = 0; i < mFirstDropDownItem; i++)
{
- mItemNamesCache.put(items.get(i)->getName());
+ mItemNamesCache.put(mItems.get(i)->getName());
}
// Rebuild the buttons only
@@ -404,7 +526,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
}
}
- createButtons(items, buttonXMLNode, buttonWidth, buttonHGap);
+ createButtons(mItems, buttonXMLNode, buttonWidth, buttonHGap);
}
// Chevron button
@@ -467,9 +589,9 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
{
S32 curr_x = buttonHGap;
// Adding buttons
- for(S32 i = mFirstDropDownItem -1; i >= 0; i--)
+ for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--)
{
- LLInventoryItem* item = items.get(i);
+ LLViewerInventoryItem* item = items.get(j++);
LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
if (NULL == fav_btn)
@@ -488,6 +610,10 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
fav_btn->setToolTip(item->getName());
fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 ));
+
+ fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+
sendChildToBack(fav_btn);
curr_x += buttonWidth + buttonHGap;
@@ -521,6 +647,15 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
std::sort(items.begin(), items.end(), LLFavoritesSort());
+ if (needToSaveItemsOrder(items))
+ {
+ S32 sortField = 0;
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ (*i)->setSortField(++sortField);
+ }
+ }
+
return TRUE;
}
@@ -528,7 +663,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
{
if (mPopupMenuHandle.isDead())
{
- LLToggleableMenu::Params menu_p;
+ LLFavoritesToggleableMenu::Params menu_p;
menu_p.name("favorites menu");
menu_p.can_tear_off(false);
menu_p.visible(false);
@@ -536,26 +671,26 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu_p.max_scrollable_items = 10;
menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
- LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
-
+ LLFavoritesToggleableMenu* menu = LLUICtrlFactory::create<LLFavoritesToggleableMenu>(menu_p);
+ menu->initFavoritesBarPointer(this);
mPopupMenuHandle = menu->getHandle();
}
- LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
+ LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*)mPopupMenuHandle.get();
if(menu)
{
if (!menu->toggleVisibility())
return;
- LLInventoryModel::item_array_t items;
+ mItems.clear();
- if (!collectFavoriteItems(items))
+ if (!collectFavoriteItems(mItems))
{
return;
}
- S32 count = items.count();
+ S32 count = mItems.count();
// Check it there are changed items, since last call
if (mItemNamesCache.size() == count)
@@ -563,7 +698,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
S32 i;
for (i = mFirstDropDownItem; i < count; i++)
{
- if (mItemNamesCache.get(i) != items.get(i)->getName())
+ if (mItemNamesCache.get(i) != mItems.get(i)->getName())
{
break;
}
@@ -587,7 +722,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
{
for (S32 i = mFirstDropDownItem; i < count; i++)
{
- mItemNamesCache.put(items.get(i)->getName());
+ mItemNamesCache.put(mItems.get(i)->getName());
}
}
@@ -598,17 +733,18 @@ void LLFavoritesBarCtrl::showDropDownMenu()
for(S32 i = mFirstDropDownItem; i < count; i++)
{
- LLInventoryItem* item = items.get(i);
+ LLViewerInventoryItem* item = mItems.get(i);
const std::string& item_name = item->getName();
- LLMenuItemCallGL::Params item_params;
+ LLFavoriteLandmarkMenuItem::Params item_params;
item_params.name(item_name);
item_params.label(item_name);
item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4));
- menu_item->setLandmarkID(item->getUUID());
+ menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
// Check whether item name wider than menu
if (menu_item->getNominalWidth() > max_width)
@@ -644,13 +780,6 @@ void LLFavoritesBarCtrl::showDropDownMenu()
void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
{
- LLInventoryModel::item_array_t items;
-
- if (!collectFavoriteItems(items))
- {
- return;
- }
-
// We only have one Inventory, gInventory. Some day this should be better abstracted.
LLInvFVBridgeAction::doAction(item_id,&gInventory);
}
@@ -797,5 +926,135 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
}
}
+void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ mDragItemId = id;
+ mStartDrag = TRUE;
+
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ LLToolDragAndDrop::getInstance()->setDragStart(screenX, screenY);
+}
+
+void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ mDragItemId = LLUUID::null;
+}
+
+BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mDragItemId != LLUUID::null && mStartDrag)
+ {
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ if(LLToolDragAndDrop::getInstance()->isOverThreshold(screenX, screenY))
+ {
+ LLToolDragAndDrop::getInstance()->beginDrag(
+ DAD_LANDMARK, mDragItemId,
+ LLToolDragAndDrop::SOURCE_LIBRARY);
+
+ mStartDrag = FALSE;
+
+ return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
+ }
+ }
+
+ return TRUE;
+}
+
+LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
+{
+ LLUICtrl* ctrl = 0;
+ S32 screenX, screenY;
+ const child_list_t* list = getChildList();
+
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ // look for a child which contains the point (screenX, screenY) in it's rectangle
+ for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
+ {
+ LLRect rect;
+ localRectToScreen((*i)->getRect(), &rect);
+
+ if (rect.pointInRect(screenX, screenY))
+ {
+ ctrl = dynamic_cast<LLUICtrl*>(*i);
+ break;
+ }
+ }
+
+ return ctrl;
+}
+
+BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array_t& items)
+{
+ BOOL result = FALSE;
+
+ // if there is an item without sort order field set, we need to save items order
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ if ((*i)->getSortField() < 0)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+void LLFavoritesBarCtrl::saveItemsOrder(LLInventoryModel::item_array_t& items)
+{
+ int sortField = 0;
+
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLViewerInventoryItem* item = *i;
+
+ item->setSortField(++sortField);
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+ }
+
+ gInventory.notifyObservers();
+}
+
+LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
+{
+ LLInventoryModel::item_array_t::iterator result = items.end();
+
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ if ((*i)->getUUID() == id)
+ {
+ result = i;
+ break;
+ }
+ }
+
+ return result;
+}
+
+void LLFavoritesBarCtrl::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId)
+{
+ LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId);
+ LLViewerInventoryItem* destItem = gInventory.getItem(destItemId);
+
+ items.erase(findItemByUUID(items, srcItem->getUUID()));
+ items.insert(findItemByUUID(items, destItem->getUUID()), srcItem);
+}
+
+void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId)
+{
+ LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId);
+ LLViewerInventoryItem* insertedItem = gInventory.getItem(insertedItemId);
+
+ items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem);
+}
// EOF