Merge branch 'release/2025.05' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/newview/skins/default/xui/en/floater_my_inventory.xml
master
Ansariel 2025-04-18 20:27:22 +02:00
commit 54dea42f7e
9 changed files with 96 additions and 45 deletions

View File

@ -1787,11 +1787,6 @@ LLRect LLFolderView::getVisibleRect()
return visible_rect;
}
S32 LLFolderView::getVisibleContentWidth()
{
return (mScrollContainer ? mScrollContainer->getVisibleContentRect().getWidth() : 0);
}
bool LLFolderView::getShowSelectionContext()
{
if (mShowSelectionContext)

View File

@ -226,8 +226,8 @@ public:
void scrollToShowSelection();
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
LLScrollContainer* getScrollContainer() { return mScrollContainer; }
LLRect getVisibleRect();
S32 getVisibleContentWidth();
bool search(LLFolderViewItem* first_item, const std::string &search_string, bool backward);
void setShowSelectionContext(bool show) { mShowSelectionContext = show; }

View File

@ -75,6 +75,9 @@ const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
const LLColor4U DEFAULT_WHITE(255, 255, 255);
constexpr S32 FAVORITE_IMAGE_SIZE = 14;
constexpr S32 FAVORITE_IMAGE_PAD = 3;
//static
LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
@ -495,6 +498,10 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
}
mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel.c_str()) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix.c_str()) + mLabelPaddingRight;
mLabelWidthDirty = false;
if (mIsFavorite)
{
mLabelWidth += FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD;
}
}
*width = llmax(*width, mLabelWidth);
@ -891,18 +898,25 @@ void LLFolderViewItem::drawFavoriteIcon()
if (favorite_image)
{
constexpr S32 PAD = 3;
constexpr S32 image_size = 14;
S32 width = mRoot->getVisibleContentWidth(); // star should stick to scroller's right side
if (width <= 0)
S32 x_offset = 0;
LLScrollContainer* scroll = mRoot->getScrollContainer();
if (scroll)
{
width = getRect().getWidth();
S32 width = scroll->getVisibleContentRect().getWidth();
S32 offset = scroll->getDocPosHorizontal();
x_offset = width + offset;
}
else
{
x_offset = getRect().getWidth();
}
gl_draw_scaled_image(
width - image_size - PAD, getRect().getHeight() - mItemHeight + PAD,
image_size, image_size, favorite_image->getImage(), sFgColor);
x_offset - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD,
getRect().getHeight() - mItemHeight + FAVORITE_IMAGE_PAD,
FAVORITE_IMAGE_SIZE,
FAVORITE_IMAGE_SIZE,
favorite_image->getImage(),
sFgColor);
}
}
@ -2018,7 +2032,7 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
}
else
{
LL_WARNS() << "FAVORITE_ADDED for a folder without favorites" << LL_ENDL;
// already up to date
self->mFavoritesDirtyFlags = 0;
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
}

View File

@ -2288,21 +2288,10 @@ void validate_marketplacelistings(
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
{
LLInventoryItem* inv_item = gInventory.getItem(item_id);
LLViewerInventoryItem* inv_item = gInventory.getItem(item_id);
if (inv_item)
{
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
new_item->setParent(new_parent_id);
new_item->updateParentOnServer(false);
gInventory.updateItem(new_item);
gInventory.notifyObservers();
gInventory.changeItemParent(inv_item, new_parent_id, false);
}
}
@ -2310,17 +2299,17 @@ void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected
{
for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
{
LLInventoryItem* inv_item = gInventory.getItem(*it);
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
if (inv_item)
{
change_item_parent(*it, new_cat_uuid);
gInventory.changeItemParent(inv_item, new_cat_uuid, false);
}
else
{
LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
{
gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
gInventory.changeCategoryParent(inv_cat, new_cat_uuid, false);
}
}
}
@ -3900,7 +3889,6 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
}
else if ("new_folder_from_selected" == action)
{
LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
if (!first_item)
{

View File

@ -47,7 +47,19 @@
static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
static const S32 WIDGET_SPACING = 3;
constexpr S32 WIDGET_SPACING = 3;
constexpr S32 FAVORITE_IMAGE_SIZE = 14;
constexpr S32 FAVORITE_IMAGE_PAD = 3;
bool get_is_item_favorite(const LLViewerInventoryItem* inv)
{
if (inv->getIsLinkType())
{
LLInventoryObject* obj = gInventory.getObject(inv->getLinkedUUID());
return obj && obj->getIsFavorite();
}
return inv->getIsFavorite();
}
LLPanelInventoryListItemBase::Params::Params()
: default_style("default_style"),
@ -80,19 +92,30 @@ void LLPanelInventoryListItemBase::draw()
LLViewerInventoryItem* inv_item = getItem();
if (inv_item)
{
updateItem(inv_item->getName());
updateItem(inv_item->getName(), get_is_item_favorite(inv_item));
}
setNeedsRefresh(false);
}
static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true);
LLRect local_rect = getLocalRect();
if (mHovered && mHoverImage)
{
mHoverImage->draw(getLocalRect());
mHoverImage->draw(local_rect);
}
else if (mIsFavorite && draw_star())
{
static LLPointer<LLUIImage> fav_img = LLRender2D::getInstance()->getUIImage("Inv_Favorite_Star_Full");
gl_draw_scaled_image(
local_rect.getWidth() - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD, FAVORITE_IMAGE_PAD,
FAVORITE_IMAGE_SIZE, FAVORITE_IMAGE_SIZE, fav_img->getImage());
}
if (mSelected && mSelectedImage)
{
mSelectedImage->draw(getLocalRect());
mSelectedImage->draw(local_rect);
}
if (mSeparatorVisible && mSeparatorImage)
@ -100,7 +123,7 @@ void LLPanelInventoryListItemBase::draw()
// place under bottom of listitem, using image height
// item_pad in list using the item should be >= image height
// to avoid cropping of top of the next item.
LLRect separator_rect = getLocalRect();
LLRect separator_rect = local_rect;
separator_rect.mTop = separator_rect.mBottom;
separator_rect.mBottom -= mSeparatorImage->getHeight();
F32 alpha = getCurrentTransparency();
@ -112,9 +135,15 @@ void LLPanelInventoryListItemBase::draw()
// virtual
void LLPanelInventoryListItemBase::updateItem(const std::string& name,
bool favorite,
EItemState item_state)
{
setIconImage(mIconImage);
if (mIsFavorite != favorite)
{
mIsFavorite = favorite;
reshapeMiddleWidgets();
}
setTitle(name, mHighlightedText, item_state);
}
@ -169,7 +198,7 @@ bool LLPanelInventoryListItemBase::postBuild()
if (inv_item)
{
mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), false);
updateItem(inv_item->getName());
updateItem(inv_item->getName(), get_is_item_favorite(inv_item));
}
setNeedsRefresh(true);
@ -295,6 +324,7 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem
mHovered(false),
mSelected(false),
mSeparatorVisible(false),
mIsFavorite(false),
mHoverImage(params.hover_image),
mSelectedImage(params.selected_image),
mSeparatorImage(params.separator_image)
@ -413,6 +443,16 @@ void LLPanelInventoryListItemBase::setTitle(const std::string& title,
default:;
}
if (mIsFavorite)
{
static LLUICachedControl<bool> use_color("InventoryFavoritesColorText", true);
if (use_color)
{
static const LLUIColor favorite_color = LLUIColorTable::instance().getColor("InventoryFavoriteColor", LLColor4::white);
style_params.color = favorite_color;
}
}
LLTextUtil::textboxSetHighlightedVal(
mTitleCtrl,
style_params,
@ -518,6 +558,10 @@ void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
S32 name_left = icon_rect.mRight + getWidgetSpacing();
S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
if (mIsFavorite)
{
name_right -= FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD;
}
LLRect name_rect(mTitleCtrl->getRect());
name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
mTitleCtrl->setShape(name_rect);

View File

@ -169,6 +169,7 @@ protected:
* Called after inventory item was updated, update panel widgets to reflect inventory changes.
*/
virtual void updateItem(const std::string& name,
bool favorite,
EItemState item_state = IS_DEFAULT);
void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
@ -226,8 +227,9 @@ private:
LLUIImagePtr mSelectedImage;
LLUIImagePtr mSeparatorImage;
bool mSelected;
bool mSeparatorVisible;
bool mSelected = false;
bool mSeparatorVisible = false;
bool mIsFavorite = false; // note that any setter needs to update tittle
std::string mHighlightedText;

View File

@ -432,21 +432,25 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
switch (sort_by_name())
{
case 2:
// Sort by favorites - favorite items first, then alphabetically
if (item1->isFavorite() != item2->isFavorite())
{
return item1->isFavorite();
}
break;
case 1:
// Sort by images - items with non-default images first, then alphabetically
if (item1->isDefaultImage() != item2->isDefaultImage())
{
return item2->isDefaultImage();
}
break;
default:
// Sort alphabetically only
break;
}
// Final comparison is always alphabetical by name
std::string name1 = item1->getItemName();
std::string name2 = item2->getItemName();
return (LLStringUtil::compareDict(name1, name2) < 0);

View File

@ -201,6 +201,7 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item
// virtual
void LLPanelWearableOutfitItem::updateItem(const std::string& name,
bool favorite,
EItemState item_state)
{
std::string search_label = name;
@ -264,7 +265,7 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name,
}
}
LLPanelInventoryListItemBase::updateItem(search_label, item_state);
LLPanelInventoryListItemBase::updateItem(search_label, favorite, item_state);
}
//////////////////////////////////////////////////////////////////////////
@ -491,6 +492,7 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt
}
void LLPanelAttachmentListItem::updateItem(const std::string& name,
bool favorite,
EItemState item_state)
{
std::string title_joint = name;
@ -508,7 +510,7 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name,
title_joint = title_joint + " (" + trans_name + ")";
}
LLPanelInventoryListItemBase::updateItem(title_joint, item_state);
LLPanelInventoryListItemBase::updateItem(title_joint, favorite, item_state);
}
// <FS:Ansariel> Show per-item complexity in COF
@ -631,7 +633,7 @@ bool LLPanelDummyClothingListItem::postBuild()
addWidgetToRightSide("btn_add_panel");
setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, false));
updateItem(wearableTypeToString(mWearableType));
updateItem(wearableTypeToString(mWearableType), false);
// Make it look loke clothing item - reserve space for 'delete' button
setLeftWidgetsWidth(getChildView("item_icon")->getRect().mLeft);

View File

@ -94,6 +94,7 @@ public:
* Updates item name and (worn) suffix.
*/
/*virtual*/ void updateItem(const std::string& name,
bool favorite,
EItemState item_state = IS_DEFAULT);
void onAddWearable();
@ -147,6 +148,7 @@ public:
/** Set item title. Joint name is added to the title in parenthesis */
/*virtual*/ void updateItem(const std::string& name,
bool favorite,
EItemState item_state = IS_DEFAULT);
protected: