From 00c8c4f6211037828bc3c48629af68ed655a59af Mon Sep 17 00:00:00 2001 From: bensaine Date: Wed, 1 Dec 2021 12:28:34 -0500 Subject: [PATCH] add: sorting (initial draft) (cherry picked from commit b4ce38099fdfa8af56c651142dbcc480fc245791) --- .../src/interface_v3/action_handler_item.cpp | 13 ++ .../src/interface_v3/dbgroup_list_sheet.cpp | 2 + .../src/interface_v3/dbgroup_list_sheet.h | 4 + .../interface_v3/dbgroup_list_sheet_text.cpp | 2 + .../interface_v3/dbgroup_list_sheet_text.h | 4 + .../interface_v3/dbgroup_list_sheet_trade.cpp | 4 +- .../src/interface_v3/inventory_manager.cpp | 168 ++++++++++-------- .../src/interface_v3/inventory_manager.h | 16 +- ryzom/client/src/net_manager.cpp | 2 +- 9 files changed, 137 insertions(+), 78 deletions(-) diff --git a/ryzom/client/src/interface_v3/action_handler_item.cpp b/ryzom/client/src/interface_v3/action_handler_item.cpp index f931f1d76..ab3af12be 100644 --- a/ryzom/client/src/interface_v3/action_handler_item.cpp +++ b/ryzom/client/src/interface_v3/action_handler_item.cpp @@ -1670,6 +1670,19 @@ class CHandlerDragNDrop : public IActionHandler }; REGISTER_ACTION_HANDLER( CHandlerDragNDrop, "drag_n_drop" ); +// ********************************************************************************************************** +class CHandlerSortInv : public IActionHandler +{ + void execute (CCtrlBase * /* pCaller */, const std::string &sParams) + { + std::string inv = getParam(sParams, "inv"); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->displaySystemInfo("CHandlerSortInv "+inv); + CInventoryManager *pInv = CInventoryManager::getInstance(); + pInv->sortInv(INVENTORIES::toInventory(inv)); + } +}; +REGISTER_ACTION_HANDLER( CHandlerSortInv, "sort_inv" ); // ********************************************************************************************************** static void sendToServerEnchantMessage(uint8 invent, uint16 slot) diff --git a/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp b/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp index 487b77c99..4c438d984 100644 --- a/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp +++ b/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp @@ -58,6 +58,8 @@ CDBGroupListSheet::CDBGroupListSheet(const TCtorParam ¶m) _MinRows= 1; _MaxRows= INT_MAX; _MaxItems= INT_MAX; + _SortBy = 0; + _SortDir = 0; _NbColumns= 2; _WSlot= 24; _WSpace= 0; diff --git a/ryzom/client/src/interface_v3/dbgroup_list_sheet.h b/ryzom/client/src/interface_v3/dbgroup_list_sheet.h index 211d872dc..b1f1f29c1 100644 --- a/ryzom/client/src/interface_v3/dbgroup_list_sheet.h +++ b/ryzom/client/src/interface_v3/dbgroup_list_sheet.h @@ -78,6 +78,8 @@ public: // Called when the list changed for a reason or another and should be reconstructed to possibly sort items virtual void sort() { } void needToSort() { _NeedToSort = true; invalidateCoords(); } + void setSortBy(sint32 sortBy) { _SortBy = sortBy; } + void setSortDir(sint32 sortDir) { _SortDir = sortDir; } /** (useful for list only) Force the validity of an element, even if its sheetId==0 * (empty slot displayed instead) @@ -173,6 +175,8 @@ protected: bool _Array : 1; bool _Squarify : 1; + sint32 _SortBy; + sint32 _SortDir; bool _CanDrop : 1; bool _Draggable : 1; diff --git a/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp b/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp index 8cc114508..dcbd0e9db 100644 --- a/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp +++ b/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp @@ -44,6 +44,8 @@ CDBGroupListSheetText::CDBGroupListSheetText(const TCtorParam ¶m) _TextTemplate(TCtorParam()) { _MaxItems = INT_MAX; + _SortBy = 0; + _SortDir = 0; _WSlot= 24; _HSlot= 24; _HSpace = 0; diff --git a/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.h b/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.h index 329d7bcea..d45ce122a 100644 --- a/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.h +++ b/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.h @@ -184,6 +184,8 @@ public: // Called when the list changed for a reason or another and should be reconstructed to possibly sort items virtual void sort() { } void needToSort() { _NeedToSort = true; invalidateCoords(); } + void setSortBy(sint32 sortBy) { _SortBy = sortBy; } + void setSortDir(sint32 sortDir) { _SortDir = sortDir; } /// Gets. sint32 getWSlot() const {return _WSlot;} @@ -253,6 +255,8 @@ protected: std::vector _SheetChildren; bool _NeedToSort; + sint32 _SortBy; + sint32 _SortDir; // Drag'n'Drop sint32 _Scrolling; sint64 _LastTimeScrolled; diff --git a/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp b/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp index 0d93baccb..d1147ddf3 100644 --- a/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp +++ b/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp @@ -720,9 +720,7 @@ void CDBGroupListSheetTrade::sort() for (i = 0; i < _SheetChildren.size(); ++i) { vTemp[i].SheetText = _SheetChildren[i]; - - CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl; - initStructForItemSort (vTemp, ctrl->getSheetId(), ctrl->getQuality(), i, ctrl->getIndexInDB()); + initStructForItemSort (vTemp, _SheetChildren[i]->Ctrl, 0, i); } std::sort(vTemp.begin(), vTemp.end()); diff --git a/ryzom/client/src/interface_v3/inventory_manager.cpp b/ryzom/client/src/interface_v3/inventory_manager.cpp index 04ad896bc..4b9837f3a 100644 --- a/ryzom/client/src/interface_v3/inventory_manager.cpp +++ b/ryzom/client/src/interface_v3/inventory_manager.cpp @@ -35,6 +35,7 @@ #include "../net_manager.h" #include "../user_entity.h" #include "../global.h" +#include #include "nel/misc/algo.h" @@ -864,7 +865,7 @@ void CInventoryManager::wearBagItem(sint32 bagEntryIndex) BagItemEquipped[bagEntryIndex]= true; grayItem (LIST_BAG_TEXT, bagEntryIndex, true); grayItem (LIST_BAG_ICONS, bagEntryIndex, true); - sortBag(); + sortAll(); } } @@ -876,7 +877,7 @@ void CInventoryManager::unwearBagItem(sint32 bagEntryIndex) BagItemEquipped[bagEntryIndex]= false; grayItem (LIST_BAG_TEXT, bagEntryIndex, false); grayItem (LIST_BAG_ICONS, bagEntryIndex, false); - sortBag(); + sortAll(); } } @@ -2114,11 +2115,12 @@ bool CTempInvManager::isOpened() // *************************************************************************** #define BAG_ITEM_NOT_SORTED 1000000 // Used for sorting -void initStructForItemSort(vector&vTemp, sint32 sheetId, sint32 quality, sint32 indexInList, sint32 indexInDB) +void initStructForItemSort(vector&vTemp, CDBCtrlSheet *ctrl, sint32 sortBy, sint32 indexInList) { // Default value is the linear pos in the db (in case its not an item) - vTemp[indexInList].Pos = toString("%08d", indexInDB); - + vTemp[indexInList].Pos = toString("%08d", ctrl->getIndexInDB()); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + sint32 sheetId = ctrl->getSheetId(); // if not empty if (sheetId != 0) { @@ -2126,7 +2128,18 @@ void initStructForItemSort(vector&vTemp, sint32 sheetId, sint32 qua if ((pItem != NULL) && (pItem->Type == CEntitySheet::ITEM)) { CItemSheet *pIS = safe_cast(pItem); - vTemp[indexInList].Pos = toString("%02d", pIS->Family); + std::map primarySort = { + {0, pIS->Family}, + {1, ctrl->getQuantity()}, + {2, ctrl->getQuality()}, + {3, (pIS->Bulk*100)*(ctrl->getQuantity())}, + {4, (ctrl->getItemWeight())*(ctrl->getQuantity())} + }; + // Sort by + vTemp[indexInList].Pos = toString("%08d", primarySort[sortBy]); + + // Secondary sort + vTemp[indexInList].Pos += toString("%02d", pIS->Family); vTemp[indexInList].Pos += toString("%03d", pIS->ItemType); // add some specific sort for raw material @@ -2142,14 +2155,14 @@ void initStructForItemSort(vector&vTemp, sint32 sheetId, sint32 qua vTemp[indexInList].Pos += toString("%02d%02d", 0, 0); - vTemp[indexInList].Pos += toString("%03d", quality); + vTemp[indexInList].Pos += toString("%03d", ctrl->getQuality()); // add sort by name vTemp[indexInList].Pos += CSheetId(sheetId).toString(); // add at last the index in DB. to avoid resort for items that are exaclty the same - vTemp[indexInList].Pos += toString("%03d", indexInDB); + vTemp[indexInList].Pos += toString("%03d", ctrl->getIndexInDB()); } } } @@ -2484,22 +2497,32 @@ void CDBGroupListSheetBag::onSwap (sint /* nDraggedSheet */, sint /* nDroppedShe void CDBGroupListSheetBag::sort() { vector vTemp; - + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->displaySystemInfo("CDBGroupListSheetBag"); vTemp.resize (_MaxItems); uint i; for (i = 0; i < _MaxItems; ++i) { vTemp[i].SheetText = _SheetChildren[i]; - - CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl; - initStructForItemSort (vTemp, ctrl->getSheetId(), ctrl->getQuality(), i, ctrl->getIndexInDB()); + //pIM->displaySystemInfo(to_string((int) _SortBy)); + initStructForItemSort (vTemp, _SheetChildren[i]->Ctrl, _SortBy, i); } - std::sort(vTemp.begin(), vTemp.end()); + pIM->displaySystemInfo("CDBGroupListSheetBag sort_dir "+to_string(_SortDir)+typeid(_SortDir).name()); + if (_SortDir == 0) { + // sort ASC + std::sort(vTemp.begin(), vTemp.end()); + } else if (_SortDir == 1) { + // sort DESC + std::sort(vTemp.rbegin(), vTemp.rend()); + } for (i = 0; i < _MaxItems; ++i) - { + { + if (vTemp[i].Pos.find('e') != std::string::npos) + pIM->displaySystemInfo(vTemp[i].Pos); + _SheetChildren[i] = vTemp[i].SheetText; } } @@ -2525,19 +2548,24 @@ bool CDBGroupIconListBag::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) void CDBGroupIconListBag::sort() { vector vTemp; - + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->displaySystemInfo("CDBGroupIconListBag"); vTemp.resize (_MaxItems); uint i; for (i = 0; i < _MaxItems; ++i) { vTemp[i].SheetIcon = _SheetChildren[i]; - - CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl; - initStructForItemSort (vTemp, ctrl->getSheetId(), ctrl->getQuality(), i, ctrl->getIndexInDB()); + initStructForItemSort (vTemp, _SheetChildren[i]->Ctrl, _SortBy, i); } - std::sort(vTemp.begin(), vTemp.end()); + if (_SortDir == 0) { + // sort ASC + std::sort(vTemp.begin(), vTemp.end()); + } else { + // sort DESC + std::sort(vTemp.rbegin(), vTemp.rend()); + } for (i = 0; i < _MaxItems; ++i) { @@ -2636,9 +2664,7 @@ void CDBGroupListSheetFilterExchangeable::sort() for (i = 0; i < _MaxItems; ++i) { vTemp[i].SheetIcon = _SheetChildren[i]; - - CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl; - initStructForItemSort (vTemp, ctrl->getSheetId(), ctrl->getQuality(), i, ctrl->getIndexInDB()); + initStructForItemSort (vTemp, _SheetChildren[i]->Ctrl, 0, i); } std::sort(vTemp.begin(), vTemp.end()); @@ -3716,61 +3742,59 @@ void CInventoryManager::debugItemInfoCache() const } // *************************************************************************** -void CInventoryManager::sortBag() +void CInventoryManager::sortAll() { CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->displaySystemInfo("sortAll"); + sortInv(INVENTORIES::bag); + sortInv(INVENTORIES::player_room); + sortInv(INVENTORIES::guild); + sortInv(INVENTORIES::pet_animal1); + sortInv(INVENTORIES::pet_animal2); + sortInv(INVENTORIES::pet_animal3); + sortInv(INVENTORIES::pet_animal4); + sortInv(INVENTORIES::pet_animal5); + sortInv(INVENTORIES::pet_animal6); + sortInv(INVENTORIES::pet_animal7); +} + +void CInventoryManager::sortInv(INVENTORIES::TInventory inv) +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CDBManager *pDM = NLGUI::CDBManager::getInstance(); + CWidgetManager *pWM = CWidgetManager::getInstance(); CDBGroupIconListBag *pIconList; CDBGroupListSheetBag *pList; - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_BAG_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_BAG_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_ROOM_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_ROOM_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_GUILD_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_GUILD_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA0_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA0_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA1_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA1_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA2_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA2_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA3_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA3_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA4_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA4_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA5_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA5_TEXT)); - if (pList != NULL) pList->needToSort(); - - pIconList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA6_ICONS)); - if (pIconList != NULL) pIconList->needToSort(); - pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(LIST_PA6_TEXT)); - if (pList != NULL) pList->needToSort(); + pIM->displaySystemInfo("sortInv " + INVENTORIES::toString(inv)); + std::map> invToProp = { + { INVENTORIES::bag, {LIST_BAG_ICONS, LIST_BAG_TEXT, BAG_SORT} }, + { INVENTORIES::player_room, {LIST_ROOM_ICONS, LIST_ROOM_TEXT, ROOM_SORT} }, + { INVENTORIES::guild, {LIST_GUILD_ICONS, LIST_GUILD_TEXT, GUILD_SORT} }, + { INVENTORIES::pet_animal1, {LIST_PA0_ICONS, LIST_PA0_TEXT, PA0_SORT} }, + { INVENTORIES::pet_animal2, {LIST_PA1_ICONS, LIST_PA1_TEXT, PA1_SORT} }, + { INVENTORIES::pet_animal3, {LIST_PA2_ICONS, LIST_PA2_TEXT, PA2_SORT} }, + { INVENTORIES::pet_animal4, {LIST_PA3_ICONS, LIST_PA3_TEXT, PA3_SORT} }, + { INVENTORIES::pet_animal5, {LIST_PA4_ICONS, LIST_PA4_TEXT, PA4_SORT} }, + { INVENTORIES::pet_animal6, {LIST_PA5_ICONS, LIST_PA5_TEXT, PA5_SORT} }, + { INVENTORIES::pet_animal7, {LIST_PA6_ICONS, LIST_PA6_TEXT, PA6_SORT} } + }; + + sint32 sortBy = pDM->getDbProp(invToProp[inv][2]+":SORT_BY")->getValue32(); + sint32 sortDir = pDM->getDbProp(invToProp[inv][2]+":SORT_DIR")->getValue32(); + pIM->displaySystemInfo("sortInv " + INVENTORIES::toString(inv) + " sortBy: " + toString(sortBy) + " sortDir: " + toString(sortDir) + " debug "+invToProp[inv][2]); + pIconList = dynamic_cast(pWM->getElementFromId(invToProp[inv][0])); + if (pIconList != NULL) { + pIconList->needToSort(); + pIconList->setSortBy(sortBy); + pIconList->setSortDir(sortDir); + } + pList = dynamic_cast(pWM->getElementFromId(invToProp[inv][1])); + if (pList != NULL) { + pList->needToSort(); + pList->setSortBy(sortBy); + pList->setSortDir(sortDir); + } } // *************************************************************************** diff --git a/ryzom/client/src/interface_v3/inventory_manager.h b/ryzom/client/src/interface_v3/inventory_manager.h index d5bd763f1..d49f247e2 100644 --- a/ryzom/client/src/interface_v3/inventory_manager.h +++ b/ryzom/client/src/interface_v3/inventory_manager.h @@ -309,7 +309,8 @@ public: void debugItemInfoWaiters(); void debugItemInfoCache() const; - void sortBag(); + void sortInv(INVENTORIES::TInventory invId); + void sortAll(); // Animal Inventories // Is the inventory present? if true, it may still not be available for modification (eg: animal too far) @@ -526,7 +527,7 @@ struct SSortStruct }; // Helper to sort with only one way for bag and trade -void initStructForItemSort(std::vector&vTemp, sint32 sheetId, sint32 quality, sint32 indexInList, sint32 indexInDB); +void initStructForItemSort(std::vector&vTemp, CDBCtrlSheet *ctrl, sint32 sortBy, sint32 indexInList); // *************************************************************************** @@ -832,6 +833,17 @@ private: #define LIST_PA6_TEXT "ui:interface:inv_pa6:content:iil:bag_list" #define LIST_PA6_ICONS "ui:interface:inv_pa6:content:iil:bag_icons" +#define BAG_SORT "UI:SAVE:INV_BAG" +#define ROOM_SORT "UI:SAVE:INV_ROOM" +#define GUILD_SORT "UI:SAVE:INV_GUILD" +#define PA0_SORT "UI:SAVE:INV_PA0" +#define PA1_SORT "UI:SAVE:INV_PA1" +#define PA2_SORT "UI:SAVE:INV_PA2" +#define PA3_SORT "UI:SAVE:INV_PA3" +#define PA4_SORT "UI:SAVE:INV_PA4" +#define PA5_SORT "UI:SAVE:INV_PA5" +#define PA6_SORT "UI:SAVE:INV_PA6" + // Theorically never used #define LIST_BAG2_TEXT "ui:interface:inv_bag:content:iil:bag_list" #define LIST_BAG2_ICONS "ui:interface:inv_bag:content:iil:bag_icons" diff --git a/ryzom/client/src/net_manager.cpp b/ryzom/client/src/net_manager.cpp index 549732372..61cd99174 100644 --- a/ryzom/client/src/net_manager.cpp +++ b/ryzom/client/src/net_manager.cpp @@ -2865,7 +2865,7 @@ void updateInventoryFromStream (NLMISC::CBitMemStream &impulse, const CInventory } } - CInventoryManager::getInstance()->sortBag(); + CInventoryManager::getInstance()->sortAll(); } catch (const Exception &e) {